--- tomcat-connectors-1.2.20-src.orig/native/common/jk_global.h 2006-11-27 13:22:29.000000000 +0100 +++ tomcat-connectors-1.2.20-src/native/common/jk_global.h 2007-01-24 10:38:24.000000000 +0100 @@ -249,6 +249,7 @@ #define JK_OPT_FLUSHPACKETS 0x0020 #define JK_OPT_FLUSHEADER 0x0040 #define JK_OPT_DISABLEREUSE 0x0080 +#define JK_OPT_FWDCERTCHAIN 0x0100 /* Check for EBCDIC systems */ --- tomcat-connectors-1.2.20-src.orig/native/apache-1.3/mod_jk.c 2006-12-03 14:57:46.000000000 +0100 +++ tomcat-connectors-1.2.20-src/native/apache-1.3/mod_jk.c 2007-01-24 11:40:20.000000000 +0100 @@ -154,6 +154,7 @@ int ssl_enable; char *https_indicator; char *certs_indicator; + char *certchain_indicator; char *cipher_indicator; char *session_indicator; char *key_size_indicator; @@ -632,8 +633,37 @@ s->ssl_cert = (char *)ap_table_get(r->subprocess_env, conf->certs_indicator); + if (conf->options & JK_OPT_FWDCERTCHAIN) { + array_header *t = ap_table_elts(r->subprocess_env); + if (t && t->nelts) { + int i; + table_entry *elts = (table_entry *) t->elts; + array_header *certs = ap_make_array(r->pool, + 1, + sizeof(char *)); + *(const char **)ap_push_array(certs) = s->ssl_cert; + for (i = 0; i < t->nelts; i++) { + if (!elts[i].key) + continue; + if (!strncasecmp(elts[i].key, + conf->certchain_indicator, + strlen(conf->certchain_indicator))) + *(const char **)ap_push_array(certs) = elts[i].val; + } + s->ssl_cert = ap_array_pstrcat(r->pool, certs, '\0'); + } + } if (s->ssl_cert) { s->ssl_cert_len = strlen(s->ssl_cert); + jk_log(conf->log ? conf->log : main_log, + JK_LOG_DEBUG, + "length of SSL client certificate: %d bytes", + s->ssl_cert_len); + if (s->ssl_cert_len > 0) + jk_log(conf->log ? conf->log : main_log, + JK_LOG_DEBUG, + ", dump follows:\n%s", + s->ssl_cert); } /* Servlet 2.3 API */ s->ssl_cipher = @@ -1525,6 +1555,23 @@ } /* + * JkCERTCHAINIndicator Directive Handling + * + * JkCERTCHAINIndicator SSL_CLIENT_CERT_CHAIN_ + */ +static const char *jk_set_certchain_indicator(cmd_parms * cmd, + void *dummy, char *indicator) +{ + server_rec *s = cmd->server; + jk_server_conf_t *conf = + (jk_server_conf_t *) ap_get_module_config(s->module_config, + &jk_module); + + conf->certchain_indicator = ap_pstrdup(cmd->pool, indicator); + return NULL; +} + +/* * JkCIPHERIndicator Directive Handling * * JkCIPHERIndicator SSL_CIPHER @@ -1588,7 +1635,9 @@ * ForwardURICompatUnparsed => Forward URI as unparsed, spec compliant but broke mod_rewrite (old TC) * ForwardURIEscaped => Forward URI escaped and Tomcat (3.3 rc2) stuff will do the decoding part * ForwardDirectories => Forward all directory requests with no index files to Tomcat - */ + * +ForwardSSLCertChain => Forward SSL Cert Chain + * -ForwardSSLCertChain => Don't Forward SSL Cert Chain (default) +*/ const char *jk_set_options(cmd_parms * cmd, void *dummy, const char *line) { @@ -1646,6 +1695,9 @@ else if (!strcasecmp(w, "DisableReuse")) { opt = JK_OPT_DISABLEREUSE; } + else if (!strcasecmp(w, "ForwardCertChain")) { + opt = JK_OPT_FWDCERTCHAIN; + } else return ap_pstrcat(cmd->pool, "JkOptions: Illegal option '", w, "'", NULL); @@ -1813,6 +1865,7 @@ * * HTTPS - indication for SSL * CERTS - Base64-Der-encoded client certificates. + * CERTCHAIN - Base64-Der-encoded client chain certificates. * CIPHER - A string specifing the ciphers suite in use. * SESSION - A string specifing the current SSL session. * KEYSIZE - Size of Key used in dialogue (#bits are secure) @@ -1821,6 +1874,8 @@ "Name of the Apache environment that contains SSL indication"}, {"JkCERTSIndicator", jk_set_certs_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains SSL client certificates"}, + {"JkCERTCHAINIndicator", jk_set_certchain_indicator, NULL, RSRC_CONF, TAKE1, + "Name of the Apache environment (prefix) that contains SSL client chain certificates"}, {"JkCIPHERIndicator", jk_set_cipher_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains SSL client cipher"}, {"JkSESSIONIndicator", jk_set_session_indicator, NULL, RSRC_CONF, TAKE1, @@ -1838,6 +1893,8 @@ * ForwardURICompat => Forward URI normally, less spec compliant but mod_rewrite compatible (old TC) * ForwardURICompatUnparsed => Forward URI as unparsed, spec compliant but broke mod_rewrite (old TC) * ForwardURIEscaped => Forward URI escaped and Tomcat (3.3 rc2) stuff will do the decoding part + * +ForwardSSLCertChain => Forward SSL certificate chain + * -ForwardSSLCertChain => Don't forward SSL certificate chain (default) */ {"JkOptions", jk_set_options, NULL, RSRC_CONF, RAW_ARGS, "Set one of more options to configure the mod_jk module"}, @@ -2123,6 +2180,7 @@ */ c->https_indicator = JK_ENV_HTTPS; c->certs_indicator = JK_ENV_CERTS; + c->certchain_indicator = "SSL_CLIENT_CERT_CHAIN_"; c->cipher_indicator = JK_ENV_CIPHER; c->session_indicator = JK_ENV_SESSION; c->key_size_indicator = JK_ENV_KEY_SIZE; @@ -2188,6 +2246,8 @@ overrides->https_indicator = base->https_indicator; if (!overrides->certs_indicator) overrides->certs_indicator = base->certs_indicator; + if (!overrides->certchain_indicator) + overrides->certchain_indicator = base->certchain_indicator; if (!overrides->cipher_indicator) overrides->cipher_indicator = base->cipher_indicator; if (!overrides->session_indicator) --- tomcat-connectors-1.2.20-src.orig/native/apache-2.0/mod_jk.c 2006-12-03 14:57:46.000000000 +0100 +++ tomcat-connectors-1.2.20-src/native/apache-2.0/mod_jk.c 2007-01-24 11:42:54.000000000 +0100 @@ -188,6 +188,7 @@ int ssl_enable; char *https_indicator; char *certs_indicator; + char *certchain_indicator; char *cipher_indicator; char *session_indicator; /* Servlet API 2.3 requirement */ char *key_size_indicator; /* Servlet API 2.3 requirement */ @@ -656,8 +657,27 @@ s->ssl_cert = (char *)apr_table_get(r->subprocess_env, conf->certs_indicator); + if (conf->options & JK_OPT_FWDCERTCHAIN) { + const apr_array_header_t *t = apr_table_elts(r->subprocess_env); + if (t && t->nelts) { + int i; + const apr_table_entry_t *elts = (const apr_table_entry_t *) t->elts; + apr_array_header_t *certs = apr_array_make(r->pool, 1, sizeof(char *)); + *(const char **)apr_array_push(certs) = s->ssl_cert; + for (i = 0; i < t->nelts; i++) { + if (!elts[i].key) + continue; + if (!strncasecmp(elts[i].key, conf->certchain_indicator, strlen(conf->certchain_indicator))) + *(const char **)apr_array_push(certs) = elts[i].val; + } + s->ssl_cert = apr_array_pstrcat(r->pool, certs, '\0'); + } + } if (s->ssl_cert) { s->ssl_cert_len = strlen(s->ssl_cert); + jk_log(conf->log, JK_LOG_DEBUG, "length of SSL client certificate: %d bytes", s->ssl_cert_len); + if (s->ssl_cert_len > 0) + jk_log(conf->log, JK_LOG_DEBUG, ", dump follows:\n%s", s->ssl_cert); } /* Servlet 2.3 API */ s->ssl_cipher = @@ -1547,6 +1567,25 @@ } /* + * JkCERTCHAINIndicator Directive Handling + * + * JkCERTCHAINIndicator SSL_CLIENT_CERT_CHAIN_ + */ + +static const char *jk_set_certchain_indicator(cmd_parms * cmd, + void *dummy, const char *indicator) +{ + server_rec *s = cmd->server; + jk_server_conf_t *conf = + (jk_server_conf_t *) ap_get_module_config(s->module_config, + &jk_module); + + conf->certchain_indicator = apr_pstrdup(cmd->pool, indicator); + + return NULL; +} + +/* * JkCIPHERIndicator Directive Handling * * JkCIPHERIndicator SSL_CIPHER @@ -1615,6 +1654,8 @@ * ForwardURICompatUnparsed => Forward URI as unparsed, spec compliant but broke mod_rewrite (old TC) * ForwardURIEscaped => Forward URI escaped and Tomcat (3.3 rc2) stuff will do the decoding part * ForwardDirectories => Forward all directory requests with no index files to Tomcat + * +ForwardSSLCertChain => Forward SSL Cert Chain + * -ForwardSSLCertChain => Don't Forward SSL Cert Chain (default) */ static const char *jk_set_options(cmd_parms * cmd, void *dummy, @@ -1674,6 +1715,9 @@ else if (!strcasecmp(w, "DisableReuse")) { opt = JK_OPT_DISABLEREUSE; } + else if (!strcasecmp(w, "ForwardCertChain")) { + opt = JK_OPT_FWDCERTCHAIN; + } else return apr_pstrcat(cmd->pool, "JkOptions: Illegal option '", w, "'", NULL); @@ -1852,6 +1896,7 @@ * * HTTPS - indication for SSL * CERTS - Base64-Der-encoded client certificates. + * CERTCHAIN - Base64-Der-encoded client chain certificates. * CIPHER - A string specifing the ciphers suite in use. * KEYSIZE - Size of Key used in dialogue (#bits are secure) * SESSION - A string specifing the current SSL session. @@ -1860,6 +1905,8 @@ "Name of the Apache environment that contains SSL indication"), AP_INIT_TAKE1("JkCERTSIndicator", jk_set_certs_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains SSL client certificates"), + AP_INIT_TAKE1("JkCERTCHAINIndicator", jk_set_certchain_indicator, NULL, RSRC_CONF, + "Name of the Apache environment (prefix) that contains SSL client chain certificates"), AP_INIT_TAKE1("JkCIPHERIndicator", jk_set_cipher_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains SSL client cipher"), @@ -1880,6 +1927,8 @@ * ForwardURICompat => Forward URI normally, less spec compliant but mod_rewrite compatible (old TC) * ForwardURICompatUnparsed => Forward URI as unparsed, spec compliant but broke mod_rewrite (old TC) * ForwardURIEscaped => Forward URI escaped and Tomcat (3.3 rc2) stuff will do the decoding part + * +ForwardSSLCertChain => Forward SSL certificate chain + * -ForwardSSLCertChain => Don't forward SSL certificate chain */ AP_INIT_RAW_ARGS("JkOptions", jk_set_options, NULL, RSRC_CONF, "Set one of more options to configure the mod_jk module"), @@ -2242,6 +2291,7 @@ */ c->https_indicator = JK_ENV_HTTPS; c->certs_indicator = JK_ENV_CERTS; + c->certchain_indicator = "SSL_CLIENT_CERT_CHAIN_"; c->cipher_indicator = JK_ENV_CIPHER; c->session_indicator = JK_ENV_SESSION; c->key_size_indicator = JK_ENV_KEY_SIZE; @@ -2313,6 +2363,8 @@ overrides->https_indicator = base->https_indicator; if (!overrides->certs_indicator) overrides->certs_indicator = base->certs_indicator; + if (!overrides->certchain_indicator) + overrides->certchain_indicator = base->certchain_indicator; if (!overrides->cipher_indicator) overrides->cipher_indicator = base->cipher_indicator; if (!overrides->session_indicator)