]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Shuffle Ssl::parse_options to Security::ParseOptions
authorAmos Jeffries <squid3@treenet.co.nz>
Sat, 21 Mar 2015 13:35:24 +0000 (06:35 -0700)
committerAmos Jeffries <squid3@treenet.co.nz>
Sat, 21 Mar 2015 13:35:24 +0000 (06:35 -0700)
The function itself is generic, the options array entries are all
conditional so library agnostic.

Adjust the context creation functions to receive pre-parsed options
instead of the string to avoid circular dependency between libsquidssl
and libsecurity.

src/anyp/PortCfg.cc
src/security/PeerOptions.cc
src/security/PeerOptions.h
src/ssl/support.cc
src/ssl/support.h
src/tests/stub_libsecurity.cc
src/tests/stub_libsslsquid.cc

index d2299244ac90e4b490daba9100ba4ded846d5a9a..e76d50b639bf0e9fd0cbdc9dcf9129bf6b3e5e42 100644 (file)
@@ -10,6 +10,7 @@
 #include "anyp/PortCfg.h"
 #include "comm.h"
 #include "fatal.h"
+#include "security/PeerOptions.h"
 #if USE_OPENSSL
 #include "ssl/support.h"
 #endif
@@ -198,7 +199,7 @@ AnyP::PortCfg::configureSslServerContext()
     if (sslflags)
         sslContextFlags = Ssl::parse_flags(sslflags);
 
-    sslOptions = Ssl::parse_options(options);
+    sslOptions = Security::ParseOptions(options);
 
     staticSslContext.reset(sslCreateServerContext(*this));
 
index bc60a20138e93905a7cb57745d2f5c1f44e98b8c..6f276713fdcf7929169ec7325fa5c5183d9a9348 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "squid.h"
 #include "Debug.h"
+#include "fatal.h"
 #include "globals.h"
 #include "Parsing.h"
 #include "security/PeerOptions.h"
@@ -39,7 +40,7 @@ Security::PeerOptions::parse(const char *token)
         // Pre-parse SSL client options to be applied when the client SSL objects created.
         // Options must not used in the case of peek or stare bump mode.
         // XXX: performance regression. c_str() can reallocate
-        parsedOptions = Ssl::parse_options(sslOptions.c_str());
+        parsedOptions = Security::ParseOptions(sslOptions.c_str());
 #endif
     } else if (strncmp(token, "cipher=", 7) == 0) {
         sslCipher = SBuf(token + 7);
@@ -65,12 +66,218 @@ Security::PeerOptions::createContext(bool setOptions)
 #if USE_OPENSSL
     // XXX: temporary performance regression. c_str() data copies and prevents this being a const method
     t = sslCreateClientContext(certFile.c_str(), privateKeyFile.c_str(), sslVersion, sslCipher.c_str(),
-                               (setOptions ? sslOptions.c_str() : NULL), sslFlags.c_str(), caFile.c_str(), caDir.c_str(), crlFile.c_str());
+                               (setOptions ? parsedOptions : 0), sslFlags.c_str(), caFile.c_str(), caDir.c_str(), crlFile.c_str());
+
 #endif
 
     return t;
 }
 
+/// set of options we can parse and what they map to
+static struct ssl_option {
+    const char *name;
+    long value;
+
+} ssl_options[] = {
+
+#if SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+    {
+        "NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+    },
+#endif
+#if SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
+    {
+        "SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
+    },
+#endif
+#if SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
+    {
+        "MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
+    },
+#endif
+#if SSL_OP_SSLEAY_080_CLIENT_DH_BUG
+    {
+        "SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG
+    },
+#endif
+#if SSL_OP_TLS_D5_BUG
+    {
+        "TLS_D5_BUG", SSL_OP_TLS_D5_BUG
+    },
+#endif
+#if SSL_OP_TLS_BLOCK_PADDING_BUG
+    {
+        "TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG
+    },
+#endif
+#if SSL_OP_TLS_ROLLBACK_BUG
+    {
+        "TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG
+    },
+#endif
+#if SSL_OP_ALL
+    {
+        "ALL", (long)SSL_OP_ALL
+    },
+#endif
+#if SSL_OP_SINGLE_DH_USE
+    {
+        "SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE
+    },
+#endif
+#if SSL_OP_EPHEMERAL_RSA
+    {
+        "EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA
+    },
+#endif
+#if SSL_OP_PKCS1_CHECK_1
+    {
+        "PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1
+    },
+#endif
+#if SSL_OP_PKCS1_CHECK_2
+    {
+        "PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2
+    },
+#endif
+#if SSL_OP_NETSCAPE_CA_DN_BUG
+    {
+        "NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG
+    },
+#endif
+#if SSL_OP_NON_EXPORT_FIRST
+    {
+        "NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST
+    },
+#endif
+#if SSL_OP_CIPHER_SERVER_PREFERENCE
+    {
+        "CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE
+    },
+#endif
+#if SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
+    {
+        "NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
+    },
+#endif
+#if SSL_OP_NO_SSLv3
+    {
+        "NO_SSLv3", SSL_OP_NO_SSLv3
+    },
+#endif
+#if SSL_OP_NO_TLSv1
+    {
+        "NO_TLSv1", SSL_OP_NO_TLSv1
+    },
+#endif
+#if SSL_OP_NO_TLSv1_1
+    {
+        "NO_TLSv1_1", SSL_OP_NO_TLSv1_1
+    },
+#endif
+#if SSL_OP_NO_TLSv1_2
+    {
+        "NO_TLSv1_2", SSL_OP_NO_TLSv1_2
+    },
+#endif
+#if SSL_OP_NO_COMPRESSION
+    {
+        "No_Compression", SSL_OP_NO_COMPRESSION
+    },
+#endif
+#if SSL_OP_NO_TICKET
+    {
+        "NO_TICKET", SSL_OP_NO_TICKET
+    },
+#endif
+    {
+        "", 0
+    },
+    {
+        NULL, 0
+    }
+};
+
+long
+Security::ParseOptions(const char *options)
+{
+    long op = 0;
+    char *tmp;
+    char *option;
+
+    if (options) {
+
+    tmp = xstrdup(options);
+    option = strtok(tmp, ":,");
+
+    while (option) {
+
+        enum {
+            MODE_ADD, MODE_REMOVE
+        } mode;
+
+        switch (*option) {
+
+        case '!':
+
+        case '-':
+            mode = MODE_REMOVE;
+            ++option;
+            break;
+
+        case '+':
+            mode = MODE_ADD;
+            ++option;
+            break;
+
+        default:
+            mode = MODE_ADD;
+            break;
+        }
+
+        struct ssl_option *opt = NULL;
+        for (struct ssl_option *opttmp = ssl_options; opttmp->name; ++opttmp) {
+            if (strcmp(opttmp->name, option) == 0) {
+                opt = opttmp;
+                break;
+            }
+        }
+
+        long value = 0;
+        if (opt)
+            value = opt->value;
+        else if (strncmp(option, "0x", 2) == 0) {
+            /* Special case.. hex specification */
+            value = strtol(option + 2, NULL, 16);
+        } else {
+            fatalf("Unknown SSL option '%s'", option);
+            value = 0;      /* Keep GCC happy */
+        }
+
+        switch (mode) {
+
+        case MODE_ADD:
+            op |= value;
+            break;
+
+        case MODE_REMOVE:
+            op &= ~value;
+            break;
+        }
+
+        option = strtok(NULL, ":,");
+    }
+
+    safe_free(tmp);
+    }
+
+#if SSL_OP_NO_SSLv2
+    // compliance with RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0
+    op = op | SSL_OP_NO_SSLv2;
+#endif
+    return op;
+}
+
 void
 parse_securePeerOptions(Security::PeerOptions *opt)
 {
index c88732f512a22a93b89c0163a05af59299d06c08..08ac9b706dee442fd3552fe34ac956c9cc3877af 100644 (file)
@@ -53,6 +53,11 @@ public:
 /// configuration options for DIRECT server access
 extern PeerOptions ProxyOutgoingConfig;
 
+/**
+ * Parses the TLS options squid.conf parameter
+ */
+long ParseOptions(const char *options);
+
 } // namespace Security
 
 // parse the tls_outgoing_options directive
index f6c744f915bf1a77c6cadfc5d5ff59a395d1129a..b1d5068c4076a8ab852b4c0b682ba4af23229a0a 100644 (file)
@@ -348,215 +348,6 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
     return ok;
 }
 
-/// \ingroup ServerProtocolSSLInternal
-static struct ssl_option {
-    const char *name;
-    long value;
-}
-
-ssl_options[] = {
-
-#if SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
-    {
-        "NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
-    },
-#endif
-#if SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
-    {
-        "SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
-    },
-#endif
-#if SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
-    {
-        "MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
-    },
-#endif
-#if SSL_OP_SSLEAY_080_CLIENT_DH_BUG
-    {
-        "SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG
-    },
-#endif
-#if SSL_OP_TLS_D5_BUG
-    {
-        "TLS_D5_BUG", SSL_OP_TLS_D5_BUG
-    },
-#endif
-#if SSL_OP_TLS_BLOCK_PADDING_BUG
-    {
-        "TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG
-    },
-#endif
-#if SSL_OP_TLS_ROLLBACK_BUG
-    {
-        "TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG
-    },
-#endif
-#if SSL_OP_ALL
-    {
-        "ALL", (long)SSL_OP_ALL
-    },
-#endif
-#if SSL_OP_SINGLE_DH_USE
-    {
-        "SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE
-    },
-#endif
-#if SSL_OP_EPHEMERAL_RSA
-    {
-        "EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA
-    },
-#endif
-#if SSL_OP_PKCS1_CHECK_1
-    {
-        "PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1
-    },
-#endif
-#if SSL_OP_PKCS1_CHECK_2
-    {
-        "PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2
-    },
-#endif
-#if SSL_OP_NETSCAPE_CA_DN_BUG
-    {
-        "NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG
-    },
-#endif
-#if SSL_OP_NON_EXPORT_FIRST
-    {
-        "NON_EXPORT_FIRST", SSL_OP_NON_EXPORT_FIRST
-    },
-#endif
-#if SSL_OP_CIPHER_SERVER_PREFERENCE
-    {
-        "CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE
-    },
-#endif
-#if SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
-    {
-        "NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
-    },
-#endif
-#if SSL_OP_NO_SSLv3
-    {
-        "NO_SSLv3", SSL_OP_NO_SSLv3
-    },
-#endif
-#if SSL_OP_NO_TLSv1
-    {
-        "NO_TLSv1", SSL_OP_NO_TLSv1
-    },
-#endif
-#if SSL_OP_NO_TLSv1_1
-    {
-        "NO_TLSv1_1", SSL_OP_NO_TLSv1_1
-    },
-#endif
-#if SSL_OP_NO_TLSv1_2
-    {
-        "NO_TLSv1_2", SSL_OP_NO_TLSv1_2
-    },
-#endif
-#if SSL_OP_NO_COMPRESSION
-    {
-        "No_Compression", SSL_OP_NO_COMPRESSION
-    },
-#endif
-#if SSL_OP_NO_TICKET
-    {
-        "NO_TICKET", SSL_OP_NO_TICKET
-    },
-#endif
-    {
-        "", 0
-    },
-    {
-        NULL, 0
-    }
-};
-
-/// \ingroup ServerProtocolSSLInternal
-long
-Ssl::parse_options(const char *options)
-{
-    long op = 0;
-    char *tmp;
-    char *option;
-
-    if (!options)
-        goto no_options;
-
-    tmp = xstrdup(options);
-
-    option = strtok(tmp, ":,");
-
-    while (option) {
-
-        struct ssl_option *opt = NULL, *opttmp;
-        long value = 0;
-        enum {
-            MODE_ADD, MODE_REMOVE
-        } mode;
-
-        switch (*option) {
-
-        case '!':
-
-        case '-':
-            mode = MODE_REMOVE;
-            ++option;
-            break;
-
-        case '+':
-            mode = MODE_ADD;
-            ++option;
-            break;
-
-        default:
-            mode = MODE_ADD;
-            break;
-        }
-
-        for (opttmp = ssl_options; opttmp->name; ++opttmp) {
-            if (strcmp(opttmp->name, option) == 0) {
-                opt = opttmp;
-                break;
-            }
-        }
-
-        if (opt)
-            value = opt->value;
-        else if (strncmp(option, "0x", 2) == 0) {
-            /* Special case.. hex specification */
-            value = strtol(option + 2, NULL, 16);
-        } else {
-            fatalf("Unknown SSL option '%s'", option);
-            value = 0;      /* Keep GCC happy */
-        }
-
-        switch (mode) {
-
-        case MODE_ADD:
-            op |= value;
-            break;
-
-        case MODE_REMOVE:
-            op &= ~value;
-            break;
-        }
-
-        option = strtok(NULL, ":,");
-    }
-
-    safe_free(tmp);
-
-no_options:
-#if SSL_OP_NO_SSLv2
-    // compliance with RFC 6176: Prohibiting Secure Sockets Layer (SSL) Version 2.0
-    op = op | SSL_OP_NO_SSLv2;
-#endif
-    return op;
-}
-
 /// \ingroup ServerProtocolSSLInternal
 #define SSL_FLAG_NO_DEFAULT_CA      (1<<0)
 /// \ingroup ServerProtocolSSLInternal
@@ -1107,7 +898,7 @@ Ssl::serverMethod(int version)
 }
 
 SSL_CTX *
-sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile)
+sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, long options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile)
 {
     int ssl_error;
     Ssl::ContextMethod method;
@@ -1127,7 +918,7 @@ sslCreateClientContext(const char *certfile, const char *keyfile, int version, c
                ERR_error_string(ssl_error, NULL));
     }
 
-    SSL_CTX_set_options(sslContext, Ssl::parse_options(options));
+    SSL_CTX_set_options(sslContext, options);
 
     if (*cipher) {
         debugs(83, 5, "Using chiper suite " << cipher << ".");
index fa52c9bacaf79c6573db369ba9a3ad934bd41984..2bde785c4ee80a7df18021558e3fb42415757ad7 100644 (file)
@@ -92,7 +92,7 @@ typedef CbDataList<Ssl::CertError> CertErrors;
 SSL_CTX *sslCreateServerContext(AnyP::PortCfg &port);
 
 /// \ingroup ServerProtocolSSLAPI
-SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile);
+SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, long options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile);
 
 /// \ingroup ServerProtocolSSLAPI
 int ssl_read_method(int, char *, int);
@@ -163,12 +163,6 @@ inline const char *bumpMode(int bm)
  */
 long parse_flags(const char *flags);
 
-/**
- \ingroup ServerProtocolSSLAPI
- * Parses the SSL options.
- */
-long parse_options(const char *options);
-
 /**
  \ingroup ServerProtocolSSLAPI
  * Load a CRLs list stored in a file
index ec7903251ed75ddb3f6c91a2ab5091e3772ffb86..041bfbabe817b6a07909590fbd5eb80df4c08b6b 100644 (file)
@@ -21,4 +21,5 @@ Security::PeerOptions Security::ProxyOutgoingConfig;
 void Security::PeerOptions::parse(char const*) STUB
 Security::ContextPointer Security::PeerOptions::createContext(bool) STUB_RETVAL(NULL)
 void parse_securePeerOptions(Security::PeerOptions *) STUB
+long Security::ParseOptions(const char *) STUB_RETVAL(0)
 
index e52608b43a457b855a8e4babab768b7bac8344f3..2d131b772bee9ee10ab46be512cfbe2a2227b5bc 100644 (file)
@@ -57,7 +57,7 @@ bool CertError::operator == (const CertError &ce) const STUB_RETVAL(false)
 bool CertError::operator != (const CertError &ce) const STUB_RETVAL(false)
 } // namespace Ssl
 SSL_CTX *sslCreateServerContext(AnyP::PortCfg &port) STUB_RETVAL(NULL)
-SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, const char *options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile) STUB_RETVAL(NULL)
+SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, long options, const char *flags, const char *CAfile, const char *CApath, const char *CRLfile) STUB_RETVAL(NULL)
 int ssl_read_method(int, char *, int) STUB_RETVAL(0)
 int ssl_write_method(int, const char *, int) STUB_RETVAL(0)
 void ssl_shutdown_method(SSL *ssl) STUB
@@ -73,7 +73,6 @@ namespace Ssl
 //GETX509ATTRIBUTE GetX509Fingerprint;
 const char *BumpModeStr[] = {""};
 long parse_flags(const char *flags) STUB_RETVAL(0)
-long parse_options(const char *options) STUB_RETVAL(0)
 STACK_OF(X509_CRL) *loadCrl(const char *CRLFile, long &flags) STUB_RETVAL(NULL)
 DH *readDHParams(const char *dhfile) STUB_RETVAL(NULL)
 ContextMethod contextMethod(int version) STUB_RETVAL(ContextMethod())