----- Original Message ----- > TS-1147: Implement default certificate fallback. > > Since we removed the certificate specification from records.config, > implement a new default fallback mechanism in ssl_multicert.config. > We can now use this default when the client does not give us a > hostname, or when the the hostname lookup fails. > > Update the ssl_multicert.config parser to accept lines that don't > have a dest_ip field. Update the documentation in > ssl_multicert.config. > > > Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo > Commit: > http://git-wip-us.apache.org/repos/asf/trafficserver/commit/cadc9b6c > Tree: > http://git-wip-us.apache.org/repos/asf/trafficserver/tree/cadc9b6c > Diff: > http://git-wip-us.apache.org/repos/asf/trafficserver/diff/cadc9b6c > > Branch: refs/heads/master > Commit: cadc9b6ce808cfb1832568676ef1592a19768f5f > Parents: e2827c0 > Author: James Peach <jpe...@apache.org> > Authored: Mon Apr 2 21:36:11 2012 -0700 > Committer: James Peach <jpe...@apache.org> > Committed: Fri Apr 6 21:20:11 2012 -0700 > > ---------------------------------------------------------------------- > iocore/net/P_SSLCertLookup.h | 5 +- > iocore/net/SSLCertLookup.cc | 37 +++++++++-------- > iocore/net/SSLNetVConnection.cc | 13 +++++- > lib/ts/MatcherUtils.cc | 2 +- > lib/ts/MatcherUtils.h | 13 +++++- > proxy/config/ssl_multicert.config.default | 50 > +++++++++++++++++++----- > 6 files changed, 85 insertions(+), 35 deletions(-) > ---------------------------------------------------------------------- > > > http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cadc9b6c/iocore/net/P_SSLCertLookup.h > ---------------------------------------------------------------------- > diff --git a/iocore/net/P_SSLCertLookup.h > b/iocore/net/P_SSLCertLookup.h > index 817cd1f..da18345 100644 > --- a/iocore/net/P_SSLCertLookup.h > +++ b/iocore/net/P_SSLCertLookup.h > @@ -34,13 +34,14 @@ class SSLCertLookup > const char *extractIPAndCert( > matcher_line * line_info, char **addr, char **cert, char **ca, > char **priKey) const; > bool addInfoToHash( > - const char *strAddr, const char *cert, const char *ca, const > char *serverPrivateKey) const; > + const char *strAddr, const char *cert, const char *ca, const > char *serverPrivateKey); > > char config_file_path[PATH_NAME_MAX]; > SslConfigParams *param; > bool multipleCerts; > > SSLContextStorage * ssl_storage; > + SSL_CTX * ssl_default; > > public: > bool hasMultipleCerts() const { return multipleCerts; } > @@ -49,7 +50,7 @@ public: > SSL_CTX *findInfoInHash(const char * address) const; > > // Return the last-resort default TLS context if there is no name > or address match. > - SSL_CTX *defaultContext() const { return NULL; } > + SSL_CTX *defaultContext() const { return ssl_default; } > > SSLCertLookup(); > ~SSLCertLookup(); > > http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cadc9b6c/iocore/net/SSLCertLookup.cc > ---------------------------------------------------------------------- > diff --git a/iocore/net/SSLCertLookup.cc > b/iocore/net/SSLCertLookup.cc > index fb50a1d..82baf3c 100644 > --- a/iocore/net/SSLCertLookup.cc > +++ b/iocore/net/SSLCertLookup.cc > @@ -80,18 +80,19 @@ SSLCertLookup sslCertLookup; > static void > insert_ssl_certificate(SSLContextStorage *, SSL_CTX *, const char > *); > > -#define SSL_IP_TAG "dest_ip" > -#define SSL_CERT_TAG "ssl_cert_name" > -#define SSL_PRIVATE_KEY_TAG "ssl_key_name" > -#define SSL_CA_TAG "ssl_ca_name" > -const char *moduleName = "SSLCertLookup"; > - > -const matcher_tags sslCertTags = { > - NULL, NULL, SSL_IP_TAG, NULL, NULL, false > +#define SSL_IP_TAG "dest_ip" > +#define SSL_CERT_TAG "ssl_cert_name" > +#define SSL_PRIVATE_KEY_TAG "ssl_key_name" > +#define SSL_CA_TAG "ssl_ca_name" > + > +static const char *moduleName = "SSLCertLookup"; > + > +static const matcher_tags sslCertTags = { > + NULL, NULL, NULL, NULL, NULL, false > }; > > SSLCertLookup::SSLCertLookup() > - : param(NULL), multipleCerts(false), ssl_storage(NEW(new > SSLContextStorage())) > + : param(NULL), multipleCerts(false), ssl_storage(NEW(new > SSLContextStorage())), ssl_default(NULL) > { > *config_file_path = '\0'; > } > @@ -166,8 +167,6 @@ SSLCertLookup::buildTable() > moduleName, configFilePath, line_num, errPtr); > IOCORE_SignalError(errBuf, alarmAlready); > } else { > - ink_assert(line_info.type == MATCH_IP); > - > errPtr = extractIPAndCert(&line_info, &addr, &sslCert, > &sslCa, &priKey); > > if (errPtr != NULL) { > @@ -175,7 +174,7 @@ SSLCertLookup::buildTable() > moduleName, configFilePath, line_num, > errPtr); > IOCORE_SignalError(errBuf, alarmAlready); > } else { > - if (addr != NULL && sslCert != NULL) { > + if (sslCert != NULL) { > addInfoToHash(addr, sslCert, sslCa, priKey); > ret = 1; > } > @@ -271,7 +270,7 @@ SSLCertLookup::extractIPAndCert(matcher_line * > line_info, char **addr, char **ce > bool > SSLCertLookup::addInfoToHash( > const char *strAddr, const char *cert, > - const char *caCert, const char *serverPrivateKey) const > + const char *caCert, const char *serverPrivateKey) > { > ink_ssl_method_t meth = NULL; > > @@ -281,14 +280,18 @@ SSLCertLookup::addInfoToHash( > SSLNetProcessor::logSSLError("Cannot create new server > contex."); > return (false); > } > -// if (serverPrivateKey == NULL) > -// serverPrivateKey = cert; > > if (ssl_NetProcessor.initSSLServerCTX(ctx, this->param, cert, > caCert, serverPrivateKey) == 0) { > char * certpath = > Layout::relative_to(this->param->getServerCertPathOnly(), > cert); > > - // Index this certificate by the specified IP(v6) address; > - this->ssl_storage->insert(ctx, strAddr); > + // Index this certificate by the specified IP(v6) address. If > the address is "*", make it the default context.
What happens if more than one such line occurs? > + if (strAddr) { > + if (strcmp(strAddr, "*") == 0) { > + this->ssl_default = ctx; > + } else { > + this->ssl_storage->insert(ctx, strAddr); > + } > + } > > // Insert additional mappings. Note that this maps multiple keys > to the same value, so when > // this code is updated to reconfigure the SSL certificates, it > will need some sort of > > http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cadc9b6c/iocore/net/SSLNetVConnection.cc > ---------------------------------------------------------------------- > diff --git a/iocore/net/SSLNetVConnection.cc > b/iocore/net/SSLNetVConnection.cc > index 0fd34a3..e9372e9 100644 > --- a/iocore/net/SSLNetVConnection.cc > +++ b/iocore/net/SSLNetVConnection.cc > @@ -51,13 +51,20 @@ ClassAllocator<SSLNetVConnection> > sslNetVCAllocator("sslNetVCAllocator"); > static int > ssl_servername_callback(SSL * ssl, int * ad, void * arg) > { > - SSL_CTX * ctx; > + SSL_CTX * ctx = NULL; > SSLCertLookup * lookup = (SSLCertLookup *) arg; > - const char * servername = SSL_get_servername(ssl, > TLSEXT_NAMETYPE_host_name); > + const char * servername = SSL_get_servername(ssl, > TLSEXT_NAMETYPE_host_name); This is some really funky style. Please don't do that. https://cwiki.apache.org/confluence/display/TS/Coding+Style > > Debug("ssl", "ssl=%p ad=%d lookup=%p server=%s", ssl, *ad, lookup, > servername); > > - ctx = lookup->findInfoInHash((char *)servername); > + if (likely(servername)) { > + ctx = lookup->findInfoInHash((char *)servername); > + } > + > + if (ctx == NULL) { > + ctx = lookup->defaultContext(); > + } > + > if (ctx == NULL) { > return SSL_TLSEXT_ERR_NOACK; > } > > http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cadc9b6c/lib/ts/MatcherUtils.cc > ---------------------------------------------------------------------- > diff --git a/lib/ts/MatcherUtils.cc b/lib/ts/MatcherUtils.cc > index 1cab191..632ed25 100644 > --- a/lib/ts/MatcherUtils.cc > +++ b/lib/ts/MatcherUtils.cc > @@ -585,7 +585,7 @@ parseConfigLine(char *line, matcher_line *p_line, > const matcher_tags * tags) > return "Malformed entry"; > } > > - if (p_line->type == MATCH_NONE) { > + if (!tags->empty() && p_line->type == MATCH_NONE) { > if (tags->dest_error_msg == false) { > return "No source specifier"; > } else { > > http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cadc9b6c/lib/ts/MatcherUtils.h > ---------------------------------------------------------------------- > diff --git a/lib/ts/MatcherUtils.h b/lib/ts/MatcherUtils.h > index 94fd2b7..7bd4133 100644 > --- a/lib/ts/MatcherUtils.h > +++ b/lib/ts/MatcherUtils.h > @@ -95,9 +95,18 @@ struct matcher_tags > const char *match_ip; > const char *match_regex; > const char *match_host_regex; > - bool dest_error_msg; // wether to use src or destination > in any > - // errog messages > + bool dest_error_msg; // whether to use src or destination > in any error messages > + > + bool empty() const { > + return this->match_host == NULL && > + this->match_domain == NULL && > + this->match_ip == NULL && > + this->match_regex == NULL && > + this->match_host_regex == NULL; > + } > + > }; > + > extern const matcher_tags http_dest_tags; > extern const matcher_tags ip_allow_tags; > extern const matcher_tags socks_server_tags; > > http://git-wip-us.apache.org/repos/asf/trafficserver/blob/cadc9b6c/proxy/config/ssl_multicert.config.default > ---------------------------------------------------------------------- > diff --git a/proxy/config/ssl_multicert.config.default > b/proxy/config/ssl_multicert.config.default > index 23b71b1..2c21808 100644 > --- a/proxy/config/ssl_multicert.config.default > +++ b/proxy/config/ssl_multicert.config.default > @@ -1,12 +1,42 @@ > # > # ssl_multicert.config > -# Allows an ssl_cert and private key to be tied to a specific > -# IP address on a multihomed machine. If the key is contained in the > -# certificate file, just do not specify an ssl_key_name. > -# If the your certificates have differen Certificate Authorities, > you > -# can specify this on a per-host basis using ssl_ca_name. > -# The certificate file path, ca path and key path specified in > -# records.config will be used # for all certificates, CAs and keys > -# specified here. Example: > -# > -#dest_ip=209.131.48.79 ssl_cert_name=server.pem > ssl_key_name=serverKey.pem > +# > +# Allows a TLS certificate and private key to be tied to a specific > +# hostname or IP address. At load time, the certificate is parsed to > +# extract the subject CN and all the DNS subjectAltNames. The > +# certificate will be presented for connections requesting any of > the > +# hostnames found in the certificate. Wildcard names are supported, > +# but only of the form '*.domain.com', ie. where '*' is the leftmost > +# domain component. > +# > +# The certificate file path, CA path and key path specified in > +# records.config will be used for all certificates, CAs and keys > +# specified here. > +# > +# Fields: > +# > +# dest_ip=ADDRESS > +# The IP (v4 or v6) address that the certificate should be > presented > +# on. This is now only used as a fallback in the case that the TLS > +# SubjectNameIndication extension is not supported. If ADDRESS is > +# '*', the certificate will be used as teh default fallback if no > +# other match can be made. > +# > +# ssl_key_name=FILENAME > +# The name of the file containg the private key for this > certificate. > +# If the key is contained in the certificate file, this field can > be > +# omitted. > +# > +# ssl_ca_name=FILENAME > +# If your certificates have different Certificate Authorities, you > +# can optionally specify the corresponding file here. > +# > +# ssl_cert_name=FILENAME > +# The name of the file containing the TLS certificate. This is the > +# only field that is required to be present. > +# > +# Examples: > +# ssl_cert_name=foo.pem > +# dest_ip=* ssl_cert_name=bar.pem ssl_key_name=barKey.pem > +# dest_ip=209.131.48.79 ssl_cert_name=server.pem > ssl_key_name=serverKey.pem > + > > -- Igor Galić Tel: +43 (0) 664 886 22 883 Mail: i.ga...@brainsware.org URL: http://brainsware.org/ GPG: 6880 4155 74BD FD7C B515 2EA5 4B1D 9E08 A097 C9AE