From 39ffff0972ed8400d7ed4922dcb9e39dd0fdf3b3 Mon Sep 17 00:00:00 2001 From: Jim Jagielski Date: Wed, 7 May 2014 12:52:55 +0000 Subject: [PATCH] restore argument structure for exec-type SSLPassPhraseDialog programs, and implement a special merging algorithm for SSLCertificate[Key]File to emulate the behavior in versions <= 2.4.7 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1593003 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 +++ STATUS | 7 ------ docs/manual/mod/mod_ssl.xml | 12 ++++----- modules/ssl/ssl_engine_config.c | 42 ++++++++++++++++++++++++++++++-- modules/ssl/ssl_engine_pphrase.c | 25 ++++++++++++++++--- modules/ssl/ssl_private.h | 10 ++++++++ 6 files changed, 82 insertions(+), 18 deletions(-) diff --git a/CHANGES b/CHANGES index 0e88a502b7..180b4d09d0 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,10 @@ Changes with Apache 2.4.10 *) mod_authn_socache: Fix crash at startup in certain configurations. PR 56371. (regression in 2.4.7) [Jan Kaluza] + *) mod_ssl: restore argument structure for "exec"-type SSLPassPhraseDialog + programs to the form used in releases up to 2.4.7, and emulate + a backwards-compatible behavior for existing setups. [Kaspar Brand] + *) mod_lua: Enforce the max post size allowed via r:parsebody() [Daniel Gruno] diff --git a/STATUS b/STATUS index 5814b93289..4a872916ae 100644 --- a/STATUS +++ b/STATUS @@ -100,13 +100,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_ssl: restore argument structure for exec-type SSLPassPhraseDialog - programs, and implement a special merging algorithm for - SSLCertificate[Key]File to emulate the behavior in versions <= 2.4.7 - trunk patch: not sensible for trunk (unneeded backwards compatibility) - 2.4.x patch: https://people.apache.org/~kbrand/mod_ssl-2.4.x-pphrase-certkeyfile-compat.diff - +1: kbrand, jkaluza, jim - * mod_proxy_scgi: Support Unix sockets httpd patch: http://svn.apache.org/r1592529 2.4.x patch: trunk patch works modulo CHANGES diff --git a/docs/manual/mod/mod_ssl.xml b/docs/manual/mod/mod_ssl.xml index ceda50a0aa..9fd0b13cf1 100644 --- a/docs/manual/mod/mod_ssl.xml +++ b/docs/manual/mod/mod_ssl.xml @@ -295,15 +295,15 @@ query can be done in two ways which can be configured by
  • exec:/path/to/program

    Here an external program is configured which is called at startup for each - encrypted Private Key file. - For versions up to 2.4.7, it is called with two arguments (the first is + encrypted Private Key file. It is called with two arguments (the first is of the form ``servername:portnumber'', the second is either - ``RSA'', ``DSA'', or ``ECC''), which + ``RSA'', ``DSA'', ``ECC'' or an + integer index starting at 3 if more than three keys are configured), which indicate for which server and algorithm it has to print the corresponding - Pass Phrase to stdout. - Starting with version 2.4.9, it is called with one argument, a string of the + Pass Phrase to stdout. In versions 2.4.8 (unreleased) + and 2.4.9, it is called with one argument, a string of the form ``servername:portnumber:index'' (with index - being a zero-based sequence number), which indicate the server, TCP port + being a zero-based integer number), which indicate the server, TCP port and certificate number. The intent is that this external program first runs security checks to make sure that the system is not compromised by an attacker, and only when these checks were passed diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c index a9e955f5bf..6fa8d0b05f 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -309,6 +309,34 @@ static void modssl_ctx_cfg_merge_proxy(apr_pool_t *p, cfgMergeString(pkp->ca_cert_file); } +static void modssl_ctx_cfg_merge_certkeys_array(apr_pool_t *p, + apr_array_header_t *base, + apr_array_header_t *add, + apr_array_header_t *mrg) +{ + int i; + + /* + * pick up to CERTKEYS_IDX_MAX+1 entries from "add" (in which case they + * they "knock out" their corresponding entries in "base", emulating + * the behavior with cfgMergeString in releases up to 2.4.7) + */ + for (i = 0; i < add->nelts && i <= CERTKEYS_IDX_MAX; i++) { + APR_ARRAY_PUSH(mrg, const char *) = APR_ARRAY_IDX(add, i, const char *); + } + + /* add remaining ones from "base" */ + while (i < base->nelts) { + APR_ARRAY_PUSH(mrg, const char *) = APR_ARRAY_IDX(base, i, const char *); + i++; + } + + /* and finally, append the rest of "add" (if there are any) */ + for (i = CERTKEYS_IDX_MAX+1; i < add->nelts; i++) { + APR_ARRAY_PUSH(mrg, const char *) = APR_ARRAY_IDX(add, i, const char *); + } +} + static void modssl_ctx_cfg_merge_server(apr_pool_t *p, modssl_ctx_t *base, modssl_ctx_t *add, @@ -316,8 +344,18 @@ static void modssl_ctx_cfg_merge_server(apr_pool_t *p, { modssl_ctx_cfg_merge(p, base, add, mrg); - cfgMergeArray(pks->cert_files); - cfgMergeArray(pks->key_files); + /* + * For better backwards compatibility with releases up to 2.4.7, + * merging global and vhost-level SSLCertificateFile and + * SSLCertificateKeyFile directives needs special treatment. + * See also PR 56306 and 56353. + */ + modssl_ctx_cfg_merge_certkeys_array(p, base->pks->cert_files, + add->pks->cert_files, + mrg->pks->cert_files); + modssl_ctx_cfg_merge_certkeys_array(p, base->pks->key_files, + add->pks->key_files, + mrg->pks->key_files); cfgMergeString(pks->ca_name_path); cfgMergeString(pks->ca_name_file); diff --git a/modules/ssl/ssl_engine_pphrase.c b/modules/ssl/ssl_engine_pphrase.c index df81d12198..a1f8734cab 100644 --- a/modules/ssl/ssl_engine_pphrase.c +++ b/modules/ssl/ssl_engine_pphrase.c @@ -43,6 +43,12 @@ typedef struct { const char *pkey_file; } pphrase_cb_arg_t; +#ifdef HAVE_ECC +static const char *key_types[] = {"RSA", "DSA", "ECC"}; +#else +static const char *key_types[] = {"RSA", "DSA"}; +#endif + /* * Return true if the named file exists and is readable */ @@ -576,16 +582,29 @@ int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv) */ else if (sc->server->pphrase_dialog_type == SSL_PPTYPE_FILTER) { const char *cmd = sc->server->pphrase_dialog_path; - const char **argv = apr_palloc(ppcb_arg->p, sizeof(char *) * 3); + const char **argv = apr_palloc(ppcb_arg->p, sizeof(char *) * 4); + const char *idx = ap_strrchr_c(ppcb_arg->key_id, ':') + 1; char *result; + int i; ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb_arg->s, APLOGNO(01969) "Init: Requesting pass phrase from dialog filter " "program (%s)", cmd); argv[0] = cmd; - argv[1] = ppcb_arg->key_id; - argv[2] = NULL; + argv[1] = apr_pstrndup(ppcb_arg->p, ppcb_arg->key_id, + idx-1 - ppcb_arg->key_id); + if ((i = atoi(idx)) < CERTKEYS_IDX_MAX+1) { + /* + * For compatibility with existing 2.4.x configurations, use + * "RSA", "DSA" and "ECC" strings for the first two/three keys + */ + argv[2] = key_types[i]; + } else { + /* Four and above: use the integer index */ + argv[2] = apr_pstrdup(ppcb_arg->p, idx); + } + argv[3] = NULL; result = ssl_util_readfilter(ppcb_arg->s, ppcb_arg->p, cmd, argv); apr_cpystrn(buf, result, bufsize); diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h index 516d7e654d..f4ea10babe 100644 --- a/modules/ssl/ssl_private.h +++ b/modules/ssl/ssl_private.h @@ -258,6 +258,16 @@ ap_set_module_config(c->conn_config, &ssl_module, val) #define DEFAULT_OCSP_TIMEOUT 10 #endif +/* + * For better backwards compatibility with the SSLCertificate[Key]File + * and SSLPassPhraseDialog ("exec" type) directives in 2.4.7 and earlier + */ +#ifdef HAVE_ECC +#define CERTKEYS_IDX_MAX 2 +#else +#define CERTKEYS_IDX_MAX 1 +#endif + /** * Define the SSL options */ -- 2.50.1