This is needed, because the standard mandates that the remote entity
must be configured as ims (mimicking the APN setting I think), but on
the other hand the ePDG will identify itself with its FQDN in the end. I
tested this and this is currently the only way to do it with strongswan
I think, because you cannot configure different identities.
This way we get updated versions automatically (referencing "master"
required manually deleting the downloaded archives and the unpacked
directories). It also allows switching versions when working in different
branches (note that REV can also be set to a commit ID, e.g. to test
changes before tagging them later and merging the branch).
Use the same configure options etc. for both builds (no need for the cert
options as we don't use TLS or X.509 parsing) and switch to a Git commit
that includes the SHA-3 OID fix (it's actually the fix itself).
This also restores the test as it was before the referenced commit so it
again, as written in the description, demonstrates that venus is unable
to ping sun without IPsec tunnel.
Fixes: f27fb58ae0 ("testing: Update description and test evaluation of host2host-transport-nat")
Note that the mobike-nat test has been removed as it basically did the same
as the mobike-virtual-ip-nat test. Instead, the mobike-nat-mapping scenario
is added, which simulates a NAT router restart.
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")
If two threads are waiting in find_entry() and remove_entry(),
respectively, and the former is woken first, the latter remains stuck
as it won't get signaled.
If there are threads waiting in find_entry() and one in remove_entry()
and the latter is woken first by a thread calling put_entry(), the
former threads would remain stuck as they get never signaled.
This can happen if an IKE_SA is terminated forcefully shortly before
terminating the daemon. The thread that handles the terminate command
will call checkin_and_destroy(), which unregisters the IKE_SA from the
manager before destroying it. The main thread that calls flush() on the
IKE_SA manager won't wait for this SA (its entry is already gone), so
the processor and in turn the watcher job/thread might get canceled
before the first thread started deleting the VIP. It would then wait
indefinitely for a signal that can never be sent.
There is still a small chance the thread hangs in wait() if the state check
happens right before the watcher is canceled and it wasn't yet able to
deliver the event from the kernel, we counter that by rechecking the state
after a while.
If a PKCS#11 library/token doesn't provide one or more attributes via
C_GetAttributeValue(), we get back CKR_ATTRIBUTE_TYPE_INVALID (similar
for protected attributes where CKR_ATTRIBUTE_SENSITIVE is returned).
This is not an error as the spec demands that all attributes have been
processed with the unavailable attributes having set their length
field to CK_UNAVAILABLE_INFORMATION.
We use this to handle the CKA_TRUSTED attribute, which some tokens
apparently don't support. We previously used a version check to remove
the attribute from the call but even the latest spec doesn't make the
attribute mandatory (it's just in a list of "common" attributes for
CKO_CERTIFICATE objects, without a default value), so there are current
tokens that don't support it and prevent us from enumerating certificates.
Depending on how CLOCK_MONOTONIC is implemented, time_monotonic() might
return 0 within 1 second after the system is started. If that's the
case, we just default to 0 for now to avoid a crash (doesn't "hide" the
system time, but it's only the uptime anyway in this case).
Closesstrongswan/strongswan#435.
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>
For some that are followed by unknown data (e.g. detailed version
information) we only do a prefix match.
Co-authored-by: Tobias Brunner <tobias@strongswan.org>
Closesstrongswan/strongswan#393.
For documentation purposes the new folders ikev1-algs, ikev2-algs,
ikev1-multi-ca and ikev2-multi-ca have been created. Most of the
test cases have now been converted to the vici interface. The
remaining legacy stroke scenarios yet to be converted have been put
into the ikev2-stroke-bye folder.
For documentation purposes some legacy stroke scenarios will be kept
in the ikev1-stroke, ikev2-stroke and ipv6-stroke folders.
The values of `yytext` and `yyleng` might not be properly defined when
the error function is called (in particular if the lexer reached EOF).
While this might just cause non-printable characters in the output, it
could actually lead to a crash depending on where `yytext` points.
Closesstrongswan/strongswan#346.
It might not exist on all platforms and according to the man page:
The kvm wrapper script is used to provide compatibility with old
qemu-kvm package which has been merged into qemu as of version 1.3.
The script executes
qemu-system-x86_64 -enable-kvm
passing all other command-line arguments to the qemu binary.
Closesstrongswan/strongswan#385.
This should give us the best performance and feature set on modern
hardware (in particular when compared to code2duo, which e.g. does not allow
nested virtualization).
Closesstrongswan/strongswan#340.
While CCM is available in earlier versions, we only use it with
OpenSSL 1.1.0 and newer because the generic control variables are not
available before and we default to GCM for them.
Closesstrongswan/strongswan#353.
On 18.04, setuptools was apparently pulled in by python-pip but is not
by python3-pip and on Ubuntu 16.04 there is an issue with tox when
installed via pip3 (syntax error in one of the dependencies) and with
pip that dependency is not even available.
That's because forks are currently not allowed to be analyzed by LGTM (unlike
with SonarCloud) so this check can't actually be successful for forks even if
variables are defined.
References strongswan/strongswan#328.
The nm test can only be done on Ubuntu 18.04 as the required libraries
are not available on newer systems.
Switch to pip3 to install tox (the only Python dependency we use).
Closesstrongswan/strongswan#327.
The lint version used on our GitHub build hosts reported these errors:
Error: Value must be ≥ 0 [Range]
db.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + cursor.getLong(cursor.getColumnIndex(KEY_ID)), null);
That's because get*() expect a valid index >= 0 but getColumnIndex()
can return -1 if the column name doesn't exist.
Due to Debian 10 linking /bin to /usr/bin which drastically
increased the number of files in /bin, the PTS measurement
was switched to /usr/sbin with a lesser number of files.
Wireshark doesn't really support it, but this way it at least decodes
the ESP packets correctly and the encryption keys are saved and the
packets can be decrypted. The full-length versions of SHA-384 and
SHA-512 are not supported by Wireshark as 256-bit is the longest ICV
it is able to decode currently.
This allows clients to send an empty certificate payload if the server
sent a certificate request. If an identity was set previously, it will
be reset so get_peer_id() may be used to check if the client was
authenticated.
The PT_TLS_AUTH_TLS_OR_SASL case currently can't be implemented properly
as TLS authentication will be enforced if a client identity is configured
on the TLS server socket.
To request client authentication if we don't know the client's identity,
it's possible to use ID_ANY. However, if we don't change the identity
get_peer_id() would still report ID_ANY after the authentication.
As client with older TLS versions, we have to ack the receipt of the server's
Finished message instead.
Fixes: 083f38259c ("tls-eap: Conclude EAP method also after processing packets")
The job is queued properly, yet the timing information is wrong.
Signed-off-by: Stefan Berghofer <stefan.berghofer@secunet.com>
Fixes: ee61471113 ("implemented RFC4478 (repeated authentication)...")
This seems to fix the build with Autotools that recently started to fail
with:
autom4te-2.69: need GNU m4 1.4 or later: /usr/local/bin/gm4
aclocal: error: /usr/local/bin/autom4te-2.69 failed with exit status: 1
autoreconf-2.69: aclocal failed with exit status: 1
Closesstrongswan/strongswan#197.
If the reauthentication is scheduled while rekeying, the difference
might be negative, however, schedule_job() takes an unsigned int,
so the reauth would get scheduled very far in the future.
If rekeying and reauthetication coincided, the reauth job could get
scheduled to run immediately i.e. before checkin() was called. So the
new IKE_SA would not get reauthenticated, however, the further delayed
delete job would later find the new IKE_SA and delete it.
This way, jobs for new IKE_SAs (created via create_new()) may be
scheduled/queued before checkin() is called. If they run before
that happens, they will now correctly block in checkout() instead of
doing nothing because the IKE_SA was not found.
We don't actually check that SA out (i.e. it's not registered with the
manager). That was originally different but had to be changed with
86993d6b90 to avoid that SAs created for rekeying don't block other
threads on the manager.
These changes should ensure that concurrent calls to checkout_by_config()
result in a single IKE_SA. For instance, when acquires for different
children of the same connection are triggered concurrently.
There are two major changes to the interface:
1) The peer config object is now always set on the returned IKE_SA.
That was previously only the case if an existing IKE_SA was
returned.
2) The IKE_SA is now always registered with the manager and properly
checked out, which also was only the case for existing IKE_SAs
before.
This adds support for TLS 1.3 to libtls and adds several new features to
existing TLS versions (e.g. support for x25519/x448, EdDSA or RSA-PSS).
Unfortunately, TLS 1.3 is not really usable for TLS-based EAP methods in
practice because, in particular, key derivation is not yet standardized.
While it works between two strongSwan instances and even FreeRADIUS 3.0.21,
there will be compatibility issues in the future when implementations move
to a standardized scheme. There are currently two Internet-Drafts in
development to specify that (see 121ac4b9e3 for details). Until they are
more stable, the default maximum version is set to 1.2.
The default minimum version has also been increased to 1.2 and several
older/weaker cipher suites have been removed (e.g. with 3DES and MD5).
If the default group listed in the cipher suite is not supported, we try
to use any other supported group (the groups are negotiated separately
so we are not locked in to a specific group).
Since DH groups (or with TLS < 1.3 curves) are negotiated separately,
it doesn't matter which one is listed in the cipher suite as any one could
be used.
This was previously treated like a resumption, which it is clearly not.
Also added a check that verifies that the same cipher suite is selected
during the retry, as per RFC 8446, section 4.1.4.
Usually, the DNs of all loaded CA certificates are included in the
CertificateRequest messages sent by the server.
Alas, certain EAP-TLS clients fail to process this message if the
list is too long, returning the fatal TLS alert 'illegal parameter'.
This new option allows configuring whether CAs are included or an
empty list is sent (TLS 1.2), or the certificate_authorities extension
is omitted (TLS 1.3). The list only serves as hint/constraint
for clients during certificate selection, they still have to provide
a certificate but are free to select any one they have available.
Closesstrongswan/strongswan#187.
With TLS 1.3, the server sends its Finished message first, so the
session is complete after processing the client's Finished message,
without having to send anything else (in particular no acknowledgement
as the last message from the client is no fragment).
ECDSA support is currently required to run the tests because ECDSA
cipher suites are not filtered when determining the supported cipher
suites. Also required are ECDH groups.
If no cipher suites are available, the new versions are the previous
values but reversed (i.e. the versions were not changed but we still
ended up with a log message saying "TLS min/max TLS 1.3/TLS 1.0 ...").
Also switched to using the numeric version names to avoid the repeated
"TLS" prefix.
RFC 8448 contains multiple TLS 1.3 message traces, this commit adds two
new test cases focusing on key derivation:
- Simple 1-RTT Handshake
- Resumed 0-RTT Handshake
Additionally, the whole test suite is restructured and duplicate code is
removed and consolidated.
This way the client also properly considers the TLS version and the signature
schemes supported by the server.
Co-authored-by: Tobias Brunner <tobias@strongswan.org>
This commit also addresses the side effect that additional messages have
an influence on the derivation of the application traffic secrets. Therefore,
key derivation is relocated after the server finished message has been sent,
so the additional messages from the client (Certificate, CertificateVerify)
don't affect the key derivation. Only the outbound key is switched there, the
inbound key remains in use until the client's finished message has been
processed.
This change mainly affects legacy TLS versions because TLS 1.3
connections are terminated by the server once the peer does not send a
CertificateVerify message next to its empty Certificate message.
The cached traffic secrets change once the application traffic secrets
are derived, but we must always use the correct base key to derive the
finished message, which are the handshake traffic secrets (RFC 8446,
section 4.4).
This won't work if the client doesn't send a `signature_algorithms`
extension. But since the default is SHA1/RSA, most will send it to at
least announce stronger hash algorithms if not ECDSA.
strongSwan supports RSA_PSS_RSAE schemes for signing but does not
differentiate between rsaEncryption and rsassaPss encoding. Thus
RSA_PSS_PSS schemes are only used for verifying signatures.
A client can send one or multiple key shares from which the server picks
one it supports (checked in its preferred order). A retry is requested if
none of the key shares are supported.
Adds support to request and handle retries with a different DH group.
Only the first key share extension sent by the client is currently
considered, so this might result in protocol errors if the server requests
a group for which the client already sent a key share.
List building also added an additional length field which is required by
client-side TLS extensions but not for server-side certificate request
extension. Now the method only returns a list of supported signature
algorithms and the implementation is responsible to add additional
length fields.
Fixes: 07f826af67 ("Fixed encoding of TLS extensions (elliptic_curves and signature_algorithms)")
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
- Encrypt then MAC
- Extended master secret
- Session ticket
and also add missing suites in the unit test.
If we don't do this, we might negotiate a TLS version for which we don't
have any suites configured, so that the cipher suite negotiation
subsequently fails.
Only suggest TLS versions of supported cipher suites. For instance, do not
suggest TLS 1.3 if none of its cipher suites (requiring GCM/CCM or
ChaPoly) are available.
Even though we return from build(), we are not actually sending a response,
so we can't return NEED_MORE (would send an invalid ClientHello message) and
if we return SUCCESS, the EAP layer treats this as failure (there is a comment
in eap_authenticator_t about client methods never returning SUCCESS from
process()). Instead we return INVALID_STATE, which allows tls_t.build() to
exit from the build() loop immediately and send the already generated Finished
message.
We generate material for both MSK and EMSK even though we only need the
former. Because HKDF-Expand-Label(), on which the export functionality
is based, encodes the requested key length, we have to allocate the same
number of bytes as e.g. FreeRADIUS does (i.e. if we only request 64
bytes, those won't be the same as the first 64 bytes after requesting
128 bytes).
Unfortunately, key derivation for TLS-based methods is currently not
standardized for TLS 1.3. There is a draft [1], which defines a scheme
that's different from previous versions (instead of individual label
strings it uses a single one and passes the EAP type/code as context
value to TLS-Export()). The current code is compatible to FreeRADIUS
3.0.x, which doesn't implement it according to that draft yet (there are
unreleased changes for EAP-TLS, not for the other methods, but these only
switch the label, no context value is passed). In a separate draft
for EAP-TLS [2] there is an altogether different scheme defined in the
latest version (label combined with EAP method, no context and separate
derivation for MSK and EMSK).
So this is a mess and we will have to change this later with the inevitable
compatibility issues (we should definitely disable TLS 1.3 by default).
[1] https://tools.ietf.org/html/draft-ietf-emu-tls-eap-types
[2] https://tools.ietf.org/html/draft-ietf-emu-eap-tls13
PKCS#1 v1.5 signatures are not defined for use with TLS 1.3 (they can
only appear in certificates, we now send a signature_algorithms_cert
extension to indicate support for them). So for RSA certificates, we
must support RSA-PSS signatures.
There are two sets of schemes, that are differentiated by the type of
RSA key used for the signature, one is for classic RSA keys (rsaEncryption
OID), which can also be used with PKCS#1 when using TLS 1.2, the other
is for RSA-PSS keys (RSASSA-PSS OID), which are not yet commonly
used (and can't be generated by our pki tool). According to the RFC,
PSS must also be supported for TLS 1.2 if the schemes are included in
the signature_algorithms extension (e.g. OpenSSL does not use PKCS#1 v1.5
anymore if PSS is proposed).
This changes how these schemes are stored and enumerated (they are not
treated as combination of hash algo and key type anymore).
Legacy schemes (MD5/SHA-1) are removed.
With the previous code, there was an issue when replying to TLS 1.3
post-handshake messages. In this case, SUCCESS is eventually returned
from build(), however, no actual data has been received so in_done is 0.
This was interpreted as EOF, plain_eof was set to TRUE and no further data
was read from the socket afterwards.
Returning SUCCESS from build() if the exchange is initiated by
write_(), as is the case with the finished reply, never was a problem
because there the return value of 0 is not interpreted as EOF.
If data is processed that eventually includes a TLS close notify, build()
will fail after a close notify has been sent in turn. However, propagating
that error immediately when reading prevented ever returning the data
already processed before the close notify was received.
Note that this breaks connecting to many TLS 1.3 servers until we support
HelloRetryRequest as we now send a key_share for ECP_256 while still
proposing other groups, so many servers request to use CURVE_25519.
These DH groups don't use the point format prefix (RFC 8422 deprecated
any other format anyway). Since they are enumerated now, they can also
be used by servers for TLS 1.2.
There is no point proposing legacy (or future) cipher suites depending on
the proposed TLS versions. It was actually possible to negotiate and use
cipher suites only defined for TLS 1.2 with earlier TLS versions.
The code is a minimal handshake with the HelloRetryRequest message
implementation missing.
Can be tested with an OpenSSL server running TLS 1.3. The server must
be at least version 1.1.1 (September 2018).
Co-authored-by: ryru <pascal.knecht@hsr.ch>
TLS 1.3 uses HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
as defined in RFC 5869 to compute traffic secrets.
Co-authored-by: bytinbit <meline.sieber@hsr.ch>
The key material, in particular the nonce/IV, is derived differently and
the IV is also generated in a different way. Additionally, the actual
content type is encrypted and there may be optional padding to mask the
actual size of the encrypted data.
For some reason, setting the time zone via TZ to `GST-1GDT` in the utils test
doesn't work anymore (the DST zone is not considered, it's as if only `GST-1`
was configured).
If we pass a pointer to NULL, the memory allocated by OpenSSL has to be
freed with OPENSSL_free(). Otherwise, this can lead to random
crashes/freezes for Windows builds as seen on AppVeyor. To not
complicate things for callers of this macro, we allocate our own memory,
which we already do for other i2d_* calls.
If no valid key is configured (e.g. because it's inadvertently uninitialized),
we should not just reuse the previous key.
The `key_set` flag is not necessary anymore because a non-NULL key is set
during initialization since 6b347d5232 ("openssl: Ensure underlying hash
algorithm is available during HMAC init").
If the peer deletes the CHILD_SA, we recreate it due to the close
action. However, if we create a new TUN device, we do so with a new
VpnService.Builder object and on that the DNS servers were never applied.
The latter happened only on the fly in the attribute handler when an
IKE_SA was established. Now we do this explicitly when creating the TUN
device, like the virtual IPs and routes. While we could avoid the
recreation of the TUN device if the CHILD_SA is recreated, there is the
theoretical possibility that the remote traffic selectors change. This
way we also avoid adding stuff to the builder in different places.
Fixes#3637.
This is not an error (as reflected by the returned status code) so we
should not print to stderr as output there might still be considered an
error (or at least an audit-worthy event) by some scripts.
In some cases, the algorithms that have been compiled into a plugin have
to be disabled at runtime. Based on the array returned by the get_features()
function the optionally provided function can strip algorithms or even
callbacks or registrations from a plugin, giving us a handy and powerful way
for runtime feature configuration aside from the plugin list.
Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
This adds helper functions to determine the first or last directory separator
in a string and to check if a given character is a separator.
Paths starting with a separator are now also considered absolute on
Windows as these are rooted at the current drive.
Note that it's fine to use DIRECTORY_SEPARATOR when combining strings as
Windows API calls accept both forward and backward slashes as separators.
Co-authored-by: Michał Skalski <mskalski@enigma.com.pl>
References #3684.
Apparently, we should use OPENSSL_free() to release memory allocated by
OpenSSL. While it generally maps to free() that's apparently not the
case on Windows, where the ECP test vectors caused `ACCESS_VIOLATION
exception` crashes (not always the same vector).
Fixes: 74e02ff5e6 ("openssl: Mainly use EVP interface for ECDH")
Uses the EVP interface for ECDH with newer OpenSSL versions, which,
compared to the previous low-level use of EC_POINT_mul() supports
hardware offloading. We used this because of the ecp_x_coordinate_only
option, which is now removed as it's been obsolete for a long time and
complicated the code. There is still some legacy code for OpenSSL 1.0
and the old BoringSSL version we currently use for the Android app.
Closesstrongswan/strongswan#186.
Functions like ECDH_compute_key() will be removed with OpenSSL 3 (which
will require additional changes as other functions will be deprecated or
removed too).
ECDH_compute_key() was not used because it only gives x-coordinate of
the result. However, the default setting, as per the errata mentioned,
is to use x-coordinate only.
Use ECDH_compute_key() for this setting as it additionally allows HW
offload of the computation using dynamic engine feature in OpenSSL.
EC_POINT_mul() doesn't allow HW offload.
Signed-off-by: Mahantesh Salimath <mahantesh@nvidia.com>
The previous approach would lead to additional zero prefixes in the
encoding of the serial (which is a positive integer, not an arbitrary
blob).
Fixes#3667.
To align with RFC 4519, section 2.31/32, the abbreviation for surname
is changed to "SN" that was previously used for serialNumber, which does
not have an abbreviation.
This mapping had its origins in the X.509 patch for FreeS/WAN that was
started in 2000. It was aligned with how OpenSSL did this in earlier
versions. However, there it was changed already in March 2002 (commit
ffbe98b7630d604263cfb1118c67ca2617a8e222) to make it compatible with
RFC 2256 (predecessor of RFC 4519).
Co-authored-by: Tobias Brunner <tobias@strongswan.org>
Closesstrongswan/strongswan#179.
Also assign online leases to a peer connecting from the same endpoint
when it requests any virtual IP. This is mainly a workaround for
Windows clients that remember the virtual IPv6 address and re-request it
the next time the connection is initiated (even if it is not a
reauthentication) but don't do the same for virtual IPv4 addresses.
This can result in duplicate policies with different reqids because
these are allocated for unique sets of traffic selectors.
Fixes#3541.
This modifies the signature of the listener_t::ike_update() callback so
that both addresses are passed and it's only called once if both
addresses change (e.g. for an address family switch).
The callback is now also triggered for MOBIKE updates and the event is
exposed via vici.
Fixes#3602.
This allows more fine grained control over what's updated and does not
require multiple calls of the method. Plus we'll be able to use it in
the ike-mobike task.
Mainly to test TKM's ability for handling multiple CAs and that the
received intermediate CA certificates are passed in the right order.
But also added a regular scenario where two intermediate CA certificates
are sent by one of the clients.
Verify certificate chains starting from the root CA certificate and
moving towards the leaf/user certificate.
Also update TKM-RPC and TKM in testing scripts to version supporting the
reworked CC handling.
Load CA certificate id mapping from config and pass the correct CA ID to
TKM when checking certificate chains. The mapping of CA certificate to
CA ID is done via SHA-1 hash of the CA certificates subjectPublicKey.
Debian, Ubuntu, Fedora et. al. started to apply usrmerge to their
latest Linux distributions, i.e. /bin, /sbin, and /lib are now
symbolical links to /usr/bin, /usr/sbin, and /usr/lib, respectively.
Since executables and libraries are contained only once in Linux
packages (e.g. /bin/cp in coreutils but not /usr/bin/cp) this leads
to missing file measurments due to the symlinks when doing remote
attestation.
The new ita_attr_symlinks PA-TNC attribute fixes this problem by
collecting symbolic links pointing to directories on the client
platform.
Depending on from where bison is called, the file might not end up in
the same directory as the .y file, but the location of the Makefile.
This has been seen on FreeBSD.
There is a conflict between Flex's bison-bridge and Bison's api.prefix
options. Apparently, the former was added without consulting the Bison
devs and requires YYSTYPE, which is not added to the header anymore by
the latter. Instead, we just provide the proper definition of yyflex()
manually (as recommended by the Bison docs), so the option is not
required anymore.
On travis-ci.com (travis-ci.org will be discontinued by the end of the
year) we are now charged for each minute. We only got 10000 credits in
a trial plan, which we used up with a few builds. Minutes also cost a
different amount of credits on different platforms: 10 on Linux,
but 50 on macOS (installing the dependencies on macOS alone took 12-15
minutes on Travis for some reason, takes about half on Github's runners).
No native Windows build yet as we have the same issue as on AppVeyor where
threading/streaming tests might get stuck. And there is also only a
single Windows platform to test on. Plus building/testing on Windows is
very slow (and getting ccache to work seems tricky).
The 'sw_collector' test case had to be disabled because we can't access
/usr/local/share on the Github build hosts (the process is just blocked
in readdir() and eventually times out).
Unfortunately, we can't test on different architectures anymore (in
particular ARM and the big-endian IBM Z/x390x).
DESTROY_IF() checks if the given value is not NULL, before calling
destroy() on it, which does not work for sub-structs. If
port_filter_attr is NULL, this could crash.
If we are already deleting the old/redundant CHILD_SA, we must not
migrate the child-create task as that would destroy the new CHILD_SA we
already moved to the IKE_SA.
Fixes#3644.
Without threads handling the resolution, there is no point waiting
for a reply. If no subsequent resolution successfully starts a
thread (there might not even be one), we'd wait indefinitely.
Fixes#3634.
The DN is otherwise not parsed until compared/printed. This avoids
false detections as ASN.1 DN if e.g. an email address starts with "0",
which is 0x30 = ASN.1 sequence tag, and the next character denotes
the exact length of the rest of the string (see the unit tests for an
example).
For apps targeting Android 10, where a method to change this was added, the
default changed so that all VPN connections are marked as metered. This means
certain background operations (e.g. syncing data) are not performed anymore
even when connected to a WiFi. By setting this to false, the metered state
of the VPN connection reflects that of the underlying networks.
This is like building the root image but using a specific strongSwan
source tree, which is helpful if code changes depend on other software
packages (e.g. TKM-related or testing new crypto libraries). If the script
is called and the root image does not exist, the new option is enabled
automatically.
The option to build in a specific guest image is now also moved to an
explicit command line option so that the source dir path is the only
remaining positional argument (see --help for details).
If we check out and build a certain revision of a dependency in a branch and
switch to another that requires a different revision and then switch back,
the previous approach installed the wrong revision as it would incorrectly
assume the required revision was already built and ready to install.
None of our build environments seem to require these declarations. And
current versions of MinGW-w64 define them as inline functions in stdio.h
so these declarations clashed with that ("static declaration of '...'
follows non-static declaration").
If no callback is specified, terminate_ike_execute() is invoked without the
listener waiting on the IKE state change.
Now, if 'force' is false, then ike_sa->delete() just queues an
IKE_DELETE task, and returns SUCCESS - indicating successful task
manager initiation.
However, terminate_ike_execute() ignored this success and set the
status to FAILED.
This is not ideal, as it will be the overall return code of
terminate_ike(), although no failure did occur. This eventually leads
vici's "terminate" to return "Command failed: terminating SA failed",
as seen in this example:
In [9]: list(session.terminate({'ike-id': 2960, 'timeout': -1}))
---------------------------------------------------------------------------
CommandException Traceback (most recent call last)
<ipython-input-9-5f95b5cea88f> in <module>()
----> 1 list(session.terminate({'ike-id': 2960, 'timeout': -1}))
vici/session.pyc in streamed_request(self, command, event_stream_type, message)
136 raise CommandException(
137 "Command failed: {errmsg}".format(
--> 138 errmsg=command_response["errmsg"]
139 )
140 )
CommandException: Command failed: terminating SA failed
If we consider both queueing the task and actually destroying the IKS_SA
a success, we can just always return SUCCESS if we don't have a
callback. There is also no need to explicitly set the status to FAILED
if a listener is waiting as that's the default anyway.
Co-authored-by: Tobias Brunner <tobias@strongswan.org>
Closesstrongswan/strongswan#185.
In FIPS mode, libgcrypt uses a DRBG, which behaves differently when the
length passed to gcry_create_nonce() or gcry_randomize() is <= 0. It
expects a struct and explicitly checks that the passed pointer is not
NULL.
This ensures that e.g. ike/child-updown messages are sent that were
queued but couldn't be sent (even the job to enable to on_write() callback
requires a worker thread that's not around anymore during shutdown).
References #3602.
The message_t object used for defragmentation was only cleared after
all fragments have been received and the message was delivered. So
if we received only some fragments of a retransmitted message, the
fragments of the next message were not processed (message_t returns
INVALID_ARG if the message ID does not match causing the message to
get ignored). This rendered the IKE_SA unusable as the client
obviously never retransmitted the fragments of that previous message
after it received our response.
Adds support to use IPv6 as transport addresses for IKE and ESP and a
bunch of fixes. On Linux servers, this requires at least a 5.8 kernel so
UDP encapsulation for IPv6 is supported.
Fixes#892.
The parser is quite picky and e.g. doesn't accept UUIDs without dashes.
Even without a specific error, this at least points the users into the
right direction.
Fixes#3583.
If the activity is not active when the service connection is
established and handleIntent() is called, the activity's state is already
saved and any fragment transaction would result in an illegalStateException
due to state loss. We just ignore this and wait for another initiation
attempt (via onNewIntent()).
With the flag set, we basically ignore the resent intent, which is not
ideal if we have not yet actually started another activity. The information
dialog we show first would disappear when closing and reopening the app
or even just rotating it (we hide all dialogs when receiving an intent),
but since the flag was restored, the dialog was not shown again even
when attempting to start other connections.
Note that manually adding an IPv6 address without disabling duplicate
address detection (DAD, e.g. via `nodad` when using iproute2) will cause
a roam event due to a flag change after about 1-2 seconds (TENTATIVE is
removed). If this is a problem, we might have to ignore addresses with
TENTATIVE flag when we receive a RTM_NEWADDR message until that flag is
eventually removed.
Fixes#3511.
We create the child_sa_t object when initiating the CREATE_CHILD_SA
request, however, the IP addresses/ports might have changed once we
eventually receive the response (potentially to a retransmit sent to
a different address). So update them before installing the SA and
policies.
If the local address changed too and depending on the kernel
implementation, the temporary SA created to allocate the inbound SPI
might remain as it can't be updated. This could cause issues if e.g.
the address switches back before that SA expired (the updated inbound
SA conflicts with the temporary one), or if that happens close together
and the expire (having to wait for the address update) causes the
updated SA to get deleted.
Fixes#3164.
The previous code required explicit support for a particular key type,
of which Ed25519 and Ed448 were missing. While a fallback to `any` would
have been possible (this is already the case for unencrypted keys in the
`private` and `pkcs8` directories, which are not parsed by swanctl), it's
not necessary (as long as swanctl and the daemon are from the same release)
and does not require the daemon to detect the key type again.
Fixes#3586.
Commit 27756b081c (revocation: Check that nonce in OCSP response matches)
introduced strict nonce validation to prevent replay attacks with OCSP
responses having a longer lifetime. However, many commercial CAs (such as
Digicert) do not support nonces in responses, as they reuse once-issued OCSP
responses for the OCSP lifetime. This can be problematic for replay attack
scenarios, but is nothing we can fix at our end.
With the mentioned commit, such OCSP responses get completely unusable,
requiring the fallback to CRL based revocation. CRLs don't provide any
replay protection either, so there is nothing gained security-wise, but may
require a download of several megabytes CRL data.
To make use of replay protection where available, but fix OCSP verification
where it is not, do nonce verification only if the response actually contains
a nonce. To be safe against replay attacks, one has to fix the OCSP responder
or use a different CA, but this is not something we can enforce.
Fixes#3557.
The x509 plugin accepted CRL signers since forever, to be precise, since
dffb176f2b ("CRLSign keyUsage or CA basicConstraint are sufficient
for CRL validation")).
References #3529.
The standard output value "syslog" was deprecated for a while and did fall
back to "journal". It causes a warning since systemd version 246 [1].
By removing the setting it will default to DefaultStandardOutput, which
defaults to "journal".
[1] https://github.com/systemd/systemd/blob/master/NEWS#L202Closesstrongswan/strongswan#181.
This was moved to a separate step with 0ff939585e ("travis: Bump tpm2-tss
to 2.4.1") so packages are installed before these dependencies are built.
However, on LGTM, packages can't be installed explicitly, so `deps` is
a no-op and we still have to list some dependencies in the config.
A new global option enables sending this vendor ID to prevent Cisco
devices from narrowing the initiator's local traffic selector to the
requested virtual IP, so e.g. 0.0.0.0/0 can be used instead.
This has been tested with a "tunnel mode ipsec ipv4" Cisco template but
should also work for GRE encapsulation.
Closesstrongswan/strongswan#180.
It's ever so close with strongTNC, sometimes the OOM killer got triggered
and the tests failed, or even worse, the whole guest system got stuck.
This might just be enough for now.
Apparently, djangorestframework-camel-case, in the referenced version,
uses `six` but does not itself require/install it (later versions removed
Python 2 support altogether).
On newer systems, the upper hard limit for open file descriptors (see
`ulimit -H -n`) was increased from 4096 to 524288. Due to how python-daemon
closes potentially open file descriptors (basically stores them in a set,
removes those excluded by config, and loops through all of them), the updown
script was either killed immediately (by the OOM killer) or not ready yet
when updown events occurred.
Newer versions of systemd etc. seem to require quite a lot of entropy
from /dev/random while booting, which can block and therefore delay the
start of other services (in particular sshd) by more than a minute.
Using the host's /dev/urandom via VirtIO RNG, we can avoid blocking the
guests.
The required kernel options are added for kernel versions 5.4+.
While `pos` was moved to the end, `len` was not adjusted (i.e. set to 0)
so later calls could write beyond the buffer. However, the last port
written might have been incomplete, so instead we just reset the string.
Don't abort the script if the version is reported as UNKNOWN, which happens
on CI hosts where the repository is only cloned with a certain depth (which
may not include the latest tag).
Also, never map VERSION to UNKNOWN.
Fixes: 2e522952c7 ("configure: Optionally use version information obtained from Git in executables")
If it takes a while to start one of the threads, another thread might already
have passed the usleep() call previously used and re-enabled cancelability
so that the loop that checked for it would never terminate.
The variable GIT_VERSION is always defined, either obtained from Git or
a file that is embedded in tarballs when they are built. Optionally,
that version is declared as VERSION in config.h so it will be used e.g. in
the daemons when they print the version number.
There is a check that should catch missing tags (i.e. if the version number
in AC_INIT() isn't a prefix of the version obtained via Git).
These changes store all CA certificates in vici_authority_t, which avoids
issues with unloading authority sections or clearing credentials.
Closesstrongswan/strongswan#172.
This way we only have one reference for each CA certificate, whether it
is loaded in an authority section, a connection or via load-certs() command.
It also avoids enumerating CA certificates multiple times if they are
loaded in different ways.
With the previous approach, CA certificates that were not re-loaded via
load-cert() (e.g. from tokens or via absolute paths) would not be available
anymore after the clear-creds() command was used. This avoids this
issue, but can cause duplicate CA certificates to get stored and enumerated,
so there might be a scaling factor.
This changes the hashtable implementation to that it maintains insertion
order. This is then used in the vici plugin to store connections in a
hash table instead of a linked list, which makes managing them quite a
bit faster if there are lots of connections.
The old implementation is extracted into a new class (hashlist_t), which
optionally supports sorting keys and provides the previous get_match()
function.
This reduces the clustering problem (primary clustering) but is not
completely free of it (secondary clustering) it still reduces the maximum
and average probing lengths.
With the previous approach we'd require at least an additional pointer
per item to store them in a list (15-18% increase in the overhead per
item). Instead we switch from handling collisions with overflow lists to
an open addressing scheme and store the actual table as variable-sized
indices pointing into an array of all inserted items in their original
order.
This can reduce the memory overhead even compared to the previous
implementation (especially for smaller tables), but because the array for
items is preallocated whenever the table is resized, it can be worse for
certain numbers of items. However, avoiding all the allocations required
by the previous design is actually a big advantage.
Depending on the usage pattern, the performance can improve quite a bit (in
particular when inserting many items). The raw lookup performance is a bit
slower as probing lengths increase with open addressing, but there are some
caching benefits due to the compact storage. So for general usage the
performance should be better. For instance, one test I did was counting the
occurrences of words in a list of 1'000'000 randomly selected words from a
dictionary of ~58'000 words (i.e. using a counter stored under each word as
key). The new implementation was ~8% faster on average while requiring
10% less memory.
Since we can't remove items from the array (would change the indices of all
items that follow it) we just mark them as removed and remove them once the
hash table is resized/rehashed (the cells in the hash table for these may
be reused). Due to this the latter may also happen if the number of stored
items does not increase e.g. after a series of remove/put operations (each
insertion requires storage in the array, no matter if items were removed).
So if the capacity is exhausted, the table is resized/rehashed (after lots
of removals the size may even be reduced) and all items marked as removed
are simply skipped.
Compared to the previous implementation the load factor/capacity is
lowered to reduce chances of collisions and to avoid primary clustering to
some degree. However, the latter in particular, but the open addressing
scheme in general, make this implementation completely unsuited for the
get_match() functionality (purposefully hashing to the same value and,
therefore, increasing the probing length and clustering). And keeping the
keys optionally sorted would complicate the code significantly. So we just
keep the existing hashlist_t implementation without adding code to maintain
the overall insertion order (we could add that feature optionally later, but
with the mentioned overhead for one or two pointers).
The maximum size is currently not changed. With the new implementation
this translates to a hard limit for the maximum number of items that can be
held in the table (=CAPACITY(MAX_SIZE)). Since this equals 715'827'882
items with the current settings, this shouldn't be a problem in practice,
the table alone would require 20 GiB in memory for that many items. The
hashlist_t implementation doesn't have that limitation due to the overflow
lists (it can store beyond it's capacity) but it itself would require over
29 GiB of memory to hold that many items.
The main intention here is that we can change the hashtable_t
implementation without being impeded by the special requirements imposed
by get_match() and sorting the keys/items in buckets.
This can improve negative lookups, but is mostly intended to be used
with get_match() so keys/items can be matched/enumerated in a specific
order. It's like storing sorted linked lists under a shared key but
with less memory overhead.
They are not marked as temporary addresses so make sure we always return
them whether temporary addresses are preferred as source addresses or not
as we need to enumerate them when searching for addresses in traffic selectors
to install routes.
Fixes: 9f12b8a61c ("kernel-netlink: Enumerate temporary IPv6 addresses according to config")
We don't track CHILD_SA down events anymore and rely on NM's initial timeout
to let the user know if the connection failed initially. So we also don't
have to explicitly differentiate between initial connection failures and
later ones like we do an Android. Also, with the default retransmission
settings, there will only be one keying try as NM's timeout is lower than
the combined retransmission timeout of 165s.
There is no visual indicator while the connection is reestablished later.
Fixes#3300.
If a MOBIKE task is deferred, the retransmission counter is reset to 0
when reinitiating. So if there were retransmits before, this alert would
not be triggered if a response is received now without retransmits.
We usually have a local IP already via ike_sa_t::resolve_hosts() before
build_i() is called but if that's not the case, it's more likely we have
one after we processed the first response (it might also have changed).
There is a potential chance we still don't have one if the socket API
doesn't provide us with the destination address of received messages,
but that seems not very likely nowadays.
We need the PSK/identity already when deriving the keys in process_i().
Fixes: 1665a4e050 ("ikev1: Use actual local identity as initiator or aggressive mode responder")
The native parseInetAddressBytes() method called by that method is not
available when running the tests.
Not very pretty and there are some warnings because PowerMock does
reflection in some illegal way but it fixes the unit tests and does
not require any new dependencies like Apache Commons or Guava just to
parse IP addresses without DNS lookup.
Fixes: 2ef473be15 ("android: Use helper to parse IP addresses where appropriate")
Fixes#3443.
Starting with Android 6, the system will aggressively suspend apps when
the device is idle (Doze mode). With Android 10 on a Pixel 4 this seems
to happen after about 70 minutes. Then the scheduler thread in our
default scheduler is only woken rarely, combined with our previous use
of the monotonic clock it meant that events were executed with severe
delays and noticing that there was such a delay. This was particularly
bad in regards to NAT keepalives as it usually meant that the device was
not reachable anymore from the outside.
Some changes here try to improve that situation, e.g. the clock is switched
to CLOCK_REALTIME (Bionic doesn't support CLOCK_BOOTTIME for condvars) so we
can measure the actual difference e.g. since the last outbound message,
other changes try to ensure that connectivity is restored after being asleep
for a while (send DPD instead of keepalive after a long delay, send DPD even
if path to peer stays the same).
However, the most significant change is the replacement of the default
scheduler with one specifically designed for Android. It schedules
long-term events via AlarmManager, which allows waking up the app even
if the system put it to sleep. The latter requires adding the app to the
system's battery optimization whitelist, which is requested from the
user automatically if necessary. With this, NAT keepalives and rekeyings
are now scheduled accurately, with little changes to the battery usage.
If the app is not whitelisted (there is a setting to ignore this), events
are delayed by up to 15 minutes after about 70 minutes, so behind a NAT
the device won't be reachable from the outside afterwards (connectivity
should be restored as soon as the device is woken from deep sleep by the
user).
Fixes#3364.
This allows users to ignore whether the app is on the device's power
whitelist without a warning. The flag is currently not set
automatically if the user denies the request.
This is necessary so we can actually schedule events accurately in Doze
mode. Otherwise, we'd only get woken in intervals of several minutes (up to
15 according to the docs) after about an hour.
This uses AlarmManager to schedule events in a way that ensures the app
is woken up (requires whitelisting when in Doze mode to be woken up at
the exact time, otherwise there are delays of up to 15 minutes).
Retransmission jobs for old requests for which we already received a
response previously left the impression that messages were sent more
recently than was actually the case.
task_manager_t always defined INVALID_STATE as possible return value if
no retransmit was sent, this just was never actually returned.
I guess we could further differentiate between actual invalid states
(e.g. if we already received the response) and when we don't send a
retransmit for other reasons e.g. because the IKE_SA became stale.
Previously, if the two utility functions were called while the VPN
connection was established (i.e. charon was initialized) the logger for
libstrongswan would get reset to the initial log handler. So certain
log messages would not get logged to the log file after the TUN device
was created (one of the helpers is used to convert IPs there).
A new NAT mapping might be created even if the IP stays the same. Due to
the DPD fallback with NAT keep-alives this might only be necessary in
corner cases, if at all.
This is useful on Android where the app might not be able to send
keep-alives if the device is asleep for a while. If the NAT mapping
has been deleted in the mean time, the NAT-D payloads allow detecting
this and connectivity can be restored by doing a MOBIKE update or
recreating the SA if the peer already deleted it because the client
wasn't reachable.
This allows measuring the delay between events more accurately if a
device is often suspended.
While CLOCK_BOOTTIME would be preferable, Android's bionic C library
does not support it for condvars.
On some systems it might be preferable to use e.g. CLOCK_BOOTTIME
instead of CLOCK_MONOTONIC, which is also not affected by time
adjustments but includes times when the system was suspended.
XML resources are apparently not supported there. Moving the icon to
the mipmap folders should fix that. Aliases are defined for the icons on
Android < 8.0.
Evidently, onClick() may be called either before onStartListening() or
after onStopListening() has been called, which causes a crash when
trying to load a VpnProfile via mDataSource.
This partially reverts 3716af079e ("android: Avoid crash related to
TileService on Huawei devices").
Manually built dependencies are now built in a separate step after
packages have been installed as they might depend themselves on some
packages (e.g. tpm2-tss, which now requires libjson-c).
This change allows to customize the previously hard-coded remote traffic
selectors.
This does not actually write the newly added "remote-ts" configuration option
into NetworkManager's configuration file, but will use an existing value.
Exposing the config setting in the GUI could be done later if this is a
desired change.
Use case: remote firewall appliance wrongly accepts the `0.0.0.0/0` TS but
does not actually route external traffic, leaving the user with a partially
working internet connection.
Closesstrongswan/strongswan#173.
If we fail connecting to the host we got redirected to, we should restart
with the original host where we might get redirected to a different host.
We must not reset this when retrying due to INVALID_KE_PAYLOAD or COOKIE
notifies. Since we keep the initiator SPI in those cases, we use that
flag as indicator.
Since we don't store the original remote_host value, we can't restore
that. So there is a potential conflict with MIPv6.
Closesstrongswan/strongswan#171.
The height of the dialog increased due to the recently added additional
fields for certificate selection and identities. On some screens the
fields to configure custom proposals were not visible anymore.
Together with less spacing on the top level GtkBox this change reduces
the height by about 80 pixels.
Fixes#3448.
The path '/usr/share/appdata' is deprecated as is the .appdata.xml
extension, files should be in installed in '/usr/share/metainfo' with
a .metainfo.xml extension.
According to the docs, the metainfo path should be well supported even
by older distros like Ubuntu 16.04.
Reference: 2.1.2. Filesystem locations
https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html
The need_secrets() method is called before connect() (where we clear the
previous secrets too), so e.g. a password-protected private could be
decrypted with the cached password from earlier but if the password was not
stored with the connection, it would later fail as no password was requested
from the user that could be passed to connect().
References #3428.
On newer desktops the auth dialog is called with --external-ui-mode and
it seems that the password flag has to be set, otherwise the password is
not stored temporarily in the profile and passed to charon-nm (not sure
how this works exactly as need_secrets() is called multiple times even
after the password was already entered, only before doing so the last
time is the password available in that callback, but only if the flag
was set). This now also allows storing the password for the private key
with the profile.
Fixes#3428.
Due to the exponential backoff a high number of retransmits only
makes sense if retransmit_limit is set. However, even with that there
was a problem.
We first calculated the timeout for the next retransmit and only then
compared that to the configured limit. Depending on the configured
base and timeout the calculation overflowed the range of uint32_t after
a relatively low number of retransmits (with the default values after 23)
causing the timeout to first get lower (on a high level) before constantly
resulting in 0 (with the default settings after 60 retransmits).
Since that's obviously lower than any configured limit, all remaining
retransmits were then sent without any delay, causing a lot of concurrent
messages if the number of retransmits was high.
This change determines the maximum number of retransmits until an
overflow occurs based on the configuration and defaults to UINT32_MAX
if that value is exceeded. Note that since the timeout is in milliseconds
UINT32_MAX equals nearly 50 days.
The calculation in task_manager_total_retransmit_timeout() uses a double
variable and the result is in seconds so the maximum number would be higher
there (with the default settings 1205). However, we want its result to
be based on the actual IKE retransmission behavior.
Some peers apparently don't send the notify and still expect to
authenticate with EAP-only authentication. This option allows forcing
the configured use of EAP-only authentication in that scenario.
If such a task was active while reestablishing it will get queued on the
new IKE_SA. If the DH group is already set, the DH groups won't be
stripped from the proposals and a KE payload will be sent, which is invalid
during IKE_AUTH. We don't want to reset the group if the task is part of a
child-rekey task.
Otherwise, the output is buffered when e.g. piping the output to another
command (or file). And it avoids having to call fflush() in the
interactive mode.
Fixes#3404.
SHA-3 is only automatically enabled on x86/x64. The tests are disabled
because we don't need them and they currently cause a compile warning/error
when built with clang on x64 (sizeof() on a pointer to an array). If the
examples are enabled, another test suite is built, which includes the
disabled crypto tests.
The file is usually opened/created by root, however, if user/group IDs
are configured and the configuration is reloaded, the file will be reopened
as configured user. Like with UNIX sockets we only attempt to change
the user if we have CAP_CHOWN allowing a start as regular user.
We don't have chown() on Windows, so check for it.
If cards/libraries don't support signature mechanisms with hashing, we fall
back to do it ourselves in software and pass the PKCS#1 digestInfo ASN.1
structure to sign via CKM_RSA_PKCS mechanism.
Closesstrongswan/strongswan#168.
OpenSSL currently doesn't support squeezing bytes out of an XOF multiple
times. Unfortunately, EVP_DigestFinalXOF() completely resets the context
and later calls not simply fail, they cause a null-pointer dereference in
libcrypto. This fixes the crash at the cost of repeating initializing
the whole state and allocating too much data for subsequent calls.
There is an open issue and PR that might add a function that allows
squeezing more data from an XOF in a future version of OpenSSL.
strtol(3) accepts values in the range of [LONG_MIN;LONG_MAX]. Based
on the architecture (32 or 64 bits), these values expand to either
0x8000000000000000/0x7fffffffffffffff for 64-bit builds, or
0x80000000/0x7fffffff for 32-bit builds.
The behavior when retrieving non-default values for charon.spi_min or
charon.spi_max, for example, depends on the architecture of the target
platform. While 0xC000001/0xCFFFFFFE work fine on a 64-bit build, on a
32-bit build, due to the use of strtol(3), an ERANGE causes get_int()
to return the default values.
By using strtoul(3) the default is only returned if the input value
exceeds 32 or 64 bits, based on the platform. Negative values are still
parsed correctly.
Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
Implements simpler routes for passthrough policies on Linux, which
basically act as fallbacks on routes in other routing tables. This way
they require less information (e.g. no interface or source IP) and can
be installed earlier and are not affected by updates.
Closes strongswan/strongswan#165.
Fixes#3118.
Enables us to ignore any future kernel features for routes unless
we actually need to consider them for the source IP routes.
Also enables us to actually really skip IPsec processing for those networks
(because even the routes don't touch those packets). It's more what
users expect.
Co-authored-by: Tobias Brunner <tobias@strongswan.org>
This is mainly an issue on FreeBSD where the current kernel still only
allows the daemon to use reqids < IPSEC_MANUAL_REQID_MAX (0x3fff = 16383).
Fixes#2315.
Charon refuses to make use of algorithms IDs from the private space
for unknown peer implementations [1]. If you chose to ignore and violate
that section of the RFC since you *know* your peers *must* support those
private IDs, there's no way to disable that behavior.
With this commit a strongswan.conf option is introduced which allows to
deliberately ignore parts of section 3.12 from the standard.
[1] http://tools.ietf.org/html/rfc7296#section-3.12
Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
Doing this for the self-signed check also (i.e. if this and issuer are
the same) is particularly useful if the issuer uses a different key type.
Otherwise, we'd try to verify the signature with an incompatible key
that would result in a log message.
Fixes#3357.
With these changes we return the lifetimes of the actually selected
transform back to the client, which is an issue if the peer uses
different lifetimes for different proposals. We now also return the
correct transform and proposal IDs.
Fixes#3329.
Previously, we simply used the lifetimes of the first
proposal/transform, which is not correct if the initiator uses different
lifetimes in its proposals/transforms.
If an IKE_SA is terminated while a task is active, the delete task is
simply queued (unless the deletion is forced). If the active task times
out before any optional timeout associated with the termination hits, the
IKE_SA previously was reestablished without considering the termination
request.
Fixes#3335.
These Debian package sources have not been updated for years and are
severely out-of-date. Since the Debian packages are properly
maintained nowadays, we don't have to provide our own package sources
to serve as examples.
References #3344.
Also makes it configurable via configure script. Depending on `$datadir` is
not ideal as package maintainers might set that to a custom value. Depending
on `$datarootdir` might have been better, the default if pkg-config fails is
now based on that.
References #3339.
Makes the client's IKE identity configurable in the NM GUI. For PSK
authentication the identity is now configured via that new field
and not the username anymore (old configs still work and are migrated
when edited). The client identity now also defaults to the IP address
if not configured when using EAP/PSK.
Fixes#2581.
With these changes, the NM service should be able to handle
reauthentication (and redirection) by switching to the new IKE_SA and
not considering the old SA going down an error.
Fixes#852.
Adds support for EAP-TLS to the NM plugin. The certificates/key
source (file, smartcard, agent) can now be selected independently of
the authentication method (i.e. for both certificate and EAP-TLS auth).
Fixes#2097.
The code is structured similar to that in the Android client, but two-round
authentication (cert+EAP) is not supported as that might require multiple
secrets ("password" is currently the only secret field used for every
method) and other details are currently missing too (like configurable
client identities).
This adds an optional field to the NM plugin to configure the server
identity, so it can differ from the address or certificate subject,
which are used by default.
It also updates the Glade file to GTK+ 3.2.
Closesstrongswan/strongswan#57.
The libiptc meta-package apparently will be removed e.g. from Debian.
We currently only need IPv4 support in the connmark and forecast plugins.
Fixes#3338.
This reverts commit d450e926de.
Was fixed by making tox depend on newer versions of six so the package
gets installed/updated automatically now when installing tox. There is
also some ongoing work that tries to make virtualenv work with older
versions of six.
Bash is not installed on the FreeBSD images here and the location would
be different anyway (`/usr/local/bin/bash`, so we'd have to change the
hashbang to e.g. `/usr/bin/env bash`).
There are a ton of libsoup/GLib-related "leaks" that we can't whitelist
and with leak detective active there is a delay that interestingly doesn't
happen with soup_session_sync_new(), so tests failed with a timeout (actually
they hung due to the lock in the fetcher manager).
On Travis, the curl plugin is used for the tests, so that's not an issue
there (and without LD the tests complete quickly and successfully).
As noted in 8ea13bbc5c newer compilers might optimize out the
assignment leading to invalid values in the keyUsage extension (as the
length was still set, the extension was encoded, just not with the
intended values).
Fixes#3249.
The build system is a bit limited, only the repository directory and
LGTM_WORKSPACE is writable. sudo doesn't work at all, for others we
don't have enough permission.
While it's unlikely that so many (large) items are allocated, this is
technically more correct. The result previously could overflow an
unsigned int (the conversion to size_t happened afterwards).
This clearly never was correct, but didn't cause problems so far.
However, GCC 10 will default to `-fno-common` instead of
`-fcommon` (https://gcc.gnu.org/PR85678), so compilation there fails
with something like:
```
libtool: link: gcc ... -o .libs/swanctl ...
ld: commands/load_authorities.o:strongswan/src/swanctl/./swanctl.h:33:
multiple definition of `swanctl_dir'; commands/load_all.o:strongswan/src/swanctl/./swanctl.h:33: first defined here
```
Fixes: 501bd53a6c ("swanctl: Make credential directories relative to swanctl.conf")
Closesstrongswan/strongswan#163.
GCC 9+ and clang 4+ (partially) optimize out usages of
chunk_from_chars() if the value is read outside of the block where the
macro is used. For instance:
```
chunk_t chunk = chunk_empty;
if (...)
{
chunk = chunk_from_chars(0x01, 0x06);
}
/* do something with chunk */
```
The chunk_from_chars() macro expands to a chunk_t declaration, which is
technically only defined inside that block.
Still, with older GCC versions the fourth line was compiled to something
like this:
```
mov WORD PTR [rsp+14], 1537 # 0x0106 in little-endian
lea rdx, [rsp+14]
mov ecx, 2
```
However, with GCC 9.1 and -O2 the first instruction might be omitted
(strangely the others usually were not, so the chunk pointed to whatever
was stored on the stack). It's not easily reproducible, so there are
situations where the seemingly identical code is not optimized in this
way.
This query should detect such problematic uses of the macro (definition
and usage in different blocks).
References #3249.
IBM Z is big-endian, IBM Power runs in little-endian mode.
Botan requires a fix for issues with GCC and amalgamation enabled (target
pragma ‘*’ is invalid) on ARM64 and IBM Power, while wolfSSL can't be
compiled successfully on IBM Z without an additional patch.
libunwind is not available for x390x, but since we explicitly disable
such backtraces it's not necessary anyway.
This is the recommended location and import config as it allows running the
tests against installed versions of the package. And while the test file
itself is automatically included in the source distribution this way, the
__init__.py file is not, so we still have to update MANIFEST.in.
This reverts commit 1806ba0890 as the
workaround is not required anymore and now actually fails because
pre-installed tools have a dependency on libtool.
While the TPM expects and returns the data in big-endian, the SAPI
implementation converts it to native-endianness. As stated in the
SAPI specification (section 3.2):
8. All SAPI data SHALL be in native-endian format. This means that
the SAPI implementation will do any endian conversion required for
both inputs and outputs.
So to use the exponent in a chunk we have to convert it to big-endian again.
Fixes: 7533cedb9a ("libtpmtss: Read RSA public key exponent instead of assuming its value")
RFC 7296, section 2.21.3:
If a peer parsing a request notices that it is badly formatted (after
it has passed the message authentication code checks and window
checks) and it returns an INVALID_SYNTAX notification, then this
error notification is considered fatal in both peers, meaning that
the IKE SA is deleted without needing an explicit Delete payload.
RFC 7296, section 2.21.3:
If a peer parsing a request notices that it is badly formatted (after
it has passed the message authentication code checks and window
checks) and it returns an INVALID_SYNTAX notification, then this
error notification is considered fatal in both peers, meaning that
the IKE SA is deleted without needing an explicit Delete payload.
While the check probably made sense when strongSwan 4.x was started, gperf
version 3.0.1 was released in 2003, so it's very unlikely that version 2.x
is still around anywhere.
When building from a tarball gperf is not required as the generated
files already exist, however, when building from the repository that's
not the case, so warn the user if gperf is not found.
This happened when installing a duplicate bypass policy for a locally
connected subnet. The destructor and the kernel-net part already
handle this correctly.
Without this we only would learn that the algorithm isn't actually
available (e.g. due to FIPS mode) when set_key() is called later, so there
isn't any automatic fallback to other implementations.
Fixes#3284.
This adds a new constraint for vici/swanctl.conf that enforces that the
certificate chain of the remote peer contains a CA certificate with a
specific identity.
This is similar to the existing CA constraints, but doesn't require that
the CA certificate is locally installed, for instance, intermediate CA
certificates received by the peers.
Wildcard identity matching (e.g. "..., OU=Research, CN=*") could also be
used for the latter, but requires trust in the intermediate CA to only
issue certificates with legitimate subject DNs (e.g. the "Sales" CA must
not issue certificates with "OU=Research"). With the new constraint
that's not necessary as long as a path length constraint prevents
intermediate CAs from issuing further intermediate CAs.
This is a prominent example where the identity based CA constraint is
benefical. While the description of the test claims a strict binding
of the client to the intermediate CA, this is not fully true if CA operators
are not fully trusted: A rogue OU=Sales intermediate may issue certificates
containing a OU=Research.
By binding the connection to the CA, we can avoid this, and using the identity
based constraint still allows moon to receive the intermediate over IKE
or hash-and-url.
Enforcing CA based constraints previously required the CA certificate file
to be locally installed. This is problematic from a maintencance perspective
when having many intermediate CAs, and is actually redundant if the client
sends its intermediate cert in the request.
The alternative was to use Distinguished Name matching in the subject
identity to indirectly check for the issuing CA by some RDN field, such as OU.
However, this requires trust in the intermediate CA to issue only certificates
with legitime subject identities.
This new approach checks for an intermediate CA by comparing the issuing
identity. This does not require trust in the intermediate, as long as
a path len constraint prevents that intermediate to issue further
intermediate certificates.
This makes sure the nonce sent in an OCSP request is contained in the
response (it also fixes parsing the nonce, which didn't matter so far
as it was never used)
Adds support to send intermediate CA certificates in hash-and-URL
encoding. For that it moves the generation of URLs from the config
backends to the ike-cert-post task.
Fixes#3234.
This avoids having to register certificates with authority/ca backends
beforehand, which is tricky for intermediate CA certificates loaded
themselves via authority/ca sections. On the other hand, the form of
these URLs can't be determined by config backends anymore (not an issue
for the two current implementations, no idea if custom implementations
ever made use of that possibility). If that became necessary, we could
perhaps pass the certificate to the CDP enumerator or add a new method
to the credential_set_t interface.
Adds a compile check the number of enum strings and updates several of
these lists, in particular, the one in the pfkey-kernel plugin, where
strings for several new extensions on FreeBSD were missing.
Fixes#3210.
Don't define structs for macOS as we don't need them (that's true for
most of the others too, though) and at least one is defined inside an extra
ifdef.
If strings are missing (e.g. because the last value of a range changed
unknowingly or adding a string was simply forgotten) compilation will
now fail.
This could be problematic if the upper limit is out of our control (e.g.
from a system header like pfkeyv2.h), in which case patches might be
required on certain platforms (enforcing at least, and not exactly, the
required number of strings might also be an option to compile against
older versions of such a header - for internal enums it's obviously
better to enforce an exact match, though).
If a CHILD_SA is terminated, the updown event is triggered after the
CHILD_SA is set to state CHILD_DELETED, so no usage stats or detail
information like SPIs were reported. However, when an IKEv2 SA is
terminated, the updown event for its children is triggered without
changing the state first, that is, they usually remain in state
INSTALLED and detailed data was reported in the event. IKEv1
CHILD_SAs are always terminated individually, i.e. with state
change and no extra data so far.
With this change usage stats are also returned for individually deleted
CHILD_SAs as long as the SA has not yet expired.
Fixes#3198.
Many of the messages sent by the kernel, including confirmations to our
requests, are sent as broadcasts to all PF_KEY sockets. So if an
external tool is used to manage SAs/policies (e.g. unrelated to IPsec)
the receive buffer might be filled, resulting in errors like these:
error sending to PF_KEY socket: No buffer space available
To avoid this, just clear the buffer before sending any message.
Fixes#3225.
This uses flags for proposal selection and cloning that control
whether DH groups and algorithms from a private range are skipped, and
for selection whether configured or supplied proposals/algorithms are
preferred.
This avoids having to call strip_dh() in child_cfg_t::get_proposals().
It also inverts the ALLOW_PRIVATE flag (i.e. makes it SKIP_PRIVATE) so
nothing has to be supplied to clone complete proposals.
During proposal selection with ike/child_cfgs a couple of boolean
variables can be set (e.g. private, prefer_self, strip_dh). To simplify
the addition of new parameters, these functions now use a set of flags
instead of indiviual boolean values.
Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
Address enumeration on Linux now ignores deprecated addresses and
whether temporary or permanent IPv6 addresses are included now depends
on the charon.prefer_temporary_addrs setting.
Closes#3192.
Our own implementation ignores NULL values, however, explicit_bzero()
can't handle that, as indicated by the `__nonnull ((1))` attribute in the
function's signature in string.h, and causes a segmentation fault. This
was noticed in one of the unit tests for NewHope. Since we usually use
memwipe() via chunk_clear(), which already ignores NULL pointers, this
is not that much of an issue in practice.
Fixes: 149d1bbb05 ("memory: Use explicit_bzero() as memwipe() if available")
Do two full build tests on 16.04 (xenial) and the two for OpenSSL 1.0
also run there. Since 18.04 ships OpenSSL 1.1.1, which conflicts with
our custom built version, we skip that until OpenSSL 3.0 is released.
A workaround is required for an issue with sonarqube on bionic.
The behavior is undefined if this happens (RFC 7296, section 2.13).
Instead of switching to the non-counter mode, or letting the counter
wrap, this makes it clear that the usage was not as intended.
Makes the local identity configurable and includes a fix for Android 10,
plus a break-before-make reauth issue (not Android specific) and some
deprecation workarounds.
This also includes a fix for Android 10 and some older fixes for
API level 28 compatibility and a crash on Huawei devices. The API
used to detect network changes is also replaced on newer Android
versions and an issue with DELETES received during break-before-make
reauthentication is also fixed.
There seem to be servers around that, upon receiving a delete from the
client, instead of responding with an empty INFORMATIONAL, send a delete
themselves.
It was deprecated in API level 28, registerNetworkCallback is available
since API level 21, but ConnectivityManager got some updates with 24
(e.g. default network handling) so we start using it then.
Android 10 will honor the preselection and could, thus, hide some
installed certificates if we only pass "RSA". The dialog will also only
be shown if there are actually certificates installed (i.e. users will
have to do that manually outside of the app or via profile import).
Fixes#3196.
This replaces the drop-down box to select certificate identities with a
text field (in the advanced settings) with auto-completion for SANs
contained in the certificate.
The field is always shown and allows using an IKE identity different from
the username for EAP authentication (e.g. to configure a more complete
identity to select a specific config on the server).
Fixes#3134.
This patch adds passing the ESN flag to the kernel if ESN was negotiated
and the appropriate flag is present in the kernel headers, which will
be the case in future FreeBSD releases.
Signed-off-by: Patryk Duda <pdk@semihalf.com>
Closesstrongswan/strongswan#155.
The unique names were introduced for the list-sas command in commit
04c0219e55. However, the child-updown
event wasn't updated to match. Even though the documentation suggests
that the section name of the CHILD_SAs are the same in both messages.
The original name is already being returned in the "name" attribute,
so it'll still be available.
Example:
>>> import vici, json
>>> s = vici.Session()
# First, for comparison, the list-sas command:
>>> print(json.dumps(list(s.list_sas()), sort_keys=True, indent=4, separators=(',', ': ')))
[
{
"vti0": {
"child-sas": {
"vti0-1": {
...
# A child-updown event before the change:
>>> for x in s.listen(["child-updown"]): print(json.dumps(x, sort_keys=True, indent=4, separators=(',', ': ')))
[
"child-updown",
{
"vti0": {
"child-sas": {
"vti0": { # <-- wrong: inconsistent with list-sas
...
# A child-updown event after the change:
>>> s = vici.Session()
>>> for x in s.listen(["child-updown"]): print(json.dumps(x, sort_keys=True, indent=4, separators=(',', ': ')))
[
"child-updown",
{
"vti0": {
"child-sas": {
"vti0-1": { # <-- fixed
Closesstrongswan/strongswan#153.
Resolves conflicts with building against wolfSSL when
`--enable-opensslextra` is set, namely the `WOLFSSL_HMAC_H_`,
`RNG` and `ASN1_*` name conflicts.
Closesstrongswan/strongswan#151.
According to the documentation, it's generally not necessary to manually
seed OpenSSL's DRBG (and it actually can cause the daemon to lock up
during start up on systems with low entropy if OpenSSL is already trying
to seed it itself and holds the lock). While that might already have been
the case with earlier versions, it's not explicitly stated in their
documentation. So we keep the code for these versions.
Since D-Bus 1.9.18 configuration files installed by third-party should
go in share/dbus-1/system.d. The old location is for sysadmin overrides.
Closesstrongswan/strongswan#150.
As specified by RFC 7296, section 2.6, the data associated with COOKIE
notifications MUST be between 1 and 64 octets in length (inclusive).
Fixes#3160.
The compiler complains that "taking address of packed member ... of
class or structure 'ip6_hdr' may result in an unaligned pointer value".
We don't care if the address is aligned as we explicitly use untoh16()
to convert the read value.
BSD make only evaluates $< for implicit rules, so building from the
repository won't work unless GNU make is installed and used, or we
replace affected uses like this.
No idea when exactly this happens but on many Huawei devices (and
only on them) it seems that onStartListening is sometimes called after
onDestroy i.e. when the database was already closed. This caused an
InvalidStateException in getProfile via updateTile when retrieving the
current profile. It's possible that it happens during shutdown (there
have been similar reports related to TileService implementations) so
users might not even notice, but it pollutes the Play Console, so this
workaround now makes sure the database is open when updateTile is called.
When missing gperf, the redirection generates an empty file, which must
be manually removed after gperf has been installed. This is difficult
to diagnose, as the produced build error is cryptic.
Use --output-file of gperf instead to avoid creating an empty file if
gperf is missing. This still requires the user to re-run ./configure
after installing gperf, though.
Compiling with GCC 9.1, as e.g. happens on AppVeyor, results in the
following warning:
asn1/asn1.c: In function 'asn1_integer':
asn1/asn1.c:871:24: error: '<Ucb40>' may be used uninitialized in this function [-Werror=maybe-uninitialized]
871 | len = content.len + ((*content.ptr & 0x80) ? 1 : 0);
| ^~~~~~~~~~~~
Some experiments showed that the problem was the chunk_from_chars()
assignment. This might be because the temporary chunk_t that was assigned
to the variable was defined in a sub-block, so it might actually be
undefined later when *content.ptr is read.
This allows using the certificate, which is technically a CA cert, as
end-entity certificate again after the RFC4945-related changes added
with 5.6.3.
Fixes#3139.
It's currently not possible to configure our indentation scheme for
continuation lines (i.e. use 1-3 spaces to align with the upper line).
There is an issue open regarding this, see [1]. So we can't run e.g.
eclint over our codebase to detect issues without getting a lot of
false positives.
The main trigger was that this sets the preferred tab width in GitHub's
code browser.
[1] https://github.com/editorconfig/editorconfig/issues/323
References #3111.
Each private key object created to access a key residing in a TPM 2.0
creates a context structure used for communication with the TSS.
When multiple IKE SAs are established at the same time and using the
same private key, it is possible to make concurrent calls to the
TSS with the same context which results in multiple threads writing
to the same place in memory causing undefined behaviour.
Fix this by protecting calls to the TSS with a mutex unique for
each TPM 2.0 context object.
By default, charon and its derivatives internally handle the SIGSEGV,
SIGILL, and SIGBUS signals raised by threads (segv_handler). Add a compile
option so that the signal handling can optionally be done externally.
Closesstrongswan/strongswan#132.
If CHILD_SAs are created while waiting for the third QM message we'd not
notice the redundancy and updown events would be triggered unevenly.
This is consistent with the behavior on the initiator, which already does
this check right before installation. Moving the existing check is not
possible due to the narrow hook and moving the installation changes which
peer installs the SAs first and could have other side-effects (e.g. in
error or conflict cases). Still, this might result in CHILD_SA state
discrepancies between the two peers.
Fixes#3060.
If the key type was specified but the ID was NULL or matched a subject, it
was possible that a certificate was returned that didn't actually match
the requested key type.
Closesstrongswan/strongswan#141.
Adds a script to generate the keys and certificates used for regression
tests dynamically. They are built with the pki version installed in the
root image so it's not necessary to have an up-to-date version with all
required plugins installed on the host system.
This does not modify the root image but uses the strongSwan version
installed there (avoids build dependencies on version installed on the
host to use pki to generate all the keys and certificates).
Checking specifically for /proc/net/pfkey is not ideal as af_key will
eventually be removed in Linux kernels. Support for KLIPS is long gone.
The detection also wasn't used for anything anymore (failures were just
ignored since the ports to BSD-based systems). And modprobing doesn't seem
to be necessary either (charon-systemd doesn't do that, for instance).
Usually, changing this won't be necessary (actually, some plugins
specifically use different DRGBs for RNG_WEAK in order to separate
the public nonces from random data used for e.g. DH).
But for experts with special plugin configurations this might be
more flexible and avoids code changes.
Updates the command wrappers in all the bindings and simplifies calling
new commands (i.e. not yet wrapped) with the Python and Ruby bindings.
Fixes#3028.
Also expose a method to call arbitrary commands, which allows calling not
yet wrapped commands. Exceptions are raised for all commands if the response
includes a negative "success" key (similar to how it's done in the Python
bindings).
Adds support for childless initiation of IKE_SAs (RFC 6023) e.g. to
force a separate DH exchange for all CHILD_SAs including the first one.
Also allows the initiation of only the IKE_SA via swanctl --initiate if
the peer supports this extension.
Closesstrongswan/strongswan#99.
Luckily, the type is only used once when generating payloads and there it
doesn't matter because the encoding rules are the same.
Closesstrongswan/strongswan#135.
While the alias is available after enabling the unit, we don't
actually do that in our testing environment (adding a symlink manually
would work too, then again, why not just use the proper name?).
Use strongswan-starter for the legacy unit and simply strongswan for the
modern one (strongswan-swanctl is configured as alias, which should
cause the installation of symlinks when the service is enabled via
systemctl).
Check for wolfssl/options.h because if it isn't included, checking other
headers will trigger a warning about hardening the wolfSSL build, which
will cause the check to fail with -Werror.
If the file doesn't exist because user_settings.h is used, the check may
be skipped by configuring with `ac_cv_header_wolfssl_options_h=yes`.
The main fixes are
* the generation of fingerprints for RSA, ECDSA, and EdDSA
* the encoding of ECDSA private keys
* calculating p and q for RSA private keys
* deriving the public key for raw Ed25519 private keys
Also, instead of numeric literals for buffer lengths ASN.1 related
constants are used.
Instead of assuming passwords are simply ASCII-encoded we now assume they are
provided UTF-8-encoded, which is quite likely nowadays. The UTF-8 byte
sequences are not validated, however, only valid code points are encoded
as UTF-16LE.
Fixes#3014.
Previously, the initiator would install the SA in transport mode if the
peer sent back the USE_TRANSPORT_MODE notify, even if that was not
requested originally.
The only messages that are generally sent encrypted but could be sent
unencrypted are INFORMATIONALs (currently only used for IKEv1 and ME
connectivity checks). This should prevent issues if the keymat_t behaves
incorrectly and does not return an aead_t when it actually should.
Might be useful for users of other daemons too. Note that compared to the
previous implementation in charon-tkm, the mask/label are applied in
network order.
Closesstrongswan/strongswan#134.
Previously, attributes in an incorrectly sent CFG_REPLY would still be passed
to attribute handlers. This does not prevent handlers from receiving
unrequested attributes if they requested at least one other.
This adds support for XFRM interfaces, which replace VTI devices and are
available with 4.19+ Linux kernels.
IPsec SAs and policies are associated with such interfaces via interface
IDs that can be configured on the CHILD_SA-level (dynamic IDs may
optionally be allocated for each instance and even direction) or on the
IKE_SA-level (again, dynamic IDs may be optionally allocated per IKE_SA).
IDs on an IKE_SA are inherited by all CHILD_SAs created under it, unless
the child configuration overrides them.
The effect the interface ID has on policies is similar to that of marks,
i.e. they won't match packets unless they are routed via interface with
matching interface ID. So it's possible to negotiate e.g. 0.0.0.0/0 as
traffic selector on both sides and then control the affected traffic via
routes/firewall.
It's possible to use separate interfaces for in- and outbound traffic (or
only use an interface in one direction and regular policies in the other).
Since iproute2 does not yet support XFRM interfaces, a small utility is
provided that allows creating and listing XFRM interfaces.
Interfaces may be created dynamically via updown/vici scripts or
statically (before or after establishing the SAs). Routes must be added
manually as needed (the daemon will not install any routes for outbound
policies with an interface ID).
When moving XFRM interfaces to other network namespaces they retain access
to the SAs and policies created in the original namespace, which allows
providing IPsec tunnels for processes in other network namespaces without
giving them access to the IPsec keys or IKE credentials.
Fixes#2845.
This is mainly to see what's necessary to create them (in case we
integrate this into the daemon) and to experiment in our testing
environment without having to add a patched version of iproute2 (the
4.20.0 version in stretch-backports doesn't support XFRM interfaces
yet). The regular version of iproute2 can be used for other operations
with these interfaces (delete, up, addrs etc.).
The PB-TNC finite state machine according to section 3.2 of RFC 5793
was not correctly implemented when sending either a CRETRY or SRETRY
batch. These batches can only be sent in the "Decided" state and a
CRETRY batch can immediately carry all messages usually transported
by a CDATA batch. strongSwan currently is not able to send a SRETRY
batch since full-duplex mode for PT-TLS isn't supported yet.
The bits not written to are marked tainted by valgrind, don't print
them in the debug messages. Also use more specific printf-specifiers
for other values.
There was a race condition between install() and uninstall()
where one thread was in the process of installing a trap
entry, and had destroyed the child_sa, while the other
thread was uninstalling the same trap entry and ended up
trying to destroy the already destroyed child_sa, resulting
in a segmentation fault in the destroy_entry() function.
The uninstall() function needs to wait until all the threads
are done with the installing before proceeding to uninstall
a trap entry.
Closesstrongswan/strongswan#131.
This can be the case for IKEv1 since 419ae9a20a ("ikev1: Default remote
identity to %any for PSK lookup if not configured").
Closesstrongswan/strongswan#128.
This seems to avoid broadcast loops (i.e. processing and reinjecting the
same broadcast packet over and over again) as the packets we send via
AF_PACKET socket are neither marked nor from that interface.
In order to avoid that the kernel uses virtual tunnel IPs for traffic
over physical interfaces we previously deprecated the virtual IP. While
this is working it is not ideal. This patch adds address labels for
virtual IPs, which should force the kernel to avoid such addresses to
reach any destination unless there is an explicit route that uses it as
source address.
Using parse_time() directly actually overwrites the next member in the
child_cfg_create_t struct, which is start_action, which can cause
incorrect configs if inactivity is parsed after start_action.
Fixes#2954.
Some users requests something like that to use different server IPs.
Interestingly, it's actually also possible to configure multiple
hostnames/IPs, separated by commas, as server address in the profile, which
are then tried one after another.
It's also useful when testing stuff to quickly compare the behavior with
some setting changed between two otherwise identical profiles.
A temporary DROP policy is added to avoid traffic leak
while the SA is being updated. It is added with
manual_prio set but when the temporary policy is removed
it is removed with manual_prio parameter set to 0.
The call to del_policies_outbound does not match the original
policy and we end up with an ever increasing refcount.
If we try to manually remove the policy, it is not removed
due to the positive refcount. Then new SA requests fail with
"unable to install policy out for reqid 1618,
the same policy for reqid 1528 exists"
Fixes: 35ef1b032d ("child-sa: Install drop policies while updating IPsec SAs and policies")
Closesstrongswan/strongswan#129.
Instead, create a socket when necessary. Apparently, it can prevent
the agent from getting terminated (e.g. during system shutdown) if e.g.
charon-nm is still running with an open connection to the agent.
In 7b7290977 ("controller: Add option to force destruction of an IKE_SA")
the 'force' option was added as 3rd parameter to controller_t::terminate_ike.
However in vici's 'clear_start_action', the argument was incorrectly
placed as the 2nd parameter - constantly sending 0 (FALSE) as the
'unique_id' to terminate, rendering calls to 'handle_start_actions'
having undo=TRUE being unable to terminate the relevant conn.
For example, this is log of such a bogus 'unload-conn':
strongswan[498]: 13[CFG] vici client 96 requests: unload-conn
strongswan[498]: 13[CFG] closing IKE_SA #9
strongswan[498]: 13[IKE] unable to terminate IKE_SA: ID 0 not found
strongswan[498]: 09[CFG] vici client 96 disconnected
here, the unloaded conn's IKE id was 9, alas 'terminate_ike_execute'
reports failure to terminate "ID 0".
Fix by passing 'id, FALSE' arguments in the correct order.
Fixes: 7b7290977 ("controller: Add option to force destruction of an IKE_SA")
Signed-off-by: Shmulik Ladkani <shmulik@metanetworks.com>
Closesstrongswan/strongswan#127.
Up to now it was assumed that the RSA public key exponent is equal to 2^16+1.
Although this is probably true in most if not all cases, it is not correct
according to the TPM 2.0 specification.
This patch fixes that by reading the exponent from the structure returned
by TPM2_ReadPublic.
Closesstrongswan/strongswan#121.
Adds all IPs to RADIUS Accounting-Stop messages even those not claimed by
a client. For instance, if the connection fails with FAILED_CP_REQUIRED,
adding the unclaimed addresses allows the RADIUS server to release the
leases early.
Fixes#2856.
All directories are now considered relative to the loaded swanctl.conf
file, in particular, when loading it from a custom location via --file
argument. The base directory, which is used if no custom location for
swanctl.conf is specified, is now also configurable at runtime via
SWANCTL_DIR environment variable.
Closesstrongswan/strongswan#120.
The functional reference created by ENGINE_init() was never released,
only the structural one created by ENGINE_by_id(). The functional
reference includes an implicit structural reference, which is also
released by ENGINE_finish().
Closesstrongswan/strongswan#119.
Makes sure to adopt active and queued Quick Mode tasks if the peer
reauthenticates the IKE_SA while creating lots of CHILD_SAs.
Closesstrongswan/strongswan#117.
This is particularly important for higher number of segments, but even
with small numbers there is a significant difference. For instance,
with 4 segments the fourth segment had no IPs assigned with the old
code, no matter how large the pool, because none of the eight bits used
for the segment check hashed/mapped to it.
Upcoming versions of FreeBSD will include an SADB_X_EXT_SA2 extension in
acquires that contains the reqid set on the matching policy. This allows
handling acquires even when no policies are installed (e.g. to work with
FreeBSD's implementation of VTI interfaces, which manage policies
themselves).
Same issue with signature malleability as with Ed25519 and apparently
OpenSSL doesn't even explicitly verify that the most significant 10 bits
are all zero.
As per RFC 8032, section 5.1.7 (and section 8.4) we have to make sure s, which
is the scalar in the second half of the signature value, is smaller than L.
Without that check, L can be added to most signatures at least once to create
another valid signature for the same public key and message.
This could be problematic if, for instance, a blacklist is based on hashes
of certificates. A new certificate could be created with a different
signature (without knowing the signature key) by simply adding L to s.
Currently, both OpenSSL 1.1.1 and Botan 2.8.0 are vulnerable to this, which is
why the unit test currently only warns about it.
OpenSSL 1.1.1 introduces DRGBs and provides two sources (same security
profile etc. but separate internal state), which allows us to use one for
RNG_WEAK (e.g. for nonces that are directly publicly visible) and the other
for stronger random data like keys.
While X25519 was already added with 1.1.0a, its use would be a lot more
complicated, as the helpers like EVP_PKEY_new_raw_public_key() were only
added in 1.1.1, which also added X448.
In case a subnet is moved from one interface to another the policies can
remain as is but the route has to change. This currently doesn't happen
automatically and there is no option to update the policy or route so
removing and reinstalling the policies is the only option.
Fixes#2820.
The peer might not have seen the CREATE_CHILD_SA response yet, receiving a
DELETE for the SA could then trigger it to abort the rekeying, causing
the deletion of the newly established SA (it can't know whether the
DELETE was sent due to an expire or because the user manually deleted
it). We just treat this SA as if we received a DELETE for it. This is
not an ideal situation anyway, as it causes some traffic to get dropped,
so it should usually be avoided by setting appropriate soft and hard limits.
References #2815.
Because the file is not available on all platforms the inclusion comes
after the user options in order to disable including it. But that means
the inclusion also follows after the defined scanner states, which are
generated as simple #defines to numbers. If the included unistd.h e.g.
uses variables in function definitions with the same names this could
result in compilation errors.
Interactive mode has to be disabled too as it relies on isatty() from
unistd.h. Since we don't use the scanners interactively, this is not a
problem and might even make the scanners a bit faster.
Fixes#2806.
The sonarcloud build runs a long time now (the win32/64 builds are also
a lot slower on xenial), which increases the overall time a build takes
because we can't run these before regular matrix jobs run. So we do a
manual matrix expansion to control the order of jobs (slower first).
This also removes the TEST=default build with GCC as that's basically
what TEST=dist does (except for forcing the printf implementation)
On Nov 12, the scanner was updated and now takes a lot more time (about
3 times as much). Using two threads reduces it a bit (by about 25%).
Using even more threads doesn't help or even increases the time again.
The automatically determined path for systemd units is an absolute system
path that doesn't respect $(prefix). That's a problem for make distcheck,
which is usually ran as regular user and it's not expected to have any
impact on the system (it does a local install in a subdir). To avoid
these issues we override the configure flags used by make distcheck and
set the path to one relative to the specified prefix.
According to gcrypt.h these callbacks are not used anymore since
version 1.6 and with clang these actually cause deprecation warnings
that let the build on travis (-Werror) fail.
This installs tmux and its two dependencies libevent-2.0-5 and libutempter0.
For the tnc/tnccs-20-ev-pt-tls test scenario older, apparently replaced
versions of these packages are entered to the collector.db database, so that
dummy SWID tags for these packages can be requested via SWIMA.
Also includes some changes for jessie's version of FreeRADIUS 2 (was
previously a custom version).
Besides the move to a subdir the config files were adapted for 3.0.
The rlm_sim_files module was removed with FreeRADIUS 3 and Debian's
package of FreeRADIUS 2 does not ship it, so we now replicate it using
the files module (via users file, which is actually a symlink to
mods-config/files/authorize in the default installation of FreeRADIUS 3).
Another approach was tried using rlm_passwd, however, that module does
not read binary/hex data, only printable strings, which would require
changing the triplets.
For 2.x a hack in the site config is necessary to make the attributes
available to the EAP-SIM module.
Debian stretch's init script for isc-dhcp-server uses the INTERFACESv4|6
variables to decide whether to start the v4 and/or v6 DHCP server.
If they are not empty, the daemon is started for the respective version,
however, if both are empty (the default), to listen on all interfaces, the
daemon is started for both versions. The latter would require a subnet
config for IPv6 as the daemon otherwise exits, letting the init script fail,
while keeping the successfully started v4 version running, which, in turn,
can't be stopped anymore with the init script because it thinks the daemon
is not running.
So it's not possible with this init script to start DHCPv4 on all interfaces
without having to configure and run DHCPv6 also.
While we could continue to use FreeRADIUS 2.x that branch is officially EOL.
So instead of investing time and effort in updating/migrating the patches to
FreeRADIUS 3.x (the module changed quite significantly as it relies solely on
the naeap library in that release), for a protocol that is superseded anyway,
we just remove these scenarios and the dependencies. Actually, the
complete rlm_eap_tnc module will be removed with FreeRADIUS 4.0.
This is because OpenSSL 1.1 started to use atexit()-handlers of its own
to clean up. Since the plugin is loaded and initialized after libcharon,
OpenSSL's cleanup functions ran before the daemon was properly
deinitialized (i.e. worker threads were still running and OpenSSL might
still be used during the deinit). So several of OpenSSL's internal
structures were already destroyed when libcharon_deinit() was eventually
called via our own atexit()-handler.
The observed behavior was that the daemon couldn't be terminated properly
anymore for some test scenarios (only three TNC scenarios were affected
actually). When the daemon tried to send the DELETE for the established
IKE_SA during its termination it got stuck in OpenSSL's RNG_WEAK
implementation (used to allocate random padding), which apparently tries
to acquire an rwlock that was already destroyed. The main thread then
just busy-waited indefinitely on the lock, i.e. until systemd killed
it eventually after a rather long timeout.
We'll probably have to apply similar changes to other apps/scripts that
load plugins and currently use atexit() to clean up. Although some
scripts (e.g. dh_speed or hash_burn) are not affected because they
register the deinitialization after loading the plugins.
If a lot of QUICK_MODE tasks are queued and the other side
sends a DPD request, there is a good chance for timeouts.
Observed this in cases where other side is quite slow in responding
QUICK_MODE requests (e.g. Cisco ASA v8.x) and about 100 CHILD_SAs
are to be spawned.
Closesstrongswan/strongswan#115.
Checking for whitelisted functions in every backtrace is not very
efficient. And because OpenSSL 1.1 does no proper cleanup anymore until
the process is terminated there are now a lot more "leaks" to ignore.
For instance, in the openssl-ikev2/rw-cert scenario, just starting and
stopping the daemon (test vectors are checked) now causes 3594 whitelisted
leaks compared to the 849 before. This prolonged the shutdown of the
daemon on each guest in every scenario, amounting to multiple seconds of
additional runtime for every affected scenario. But even with this
patch there is still some overhead, compared to running the scenarios on
jessie.
RC4, which was previously used for performance reasons, is not supported
anymore with newer versions of SSH (stretch still supports it, but it
requires explicit configuration on the guests when they act as clients
too - the version in Ubuntu 18.04 apparently doesn't support it anymore
at all).
AES-GCM should actually be faster (at least for larger amounts of data and
in particular with hardware acceleration).
ClientAuthentication is known in OpenSSL 1.1 and the redefinition, therefore,
causes an error. These two OIDs are not used anyway in these config
files.
This adds the ability to return supported signature schemes (and
parameters) from a private key.
This is useful for keys on a TPM 2.0 as these can be used only with a
particular scheme (the hash algorithm and for RSA even the padding scheme
is fixed). For RSA with PSS padding there is an additional complication
because different TPMs use different salt lengths, which we have to know
beforehand to correctly produce e.g. a certificate request (the signature
covers the algorithm identifier that describes the signature scheme).
It turned out that the new method is also useful for the agent plugin.
Newer ssh/gpg-agents support SHA-256 and SHA-512 for RSA signatures, but
not SHA-384, which we can now convey to the pubkey authenticator.
Unfortunately, older agents ignore the flags that request a SHA2 signature
and just return one with SHA-1, in such scenarios IKEv2 signature
authentication has to be disabled.
SHA-384 is not supported but is selected by signature_schemes_for_key()
for keys between 3072 and 7680 bits.
Since this is only called for IKEv2 signature authentication we don't
even provide SHA-1 anymore. We always provide both schemes, though,
which is what pubkey-authenticator does too for RSA.
Older agents apparently just ignore the flags and always return a SHA-1
signature. If that's the case, charon.signature_authentication has to
be disabled.
On newer Android versions (8+) this does not seem to be necessary (adding
the onClick handler also sets "clickable" and that in turn seems to make
it focusable), however, for older releases it is (tested with 7.1.1
keyboard navigation just skips over the button). This was seen on a
Fire TV stick.
It looks like Android 9 incorrectly continues to use the regular DNS
servers after the blocking TUN device is replaced with the actual
interface. Setting DNS servers prevents that (since all traffic is
blocked, which ones doesn't really matter but local/loopback addresses
are rejected).
Interestingly, if the VPN server later does not assign any DNS servers, there
is no fallback to the non-VPN DNS servers for some reason (that's definitely
not as documented). This could potentially be a problem as we don't
offer an option to configure DNS servers in the VPN profile.
Neither issue is seen on older Android versions (only tested on 7.1.1).
Not sure when this happens exactly, in particular because the reported
stack traces look like this
java.lang.NullPointerException:
at org.strongswan.android.ui.VpnTileService.updateTile (VpnTileService.java:220)
at org.strongswan.android.ui.VpnTileService.onStartListening (VpnTileService.java:97)
at android.service.quicksettings.TileService$H.handleMessage (TileService.java:407)
which violates the API documentation for getQsTile(), which states:
This tile is only valid for updates between onStartListening() and
onStopListening().
But apparently that's not always the case. There have been two reports
of such a crash, both on Android 8.0 and on Xiaomi Mi 5/6 devices, so
maybe it's a bug in that particular image.
The previous code lost track of the selected profile IDs, but the
widgets maintained their state (i.e. the list item was still selected and the
edit button still enabled). Clicking the edit button then caused a crash when
trying to get the first item in the set.
The task manager for IKEv1 issues a retransmit send alert in the
retransmit_packet() function. The corresponding retransmit cleared alert
however is only issued for exchanges we initiated after processing the
response in process_response().
For quick mode exchanges we may retransmit the second packet if the peer
(the initiator) does not send the third message in a timely manner. In
this case the retransmit send alert may never be cleared.
With this patch the retransmit cleared alert is issued for packets that
were retransmitted also when we are the responding party when we receive
the outstanding response.
Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
Because `keylen` is unsigned the subtraction results in an integer
underflow if the key length is < 11 bytes.
This is only a problem when verifying signatures with a public key (for
private keys the plugin enforces a minimum modulus length) and to do so
we usually only use trusted keys. However, the x509 plugin actually
calls issued_by() on a parsed certificate to check if it is self-signed,
which is the reason this issue was found by OSS-Fuzz in the first place.
So, unfortunately, this can be triggered by sending an invalid client
cert to a peer.
Fixes: 5955db5b12 ("gmp: Don't parse PKCS1 v1.5 RSA signatures to verify them")
Fixes: CVE-2018-17540
Instead we generate the expected signature encoding and compare it to the
decrypted value.
Due to the lenient nature of the previous parsing code (minimum padding
length was not enforced, the algorithmIdentifier/OID parser accepts arbitrary
data after OIDs and in the parameters field etc.) it was susceptible to
Daniel Bleichenbacher's low-exponent attack (from 2006!), which allowed
forging signatures for keys that use low public exponents (i.e. e=3).
Since the public exponent is usually set to 0x10001 (65537) since quite a
while, the flaws in the previous code should not have had that much of a
practical impact in recent years.
Fixes: CVE-2018-16151, CVE-2018-16152
This merges all source files into botan_all.cpp, which reduces the build
time by almost 50%. Building outside the strongSwan tree avoids analyzing
Botan with sonarqube.
ldconfig is required, otherwise the library won't be found by
strongSwan in the same session.
Should later be changed to 2.8.0 or a newer stable release.
This also changes how unknown/corrupted memory is handled in the free()
and realloc() hooks in general.
Incorporates changes provided by Thomas Egerer who ran into a similar
issue.
Due to the mangled C++ function names it's tricky to be more specific. The
"leaked" allocations are from a static hashtable containing EC groups.
There is another leak caused by the locking allocator singleton
(triggered by the first function that uses it, usually initialization of
a cipher, but could be a hasher in other test runners), but we can avoid
that with a Botan config option.
Simplifies public key loading and this way unencrypted PKCS#8-encoded
keys can be loaded directly without pkcs8 plugin (code for encrypted
keys could probably later be added, if necessary).
It also simplifies the implementation of private_key_t::get_public_key()
a lot.
Without OID we can't generate an algorithmIdentifier when loading the
key again. And older versions of OpenSSL insist on a public key when
e.g. converting a key to PKCS#8.
Simply unwrapping the ECPrivateKey structure avoids log messages when
parsing other keys in the KEY_ANY case.
Support MD5 in the Botan plugin if supported by Botan.
MD5 is required for RADIUS and obviously EAP-MD5,
and also for non-PKCS#8 encoded, encrypted private keys.
Botan only allows RSA generating keys >= 1,024 bits, which makes
the RSA test suite fail. It is questionable whether it makes
sense to test 768 bit RSA keys anymore. They are too weak
from today's perspective anyway.
This requires config changes if filelog is used with a path that
contains dots. This path must now be defined in the `path` setting of an
arbitrarily named subsection of `filelog`. Without that change the
whole strongswan.conf file will fail to load, which some users might
not notice immediately.
This adds the ability to configure marks the in- and/or outbound SA
should apply to packets after processing on Linux. Configuring such a mark
for outbound SAs requires at least a 4.14 kernel. The ability to set a mask
and configuring a mark/mask for inbound SAs will be added with the upcoming
4.19 kernel.
For inbound processing, it can be rather useful to apply the mark to the
packet in the SA, so the associated policy with that mark implicitly matches.
When using %unique as match mark, we don't know the mark beforehand, so
we most likely want to set the mark we match against.
%unique (and the upcoming %same key) are usable in specific contexts only.
To restrict the user from using it in other places where it does not get the
expected results, reject such keywords unless explicitly allowed.
We don't retransmit DPD requests like we do requests for proper exchanges,
so increasing the number with each sent DPD could result in the peer's state
getting out of sync if DPDs are lost. Because according to RFC 3706, DPDs
with an unexpected sequence number SHOULD be rejected (it does mention the
possibility of maintaining a window of acceptable numbers, but we currently
don't implement that). We partially ignore such messages (i.e. we don't
update the expected sequence number and the inbound message stats, so we
might send a DPD when none is required). However, we always send a response,
so a peer won't really notice this (it also ensures a reply for "retransmits"
caused by this change, i.e. multiple DPDs with the same number - hopefully,
other implementations behave similarly when receiving such messages).
Fixes#2714.
This is mainly for HA where a passive SA was already created when the
IKE keys were derived. If e.g. an authentication error occurs later that
SA wouldn't get cleaned up.
The reload of the configuration of the loggers so far only included
the log levels. In order to support the reload of all other options,
a reload function may be implemented.
Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
Adds new options that allow configuring how/whether certain fields in
the IP headers are copied during IPsec processing. Currently only allows
configuration on Linux.
Closesstrongswan/strongswan#104.
The options control whether the DF and ECN header bits/fields are copied
from the unencrypted packets to the encrypted packets in tunnel mode (DF only
for IPv4), and for ECN whether the same is done for inbound packets.
Note: This implementation only works with Linux/Netlink/XFRM.
Based on a patch by Markus Sattler.
During a test with ~12000 established SAs it was noted that vici
related operations hung.
The operations took over 16 minutes to finish. The time was spent in
the vici message parser, which was assigning the message over and over
again, to get rid of the already parsed portions.
First fixed by cutting the consumed parts off without copying the message.
Runtime for ~12000 SAs is now around 20 seconds.
Further optimization brought the runtime down to roughly 1-2 seconds
by using an fd to read through the message variable.
Closesstrongswan/strongswan#103.
The code to support parallel Netlink queries (commit 3c7193f) made use
of nlmsg_len member from struct nlmsghdr to allocate and copy the
responses. Since NLMSG_NEXT is later used to parse these responses, they
must be aligned, or the results are undefined.
Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
For some reason the clang binary that's installed in an uncommon
directory could not be found anymore when installing packages via pip for
the last couple of builds. While the directory is obviously contained in PATH,
using `sudo -E` didn't help. So we now install the Python packages in the
user's home directory to avoid having to use sudo.
Previously, when the user supplied an ECDSA key for public key authentication,
the user was always asked to provide a password, even if the key was not
encrypted.
Related: 954f73ea6e ("charon-nm: Parse any type of private key not only RSA")
Closesstrongswan/strongswan#108.
macOS supports AES_GCM_ICV16 natively using PF_KEYv2.
This change enables AES_GCM if the corresponding definition is detected
in the headers.
With this change it is no longer necessary to use the libipsec module to
use AES_GCM on macOS.
Closesstrongswan/strongswan#107.
This reverts commit 064c97afae.
We have to make this optional and more configurable. It seems some
commercial VPN providers use self-signed certificates for their AAA
servers.
This avoids a NullPointerException on Android 8 related to the optional
Autofill functionality. The bug has been fixed in Android 8.1 [1] but there
is no fix for Android 8.
[1] https://issuetracker.google.com/issues/67675432
This is hopefully a bit more efficient for large log files than the previous
single TextView. The ListView widget also provides an auto-scroll mechanism.
Always reset the error state when disconnecting via state service. This
way the error state is also cleared when the connection is terminated
directly via control activity.
For instance, rotating a device will restart it and this previously
could have started the wrong profile or shown the system's VPN
confirmation dialog twice.
As documented, onActivityResult() is called right before onResume() when
the activity is reactivated. However, if the system's VPN confirmation
dialog is shown and the home button is pressed, the activity is stopped
and not just paused, so its state is saved. And onActivityResult() is
actually also called before onStart(). This means that no fragment
transactions may be committed (i.e. no dialog may be shown) when the
activity is later restarted (e.g. because there is another attempt to
connect the VPN) until onStart() has been called. So if we'd try to show
the error dialog in onActivityResult() after returning to the launcher
it would result in an IllegalStateException.
However, showing the dialog for the previous confirmation dialog is not
ideal anyway, so we just ignore that result.
This allows cancelling connecting if e.g. the OCSP server is not
reachable. Previously this caused some delay in disconnecting state but
even worse it cause an ANR if the user tried reconnecting during that
time as the main thread would get struck in setNextProfile() (we could
probably find a better solution there too in the future).
It's reinstalled when reconnecting (or during error recovery) and
eventually uninstalled after disconnecting.
Only on Android 5+, otherwise we'd block our fetcher (and Android 4.4 is
stupid in regards to overlapping TUN devices anyway).
Note that Android 8's blocking feature blocks everything that passes by
the VPN, so this only works when tunneling everything (i.e. neither subnets,
nor apps can be excluded from the VPN if that feature is enabled).
Otherwise, a blocking VPN interface would prevent our fetcher from working
as we currently rely on an interface that doesn't allow access to the
underlying socket/FD, which would be required to call VpnService.protect().
Removing and readding the entry to a potentially different row/segment,
while driving out waiting and new threads, could prevent threads from
acquiring the SA even if they were waiting to check it out by unique
ID (which doesn't change), or if they were just trying to enumerate it.
With this change the row and segment doesn't change anymore and waiting
threads may acquire the SA. However, those looking for an IKE_SA by SPIs
might get one back that has a different SPI (but that's probably not
something that happens very often this early).
This was noticed because we check out SAs by unique ID in the Android
app to terminate them after failed retransmits if we are not reestablishing
the SA (otherwise we continue), and this sometimes failed.
Fixes: eaedcf8c00 ("ike-sa-manager: Add method to change the initiator SPI of an IKE_SA")
The button to view the log is now below the status info. And since the
IMC results are just below that we don't need a special handling for
that anymore.
This can happen on systems (e.g. Android 7.x) where Always-on VPNs are
triggered right after booting before the KeyChain is unlocked by the user.
Retrieving the certificate chain or private key then fails with
"KeyChainException: IllegalStateException: keystore is LOCKED" until the
user unlocks the screen once.
The built-in client actually also fails in this situation (e.g. with XAuth
RSA), it tries three times then stops and shows an error notification.
With Android 8.1 this isn't triggered after a reboot until the device
has been unlocked once (solving the issue with the key store) and traffic
may optionally be blocked by the user until the VPN is established.
There are still some issues (e.g. password prompts and fatal errors), and we
might need some workaround for older Android releases.
Only if there is no currently active (or previously active) profile does
this currently operate on the configured (or stored most recently used)
profile. This way it's possible to use a different connection and
quickly disable and re-enable it again. When unlocked the profile name
is shown, when locked a generic text is used (this detection doesn't seem
to work 100% reliably). To disconnect, the user is forced to unlock the
device, connecting is possible without, if the credentials are available
and no fatal error occurs (it even works with the system credential store,
at least on Android 8.1).
Note that the tile is not available right after a reboot. It seems that
the system has to be unlocked once to activate third-party tiles (will
be interesting to see how this works together with Always-on VPN).
Unfortunately, setLockscreenVisibility() doesn't seem to have any
effect. So the full notification is shown unless the user manually
configures the notification settings.
This allows us to add tiles to Quick Settings and enabling the Always-on
VPN feature in the VPN settings (both require API level 24, but 26 will
be required as targetSdkVersion later this year).
Unless there are profiles created with old versions of the app (< 1.8.0)
that were never updated since, all profiles should already have a UUID
assigned. If not, we do that now with a DB migration.
This is either because a third-party VPN app has the always-on feature
enabled, or because the user denied the permission in the system's confirmation
dialog.
If the always-on feature is enabled for a connection of the built-in VPN
client we get an IllegalStateException, for which we show an updated and
clearer error message.
The type of the value was incorrect (void**) if NULL was passed to cas_ptr()
as expected value, which caused a compiler warning with Clang because
__atomic_compare_exchange_n() expects the types of the first two arguments
to be the same.
armeabi has been superseded by armeabi-v7a and the MIPS ABIs were removed
with the latest NDK (r17), after being marked deprecated for a while.
By not specifying APP_ABI we build for all non-deprecated ABIs.
This allows switching the originally selected IKE config (based on the
IPs and IKE version) to a different one if no matching proposal is found.
This way we don't rely that much on the order of configs anymore and it's
possible to configure separate configs for clients that require weak
algorithms.
Instead of logging the search parameters for IKE configs (which were already
before starting the lookup) we log the configured settings.
The peer config lookup is also changed slightly by doing the IKE config
match first and skipping some checks if that or the local peer identity
doesn't match.
Although being already logged on level 2, these messages are usually just
confusing if they pop up randomly in the log when e.g. querying the configs
or installing traps. So after this the log messages will only be logged when
actually proposing or selecting traffic selectors during IKE.
This way we don't rely on the order of equally matching configs as
heavily anymore (which is actually tricky in vici) and this also doesn't
require repeating weak algorithms in all configs that might potentially be
selected if there are some clients that require them.
There is currently no ordering, so an explicitly configured exactly matching
proposal isn't a better match than e.g. the default proposal that also
contains the proposed algorithms.
In some scenarios we might find multiple usable peer configs with different
IKE proposals. This is a problem if we use a config with non-matching
proposals that later causes IKE rekeying to fail. It might even be a problem
already when creating the CHILD_SA if the proposals of IKE and CHILD_SA
are consistent.
This adds the ability to reference existing sections to the settings parser.
Mainly for swanctl.conf, where this could simplify complex configs a lot
as redundant information has only to be specified once and may then be
included in other sections (there is an example in the man page and
there are some in the unit tests).
Also added is a new setting in filelog sections to specify the path of
the log file (in case it contains characters that are not allowed in section
names). We should encourage people to configure their log files that way
which might allow use to prohibit dots in section names in the future.
There was a potential chance for a race condition if the ensured section
was purged for some reason before using it later.
This also changes the behavior for NULL/empty strings via load_string*
with merge == FALSE, which now purges the config/section.
Similar to the `also` keyword in ipsec.conf, the new syntax allows adding
one or more references to other sections, which means all the settings and
subsections defined there are inherited (values may be overridden, even
with an empty value to clear it).
It's important to note that all subsections are inherited, so if this is
used to reference a connection in swanctl.conf all auth rounds and
children are inherited. There is currently no syntax to limit the
inclusion level or clear inherited sections (but as mentioned, settings
in those inherited sections may be overridden).
Another property is that inherited settings or sections always follow
explicitly defined entries in the current section when they are enumerated.
This is relevant if the order is important (e.g. for auth rounds if `round`
is not specified).
References are evaluated dynamically at runtime, so referring to
sections later in the config file or included via other files is no
problem.
The colon used as separator to reference other sections may be used in
section names by writing :: (e.g. for Windows log file paths).
This is based on a patch originally written in 2016.
This way we get early log messages during plugin loading (including
integrity check results).
Instead of the fallback we could also remove the `customlog` namespace,
which was added to avoid conflicts with other settings/sections.
This was quite confusing previously: While calling insert_before()
and then remove_at() properly replaced the current item, calling them the
other way around inserted the new item before the previous item because
remove_at() changed the enumerator's position to the previous item.
The behavior in corner cases (calling the methods before or after
enumeration) is also changed slightly.
This allows switching to probing mode if the client is on a public IP
and this is the active task and connectivity gets restored. We only add
NAT-D payloads if we are currently behind a NAT (to detect changed NAT
mappings), a MOBIKE update that might follow will add them in case we
move behind a NAT.
This is quite helpful to debug why a pattern didn't match.
As it could produce quite a lot of output if something is not found in a
log file, the complete output is only printed in verbose mode, otherwise,
`head` is used to print the first 10 lines of output.
We only get stdout from SSH, so the stderr redirection is only really
for errors ssh itself produces.
Allow charon to start as a non-root user without CAP_CHOWN and still be
able to change the group on files that need to be accessed by charon
after capabilities have been dropped. This requires the user charon starts
as to have access to socket/pidfile directory as well as belong to the
group that charon will run as after dropping capabilities.
Closesstrongswan/strongswan#105.
Stater will lose update/reload commands when there is a second signal
coming in when the previous is still processed. This can happen more
easily with big configurations.
Closesstrongswan/strongswan#101.
In case the PRF's set_key() or allocate_bytes() method failed, skeyseed
was not initialized and the chunk_clear() call later caused a crash.
This could have happened with OpenSSL in FIPS mode when MD5 was
negotiated (and test vectors were not checked, in which case the PRF
couldn't be instantiated as the test vectors would have failed).
MD5 is not included in the default proposal anymore since 5.6.1, so
with recent versions this could only happen with configs that are not
valid in FIPS mode anyway.
Fixes: CVE-2018-10811
We continue to parse them but remove the documentation because mixing the two
sets of keywords in the same config might result in unexpected behavior.
References #2663.
Adds new options to force the local destruction of an IKE_SA (after
trying to send a DELETE first). This might be useful in situations where
it's known the other end is not reachable or already deleted the IKE_SA so
there is no point in retransmitting the DELETE and waiting for a response.
The keylength fix for ChaCha20Poly1305 (5a7b0be2) removes the keylength
attribute from the AEAD transform. This breaks compatibility between
versions with the patch and those without. The ChaCha20Poly1305 AEAD
won't match in proposals between such versions, and if no other algorithm
is available, negotiating SAs fails.
As a migration strategy, this patch introduces a new string identifier for a
ChaCha20Poly1305 proposal keyword which uses the explicit keylength, exactly
as it was used before the mentioned patch. Administrators that care about
the use of that AEAD with old clients can temporarily add this keyword to
the list of proposals, until all clients have been upgraded.
The used approach is the least invasive, as it just adds an additional
keyword that can't do any harm if not explicitly configured. Nontheless
allows it the administrator to smoothly keep ChaCha20Poly1305 working,
even if upgrading all peers simultaneously is not an option. It requires
manual configuration edits, though, but we assume that ChaCha20Poly1305
is not that widely used, and not as the only transform in proposals.
Removing the compat keyword in a future version is an option; it might
be helpful for other implementations, though, that falsely use an
explicit key length in ChaCha20Poly1305 AEAD transforms.
We now check if there are other routes tracked for the same destination
and replace the installed route instead of just removing it. Same during
installation, where we previously didn't replace existing routes due to
NLM_F_EXCL. Routes with virtual IPs as source address are preferred over
routes without.
This should allow using trap policies with virtual IPs on Linux.
Fixes#85, #2162.
This fixes several issues that came up via BSI's Certification Path
Validation Test Tool (CPT):
1) In compliance with RFC 4945, section 5.1.3.2, we now enforce that a
certificate used for IKE authentication either does not contain a keyUsage
extension (like the ones produced by pki --issue) or that they include
digitalSignature or nonRepudiation.
2) CRLs that are not yet valid are now rejected as that could be a
problem in scenarios where expired certificates are removed from CRLs and
the clock on the host doing the revocation check is trailing behind that
of the host issuing CRLs.
3) Results other than revocation (e.g. a skipped check because the CRL
couldn't be fetched) are now stored also for intermediate CA certificates
and not only for end-entity certificates, so a strict CRL policy can be
enforced in such cases.
If the certificate is revoked, we immediately returned and the chain was
invalid, however, if we couldn't fetch the CRL that result was not stored
for intermediate CAs and we weren't able to enforce a strict CRL policy
later.
Using such CRLs can be a problem if the clock on the host doing the
revocation check is trailing behind that of the host issuing CRLs in
scenarios where expired certificates are removed from CRLs. As revoked
certificates that expired will then not be part of new CRLs a host with
trailing clock might still accept such a certificate if it is still
valid according to its system clock but is not contained anymore in the
not yet valid CRL.
According to RFC 4945, section 5.1.3.2, a certificate for IKE must
either not contain the keyUsage extension, or, if it does, have at least
one of the digitalSignature or nonReputiation bits set.
Fixes some issues in the dhcp plugin like avoiding ICMP port unreachables
when setting a specific server address, or increasing the maximum size for
options e.g. for DNs in the client identifier option. The latter is also
only sent now if identity_lease is enabled (for most DHCP servers it
serves the same function as a unique MAC address does).
The client identifier serves as unique identifier just like a unique MAC
address would, so even with identity_leases disabled some DHCP servers
might assign unique leases per identity.
This increases the chances that subject DNs that might have been cut
off with the arbitrary previous limit of 64 bytes might now be sent
successfully.
The REQUEST message has the most static overhead in terms of other
options (17 bytes) as compared to DISCOVER (5) and RELEASE (7).
Added to that are 3 bytes for the DHCP message type, which means we have
288 bytes left for the two options based on the client identity (host
name and client identification). Since both contain the same value, a
FQDN identity, which causes a host name option to get added, may be
142 bytes long, other identities like subject DNs may be 255 bytes
long (the maximum for a DHCP option).
According to RFC 2131, the minimum size of the 'options' field is 312
bytes, including the 4 byte magic cookie. There also does not seem to
be any restriction regarding the message length, previously the length
was rounded to a multiple of 64 bytes. The latter might have been
because in BOOTP the options field (or rather vendor-specific area as it
was called back then) had a fixed length of 64 bytes (so max(optlen+4, 64)
might actually have been what was intended), but for DHCP the field is
explicitly variable length, so I don't think it's necessary to pad it.
Since we won't read from the socket reducing the receive buffer saves
some memory and it should also minimize the impact on other processes that
bind the same port (Linux distributes packets to the sockets round-robin).
DHCP servers will respond to port 67 if giaddr is non-zero, which we set
if we are not broadcasting. While such messages are received fine via
RAW socket the kernel will respond with an ICMP port unreachable if no
socket is bound to that port. Instead of opening a dummy socket on port
67 just to avoid the ICMPs we can also just operate with a single
socket, bind it to port 67 and send our requests from that port.
Since SO_REUSEADDR behaves on Linux like SO_REUSEPORT does on other
systems we can bind that port even if a DHCP server is running on the
same host as the daemon (this might have to be adapted to make this work
on other systems, but due to the raw socket the plugin is not that portable
anyway).
The previous code compared the port in the packet to the client port and, if
successful, checked it also against the server port, which, therefore, never
matched, but due to incorrect offsets did skip the BPF_JA. If the client port
didn't match the code also skipped to the instruction after the BPF_JA.
However, the latter was incorrect also and processing would have continued at
the next instruction anyway. Basically, DHCP packets to any port were accepted.
What's not fixed with this is that the kernel returns an ICMP Port
unreachable for packets sent to the server port (67) because we don't
have a socket bound to it.
Fixes: f0212e8837 ("Accept DHCP replies on bootps port, as we act as a relay agent if server address configured")
This patch allows for giving strongSwan only the runtime capabilities it
needs, rather than full root privileges.
Adds preprocessor directives which allow strongSwan to be configured to
1) start up as a non-root user
2) avoid modprobe()'ing IPsec kernel modules into the kernel, which
would normally require root or CAP_SYS_MODULE
Additionally, some small mods to charon/libstrongswan ensure that charon
fully supports starting as a non-root user.
Tested with strongSwan 5.5.3.
We don't have MOBIKE and the fallback to reauthentication does also not
make much sense as that doesn't affect the CHILD_SAs for IKEv1. So
instead of complicating the code we just ignore roam events for IKEv1
for now.
Closesstrongswan/strongswan#100.
In very early versions routed CHILD_SAs were attached to IKE_SAs, since
that's not the case anymore (they are handled via trap manager), we can
remove this special handling.
This algorithm uses a fixed-length key and we MUST NOT send a key length
attribute when proposing such algorithms.
While we could accept transforms with key length this would only work as
responder, as original initiator it wouldn't because we won't know if a
peer requires the key length. And as exchange initiator (e.g. for
rekeyings), while being original responder, we'd have to go to great
lengths to store the condition and modify the sent proposal to patch in
the key length. This doesn't seem worth it for only a partial fix.
This means, however, that ChaCha20/Poly1305 can't be used with previous
releases (5.3.3 an newer) that don't contain this fix.
Fixes#2614.
Fixes: 3232c0e64e ("Merge branch 'chapoly'")
Since these are installed overlapping (like during a rekeying) we have to use
the same (unique) marks (and possibly reqid) that were used previously,
otherwise, the policy installation will fail.
Fixes#2610.
If the responder is behind a NAT that remaps the response from the
statically forwarded port 500 to a new external port (as Azure seems to be
doing) we should still switch to port 4500 if we used port 500 so far as
it would not have been possible to send any messages to it if it wasn't
really port 500 (we only add a non-ESP marker if neither port is 500).
This helps to distinguish between port and protocol if only one of them
is set. If no protocol is set it's printed as 0, if the traffic
selector covers any port (0-65535) the slash that separates the two values
and the port is omitted.
This adds a new state for CHILD_SAs that we deleted but still keep
around to process delayed packets (IKEv2 only). This allows us to treat
them specially in some cases (e.g. to avoid triggering child_updown()
events as we already did that when we deleted such SAs).
Closesstrongswan/strongswan#93.
If a Quick mode is initiated for a CHILD_SA that is already installed
we can identify this situation and rekey the already installed CHILD_SA.
Otherwise we end up with several CHILD_SAs in state INSTALLED which
means multiple calls of child_updown are done. Unfortunately,
the deduplication code later does not call child_updown() (so up and down
were not even).
Closesstrongswan/strongswan#95.
This lets IPsec SA installation explicitly fail if HW offload is enabled
but either the kernel or the device don't support it. And it adds a new
configuration mode 'auto', which enables HW offload, if supported, but
does not fail the installation otherwise.
Until now the configuration available to user for HW offload were:
hw_offload = no
hw_offload = yes
With this commit users will be able to configure auto mode using:
hw_offload = auto
Signed-off-by: Adi Nissim <adin@mellanox.com>
Reviewed-by: Aviv Heller <avivh@mellanox.com>
Until now there were 2 hw_offload modes: no/yes
* hw_offload = no : Configure the SA without HW offload.
* hw_offload = yes : Configure the SA with HW offload.
In this case, if the device does not support
offloading, SA creation will fail.
This commit introduces a new mode: hw_offload = auto
----------------------------------------------------
If the device and kernel support HW offload, configure
the SA with HW offload, but do not fail SA creation otherwise.
Signed-off-by: Adi Nissim <adin@mellanox.com>
Reviewed-by: Aviv Heller <avivh@mellanox.com>
If a daemon PID file references the process that does the check, it is safe
to ignore it; no running process can have the same PID. While this is rather
unlikely to get restarted with the same PID under normal conditions, it is
quite common when running inside PID namespaced containers: If a container
gets stopped and restarted with a PID file remaining, it is very likely that
the PID namespace assigns the same PID to our service, as they are assigned
sequentially starting from 1.
According to RFC 5114 the exponent length for these groups should always equal
the size of their prime order subgroup.
This was handled correctly before the initialization was done during
library initialization.
Fixes: 46184b07c1 ("diffie-hellman: Explicitly initialize DH exponent sizes during initialization")
The previous code was obviously incorrect and caused strange side effects
depending on the compiler and its optimization flags (infinite looping seen
with GCC 4.8.4, segfault when destroying the private key in build() seen
with clang 4.0.0 on FreeBSD).
Fixes#2579.
We can't use ASN1_DEF, which would technically be more correct, as the
ASN.1 parser currently can't handle that. For algorithm identifiers we
often use ASN1_EOC as type (with ASN1_RAW), however, that doesn't work with
ASN1_DEF because the element is assumed missing if the type doesn't match.
On the other hand, we can't set the type to ASN1_SEQUENCE because then the
parser skips the following rule if the element is missing (it does so for
all constructed types, but I guess is mainly intended for context tags),
which in this case overruns the parser rules array.
This changes how unknown transform types are handled in proposals. In
particular we make sure not to accept a proposal if it contains unknown
transform types (they were just ignored previously, which could have
resulted in an invalid selected proposal).
Fixes#2557.
This way there will be a mismatch if one of the proposals contains
transform types not contained in the other (the fix list of transform
types used previously resulted in a match if unknown transform types
were contained in one of the proposals). Merging the sets of types
makes comparing proposals with optional transform types easier (e.g.
DH for ESP with MODP_NONE).
This improves the behavior during CREATE_CHILD_SA exchanges if the peer
sends an INVALID_KE_PAYLOAD with a DH group we didn't request or continues
to return the same notify even if we use the requested group.
Fixes#2536.
If we receive an INVALID_KE_PAYLOAD notify we should not just retry
with the requested DH group without checking first if we actually propose
the group (or any at all).
After a rekeying we keep the inbound SA and policies installed for a
while, but the outbound SA and policies are already removed. Attempting
to update them could get the refcount in the kernel interface out of sync
as the additional policy won't be removed when the CHILD_SA object is
eventually destroyed.
This changes how trap policies are deleted in order to avoid conflicts if a
trap policy with changed peer config is concurrently removed and reinstalled
under a different name (the reqid will be the same, so the wrong policy
could have been deleted by the old code).
When initiating a trap policy we explicitly pass the reqid along. I guess
the lookup was useful to get the same reqid if a trapped CHILD_SA is manually
initiated. However, we now get the same reqid anyway if there is no
narrowing. And if the traffic selectors do get narrowed the reqid will be
different but that shouldn't be a problem as that doesn't cause an issue with
any temporary SAs in the kernel (this is why we pass the reqid to the
triggered CHILD_SA, otherwise, no new acquire would get triggered for
traffic that doesn't match the wider trap policy).
Reqids for the same traffic selectors are now stable so we don't have to
pass reqids of previously installed CHILD_SAs. Likewise, we don't need
to know the reqid of the newly installed trap policy as we now uninstall
by name.
The timed wait functions tested in the threading unit tests often but
randomly trigger a bit early on AppVeyor Windows containers. We allow this
if it is not earlier than 5ms.
g_variant_builder_add() creates a new GVariant using g_variant_new() and
then adds it to the builder. Passing a GVariant probably adds the
pointer to the array, not the value. I think an alternative fix would
be to use "@u" as type string for the g_variant_builder_add() call, then
the already allocated GVariant is adopted.
Fixes: 9a71b7219c ("charon-nm: Port to libnm")
With IKEv1 we transmit both public DH factors (used to derive the initial
IV) besides the shared secret. So these messages could get significantly
larger than 1024 bytes, depending on the DH group (modp2048 just about
fits into it). The new default of 2048 bytes should be fine up to modp4096
and for larger groups the buffer size may be increased (an error is
logged should this happen).
The Trusty image used by Travis was updated in December and now has Clang
5.0.0 installed. So this workaround is not necessary anymore.
This reverts commit f4bd467641.
Since version 5.5.1, different keys can be put together in
/etc/swanctl/private.
See:
* tobiasbrunner@7caba2eb5524be6b51943bcc3d2cb0e4c5ecc09a
swanctl: Add 'private' directory/section to load any type of private key
Signed-off-by: Liu Qun (liuqun) <qunliu@zyhx-group.com>
These changes improve MOBIKE task queuing. In particular we don't
want to ignore the response to an update (with NAT-D payloads) if only
an address list update or DPD is queued as that could prevent use from
updating the UDP encapsulation in the kernel.
A new optional roam trigger is added to the kernel-netlink plugin based
on routing rule changes. This only works properly, though, if the kernel
based route lookup is used as the kernel-netlink plugin does currently
not consider routing rules for its own route lookup.
Another change prevents acquires during address updates if we have to
update IPsec SAs by deleting and readding them. Because the outbound policy
is still installed an acquire and temporary SA might get triggered in
the short time no IPsec SA is installed, which could subsequently prevent the
reinstallation of the SA. To this end we install drop policies before
updating the policies and SAs. These also replace the fallback drop policies
we previously used to prevent plaintext leaks during policy updates (which
reduces the overhead in cases where addresses never or rarely change as
additional policies will only have to be tracked during address updates).
Fixes#2518.
This is really only needed for other exchanges like DPDs not when we
just updated the addresses. The NAT-D payloads are only used here to
detect whether UDP encapsulation has to be enabled/disabled.
If we have to remove and reinstall SAs for address updates (as with the
Linux kernel) there is a short time where there is no SA installed. If
we keep the policies installed they (or any traps) might cause acquires
and temporary kernel states that could prevent the updated SA from
getting installed again.
This replaces the previous workaround to avoid plaintext traffic leaks
during policy updates, which used low-priority drop policies.
This can be useful if routing rules (instead of e.g. route metrics) are used
to switch from one to another interface (i.e. from one to another
routing table). Since we currently don't evaluate routing rules when
doing the route lookup this is only useful if the kernel-based route
lookup is used.
Resolvesstrongswan/strongswan#88.
The counter does not tell us what task is actually queued, so we might
ignore the response to an update (with NAT-D payloads) if only an address
update is queued.
Instead of destroying the new task and keeping the existing one we
update any already queued task, so we don't loose any work (e.g. if a
DPD task is active and address update is queued and we'd actually like
to queue a roam task).
According to RFC 3748 MSKs must be at least 64 bytes, however, that's
not the case for the MSK derived via EAP-MSCHAPv2. The two key parts
received are only 16 bytes each (derived according to RFC 3079,
section 3.3), so we end up with an MSK of only 32 bytes. The eap-mschapv2
plugin, on the other hand, pads these two parts with 32 zeros.
Interestingly, this is not a problem in many cases as the SHA1/2 based
PRFs used later use a block size that's >= 64 bytes, so the shorter MSK
is just padded with zeros then. However, with AES-XCBC-PRF-128, for
instance, which uses a block size of 16 bytes, the different MSKs are an
issue as XCBC is applied to both to shorten them, with different results.
This eventually causes the authentication to fail if the client uses a
zero-padded MSK produced by the eap-mschapv2 plugin and the server the 32
byte MSK received via RADIUS.
These changes improve rekeying after the peer initially selected a
different DH group than we proposed. Instead of using the configured DH
group again, and causing another INVALID_KE_PAYLOAD notify, we now reuse
the previously negotiated group. We also send the selected DH group
first in the proposals (and move proposals that don't contain the group
to the back) so that implementations that select the proposal first and
without consulting the KE payload (e.g. strongSwan when preferring the
client's proposals) will see the preferred group first.
Fixes#2526.
This is currently not an issue for CHILD_SA rekeying tests as these only
check rekeyings of the CHILD_SA created with the IKE_SA, i.e. there is
no previous DH group to reuse.
For the CHILD_SA created with the IKE_SA the group won't be set in the
proposal, so we will use the first one configure just as if the SA was
created new with a CREATE_CHILD_SA exchange. I guess we could
theoretically try to use the DH group negotiated for IKE but then this
would get a lot more complicated as we'd have to check if that group is
actually contained in any of the CHILD_SA's configured proposals.
This way we get proper error handling if the DH group the peer requested
is not actually supported for some reason (otherwise we'd just retry to
initiate with the configured group and get back another notify).
This fixes two issues, one is a bug if a DH group is configured for the
local ESP proposals and charon.prefer_configured_proposals is disabled.
This would cause the DH groups to get stripped not from the configured but
from the supplied proposal, which usually already has them stripped. So
the proposals wouldn't match. We'd have to always strip them from the local
proposal. Since there are apparently implementations that, incorrectly, don't
remove the DH groups in the IKE_AUTH exchange (e.g. WatchGuard XTM25
appliances) we just strip them from both proposals. It's a bit more lenient
that way and we don't have to complicate the code to only clone and strip the
local proposal, which would depend on a flag.
References #2503.
IKE_SAs newly created via HA_IKE_ADD message don't have any IKE or peer
config assigned yet (this happens later with an HA_IKE_UPDATE message).
And because the state is initially set to IKE_CONNECTING the roam() method
does not immediately return, as it later would for passive HA SAs. This
might cause the check for explicitly configured local addresses to crash
the daemon with a segmentation fault.
Fixes#2500.
In scenarios where the server accepts client certificates from dozens or
even hundreds of CAs it might be necessary to omit certificate request
payloads from the IKE_SA_INIT response to avoid fragmentation.
As it is rarely the case in road-warrior scenarios that the server
already has the client certificate installed it should not be a problem
to always send it.
The kernel creates such SAs to handle uncompressed small packets. They
are implicitly created and deleted with IPComp SAs. The problem is that
when we delete an IPComp SA only that state is deleted and removed from
the SA lists immediately, the IP-in-IP state is not removed until the IPComp
state is eventually destroyed. This could take a while if there are still
references to it around. So the IP-in-IP states will keep getting reported
by ip xfrm state until that happens (we also can't flush or explicitly delete
such kernel-created states).
In kernels before 4.14 this wasn't really a problem but since
ec30d78c14a8 ("xfrm: add xdst pcpu cache") the kernel seems to keep the
references to the last used SAs around a lot longer.
Also, usually a test scenario following an IPComp scenario will create
and use new SAs and thus the cached SAs will disappear before the kernel
state is checked again. However, if a following scenario uses different
hosts the states might remain, which caused some unrelated scenarios to
fail before adding this fix.
Depending on the plugins that eventually parse the certificate and CRL,
serials with MSB set (i.e. negative numbers that have a zero byte prefixed
when encoded as ASN.1 INTEGER) might have (x509 plugin) or not have
(openssl plugin) a zero byte prefix when returned by get_serial() or
enumerated from the CRL. Strip them before doing the comparison or
revocation checking might fail if not both credentials are parsed by the
same plugin (which should be rare and only happen if parsing of either
cert or CRL fails with one of the plugins and there is a fallback to the
implementation provided by the other plugin).
Fixes#2509.
Reset errno to 0 before calling strtoul() since it sets errno only on
error cases. So the following test fails even on correct conversions if
errno had a value != 0.
Fixes#2506.
Otherwise, the remote identity is ignored when matching owner identities
of PSKs and this way matching PSKs that explicitly have %any assigned is
improved.
Fixes#2497.
If users want to associate secrets with any identity, let 'em. This is
also possible with vici and might help if e.g. the remote identity is
actually %any as that would match a PSK with local IP and %any better
than one with local and different remote IP.
Fixes#2497.
This adds several route-based VPN scenarios (using VTI or GRE interfaces).
It also fixes several swanctl --list-sas checks in other scenarios.
Closesstrongswan/strongswan#84.
chroot will capture the user environment's PATH variable, which may be
wrong (e.g. not include /bin:/sbin, as it is on Arch). We should set a
known-working PATH variable in the chroot.
Use argument evaluation provided by settings_t instead of using strings
to enumerate key/values.
If section names contain dots the latter causes the names to get split
and interpreted as non-existing sections and subsections.
This currently doesn't work for connections and their subsections due to
the recursion.
libnm-glib is deprecated for several years and reaching the end of its
life. Let's switch to the more up-to-date library.
Closesstrongswan/strongswan#85.
Xcode 8.3, to which there recently was a switch, spits out a warning for
the potentially unaligned access to ip6_plen in ip-packet.c, which we
explicitly read via untoh16() hence the access to that pointer is not
actually unaligned. It seems the compiler is not able to determine that
there is no unaligned access even though the function is defined in the
header and marked inline.
Support for mark=%unique/%unique-dir is implemented by using designated
magic mark values.
Use of masks is orthogonal to the 'unique' feature, as it is useful to be
able to designate portions of the packet mark for other purposes, while
still using different marks for different connections.
When these magic values are masked, their magic meaning is lost.
Perform masking only on explicit mark values.
Closesstrongswan/strongswan#87.
This allows us to use it without having to initialize libcharon, which
was required for the logging (we probably could have included debug.h
instead of daemon.h to workaround that but this seems more correct).
We could make the same change for charon (actually setting it for charon
in strongswan.conf.testing would work for charon-systemd too), however,
there are dozens of test cases that currently set charondebug in
ipsec.conf.
Make sure, though, that we only remove the file if we actually
created it (e.g. not for --help or --version). And do so before
deinitializing libstrongswan due to leak detective.
Fixes#2460.
libstrongswan and kernel-netlink are the only two components which do
not adhere to the naming scheme used for all other tests. If the tests
are run by an external application this imposes problems due to clashing
names.
Signed-off-by: Thomas Egerer <thomas.egerer@secunet.com>
This adds support for RSASSA-PSS signatures in IKEv2 digital signature
authentication (RFC 7427), certificates and CRLs etc., and when signing
credentials via pki tool. For interoperability with older versions, the
default is to use classic PKCS#1 signatures. To use PSS padding either enable
rsa_pss via strongswan.conf or explicitly use it either via ike:rsa/pss...
auth token or the --rsa-padding option of the pki tool.
References #2427.
In theory we should treat any parameters and the identifier itself as
restriction to only use the key to create signatures accordingly (e.g.
only use RSA with PSS padding or even use specific hash algorithms).
But that's currently tricky as we'd have to store and pass this information
along with our private keys (i.e. use PKCS#8 to store them and change the
builder calls to pass along the identifier and parameters). That would
require quite some work.
For salt lengths other than 20 this requires 0bd8137e68c2 ("cipher:
Add option to specify salt length for PSS verification."), which was
included in libgcrypt 1.7.0 (for Ubuntu requires 17.04). As that makes
it pretty much useless for us (SHA-1 is a MUST NOT), we require that version
to even provide the feature.
Since not all implementations allow setting a specific salt value when
generating signatures (e.g. OpenSSL doesn't), we are often limited to
only using the test vectors with salt length of 0.
We also exclude test vectors with SHA-1, SHA-224 and SHA-384.
RFC 8247 demoted it to SHOULD NOT. This might break connections with
Windows clients unless they are configured to use a stronger group or
matching weak proposals are configured explicitly on the server.
References #2427.
The MySQL client doesn't like overlapping queries on the same
connection, so we make sure to destroy the enumerator used to check for
an existing pool before deleting it when --replace is used.
This is not ideal as the call to C_Finalize() should be the last one via
the PKCS#11 API. Since the order in which jobs are canceled is undefined
we can't be sure there is no other thread still using the library (it could
even be the canceled job that still handles a previous slot event).
According to PKCS#11 the behavior of C_Finalize() is undefined while other
threads still make calls over the API.
However, canceling the thread, as done previously, could also be problematic
as PKCS#11 libraries could hold locks while in the C_WaitForSlotEvent() call,
which might not get released properly when the thread is just canceled,
and which then might cause later calls to other API functions to block.
Fixes#2437.
If enabled, add the RADIUS Class attributes received in Access-Accept messages
to RADIUS accounting messages as suggested by RFC 2865 section 5.25.
Fixes#2451.
We do something similar in reestablish() for break-before-make reauth.
If we don't abort we'd be sending an IKE_AUTH without any TS payloads.
References #2430.
The fix for gperf in 0ae19f0ced added the generated header to
EXTRA_DIST but that's already added to the distribution because it is
contained in *_SOURCES, what was not added, though, was the .h.in file.
Also fixes the reference to the header file in the .c rule here and for
stroke in out-of-tree builds.
Fixes: 0ae19f0ced ("configure: Fix gperf length parameter determination")
This can happen if a stream is used blocking exclusively (the FD is
never registered with watcher, but is removed in the stream's destructor
just in case it ever was - doing this conditionally would require an
additional flag in streams). There may be no thread reading from
the read end of the notify pipe (e.g. in starter), causing the write
to the notify pipe to block after it's full. Anyway, doing a relatively
expensive FD update is unnecessary if there were no changes.
Fixes#1453.
This allows systemd socket activation by passing URIs such as systemd://foo
to plugins such as VICI.
For example setting charon.plugins.vici.socket = systemd://vici, a
systemd socket file descriptor with the name "vici" will be picked up.
So these would be the corresponding unit options:
[Socket]
FileDescriptorName=vici
Service=strongswan.service
ListenStream=/run/charon.vici
The implementation currently is very basic and right now only the first
file descriptor for a particular identifier is picked up if there are
multiple socket units with the same FileDescriptorName.
Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Closesstrongswan/strongswan#79.
Just rely on the default proposals by charon if nothing is defined. The
hard-coded IKE proposal used curve25519, which depends on an optional
plugin (while enabled by default it might still not be loaded, or, like
on Debian, shipped in an optional package). With charon's default
proposal only loaded algorithms are proposed for IKE avoiding this issue.
With OpenSSL 1.1.0 the library is now named libcrypto too on Windows.
Check for libeay32 first so we don't link against the build environment's
version of OpenSSL instead of the native one that might be available.
The order of arguments in X509_CRL_get0_signature() is not the same as that
of X509_get0_signature().
Fixes: 989ba4b6cd ("openssl: Update CRL API to OpenSSL 1.1.0")
gperf is not actually a build dependency as the generated files are
shipped in the tarball. So the type depends on the gperf version on
the host that ran gperf and created the tarball, which might not be
the same as that on the actual build host, and gperf might not even
be installed there, leaving the type undetermined.
Fixes: e0e4322973 ("configure: Detect type of length parameter for gperf generated function")
It seems that there is a race, at least in 10.13, that lets
if_indextoname() fail for the new TUN device. So we delay the call a bit,
which seems to "fix" the issue. It's strange anyway that the previous
delay was only applied when an iface entry was already found.
Recent releases of glibc don't include the full stdint.h header in some
network headers included by utils.h. So uintptr_t might not be defined.
Since we use fixed width integers, including the latter, all over the place
we make sure the complete file is included.
Fixes#2425.
The value of DHCP_OPTEND is 255. When it is assigned this result in a
sign change as the positive int constant is cast to a signed char and -1
results. Clang 4.0 complains about this.
This is a follow up on the issue documented in the previous commit.
To build with -Werror and Clang 3.9 we'd have to change all enum arguments
that are used as last argument before ... to e.g. u_int, which affects
quite a lot of places (crypto-factory, MODP_CUSTOM constructors, auth-cfg,
bus, vici-builder, vici-message). Besides that it doesn't look as nice
it also seems a bit too much hassle just to cater to the whims of a
particular version of one compiler, so we just don't build with that
version on Travis and use 4.0 instead.
This fixes compilation with -Werror when using Clang 4.0 (but not 3.9)
and possibly prevents undefined behavior.
According to the C standard the following applies to the second
parameter of the va_start() macro (subclause 7.16.1.4, paragraph 4):
The parameter parmN is the identifier of the rightmost parameter
in the variable parameter list in the function definition (the
one just before the ...). If the parameter parmN is declared with
the register storage class, with a function or array type, or with
a type that is not compatible with the type that results after
application of the default argument promotions, the behavior is
undefined.
Because bool is usually just 1 byte and therefore smaller than int (i.e.
the result of default argument promotion) its use as last argument before
... might result in undefined behavior. This theoretically can also
apply to enums as a compiler may use a smaller base type than int.
Since Clang 3.9 (currently in use on Travis by default) a warning is
issued about this, however, that version did not yet compare the actual
size of the argument's type, causing warnings where they are not
warranted (basically for all cases where enum types are used for the
last argument). This was apparently fixed with Clang 4.0, which only
warns about this use of bool with va_start(), which makes sense.
They now match the dh_constructor_t signature. This is a follow up for
the changes merged with b668bf3f9e and should fix use of MODP_CUSTOM on
Apple's ARM64 platform.
This causes problems e.g. on Android where we handle the alert (and
reestablish the IKE_SA) even though it usually is no problem if the
peer retries with the requested group. We don't consider it as a
failure on the initiator either.
If an IPsec SA is actually replaced with a rekeying its entry in the
manager is freed. That means that when the hard expire is triggered a
new entry might be found at the cached pointer location. So we have
to make sure we trigger the expire only if we found the right SA.
We could use SPI and addresses for the lookup, but this here requires
a bit less memory and is just a small change. Another option would be to
somehow cancel the queued job, but our scheduler doesn't allow that at
the moment.
Fixes#2399.
This fixes "packet too short" errors when parsing fragmented IPv4
packets and correctly determines the protocol in fragmented IPv6 packets.
Protocol headers are only parsed in unfragmented IPv4 and IPv6 packets,
or IPv4 first fragments.
Closesstrongswan/strongswan#80.
We don't attempt to parse the transport headers for fragments, not even
for the initial fragment (it's not guaranteed they contain the header,
depending on the number and type of extension headers).
Since we are also releasing the ESA ID we have to make sure that the ESA
context is reset and in a clean state in order for it to be actually
reusable.
Use new reference counting feature of ID manager for AE contexts and
only perform reset if count is zero. Also, do not pass on AE ID as every
IKE SA must decrement AE ID count once it is not used any longer.
sec-updater downloads the deb package files from security updates from
a given linux repository and uses the swid_generator command to
derive a SWID tag. The SWID tag is then imported into strongTNC
using the manage.py importswid command.
In case we send retransmits for an IKE_SA_INIT where we propose a DH
group the responder will reject we might later receive delayed responses
that either contain INVALID_KE_PAYLOAD notifies with the group we already
use or, if we retransmitted an IKE_SA_INIT with the requested group but
then had to restart again, a KE payload with a group different from the
one we proposed. So far we didn't change the initiator SPI when
restarting the connection, i.e. these delayed responses were processed
and might have caused fatal errors due to a failed DH negotiation or
because of the internal retry counter in the ike-init task. Changing
the initiator SPI avoids that as we won't process the delayed responses
anymore that caused this confusion.
Caches CRLs in the app directory, adds support for OCSP, adds a button
to reconnect to the "already connected" dialog, only apply/configure app
selection on Android >= 5 (older versions don't support the API), and catches
some random exceptions.
sec-updater checks for security updates and backports in Debian/
Ubuntu repositories and sets the security flags in the strongTNC
policy database accordingly.
If an interface is renamed we already have an entry (based on the
ifindex) allocated but previously only set the usable state once
based on the original name.
Fixes#2403.
There is a bug in some versions of lcov that causes it to fail writing
to files via relative paths after it issued warnings (e.g. due to
negative counts in the tracefile).
The generic field of size 0 in the union that was used previously
triggered index-out-of-bounds errors with the UBSAN sanitizer that's
used on OSS-Fuzz. Since the two family specific union members don't
really provide any advantage, we can just use a single buffer for both
families to avoid the errors.
Please refer to the [developer documentation](https://wiki.strongswan.org/projects/strongswan/wiki/DeveloperDocumentation)
on our wiki for details regarding **code style** and [**contribution requirements**](https://wiki.strongswan.org/projects/strongswan/wiki/Contributions).