]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
with --allow-insecure-crypto, additionally attempt to disable insecure systemwide...
authorDaniel Lenski <dlenski@gmail.com>
Fri, 22 Jan 2021 00:27:23 +0000 (16:27 -0800)
committerDaniel Lenski <dlenski@gmail.com>
Sat, 23 Jan 2021 00:50:44 +0000 (16:50 -0800)
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.

FIXME: OpenSSL implementation needs library reinitialization.

Signed-off-by: Daniel Lenski <dlenski@gmail.com>
gnutls.c
library.c
main.c
openconnect-internal.h
openconnect.8.in
openssl.c

index 7d5b99248270d682ea61de0ff0d33c934a32bd53..bab38e00f4b68015b6fd070e19dc18cadcfced3a 100644 (file)
--- a/gnutls.c
+++ b/gnutls.c
@@ -78,12 +78,23 @@ const char *openconnect_get_tls_library_version()
 
 int can_enable_insecure_crypto()
 {
+       int ret = 0;
+
+       if (setenv("GNUTLS_SYSTEM_PRIORITY_FILE", DEVNULL, 1) < 0)
+               return -errno;
+
+       gnutls_global_deinit();
+       ret = openconnect_init_ssl();
+       if (ret)
+               return ret;
+
        /* XX: As of GnuTLS 3.6.13, no released version has (yet) removed 3DES/RC4 from default builds,
         * but like OpenSSL (removed in 1.1.0) it may happen. */
        if (gnutls_cipher_get_id("3DES-CBC") == GNUTLS_CIPHER_UNKNOWN ||
            gnutls_cipher_get_id("ARCFOUR-128") == GNUTLS_CIPHER_UNKNOWN)
-               return -ENOENT;
-       return 0;
+               ret = -ENOENT;
+
+       return ret;
 }
 
 /* Helper functions for reading/writing lines over TLS/DTLS. */
index 3a8d6cd664c01fc796e58edeffb97649b23b4c80..4db0d36809236a5f48ec00b685a719f4bbfc9ba7 100644 (file)
--- a/library.c
+++ b/library.c
@@ -757,10 +757,8 @@ void openconnect_set_pfs(struct openconnect_info *vpninfo, unsigned val)
 int openconnect_set_allow_insecure_crypto(struct openconnect_info *vpninfo, unsigned val)
 {
        int ret = can_enable_insecure_crypto();
-       if (ret)
-               return ret;
        vpninfo->allow_insecure_crypto = val;
-       return 0;
+       return ret;
 }
 
 void openconnect_set_cancel_fd(struct openconnect_info *vpninfo, int fd)
diff --git a/main.c b/main.c
index 58a7fc0f9806d5d4bf6b769a97be5458a59c7d3e..9780e44d6ed55d90c5f556f0edf00d8fcde774c2 100644 (file)
--- a/main.c
+++ b/main.c
@@ -924,6 +924,7 @@ static void usage(void)
        printf("      --no-http-keepalive         %s\n", _("Disable HTTP connection re-use"));
        printf("      --no-xmlpost                %s\n", _("Do not attempt XML POST authentication"));
        printf("      --allow-insecure-crypto     %s\n", _("Allow use of the ancient, insecure 3DES and RC4 ciphers"));
+       printf("                                  %s\n", _("(and attempt to override OS crypto policies)"));
 
        printf("\n");
 
@@ -1639,9 +1640,12 @@ int main(int argc, char **argv)
                        openconnect_set_pfs(vpninfo, 1);
                        break;
                case OPT_ALLOW_INSECURE_CRYPTO:
-                       if (openconnect_set_allow_insecure_crypto(vpninfo, 1)) {
-                               fprintf(stderr, _("Cannot enable insecure 3DES or RC4 ciphers, because the library\n"
+                       ret = openconnect_set_allow_insecure_crypto(vpninfo, 1);
+                       if (ret == -ENOENT)
+                               fprintf(stderr, _("WARNING: cannot enable insecure 3DES and/or RC4 ciphers, because the library\n"
                                                  "%s no longer supports them.\n"), openconnect_get_tls_library_version());
+                       else if (ret < 0) {
+                               fprintf(stderr, _("Unknown error while enabling insecure crypto.\n"));
                                exit(1);
                        }
                        break;
index d35bf4455d215fc4e39e6cb117a1cf1504c4d961..429aa6f83985920df8ed97f3e5a0c39fb426a161 100644 (file)
 
 #include "openconnect.h"
 
+/* Equivalent of "/dev/null" on Windows.
+ * See https://stackoverflow.com/a/44163934
+ */
+#ifdef _WIN32
+#define DEVNULL "NUL"
+#else
+#define DEVNULL "/dev/null"
+#endif
+
 #if defined(OPENCONNECT_OPENSSL)
 #include <openssl/ssl.h>
 #include <openssl/err.h>
@@ -1069,7 +1078,7 @@ int do_gen_hotp_code(struct openconnect_info *vpninfo,
                     struct oc_auth_form *form,
                     struct oc_form_opt *opt);
 
-int set_oidc_token(struct openconnect_info *vpninfo, 
+int set_oidc_token(struct openconnect_info *vpninfo,
                     const char *token_str);
 
 /* stoken.c */
index 741f42399d7b7017f3e56a801977563c602399c2..73edd838ce98fd92bbc130445f92f8d4de391886 100644 (file)
@@ -469,8 +469,11 @@ The ancient, broken 3DES and RC4 ciphers are insecure; we explicitly
 disable them by default. However, some still-in-use VPN servers can't do
 any better.
 
-This option enables use of these insecure ciphers, as well as the use
-of SHA1 for server certificate validation.
+This option
+.B attempts
+to enable use of these insecure ciphers, as well as
+the use of SHA1 for server certificate validation, and to override any
+other system policies regarding minimum crypto requirements.
 .TP
 .B \-\-non\-inter
 Do not expect user input; exit if it is required.
index 26ac750e4ba78852a30131b50419b8f823774954..8fb03b92a63ceafd1c6b6849ee9be82dd8b19f98 100644 (file)
--- a/openssl.c
+++ b/openssl.c
@@ -63,10 +63,23 @@ const char *openconnect_get_tls_library_version()
 
 int can_enable_insecure_crypto()
 {
+       int ret = 0;
+
+       if (setenv("OPENSSL_CONF", DEVNULL, 1) < 0)
+               return -errno;
+
+       /* FIXME: deinitialize and reinitialize library, as is done for GnuTLS,
+        * to ensure that updated value is used.
+        *
+        * Cleaning up and reinitalizing OpenSSL appears to be complex:
+        *   https://wiki.openssl.org/index.php/Library_Initialization#Cleanup
+        */
+
        if (EVP_des_ede3_cbc() == NULL ||
            EVP_rc4() == NULL)
-               return -ENOENT;
-       return 0;
+               ret = -ENOENT;
+
+       return ret;
 }
 
 int openconnect_sha1(unsigned char *result, void *data, int len)