#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);
};
// 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)
{
#if HAVE_LIMITS
#include <limits>
#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<size_t>::max())
#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
++
#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 */
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 */
#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 **);
- #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))
+#if USE_SSL
+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);
}
}
- {
-
- 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
/* 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);
}
sslBumpAccessCheckDoneWrapper(allow_t answer, void *data)
{
ClientRequestContext *calloutContext = static_cast<ClientRequestContext *>(data);
- calloutContext->sslBumpAccessCheckDone(answer == ACCESS_ALLOWED);
+
+ if (!calloutContext->httpStateIsValid())
+ return;
+ calloutContext->sslBumpAccessCheckDone(answer);
}
void
#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"