Daniel Lenski [Wed, 5 Jun 2019 03:30:30 +0000 (20:30 -0700)]
add openconnect_disable_dtls() API function
This also adds the API function to the Java bindings.
The immediate motivation is that there are a lot of Android users with
MTU-related issues (https://github.com/cernekee/ics-openconnect), and
disabling UDP/DTLS/ESP is a good temporary band-aid.
Daniel Lenski [Sat, 20 Feb 2021 00:05:09 +0000 (00:05 +0000)]
Try to generate static website using GitLab pages
Based on the example at https://gitlab.com/pages/plain-html, and ocserv's configuration (https://gitlab.com/openconnect/ocserv/blob/master/.gitlab-ci.yml)
Daniel Lenski [Mon, 25 Jan 2021 07:39:39 +0000 (23:39 -0800)]
allow specification of multiple certificate fingerprints on command-line via --servercert
Server certificates will be accepted if they match *any* of the provided fingerprints.
Behavior with `--servercert` is otherwise unchanged; it still disables system trust
stores, meaning that _only_ certificates matching the provided fingerprints will be
accepted if it is specified one or more times.
This will allow the use of `--servercert` to non-interactively connect to a server which
has a non-trusted certificate and redirects to one or more other servers with non-trusted
certificates. (See #25 for a real case.)
Daniel Lenski [Fri, 22 Jan 2021 00:27:23 +0000 (16:27 -0800)]
with --allow-insecure-crypto, additionally attempt to disable insecure systemwide minimum crypto settings
Because openconnect_set_allow_insecure_crypto() now does more than just attempt to reenable 3DES and ARC4,
its failure to enable those ciphers should not be treated as fatal, but merely a warning.
Setting the appropriate environment variable (GNUTLS_SYSTEM_PRIORITY_FILE or OPENSSL_CONF) to `/dev/null`
*before* crypto library initialization should ensure that a systemwide crypto configuration file doesn't
set a minimum crypto requirement which would override the user choice.
See https://gitlab.com/openconnect/openconnect/-/issues/211#note_482161646 for discussion of GnuTLS
settings, and https://www.openssl.org/docs/man1.1.1/man5/config.html for OpenSSL.
Daniel Lenski [Fri, 22 Jan 2021 02:01:42 +0000 (18:01 -0800)]
add openconnect__win32_setenv function to compat.c
Based on:
* POSIX-compatible `setenv` implementation for Windows: https://stackoverflow.com/a/23616164
* Enabling Windows "secure API" getenv_s and _putenv_s functions in MinGW:
* Using -DMINGW_HAS_SECURE_API: https://stackoverflow.com/a/51977723
* By manually defining their prototypes: https://stackoverflow.com/a/51977723
* Apparently, only newer versions of MinGW follow the MINGW_HAS_SECURE_API flag, and
autodetecting them is quite hard.
Tom Carroll [Sat, 16 Jan 2021 07:37:42 +0000 (23:37 -0800)]
Use separate counters for inner and outer loop.
The inner and outer loop share a counter. The inner loop resets the
counter to zero when entering the loop. I don't believe this is the
intention from an examination of the code. Have inner and outer loops
use separate counters.
Signed-off-by: Tom Carroll <incentivedesign@gmail.com>
Tom Carroll [Fri, 8 Jan 2021 19:26:48 +0000 (11:26 -0800)]
Free pcerts array for all assign_privkey paths.
Ensure the array pcerts is free'd for both success/fail paths. The function
gnutls_certificate_set_key() is odd as it takes ownership of the contents of
pcerts, but not the pcerts array itself. See:
Elias Norberg [Fri, 1 May 2020 12:08:02 +0000 (14:08 +0200)]
Always set security level to 0 for openssl versions >= 1.1.0
In version 1.1.0 of OpenSSL, a security level was introduced that enforces specific settings for certificates etc.
This PR sets the security level to 0, to retain the functionality that
previous versions of openssl had, and preventing errors like:
140088222534656:error:140AB18E:SSL routines:SSL_CTX_use_certificate:ca md too weak:../ssl/ssl_rsa.c:310
See https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_security_level.html for more information about security levels.
Signed-off-by: Elias Norberg <elias@aisle.se> Signed-off-by: Daniel Lenski <dlenski@gmail.com>
Daniel Lenski [Tue, 5 Jan 2021 04:48:20 +0000 (20:48 -0800)]
defer the switch to syslog until AFTER the tunnel is fully up,
This way, initial connection information and background PID will be usefully
printed to the console, as will errors which prevent the tunnel from being
started (and thus cause OpenConnect to abort as soon as it's established
a connection to the server).
Daniel Lenski [Thu, 24 Sep 2020 23:54:57 +0000 (16:54 -0700)]
Add `openconnect_get_auth_expiration` function to library and JNI
This allows protocols to save the moment when a session's authentication
(`vpninfo->cookie`) is expected to expire and no longer be useful for
reconnection.
The motivation is to eventually allow front-ends to know whether
reauthentication is needed, or whether they should try using a cached
cookie.
Current state:
- AnyConnect protocol: expiration is determined from the CONNECT
response header `X-CSTP-Session-Timeout-Remaining` (with
`X-CSTP-Session-Timeout` or `X-CSTP-Lease-Duration` as upper bounds in its
absence)
- GlobalProtect protocol: expiration is determined from the `<lifetime>` tag of
the XML config.
- Juniper Network Connect protocol: no currently known way to determine
expiration. The `DSID` cookie is a standard HTTP cookie, so perhaps its
expiration timestamp is intended for this purpose; however, I can find
no real-world case where it has an expiration timestamp set.
- None of the currently-supported protocols provide the expiration
timestamp until the connection phase, so it can't be obtained for
export by the `--authenticate` option.
Daniel Lenski [Mon, 30 Nov 2020 22:21:21 +0000 (14:21 -0800)]
GP: explicitly warn when server has a missing ESP configuration
I'm tired of OpenConnect getting blamed for lack of ESP connectivity when in
fact literally every example that has been investigated since 2017 turned
out to be due to a missing server configuration, broken server
configuration, or network UDP blockage.
Daniel Lenski [Mon, 30 Nov 2020 06:41:12 +0000 (22:41 -0800)]
more logging around Trojan script invocation (CSD/HIP/TNCC)
See #203 for a recent example of where it wasn't clear that a problem was
caused by a CSD script being invoked and never returning, due to the lack of
logging.
Daniel Lenski [Sun, 15 Nov 2020 23:32:08 +0000 (15:32 -0800)]
GP: ask user to report unexpected value of <connected-gw-ip>
We don't know what this one means, but it seems likely that we need to do
some special processing if this differs from the VPN server's external IP
address.
See https://gitlab.com/openconnect/openconnect/-/issues/193#note_447466255
for an example of this field observed "in the wild".
Daniel Lenski [Mon, 16 Nov 2020 22:00:47 +0000 (14:00 -0800)]
less confusing output when authentication fails
* "Failed to obtain WebVPN cookie" → "Failed to complete authentication"
(WebVPN is Cisco-specific and unclear to end users)
* GlobalProtect shouldn't treat a SAML-required login response as a failure to *parse*
the login response. This results in unnecessary and confusing logging. (ping #197)
Daniel Lenski [Wed, 20 May 2020 05:06:34 +0000 (22:06 -0700)]
use setup_tun callback to defer printing connection status AND backgrounding until tun_is_up
This will make scripted use of OpenConnect a lot less sensitive to timing of the tunnel
coming up, if a script is trying to use the tunnel as soon as the main process exits.
(See https://gitlab.com/openconnect/openconnect/-/issues/117 for examples.)
Here's a log of OpenConnect connecting to a GlobalProtect server where ESP
fails to start succesfully due to a firewall blocking UDP. With this
change, it doesn't print the connection status or go to background until after the
attempt to connect ESP has failed, and the tunnel has been started.
$ echo PASSWORD | sudo ./openconnect -u USERNAME vpn.company.com/gateway --prot=gp --passwd-on-stdin -b \
-s 'echo +++ vpnc-script called with reason $reason'
POST https://vpn.company.com/ssl-vpn/prelogin.esp?tmp=tmp&clientVer=4100&clientos=Linux
Connected to 1.2.3.4:443
SSL negotiation with vpn.company.com
Connected to HTTPS on vpn.company.com with ciphersuite (TLS1.2)-(RSA)-(AES-256-GCM)
Enter login credentials
POST https://vpn.company.com/ssl-vpn/login.esp
POST https://vpn.company.com/ssl-vpn/getconfig.esp
Session will expire after 1440 minutes.
Tunnel timeout (rekey interval) is 180 minutes.
Idle timeout is 180 minutes.
No MTU received. Calculated 1214 for ESP tunnel
POST https://vpn.company.com/ssl-vpn/hipreportcheck.esp
Delaying tunnel for 1000 ms with reason: awaiting GPST ESP connection
Delaying tunnel for 1000 ms with reason: awaiting GPST ESP connection
Delaying tunnel for 1000 ms with reason: awaiting GPST ESP connection
Delaying tunnel for 1000 ms with reason: awaiting GPST ESP connection
Delaying tunnel for 1000 ms with reason: awaiting GPST ESP connection
Delaying tunnel for 1000 ms with reason: awaiting GPST ESP connection
Failed to connect ESP tunnel; using HTTPS instead.
Connected as 10.0.1.2, using SSL, with ESP unsuccessful
Continuing in background; pid 1234
+++ vpnc-script called with reason pre-init
+++ vpnc-script called with reason connect
$
Here's an example of attempted DTLS connecting on an AnyConnect VPN, where DTLS
never succeeds. This right away gives us some good feedback that we could probably
reduce the duration of the loop:
Connected to 1.2.3.4:443
SSL negotiation with vpn.company.com
Server certificate verify failed: signer not found
Connected to HTTPS on vpn.company.com with ciphersuite (TLS1.2)-(ECDHE-RSA-SECP384R1)-(AES-256-GCM)
Got CONNECT response: HTTP/1.1 200 OK
CSTP connected. DPD 30, Keepalive 20
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
DTLS handshake failed: Resource temporarily unavailable, try again.
Delaying tunnel for 1000 ms with reason: DTLS MTU detection
Connected as 10.0.1.2, using SSL, with DTLS in progress
There's no clear rationale for using with Pulse/oNCP ESP setup (yet):
- We don't do any MTU detection
- Unlike GPST, we can start sending and receiving packets via the TLS tunnel
immediately, while attempting to connect ESP as well.
Daniel Lenski [Sun, 17 May 2020 00:06:10 +0000 (17:06 -0700)]
add delay_tunnel_reason and delay_close
- As long as the protocol-specific mainloop sets delay_tunnel_reason to a non-NULL value, tunnel
device creation will be delayed.
- If delay_close is set, mainloop will continue to iterate even if cancel_cmd or pause_cmd is set.
A protocol should set DELAY_CLOSE_IMMEDIATE_CALLBACK for the case where its mainloop needs an
immediate callback (e.g. to send some kind of termination request), and DELAY_CLOSE_WAIT for the
case where its mainloop is waiting to receive something (e.g. a termination acknowledgement).
openconnect_mainloop() will unset both delay_tunnel_reason and delay_close on each iteration. A
protocol mainloop must thus affirmatively extend a delay in order for it to continue.
Daniel Lenski [Thu, 15 Oct 2020 05:01:34 +0000 (22:01 -0700)]
finesse the URL-decoding of the GP login args
Unsurprisingly, it's messier than I thought it was. Some of them definitely
need to be URL-decoded, and some definitely shouldn't be.
https://gitlab.com/openconnect/openconnect/-/issues/147#note_429943037