Remove outbound SA and policy of rekeyed CHILD_SA since only one is valid.
Otherwise, during update-SA job (when NAT mapping changed), CHILD_SA are
updated and installed one by one, leaving a window where old SAs are being
used. There are also circumstances where the new SA is not processed last.
Closesstrongswan/strongswan#1041
This allows managing trap policies outside of the trap manager.
We'll use this to create trap policies with generic labels if trap policies
can't (or won't) be used (e.g. as responder for roadwarriors).
If update_sa() is called and dynamic traffic selectors are changed using
new addresses, this might cause issues if we continue to use a reqid that
doesn't match the updated traffic selectors. For instance, if the initiator
then uses make-before-break reauth from the new IP. It's also a particular
problem in the SELinux case where multiple CHILD_SAs with specific labels
all share the same (trap) policy with generic label. However, SAs created
after the update would not match due to the new reqid.
With SELinux and without a specific label from an acquire, we abort
establishing the CHILD_SA (for the first one we prefer a childless IKE_SA,
but since that's a separate extension, we fall back to letting the initial
CHILD_SA fail as we won't propose a label).
If trap policies are not installed already (e.g. because it's impossible to
do so like as responder for roadwarriors), this will require installing
them dynamically once the IKE_SA is established.
In SELinux mode we install the configured label on the policies and the
negotiated one on the SAs. This is how it usually is configured where the
policy/configuration has a generic context and the SAs will get the actual
context of the flows assigned (the latter matches the former, so flows
match the policies but will trigger an acquire if no matching SA exists).
In the simple mode we don't pass the label to the kernel and to avoid
duplicate policy errors we also don't use it to acquire unique reqids.
The security labels can be retrieved in a separate list from the
regular traffic selectors. We currently only plan to support a single
security label ourselves, so when generating we don't expect a list.
While combining the actions could cause duplicates (while the SA is
initiated, traffic might trigger the trap and the initiation of another
CHILD_SA), the previous commit should avoid most duplicates. If reuse_ikesa
is disabled, duplicates can't be prevented, though.
This could happen if an acquire is triggered while we respond to a
CREATE_CHILD_SA request from the peer, or if an acquire is triggered
while an IKE_SA (with its existing CHILD_SAs) is reestablished (also
with break-before-make reauthentication). Also catches multiple
manual initiations.
Note that this ignores the traffic selectors from acquires (narrowing to
them seems rare in practice anyway).
Duplicates can still get created if e.g. both peers initiate them
concurrently.
These are set via methods, which are not called again after migration
(e.g. when retrying due to INVALID_KE or when moving queued tasks), so we
don't want to clear these values.
This should make the DoS limits (cookie_threshold[_ip] and block_threshold)
more accurate so that it won't be possible to create lots of jobs from
spoofed IP addresses before half-open IKE_SAs are actually created from
these jobs to enforce those limits.
Note that retransmits are tracked as half-open SAs until they are
processed/dismissed as the check only happens in checkout_by_message().
Increasing the count in process_message_job_create() avoids issues with
missing calls to track_init() before calling checkout_by_message() (e.g.
when processing fragmented IKEv1 messages, which are reinjected via a
process message job).
This can happen if an IKE_SA is initiated to a static IP before DHCP is
done. Instead of failing the initiation, we either fake a NAT situation
(for IPv4) or disable NAT-D (for IPv6 where NATs and UDP-encap are not
widely used or supported).
This also removes the old fallbacks to determine the source address(es).
A source address lookup is done in ike_sa_t::resolve_hosts() (wasn't the
case initially) and enumerating local IPs (which was added even earlier)
could still lead to issues if e.g. LAN addresses are available but the
WAN address that's later used is not yet (in which case only the responder
would detect a NAT and UDP-encap would be configured asymmetrically).
To force UDP-encap locally in case there is no actual NAT, we store this
as COND_NAT_HERE instead of COND_NAT_FAKE. This ensures DPDs will contain
NAT-D notifies and we can later remove the state via MOBIKE. We trigger
a MOBIKE update after such a DPD by registering a changed NAT mapping after
checking for a disappearing local NAT, which is very unlikely to happen
outside of a MOBIKE update (where that flag is not checked).
Without this, the authentication succeeded if the server sent an early
EAP-Success message for mutual, key-generating EAP methods like EAP-TLS,
which may be used in EAP-only scenarios but would complete without server
or client authentication. For clients configured for such EAP-only
scenarios, a rogue server could capture traffic after the tunnel is
established or even access hosts behind the client. For non-mutual EAP
methods, public key server authentication has been enforced for a while.
A server previously could also crash a client by sending an EAP-Success
immediately without initiating an actual EAP method.
Fixes: 0706c39cda ("added support for EAP methods not establishing an MSK")
Fixes: CVE-2021-45079
This is useful for kernel implementations where the ordering of SAs
is unpredictable and the new SA might otherwise not be used until the
DELETE response has been received, which is not ideal as the responder
might not keep the old SA around that long. On Linux, it makes no
difference as we switch to the new outbound SA immediately because the
updated outbound policy references its SPI.
Currently the length of vendor ID Cisco VPN Concentrator is 16
bytes but the string has only 13+1 bytes. The actual vendor
ID has 16 bytes with a prefix length of 14 bytes and two version
bytes.
Fixes: 6c49ddfbca ("ike: Add additional Vendor IDs for third-party implementations")
Before commit 6c49ddfbca ("ike: Add additional Vendor IDs for
third-party implementations") the prefix length of vendor ID
Cisco Unity was hardcoded to 14. Since we need to know the actual
length of this VID to send it, the length can't be overloaded
with a prefix length. Revert part of commit 6c49ddfbca to
fix this problem.
Fixes: 6c49ddfbca ("ike: Add additional Vendor IDs for third-party implementations")
Before commit 6c49ddfbca ("ike: Add additional Vendor IDs for
third-party implementations") the prefix length of vendor ID
MS NT5 ISAKMPOAKLEY was hardcoded to 16. Change the prefix length
accordingly.
Fixes: 6c49ddfbca ("ike: Add additional Vendor IDs for third-party implementations")
If there are many CHILD_SAs, the time between initiating the new IKE_SA
and checking it in might be longer (depending on what else is going on
in the daemon) than the retransmission timeout and no retransmits might
be sent afterwards for this SA (it will just linger around dead).
Calling initiate() last should avoid that (we do this similarly for MBB
reauthentication).
If we are using make-before-break reauthentication, this could lead to
duplicates as the new IKE_SA wouldn't be able to delete the previous
one if it was replaced by a rekeying.
If we initiated a make-before-break reauthentication and the peer
concurrently deletes the IKE_SA (e.g. because it uses break-before-make
reauthentication), we would create a duplicate IKE_SA (the condition forces
a recreation of all existing CHILD_SAs because reestablish() is also called
to complete a break-before-make reauthentication).
The addresses observed by the client behind the NAT are exactly the same if
the NAT router gets restarted.
Fixes: 2b255f01af ("ike-mobike: Use ike_sa_t::update_hosts() to trigger events")
This now includes all key material derived for IKE_SAs in the order
defined in the RFC:
{SK_d | SK_ai | SK_ar | SK_ei | SK_er | SK_pi | SK_pr}
= prf+ (SKEYSEED, Ni | Nr | SPIi | SPIr)
Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>