While 3c12905103 ("ipsec: Add function to compare two ipsec_sa_cfg_t
instances") added a comparison function to avoid issues with non-zeroed
padding, hashes were still calculated using chunk_hash().
If a CHILD_SA is rekeyed using a CREATE_CHILD_SA request, a subsequent
DELETE for the old CHILD_SA may time out. Before sending this DELETE,
a CHILD_REKEYED state CHILD_SA set from child_rekey::process_i() is
immediately set to CHILD_DELETING from child_delete::build_i(). If the
IKE_SA dies due to a retransmission timeout of this DELETE, a redundant
child-down event is issued for the rekeyed CHILD_SA that has already seen a
child-rekey event.
A reproducer shows the following log and events:
[CFG] vici rekey CHILD_SA #533
[IKE] establishing CHILD_SA XXX{534} reqid 20
[ENC] generating CREATE_CHILD_SA request 0 [ N(REKEY_SA) SA No KE TSi TSr ]
[ENC] parsed CREATE_CHILD_SA response 0 [ SA No TSi TSr ]
[IKE] rekeyed CHILD_SA XXX{533} with SPIs ca997de6_i cd27d4fe_o with XXX{534} with SPIs ced1cd01_i c460a7c9_o
Event: child-rekey
[OLD SA] state: REKEYING, spi-in: ca997de6
[NEW SA] state: INSTALLED, spi-in: ced1cd01
[IKE] closing CHILD_SA XXX{533} with SPIs ca997de6_i (352 bytes) cd27d4fe_o (264 bytes) and TS 0.0.0.0/0 === 10.11.9.40/29
[IKE] sending DELETE for ESP CHILD_SA with SPI ca997de6
[ENC] generating INFORMATIONAL request 1 [ D ]
[IKE] retransmit 1 of request with message ID 1
[IKE] retransmit 2 of request with message ID 1
[IKE] retransmit 3 of request with message ID 1
[IKE] retransmit 4 of request with message ID 1
[IKE] giving up after 4 retransmits
Event: child-updown
[SA] state: DELETING, spi-in: ca997de6
Event: child-updown
[SA] state: INSTALLED, spi-in: ced1cd01
To prevent the redundant child-down event for the successfully rekeyed CHILD_SA,
check if a DELETING CHILD_SA has already removed its outbound state due to
having been rekeyed before issuing the child-down event.
Add a new exchange test exercising that a delete timeout after rekeying does
not cause a duplicate child-down event.
This is useful during make-before-break reauthentication, where the
new SA is created before the old one is terminated and the virtual IP
gets released.
This also changes the hash() and equals() functions to avoid potential
collisions.
References strongswan/strongswan#2967
The referenced commit ignored that INVALID_ARG was returned by this
authenticator if an unsupported signature scheme is encountered. This
caused a crash in find_alternative_eap_cfg() as no EAP identity is
stored in the current auth config.
Since we don't distinguish the situation outside of the authenticator,
we can just return FAILED.
Closesstrongswan/strongswan#2979
Fixes: 2f2e4abe3c ("ikev2: Add support to switch peer configs based on EAP-Identities")
Some (Windows) peers have been seen to initiate a second rekeying for the
same Child SA. Presumably, this happens if a rekey request from us for
the same old Child SA arrives while it waits for the response to its
first rekey request. Once we receive the delete for the old SA, we
conclude the rekeying with the second replacement. However, the first
replacement remained linked to the old SA. So this change prevents a
crash once the peer sends a delete for that first replacement (which it
seems to do after about 5 minutes).
References strongswan/strongswan#2944Closesstrongswan/strongswan#2945
For message lengths between 6 and 8, subtracting HEADER_LEN (9) causes
`message_len` to become negative, which is then used in calls to malloc()
and memcpy() that both take size_t arguments, causing an integer
underflow.
For 6 and 7, the huge size requested from malloc() will fail (it exceeds
PTRDIFF_MAX) and the returned NULL pointer will cause a segmentation
fault in memcpy().
However, for 8, the allocation is 0, which succeeds. But then the -1
passed to memcpy() causes a heap-based buffer overflow (and possibly a
segmentation fault when attempting to read/write that much data).
Fortunately, if compiled with -D_FORTIFY_SOURCE=3 (the default on e.g.
Ubuntu), the compiler will use __memcpy_chk(), which prevents that buffer
overflow and causes the daemon to get aborted immediately instead.
Fixes: f98cdf7a47 ("adding plugin for EAP-MS-CHAPv2")
Fixes: CVE-2025-62291
While wrong, this isn't an issue in practice as AUTH_RESPONSE_LEN is
long enough that subtracting HEADER_LEN is fine.
Fixes: f98cdf7a47 ("adding plugin for EAP-MS-CHAPv2")
This allows re-connecting to a new session in a disconnect listener and
continue listening without having to return from listen(). The exception
can also be used to stop listening after some condition (e.g. to wait
until a specific SA got created and then stop).
When sending a TS_UNACCEPTABLE notify, a ALERT_TS_MISMATCH is sent, but
not when receiving one. This seems inconsistent compared to proposal
mismatch handling, so extend the child_create task to raise such an alert.
The bus alert infrastructure is currently exposed through the error-notify
plugin using a dedicated socket using a rather archaic message format.
Vici clients would need a dedicated socket connection just to receive such
alert messages, making their implementation more complex.
With vici, it is rather trivial to expose bus alerts through a dedicated
event message that vici clients may subscribe to. Add such an "alert"
event type to vici. Alert names are mapped to strings for simple consumption by
clients.
For now, the error-notify string message is omitted from events, as it mostly
contains static information without much value; instead add the IKE_SA details
for alerts associated to an IKE_SA. Other alert specific data may be added in
the future if needed; preferably using a structured format instead of the
arbitrary string messages used by error-notify. To allow future extensions,
wrap IKE_SA details under a dedicated "ike-sa" property.
If an entry is added while we wait for a checked out SA in flush() (e.g.
due to an action performed by that SA), new entries might get inserted
before the one we wait for. If that was the first entry in the row, we
didn't correctly update the table and the new entries were basically lost
by overwriting the first entry in the row. As the SA count was still
increased but the new entries couldn't get enumerated, the daemon wasn't
terminated properly but was stuck in the loop in flush().
Was apparently forgotten when support was added to the attr plugin
with 98a3ba8a5a ("attr: Add p-cscf keyword for P-CSCF server addresses").
For consistency, using an underscore like the `split*` options and not a
dash like in the attr plugin.
References strongswan/strongswan#2396
Apparently, some clients (e.g. native Android) just send an empty
EAP-Identity response. We silently ignored that previously and then
used the IKE identity for the actual EAP method. This change tries to
do something similar (i.e. don't fail if the response is empty), but by
assuming the IKE identity as EAP-Identity, we match that and possibly
can switch configs.
Closesstrongswan/strongswan#2833
Fixes: 2f2e4abe3c ("ikev2: Add support to switch peer configs based on EAP-Identities")
This now adds some state (basically a message buffer), but simplifies
error handling as we don't have to handle two potential failure paths
and could avoid some potential issues by still calling the blocking
read_all().
It also fixes a memory leak when clients disconnect.
Performing a stream read_all call (which is a blocking read) from
within the accept callback has the issue that if a whitelist client is
still connected whilst a shutdown of the charon deamon is triggered
then that shutdown won't complete gracefully due to the accept task
never exiting.
So fix shutting down gracefully by using the socket watcher rather than
a blocking read upon connection accept. Fall back to a blocking read
for partial messages to avoid the complexity associated (i.e. storing
state) for incomplete reads, which shouldn't block and cause the
original problem if the client only sends whole messages.
As we set the remote port to 0, we'd get a mapping change message with
every packet. Setting the threshold avoids all kernel messages after the
first, which we suppress explicitly as well.