[squid-dev] [PATCH] Initial libsecurity API
Amos Jeffries
squid3 at treenet.co.nz
Wed Jan 14 15:50:34 UTC 2015
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
This is the first step(s) towards a generic TLS/SSL security API for
Squid.
Creates the basic security/libsecurity.la library and Security::
namespace infrastructure. Symbols provided by this API are always
available instead of conditionally compiled (unlike the ssl/* code for
OpenSSL use).
Merge the TLS/SSL context parameters into a Security::PeerOptions
object instead of maintaining multiple member variables in the
CachePeer and SquidConfig objects.
Squid now provides an error if SSL-specific squid.conf parameters
used for a Squid without OpenSSL support, instead of silently ignoring
them.
Added documentation of an existing bug where the security context for
DIRECT traffic is stored in SquidConfig and leaked on reconfigure.
Amos
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (MingW32)
iQEcBAEBAgAGBQJUtpBIAAoJELJo5wb/XPRjYOcH/0sAFLiWH16ax2zcSbK5Tdq2
bnMl+QzCPYPdx+OSR2ALu27qj3QS4V/TlCj0ASq+3QusJ+tj8f0NO0Se+5+QjIJX
vG1PBwGootGuKRwZUqlSJwAlHJzk0JRz8CZeHQ0FwB6Z2qXnKXIetnw/Smn1ndvW
xeh72eHJbRa/pptI8VmfTbrUpCcWUBnZocYP7nZkTtBL4lY7P0P9cSgFCy/KJtOx
fObOawS9WgGmWdY38eTD58CqBDdCR/pmj30UH+WkWuyWaOuhSlLwxjiRjkQlJtsj
9XZC0UWFJw2/+9tcr4TSk5br0KPwTMBblpk4bD47uAAxympSWuPYWiR6v171gb8=
=4THR
-----END PGP SIGNATURE-----
-------------- next part --------------
=== modified file 'configure.ac'
--- configure.ac 2015-01-13 07:25:36 +0000
+++ configure.ac 2015-01-14 15:09:13 +0000
@@ -3859,36 +3859,37 @@
src/base/Makefile
src/clients/Makefile
src/comm/Makefile
src/esi/Makefile
src/eui/Makefile
src/format/Makefile
src/fs/Makefile
src/ftp/Makefile
src/helper/Makefile
src/http/Makefile
src/http/one/Makefile
src/icmp/Makefile
src/ident/Makefile
src/ip/Makefile
src/ipc/Makefile
src/log/Makefile
src/mem/Makefile
src/mgr/Makefile
src/parser/Makefile
src/repl/Makefile
+ src/security/Makefile
src/servers/Makefile
src/snmp/Makefile
src/ssl/Makefile
test-suite/Makefile
tools/Makefile
tools/helper-mux/Makefile
tools/purge/Makefile
tools/squidclient/Makefile
tools/systemd/Makefile
tools/sysvinit/Makefile
])
# must configure libltdl subdir unconditionally for "make distcheck" to work
#AC_CONFIG_SUBDIRS(libltdl)
AC_OUTPUT
=== modified file 'doc/release-notes/release-3.6.sgml'
--- doc/release-notes/release-3.6.sgml 2015-01-13 07:25:36 +0000
+++ doc/release-notes/release-3.6.sgml 2015-01-14 15:09:41 +0000
@@ -81,40 +81,44 @@
<em>basic_smb_lm_auth</em> helper performs the same actions without extra
Perl and Samba dependencies.
<sect>Changes to squid.conf since Squid-3.5
<p>
There have been changes to Squid's configuration file since Squid-3.5.
This section gives a thorough account of those changes in three categories:
<itemize>
<item><ref id="newtags" name="New tags">
<item><ref id="modifiedtags" name="Changes to existing tags">
<item><ref id="removedtags" name="Removed tags">
</itemize>
<p>
<sect1>New tags<label id="newtags">
<p>
<descrip>
+ <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. </p>
</descrip>
<sect1>Changes to existing tags<label id="modifiedtags">
<p>
<descrip>
<tag>auth_param</tag>
<p>New parameter <em>queue-size=</em> to set the maximum number
of queued requests.
<tag>cache_peer</tag>
<p>All <em>ssloption=</em> and <em>sslversion=</em> values for
SSLv2 configuration or disabling have been removed.
<p>Manual squid.conf update may be required on upgrade.
<tag>external_acl_type<tag>
<p>New parameter <em>queue-size=</em> to set the maximum number
@@ -137,40 +141,63 @@
<tag>sslcrtvalidator_children</tag>
<p>New parameter <em>queue-size=</em> to set the maximum number
of queued requests.
<tag>sslproxy_options</tag>
<p>All values for SSLv2 configuration or disabling have been removed.
<p>Manual squid.conf update may be required on upgrade.
<tag>sslproxy_version</tag>
<p>Value '2' for SSLv2-only operation is no longer supported.
<tag>url_rewrite_children<tag>
<p>New parameter <em>queue-size=</em> to set the maximum number
of queued requests.
</descrip>
<sect1>Removed tags<label id="removedtags">
<p>
<descrip>
+ <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>
<sect>Changes to ./configure options since Squid-3.5
<p>
There have been some changes to Squid's build configuration since Squid-3.5.
This section gives an account of those changes in three categories:
<itemize>
<item><ref id="newoptions" name="New options">
<item><ref id="modifiedoptions" name="Changes to existing options">
<item><ref id="removedoptions" name="Removed options">
</itemize>
<sect1>New options<label id="newoptions">
<p>
<descrip>
=== modified file 'src/CachePeer.h'
--- src/CachePeer.h 2015-01-13 07:25:36 +0000
+++ src/CachePeer.h 2015-01-14 15:43:27 +0000
@@ -1,36 +1,37 @@
/*
* 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.
*/
#ifndef SQUID_CACHEPEER_H_
#define SQUID_CACHEPEER_H_
#include "acl/forward.h"
#include "base/CbcPointer.h"
#include "enums.h"
#include "icp_opcode.h"
#include "ip/Address.h"
+#include "security/PeerOptions.h"
//TODO: remove, it is unconditionally defined and always used.
#define PEER_MULTICAST_SIBLINGS 1
#if HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#endif
class CachePeerDomainList;
class NeighborTypeDomainList;
class PconnPool;
class PeerDigest;
class PeerPoolMgr;
// currently a POD
class CachePeer
{
public:
u_int index;
char *name;
@@ -159,43 +160,35 @@
double load_factor; /* normalized weight value */
} userhash;
#endif
struct {
unsigned int hash;
double load_multiplier;
double load_factor; /* normalized weight value */
} sourcehash;
char *login; /* Proxy authorization */
time_t connect_timeout;
int connect_fail_limit;
int max_conn;
struct {
PconnPool *pool; ///< idle connection pool for this peer
CbcPointer<PeerPoolMgr> mgr; ///< pool manager
int limit; ///< the limit itself
bool waitingForClose; ///< a conn must close before we open a standby conn
} standby; ///< optional "cache_peer standby=limit" feature
char *domain; /* Forced domain */
-#if USE_OPENSSL
- int use_ssl;
- char *sslcert;
- char *sslkey;
- int sslversion;
- char *ssloptions;
- char *sslcipher;
- char *sslcafile;
- char *sslcapath;
- char *sslcrlfile;
- char *sslflags;
- char *ssldomain;
+ /// security settings for peer connection
+ Security::PeerOptions secure;
+
+#if USE_OPENSSL
SSL_CTX *sslContext;
SSL_SESSION *sslSession;
#endif
int front_end_https;
int connection_auth;
};
#endif /* SQUID_CACHEPEER_H_ */
=== modified file 'src/FwdState.cc'
--- src/FwdState.cc 2015-01-13 07:25:36 +0000
+++ src/FwdState.cc 2015-01-14 15:05:47 +0000
@@ -666,41 +666,41 @@
peerConnectFailed(conn->getPeer());
conn->close();
}
retryOrBail();
return;
}
serverConn = conn;
flags.connected_okay = true;
debugs(17, 3, HERE << serverConnection() << ": '" << entry->url() << "'" );
comm_add_close_handler(serverConnection()->fd, fwdServerClosedWrapper, this);
if (serverConnection()->getPeer())
peerConnectSucceded(serverConnection()->getPeer());
#if USE_OPENSSL
if (!request->flags.pinned) {
- if ((serverConnection()->getPeer() && serverConnection()->getPeer()->use_ssl) ||
+ if ((serverConnection()->getPeer() && serverConnection()->getPeer()->secure.ssl) ||
(!serverConnection()->getPeer() && request->url.getScheme() == AnyP::PROTO_HTTPS) ||
request->flags.sslPeek) {
HttpRequest::Pointer requestPointer = request;
AsyncCall::Pointer callback = asyncCall(17,4,
"FwdState::ConnectedToPeer",
FwdStatePeerAnswerDialer(&FwdState::connectedToPeer, this));
// Use positive timeout when less than one second is left.
const time_t sslNegotiationTimeout = max(static_cast<time_t>(1), timeLeft());
Ssl::PeerConnector *connector =
new Ssl::PeerConnector(requestPointer, serverConnection(), clientConn, callback, sslNegotiationTimeout);
AsyncJob::Start(connector); // will call our callback
return;
}
}
#endif
// should reach ConnStateData before the dispatched Client job starts
CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData,
ConnStateData::notePeerConnection, serverConnection());
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2015-01-13 07:25:36 +0000
+++ src/Makefile.am 2015-01-14 15:10:20 +0000
@@ -41,50 +41,49 @@
StoreMetaVary.cc \
StoreMetaVary.h
LOADABLE_MODULES_SOURCES = \
LoadableModule.h \
LoadableModule.cc \
LoadableModules.h \
LoadableModules.cc
SUBDIRS = mem base anyp helper ftp parser comm eui acl format clients servers fs repl
DIST_SUBDIRS = mem base anyp helper ftp parser comm eui acl format clients servers fs repl
if ENABLE_AUTH
SUBDIRS += auth
AUTH_LIBS= auth/libauth.la
AUTH_ACL_LIBS= auth/libacls.la
check_PROGRAMS+= tests/testACLMaxUserIP
endif
DIST_SUBDIRS += auth
-SUBDIRS += http ip icmp ident log ipc mgr
-DIST_SUBDIRS += http ip icmp ident log ipc mgr
+SUBDIRS += http ip icmp ident log ipc mgr security
+DIST_SUBDIRS += http ip icmp ident log ipc mgr security
+SSL_LIBS=
if ENABLE_SSL
SUBDIRS += ssl
-SSL_LIBS = \
+SSL_LIBS += \
ssl/libsslsquid.la \
ssl/libsslutil.la
-else
-SSL_LOCAL_LIBS =
endif
DIST_SUBDIRS += ssl
SNMP_ALL_SOURCE = \
SnmpRequest.h \
snmp_core.h \
snmp_core.cc \
snmp_agent.h \
snmp_agent.cc
if ENABLE_SNMP
SNMP_SOURCE = $(SNMP_ALL_SOURCE)
SUBDIRS += snmp
SNMP_LIBS = snmp/libsnmp.la $(SNMPLIB)
else
SNMP_SOURCE =
endif
DIST_SUBDIRS += snmp
if USE_ADAPTATION
SUBDIRS += adaptation
@@ -597,40 +596,41 @@
CLEANFILES += $(BUILT_SOURCES)
nodist_squid_SOURCES = \
$(DISKIO_GEN_SOURCE) \
$(BUILT_SOURCES)
squid_LDADD = \
$(AUTH_ACL_LIBS) \
ident/libident.la \
acl/libacls.la \
acl/libstate.la \
$(AUTH_LIBS) \
$(DISK_LIBS) \
acl/libapi.la \
clients/libclients.la \
servers/libservers.la \
ftp/libftp.la \
helper/libhelper.la \
http/libsquid-http.la \
parser/libsquid-parser.la \
+ security/libsecurity.la \
base/libbase.la \
libsquid.la \
ip/libip.la \
fs/libfs.la \
$(SSL_LIBS) \
ipc/libipc.la \
mgr/libmgr.la \
anyp/libanyp.la \
comm/libcomm.la \
eui/libeui.la \
icmp/libicmp.la icmp/libicmp-core.la \
log/liblog.la \
format/libformat.la \
$(XTRA_OBJS) \
$(DISK_LINKOBJS) \
$(REPL_OBJS) \
$(DISK_OS_LIBS) \
$(NETTLELIB) \
$(CRYPTLIB) \
$(REGEXLIB) \
@@ -1460,40 +1460,41 @@
HttpHeaderTools.h \
HttpHeaderTools.cc \
HttpHeaderFieldStat.h \
HttpHdrCc.h \
HttpHdrCc.cc \
HttpHdrCc.cci \
HttpHdrContRange.cc \
HttpHdrRange.cc \
HttpHdrSc.cc \
HttpHdrScTarget.cc \
HttpMsg.cc \
HttpReply.cc \
icp_v2.cc \
icp_v3.cc \
$(IPC_SOURCE) \
ipcache.cc \
int.h \
int.cc \
internal.h \
internal.cc \
+ tests/stub_libsecurity.cc \
SquidList.h \
SquidList.cc \
MasterXaction.cc \
MasterXaction.h \
multicast.h \
multicast.cc \
mem_node.cc \
MemBuf.cc \
MemObject.cc \
mime.h \
mime.cc \
mime_header.h \
mime_header.cc \
neighbors.h \
neighbors.cc \
Notes.cc \
Notes.h \
Packer.cc \
Parsing.cc \
pconn.cc \
@@ -1880,40 +1881,41 @@
HttpHdrCc.cci \
HttpHdrContRange.cc \
HttpHdrRange.cc \
HttpHdrSc.cc \
HttpHdrScTarget.cc \
HttpMsg.cc \
HttpReply.cc \
PeerPoolMgr.h \
PeerPoolMgr.cc \
RequestFlags.h \
RequestFlags.cc \
HttpRequest.cc \
icp_v2.cc \
icp_v3.cc \
$(IPC_SOURCE) \
ipcache.cc \
int.h \
int.cc \
internal.h \
internal.cc \
+ tests/stub_libsecurity.cc \
SquidList.h \
SquidList.cc \
MasterXaction.cc \
MasterXaction.h \
tests/stub_libmem.cc \
mem_node.cc \
MemBuf.cc \
MemObject.cc \
mime.h \
mime.cc \
mime_header.h \
mime_header.cc \
multicast.h \
multicast.cc \
neighbors.h \
neighbors.cc \
Notes.cc \
Notes.h \
Packer.cc \
Parsing.cc \
@@ -2123,40 +2125,41 @@
HttpHdrCc.cci \
HttpHdrContRange.cc \
HttpHdrRange.cc \
HttpHdrSc.cc \
HttpHdrScTarget.cc \
HttpMsg.cc \
HttpReply.cc \
PeerPoolMgr.h \
PeerPoolMgr.cc \
RequestFlags.h \
RequestFlags.cc \
HttpRequest.cc \
icp_v2.cc \
icp_v3.cc \
$(IPC_SOURCE) \
ipcache.cc \
int.h \
int.cc \
internal.h \
internal.cc \
+ tests/stub_libsecurity.cc \
SquidList.h \
SquidList.cc \
MasterXaction.cc \
MasterXaction.h \
MemBuf.cc \
MemObject.cc \
tests/stub_libmem.cc \
mem_node.cc \
mime.h \
mime.cc \
mime_header.h \
mime_header.cc \
multicast.h \
multicast.cc \
neighbors.h \
neighbors.cc \
Notes.cc \
Notes.h \
Packer.cc \
Parsing.cc \
@@ -2361,40 +2364,41 @@
HttpHeader.h \
HttpHeader.cc \
HttpHeaderFieldInfo.h \
HttpHeaderTools.h \
HttpHeaderTools.cc \
HttpMsg.cc \
HttpReply.cc \
PeerPoolMgr.h \
PeerPoolMgr.cc \
RequestFlags.h \
RequestFlags.cc \
HttpRequest.cc \
icp_v2.cc \
icp_v3.cc \
int.h \
int.cc \
internal.h \
internal.cc \
$(IPC_SOURCE) \
ipcache.cc \
+ tests/stub_libsecurity.cc \
SquidList.h \
SquidList.cc \
MasterXaction.cc \
MasterXaction.h \
MemBuf.cc \
MemObject.cc \
tests/stub_libmem.cc \
mem_node.cc \
mime.h \
mime.cc \
mime_header.h \
mime_header.cc \
multicast.h \
multicast.cc \
neighbors.h \
neighbors.cc \
Notes.cc \
Notes.h \
Packer.cc \
Parsing.cc \
@@ -2654,40 +2658,41 @@
HttpHeaderTools.h \
HttpHeaderTools.cc \
HttpHeaderFieldStat.h \
HttpHdrCc.h \
HttpHdrCc.cc \
HttpHdrCc.cci \
HttpHdrContRange.cc \
HttpHdrRange.cc \
HttpHdrSc.cc \
HttpHdrScTarget.cc \
HttpMsg.cc \
HttpReply.cc \
icp_v2.cc \
icp_v3.cc \
$(IPC_SOURCE) \
ipcache.cc \
int.h \
int.cc \
internal.h \
internal.cc \
+ tests/stub_libsecurity.cc \
SquidList.h \
SquidList.cc \
MasterXaction.cc \
MasterXaction.h \
multicast.h \
multicast.cc \
mem_node.cc \
MemBuf.cc \
MemObject.cc \
mime.h \
mime.cc \
mime_header.h \
mime_header.cc \
neighbors.h \
neighbors.cc \
Notes.cc \
Notes.h \
Packer.cc \
Parsing.cc \
pconn.cc \
@@ -3470,40 +3475,41 @@
HttpHeader.h \
HttpHeader.cc \
HttpHeaderFieldInfo.h \
HttpHeaderTools.h \
HttpHeaderTools.cc \
HttpMsg.cc \
HttpReply.cc \
PeerPoolMgr.h \
PeerPoolMgr.cc \
RequestFlags.h \
RequestFlags.cc \
HttpRequest.cc \
icp_v2.cc \
icp_v3.cc \
$(IPC_SOURCE) \
ipcache.cc \
int.h \
int.cc \
internal.h \
internal.cc \
+ tests/stub_libsecurity.cc \
SquidList.h \
SquidList.cc \
MasterXaction.cc \
MasterXaction.h \
multicast.h \
multicast.cc \
tests/stub_libmem.cc \
mem_node.cc \
MemBuf.cc \
MemObject.cc \
mime.h \
mime.cc \
mime_header.h \
mime_header.cc \
neighbors.h \
neighbors.cc \
Notes.h \
Notes.cc \
Packer.cc \
Parsing.cc \
=== modified file 'src/PeerPoolMgr.cc'
--- src/PeerPoolMgr.cc 2015-01-13 07:25:36 +0000
+++ src/PeerPoolMgr.cc 2015-01-14 15:05:47 +0000
@@ -96,41 +96,41 @@
if (!validPeer()) {
debugs(48, 3, "peer gone");
if (params.conn != NULL)
params.conn->close();
return;
}
if (params.flag != Comm::OK) {
/* it might have been a timeout with a partially open link */
if (params.conn != NULL)
params.conn->close();
peerConnectFailed(peer);
checkpoint("conn opening failure"); // may retry
return;
}
Must(params.conn != NULL);
#if USE_OPENSSL
// Handle SSL peers.
- if (peer->use_ssl) {
+ if (peer->secure.ssl) {
typedef CommCbMemFunT<PeerPoolMgr, CommCloseCbParams> CloserDialer;
closer = JobCallback(48, 3, CloserDialer, this,
PeerPoolMgr::handleSecureClosure);
comm_add_close_handler(params.conn->fd, closer);
securer = asyncCall(48, 4, "PeerPoolMgr::handleSecuredPeer",
MyAnswerDialer(this, &PeerPoolMgr::handleSecuredPeer));
const int peerTimeout = peer->connect_timeout > 0 ?
peer->connect_timeout : Config.Timeout.peer_connect;
const int timeUsed = squid_curtime - params.conn->startTime();
// Use positive timeout when less than one second is left for conn.
const int timeLeft = max(1, (peerTimeout - timeUsed));
Ssl::PeerConnector *connector =
new Ssl::PeerConnector(request, params.conn, NULL, securer, timeLeft);
AsyncJob::Start(connector); // will call our callback
return;
}
#endif
=== modified file 'src/SquidConfig.h'
--- src/SquidConfig.h 2015-01-13 07:25:36 +0000
+++ src/SquidConfig.h 2015-01-14 15:05:47 +0000
@@ -480,51 +480,41 @@
char *ssl_engine;
int session_ttl;
size_t sessionCacheSize;
char *certSignHash;
} SSL;
#endif
wordlist *ext_methods;
struct {
int high_rptm;
int high_pf;
size_t high_memory;
} warnings;
char *store_dir_select_algorithm;
int sleep_after_fork; /* microseconds */
time_t minimum_expiry_time; /* seconds */
external_acl *externalAclHelperList;
#if USE_OPENSSL
-
struct {
- char *cert;
- char *key;
- int version;
- char *options;
- char *cipher;
- char *cafile;
- char *capath;
- char *crlfile;
- char *flags;
acl_access *cert_error;
SSL_CTX *sslContext;
sslproxy_cert_sign *cert_sign;
sslproxy_cert_adapt *cert_adapt;
} ssl_client;
#endif
char *accept_filter;
int umask;
int max_filedescriptors;
int workers;
CpuAffinityMap *cpuAffinityMap;
#if USE_LOADABLE_MODULES
wordlist *loadable_module_names;
#endif
int client_ip_max_connections;
char *redirector_extras;
=== modified file 'src/cache_cf.cc'
--- src/cache_cf.cc 2015-01-13 07:25:36 +0000
+++ src/cache_cf.cc 2015-01-14 15:05:47 +0000
@@ -868,46 +868,48 @@
Config2.effectiveGroupID = getegid();
}
if (NULL != Config.effectiveGroup) {
struct group *grp = getgrnam(Config.effectiveGroup);
if (NULL == grp) {
fatalf("getgrnam failed to find groupid for effective group '%s'",
Config.effectiveGroup);
return;
}
Config2.effectiveGroupID = grp->gr_gid;
}
#if USE_OPENSSL
debugs(3, DBG_IMPORTANT, "Initializing https proxy context");
- Config.ssl_client.sslContext = sslCreateClientContext(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);
+ // BUG: ssl_client.sslContext will leak on reconfigure when Config gets memset()
+ // it makes more sense to create a context per outbound connection instead of this
+ Config.ssl_client.sslContext = Security::ProxyOutgoingConfig.createContext();
for (CachePeer *p = Config.peers; p != NULL; p = p->next) {
- if (p->use_ssl) {
+ if (p->secure.ssl) {
debugs(3, DBG_IMPORTANT, "Initializing cache_peer " << p->name << " SSL context");
- 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();
}
}
for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) {
if (!s->flags.tunnelSslBumping)
continue;
debugs(3, DBG_IMPORTANT, "Initializing http_port " << s->s << " SSL context");
s->configureSslServerContext();
}
for (AnyP::PortCfgPointer s = HttpsPortList; s != NULL; s = s->next) {
debugs(3, DBG_IMPORTANT, "Initializing https_port " << s->s << " SSL context");
s->configureSslServerContext();
}
#endif
// prevent infinite fetch loops in the request parser
// due to buffer full but not enough data recived to finish parse
@@ -959,40 +961,70 @@
if (!strcmp(name, "url_rewrite_concurrency")) {
int cval;
parse_int(&cval);
debugs(3, DBG_CRITICAL, "WARNING: url_rewrite_concurrency upgrade overriding url_rewrite_children settings.");
Config.redirectChildren.concurrency = cval;
}
if (!strcmp(name, "log_access"))
self_destruct();
if (!strcmp(name, "log_icap"))
self_destruct();
if (!strcmp(name, "ignore_ims_on_miss")) {
// the replacement directive cache_revalidate_on_miss has opposite meanings for ON/OFF value
// than the 2.7 directive. We need to parse and invert the configured value.
int temp = 0;
parse_onoff(&temp);
Config.onoff.cache_miss_revalidate = !temp;
}
+
+ if (!strncmp(name, "sslproxy_", 9)) {
+ // the replacement directive tls_outgoing_options uses options instead of whole-line input
+ SBuf tmp;
+ if (!strcmp(name, "sslproxy_cafile"))
+ tmp.append("cafile=");
+ else if (!strcmp(name, "sslproxy_capath"))
+ tmp.append("capath=");
+ else if (!strcmp(name, "sslproxy_cipher"))
+ tmp.append("cipher=");
+ else if (!strcmp(name, "sslproxy_client_certificate"))
+ tmp.append("cert=");
+ else if (!strcmp(name, "sslproxy_client_key"))
+ tmp.append("key=");
+ else if (!strcmp(name, "sslproxy_flags"))
+ tmp.append("flags=");
+ else if (!strcmp(name, "sslproxy_options"))
+ tmp.append("options=");
+ else if (!strcmp(name, "sslproxy_version"))
+ tmp.append("version=");
+ else {
+ debugs(3, DBG_CRITICAL, "ERROR: unknown directive: " << name);
+ self_destruct();
+ }
+
+ // add the value as unquoted-string because the old values did not support whitespace
+ const char *token = ConfigParser::NextQuotedOrToEol();
+ tmp.append(token, strlen(token));
+ Security::ProxyOutgoingConfig.parse(tmp.c_str());
+ }
}
/* Parse a time specification from the config file. Store the
* result in 'tptr', after converting it to 'units' */
static void
parseTimeLine(time_msec_t * tptr, const char *units, bool allowMsec, bool expectMoreArguments = false)
{
char *token;
double d;
time_msec_t m;
time_msec_t u;
if ((u = parseTimeUnits(units, allowMsec)) == 0)
self_destruct();
if ((token = ConfigParser::NextToken()) == NULL)
self_destruct();
d = xatof(token);
@@ -2232,77 +2264,49 @@
#if USE_CACHE_DIGESTS
} else if (!strncmp(token, "digest-url=", 11)) {
p->digest_url = xstrdup(token + 11);
#endif
} else if (!strcmp(token, "allow-miss")) {
p->options.allow_miss = true;
} else if (!strncmp(token, "max-conn=", 9)) {
p->max_conn = xatoi(token + 9);
} else if (!strncmp(token, "standby=", 8)) {
p->standby.limit = xatoi(token + 8);
} else if (!strcmp(token, "originserver")) {
p->options.originserver = true;
} else if (!strncmp(token, "name=", 5)) {
safe_free(p->name);
if (token[5])
p->name = xstrdup(token + 5);
} else if (!strncmp(token, "forceddomain=", 13)) {
safe_free(p->domain);
-
if (token[13])
p->domain = xstrdup(token + 13);
-#if USE_OPENSSL
-
- } 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 = xatoi(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->sslcrlfile = xstrdup(token + 11);
- } 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", 3) == 0) {
+#if !USE_OPENSSL
+ debugs(0, DBG_CRITICAL, "WARNING: cache_peer option '" << token << "' requires --with-openssl");
+#else
+ p->secure.ssl = true;
+ p->secure.parse(token+3);
#endif
} else if (strcmp(token, "front-end-https") == 0) {
p->front_end_https = 1;
} else if (strcmp(token, "front-end-https=on") == 0) {
p->front_end_https = 1;
} else if (strcmp(token, "front-end-https=auto") == 0) {
p->front_end_https = 2;
} else if (strcmp(token, "connection-auth=off") == 0) {
p->connection_auth = 0;
} else if (strcmp(token, "connection-auth") == 0) {
p->connection_auth = 1;
} else if (strcmp(token, "connection-auth=on") == 0) {
p->connection_auth = 1;
} else if (strcmp(token, "connection-auth=auto") == 0) {
p->connection_auth = 2;
} else if (token[0] == '#') {
// start of a text comment. stop reading this line.
break;
} else {
=== modified file 'src/cf.data.depend'
--- src/cf.data.depend 2015-01-13 07:25:36 +0000
+++ src/cf.data.depend 2015-01-14 15:05:47 +0000
@@ -49,40 +49,41 @@
icap_service_type
icap_service_failure_limit
ecap_service_type
int
kb_int64_t
kb_size_t
logformat
YesNoNone
memcachemode
note acl
obsolete
onoff
peer
peer_access cache_peer acl
pipelinePrefetch
PortCfg
QosConfig
TokenOrQuotedString
refreshpattern
removalpolicy
+securePeerOptions
size_t
IpAddress_list
string
string
time_msec
time_t
tristate
uri_whitespace
UrlHelperTimeout acl
u_short
wccp2_method
wccp2_amethod
wccp2_service
wccp2_service_info
wordlist
sslproxy_ssl_bump acl
sslproxy_ssl_bump_peeked acl
sslproxy_cert_sign acl
sslproxy_cert_adapt acl
ftp_epsv acl
=== modified file 'src/cf.data.pre'
--- src/cf.data.pre 2015-01-13 07:25:36 +0000
+++ src/cf.data.pre 2015-01-14 15:10:52 +0000
@@ -131,40 +131,89 @@
DOC_END
NAME: external_refresh_check
TYPE: obsolete
DOC_START
This option is not yet supported by Squid-3.
DOC_END
NAME: location_rewrite_program location_rewrite_access location_rewrite_children location_rewrite_concurrency
TYPE: obsolete
DOC_START
This option is not yet supported by Squid-3.
DOC_END
NAME: refresh_stale_hit
TYPE: obsolete
DOC_START
This option is not yet supported by Squid-3.
DOC_END
+# Options removed in 3.6
+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
DOC_START
Remove this line. Use always_direct or cache_peer_access ACLs instead if you need to prevent cache_peer use.
DOC_END
NAME: log_access
TYPE: obsolete
DOC_START
Remove this line. Use acls with access_log directives to control access logging
DOC_END
NAME: log_icap
TYPE: obsolete
DOC_START
Remove this line. Use acls with icap_log directives to control icap logging
DOC_END
# Options Removed in 3.3
@@ -2349,160 +2398,139 @@
directly to the original client destination IP or seek a faster
source using the HTTP Host header.
Using Host to locate alternative servers can provide faster
connectivity with a range of failure recovery options.
But can also lead to connectivity trouble when the client and
server are attempting stateful interactions unaware of the proxy.
This option (on by default) prevents alternative DNS entries being
located to send intercepted traffic DIRECT to an origin server.
The clients original destination IP and port will be used instead.
Regardless of this option setting, when dealing with intercepted
traffic Squid will verify the Host: header and any traffic which
fails Host verification will be treated as if this option were ON.
see host_verify_strict for details on the verification process.
DOC_END
COMMENT_START
+ TLS OPTIONS
+ -----------------------------------------------------------------------------
+COMMENT_END
+
+NAME: tls_outgoing_options
+IFDEF: USE_GNUTLS||USE_OPENSSL
+TYPE: securePeerOptions
+DEFAULT: disable
+LOC: Security::ProxyOutgoingConfig
+DOC_START
+ disable Do not support https:// URLs.
+
+ cert=/path/to/client/certificate
+ A client TLS certificate to use when connecting.
+
+ key=/path/to/client/private_key
+ The private TLS key corresponding to the cert= above.
+ If key= is not specified cert= is assumed to reference
+ a PEM file containing both the certificate and the key.
+
+ version=1|3|4|5|6
+ The TLS/SSL version to use when connecting
+ 1 = automatic (default)
+ 3 = SSL v3 only
+ 4 = TLS v1.0 only
+ 5 = TLS v1.1 only
+ 6 = TLS v1.2 only
+
+ cipher=... The list of valid TLS ciphers to use.
+
+ options=... Specify various TLS/SSL implementation options:
+
+ 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 TLS/SSL
+ 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 peer certificate.
+
+ capath=... A directory containing additional CA certificates to
+ use when verifying the peer certificate.
+
+ crlfile=... A certificate revocation list file to use when
+ verifying the peer certificate.
+
+ flags=... Specify various flags modifying the TLS implementation:
+
+ DONT_VERIFY_PEER
+ Accept 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 peer certificate
+ matches the server name
+
+ domain= The peer name as advertised in its certificate.
+ Used for verifying the correctness of the received peer
+ certificate. If not specified the peer hostname will be
+ used.
+DOC_END
+
+COMMENT_START
SSL OPTIONS
-----------------------------------------------------------------------------
COMMENT_END
NAME: ssl_unclean_shutdown
IFDEF: USE_OPENSSL
TYPE: onoff
DEFAULT: off
LOC: Config.SSL.unclean_shutdown
DOC_START
Some browsers (especially MSIE) bugs out on SSL shutdown
messages.
DOC_END
NAME: ssl_engine
IFDEF: USE_OPENSSL
TYPE: string
LOC: Config.SSL.ssl_engine
DEFAULT: none
DOC_START
The OpenSSL engine to use. You will need to set this if you
would like to use hardware SSL acceleration for example.
DOC_END
-NAME: sslproxy_client_certificate
-IFDEF: USE_OPENSSL
-DEFAULT: none
-LOC: Config.ssl_client.cert
-TYPE: string
-DOC_START
- Client SSL Certificate to use when proxying https:// URLs
-DOC_END
-
-NAME: sslproxy_client_key
-IFDEF: USE_OPENSSL
-DEFAULT: none
-LOC: Config.ssl_client.key
-TYPE: string
-DOC_START
- Client SSL Key to use when proxying https:// URLs
-DOC_END
-
-NAME: sslproxy_version
-IFDEF: USE_OPENSSL
-DEFAULT: 1
-DEFAULT_DOC: automatic SSL/TLS version negotiation
-LOC: Config.ssl_client.version
-TYPE: int
-DOC_START
- SSL version level to use when proxying https:// URLs
-
- The versions of SSL/TLS supported:
-
- 1 automatic (default)
- 3 SSLv3 only
- 4 TLSv1.0 only
- 5 TLSv1.1 only
- 6 TLSv1.2 only
-DOC_END
-
-NAME: sslproxy_options
-IFDEF: USE_OPENSSL
-DEFAULT: none
-LOC: Config.ssl_client.options
-TYPE: string
-DOC_START
- SSL implementation options to use when proxying https:// URLs
-
- 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 temporary/ephemeral
- DH key exchanges
- SSL_OP_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 may reduce SSL/TLS
- strength to some attacks.
-
- See the OpenSSL SSL_CTX_set_options documentation for a
- complete list of possible options.
-DOC_END
-
-NAME: sslproxy_cipher
-IFDEF: USE_OPENSSL
-DEFAULT: none
-LOC: Config.ssl_client.cipher
-TYPE: string
-DOC_START
- SSL cipher list to use when proxying https:// URLs
-
- Colon separated list of supported ciphers.
-DOC_END
-
-NAME: sslproxy_cafile
-IFDEF: USE_OPENSSL
-DEFAULT: none
-LOC: Config.ssl_client.cafile
-TYPE: string
-DOC_START
- file containing CA certificates to use when verifying server
- certificates while proxying https:// URLs
-DOC_END
-
-NAME: sslproxy_capath
-IFDEF: USE_OPENSSL
-DEFAULT: none
-LOC: Config.ssl_client.capath
-TYPE: string
-DOC_START
- directory containing CA certificates to use when verifying
- server certificates while proxying https:// URLs
-DOC_END
-
NAME: sslproxy_session_ttl
IFDEF: USE_OPENSSL
DEFAULT: 300
LOC: Config.SSL.session_ttl
TYPE: int
DOC_START
Sets the timeout value for SSL sessions
DOC_END
NAME: sslproxy_session_cache_size
IFDEF: USE_OPENSSL
DEFAULT: 2 MB
LOC: Config.SSL.sessionCacheSize
TYPE: b_size_t
DOC_START
Sets the cache size to use for ssl session
DOC_END
NAME: sslproxy_cert_sign_hash
IFDEF: USE_OPENSSL
@@ -2590,53 +2618,40 @@
steps. Rules with actions that are impossible at the current step are
ignored. The first matching ssl_bump action wins and is applied at the
end of the current step. If no rules match, the splice action is used.
See the at_step ACL for a list of the supported SslBump steps.
This clause supports both fast and slow acl types.
See http://wiki.squid-cache.org/SquidFaq/SquidAcl for details.
See also: http_port ssl-bump, https_port ssl-bump, and acl at_step.
# Example: Bump all requests except those originating from
# localhost or those going to example.com.
acl broken_sites dstdomain .example.com
ssl_bump splice localhost
ssl_bump splice broken_sites
ssl_bump bump all
DOC_END
-NAME: sslproxy_flags
-IFDEF: USE_OPENSSL
-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_OPENSSL
DEFAULT: none
DEFAULT_DOC: Server certificate errors terminate the transaction.
LOC: Config.ssl_client.cert_error
TYPE: acl_access
DOC_START
Use this ACL to bypass server certificate validation errors.
For example, the following lines will bypass all validation errors
when talking to servers for example.com. All other
validation errors will result in ERR_SECURE_CONNECT_FAIL error.
acl BrokenButTrustedServers dstdomain example.com
sslproxy_cert_error allow BrokenButTrustedServers
sslproxy_cert_error deny all
This clause only supports fast acl types.
See http://wiki.squid-cache.org/SquidFaq/SquidAcl for details.
Using slow acl types may result in server crashes
=== modified file 'src/cf_gen_defines'
--- src/cf_gen_defines 2015-01-13 07:25:36 +0000
+++ src/cf_gen_defines 2015-01-14 15:05:47 +0000
@@ -17,40 +17,41 @@
print " * Please see the COPYING and CONTRIBUTORS files for details."
print " */"
print ""
print "#include \"autoconf.h\""
print "static struct { const char *name; const char *enable; int defined;} defines[] = {"
define["_SQUID_WINDOWS_"]="MS Windows"
define["FOLLOW_X_FORWARDED_FOR"]="--enable-follow-x-forwarded-for"
define["FOLLOW_X_FORWARDED_FOR&&LINUX_NETFILTER"]="--enable-follow-x-forwarded-for and --enable-linux-netfilter"
define["FOLLOW_X_FORWARDED_FOR&&USE_ADAPTATION"]="--enable-follow-x-forwarded-for and (--enable-icap-client and/or --enable-ecap)"
define["FOLLOW_X_FORWARDED_FOR&&USE_DELAY_POOLS"]="--enable-follow-x-forwarded-for and --enable-delay-pools"
define["HAVE_MSTATS&&HAVE_GNUMALLOC_H"]="GNU Malloc with mstats()"
define["ICAP_CLIENT"]="--enable-icap-client"
define["SO_MARK&&USE_LIBCAP"]="Packet MARK (Linux)"
define["SQUID_SNMP"]="--enable-snmp"
define["USE_ADAPTATION"]="--enable-ecap or --enable-icap-client"
define["USE_AUTH"]="--enable-auth"
define["USE_CACHE_DIGESTS"]="--enable-cache-digests"
define["USE_DELAY_POOLS"]="--enable-delay-pools"
define["USE_ECAP"]="--enable-ecap"
define["USE_ERR_LOCALES"]="--enable-auto-locale"
+ define["USE_GNUTLS||USE_OPENSSL"]="--with-gnutls or --with-openssl"
define["USE_HTCP"]="--enable-htcp"
define["USE_HTTP_VIOLATIONS"]="--enable-http-violations"
define["USE_ICMP"]="--enable-icmp"
define["USE_IDENT"]="--enable-ident-lookups"
define["USE_LOADABLE_MODULES"]="--enable-loadable-modules"
define["USE_OPENSSL"]="--with-openssl"
define["USE_QOS_TOS"]="--enable-zph-qos"
define["USE_SQUID_ESI"]="--enable-esi"
define["USE_SQUID_EUI"]="--enable-eui"
define["USE_SSL_CRTD"]="--enable-ssl-crtd"
define["USE_UNLINKD"]="--enable-unlinkd"
define["USE_WCCP"]="--enable-wccp"
define["USE_WCCPv2"]="--enable-wccpv2"
}
/^IFDEF:/ {
if (define[$2] != "")
DEFINE=define[$2]
else
DEFINE="-D" $2 " define"
print "{\"" $2 "\", \"" DEFINE "\", "
=== added directory 'src/security'
=== added file 'src/security/Context.h'
--- src/security/Context.h 1970-01-01 00:00:00 +0000
+++ src/security/Context.h 2015-01-14 15:04:28 +0000
@@ -0,0 +1,29 @@
+/*
+ * 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_CONTEXT_H
+#define SQUID_SRC_SECURITY_CONTEXT_H
+
+#if USE_OPENSSL
+#include "ssl/gadgets.h"
+#endif
+
+namespace Security {
+
+#if USE_OPENSSL
+// XXX: make this a SSL_CTX_Pointer
+typedef SSL_CTX* ContextPointer;
+
+#else
+// use void* so we can check against NULL
+typedef void* ContextPointer;
+#endif
+
+} // namespace Security
+
+#endif /* SQUID_SRC_SECURITY_CONTEXT_H */
=== added file 'src/security/Makefile.am'
--- src/security/Makefile.am 1970-01-01 00:00:00 +0000
+++ src/security/Makefile.am 2015-01-14 15:04:28 +0000
@@ -0,0 +1,16 @@
+## 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 $(top_srcdir)/src/Common.am
+include $(top_srcdir)/src/TestHeaders.am
+
+noinst_LTLIBRARIES = libsecurity.la
+
+libsecurity_la_SOURCES= \
+ Context.h \
+ PeerOptions.cc \
+ PeerOptions.h
=== added file 'src/security/PeerOptions.cc'
--- src/security/PeerOptions.cc 1970-01-01 00:00:00 +0000
+++ src/security/PeerOptions.cc 2015-01-14 15:04:28 +0000
@@ -0,0 +1,65 @@
+/*
+ * 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);
+ } 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);
+ } 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
+Security::PeerOptions::createContext()
+{
+ Security::ContextPointer t = NULL;
+
+ if (privateKeyFile.isEmpty())
+ privateKeyFile = certFile;
+
+#if USE_OPENSSL
+ t = sslCreateClientContext(certFile.c_str(), privateKeyFile.c_str(), sslVersion, sslCipher.c_str(),
+ sslOptions.c_str(), sslFlags.c_str(), caFile.c_str(), caDir.c_str(), crlFile.c_str());
+#endif
+ return t;
+}
=== added file 'src/security/PeerOptions.h'
--- src/security/PeerOptions.h 1970-01-01 00:00:00 +0000
+++ src/security/PeerOptions.h 2015-01-14 15:04:28 +0000
@@ -0,0 +1,65 @@
+/*
+ * 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
+{
+
+class PeerOptions
+{
+public:
+ PeerOptions() : ssl(false), sslVersion(0) {}
+
+ /// 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 the configured options
+ Security::ContextPointer createContext();
+
+ bool ssl; ///< whether SSL is to be used on this connection
+
+ 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 containign a set of trusted Certificate Authorities
+ SBuf crlFile; ///< path of file containing Certificate Revoke List
+
+ int sslVersion;
+ SBuf sslCipher;
+ SBuf sslFlags;
+ SBuf sslDomain;
+};
+
+/// configuration options for DIRECT server access
+extern PeerOptions ProxyOutgoingConfig;
+
+} // namespace Security
+
+// parse the tls_outgoing_options directive
+inline void
+parse_securePeerOptions(Security::PeerOptions *opt)
+{
+ while(const char *token = ConfigParser::NextToken()) {
+ opt->parse(token);
+ }
+}
+
+#define free_securePeerOptions(x) Security::ProxyOutgoingConfig.clear()
+#define dump_securePeerOptions(e,n,x) // not supported yet
+
+#endif /* SQUID_SRC_SECURITY_PEEROPTIONS_H */
=== modified file 'src/ssl/PeerConnector.cc'
--- src/ssl/PeerConnector.cc 2015-01-13 07:25:36 +0000
+++ src/ssl/PeerConnector.cc 2015-01-14 15:44:07 +0000
@@ -94,70 +94,73 @@
if (!Comm::IsConnOpen(serverConn) || fd_table[serverConn->fd].closing()) {
connectionClosed("Ssl::PeerConnector::prepareSocket");
return false;
}
// watch for external connection closures
typedef CommCbMemFunT<Ssl::PeerConnector, CommCloseCbParams> Dialer;
closeHandler = JobCallback(9, 5, Dialer, this, Ssl::PeerConnector::commCloseHandler);
comm_add_close_handler(fd, closeHandler);
return true;
}
void
Ssl::PeerConnector::initializeSsl()
{
SSL_CTX *sslContext = NULL;
const CachePeer *peer = serverConnection()->getPeer();
const int fd = serverConnection()->fd;
if (peer) {
- assert(peer->use_ssl);
+ assert(peer->secure.ssl);
sslContext = peer->sslContext;
} else {
+ // XXX: locate a per-server context in Security:: instead
sslContext = ::Config.ssl_client.sslContext;
}
assert(sslContext);
SSL *ssl = Ssl::CreateClient(sslContext, fd, "server https start");
if (!ssl) {
ErrorState *anErr = new ErrorState(ERR_SOCKET_FAILURE, Http::scInternalServerError, request.getRaw());
anErr->xerrno = errno;
debugs(83, DBG_IMPORTANT, "Error allocating SSL handle: " << ERR_error_string(ERR_get_error(), NULL));
bail(anErr);
return;
}
if (peer) {
- if (peer->ssldomain)
- SSL_set_ex_data(ssl, ssl_ex_index_server, peer->ssldomain);
-
+ if (!peer->secure.sslDomain.isEmpty()) {
+ // const loss is okay here, ssl_ex_index_server is only read and not assigned a destructor
+ SSL_set_ex_data(ssl, ssl_ex_index_server, const_cast<SBuf*>(&peer->secure.sslDomain));
+ }
#if NOT_YET
else if (peer->name)
SSL_set_ex_data(ssl, ssl_ex_index_server, peer->name);
#endif
-
+#if WHEN_PEER_HOST_IS_SBUF
else
SSL_set_ex_data(ssl, ssl_ex_index_server, peer->host);
+#endif
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
// 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);
=== modified file 'src/ssl/support.cc'
--- src/ssl/support.cc 2015-01-13 07:25:36 +0000
+++ src/ssl/support.cc 2015-01-14 15:05:47 +0000
@@ -1091,115 +1091,109 @@
default:
debugs(83, 5, "Using SSLv2/SSLv3.");
return SSLv23_server_method();
break;
}
//Not reached
return 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)
{
int ssl_error;
Ssl::ContextMethod method;
SSL_CTX * sslContext;
long fl = Ssl::parse_flags(flags);
ssl_initialize();
- if (!keyfile)
- keyfile = certfile;
-
- if (!certfile)
- certfile = keyfile;
-
if (!(method = Ssl::method(version)))
return NULL;
sslContext = SSL_CTX_new(method);
if (sslContext == NULL) {
ssl_error = ERR_get_error();
fatalf("Failed to allocate SSL context: %s\n",
ERR_error_string(ssl_error, NULL));
}
SSL_CTX_set_options(sslContext, Ssl::parse_options(options));
- if (cipher) {
+ if (*cipher) {
debugs(83, 5, "Using chiper suite " << cipher << ".");
if (!SSL_CTX_set_cipher_list(sslContext, cipher)) {
ssl_error = ERR_get_error();
fatalf("Failed to set SSL cipher suite '%s': %s\n",
cipher, ERR_error_string(ssl_error, NULL));
}
}
- if (certfile) {
+ if (*certfile) {
debugs(83, DBG_IMPORTANT, "Using certificate in " << certfile);
if (!SSL_CTX_use_certificate_chain_file(sslContext, certfile)) {
ssl_error = ERR_get_error();
fatalf("Failed to acquire SSL certificate '%s': %s\n",
certfile, ERR_error_string(ssl_error, NULL));
}
debugs(83, DBG_IMPORTANT, "Using private key in " << keyfile);
ssl_ask_password(sslContext, keyfile);
if (!SSL_CTX_use_PrivateKey_file(sslContext, keyfile, SSL_FILETYPE_PEM)) {
ssl_error = ERR_get_error();
fatalf("Failed to acquire SSL private key '%s': %s\n",
keyfile, ERR_error_string(ssl_error, NULL));
}
debugs(83, 5, "Comparing private and public SSL keys.");
if (!SSL_CTX_check_private_key(sslContext)) {
ssl_error = ERR_get_error();
fatalf("SSL private key '%s' does not match public key '%s': %s\n",
certfile, keyfile, ERR_error_string(ssl_error, NULL));
}
}
debugs(83, 9, "Setting RSA key generation callback.");
SSL_CTX_set_tmp_rsa_callback(sslContext, ssl_temp_rsa_cb);
if (fl & SSL_FLAG_DONT_VERIFY_PEER) {
debugs(83, 2, "NOTICE: Peer certificates are not verified for validity!");
SSL_CTX_set_verify(sslContext, SSL_VERIFY_NONE, NULL);
} else {
debugs(83, 9, "Setting certificate verification callback.");
SSL_CTX_set_verify(sslContext, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ssl_verify_cb);
}
debugs(83, 9, "Setting CA certificate locations.");
- if ((CAfile || CApath) && !SSL_CTX_load_verify_locations(sslContext, CAfile, CApath)) {
+ if ((*CAfile || *CApath) && !SSL_CTX_load_verify_locations(sslContext, CAfile, 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) {
+ if (*CRLfile) {
ssl_load_crl(sslContext, CRLfile);
fl |= SSL_FLAG_VERIFY_CRL;
}
#if X509_V_FLAG_CRL_CHECK
if (fl & SSL_FLAG_VERIFY_CRL_ALL)
X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
else if (fl & SSL_FLAG_VERIFY_CRL)
X509_STORE_set_flags(SSL_CTX_get_cert_store(sslContext), X509_V_FLAG_CRL_CHECK);
#endif
if (!(fl & SSL_FLAG_NO_DEFAULT_CA) &&
!SSL_CTX_set_default_verify_paths(sslContext)) {
ssl_error = ERR_get_error();
debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default CA certificate location: " << ERR_error_string(ssl_error, NULL));
}
return sslContext;
}
=== added file 'src/tests/stub_libsecurity.cc'
--- src/tests/stub_libsecurity.cc 1970-01-01 00:00:00 +0000
+++ src/tests/stub_libsecurity.cc 2015-01-14 15:04:28 +0000
@@ -0,0 +1,17 @@
+/*
+ * 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() STUB_RETVAL(NULL)
=== modified file 'src/tunnel.cc'
--- src/tunnel.cc 2015-01-13 07:25:36 +0000
+++ src/tunnel.cc 2015-01-14 15:05:47 +0000
@@ -936,41 +936,41 @@
tunnelClientClosed,
tunnelState);
AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "tunnelTimeout",
CommTimeoutCbPtrFun(tunnelTimeout, tunnelState));
commSetConnTimeout(tunnelState->client.conn, Config.Timeout.lifetime, timeoutCall);
peerSelect(&(tunnelState->serverDestinations), request, al,
NULL,
tunnelPeerSelectComplete,
tunnelState);
}
void
TunnelStateData::connectToPeer()
{
const Comm::ConnectionPointer &srv = server.conn;
#if USE_OPENSSL
if (CachePeer *p = srv->getPeer()) {
- if (p->use_ssl) {
+ if (p->secure.ssl) {
AsyncCall::Pointer callback = asyncCall(5,4,
"TunnelStateData::ConnectedToPeer",
MyAnswerDialer(&TunnelStateData::connectedToPeer, this));
Ssl::PeerConnector *connector =
new Ssl::PeerConnector(request, srv, client.conn, callback);
AsyncJob::Start(connector); // will call our callback
return;
}
}
#endif
tunnelRelayConnectRequest(srv, this);
}
#if USE_OPENSSL
/// Ssl::PeerConnector callback
void
TunnelStateData::connectedToPeer(Ssl::PeerConnectorAnswer &answer)
{
if (ErrorState *error = answer.error.get()) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: cryptong_libsecurity_mk1.patch.sig
Type: application/octet-stream
Size: 287 bytes
Desc: not available
URL: <http://lists.squid-cache.org/pipermail/squid-dev/attachments/20150115/e722cc86/attachment-0001.obj>
More information about the squid-dev
mailing list