This reverts commit 8b9b11919d.
Since ESN was negotiated via proposal, just configuring the SA without
ESN won't work as the ICV will be incorrect if the peer enabled ESN
on its SA. While the Linux kernel currently doesn't support disabling
replay protection for SAs that use ESN, this at least gets users an
explicit error not just dropped packets, and it will automatically work
if the kernel supports this combination at some point.
References strongswan/strongswan#2117
This also refactors the BPF handling so it can be shared between the
dhcp and farp plugins. The latter is adapted accordingly.
Closesstrongswan/strongswan#2047
Co-authored-by: Tobias Brunner <tobias@strongswan.org>
A refcount variable is used to allocate sequential unique identifiers for
Netlink sequence numbers, subject to overflows. The risk of an overflow
has so far not been considered practical, as it requires 2^32 netlink
requests.
It seems that this issue is not only theoretical. A host with thousands
of tunnels doing aggressive rekeying and/or aggressive status checking
(via vici list-sas) may trigger the overflow after a few weeks uptime.
The consequences are rather devastating: Once the refcount overflows, a
Netlink request is sent with sequence number 0. This request is answered
by the kernel, but can't be matched to the request, resulting in the error:
"received unknown netlink seq 0, ignored". Without Netlink timeouts, the
thread indefinitely waits for a response while holding the Netlink mutex,
bringing all threads to a halt.
So at all costs avoid zero sequence numbers. Also, start at sequence number
1 instead of the arbitrary 201, so the same range is used on start and after
an overflow.
The kernel includes the XFRMA_REPLAY_ESN_VAL attribute when dumping
SAs since it was added with 2.6.39. So we basically added this attribute
twice to the message sent to the kernel, potentially exceeding the
message buffer if the window size is large.
The XFRMA_REPLAY_VAL attribute is only dumped since 3.19, so that might
still be relevant (Google seems to maintain a 3.18 kernel) and since we
have to query the current lifetime stats anyway, we can just avoid adding
this attribute twice.
Closesstrongswan/strongswan#1967
Fixes a problem installing policies with source traffic selectors that do
not contain/match any of the local addresses.
When installing a route for a source TS that does contain one or more
local addresses, a preferred source address should be set in the route
(analogous to the `src` option in `ip route add`). This address is used
when the host itself sends traffic via that route (in contrast to
forwarding it).
When the source TS does not encompass any of the local addresses, the
host is not allowed to send traffic via this route and does not need to
set the preferred source address. However, the code would just return a
failure because it could not find a matching local address. This commit
changes this so routes without preferred source IP are installed to
allow non-local traffic to get forwarded via TUN device.
Closesstrongswan/strongswan#1766
socket.connect() takes a single argument with the address that depends
on the address family, for TCP it's a tuple with IP and port.
Fixes: 00a75e332f ("vici: Create default TCP socket on Windows in Python bindings")
Closesstrongswan/strongswan#1874
When adding a virtual IP on a TUN interface, the interface might get
activated (in terms of receiving the event) after we've already set the
virtual flag for the added address. As the activation repopulates the
addresses on the interface, this cleared the flag and the address would
no longer be treated as virtual IP when installing routes for CHILD_SAs
that reference it in their local traffic selectors.
Closesstrongswan/strongswan#1807
Also simplify how we try to exceed the system-wide maximum. We basically
just try to force the value and simply fall back to the regular call.
The kernel actually won't let the latter fail if the value is too big,
it just caps it at the internal maximum.
Since 17fd304e60 ("resolve: Don't install individual servers via
resolvconf"), DNS servers were sorted if getting installed via resolvconf.
In some setups the order might be important (even though relying on it
isn't a good idea in general as stub resolvers are free to use all of
the servers as they please).
This is currently only supported on Linux and with the appropriate
permissions.
Since it's experimental, it's disabled by default.
The log messages for each sent and received ESP message are logged in NET
like the ones in the socket-default plugin for UDP-encapsulated messages.
The calculation of the timeout is also shared now and the total
timeout in seconds is corrected in case retransmit_base is <= 1.
This could make it easier in the future to apply different retransmission
settings to messages/exchanges.
As long as any `child*` selector is received, only CHILD_SAs will be
terminated or rekeyed. Any passed `ike*` selectors will only be used to
filter the IKE_SAs when looking for matching CHILD_SAs. However, the
previous log messages seemed to indicate that IKE_SAs will also be
terminated/rekeyed.
References strongswan/strongswan#1655
Previously, the logger installed by the controller always announced
LEVEL_PRIVATE(4), which produced completely useless logging calls with
the common clients (vici/stroke) whose default log level is LEVEL_CTRL(1).
This can produce quite some overhead if there are e.g. a lot of concurrent
initiate() calls.
This should prevent a deadlock that could previously be caused when a
control-log event was raised. The deadlock looked something like this:
* Thread A holds the read lock on bus_t and raises the control-log event.
This requires acquiring the connection entry in write mode to queue the
outgoing message. If it is already held by another thread, this blocks
on a condvar.
* Thread B is registering the on_write() callback on the same connection's
stream due to a previous log message. Before this change, the code
acquired the entry in write mode as well, thus, blocking thread A. To
remove/add the stream, the mutex in watcher_t needs to be acquired.
* Thread C is in watcher_t's watch() and holds the mutex while logging on
level 2 or 3. The latter requires the read lock on bus_t, which should
usually be acquirable even if thread A holds it. Unless writers are
concurrently waiting on the lock and the implementation is blocking
new readers to prevent writer starvation.
* Thread D is removing a logger from the bus (e.g. after an initiate()
call) and is waiting to acquire the write lock on bus_t and is thereby
blocking thread C.
With this change, thread B should not block thread A anymore. So thread D
and thread C should eventually be able to proceed as well.
Thread A could be held up a bit if there is a thread already sending
messages for the same connection, but that should only cause a delay, no
deadlock, as on_write() and do_write() don't log (or lock) anything while
keeping the entry locked in write mode.
Closesstrongswan/strongswan#566
Also adds error reporting via VICI for issues with mediation settings.
Fixes: 229cdf6bc8 ("vici: Order auth rounds by optional `round` parameter instead of by position in the request")
References strongswan/strongswan#1569
That method is subject to interface filtering, which isn't ideal for
DHCP traffic that probably uses an internal interface on which the IKE
daemon might be disabled. In that case `giaddr` is set to an incorrect
public IP, which in turn might prevent the plugin from receiving the
DHCP server's unicast response, in particular if the DHCP socket
is bound to the internal interface.
This new approach connects the client socket and thereby determines the
source address to reach the DHCP server.
Closesstrongswan/strongswan#1573
With 5401a74d36 ("eap-tls: Add support for TLS 1.3") a TLS application
was added to implement TLS 1.3's protected success indication. For
earlier TLS versions, its build() method simply returned SUCCESS as
there was nothing to send. However, that had the unintended side-effect
of also not sending the final TLS handshake messages (ChangeCipherSpec
and Finished).
The reason is that the TLS stack first checks for remaining handshake
messages but then also asks the registered application for data to
piggyback to that response (before the commit there was no application,
so that step was skipped). The problem is that the status returned by
the application is directly forwarded through the TLS stack. So not
returning INVALID_STATE caused the session to get concluded immediately
instead of resulting in ALREADY_DONE that would trigger sending the
final EAP message instead of an EAP-Success.
Fixes: 5401a74d36 ("eap-tls: Add support for TLS 1.3")
Since 3dd5dc5011 ("Merge branch 'vici-python-timeout'"), any timeout
set directly on the socket is reset by `vici.Transport.receive()` unless
called by `vici.Session.listen()`. This prevents configuring a default
timeout directly on the socket.
However, setting a timeout directly on the socket also had drawbacks
since it can cause `vici.Transport.receive()` to raise a timeout error
while a subset of the data have been received, with no way to recover.
This commit merges both approaches by considering the timeout configured
on the socket by default (when no timeout is explicitly set) and
keeping the switch to blocking receive once the first byte has been
received. When the full expected data have been received, the timeout
configured on the socket is restored.
Co-authored-by: Tobias Brunner <tobias@strongswan.org>
Signed-off-by: Jean-Tiare Le Bigot <jt@yadutaf.fr>
Closesstrongswan/strongswan#1562
Before TLS 1.3, the server sent the last handshake message and had the
option to piggyback the EAP-Identity request directly onto the packet
with the TLS Finished message, or wait for the empty message by the
client that acknowledges the completion of the handshake. With TLS 1.3,
the client finishes the handshake after the server. So this option
is irrelevant there and we immediately start with Phase 2.