=== modified file 'src/CachePeer.h' --- src/CachePeer.h 2012-09-23 09:04:21 +0000 +++ src/CachePeer.h 2012-11-26 01:17:54 +0000 @@ -37,6 +37,7 @@ #define PEER_MULTICAST_SIBLINGS 1 #if USE_SSL +#include "ssl/Config.h" #include #endif @@ -190,15 +191,7 @@ #if USE_SSL int use_ssl; - char *sslcert; - char *sslkey; - int sslversion; - char *ssloptions; - char *sslcipher; - char *sslcafile; - char *sslcapath; - char *sslcrlfile; - char *sslflags; + Ssl::ConfigOptions ssl; char *ssldomain; SSL_CTX *sslContext; SSL_SESSION *sslSession; === modified file 'src/anyp/PortCfg.cc' --- src/anyp/PortCfg.cc 2012-11-23 05:39:27 +0000 +++ src/anyp/PortCfg.cc 2012-11-23 12:48:15 +0000 @@ -34,14 +34,6 @@ safe_free(protocol); #if USE_SSL - safe_free(cert); - safe_free(key); - safe_free(options); - safe_free(cipher); - safe_free(cafile); - safe_free(capath); - safe_free(dhfile); - safe_free(sslflags); safe_free(sslContextSessionId); #endif } @@ -69,21 +61,12 @@ memcpy( &(b->tcp_keepalive), &(tcp_keepalive), sizeof(tcp_keepalive)); + b->ssl = ssl; + #if 0 // AYJ: 2009-07-18: for now SSL does not clone. Configure separate ports with IPs and SSL settings #if USE_SSL - char *cert; - char *key; - int version; - char *cipher; - char *options; - char *clientca; - char *cafile; - char *capath; - char *crlfile; - char *dhfile; - char *sslflags; char *sslContextSessionId; SSL_CTX *sslContext; #endif @@ -96,8 +79,8 @@ #if USE_SSL void AnyP::PortCfg::configureSslServerContext() { - if (cert) - Ssl::readCertChainAndPrivateKeyFromFiles(signingCert, signPkey, certsToChain, cert, key); + if (ssl.certfile) + Ssl::readCertChainAndPrivateKeyFromFiles(signingCert, signPkey, certsToChain, ssl.certfile, ssl.keyfile); if (!signingCert) { char buf[128]; @@ -115,27 +98,27 @@ fatalf("Unable to generate signing SSL certificate for untrusted sites for %s_port %s", protocol, s.ToURL(buf, sizeof(buf))); } - if (crlfile) - clientVerifyCrls.reset(Ssl::loadCrl(crlfile, sslContextFlags)); + if (ssl.CRLfile) + clientVerifyCrls.reset(Ssl::loadCrl(ssl.CRLfile, sslContextFlags)); - if (clientca) { - clientCA.reset(SSL_load_client_CA_file(clientca)); + if (ssl.clientCA) { + clientCA.reset(SSL_load_client_CA_file(ssl.clientCA)); if (clientCA.get() == NULL) { - fatalf("Unable to read client CAs! from %s", clientca); + fatalf("Unable to read client CAs! from %s", ssl.clientCA); } } - contextMethod = Ssl::contextMethod(version); + contextMethod = Ssl::contextMethod(ssl.version); if (!contextMethod) fatalf("Unable to compute context method to use"); - if (dhfile) - dhParams.reset(Ssl::readDHParams(dhfile)); - - if (sslflags) - sslContextFlags = Ssl::parse_flags(sslflags); - - sslOptions = Ssl::parse_options(options); + if (ssl.DHfile) + dhParams.reset(Ssl::readDHParams(ssl.DHfile)); + + if (ssl.flags) + sslContextFlags = Ssl::parse_flags(ssl.flags); + + sslOptions = Ssl::parse_options(ssl.options); Ssl::CreateServerContext(staticSslContext, *this); === modified file 'src/anyp/PortCfg.h' --- src/anyp/PortCfg.h 2012-10-09 23:15:44 +0000 +++ src/anyp/PortCfg.h 2012-11-23 12:40:07 +0000 @@ -5,6 +5,7 @@ #include "comm/Connection.h" #if USE_SSL +#include "ssl/Config.h" #include "ssl/gadgets.h" #endif @@ -57,17 +58,8 @@ Comm::ConnectionPointer listenConn; #if USE_SSL - char *cert; - char *key; - int version; - char *cipher; - char *options; - char *clientca; - char *cafile; - char *capath; - char *crlfile; - char *dhfile; - char *sslflags; + Ssl::ConfigOptions ssl; ///< SSL options found in the config file for this port. + 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 === modified file 'src/cache_cf.cc' --- src/cache_cf.cc 2012-11-23 05:39:27 +0000 +++ src/cache_cf.cc 2013-06-24 09:33:32 +0000 @@ -41,6 +41,7 @@ #include "anyp/PortCfg.h" #include "AuthReg.h" #include "base/RunnersRegistry.h" +#include "base/StringArea.h" #include "mgr/ActionPasswordList.h" #include "CachePeer.h" #include "CachePeerDomainList.h" @@ -920,13 +921,13 @@ // XXX: move the ssl_client out of the master Config structure so we can re-use its fields and Store a SSL_CTX_Pointer member. // the global structure has memset() applied which screws with refcount/locking *_Pointer classes Ssl::SSL_CTX_Pointer sslClient; - Ssl::CreateClientContext(sslClient, Config.ssl_client.cert, Config.ssl_client.key, Config.ssl_client.version, Config.ssl_client.cipher, Config.ssl_client.options, Config.ssl_client.flags, Config.ssl_client.cafile, Config.ssl_client.capath, Config.ssl_client.crlfile); + Ssl::CreateClientContext(sslClient, Ssl::TheConfig.sslProxyDirect); Config.ssl_client.sslContext = sslClient.release(); for (CachePeer *p = Config.peers; p != NULL; p = p->next) { if (p->use_ssl) { debugs(3, DBG_IMPORTANT, "Initializing cache_peer " << p->name << " SSL context"); - Ssl::CreateClientContext(sslClient, p->sslcert, p->sslkey, p->sslversion, p->sslcipher, p->ssloptions, p->sslflags, p->sslcafile, p->sslcapath, p->sslcrlfile); + Ssl::CreateClientContext(sslClient, p->ssl); p->sslContext = sslClient.release(); } } @@ -2263,35 +2264,15 @@ } else if (strcmp(token, "ssl") == 0) { p->use_ssl = 1; - } else if (strncmp(token, "sslcert=", 8) == 0) { - safe_free(p->sslcert); - p->sslcert = xstrdup(token + 8); - } else if (strncmp(token, "sslkey=", 7) == 0) { - safe_free(p->sslkey); - p->sslkey = xstrdup(token + 7); - } else if (strncmp(token, "sslversion=", 11) == 0) { - p->sslversion = atoi(token + 11); - } else if (strncmp(token, "ssloptions=", 11) == 0) { - safe_free(p->ssloptions); - p->ssloptions = xstrdup(token + 11); - } else if (strncmp(token, "sslcipher=", 10) == 0) { - safe_free(p->sslcipher); - p->sslcipher = xstrdup(token + 10); - } else if (strncmp(token, "sslcafile=", 10) == 0) { - safe_free(p->sslcafile); - p->sslcafile = xstrdup(token + 10); - } else if (strncmp(token, "sslcapath=", 10) == 0) { - safe_free(p->sslcapath); - p->sslcapath = xstrdup(token + 10); - } else if (strncmp(token, "sslcrlfile=", 11) == 0) { - safe_free(p->sslcrlfile); - p->sslcapath = xstrdup(token + 10); - } else if (strncmp(token, "sslflags=", 9) == 0) { - safe_free(p->sslflags); - p->sslflags = xstrdup(token + 9); } else if (strncmp(token, "ssldomain=", 10) == 0) { safe_free(p->ssldomain); p->ssldomain = xstrdup(token + 10); + } else if (strncmp(token, "ssl-", 4) == 0) { + p->ssl.parseOne(token+4); + } else if (strncmp(token, "ssl", 3) == 0) { + // old options were 'sslfoo='. Do a quiet upgrade for now. + p->ssl.parseOne(token+3); + debugs(3, DBG_PARSE_NOTE(2), "UPGRADE: cache_peer option '" << token << "' is replaced by 'ssl-" << (token+3) << "'"); #endif } else if (strcmp(token, "front-end-https") == 0) { @@ -3518,6 +3499,9 @@ parse_port_option(AnyP::PortCfg * s, char *token) { /* modes first */ +#if USE_SSL + static int sslUpgradeWarnLevel = DBG_IMPORTANT; +#endif if (strcmp(token, "accel") == 0) { if (s->intercepted || s->spoof_client_ip) { @@ -3657,45 +3641,58 @@ } #if USE_SSL } else if (strcasecmp(token, "sslBump") == 0) { - debugs(3, DBG_CRITICAL, "WARNING: '" << token << "' is deprecated " << + debugs(3, DBG_PARSE_NOTE(1), "WARNING: '" << token << "' is deprecated " << "in http_port. Use 'ssl-bump' instead."); s->sslBump = 1; // accelerated when bumped, otherwise not } else if (strcmp(token, "ssl-bump") == 0) { s->sslBump = 1; // accelerated when bumped, otherwise not + } else if (strncmp(token, "ssl-", 5) == 0) { + s->ssl.parseOne(token+4); // any SSL option prefixed by 'ssl-' + } else if (strncmp(token, "cert=", 5) == 0) { - safe_free(s->cert); - s->cert = xstrdup(token + 5); + s->ssl.parseOne(token); + debugs(3, DBG_PARSE_NOTE(sslUpgradeWarnLevel), "UPGRADE: http(s)_port SSL options are prefixed with 'ssl-...'. Spotted: " << token); + sslUpgradeWarnLevel=2; } else if (strncmp(token, "key=", 4) == 0) { - safe_free(s->key); - s->key = xstrdup(token + 4); + s->ssl.parseOne(token); + debugs(3, DBG_PARSE_NOTE(sslUpgradeWarnLevel), "UPGRADE: http(s)_port SSL options are prefixed with 'ssl-...'. Spotted: " << token); + sslUpgradeWarnLevel=2; } else if (strncmp(token, "version=", 8) == 0) { - s->version = xatoi(token + 8); - if (s->version < 1 || s->version > 4) - self_destruct(); + s->ssl.parseOne(token); + debugs(3, DBG_PARSE_NOTE(sslUpgradeWarnLevel), "UPGRADE: http(s)_port SSL options are prefixed with 'ssl-...'. Spotted: " << token); + sslUpgradeWarnLevel=2; } else if (strncmp(token, "options=", 8) == 0) { - safe_free(s->options); - s->options = xstrdup(token + 8); + s->ssl.parseOne(token); + debugs(3, DBG_PARSE_NOTE(sslUpgradeWarnLevel), "UPGRADE: http(s)_port SSL options are prefixed with 'ssl-...'. Spotted: " << token); + sslUpgradeWarnLevel=2; } else if (strncmp(token, "cipher=", 7) == 0) { - safe_free(s->cipher); - s->cipher = xstrdup(token + 7); + s->ssl.parseOne(token); + debugs(3, DBG_PARSE_NOTE(sslUpgradeWarnLevel), "UPGRADE: http(s)_port SSL options are prefixed with 'ssl-...'. Spotted: " << token); + sslUpgradeWarnLevel=2; } else if (strncmp(token, "clientca=", 9) == 0) { - safe_free(s->clientca); - s->clientca = xstrdup(token + 9); + s->ssl.parseOne(token); + debugs(3, DBG_PARSE_NOTE(sslUpgradeWarnLevel), "UPGRADE: http(s)_port SSL options are prefixed with 'ssl-...'. Spotted: " << token); + sslUpgradeWarnLevel=2; } else if (strncmp(token, "cafile=", 7) == 0) { - safe_free(s->cafile); - s->cafile = xstrdup(token + 7); + s->ssl.parseOne(token); + debugs(3, DBG_PARSE_NOTE(sslUpgradeWarnLevel), "UPGRADE: http(s)_port SSL options are prefixed with 'ssl-...'. Spotted: " << token); + sslUpgradeWarnLevel=2; } else if (strncmp(token, "capath=", 7) == 0) { - safe_free(s->capath); - s->capath = xstrdup(token + 7); + s->ssl.parseOne(token); + debugs(3, DBG_PARSE_NOTE(sslUpgradeWarnLevel), "UPGRADE: http(s)_port SSL options are now prefixed with 'ssl-...'. Spotted: " << token); + sslUpgradeWarnLevel=2; } else if (strncmp(token, "crlfile=", 8) == 0) { - safe_free(s->crlfile); - s->crlfile = xstrdup(token + 8); + s->ssl.parseOne(token); + debugs(3, DBG_PARSE_NOTE(sslUpgradeWarnLevel), "UPGRADE: http(s)_port SSL options are now prefixed with 'ssl-...'. Spotted: " << token); + sslUpgradeWarnLevel=2; } else if (strncmp(token, "dhparams=", 9) == 0) { - safe_free(s->dhfile); - s->dhfile = xstrdup(token + 9); + s->ssl.parseOne(token); + debugs(3, DBG_PARSE_NOTE(sslUpgradeWarnLevel), "UPGRADE: http(s)_port SSL options are prefixed with 'ssl-...'. Spotted: " << token); + sslUpgradeWarnLevel=2; } else if (strncmp(token, "sslflags=", 9) == 0) { - safe_free(s->sslflags); - s->sslflags = xstrdup(token + 9); + s->ssl.parseOne(token+3); + debugs(3, DBG_PARSE_NOTE(sslUpgradeWarnLevel), "UPGRADE: http(s)_port SSL options are prefixed with 'ssl-...'. Spotted: " << token); + sslUpgradeWarnLevel=2; } else if (strncmp(token, "sslcontext=", 11) == 0) { safe_free(s->sslContextSessionId); s->sslContextSessionId = xstrdup(token + 11); @@ -3864,35 +3861,35 @@ if (s->sslBump) storeAppendPrintf(e, " ssl-bump"); - if (s->cert) - storeAppendPrintf(e, " cert=%s", s->cert); - - if (s->key) - storeAppendPrintf(e, " key=%s", s->key); - - if (s->version) - storeAppendPrintf(e, " version=%d", s->version); - - if (s->options) - storeAppendPrintf(e, " options=%s", s->options); - - if (s->cipher) - storeAppendPrintf(e, " cipher=%s", s->cipher); - - if (s->cafile) - storeAppendPrintf(e, " cafile=%s", s->cafile); - - if (s->capath) - storeAppendPrintf(e, " capath=%s", s->capath); - - if (s->crlfile) - storeAppendPrintf(e, " crlfile=%s", s->crlfile); - - if (s->dhfile) - storeAppendPrintf(e, " dhparams=%s", s->dhfile); - - if (s->sslflags) - storeAppendPrintf(e, " sslflags=%s", s->sslflags); + if (s->ssl.certfile) + storeAppendPrintf(e, " ssl-cert=%s", s->ssl.certfile); + + if (s->ssl.keyfile) + storeAppendPrintf(e, " ssl-key=%s", s->ssl.keyfile); + + if (s->ssl.version) + storeAppendPrintf(e, " ssl-version=%d", s->ssl.version); + + if (s->ssl.options) + storeAppendPrintf(e, " ssl-options=%s", s->ssl.options); + + if (s->ssl.cipher) + storeAppendPrintf(e, " ssl-cipher=%s", s->ssl.cipher); + + if (s->ssl.CAfile) + storeAppendPrintf(e, " ssl-cafile=%s", s->ssl.CAfile); + + if (s->ssl.CApath) + storeAppendPrintf(e, " ssl-capath=%s", s->ssl.CApath); + + if (s->ssl.CRLfile) + storeAppendPrintf(e, " ssl-crlfile=%s", s->ssl.CRLfile); + + if (s->ssl.DHfile) + storeAppendPrintf(e, " ssl-dhparams=%s", s->ssl.DHfile); + + if (s->ssl.flags) + storeAppendPrintf(e, " ssl-flags=%s", s->ssl.flags); if (s->sslContextSessionId) storeAppendPrintf(e, " sslcontext=%s", s->sslContextSessionId); === modified file 'src/cf.data.depend' --- src/cf.data.depend 2012-10-26 19:42:31 +0000 +++ src/cf.data.depend 2012-11-26 01:01:22 +0000 @@ -57,7 +57,7 @@ removalpolicy size_t IpAddress_list -string +ssl_options string time_msec time_t === modified file 'src/cf.data.pre' --- src/cf.data.pre 2012-10-29 01:31:29 +0000 +++ src/cf.data.pre 2013-06-26 07:07:34 +0000 @@ -2008,12 +2008,91 @@ would like to use hardware SSL acceleration for example. DOC_END +NAME: ssl_proxy_direct +IFDEF: USE_SSL +LOC: none +DEFAULT: none +TYPE: ssl_options +DOC_START + SSL options to use when connecting to upstream HTTPS servers. + + This directive accepts a series of key=value pairs the same + as would be set on a cache_peer directive, but these options + are used for DIRECT traffic. + + ==== OPTIONS ==== + + cert=/path/to/ssl/certificate + A client SSL certificate to use when connecting to + upstream servers. + + key=/path/to/ssl/key + The private SSL key corresponding to sslcert above. + If 'sslkey' is not specified 'sslcert' is assumed to + reference a combined file containing both the + certificate and the key. + + version=1|2|3|4|5|6 + The SSL version to use when connecting to upstream servers + 1 = automatic (default) + 2 = SSL v2 only + 3 = SSL v3 only + 4 = TLS v1.0 only + 5 = TLS v1.1 only + 6 = TLS v1.2 only + + cipher=... The list of valid SSL ciphers to use when connecting + to upstream servers. + + options=... Specify various SSL implementation options: + + NO_SSLv2 Disallow the use of SSLv2 + NO_SSLv3 Disallow the use of SSLv3 + NO_TLSv1 Disallow the use of TLSv1.0 + NO_TLSv1_1 Disallow the use of TLSv1.1 + NO_TLSv1_2 Disallow the use of TLSv1.2 + SINGLE_DH_USE + Always create a new key when using + temporary/ephemeral DH key exchanges + ALL Enable various bug workarounds + suggested as "harmless" by OpenSSL + Be warned that this reduces SSL/TLS + strength to some attacks. + + See the OpenSSL SSL_CTX_set_options documentation for a + more complete list. + + cafile=... A file containing additional CA certificates to use + when verifying the server certificate. + + capath=... A directory containing additional CA certificates to + use when verifying the server certificate. + + crlfile=... A certificate revocation list file to use when + verifying the server certificate. + + flags=... Specify various flags modifying the SSL implementation: + + DONT_VERIFY_PEER + Accept all server certificates even if they + fail to verify. + NO_DEFAULT_CA + Don't use the default CA list built in + to OpenSSL. + DONT_VERIFY_DOMAIN + Don't verify the server certificate + matches the server name + +DOC_END + NAME: sslproxy_client_certificate IFDEF: USE_SSL DEFAULT: none LOC: Config.ssl_client.cert TYPE: string DOC_START + Deprecated. Instead use: ssl_proxy_direct cert=... + Client SSL Certificate to use when proxying https:// URLs DOC_END @@ -2023,6 +2102,8 @@ LOC: Config.ssl_client.key TYPE: string DOC_START + Deprecated. Instead use: ssl_proxy_direct key=... + Client SSL Key to use when proxying https:// URLs DOC_END @@ -2032,6 +2113,8 @@ LOC: Config.ssl_client.version TYPE: int DOC_START + Deprecated. Instead use: ssl_proxy_direct version=... + SSL version level to use when proxying https:// URLs The versions of SSL/TLS supported: @@ -2042,6 +2125,7 @@ 4 TLSv1.0 only 5 TLSv1.1 only 6 TLSv1.2 only + DOC_END NAME: sslproxy_options @@ -2050,6 +2134,8 @@ LOC: Config.ssl_client.options TYPE: string DOC_START + Deprecated. Instead use: ssl_proxy_direct options=... + SSL implementation options to use when proxying https:// URLs The most important being: @@ -2080,6 +2166,8 @@ LOC: Config.ssl_client.cipher TYPE: string DOC_START + Deprecated. Instead use: ssl_proxy_direct cipher=... + SSL cipher list to use when proxying https:// URLs Colon separated list of supported ciphers. @@ -2091,6 +2179,8 @@ LOC: Config.ssl_client.cafile TYPE: string DOC_START + Deprecated. Instead use: ssl_proxy_direct cafile=... + file containing CA certificates to use when verifying server certificates while proxying https:// URLs DOC_END @@ -2101,10 +2191,27 @@ LOC: Config.ssl_client.capath TYPE: string DOC_START + Deprecated. Instead use: ssl_proxy_direct capath=... + directory containing CA certificates to use when verifying server certificates while proxying https:// URLs DOC_END +NAME: sslproxy_flags +IFDEF: USE_SSL +DEFAULT: none +LOC: Config.ssl_client.flags +TYPE: string +DOC_START + Deprecated. Instead use: ssl_proxy_direct flags=... + + Various flags modifying the use of SSL while proxying https:// URLs: + DONT_VERIFY_PEER Accept certificates that fail verification. + For refined control, see sslproxy_cert_error. + NO_DEFAULT_CA Don't use the default CA list built in + to OpenSSL. +DOC_END + NAME: ssl_bump IFDEF: USE_SSL TYPE: sslproxy_ssl_bump @@ -2163,19 +2270,6 @@ ssl_bump server-first all DOC_END -NAME: sslproxy_flags -IFDEF: USE_SSL -DEFAULT: none -LOC: Config.ssl_client.flags -TYPE: string -DOC_START - Various flags modifying the use of SSL while proxying https:// URLs: - DONT_VERIFY_PEER Accept certificates that fail verification. - For refined control, see sslproxy_cert_error. - NO_DEFAULT_CA Don't use the default CA list built in - to OpenSSL. -DOC_END - NAME: sslproxy_cert_error IFDEF: USE_SSL DEFAULT: none === modified file 'src/ssl/Config.cc' --- src/ssl/Config.cc 2012-10-04 11:10:17 +0000 +++ src/ssl/Config.cc 2013-07-01 21:10:12 +0000 @@ -1,4 +1,6 @@ #include "squid.h" +#include "Debug.h" +#include "Parsing.h" #include "ssl/Config.h" Ssl::Config Ssl::TheConfig; @@ -17,3 +19,70 @@ xfree(ssl_crtd); #endif } + +void +Ssl::Config::parse(const char *name) +{ + // XXX: use name to determine what parsing style + + if (strcmp(name, "ssl_proxy_direct") != 0) { + // directive formed from key=value pairs + // XXX: need to support quoted string values with whitespace + + const char *token = NULL; + while ((token = strtok(NULL, w_space)) != NULL) { + if (!sslProxyDirect.parseOne(token)) { + debugs(3, DBG_CRITICAL, "ERROR: Ingnoring unknown SSL option '" << token << "'."); + } + } + } + else { + // XXX: for the deprecated options - parse directly into the particular field indicated by name. + } +} + +bool +Ssl::ConfigOptions::parseOne(const char *token) +{ + if (strncmp(token, "cert=", 5) == 0) { + xfree(certfile); + certfile = xstrdup(token + 5); + } else if (strncmp(token, "key=", 4) == 0) { + xfree(keyfile); + keyfile = xstrdup(token + 4); + } else if (strncmp(token, "version=", 8) == 0) { + version = xatoi(token + 8); + if (version < 1 || version > 6) { + debugs(0,DBG_IMPORTANT, "Unknown SSL version '" << (token+8) << "'"); + return false; + } + } else if (strncmp(token, "options=", 8) == 0) { + xfree(options); + options = xstrdup(token + 8); + } else if (strncmp(token, "cipher=", 7) == 0) { + xfree(cipher); + cipher = xstrdup(token + 7); + } else if (strncmp(token, "clientca=", 9) == 0) { + xfree(clientCA); + clientCA = xstrdup(token + 9); + } else if (strncmp(token, "cafile=", 7) == 0) { + xfree(CAfile); + CAfile = xstrdup(token + 7); + } else if (strncmp(token, "capath=", 7) == 0) { + xfree(CApath); + CApath = xstrdup(token + 7); + } else if (strncmp(token, "crlfile=", 8) == 0) { + xfree(CRLfile); + CRLfile = xstrdup(token + 8); + } else if (strncmp(token, "dhparams=", 9) == 0) { + xfree(DHfile); + DHfile = xstrdup(token + 9); + } else if (strncmp(token, "flags=", 6) == 0) { + xfree(flags); + flags = xstrdup(token + 6); + } else { + return false; + } + + return true; +} === modified file 'src/ssl/Config.h' --- src/ssl/Config.h 2012-10-04 11:10:17 +0000 +++ src/ssl/Config.h 2013-07-01 21:10:05 +0000 @@ -1,14 +1,63 @@ -#ifndef SQUID_SSL_CONFIG_H -#define SQUID_SSL_CONFIG_H +#ifndef SQUID_SRC_SSL_CONFIG_H +#define SQUID_SRC_SSL_CONFIG_H #include "HelperChildConfig.h" namespace Ssl { +/// parse and store the configuration options used +/// for generating an SSL context +class ConfigOptions +{ +public: + ConfigOptions() { memset(this, 0, sizeof(ConfigOptions)); }; + ConfigOptions(const Ssl::ConfigOptions &other) : + certfile(other.certfile?xstrdup(other.certfile):NULL), + keyfile(other.keyfile?xstrdup(other.keyfile):NULL), + version(other.version), + cipher(other.cipher?xstrdup(other.cipher):NULL), + flags(other.flags?xstrdup(other.flags):NULL), + clientCA(other.clientCA?xstrdup(other.clientCA):NULL), + CAfile(other.CAfile?xstrdup(other.CAfile):NULL), + CApath(other.CApath?xstrdup(other.CApath):NULL), + CRLfile(other.CRLfile?xstrdup(other.CRLfile):NULL), + DHfile(other.DHfile?xstrdup(other.DHfile):NULL) + {} + ~ConfigOptions() { + xfree(certfile); + xfree(keyfile); + xfree(cipher); + xfree(flags); + xfree(clientCA); + xfree(CAfile); + xfree(CApath); + xfree(CRLfile); + xfree(DHfile); + } + +public: // options text as found in squid.conf parameters + char *certfile; // public cert file + char *keyfile; // private key file + int version; + char *cipher; + char *options; + char *flags; + char *clientCA; + char *CAfile; + char *CApath; // path where CAfile may be found + char *CRLfile; + char *DHfile; + + /// parse one option token as given on http(s)_port and cache_peer directives + bool parseOne(const char *cfg); +}; + class Config { public: + ConfigOptions sslProxyDirect; ///< options used to generate the DIRECT outgoing context + #if USE_SSL_CRTD char *ssl_crtd; ///< Name of external ssl_crtd application. /// The number of processes spawn for ssl_crtd. @@ -16,6 +65,7 @@ #endif Config(); ~Config(); + void parse(const char *name); ///< parse a SSL config directive. private: Config(const Config &); // not implemented Config &operator =(const Config &); // not implemented @@ -24,4 +74,9 @@ extern Config TheConfig; } // namespace Ssl + +#define parse_ssl_options() Ssl::TheConfig.parse(token); +#define free_ssl_options() // TODO +#define dump_ssl_options(e,n,x) // TODO + #endif === modified file 'src/ssl/support.cc' --- src/ssl/support.cc 2012-11-23 06:03:26 +0000 +++ src/ssl/support.cc 2012-11-23 14:03:56 +0000 @@ -778,12 +778,12 @@ SSL_CTX_set_quiet_shutdown(sslContext.get(), 1); } - if (port.cipher) { - debugs(83, 5, "Using chiper suite " << port.cipher << "."); + if (port.ssl.cipher) { + debugs(83, 5, "Using chiper suite " << port.ssl.cipher << "."); - if (!SSL_CTX_set_cipher_list(sslContext.get(), port.cipher)) { + if (!SSL_CTX_set_cipher_list(sslContext.get(), port.ssl.cipher)) { ssl_error = ERR_get_error(); - debugs(83, DBG_CRITICAL, "ERROR: Failed to set SSL cipher suite '" << port.cipher << "': " << ERR_error_string(ssl_error, NULL)); + debugs(83, DBG_CRITICAL, "ERROR: Failed to set SSL cipher suite '" << port.ssl.cipher << "': " << ERR_error_string(ssl_error, NULL)); return false; } } @@ -793,8 +793,8 @@ debugs(83, 9, "Setting CA certificate locations."); - const char *cafile = port.cafile ? port.cafile : port.clientca; - if ((cafile || port.capath) && !SSL_CTX_load_verify_locations(sslContext.get(), cafile, port.capath)) { + const char *cafile = port.ssl.CAfile ? port.ssl.CAfile : port.ssl.clientCA; + if ((cafile || port.ssl.CApath) && !SSL_CTX_load_verify_locations(sslContext.get(), cafile, port.ssl.CApath)) { ssl_error = ERR_get_error(); debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate locations: " << ERR_error_string(ssl_error, NULL)); } @@ -856,8 +856,8 @@ // build the context in a temporary which will do any cleanup // store in 'result' parameter only if successfully created. const char *keyfile, *certfile; - certfile = port.cert; - keyfile = port.key; + certfile = port.ssl.certfile; + keyfile = port.ssl.keyfile; ssl_initialize(); @@ -938,7 +938,8 @@ } bool -Ssl::CreateClientContext(Ssl::SSL_CTX_Pointer &result, 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::CreateClientContext(Ssl::SSL_CTX_Pointer &result, const Ssl::ConfigOptions &cfg) +// 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) { #if HAVE_OPENSSL int ssl_error; @@ -947,17 +948,19 @@ #else const SSL_METHOD *method; #endif - long fl = Ssl::parse_flags(flags); + long fl = Ssl::parse_flags(cfg.flags); ssl_initialize(); + char *keyfile = cfg.keyfile; if (!keyfile) - keyfile = certfile; + keyfile = cfg.certfile; + char *certfile = cfg.certfile; if (!certfile) - certfile = keyfile; + certfile = cfg.keyfile; - switch (version) { + switch (cfg.version) { case 2: #ifndef OPENSSL_NO_SSL2 @@ -1015,15 +1018,15 @@ ERR_error_string(ssl_error, NULL)); } - SSL_CTX_set_options(sslContext.get(), Ssl::parse_options(options)); - - if (cipher) { - debugs(83, 5, "Using chiper suite " << cipher << "."); - - if (!SSL_CTX_set_cipher_list(sslContext.get(), cipher)) { + SSL_CTX_set_options(sslContext.get(), Ssl::parse_options(cfg.options)); + + if (cfg.cipher) { + debugs(83, 5, "Using chiper suite " << cfg.cipher << "."); + + if (!SSL_CTX_set_cipher_list(sslContext.get(), cfg.cipher)) { ssl_error = ERR_get_error(); fatalf("Failed to set SSL cipher suite '%s': %s\n", - cipher, ERR_error_string(ssl_error, NULL)); + cfg.cipher, ERR_error_string(ssl_error, NULL)); } } @@ -1067,13 +1070,13 @@ debugs(83, 9, "Setting CA certificate locations."); - if ((CAfile || CApath) && !SSL_CTX_load_verify_locations(sslContext.get(), CAfile, CApath)) { + if ((cfg.CAfile || cfg.CApath) && !SSL_CTX_load_verify_locations(sslContext.get(), cfg.CAfile, cfg.CApath)) { ssl_error = ERR_get_error(); debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate locations: " << ERR_error_string(ssl_error, NULL)); } - if (CRLfile) { - ssl_load_crl(sslContext.get(), CRLfile); + if (cfg.CRLfile) { + ssl_load_crl(sslContext.get(), cfg.CRLfile); fl |= SSL_FLAG_VERIFY_CRL; } === modified file 'src/ssl/support.h' --- src/ssl/support.h 2012-11-23 05:39:27 +0000 +++ src/ssl/support.h 2012-11-23 14:18:55 +0000 @@ -72,6 +72,8 @@ namespace Ssl { +class ConfigOptions; + /// Squid defined error code (<0), an error code returned by SSL X509 api, or SSL_ERROR_NONE typedef int ssl_error_t; @@ -81,7 +83,7 @@ bool CreateServerContext(SSL_CTX_Pointer &sslContext, AnyP::PortCfg &port); /// \ingroup ServerProtocolSSLAPI -bool CreateClientContext(SSL_CTX_Pointer &sslContext, 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); +bool CreateClientContext(SSL_CTX_Pointer &sslContext, const Ssl::ConfigOptions &options); } //namespace Ssl