----- 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 <[email protected]>
> Authored: Mon Apr 2 21:36:11 2012 -0700
> Committer: James Peach <[email protected]>
> 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: [email protected]
URL: http://brainsware.org/
GPG: 6880 4155 74BD FD7C B515 2EA5 4B1D 9E08 A097 C9AE