This creates an Ssl::Config class to manage SSL configuration settings
and creates a ConfigOptions sub-class to hold the settings which are
needed passing around in the SSL code.
Functional changes are all in the parsing and SSL options for
cache_peer, http(s)_port are aligned and a new directive
ssl_proxy_direct is added to combine the DIRECT SSL connection settings
with the same set of options.
TODO:
* implement dump/free functions properly
* implement parse for backward-compatible loading of the old DIRECT SSL
settings options.
Amos
=== 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 <openssl/ssl.h>
#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