From e8122d447d312afb94d4bb709eef3c0a410b1e50 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: May 26 2020 13:56:32 +0000 Subject: import httpd24-httpd-2.4.34-18.el7 --- diff --git a/SOURCES/01-md.conf b/SOURCES/01-md.conf deleted file mode 100644 index 2739202..0000000 --- a/SOURCES/01-md.conf +++ /dev/null @@ -1 +0,0 @@ -LoadModule md_module modules/mod_md.so diff --git a/SOURCES/httpd-2.4.34-CVE-2019-10098.patch b/SOURCES/httpd-2.4.34-CVE-2019-10098.patch new file mode 100644 index 0000000..e1582ca --- /dev/null +++ b/SOURCES/httpd-2.4.34-CVE-2019-10098.patch @@ -0,0 +1,91 @@ +diff --git a/include/ap_regex.h b/include/ap_regex.h +index 7d8df79..7af2f99 100644 +--- a/include/ap_regex.h ++++ b/include/ap_regex.h +@@ -84,7 +84,11 @@ extern "C" { + + #define AP_REG_DOLLAR_ENDONLY 0x200 /* '$' matches at end of subject string only */ + +-#define AP_REG_MATCH "MATCH_" /** suggested prefix for ap_regname */ ++#define AP_REG_NO_DEFAULT 0x400 /**< Don't implicitely add AP_REG_DEFAULT options */ ++ ++#define AP_REG_MATCH "MATCH_" /**< suggested prefix for ap_regname */ ++ ++#define AP_REG_DEFAULT (AP_REG_DOTALL|AP_REG_DOLLAR_ENDONLY) + + /* Error values: */ + enum { +diff --git a/modules/filters/mod_substitute.c b/modules/filters/mod_substitute.c +index b7d5296..e976c51 100644 +--- a/modules/filters/mod_substitute.c ++++ b/modules/filters/mod_substitute.c +@@ -667,8 +667,10 @@ static const char *set_pattern(cmd_parms *cmd, void *cfg, const char *line) + + /* first see if we can compile the regex */ + if (!is_pattern) { +- r = ap_pregcomp(cmd->pool, from, AP_REG_EXTENDED | +- (ignore_case ? AP_REG_ICASE : 0)); ++ int flags = AP_REG_NO_DEFAULT ++ | (ap_regcomp_get_default_cflags() & AP_REG_DOLLAR_ENDONLY) ++ | (ignore_case ? AP_REG_ICASE : 0); ++ r = ap_pregcomp(cmd->pool, from, flags); + if (!r) + return "Substitute could not compile regex"; + } +diff --git a/server/core.c b/server/core.c +index 9d1b973..8011698 100644 +--- a/server/core.c ++++ b/server/core.c +@@ -4970,7 +4970,7 @@ static int core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptem + init_config_defines(pconf); + apr_pool_cleanup_register(pconf, NULL, reset_config, apr_pool_cleanup_null); + +- ap_regcomp_set_default_cflags(AP_REG_DOLLAR_ENDONLY); ++ ap_regcomp_set_default_cflags(AP_REG_DEFAULT); + + mpm_common_pre_config(pconf); + +diff --git a/server/util_pcre.c b/server/util_pcre.c +index f2cb1bb..2a665c8 100644 +--- a/server/util_pcre.c ++++ b/server/util_pcre.c +@@ -120,7 +120,7 @@ AP_DECLARE(void) ap_regfree(ap_regex_t *preg) + * Compile a regular expression * + *************************************************/ + +-static int default_cflags = AP_REG_DOLLAR_ENDONLY; ++static int default_cflags = AP_REG_DEFAULT; + + AP_DECLARE(int) ap_regcomp_get_default_cflags(void) + { +@@ -168,7 +168,8 @@ AP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags) + int errcode = 0; + int options = PCRE_DUPNAMES; + +- cflags |= default_cflags; ++ if ((cflags & AP_REG_NO_DEFAULT) == 0) ++ cflags |= default_cflags; + if ((cflags & AP_REG_ICASE) != 0) + options |= PCRE_CASELESS; + if ((cflags & AP_REG_NEWLINE) != 0) +diff --git a/server/util_regex.c b/server/util_regex.c +index 2a30d68..5405f8d 100644 +--- a/server/util_regex.c ++++ b/server/util_regex.c +@@ -94,6 +94,7 @@ AP_DECLARE(ap_rxplus_t*) ap_rxplus_compile(apr_pool_t *pool, + } + + /* anything after the current delimiter is flags */ ++ ret->flags = ap_regcomp_get_default_cflags() & AP_REG_DOLLAR_ENDONLY; + while (*++endp) { + switch (*endp) { + case 'i': ret->flags |= AP_REG_ICASE; break; +@@ -106,7 +107,7 @@ AP_DECLARE(ap_rxplus_t*) ap_rxplus_compile(apr_pool_t *pool, + default: break; /* we should probably be stricter here */ + } + } +- if (ap_regcomp(&ret->rx, rxstr, ret->flags) == 0) { ++ if (ap_regcomp(&ret->rx, rxstr, AP_REG_NO_DEFAULT | ret->flags) == 0) { + apr_pool_cleanup_register(pool, &ret->rx, rxplus_cleanup, + apr_pool_cleanup_null); + } diff --git a/SOURCES/httpd-2.4.34-mod-md-mod-ssl-hooks.patch b/SOURCES/httpd-2.4.34-mod-md-mod-ssl-hooks.patch new file mode 100644 index 0000000..e4b90fb --- /dev/null +++ b/SOURCES/httpd-2.4.34-mod-md-mod-ssl-hooks.patch @@ -0,0 +1,543 @@ +diff --git a/modules/ssl/mod_ssl.h b/modules/ssl/mod_ssl.h +index 24a65a0..a360911 100644 +--- a/modules/ssl/mod_ssl.h ++++ b/modules/ssl/mod_ssl.h +@@ -29,6 +29,7 @@ + #include "httpd.h" + #include "http_config.h" + #include "apr_optional.h" ++#include "apr_tables.h" /* for apr_array_header_t */ + + /* Create a set of SSL_DECLARE(type), SSL_DECLARE_NONSTD(type) and + * SSL_DECLARE_DATA with appropriate export and import tags for the platform +@@ -86,6 +87,34 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *)); + APR_DECLARE_OPTIONAL_FN(int, ssl_engine_set, (conn_rec *, + ap_conf_vector_t *, + int proxy, int enable)); ++ ++/* Check for availability of new hooks */ ++#define SSL_CERT_HOOKS ++#ifdef SSL_CERT_HOOKS ++ ++/** Lets others add certificate and key files to the given server. ++ * For each cert a key must also be added. ++ * @param cert_file and array of const char* with the path to the certificate chain ++ * @param key_file and array of const char* with the path to the private key file ++ */ ++APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, add_cert_files, ++ (server_rec *s, apr_pool_t *p, ++ apr_array_header_t *cert_files, ++ apr_array_header_t *key_files)) ++ ++/** In case no certificates are available for a server, this ++ * lets other modules add a fallback certificate for the time ++ * being. Regular requests against this server will be answered ++ * with a 503. ++ * @param cert_file and array of const char* with the path to the certificate chain ++ * @param key_file and array of const char* with the path to the private key file ++ */ ++APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, add_fallback_cert_files, ++ (server_rec *s, apr_pool_t *p, ++ apr_array_header_t *cert_files, ++ apr_array_header_t *key_files)) ++ ++#endif /* SSL_CERT_HOOKS */ + + #endif /* __MOD_SSL_H__ */ + /** @} */ +diff --git a/modules/ssl/mod_ssl_openssl.h b/modules/ssl/mod_ssl_openssl.h +index 0fa654a..d4f684f 100644 +--- a/modules/ssl/mod_ssl_openssl.h ++++ b/modules/ssl/mod_ssl_openssl.h +@@ -69,5 +69,45 @@ APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, pre_handshake, + APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, proxy_post_handshake, + (conn_rec *c, SSL *ssl)) + ++/** On TLS connections that do not relate to a configured virtual host, ++ * allow other modules to provide a X509 certificate and EVP_PKEY to ++ * be used on the connection. This first hook which does not ++ * return DECLINED will determine the outcome. */ ++APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, answer_challenge, ++ (conn_rec *c, const char *server_name, ++ X509 **pcert, EVP_PKEY **pkey)) ++ ++/** During post_config phase, ask around if someone wants to provide ++ * OCSP stapling status information for the given cert (with the also ++ * provided issuer certificate). The first hook which does not ++ * return DECLINED promises to take responsibility (and respond ++ * in later calls via hook ssl_get_stapling_status). ++ * If no hook takes over, mod_ssl's own stapling implementation will ++ * be applied (if configured). ++ */ ++APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, init_stapling_status, ++ (server_rec *s, apr_pool_t *p, ++ X509 *cert, X509 *issuer)) ++ ++/** Anyone answering positive to ssl_init_stapling_status for a ++ * certificate, needs to register here and supply the actual OCSP stapling ++ * status data (OCSP_RESP) for a new connection. ++ * A hook supplying the response data must return APR_SUCCESS. ++ * The data is returned in DER encoded bytes via pder and pderlen. The ++ * returned pointer may be NULL, which indicates that data is (currently) ++ * unavailable. ++ * If DER data is returned, it MUST come from a response with ++ * status OCSP_RESPONSE_STATUS_SUCCESSFUL and V_OCSP_CERTSTATUS_GOOD ++ * or V_OCSP_CERTSTATUS_REVOKED, not V_OCSP_CERTSTATUS_UNKNOWN. This means ++ * errors in OCSP retrieval are to be handled/logged by the hook and ++ * are not done by mod_ssl. ++ * Any DER bytes returned MUST be allocated via malloc() and ownership ++ * passes to mod_ssl. Meaning, the hook must return a malloced copy of ++ * the data it has. mod_ssl (or OpenSSL) will free it. ++ */ ++APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, get_stapling_status, ++ (unsigned char **pder, int *pderlen, ++ conn_rec *c, server_rec *s, X509 *cert)) ++ + #endif /* __MOD_SSL_OPENSSL_H__ */ + /** @} */ +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index 397712b..5eec016 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -36,6 +36,25 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_server, + (server_rec *s,apr_pool_t *p,int is_proxy,SSL_CTX *ctx), + (s,p,is_proxy,ctx), OK, DECLINED) + ++APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, add_cert_files, ++ (server_rec *s, apr_pool_t *p, ++ apr_array_header_t *cert_files, apr_array_header_t *key_files), ++ (s, p, cert_files, key_files), ++ OK, DECLINED) ++ ++APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, add_fallback_cert_files, ++ (server_rec *s, apr_pool_t *p, ++ apr_array_header_t *cert_files, apr_array_header_t *key_files), ++ (s, p, cert_files, key_files), ++ OK, DECLINED) ++ ++APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, answer_challenge, ++ (conn_rec *c, const char *server_name, ++ X509 **pcert, EVP_PKEY **pkey), ++ (c, server_name, pcert, pkey), ++ DECLINED, DECLINED) ++ ++ + /* _________________________________________________________________ + ** + ** Module Initialization +@@ -165,18 +184,18 @@ static void ssl_add_version_components(apr_pool_t *p, + modver, AP_SERVER_BASEVERSION, incver); + } + +-/**************************************************************************************************/ +-/* Managed Domains Interface */ +- +-static APR_OPTIONAL_FN_TYPE(md_is_managed) *md_is_managed; +-static APR_OPTIONAL_FN_TYPE(md_get_certificate) *md_get_certificate; +-static APR_OPTIONAL_FN_TYPE(md_is_challenge) *md_is_challenge; ++/* _________________________________________________________________ ++** ++** Let other answer special connection attempts. ++** Used in ACME challenge handling by mod_md. ++** _________________________________________________________________ ++*/ + + int ssl_is_challenge(conn_rec *c, const char *servername, + X509 **pcert, EVP_PKEY **pkey) + { +- if (md_is_challenge) { +- return md_is_challenge(c, servername, pcert, pkey); ++ if (APR_SUCCESS == ssl_run_answer_challenge(c, servername, pcert, pkey)) { ++ return 1; + } + *pcert = NULL; + *pkey = NULL; +@@ -223,16 +242,6 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, + ssl_config_global_create(base_server); /* just to avoid problems */ + ssl_config_global_fix(mc); + +- /* Initialize our interface to mod_md, if it is loaded +- */ +- md_is_managed = APR_RETRIEVE_OPTIONAL_FN(md_is_managed); +- md_get_certificate = APR_RETRIEVE_OPTIONAL_FN(md_get_certificate); +- md_is_challenge = APR_RETRIEVE_OPTIONAL_FN(md_is_challenge); +- if (!md_is_managed || !md_get_certificate) { +- md_is_managed = NULL; +- md_get_certificate = NULL; +- } +- + /* + * try to fix the configuration and open the dedicated SSL + * logfile as early as possible +@@ -1292,8 +1301,7 @@ static apr_status_t ssl_init_server_certs(server_rec *s, + * loaded via SSLOpenSSLConfCmd Certificate), so for 1.0.2 and + * later, we defer to the code in ssl_init_server_ctx. + */ +- if ((mctx->stapling_enabled == TRUE) && +- !ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) { ++ if (!ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02567) + "Unable to configure certificate %s for stapling", + key_id); +@@ -1680,11 +1688,13 @@ static apr_status_t ssl_init_server_ctx(server_rec *s, + apr_array_header_t *pphrases) + { + apr_status_t rv; ++ modssl_pk_server_t *pks; + #ifdef HAVE_SSL_CONF_CMD + ssl_ctx_param_t *param = (ssl_ctx_param_t *)sc->server->ssl_ctx_param->elts; + SSL_CONF_CTX *cctx = sc->server->ssl_ctx_config; + int i; + #endif ++ int n; + + /* + * Check for problematic re-initializations +@@ -1696,50 +1706,24 @@ static apr_status_t ssl_init_server_ctx(server_rec *s, + return APR_EGENERAL; + } + +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10083) +- "Init: (%s) mod_md support is %s.", ssl_util_vhostid(p, s), +- md_is_managed? "available" : "unavailable"); +- if (md_is_managed && md_is_managed(s)) { +- modssl_pk_server_t *const pks = sc->server->pks; +- if (pks->cert_files->nelts > 0 || pks->key_files->nelts > 0) { +- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10084) +- "Init: (%s) You configured certificate/key files on this host, but " +- "is is covered by a Managed Domain. You need to remove these directives " +- "for the Managed Domain to take over.", ssl_util_vhostid(p, s)); +- } +- else { +- const char *key_file, *cert_file, *chain_file; +- +- key_file = cert_file = chain_file = NULL; +- +- if (md_get_certificate) { +- rv = md_get_certificate(s, p, &key_file, &cert_file); +- } +- else { +- rv = APR_ENOTIMPL; +- } +- +- if (key_file && cert_file) { +- ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, +- "%s: installing key=%s, cert=%s, chain=%s", +- ssl_util_vhostid(p, s), key_file, cert_file, chain_file); +- APR_ARRAY_PUSH(pks->key_files, const char *) = key_file; +- APR_ARRAY_PUSH(pks->cert_files, const char *) = cert_file; +- sc->server->cert_chain = chain_file; +- } +- +- if (APR_STATUS_IS_EAGAIN(rv)) { +- /* Managed Domain not ready yet. This is not a reason to fail the config */ +- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10085) +- "Init: %s will respond with '503 Service Unavailable' for now. This " +- "host is part of a Managed Domain, but no SSL certificate is " +- "available (yet).", ssl_util_vhostid(p, s)); +- pks->service_unavailable = 1; +- } +- else if (rv != APR_SUCCESS) { +- return rv; +- } +- } ++ /* Allow others to provide certificate files */ ++ pks = sc->server->pks; ++ n = pks->cert_files->nelts; ++ ssl_run_add_cert_files(s, p, pks->cert_files, pks->key_files); ++ ++ if (n < pks->cert_files->nelts) { ++ /* this overrides any old chain configuration */ ++ sc->server->cert_chain = NULL; ++ } ++ ++ if (apr_is_empty_array(pks->cert_files) && !sc->server->cert_chain) { ++ ssl_run_add_fallback_cert_files(s, p, pks->cert_files, pks->key_files); ++ ++ pks->service_unavailable = 1; ++ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10085) ++ "Init: %s will respond with '503 Service Unavailable' for now. There " ++ "are no SSL certificates configured and no other module contributed any.", ++ ssl_util_vhostid(p, s)); + } + + if ((rv = ssl_init_ctx(s, p, ptemp, sc->server)) != APR_SUCCESS) { +@@ -1792,7 +1776,7 @@ static apr_status_t ssl_init_server_ctx(server_rec *s, + * (late) point makes sure that we catch both certificates loaded + * via SSLCertificateFile and SSLOpenSSLConfCmd Certificate. + */ +- if (sc->server->stapling_enabled == TRUE) { ++ do { + X509 *cert; + int i = 0; + int ret = SSL_CTX_set_current_cert(sc->server->ssl_ctx, +@@ -1809,7 +1793,7 @@ static apr_status_t ssl_init_server_ctx(server_rec *s, + SSL_CERT_SET_NEXT); + i++; + } +- } ++ } while(0); + #endif + + #ifdef HAVE_TLS_SESSION_TICKETS +diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c +index d6aa051..456984a 100644 +--- a/modules/ssl/ssl_engine_kernel.c ++++ b/modules/ssl/ssl_engine_kernel.c +@@ -2114,6 +2114,37 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc) + } + + #ifdef HAVE_TLSEXT ++ ++static apr_status_t set_challenge_creds(conn_rec *c, const char *servername, ++ SSL *ssl, X509 *cert, EVP_PKEY *key) ++{ ++ SSLConnRec *sslcon = myConnConfig(c); ++ ++ sslcon->service_unavailable = 1; ++ if ((SSL_use_certificate(ssl, cert) < 1)) { ++ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10086) ++ "Failed to configure challenge certificate %s", ++ servername); ++ return APR_EGENERAL; ++ } ++ ++ if (!SSL_use_PrivateKey(ssl, key)) { ++ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10087) ++ "error '%s' using Challenge key: %s", ++ ERR_error_string(ERR_peek_last_error(), NULL), ++ servername); ++ return APR_EGENERAL; ++ } ++ ++ if (SSL_check_private_key(ssl) < 1) { ++ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10088) ++ "Challenge certificate and private key %s " ++ "do not match", servername); ++ return APR_EGENERAL; ++ } ++ return APR_SUCCESS; ++} ++ + /* + * This function sets the virtual host from an extended + * client hello with a server name indication extension ("SNI", cf. RFC 6066). +@@ -2144,29 +2175,12 @@ static apr_status_t init_vhost(conn_rec *c, SSL *ssl) + } + else if (ssl_is_challenge(c, servername, &cert, &key)) { + +- sslcon->service_unavailable = 1; +- if ((SSL_use_certificate(ssl, cert) < 1)) { +- ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10086) +- "Failed to configure challenge certificate %s", +- servername); ++ /* With ACMEv1 we can have challenge connections to a unknown domains ++ * that need to be answered with a special certificate and will ++ * otherwise not answer any requests. */ ++ if (set_challenge_creds(c, servername, ssl, cert, key) != APR_SUCCESS) { + return APR_EGENERAL; + } +- +- if (!SSL_use_PrivateKey(ssl, key)) { +- ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10087) +- "error '%s' using Challenge key: %s", +- ERR_error_string(ERR_peek_last_error(), NULL), +- servername); +- return APR_EGENERAL; +- } +- +- if (SSL_check_private_key(ssl) < 1) { +- ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10088) +- "Challenbge certificate and private key %s " +- "do not match", servername); +- return APR_EGENERAL; +- } +- + } + else { + ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02044) +@@ -2457,6 +2471,23 @@ int ssl_callback_alpn_select(SSL *ssl, + proposed); + return SSL_TLSEXT_ERR_ALERT_FATAL; + } ++ ++ /* protocol was switched, this could be a challenge protocol such as "acme-tls/1". ++ * For that to work, we need to allow overrides to our ssl certificate. ++ * However, exclude challenge checks on our best known traffic protocol. ++ * (http/1.1 is the default, we never switch to it anyway.) ++ */ ++ if (strcmp("h2", proposed)) { ++ const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); ++ X509 *cert; ++ EVP_PKEY *key; ++ ++ if (ssl_is_challenge(c, servername, &cert, &key)) { ++ if (set_challenge_creds(c, servername, ssl, cert, key) != APR_SUCCESS) { ++ return SSL_TLSEXT_ERR_ALERT_FATAL; ++ } ++ } ++ } + } + + return SSL_TLSEXT_ERR_OK; +diff --git a/modules/ssl/ssl_util_stapling.c b/modules/ssl/ssl_util_stapling.c +index c3e2cfa..4df0a9a 100644 +--- a/modules/ssl/ssl_util_stapling.c ++++ b/modules/ssl/ssl_util_stapling.c +@@ -31,12 +31,28 @@ + #include "ssl_private.h" + #include "ap_mpm.h" + #include "apr_thread_mutex.h" ++#include "mod_ssl_openssl.h" ++ ++APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_stapling_status, ++ (server_rec *s, apr_pool_t *p, ++ X509 *cert, X509 *issuer), ++ (s, p, cert, issuer), ++ DECLINED, DECLINED) ++ ++APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, get_stapling_status, ++ (unsigned char **pder, int *pderlen, ++ conn_rec *c, server_rec *s, X509 *cert), ++ (pder, pderlen, c, s, cert), ++ DECLINED, DECLINED) ++ + + #ifdef HAVE_OCSP_STAPLING + + static int stapling_cache_mutex_on(server_rec *s); + static int stapling_cache_mutex_off(server_rec *s); + ++static int stapling_cb(SSL *ssl, void *arg); ++ + /** + * Maxiumum OCSP stapling response size. This should be the response for a + * single certificate and will typically include the responder certificate chain +@@ -119,7 +135,38 @@ int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, + OCSP_CERTID *cid = NULL; + STACK_OF(OPENSSL_STRING) *aia = NULL; + +- if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1)) ++ if (x == NULL) ++ return 0; ++ ++ if (!(issuer = stapling_get_issuer(mctx, x))) { ++ /* In Apache pre 2.4.40, we use to come here only when mod_ssl stapling ++ * was enabled. With the new hooks, we give other modules the chance ++ * to provide stapling status. However, we do not want to log ssl errors ++ * where we did not do so in the past. */ ++ if (mctx->stapling_enabled == TRUE) { ++ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02217) ++ "ssl_stapling_init_cert: can't retrieve issuer " ++ "certificate!"); ++ return 0; ++ } ++ return 1; ++ } ++ ++ if (ssl_run_init_stapling_status(s, p, x, issuer) == APR_SUCCESS) { ++ /* Someone's taken over or mod_ssl's own implementation is not enabled */ ++ if (mctx->stapling_enabled != TRUE) { ++ SSL_CTX_set_tlsext_status_cb(mctx->ssl_ctx, stapling_cb); ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO() "OCSP stapling added via hook"); ++ } ++ return 1; ++ } ++ ++ if (mctx->stapling_enabled != TRUE) { ++ /* mod_ssl's own implementation is not enabled */ ++ return 1; ++ } ++ ++ if (X509_digest(x, EVP_sha1(), idx, NULL) != 1) + return 0; + + cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx)); +@@ -139,13 +186,6 @@ int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, + return 1; + } + +- if (!(issuer = stapling_get_issuer(mctx, x))) { +- ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02217) +- "ssl_stapling_init_cert: can't retrieve issuer " +- "certificate!"); +- return 0; +- } +- + cid = OCSP_cert_to_id(NULL, x, issuer); + X509_free(issuer); + if (!cid) { +@@ -182,18 +222,16 @@ int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, + mctx->sc->vhost_id); + + apr_hash_set(stapling_certinfo, cinf->idx, sizeof(cinf->idx), cinf); +- ++ + return 1; + } + +-static certinfo *stapling_get_certinfo(server_rec *s, modssl_ctx_t *mctx, ++static certinfo *stapling_get_certinfo(server_rec *s, X509 *x, modssl_ctx_t *mctx, + SSL *ssl) + { + certinfo *cinf; +- X509 *x; + UCHAR idx[SHA_DIGEST_LENGTH]; +- x = SSL_get_certificate(ssl); +- if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1)) ++ if (X509_digest(x, EVP_sha1(), idx, NULL) != 1) + return NULL; + cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx)); + if (cinf && cinf->cid) +@@ -750,18 +788,34 @@ static int stapling_cb(SSL *ssl, void *arg) + OCSP_RESPONSE *rsp = NULL; + int rv; + BOOL ok = TRUE; ++ X509 *x; ++ unsigned char *rspder = NULL; ++ int rspderlen; + ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951) ++ "stapling_cb: OCSP Stapling callback called"); ++ ++ x = SSL_get_certificate(ssl); ++ if (x == NULL) { ++ return SSL_TLSEXT_ERR_NOACK; ++ } ++ ++ if (ssl_run_get_stapling_status(&rspder, &rspderlen, conn, s, x) == APR_SUCCESS) { ++ /* a hook handles stapling for this certicate and determines the response */ ++ if (rspder == NULL || rspderlen <= 0) { ++ return SSL_TLSEXT_ERR_NOACK; ++ } ++ SSL_set_tlsext_status_ocsp_resp(ssl, rspder, rspderlen); ++ return SSL_TLSEXT_ERR_OK; ++ } ++ + if (sc->server->stapling_enabled != TRUE) { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01950) + "stapling_cb: OCSP Stapling disabled"); + return SSL_TLSEXT_ERR_NOACK; + } + +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951) +- "stapling_cb: OCSP Stapling callback called"); +- +- cinf = stapling_get_certinfo(s, mctx, ssl); +- if (cinf == NULL) { ++ if ((cinf = stapling_get_certinfo(s, x, mctx, ssl)) == NULL) { + return SSL_TLSEXT_ERR_NOACK; + } + +@@ -864,9 +918,10 @@ apr_status_t modssl_init_stapling(server_rec *s, apr_pool_t *p, + if (mctx->stapling_responder_timeout == UNSET) { + mctx->stapling_responder_timeout = 10 * APR_USEC_PER_SEC; + } ++ + SSL_CTX_set_tlsext_status_cb(ctx, stapling_cb); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01960) "OCSP stapling initialized"); +- ++ + return APR_SUCCESS; + } + diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec index 109c619..11104d0 100644 --- a/SPECS/httpd.spec +++ b/SPECS/httpd.spec @@ -51,7 +51,7 @@ Summary: Apache HTTP Server Name: %{?scl:%scl_prefix}httpd Version: 2.4.34 -Release: 15%{?dist} +Release: 18%{?dist} URL: http://httpd.apache.org/ Source0: http://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2 Source1: index.html @@ -81,7 +81,6 @@ Source26: action-graceful.sh Source27: action-configtest.sh Source28: 00-optional.conf Source29: httpd-scl-wrapper -Source30: 01-md.conf Source31: config.layout # Documentation @@ -130,6 +129,11 @@ Patch84: httpd-2.4.34-r1842929+.patch Patch85: httpd-2.4.34-r1847288.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1744120 Patch86: httpd-2.4.34-r1865740.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1788976 +# patch only RHEL-7, where we ship mod_md +%if %{enable_mod_md} +Patch87: httpd-2.4.34-mod-md-mod-ssl-hooks.patch +%endif # Security fixes Patch200: httpd-2.4.34-CVE-2018-11763.patch @@ -151,6 +155,8 @@ Patch206: httpd-2.4.34-CVE-2018-17189.patch Patch207: httpd-2.4.34-CVE-2019-10092.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1747290 Patch208: httpd-2.4.34-CVE-2019-10097.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1747285 +Patch209: httpd-2.4.34-CVE-2019-10098.patch License: ASL 2.0 Group: System Environment/Daemons @@ -253,21 +259,6 @@ The mod_ssl module provides strong cryptography for the Apache Web server via the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols. -%if %{enable_mod_md} -%package -n %{?scl:%scl_prefix}mod_md -Group: System Environment/Daemons -Summary: Certificate provisioning using ACME for the Apache HTTP Server -Requires: %{?scl:%scl_prefix}httpd = 0:%{version}-%{release}, %{?scl:%scl_prefix}httpd-mmn = %{mmnisa} -BuildRequires: jansson-devel, %{?scl:%scl_prefix}libcurl-devel - -%description -n %{?scl:%scl_prefix}mod_md -This module manages common properties of domains for one or more -virtual hosts. Specifically it can use the ACME protocol (RFC Draft) -to automate certificate provisioning. These will be configured for -managed domains and their virtual hosts automatically. This includes -renewal of certificates before they expire. -%endif - %package -n %{?scl:%scl_prefix}mod_proxy_html Group: System Environment/Daemons Summary: HTML and XML content filters for the Apache HTTP Server @@ -361,6 +352,10 @@ export LD_LIBRARY_PATH=%{_libdir}:$LD_LIBRARY_PATH %patch84 -p1 -b .r1842929+ %patch85 -p1 -b .r1847288 %patch86 -p1 -b .r1865740 +# patch only RHEL-7, where we ship mod_md +%if %{enable_mod_md} +%patch87 -p1 -b .mod-md-mod-ssl-hooks +%endif %patch200 -p1 -b .CVE-2018-11763 %patch201 -p1 -b .CVE-2019-0211 @@ -371,6 +366,7 @@ export LD_LIBRARY_PATH=%{_libdir}:$LD_LIBRARY_PATH %patch206 -p1 -b .CVE-2018-17189 %patch207 -p1 -b .CVE-2019-10092 %patch208 -p1 -b .CVE-2019-10097 +%patch209 -p1 -b .CVE-2019-10098 # Patch in the vendor string and the release string sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h @@ -453,6 +449,9 @@ export LYNX_PATH=/usr/bin/links --enable-cgid --enable-cgi \ --enable-authn-anon --enable-authn-alias \ --disable-imagemap \ +%if %{enable_mod_md} + --disable-md \ +%endif --localstatedir=%{_localstatedir} make %{?_smp_mflags} @@ -529,9 +528,6 @@ for f in 00-base.conf 00-mpm.conf 00-lua.conf 01-cgi.conf 00-dav.conf \ %if %{use_systemd} 00-systemd.conf \ %endif -%if %{enable_mod_md} - 01-md.conf \ -%endif 01-ldap.conf 01-session.conf 00-optional.conf; do install -m 644 -p $RPM_SOURCE_DIR/$f \ $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/$f @@ -906,9 +902,6 @@ rm -rf $RPM_BUILD_ROOT %exclude %{_sysconfdir}/httpd/conf.modules.d/00-proxyhtml.conf %exclude %{_sysconfdir}/httpd/conf.modules.d/01-ldap.conf %exclude %{_sysconfdir}/httpd/conf.modules.d/01-session.conf -%if %{enable_mod_md} -%exclude %{_sysconfdir}/httpd/conf.modules.d/01-md.conf -%endif %config(noreplace) %{_sysconfdir}/sysconfig/httpd %config(noreplace) %{_sysconfdir}/sysconfig/htcacheclean @@ -1017,12 +1010,6 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/httpd/modules/mod_auth_form.so %config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/01-session.conf -%if %{enable_mod_md} -%files -n %{?scl:%scl_prefix}mod_md -%{_libdir}/httpd/modules/mod_md.so -%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/01-md.conf -%endif - %files devel %defattr(-,root,root) %{_includedir}/httpd @@ -1038,6 +1025,16 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Tue Mar 17 2020 Lubos Uhliarik - 2.4.34-18 +- Related: #1743959 (CVE-2019-10098) - CVE-2019-10098 httpd: mod_rewrite + potential open redirect + +* Mon Feb 03 2020 Lubos Uhliarik - 2.4.34-16 +- remove bundled mod_md module +- Resolves: #1788976 - RFE: updated collection for httpd 2.4 +- Resolves: #1743959 (CVE-2019-10098) - CVE-2019-10098 httpd: mod_rewrite + potential open redirect + * Wed Nov 13 2019 Lubos Uhliarik - 2.4.34-15 - Related: #1725922 - duplicated cookie in Apache httpd with mod_session