From: Amos Jeffries Date: Thu, 26 Mar 2015 09:57:25 +0000 (-0700) Subject: Move Ssl::parse_flags to Security::ParseFlags X-Git-Tag: merge-candidate-3-v1~38^2~21^2~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b24e9ae70856a19ae8b79c764d456518ae0cf4fb;p=thirdparty%2Fsquid.git Move Ssl::parse_flags to Security::ParseFlags ... in preparation for making PeerOptions used by both server and client configuation. --- diff --git a/src/anyp/PortCfg.cc b/src/anyp/PortCfg.cc index e76d50b639..1c69394cce 100644 --- a/src/anyp/PortCfg.cc +++ b/src/anyp/PortCfg.cc @@ -54,7 +54,6 @@ AnyP::PortCfg::PortCfg() : capath(NULL), crlfile(NULL), dhfile(NULL), - sslflags(NULL), sslContextSessionId(NULL), generateHostCertificates(false), dynamicCertMemCacheSize(std::numeric_limits::max()), @@ -95,7 +94,6 @@ AnyP::PortCfg::~PortCfg() safe_free(capath); safe_free(crlfile); safe_free(dhfile); - safe_free(sslflags); safe_free(sslContextSessionId); #endif } @@ -140,8 +138,8 @@ AnyP::PortCfg::clone() const b->crlfile = xstrdup(crlfile); if (dhfile) b->dhfile = xstrdup(dhfile); - if (sslflags) - b->sslflags = xstrdup(sslflags); + b->sslflags = sslflags; + b->sslContextFlags = sslContextFlags; if (sslContextSessionId) b->sslContextSessionId = xstrdup(sslContextSessionId); @@ -196,9 +194,7 @@ AnyP::PortCfg::configureSslServerContext() if (dhfile) dhParams.reset(Ssl::readDHParams(dhfile)); - if (sslflags) - sslContextFlags = Ssl::parse_flags(sslflags); - + sslContextFlags = Security::ParseFlags(sslflags); sslOptions = Security::ParseOptions(options); staticSslContext.reset(sslCreateServerContext(*this)); diff --git a/src/anyp/PortCfg.h b/src/anyp/PortCfg.h index f4f3d9e6f4..ccaede26f7 100644 --- a/src/anyp/PortCfg.h +++ b/src/anyp/PortCfg.h @@ -13,6 +13,7 @@ #include "anyp/ProtocolVersion.h" #include "anyp/TrafficMode.h" #include "comm/Connection.h" +#include "SBuf.h" #if USE_OPENSSL #include "ssl/gadgets.h" @@ -78,7 +79,7 @@ public: char *capath; char *crlfile; char *dhfile; - char *sslflags; + SBuf sslflags; char *sslContextSessionId; ///< "session id context" for staticSslContext bool generateHostCertificates; ///< dynamically make host cert for sslBump size_t dynamicCertMemCacheSize; ///< max size of generated certificates memory cache diff --git a/src/cache_cf.cc b/src/cache_cf.cc index f2e7ccbd3e..69652d2bc1 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -3606,8 +3606,7 @@ parse_port_option(AnyP::PortCfgPointer &s, char *token) safe_free(s->dhfile); s->dhfile = xstrdup(token + 9); } else if (strncmp(token, "sslflags=", 9) == 0) { - safe_free(s->sslflags); - s->sslflags = xstrdup(token + 9); + s->sslflags = SBuf(token + 9); } else if (strncmp(token, "sslcontext=", 11) == 0) { safe_free(s->sslContextSessionId); s->sslContextSessionId = xstrdup(token + 11); @@ -3828,8 +3827,8 @@ dump_generic_port(StoreEntry * e, const char *n, const AnyP::PortCfgPointer &s) if (s->dhfile) storeAppendPrintf(e, " dhparams=%s", s->dhfile); - if (s->sslflags) - storeAppendPrintf(e, " sslflags=%s", s->sslflags); + if (!s->sslflags.isEmpty()) + storeAppendPrintf(e, " sslflags=" SQUIDSBUFPH, SQUIDSBUFPRINT(s->sslflags)); if (s->sslContextSessionId) storeAppendPrintf(e, " sslcontext=%s", s->sslContextSessionId); diff --git a/src/security/PeerOptions.cc b/src/security/PeerOptions.cc index e537c7a2d7..7e9fba6d3c 100644 --- a/src/security/PeerOptions.cc +++ b/src/security/PeerOptions.cc @@ -11,6 +11,7 @@ #include "fatal.h" #include "globals.h" #include "Parsing.h" +#include "parser/Tokenizer.h" #include "security/PeerOptions.h" #if USE_OPENSSL @@ -51,7 +52,11 @@ Security::PeerOptions::parse(const char *token) } else if (strncmp(token, "crlfile=", 8) == 0) { crlFile = SBuf(token + 8); } else if (strncmp(token, "flags=", 6) == 0) { + if (parsedFlags != 0) { + debugs(0, DBG_PARSE_NOTE(1), "WARNING: Overwriting flags=" << sslFlags << " with " << SBuf(token + 6)); + } sslFlags = SBuf(token + 6); + parsedFlags = Security::ParseFlags(sslFlags); } else if (strncmp(token, "domain=", 7) == 0) { sslDomain = SBuf(token + 7); } @@ -66,7 +71,7 @@ Security::PeerOptions::createClientContext(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 ? parsedOptions : 0), sslFlags.c_str(), caFile.c_str(), caDir.c_str(), crlFile.c_str()); + (setOptions ? parsedOptions : 0), parsedFlags, caFile.c_str(), caDir.c_str(), crlFile.c_str()); #endif @@ -278,6 +283,48 @@ Security::ParseOptions(const char *options) return op; } +long +Security::ParseFlags(const SBuf &flags) +{ + if (flags.isEmpty()) + return 0; + + static struct { + SBuf label; + long mask; + } flagTokens[] = { + { SBuf("NO_DEFAULT_CA"), SSL_FLAG_NO_DEFAULT_CA }, + { SBuf("DELAYED_AUTH"), SSL_FLAG_DELAYED_AUTH }, + { SBuf("DONT_VERIFY_PEER"), SSL_FLAG_DONT_VERIFY_PEER }, + { SBuf("DONT_VERIFY_DOMAIN"), SSL_FLAG_DONT_VERIFY_DOMAIN }, + { SBuf("NO_SESSION_REUSE"), SSL_FLAG_NO_SESSION_REUSE }, +#if X509_V_FLAG_CRL_CHECK + { SBuf("VERIFY_CRL"), SSL_FLAG_VERIFY_CRL }, + { SBuf("VERIFY_CRL_ALL"), SSL_FLAG_VERIFY_CRL_ALL }, +#endif + { SBuf(), 0 } + }; + + ::Parser::Tokenizer tok(flags); + static const CharacterSet delims("Flag-delimiter", ":,"); + + long fl = 0; + do { + long found = 0; + for (size_t i = 0; flagTokens[i].mask; ++i) { + if (tok.skip(flagTokens[i].label) == 0) { + found = flagTokens[i].mask; + break; + } + } + if (!found) + fatalf("Unknown SSL flag '" SQUIDSBUFPH "'", SQUIDSBUFPRINT(tok.remaining())); + fl |= found; + } while (tok.skipOne(delims)); + + return fl; +} + void parse_securePeerOptions(Security::PeerOptions *opt) { diff --git a/src/security/PeerOptions.h b/src/security/PeerOptions.h index 678e6073cf..e50184f0b4 100644 --- a/src/security/PeerOptions.h +++ b/src/security/PeerOptions.h @@ -39,10 +39,11 @@ public: SBuf crlFile; ///< path of file containing Certificate Revoke List SBuf sslCipher; - SBuf sslFlags; + SBuf sslFlags; ///< flags defining what TLS operations Squid performs SBuf sslDomain; long parsedOptions; ///< parsed value of sslOptions + long parsedFlags; ///< parsed value of sslFlags int sslVersion; @@ -58,6 +59,11 @@ extern PeerOptions ProxyOutgoingConfig; */ long ParseOptions(const char *options); +/** + * Parses the TLS flags squid.conf parameter + */ +long ParseFlags(const SBuf &); + } // namespace Security // parse the tls_outgoing_options directive diff --git a/src/security/forward.h b/src/security/forward.h index c686bcea7c..bf49f518b6 100644 --- a/src/security/forward.h +++ b/src/security/forward.h @@ -11,6 +11,15 @@ #include "security/Context.h" +/* flags a SSL connection can be configured with */ +#define SSL_FLAG_NO_DEFAULT_CA (1<<0) +#define SSL_FLAG_DELAYED_AUTH (1<<1) +#define SSL_FLAG_DONT_VERIFY_PEER (1<<2) +#define SSL_FLAG_DONT_VERIFY_DOMAIN (1<<3) +#define SSL_FLAG_NO_SESSION_REUSE (1<<4) +#define SSL_FLAG_VERIFY_CRL (1<<5) +#define SSL_FLAG_VERIFY_CRL_ALL (1<<6) + /// Network/connection security abstraction layer namespace Security { diff --git a/src/ssl/support.cc b/src/ssl/support.cc index b1d5068c40..2223620830 100644 --- a/src/ssl/support.cc +++ b/src/ssl/support.cc @@ -348,67 +348,6 @@ ssl_verify_cb(int ok, X509_STORE_CTX * ctx) return ok; } -/// \ingroup ServerProtocolSSLInternal -#define SSL_FLAG_NO_DEFAULT_CA (1<<0) -/// \ingroup ServerProtocolSSLInternal -#define SSL_FLAG_DELAYED_AUTH (1<<1) -/// \ingroup ServerProtocolSSLInternal -#define SSL_FLAG_DONT_VERIFY_PEER (1<<2) -/// \ingroup ServerProtocolSSLInternal -#define SSL_FLAG_DONT_VERIFY_DOMAIN (1<<3) -/// \ingroup ServerProtocolSSLInternal -#define SSL_FLAG_NO_SESSION_REUSE (1<<4) -/// \ingroup ServerProtocolSSLInternal -#define SSL_FLAG_VERIFY_CRL (1<<5) -/// \ingroup ServerProtocolSSLInternal -#define SSL_FLAG_VERIFY_CRL_ALL (1<<6) - -/// \ingroup ServerProtocolSSLInternal -long -Ssl::parse_flags(const char *flags) -{ - long fl = 0; - char *tmp; - char *flag; - - if (!flags) - return 0; - - tmp = xstrdup(flags); - - flag = strtok(tmp, ":,"); - - while (flag) { - if (strcmp(flag, "NO_DEFAULT_CA") == 0) - fl |= SSL_FLAG_NO_DEFAULT_CA; - else if (strcmp(flag, "DELAYED_AUTH") == 0) - fl |= SSL_FLAG_DELAYED_AUTH; - else if (strcmp(flag, "DONT_VERIFY_PEER") == 0) - fl |= SSL_FLAG_DONT_VERIFY_PEER; - else if (strcmp(flag, "DONT_VERIFY_DOMAIN") == 0) - fl |= SSL_FLAG_DONT_VERIFY_DOMAIN; - else if (strcmp(flag, "NO_SESSION_REUSE") == 0) - fl |= SSL_FLAG_NO_SESSION_REUSE; - -#if X509_V_FLAG_CRL_CHECK - - else if (strcmp(flag, "VERIFY_CRL") == 0) - fl |= SSL_FLAG_VERIFY_CRL; - else if (strcmp(flag, "VERIFY_CRL_ALL") == 0) - fl |= SSL_FLAG_VERIFY_CRL_ALL; - -#endif - - else - fatalf("Unknown ssl flag '%s'", flag); - - flag = strtok(NULL, ":,"); - } - - safe_free(tmp); - return fl; -} - // "dup" function for SSL_get_ex_new_index("cert_err_check") static int ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *, @@ -898,12 +837,11 @@ Ssl::serverMethod(int version) } 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) +sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, long options, long fl, const char *CAfile, const char *CApath, const char *CRLfile) { int ssl_error; Ssl::ContextMethod method; SSL_CTX * sslContext; - long fl = Ssl::parse_flags(flags); ssl_initialize(); diff --git a/src/ssl/support.h b/src/ssl/support.h index 2bde785c4e..64a9d76a1b 100644 --- a/src/ssl/support.h +++ b/src/ssl/support.h @@ -92,7 +92,7 @@ typedef CbDataList CertErrors; SSL_CTX *sslCreateServerContext(AnyP::PortCfg &port); /// \ingroup ServerProtocolSSLAPI -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); +SSL_CTX *sslCreateClientContext(const char *certfile, const char *keyfile, int version, const char *cipher, long options, long flags, const char *CAfile, const char *CApath, const char *CRLfile); /// \ingroup ServerProtocolSSLAPI int ssl_read_method(int, char *, int); diff --git a/src/tests/stub_libsecurity.cc b/src/tests/stub_libsecurity.cc index c581c1dce5..b274c3b4b3 100644 --- a/src/tests/stub_libsecurity.cc +++ b/src/tests/stub_libsecurity.cc @@ -22,4 +22,5 @@ void Security::PeerOptions::parse(char const*) STUB Security::ContextPointer Security::PeerOptions::createClientContext(bool) STUB_RETVAL(NULL) void parse_securePeerOptions(Security::PeerOptions *) STUB long Security::ParseOptions(const char *) STUB_RETVAL(0) +long Security::ParseFlags(const SBuf &) STUB_RETVAL(0)