From: Christos Tsantilas Date: Mon, 14 May 2012 10:37:40 +0000 (+0300) Subject: Merged from trunk (r12132, v3.2.0.17+) X-Git-Tag: BumpSslServerFirst.take08~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5ae655811f1f7a082d2d2b99637c8a0b76b030c7;p=thirdparty%2Fsquid.git Merged from trunk (r12132, v3.2.0.17+) --- 5ae655811f1f7a082d2d2b99637c8a0b76b030c7 diff --cc src/ClientRequestContext.h index 9abf326ce7,4ea052eba0..a52d88fbdf --- a/src/ClientRequestContext.h +++ b/src/ClientRequestContext.h @@@ -68,14 -68,8 +68,10 @@@ public #if USE_SSL bool sslBumpCheckDone; #endif + ErrorState *error; + bool readNextRequest; - /// Send authentication response (challenge or error) if ACL result indicates one is needed - /// \return true if an error page of any kind has been sent back to the client. - // NP: public only until ACLChecklist::nonBlockingCheck() takes Async::Pointer to a call - bool maybeSendAuthChallenge(const allow_t &answer); - + private: CBDATA_CLASS(ClientRequestContext); }; diff --cc src/acl/Acl.h index 359b302a52,6eff7c1b68..3cc8c52ca6 --- a/src/acl/Acl.h +++ b/src/acl/Acl.h @@@ -116,36 -116,8 +116,33 @@@ typedef enum // Authentication ACL result states ACCESS_AUTH_REQUIRED, // Missing Credentials - ACCESS_AUTH_EXPIRED_OK, // Expired now. Were Okay. - ACCESS_AUTH_EXPIRED_BAD // Expired now. Were Failed. -} allow_t; +} aclMatchCode; + +/// \ingroup ACLAPI +/// ACL check answer; TODO: Rename to Acl::Answer +class allow_t { +public: + // not explicit: allow "aclMatchCode to allow_t" conversions (for now) + allow_t(const aclMatchCode aCode): code(aCode), kind(0) {} + + allow_t(): code(ACCESS_DUNNO), kind(0) {} + + bool operator ==(const aclMatchCode aCode) const { + return code == aCode; + } + + bool operator !=(const aclMatchCode aCode) const { + return !(*this == aCode); + } + + operator aclMatchCode() const { + return code; + } + + aclMatchCode code; ///< ACCESS_* code + int kind; ///< which custom access list verb matched +}; - inline std::ostream & operator <<(std::ostream &o, const allow_t a) { diff --cc src/anyp/PortCfg.cc index a520d9b568,81dcaa30f2..f128a788d1 --- a/src/anyp/PortCfg.cc +++ b/src/anyp/PortCfg.cc @@@ -3,12 -4,13 +4,16 @@@ #if HAVE_LIMITS #include #endif +#if USE_SSL +#include "ssl/support.h" +#endif - http_port_list::http_port_list(const char *aProtocol) + CBDATA_NAMESPACED_CLASS_INIT(AnyP, PortCfg); + + int NHttpSockets = 0; + int HttpSockets[MAXTCPLISTENPORTS]; + + AnyP::PortCfg::PortCfg(const char *aProtocol) #if USE_SSL : dynamicCertMemCacheSize(std::numeric_limits::max()) @@@ -41,40 -43,49 +46,88 @@@ AnyP::PortCfg::~PortCfg( #endif } + AnyP::PortCfg * + AnyP::PortCfg::clone() const + { + AnyP::PortCfg *b = new AnyP::PortCfg(protocol); + + b->s = s; + if (name) + b->name = xstrdup(name); + if (defaultsite) + b->defaultsite = xstrdup(defaultsite); + + b->intercepted = intercepted; + b->spoof_client_ip = spoof_client_ip; + b->accel = accel; + b->allow_direct = allow_direct; + b->vhost = vhost; + b->sslBump = sslBump; + b->vport = vport; + b->connection_auth_disabled = connection_auth_disabled; + b->disable_pmtu_discovery = disable_pmtu_discovery; + + memcpy( &(b->tcp_keepalive), &(tcp_keepalive), sizeof(tcp_keepalive)); + + #if 0 + // AYJ: 2009-07-18: for now SSL does not clone. Configure separate ports with IPs and SSL settings + #if USE_SSL - void http_port_list::configureSslServerContext() + 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 + + #endif /*0*/ + + return b; + } ++ ++#if USE_SSL ++void AnyP::PortCfg::configureSslServerContext() +{ + staticSslContext.reset( + sslCreateServerContext(cert, key, + version, cipher, options, sslflags, clientca, + cafile, capath, crlfile, dhfile, + sslContextSessionId)); + + if (!staticSslContext) { + char buf[128]; + fatalf("%s_port %s initialization error", protocol, s.ToURL(buf, sizeof(buf))); + } + + if (!sslBump) + return; + + if (cert) + Ssl::readCertChainAndPrivateKeyFromFiles(signingCert, signPkey, certsToChain, cert, key); + + if (!signingCert) { + char buf[128]; + fatalf("No valid signing SSL certificate configured for %s_port %s", protocol, s.ToURL(buf, sizeof(buf))); + } + + if (!signPkey) + debugs(3, DBG_IMPORTANT, "No SSL private key configured for " << protocol << "_port " << s); + + Ssl::generateUntrustedCert(untrustedSigningCert, untrustedSignPkey, + signingCert, signPkey); + + if (!untrustedSigningCert) { + char buf[128]; + fatalf("Unable to generate signing SSL certificate for untrusted sites for %s_port %s", protocol, s.ToURL(buf, sizeof(buf))); + } +} +#endif ++ diff --cc src/anyp/PortCfg.h index 6e3cad24b1,b65433646e..1e22043f0e --- a/src/anyp/PortCfg.h +++ b/src/anyp/PortCfg.h @@@ -12,14 -8,15 +8,18 @@@ #include "ssl/gadgets.h" #endif - struct http_port_list { - http_port_list(const char *aProtocol); - ~http_port_list(); + namespace AnyP + { + + struct PortCfg { + PortCfg(const char *aProtocol); + ~PortCfg(); + AnyP::PortCfg *clone() const; +#if USE_SSL + void configureSslServerContext(); +#endif - http_port_list *next; + PortCfg *next; Ip::Address s; char *protocol; /* protocol name */ @@@ -73,11 -70,18 +73,20 @@@ Ssl::X509_Pointer signingCert; ///< x509 certificate for signing generated certificates Ssl::EVP_PKEY_Pointer signPkey; ///< private key for sighing generated certificates Ssl::X509_STACK_Pointer certsToChain; ///< x509 certificates to send with the generated cert + Ssl::X509_Pointer untrustedSigningCert; ///< x509 certificate for signing untrusted generated certificates + Ssl::EVP_PKEY_Pointer untrustedSignPkey; ///< private key for signing untrusted generated certificates #endif - CBDATA_CLASS2(http_port_list); + CBDATA_CLASS2(PortCfg); // namespaced }; - #endif /* SQUID_PROTO_PORT_H */ + } // namespace AnyP + + // Max number of TCP listening ports + #define MAXTCPLISTENPORTS 128 + + // TODO: kill this global array. Need to check performance of array vs list though. + extern int NHttpSockets; + extern int HttpSockets[MAXTCPLISTENPORTS]; + + #endif /* SQUID_ANYP_PORTCFG_H */ diff --cc src/cache_cf.cc index a9781c4765,c1ca4767d9..338583ffce --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@@ -190,27 -189,11 +190,23 @@@ static int check_null_IpAddress_list(co #endif /* CURRENTLY_UNUSED */ #endif /* USE_WCCPv2 */ - static void parsePortList(http_port_list **, const char *protocol); - #define parse_http_port_list(l) parsePortList((l),"http") - static void dump_http_port_list(StoreEntry *, const char *, const http_port_list *); - static void free_http_port_list(http_port_list **); + static void parsePortCfg(AnyP::PortCfg **, const char *protocol); + #define parse_PortCfg(l) parsePortCfg((l), token) + static void dump_PortCfg(StoreEntry *, const char *, const AnyP::PortCfg *); + static void free_PortCfg(AnyP::PortCfg **); +#if USE_SSL - #define parse_https_port_list(l) parsePortList((l),"https") - #define dump_https_port_list(e,n,l) dump_http_port_list((e),(n),(l)) - #define free_https_port_list(l) free_http_port_list((l)) - #define check_null_https_port_list(l) check_null_http_port_list((l)) +static void parse_sslproxy_cert_sign(sslproxy_cert_sign **cert_sign); +static void dump_sslproxy_cert_sign(StoreEntry *entry, const char *name, sslproxy_cert_sign *cert_sign); +static void free_sslproxy_cert_sign(sslproxy_cert_sign **cert_sign); +static void parse_sslproxy_cert_adapt(sslproxy_cert_adapt **cert_adapt); +static void dump_sslproxy_cert_adapt(StoreEntry *entry, const char *name, sslproxy_cert_adapt *cert_adapt); +static void free_sslproxy_cert_adapt(sslproxy_cert_adapt **cert_adapt); +static void parse_sslproxy_ssl_bump(acl_access **ssl_bump); +static void dump_sslproxy_ssl_bump(StoreEntry *entry, const char *name, acl_access *ssl_bump); +static void free_sslproxy_ssl_bump(acl_access **ssl_bump); +#endif /* USE_SSL */ + static void parse_b_size_t(size_t * var); static void parse_b_int64_t(int64_t * var); @@@ -904,27 -880,29 +895,17 @@@ configDoConfigure(void } } - { - - http_port_list *s; - - for (s = Config.Sockaddr.http; s != NULL; s = (http_port_list *) s->next) { - if (!s->sslBump) - continue; + for (AnyP::PortCfg *s = Config.Sockaddr.http; s != NULL; s = s->next) { - if (!s->cert && !s->key) ++ if (!s->sslBump) + continue; - debugs(3, 1, "Initializing http_port " << s->s << " SSL context"); - s->configureSslServerContext(); - } + debugs(3, 1, "Initializing http_port " << s->s << " SSL context"); - - s->staticSslContext.reset( - sslCreateServerContext(s->cert, s->key, - s->version, s->cipher, s->options, s->sslflags, s->clientca, - s->cafile, s->capath, s->crlfile, s->dhfile, - s->sslContextSessionId)); - - Ssl::readCertChainAndPrivateKeyFromFiles(s->signingCert, s->signPkey, s->certsToChain, s->cert, s->key); ++ s->configureSslServerContext(); } - { - - http_port_list *s; - - for (s = Config.Sockaddr.https; s != NULL; s = s->next) { - debugs(3, 1, "Initializing https_port " << s->s << " SSL context"); - s->configureSslServerContext(); - } + for (AnyP::PortCfg *s = Config.Sockaddr.https; s != NULL; s = s->next) { + debugs(3, 1, "Initializing https_port " << s->s << " SSL context"); - - s->staticSslContext.reset( - sslCreateServerContext(s->cert, s->key, - s->version, s->cipher, s->options, s->sslflags, s->clientca, - s->cafile, s->capath, s->crlfile, s->dhfile, - s->sslContextSessionId)); ++ s->configureSslServerContext(); } #endif @@@ -3862,27 -3788,12 +3791,27 @@@ parsePortCfg(AnyP::PortCfg ** head, con /* parse options ... */ while ((token = strtok(NULL, w_space))) { - parse_http_port_option(s, token); + parse_port_option(s, token); } +#if USE_SSL + if (strcasecmp(protocol, "https") == 0) { + /* ssl-bump on https_port configuration requires either tproxy or intercepted, and vice versa */ + const bool hijacked = s->spoof_client_ip || s->intercepted; + if (s->sslBump && !hijacked) { + debugs(3, DBG_CRITICAL, "FATAL: ssl-bump on https_port requires tproxy/intercepted which is missing."); + self_destruct(); + } + if (hijacked && !s->sslBump) { + debugs(3, DBG_CRITICAL, "FATAL: tproxy/intercepted on https_port requires ssl-bump which is missing."); + self_destruct(); + } + } +#endif + if (Ip::EnableIpv6&IPV6_SPECIAL_SPLITSTACK && s->s.IsAnyAddr()) { // clone the port options from *s to *(s->next) - s->next = clone_http_port_list(s); + s->next = s->clone(); s->next->s.SetIPv4(); debugs(3, 3, protocol << "_port: clone wildcard address for split-stack: " << s->s << " and " << s->next->s); } diff --cc src/client_side_request.cc index 40cab05209,7c738f45d1..4f281f79e5 --- a/src/client_side_request.cc +++ b/src/client_side_request.cc @@@ -1318,7 -1300,10 +1306,10 @@@ static voi sslBumpAccessCheckDoneWrapper(allow_t answer, void *data) { ClientRequestContext *calloutContext = static_cast(data); + + if (!calloutContext->httpStateIsValid()) + return; - calloutContext->sslBumpAccessCheckDone(answer == ACCESS_ALLOWED); + calloutContext->sslBumpAccessCheckDone(answer); } void diff --cc src/forward.cc index 35528305e3,e78081b5fa..2cabf4c71a --- a/src/forward.cc +++ b/src/forward.cc @@@ -35,6 -35,6 +35,7 @@@ #include "forward.h" #include "acl/FilledChecklist.h" #include "acl/Gadgets.h" ++#include "anyp/PortCfg.h" #include "CacheManager.h" #include "comm/Connection.h" #include "comm/ConnOpener.h"