<sect1>New tags<label id="newtags">
<p>
<descrip>
- <tag> url_rewrite_timeout </tag>
- <p> Squid times active requests to redirector. This option sets
- the timeout value and the Squid reaction to a timed out
- request. </p>
+ <tag>tls_outgoing_options</tag>
+ <p>New tag to define TLS security context options for outgoing
+ connections. For example to HTTPS servers.
+
+ <tag>url_rewrite_timeout</tag>
+ <p>Squid times active requests to redirector. This option sets
+ the timeout value and the Squid reaction to a timed out
+ request.
+
</descrip>
<sect1>Changes to existing tags<label id="modifiedtags">
<sect1>Removed tags<label id="removedtags">
<p>
<descrip>
+ <tag>cache_peer_domain</tag>
+ <p>Superceded by <em>cache_peer_access</em>. Use dstdomain ACL
+ in the access control list to restrict domains requested.
+
+ <tag>refresh_pattern</tag>
+ <p>Option <em>ignore-auth</em> removed. Its original intent was
+ to improve caching. HTTP/1.1 permits caching of authenticated
+ messages under conditions which Squid does check for and obey.
+
+ <tag>sslproxy_cafile</tag>
+ <p>Replaced by <em>tls_outgoing_options cafile=</em>.
+
+ <tag>sslproxy_capath</tag>
+ <p>Replaced by <em>tls_outgoing_options capath=</em>.
+
+ <tag>sslproxy_cipher</tag>
+ <p>Replaced by <em>tls_outgoing_options cipher=</em>.
+
+ <tag>sslproxy_client_certificate</tag>
+ <p>Replaced by <em>tls_outgoing_options cert=</em>.
+
+ <tag>sslproxy_client_key</tag>
+ <p>Replaced by <em>tls_outgoing_options key=</em>.
+
+ <tag>sslproxy_flags</tag>
+ <p>Replaced by <em>tls_outgoing_options flags=</em>.
+
+ <tag>sslproxy_options</tag>
+ <p>Replaced by <em>tls_outgoing_options options=</em>.
+
+ <tag>sslproxy_version</tag>
+ <p>Replaced by <em>tls_outgoing_options version=</em>.
+
</descrip>
--- /dev/null
- use_ssl(0),
- sslcert(NULL),
- sslkey(NULL),
- sslversion(0),
- ssloptions(NULL),
- sslcipher(NULL),
- sslcafile(NULL),
- sslcapath(NULL),
- sslcrlfile(NULL),
- sslflags(NULL),
- ssldomain(NULL),
+ /*
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+ #include "squid.h"
+ #include "acl/Gadgets.h"
+ #include "CachePeer.h"
+ #include "defines.h"
+ #include "NeighborTypeDomainList.h"
+ #include "pconn.h"
+ #include "PeerPoolMgr.h"
+
+ CBDATA_CLASS_INIT(CachePeer);
+
+ CachePeer::CachePeer() :
+ index(0),
+ name(NULL),
+ host(NULL),
+ type(PEER_NONE),
+ http_port(CACHE_HTTP_PORT),
+ typelist(NULL),
+ access(NULL),
+ weight(1),
+ basetime(0),
+ #if USE_CACHE_DIGESTS
+ digest(NULL),
+ digest_url(NULL),
+ #endif
+ tcp_up(0),
+ n_addresses(0),
+ rr_count(0),
+ next(NULL),
+ testing_now(false),
+ login(NULL),
+ connect_timeout(0),
+ connect_fail_limit(0),
+ max_conn(0),
+ domain(NULL),
+ #if USE_OPENSSL
- xfree(sslcert);
- xfree(sslkey);
- xfree(ssloptions);
- xfree(sslcipher);
- xfree(sslcafile);
- xfree(sslcapath);
- xfree(sslcrlfile);
- xfree(sslflags);
- xfree(ssldomain);
-
+ sslContext(NULL),
+ sslSession(NULL),
+ #endif
+ front_end_https(0),
+ connection_auth(2 /* auto */)
+ {
+ memset(&stats, 0, sizeof(stats));
+ stats.logged_state = PEER_ALIVE;
+
+ memset(&icp, 0, sizeof(icp));
+ icp.port = CACHE_ICP_PORT;
+ icp.version = ICP_VERSION_CURRENT;
+
+ #if USE_HTCP
+ memset(&htcp, 0, sizeof(htcp));
+ #endif
+ memset(&options, 0, sizeof(options));
+ memset(&mcast, 0, sizeof(mcast));
+ memset(&carp, 0, sizeof(carp));
+ #if USE_AUTH
+ memset(&userhash, 0, sizeof(userhash));
+ #endif
+ memset(&sourcehash, 0, sizeof(sourcehash));
+
+ standby.pool = NULL;
+ standby.limit = 0;
+ standby.waitingForClose = false;
+ }
+
+ CachePeer::~CachePeer()
+ {
+ xfree(name);
+ xfree(host);
+
+ while (NeighborTypeDomainList *l = typelist) {
+ typelist = l->next;
+ xfree(l->domain);
+ xfree(l);
+ }
+
+ aclDestroyAccessList(&access);
+
+ #if USE_CACHE_DIGESTS
+ cbdataReferenceDone(digest);
+ xfree(digest_url);
+ #endif
+
+ delete next;
+
+ xfree(login);
+
+ delete standby.pool;
+
+ // the mgr job will notice that its owner is gone and stop
+ PeerPoolMgr::Checkpoint(standby.mgr, "peer gone");
+
+ xfree(domain);
+
+ #if USE_OPENSSL
+ if (sslContext)
+ SSL_CTX_free(sslContext);
+
+ if (sslSession)
+ SSL_SESSION_free(sslSession);
+ #endif
+ }
+
helper/libhelper.la \
http/libsquid-http.la \
parser/libsquid-parser.la \
+ dns/libdns.la \
+ security/libsecurity.la \
base/libbase.la \
libsquid.la \
ip/libip.la \
debugs(3, DBG_IMPORTANT, "Initializing https proxy context");
- Config.ssl_client.sslContext = Security::ProxyOutgoingConfig.createContext();
- Config.ssl_client.sslContext = sslCreateClientContext(Config.ssl_client.cert, Config.ssl_client.key, Config.ssl_client.version, Config.ssl_client.cipher, NULL, Config.ssl_client.flags, Config.ssl_client.cafile, Config.ssl_client.capath, Config.ssl_client.crlfile);
- // 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.
- Config.ssl_client.parsedOptions = Ssl::parse_options(::Config.ssl_client.options);
++ Config.ssl_client.sslContext = Security::ProxyOutgoingConfig.createContext(false);
for (CachePeer *p = Config.peers; p != NULL; p = p->next) {
- if (p->use_ssl) {
+
+ // default value for ssldomain= is the peer host/IP
+ if (p->secure.sslDomain.isEmpty())
+ p->secure.sslDomain = p->host;
+
+ if (p->secure.encryptTransport) {
debugs(3, DBG_IMPORTANT, "Initializing cache_peer " << p->name << " SSL context");
- p->sslContext = p->secure.createContext();
- p->sslContext = sslCreateClientContext(p->sslcert, p->sslkey, p->sslversion, p->sslcipher, p->ssloptions, p->sslflags, p->sslcafile, p->sslcapath, p->sslcrlfile);
++ p->sslContext = p->secure.createContext(true);
}
}
DOC_END
# Options removed in 3.6
+ NAME: cache_peer_domain cache_host_domain
+ TYPE: obsolete
+ DOC_START
+ Replace with dstdomain ACLs and cache_peer_access.
+ DOC_END
+
+NAME: sslproxy_cafile
+TYPE: obsolete
+DOC_START
+ Remove this line. Use tls_outgoing_options cafile= instead.
+DOC_END
+
+NAME: sslproxy_capath
+TYPE: obsolete
+DOC_START
+ Remove this line. Use tls_outgoing_options capath= instead.
+DOC_END
+
+NAME: sslproxy_cipher
+TYPE: obsolete
+DOC_START
+ Remove this line. Use tls_outgoing_options cipher= instead.
+DOC_END
+
+NAME: sslproxy_client_certificate
+TYPE: obsolete
+DOC_START
+ Remove this line. Use tls_outgoing_options cert= instead.
+DOC_END
+
+NAME: sslproxy_client_key
+TYPE: obsolete
+DOC_START
+ Remove this line. Use tls_outgoing_options key= instead.
+DOC_END
+
+NAME: sslproxy_flags
+TYPE: obsolete
+DOC_START
+ Remove this line. Use tls_outgoing_options flags= instead.
+DOC_END
+
+NAME: sslproxy_options
+TYPE: obsolete
+DOC_START
+ Remove this line. Use tls_outgoing_options options= instead.
+DOC_END
+
+NAME: sslproxy_version
+TYPE: obsolete
+DOC_START
+ Remove this line. Use tls_outgoing_options version= instead.
+DOC_END
+
# Options removed in 3.5
NAME: hierarchy_stoplist
TYPE: obsolete
options= Various SSL implementation options. The most important
being:
+
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
+
+ SINGLE_DH_USE
+ Always create a new key when using
temporary/ephemeral DH key exchanges
- NO_TICKET Disables TLS tickets extension
+
- SSL_OP_NO_TICKET
++ NO_TICKET
+ Disable use of RFC5077 session tickets.
+ Some servers may have problems
+ understanding the TLS extension due
+ to ambiguous specification in RFC4507.
+
ALL Enable various bug workarounds
suggested as "harmless" by OpenSSL
Be warned that this reduces SSL/TLS
--- /dev/null
- Security::PeerOptions::createContext()
+/*
+ * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+#include "Debug.h"
+#include "globals.h"
+#include "Parsing.h"
+#include "security/PeerOptions.h"
+
+#if USE_OPENSSL
+#include "ssl/support.h"
+#endif
+
+Security::PeerOptions Security::ProxyOutgoingConfig;
+
+void
+Security::PeerOptions::parse(const char *token)
+{
+ if (strncmp(token, "cert=", 5) == 0) {
+ certFile = SBuf(token + 5);
+ if (privateKeyFile.isEmpty())
+ privateKeyFile = certFile;
+ } else if (strncmp(token, "key=", 4) == 0) {
+ privateKeyFile = SBuf(token + 4);
+ if (certFile.isEmpty()) {
+ debugs(0, DBG_PARSE_NOTE(1), "WARNING: cert= option needs to be set before key= is used.");
+ certFile = privateKeyFile;
+ }
+ } else if (strncmp(token, "version=", 8) == 0) {
+ sslVersion = xatoi(token + 8);
+ } else if (strncmp(token, "options=", 8) == 0) {
+ sslOptions = SBuf(token + 8);
++#if USE_OPENSSL
++ // 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());
++#endif
+ } else if (strncmp(token, "cipher=", 7) == 0) {
+ sslCipher = SBuf(token + 7);
+ } else if (strncmp(token, "cafile=", 7) == 0) {
+ caFile = SBuf(token + 7);
+ } else if (strncmp(token, "capath=", 7) == 0) {
+ caDir = SBuf(token + 7);
+ } else if (strncmp(token, "crlfile=", 8) == 0) {
+ crlFile = SBuf(token + 8);
+ } else if (strncmp(token, "flags=", 6) == 0) {
+ sslFlags = SBuf(token + 6);
+ } else if (strncmp(token, "domain=", 7) == 0) {
+ sslDomain = SBuf(token + 7);
+ }
+}
+
+// XXX: make a GnuTLS variant
+Security::ContextPointer
- sslOptions.c_str(), sslFlags.c_str(), caFile.c_str(), caDir.c_str(), crlFile.c_str());
++Security::PeerOptions::createContext(bool setOptions)
+{
+ Security::ContextPointer t = NULL;
+
+#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());
+#endif
++
+ return t;
+}
+
+void
+parse_securePeerOptions(Security::PeerOptions *opt)
+{
+ while(const char *token = ConfigParser::NextToken())
+ opt->parse(token);
+}
+
--- /dev/null
- Security::ContextPointer createContext();
+/*
+ * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#ifndef SQUID_SRC_SECURITY_PEEROPTIONS_H
+#define SQUID_SRC_SECURITY_PEEROPTIONS_H
+
+#include "ConfigParser.h"
+#include "SBuf.h"
+#include "security/Context.h"
+
+namespace Security
+{
+
+/// TLS squid.conf settings for a remote server peer
+class PeerOptions
+{
+public:
+ PeerOptions() : sslVersion(0), encryptTransport(false) {}
+
+ /// parse a TLS squid.conf option
+ void parse(const char *);
+
+ /// reset the configuration details to default
+ void clear() {*this = PeerOptions();}
+
+ /// generate a security context from these configured options
++ Security::ContextPointer createContext(bool setOptions);
+
+ SBuf certFile; ///< path of file containing PEM format X509 certificate
+ SBuf privateKeyFile; ///< path of file containing private key in PEM format
+ SBuf sslOptions; ///< library-specific options string
+ SBuf caFile; ///< path of file containing trusted Certificate Authority
+ SBuf caDir; ///< path of directory containing a set of trusted Certificate Authorities
+ SBuf crlFile; ///< path of file containing Certificate Revoke List
+
+ SBuf sslCipher;
+ SBuf sslFlags;
+ SBuf sslDomain;
+
++ long parsedOptions; ///< parsed value of sslOptions
++
+ int sslVersion;
+
+ /// whether transport encryption (TLS/SSL) is to be used on connections to the peer
+ bool encryptTransport;
+};
+
+/// configuration options for DIRECT server access
+extern PeerOptions ProxyOutgoingConfig;
+
+} // namespace Security
+
+// parse the tls_outgoing_options directive
+void parse_securePeerOptions(Security::PeerOptions *);
+#define free_securePeerOptions(x) Security::ProxyOutgoingConfig.clear()
+#define dump_securePeerOptions(e,n,x) // not supported yet
+
+#endif /* SQUID_SRC_SECURITY_PEEROPTIONS_H */
if (peer->sslSession)
SSL_set_session(ssl, peer->sslSession);
-
- } else if (request->clientConnectionManager->sslBumpMode == Ssl::bumpPeek || request->clientConnectionManager->sslBumpMode == Ssl::bumpStare) {
- // client connection is required for Peek or Stare mode in the case we need to splice
+ } else if (ConnStateData *csd = request->clientConnectionManager.valid()) {
+ // client connection is required in the case we need to splice
// or terminate client and server connections
assert(clientConn != NULL);
- SSL *clientSsl = fd_table[request->clientConnectionManager->clientConnection->fd].ssl;
- BIO *b = SSL_get_rbio(clientSsl);
- Ssl::ClientBio *clnBio = static_cast<Ssl::ClientBio *>(b->ptr);
- const Ssl::Bio::sslFeatures &features = clnBio->getFeatures();
- if (features.sslVersion != -1) {
- features.applyToSSL(ssl);
- // Should we allow it for all protocols?
- if (features.sslVersion >= 3) {
- b = SSL_get_rbio(ssl);
- Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(b->ptr);
- srvBio->setClientFeatures(features);
- srvBio->recordInput(true);
- srvBio->mode(request->clientConnectionManager->sslBumpMode);
- }
+ const char *hostName = NULL;
+ Ssl::ClientBio *cltBio = NULL;
+
+ // In server-first bumping mode, clientSsl is NULL.
+ if (SSL *clientSsl = fd_table[clientConn->fd].ssl) {
+ BIO *b = SSL_get_rbio(clientSsl);
+ cltBio = static_cast<Ssl::ClientBio *>(b->ptr);
+ const Ssl::Bio::sslFeatures &features = cltBio->getFeatures();
+ if (!features.serverName.isEmpty())
+ hostName = features.serverName.c_str();
+ }
- const bool isConnectRequest = request->clientConnectionManager.valid() &&
- !request->clientConnectionManager->port->flags.isIntercepted();
- if (isConnectRequest)
- SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)request->GetHost());
- else if (!features.serverName.isEmpty())
- SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)features.serverName.c_str());
+ if (!hostName) {
+ // While we are peeking at the certificate, we may not know the server
+ // name that the client will request (after interception or CONNECT)
+ // unless it was the CONNECT request with a user-typed address.
+ const bool isConnectRequest = !csd->port->flags.isIntercepted();
+ if (!request->flags.sslPeek || isConnectRequest)
+ hostName = request->GetHost();
+ }
+
+ if (hostName)
+ SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)hostName);
+
+ Must(!csd->serverBump() || csd->serverBump()->step <= Ssl::bumpStep2);
+ if (csd->sslBumpMode == Ssl::bumpPeek || csd->sslBumpMode == Ssl::bumpStare) {
+ assert(cltBio);
+ const Ssl::Bio::sslFeatures &features = cltBio->getFeatures();
+ if (features.sslVersion != -1) {
+ features.applyToSSL(ssl);
+ // Should we allow it for all protocols?
+ if (features.sslVersion >= 3) {
+ BIO *b = SSL_get_rbio(ssl);
+ Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(b->ptr);
+ // Inherite client features, like SSL version, SNI and other
+ srvBio->setClientFeatures(features);
+ srvBio->recordInput(true);
+ srvBio->mode(csd->sslBumpMode);
+ }
+ }
+ } else {
+ // Set client SSL options
- SSL_set_options(ssl, ::Config.ssl_client.parsedOptions);
++ SSL_set_options(ssl, ::Security::ProxyOutgoingConfig.parsedOptions);
+
+ // Use SNI TLS extension only when we connect directly
+ // to the origin server and we know the server host name.
+ const char *sniServer = hostName ? hostName :
+ (!request->GetHostIsNumeric() ? request->GetHost() : NULL);
+ if (sniServer)
+ Ssl::setClientSNI(ssl, sniServer);
}
- } else {
- // While we are peeking at the certificate, we may not know the server
- // name that the client will request (after interception or CONNECT)
- // unless it was the CONNECT request with a user-typed address.
- const char *hostname = request->GetHost();
- const bool hostnameIsIp = request->GetHostIsNumeric();
- const bool isConnectRequest = request->clientConnectionManager.valid() &&
- !request->clientConnectionManager->port->flags.isIntercepted();
- if (!request->flags.sslPeek || isConnectRequest)
- SSL_set_ex_data(ssl, ssl_ex_index_server, (void*)hostname);
-
- // Use SNI TLS extension only when we connect directly
- // to the origin server and we know the server host name.
- if (!hostnameIsIp)
- Ssl::setClientSNI(ssl, hostname);
}
// If CertValidation Helper used do not lookup checklist for errors,
--- /dev/null
- Security::ContextPointer Security::PeerOptions::createContext() STUB_RETVAL(NULL)
+/*
+ * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+
+#define STUB_API "security/libsecurity.la"
+#include "tests/STUB.h"
+
+#include "security/PeerOptions.h"
+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