From eafb46761acac68c3f98f49873a921f162ad66c599444a7fce75ca6ae652f8ff Mon Sep 17 00:00:00 2001 From: Stephan Kulow Date: Tue, 7 Aug 2012 09:03:36 +0000 Subject: [PATCH] revert back to rev 62 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=64 --- apache-20-22-upgrade | 8 +- apache2-default-server.conf | 2 +- apache2-httpd.conf | 2 +- apache2-mod_ssl_npn.patch | 1396 ++--------------- ...tch => apache2.2-mpm-itk-20090414-00.patch | 1308 +++++++-------- apache2.changes | 25 - apache2.spec | 64 +- httpd-2.0.54-envvars.dif | 16 +- httpd-2.1.9-apachectl.dif | 22 +- httpd-2.2.22.tar.bz2 | 3 + httpd-2.2.22.tar.bz2.asc | Bin 0 -> 678 bytes ...-2.2.x-CVE-2011-3368-server_protocl_c.diff | 68 + httpd-2.2.x-bnc690734.patch | 21 +- httpd-2.4.2.tar.xz | 3 - httpd-keepalivetimeout-millisecs.patch | 20 + httpd-mod_deflate_head.patch | 23 + httpd-new_pcre.patch | 23 + ssl-mode-release-buffers.patch | 13 + 18 files changed, 926 insertions(+), 2091 deletions(-) rename apache2.4-mpm-itk-2.4.2-01.patch => apache2.2-mpm-itk-20090414-00.patch (62%) create mode 100644 httpd-2.2.22.tar.bz2 create mode 100644 httpd-2.2.22.tar.bz2.asc create mode 100644 httpd-2.2.x-CVE-2011-3368-server_protocl_c.diff delete mode 100644 httpd-2.4.2.tar.xz create mode 100644 httpd-keepalivetimeout-millisecs.patch create mode 100644 httpd-mod_deflate_head.patch create mode 100644 httpd-new_pcre.patch create mode 100644 ssl-mode-release-buffers.patch diff --git a/apache-20-22-upgrade b/apache-20-22-upgrade index 561c697..6eeaaf2 100644 --- a/apache-20-22-upgrade +++ b/apache-20-22-upgrade @@ -13,6 +13,7 @@ if a2enmod -q auth; then a2enmod authz_groupfile a2enmod authz_default a2enmod authz_user + cat <<-EOF @@ -60,11 +61,4 @@ if a2enmod -q auth_ldap; then a2enmod mod_authnz_ldap fi -for module in mod_authn_default mod_authz_default mod_mem_cache; do - if a2enmod -q "$module"; then - echo "!!ATTENTION! $module was removed from apache version 2.4 or later, CHECK YOUR CONFIGURATION!!!" - a2dismod "$module" - fi -done - echo 'Done.' diff --git a/apache2-default-server.conf b/apache2-default-server.conf index eb12cad..fc45e52 100644 --- a/apache2-default-server.conf +++ b/apache2-default-server.conf @@ -102,5 +102,5 @@ ScriptAlias /cgi-bin/ "/srv/www/cgi-bin/" Include /etc/apache2/conf.d/*.conf # The manual... if it is installed ('?' means it won't complain) -IncludeOptional /etc/apache2/conf.d/apache2-manual?conf +Include /etc/apache2/conf.d/apache2-manual?conf diff --git a/apache2-httpd.conf b/apache2-httpd.conf index fe1f272..696da7a 100644 --- a/apache2-httpd.conf +++ b/apache2-httpd.conf @@ -202,7 +202,7 @@ Include /etc/apache2/sysconfig.d/include.conf # You may use the command line option '-S' to verify your virtual host # configuration. # -IncludeOptional /etc/apache2/vhosts.d/*.conf +Include /etc/apache2/vhosts.d/*.conf # Note: instead of adding your own configuration here, consider diff --git a/apache2-mod_ssl_npn.patch b/apache2-mod_ssl_npn.patch index 4162345..246cd74 100644 --- a/apache2-mod_ssl_npn.patch +++ b/apache2-mod_ssl_npn.patch @@ -1,658 +1,51 @@ -diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c -index fe7aeae..0ca336f 100644 ---- a/modules/ssl/mod_ssl.c -+++ b/modules/ssl/mod_ssl.c -@@ -94,6 +94,15 @@ static const command_rec ssl_config_cmds[] = { - SSL_CMD_SRV(PKCS7CertificateFile, TAKE1, - "PKCS#7 file containing server certificate and chain" - " certificates ('/path/to/file' - PEM encoded)") -+ SSL_CMD_ALL(RSAAuthzFile, TAKE1, -+ "RFC 5878 Authz Extension file for RSA certificate " -+ "(`/path/to/file')") -+ SSL_CMD_ALL(DSAAuthzFile, TAKE1, -+ "RFC 5878 Authz Extension file for DSA certificate " -+ "(`/path/to/file')") -+ SSL_CMD_ALL(ECAuthzFile, TAKE1, -+ "RFC 5878 Authz Extension file for EC certificate " -+ "(`/path/to/file')") - #ifdef HAVE_TLS_SESSION_TICKETS - SSL_CMD_SRV(SessionTicketKeyFile, TAKE1, - "TLS session ticket encryption/decryption key file (RFC 5077) " -@@ -138,6 +147,9 @@ static const command_rec ssl_config_cmds[] = { - "('[+-][" SSL_PROTOCOLS "] ...' - see manual)") - SSL_CMD_SRV(HonorCipherOrder, FLAG, - "Use the server's cipher ordering preference") -+ SSL_CMD_SRV(Compression, FLAG, -+ "Enable SSL level compression" -+ "(`on', `off')") - SSL_CMD_SRV(InsecureRenegotiation, FLAG, - "Enable support for insecure renegotiation") - SSL_CMD_ALL(UserName, TAKE1, -@@ -145,6 +157,15 @@ static const command_rec ssl_config_cmds[] = { - SSL_CMD_SRV(StrictSNIVHostCheck, FLAG, - "Strict SNI virtual host checking") +# This patch adds hooks for Next Protocol Negotiation (NPN) into mod_ssl. This +# change is under review to be included in Apache trunk: +# https://issues.apache.org/bugzilla/show_bug.cgi?id=52210 +# But until it becomes part of an Apache 2.2 release, we need to apply the patch +# ourselves. +Index: modules/ssl/ssl_private.h +=================================================================== +--- modules/ssl/ssl_private.h (revision 1202283) ++++ modules/ssl/ssl_private.h (working copy) +@@ -603,6 +603,7 @@ + #ifndef OPENSSL_NO_TLSEXT + int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *); + #endif ++int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data, unsigned int *len, void *arg); -+#ifndef OPENSSL_NO_SRP -+ SSL_CMD_SRV(SRPVerifierFile, TAKE1, -+ "SRP verifier file " -+ "('/path/to/file' - created by srptool)") -+ SSL_CMD_SRV(SRPUnknownUserSeed, TAKE1, -+ "SRP seed for unknown users (to avoid leaking a user's existence) " -+ "('some secret text')") -+#endif -+ - /* - * Proxy configuration for remote SSL connections - */ -@@ -260,6 +281,18 @@ static const command_rec ssl_config_cmds[] = { - AP_END_CMD - }; + /** Session Cache Support */ + void ssl_scache_init(server_rec *, apr_pool_t *); +@@ -714,4 +715,3 @@ -+/* Implement 'modssl_run_npn_advertise_protos_hook'. */ -+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL( -+ modssl, AP, int, npn_advertise_protos_hook, -+ (conn_rec *connection, apr_array_header_t *protos), -+ (connection, protos), OK, DECLINED); -+ -+/* Implement 'modssl_run_npn_proto_negotiated_hook'. */ -+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL( -+ modssl, AP, int, npn_proto_negotiated_hook, -+ (conn_rec *connection, const char *proto_name, apr_size_t proto_name_len), -+ (connection, proto_name, proto_name_len), OK, DECLINED); -+ - /* - * the various processing hooks - */ -diff --git a/modules/ssl/mod_ssl.h b/modules/ssl/mod_ssl.h -index 48984e2..0280a68 100644 ---- a/modules/ssl/mod_ssl.h -+++ b/modules/ssl/mod_ssl.h -@@ -63,5 +63,26 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *)); - - APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *)); - -+/** The npn_advertise_protos optional hook allows other modules to add entries -+ * to the list of protocol names advertised by the server during the Next -+ * Protocol Negotiation (NPN) portion of the SSL handshake. The hook callee is -+ * given the connection and an APR array; it should push one or more char*'s -+ * pointing to null-terminated strings (such as "http/1.1" or "spdy/2") onto -+ * the array and return OK, or do nothing and return DECLINED. */ -+APR_DECLARE_EXTERNAL_HOOK(modssl, AP, int, npn_advertise_protos_hook, -+ (conn_rec *connection, apr_array_header_t *protos)); -+ -+/** The npn_proto_negotiated optional hook allows other modules to discover the -+ * name of the protocol that was chosen during the Next Protocol Negotiation -+ * (NPN) portion of the SSL handshake. Note that this may be the empty string -+ * (in which case modules should probably assume HTTP), or it may be a protocol -+ * that was never even advertised by the server. The hook callee is given the -+ * connection, a non-null-terminated string containing the protocol name, and -+ * the length of the string; it should do something appropriate (i.e. insert or -+ * remove filters) and return OK, or do nothing and return DECLINED. */ -+APR_DECLARE_EXTERNAL_HOOK(modssl, AP, int, npn_proto_negotiated_hook, -+ (conn_rec *connection, const char *proto_name, -+ apr_size_t proto_name_len)); -+ - #endif /* __MOD_SSL_H__ */ + #endif /* SSL_PRIVATE_H */ /** @} */ -diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c -index 6aab764..39f20f9 100644 ---- a/modules/ssl/ssl_engine_config.c -+++ b/modules/ssl/ssl_engine_config.c -@@ -125,6 +125,10 @@ static void modssl_ctx_init(modssl_ctx_t *mctx) - mctx->crl_file = NULL; - mctx->crl_check_mode = SSL_CRLCHECK_UNSET; - -+ mctx->rsa_authz_file = NULL; -+ mctx->dsa_authz_file = NULL; -+ mctx->ec_authz_file = NULL; -+ - mctx->auth.ca_cert_path = NULL; - mctx->auth.ca_cert_file = NULL; - mctx->auth.cipher_suite = NULL; -@@ -149,6 +153,12 @@ static void modssl_ctx_init(modssl_ctx_t *mctx) - mctx->stapling_responder_timeout = UNSET; - mctx->stapling_force_url = NULL; - #endif -+ -+#ifndef OPENSSL_NO_SRP -+ mctx->srp_vfile = NULL; -+ mctx->srp_unknown_user_seed = NULL; -+ mctx->srp_vbase = NULL; -+#endif - } - - static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc, -@@ -207,6 +217,9 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p) - #ifdef HAVE_FIPS - sc->fips = UNSET; - #endif -+#ifndef OPENSSL_NO_COMP -+ sc->compression = UNSET; -+#endif - - modssl_ctx_init_proxy(sc, p); - -@@ -248,6 +261,10 @@ static void modssl_ctx_cfg_merge(modssl_ctx_t *base, - cfgMerge(crl_file, NULL); - cfgMerge(crl_check_mode, SSL_CRLCHECK_UNSET); - -+ cfgMergeString(rsa_authz_file); -+ cfgMergeString(dsa_authz_file); -+ cfgMergeString(ec_authz_file); -+ - cfgMergeString(auth.ca_cert_path); - cfgMergeString(auth.ca_cert_file); - cfgMergeString(auth.cipher_suite); -@@ -271,6 +288,11 @@ static void modssl_ctx_cfg_merge(modssl_ctx_t *base, - cfgMergeInt(stapling_responder_timeout); - cfgMerge(stapling_force_url, NULL); - #endif -+ -+#ifndef OPENSSL_NO_SRP -+ cfgMergeString(srp_vfile); -+ cfgMergeString(srp_unknown_user_seed); -+#endif - } - - static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base, -@@ -328,6 +350,9 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv) - #ifdef HAVE_FIPS - cfgMergeBool(fips); - #endif -+#ifndef OPENSSL_NO_COMP -+ cfgMergeBool(compression); -+#endif - - modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy); - -@@ -663,6 +688,23 @@ static const char *ssl_cmd_check_file(cmd_parms *parms, - - } - -+const char *ssl_cmd_SSLCompression(cmd_parms *cmd, void *dcfg, int flag) -+{ -+#if !defined(OPENSSL_NO_COMP) -+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server); -+#ifndef SSL_OP_NO_COMPRESSION -+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); -+ if (err) -+ return "This version of openssl does not support configuring " -+ "compression within sections."; -+#endif -+ sc->compression = flag ? TRUE : FALSE; -+ return NULL; -+#else -+ return "Setting Compression mode unsupported; not implemented by the SSL library"; -+#endif -+} -+ - const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag) - { - #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE -@@ -806,6 +848,54 @@ const char *ssl_cmd_SSLPKCS7CertificateFile(cmd_parms *cmd, - return NULL; - } - -+const char *ssl_cmd_SSLRSAAuthzFile(cmd_parms *cmd, -+ void *dcfg, -+ const char *arg) -+{ -+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server); -+ const char *err; -+ -+ if ((err = ssl_cmd_check_file(cmd, &arg))) { -+ return err; -+ } -+ -+ sc->server->rsa_authz_file = arg; -+ -+ return NULL; -+} -+ -+const char *ssl_cmd_SSLDSAAuthzFile(cmd_parms *cmd, -+ void *dcfg, -+ const char *arg) -+{ -+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server); -+ const char *err; -+ -+ if ((err = ssl_cmd_check_file(cmd, &arg))) { -+ return err; -+ } -+ -+ sc->server->dsa_authz_file = arg; -+ -+ return NULL; -+} -+ -+const char *ssl_cmd_SSLECAuthzFile(cmd_parms *cmd, -+ void *dcfg, -+ const char *arg) -+{ -+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server); -+ const char *err; -+ -+ if ((err = ssl_cmd_check_file(cmd, &arg))) { -+ return err; -+ } -+ -+ sc->server->ec_authz_file = arg; -+ -+ return NULL; -+} -+ - #ifdef HAVE_TLS_SESSION_TICKETS - const char *ssl_cmd_SSLSessionTicketKeyFile(cmd_parms *cmd, - void *dcfg, -@@ -1759,6 +1849,32 @@ const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *cmd, void *dcfg, - - #endif /* HAVE_OCSP_STAPLING */ - -+#ifndef OPENSSL_NO_SRP -+ -+const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg, -+ const char *arg) -+{ -+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server); -+ const char *err; -+ -+ if ((err = ssl_cmd_check_file(cmd, &arg))) -+ return err; -+ /* SRP_VBASE_init takes char*, not const char* */ -+ sc->server->srp_vfile = apr_pstrdup(cmd->pool, arg); -+ return NULL; -+} -+ -+const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg, -+ const char *arg) -+{ -+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server); -+ /* SRP_VBASE_new takes char*, not const char* */ -+ sc->server->srp_unknown_user_seed = apr_pstrdup(cmd->pool, arg); -+ return NULL; -+} -+ -+#endif /* OPENSSL_NO_SRP */ -+ - void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s) - { - apr_file_t *out = NULL; -diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c -index 5d81647..8cdc29a 100644 ---- a/modules/ssl/ssl_engine_init.c -+++ b/modules/ssl/ssl_engine_init.c -@@ -349,7 +349,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, - else { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01885) "FIPS mode failed"); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - } - } -@@ -438,7 +438,7 @@ void ssl_init_Engine(server_rec *s, apr_pool_t *p) - "Init: Failed to load Crypto Device API `%s'", - mc->szCryptoDevice); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - - if (strEQ(mc->szCryptoDevice, "chil")) { -@@ -450,7 +450,7 @@ void ssl_init_Engine(server_rec *s, apr_pool_t *p) - "Init: Failed to enable Crypto Device API `%s'", - mc->szCryptoDevice); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01890) - "Init: loaded Crypto Device API `%s'", -@@ -473,7 +473,7 @@ static void ssl_init_server_check(server_rec *s, - if (!mctx->pks->cert_files[0] && !mctx->pkcs7) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01891) - "No SSL Certificate set [hint: SSLCertificateFile]"); -- ssl_die(); -+ ssl_die(s); - } - - /* -@@ -489,7 +489,7 @@ static void ssl_init_server_check(server_rec *s, - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01892) - "Illegal attempt to re-initialise SSL for server " - "(SSLEngine On should go in the VirtualHost, not in global scope.)"); -- ssl_die(); -+ ssl_die(s); - } - } - -@@ -515,7 +515,7 @@ static void ssl_init_ctx_tls_extensions(server_rec *s, - "Unable to initialize TLS servername extension " - "callback (incompatible OpenSSL version?)"); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - - #ifdef HAVE_OCSP_STAPLING -@@ -526,6 +526,38 @@ static void ssl_init_ctx_tls_extensions(server_rec *s, - modssl_init_stapling(s, p, ptemp, mctx); - } - #endif -+ -+#ifndef OPENSSL_NO_SRP -+ /* -+ * TLS-SRP support -+ */ -+ if (mctx->srp_vfile != NULL) { -+ int err; -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02308) -+ "Using SRP verifier file [%s]", mctx->srp_vfile); -+ -+ if (!(mctx->srp_vbase = SRP_VBASE_new(mctx->srp_unknown_user_seed))) { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02309) -+ "Unable to initialize SRP verifier structure " -+ "[%s seed]", -+ mctx->srp_unknown_user_seed ? "with" : "without"); -+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -+ ssl_die(s); -+ } -+ -+ err = SRP_VBASE_init(mctx->srp_vbase, mctx->srp_vfile); -+ if (err != SRP_NO_ERROR) { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02310) -+ "Unable to load SRP verifier file [error %d]", err); -+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -+ ssl_die(s); -+ } -+ -+ SSL_CTX_set_srp_username_callback(mctx->ssl_ctx, -+ ssl_callback_SRPServerParams); -+ SSL_CTX_set_srp_cb_arg(mctx->ssl_ctx, mctx); -+ } -+#endif - } - #endif - -@@ -546,7 +578,7 @@ static void ssl_init_ctx_protocol(server_rec *s, - if (protocol == SSL_PROTOCOL_NONE) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231) - "No SSL protocols available [hint: SSLProtocol]"); -- ssl_die(); -+ ssl_die(s); - } - - cp = apr_pstrcat(p, -@@ -622,6 +654,18 @@ static void ssl_init_ctx_protocol(server_rec *s, - } - #endif - -+ -+#ifndef OPENSSL_NO_COMP -+ if (sc->compression == FALSE) { -+#ifdef SSL_OP_NO_COMPRESSION -+ /* OpenSSL >= 1.0 only */ -+ SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION); -+#elif OPENSSL_VERSION_NUMBER >= 0x00908000L -+ sk_SSL_COMP_zero(SSL_COMP_get_compression_methods()); -+#endif -+ } -+#endif -+ - #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION - if (sc->insecure_reneg == TRUE) { - SSL_CTX_set_options(ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION); -@@ -681,6 +725,11 @@ static void ssl_init_ctx_callbacks(server_rec *s, - #endif +- +Index: modules/ssl/ssl_engine_init.c +=================================================================== +--- modules/ssl/ssl_engine_init.c (revision 1202283) ++++ modules/ssl/ssl_engine_init.c (working copy) +@@ -559,6 +559,11 @@ + SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); SSL_CTX_set_info_callback(ctx, ssl_callback_Info); + -+#ifdef HAVE_TLS_NPN ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + SSL_CTX_set_next_protos_advertised_cb( + ctx, ssl_callback_AdvertiseNextProtos, NULL); +#endif } static void ssl_init_ctx_verify(server_rec *s, -@@ -731,7 +780,7 @@ static void ssl_init_ctx_verify(server_rec *s, - "Unable to configure verify locations " - "for client authentication"); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } +@@ -1352,4 +1357,3 @@ - if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) { -@@ -746,7 +795,7 @@ static void ssl_init_ctx_verify(server_rec *s, - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01896) - "Unable to determine list of acceptable " - "CA certificates for client authentication"); -- ssl_die(); -+ ssl_die(s); - } - - SSL_CTX_set_client_CA_list(ctx, ca_list); -@@ -791,7 +840,7 @@ static void ssl_init_ctx_cipher_suite(server_rec *s, - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01898) - "Unable to configure permitted SSL ciphers"); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } + return APR_SUCCESS; } - -@@ -815,7 +864,7 @@ static void ssl_init_ctx_crl(server_rec *s, - "Host %s: CRL checking has been enabled, but " - "neither %sCARevocationFile nor %sCARevocationPath " - "is configured", mctx->sc->vhost_id, cfgp, cfgp); -- ssl_die(); -+ ssl_die(s); - } - return; - } -@@ -829,7 +878,7 @@ static void ssl_init_ctx_crl(server_rec *s, - "Host %s: unable to configure X.509 CRL storage " - "for certificate revocation", mctx->sc->vhost_id); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - - switch (mctx->crl_check_mode) { -@@ -915,7 +964,7 @@ static void ssl_init_ctx_cert_chain(server_rec *s, - if (n < 0) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01903) - "Failed to configure CA certificate chain!"); -- ssl_die(); -+ ssl_die(s); - } - - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01904) -@@ -953,7 +1002,8 @@ static void ssl_init_ctx(server_rec *s, - static int ssl_server_import_cert(server_rec *s, - modssl_ctx_t *mctx, - const char *id, -- int idx) -+ int idx, -+ const char *authz_file) - { - SSLModConfigRec *mc = myModConfig(s); - ssl_asn1_t *asn1; -@@ -973,14 +1023,14 @@ static int ssl_server_import_cert(server_rec *s, - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02233) - "Unable to import %s server certificate", type); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - - if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) <= 0) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02234) - "Unable to configure %s server certificate", type); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - - #ifdef HAVE_OCSP_STAPLING -@@ -992,6 +1042,24 @@ static int ssl_server_import_cert(server_rec *s, - } - #endif - -+ if (authz_file) { -+#if !defined(OPENSSL_NO_TLSEXT) && OPENSSL_VERSION_NUMBER >= 0x10002000L -+ if (!SSL_CTX_use_authz_file(mctx->ssl_ctx, authz_file)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, -+ "Unable to initialize TLS authz extension"); -+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); -+ ssl_die(s); -+ } -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "Set %s authz_file to %s", -+ type, authz_file); -+#else -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, -+ "Unable to initialize TLS authz extension: " -+ "OpenSSL version too low"); -+ ssl_die(s); -+#endif -+ } -+ - mctx->pks->certs[idx] = cert; - - return TRUE; -@@ -1029,14 +1097,14 @@ static int ssl_server_import_key(server_rec *s, - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02237) - "Unable to import %s server private key", type); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - - if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02238) - "Unable to configure %s server private key", type); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - - /* -@@ -1174,10 +1242,13 @@ static void ssl_init_server_certs(server_rec *s, - ecc_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_ECC); - #endif - -- have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA); -- have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA); -+ have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA, -+ mctx->rsa_authz_file); -+ have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA, -+ mctx->dsa_authz_file); - #ifndef OPENSSL_NO_EC -- have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC); -+ have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC, -+ mctx->ec_authz_file); - #endif - - if (!(have_rsa || have_dsa -@@ -1188,7 +1259,7 @@ static void ssl_init_server_certs(server_rec *s, - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01910) - "Oops, no " KEYTYPES " server certificate found " - "for '%s:%d'?!", s->server_hostname, s->port); -- ssl_die(); -+ ssl_die(s); - } - - for (i = 0; i < SSL_AIDX_MAX; i++) { -@@ -1208,7 +1279,7 @@ static void ssl_init_server_certs(server_rec *s, - )) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01911) - "Oops, no " KEYTYPES " server private key found?!"); -- ssl_die(); -+ ssl_die(s); - } - } - -@@ -1238,7 +1309,7 @@ static void ssl_init_ticket_key(server_rec *s, - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02286) - "Failed to open ticket key file %s: (%d) %pm", - path, rv, &rv); -- ssl_die(); -+ ssl_die(s); - } - - rv = apr_file_read_full(fp, &buf[0], TLSEXT_TICKET_KEY_LEN, &len); -@@ -1247,7 +1318,7 @@ static void ssl_init_ticket_key(server_rec *s, - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02287) - "Failed to read %d bytes from %s: (%d) %pm", - TLSEXT_TICKET_KEY_LEN, path, rv, &rv); -- ssl_die(); -+ ssl_die(s); - } - - memcpy(ticket_key->key_name, buf, 16); -@@ -1260,7 +1331,7 @@ static void ssl_init_ticket_key(server_rec *s, - "Unable to initialize TLS session ticket key callback " - "(incompatible OpenSSL version?)"); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - - ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02288) -@@ -1315,7 +1386,7 @@ static void ssl_init_proxy_certs(server_rec *s, - ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252) - "incomplete client cert configured for SSL proxy " - "(missing or encrypted private key?)"); -- ssl_die(); -+ ssl_die(s); - return; - } - } -@@ -1338,7 +1409,7 @@ static void ssl_init_proxy_certs(server_rec *s, - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02208) - "SSL proxy client cert initialization failed"); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - - X509_STORE_load_locations(store, pkp->ca_cert_file, NULL); -@@ -1628,7 +1699,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02211) - "Failed to open Certificate Path `%s'", - ca_path); -- ssl_die(); -+ ssl_die(s); - } - - while ((apr_dir_read(&direntry, finfo_flags, dir)) == APR_SUCCESS) { -@@ -1675,6 +1746,13 @@ void ssl_init_Child(apr_pool_t *p, server_rec *s) - static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx) - { - MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx); -+ -+#ifndef OPENSSL_NO_SRP -+ if (mctx->srp_vbase != NULL) { -+ SRP_VBASE_free(mctx->srp_vbase); -+ mctx->srp_vbase = NULL; -+ } -+#endif - } - - static void ssl_init_ctx_cleanup_proxy(modssl_ctx_t *mctx) -diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c -index 2ffe21f..12c9c7f 100644 ---- a/modules/ssl/ssl_engine_io.c -+++ b/modules/ssl/ssl_engine_io.c -@@ -28,6 +28,7 @@ - core keeps dumping.'' - -- Unknown */ - #include "ssl_private.h" -+#include "mod_ssl.h" - #include "apr_date.h" - - /* _________________________________________________________________ -@@ -297,6 +298,7 @@ typedef struct { +- +Index: modules/ssl/ssl_engine_io.c +=================================================================== +--- modules/ssl/ssl_engine_io.c (revision 1202283) ++++ modules/ssl/ssl_engine_io.c (working copy) +@@ -338,6 +338,7 @@ apr_pool_t *pool; char buffer[AP_IOBUFSIZE]; ssl_filter_ctx_t *filter_ctx; @@ -660,212 +53,44 @@ index 2ffe21f..12c9c7f 100644 } bio_filter_in_ctx_t; /* -@@ -813,12 +815,12 @@ static apr_status_t ssl_filter_write(ap_filter_t *f, - /* Just use a simple request. Any request will work for this, because - * we use a flag in the conn_rec->conn_vector now. The fake request just - * gets the request back to the Apache core so that a response can be sent. -- * -- * To avoid calling back for more data from the socket, use an HTTP/0.9 -- * request, and tack on an EOS bucket. -+ * Since we use an HTTP/1.x request, we also have to inject the empty line -+ * that terminates the headers, or the core will read more data from the -+ * socket. - */ - #define HTTP_ON_HTTPS_PORT \ -- "GET /" CRLF -+ "GET / HTTP/1.0" CRLF - - #define HTTP_ON_HTTPS_PORT_BUCKET(alloc) \ - apr_bucket_immortal_create(HTTP_ON_HTTPS_PORT, \ -@@ -848,6 +850,7 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f, - { - SSLConnRec *sslconn = myConnConfig(f->c); - apr_bucket *bucket; -+ int send_eos = 1; - - switch (status) { - case MODSSL_ERROR_HTTP_ON_HTTPS: -@@ -857,11 +860,12 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f, - "trying to send HTML error page"); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, sslconn->server); - -- sslconn->non_ssl_request = 1; -+ sslconn->non_ssl_request = NON_SSL_SEND_HDR_SEP; - ssl_io_filter_disable(sslconn, f); - - /* fake the request line */ - bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc); -+ send_eos = 0; - break; - - case MODSSL_ERROR_BAD_GATEWAY: -@@ -877,9 +881,10 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f, - } - - APR_BRIGADE_INSERT_TAIL(bb, bucket); -- bucket = apr_bucket_eos_create(f->c->bucket_alloc); -- APR_BRIGADE_INSERT_TAIL(bb, bucket); -- -+ if (send_eos) { -+ bucket = apr_bucket_eos_create(f->c->bucket_alloc); -+ APR_BRIGADE_INSERT_TAIL(bb, bucket); -+ } - return APR_SUCCESS; - } - -@@ -1282,6 +1287,13 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f, - } - - if (!inctx->ssl) { -+ SSLConnRec *sslconn = myConnConfig(f->c); -+ if (sslconn->non_ssl_request == NON_SSL_SEND_HDR_SEP) { -+ apr_bucket *bucket = apr_bucket_immortal_create(CRLF, 2, f->c->bucket_alloc); -+ APR_BRIGADE_INSERT_TAIL(bb, bucket); -+ sslconn->non_ssl_request = NON_SSL_SET_ERROR_MSG; -+ return APR_SUCCESS; -+ } - return ap_get_brigade(f->next, bb, mode, block, readbytes); - } - -@@ -1364,6 +1376,26 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f, +@@ -1409,6 +1410,21 @@ APR_BRIGADE_INSERT_TAIL(bb, bucket); } -+#ifdef HAVE_TLS_NPN + /* By this point, Next Protocol Negotiation (NPN) should be completed (if + * our version of OpenSSL supports it). If we haven't already, find out + * which protocol was decided upon and inform other modules by calling + * npn_proto_negotiated_hook. */ + if (!inctx->npn_finished) { ++ inctx->npn_finished = 1; ++#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + const unsigned char *next_proto = NULL; + unsigned next_proto_len = 0; -+ -+ SSL_get0_next_proto_negotiated( -+ inctx->ssl, &next_proto, &next_proto_len); -+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, f->c, -+ APLOGNO(02306) "SSL NPN negotiated protocol: '%*s'", -+ next_proto_len, (const char*)next_proto); -+ modssl_run_npn_proto_negotiated_hook( -+ f->c, (const char*)next_proto, next_proto_len); -+ inctx->npn_finished = 1; -+ } ++ SSL_get0_next_proto_negotiated(inctx->ssl, &next_proto, ++ &next_proto_len); ++ ssl_run_npn_proto_negotiated_hook(f->c, next_proto, next_proto_len); +#endif ++ } + return APR_SUCCESS; } -@@ -1845,6 +1877,7 @@ static void ssl_io_input_add_filter(ssl_filter_ctx_t *filter_ctx, conn_rec *c, +@@ -1753,6 +1769,7 @@ inctx->block = APR_BLOCK_READ; inctx->pool = c->pool; inctx->filter_ctx = filter_ctx; + inctx->npn_finished = 0; } - /* The request_rec pointer is passed in here only to ensure that the -diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c -index 35b2a85..1b69d4c 100644 ---- a/modules/ssl/ssl_engine_kernel.c -+++ b/modules/ssl/ssl_engine_kernel.c -@@ -29,6 +29,7 @@ - time I was too famous.'' - -- Unknown */ - #include "ssl_private.h" -+#include "mod_ssl.h" - #include "util_md5.h" - - static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn); -@@ -140,37 +141,16 @@ int ssl_hook_ReadReq(request_rec *r) - return DECLINED; + void ssl_io_filter_init(conn_rec *c, SSL *ssl) +Index: modules/ssl/ssl_engine_kernel.c +=================================================================== +--- modules/ssl/ssl_engine_kernel.c (revision 1202283) ++++ modules/ssl/ssl_engine_kernel.c (working copy) +@@ -1969,6 +1969,77 @@ } - -- if (sslconn->non_ssl_request) { -- const char *errmsg; -- char *thisurl; -- char *thisport = ""; -- int port = ap_get_server_port(r); -- -- if (!ap_is_default_port(port, r)) { -- thisport = apr_psprintf(r->pool, ":%u", port); -- } -- -- thisurl = ap_escape_html(r->pool, -- apr_psprintf(r->pool, "https://%s%s/", -- ap_get_server_name_for_url(r), -- thisport)); -- -- errmsg = apr_psprintf(r->pool, -- "Reason: You're speaking plain HTTP " -- "to an SSL-enabled server port.
\n" -- "Instead use the HTTPS scheme to access " -- "this URL, please.
\n" -- "
Hint: " -- "%s
", -- thisurl, thisurl); -- -- apr_table_setn(r->notes, "error-notes", errmsg); -+ if (sslconn->non_ssl_request == NON_SSL_SET_ERROR_MSG) { -+ apr_table_setn(r->notes, "error-notes", -+ "Reason: You're speaking plain HTTP to an SSL-enabled " -+ "server port.
\n Instead use the HTTPS scheme to " -+ "access this URL, please.
\n"); - - /* Now that we have caught this error, forget it. we are done - * with using SSL on this request. - */ -- sslconn->non_ssl_request = 0; -- -+ sslconn->non_ssl_request = NON_SSL_OK; - - return HTTP_BAD_REQUEST; - } -@@ -350,6 +330,19 @@ int ssl_hook_Access(request_rec *r) - return DECLINED; - } - -+#ifndef OPENSSL_NO_SRP -+ /* -+ * Support for per-directory reconfigured SSL connection parameters -+ * -+ * We do not force any renegotiation if the user is already authenticated -+ * via SRP. -+ * -+ */ -+ if (SSL_get_srp_username(ssl)) { -+ return DECLINED; -+ } -+#endif -+ - /* - * Support for per-directory reconfigured SSL connection parameters. - * -@@ -1109,6 +1102,10 @@ static const char *ssl_hook_Fixup_vars[] = { - "SSL_SERVER_A_SIG", - "SSL_SESSION_ID", - "SSL_SESSION_RESUMED", -+#ifndef OPENSSL_NO_SRP -+ "SSL_SRP_USER", -+ "SSL_SRP_USERINFO", -+#endif - NULL - }; - -@@ -2093,7 +2090,7 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s) - - return 0; } --#endif -+#endif /* OPENSSL_NO_TLSEXT */ - #ifdef HAVE_TLS_SESSION_TICKETS - /* -@@ -2163,4 +2160,114 @@ int ssl_callback_SessionTicket(SSL *ssl, - /* OpenSSL is not expected to call us with modes other than 1 or 0 */ - return -1; - } --#endif -+#endif /* HAVE_TLS_SESSION_TICKETS */ -+ -+#ifdef HAVE_TLS_NPN +/* + * This callback function is executed when SSL needs to decide what protocols + * to advertise during Next Protocol Negotiation (NPN). It must produce a @@ -876,65 +101,55 @@ index 35b2a85..1b69d4c 100644 +int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data_out, + unsigned int *size_out, void *arg) +{ -+ conn_rec *c = (conn_rec*)SSL_get_app_data(ssl); -+ apr_array_header_t *protos; -+ int num_protos; -+ unsigned int size; -+ int i; -+ unsigned char *data; -+ unsigned char *start; -+ + *data_out = NULL; + *size_out = 0; + -+ /* If the connection object is not available, then there's nothing for us -+ * to do. */ ++ /* Get the connection object. If it's not available, then there's nothing ++ * for us to do. */ ++ conn_rec *c = (conn_rec*)SSL_get_app_data(ssl); + if (c == NULL) { + return SSL_TLSEXT_ERR_OK; + } + + /* Invoke our npn_advertise_protos hook, giving other modules a chance to + * add alternate protocol names to advertise. */ -+ protos = apr_array_make(c->pool, 0, sizeof(char*)); -+ modssl_run_npn_advertise_protos_hook(c, protos); -+ num_protos = protos->nelts; ++ apr_array_header_t *protos = apr_array_make(c->pool, 0, sizeof(char*)); ++ ssl_run_npn_advertise_protos_hook(c, protos); ++ int num_protos = protos->nelts; ++ ++ /* If no other modules added any alternate protocols, then we're done. */ ++ if (num_protos == 0) { ++ return SSL_TLSEXT_ERR_OK; ++ } + + /* We now have a list of null-terminated strings; we need to concatenate + * them together into a single string, where each protocol name is prefixed + * by its length. First, calculate how long that string will be. */ -+ size = 0; ++ unsigned int size = 0; ++ int i; + for (i = 0; i < num_protos; ++i) { -+ const char *string = APR_ARRAY_IDX(protos, i, const char*); ++ const char* string = APR_ARRAY_IDX(protos, i, const char*); + unsigned int length = strlen(string); + /* If the protocol name is too long (the length must fit in one byte), -+ * then log an error and skip it. */ ++ * then log an error and quit. */ + if (length > 255) { -+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02307) ++ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, + "SSL NPN protocol name too long (length=%u): %s", + length, string); -+ continue; ++ return SSL_TLSEXT_ERR_OK; + } + /* Leave room for the length prefix (one byte) plus the protocol name + * itself. */ + size += 1 + length; + } + -+ /* If there is nothing to advertise (either because no modules added -+ * anything to the protos array, or because all strings added to the array -+ * were skipped), then we're done. */ -+ if (size == 0) { -+ return SSL_TLSEXT_ERR_OK; -+ } -+ + /* Now we can build the string. Copy each protocol name string into the + * larger string, prefixed by its length. */ -+ data = apr_palloc(c->pool, size * sizeof(unsigned char)); -+ start = data; ++ unsigned char* data = apr_palloc(c->pool, size * sizeof(unsigned char)); ++ unsigned char* start = data; + for (i = 0; i < num_protos; ++i) { -+ const char *string = APR_ARRAY_IDX(protos, i, const char*); -+ apr_size_t length = strlen(string); -+ if (length > 255) -+ continue; ++ const char* string = APR_ARRAY_IDX(protos, i, const char*); ++ size_t length = strlen(string); + *start = (unsigned char)length; + ++start; + memcpy(start, string, length * sizeof(unsigned char)); @@ -947,427 +162,60 @@ index 35b2a85..1b69d4c 100644 + return SSL_TLSEXT_ERR_OK; +} + -+#endif /* HAVE_TLS_NPN */ -+ -+#ifndef OPENSSL_NO_SRP -+ -+int ssl_callback_SRPServerParams(SSL *ssl, int *ad, void *arg) -+{ -+ modssl_ctx_t *mctx = (modssl_ctx_t *)arg; -+ char *username = SSL_get_srp_username(ssl); -+ SRP_user_pwd *u; -+ -+ if (username == NULL -+ || (u = SRP_VBASE_get_by_user(mctx->srp_vbase, username)) == NULL) { -+ *ad = SSL_AD_UNKNOWN_PSK_IDENTITY; -+ return SSL3_AL_FATAL; -+ } -+ -+ if (SSL_set_srp_server_param(ssl, u->N, u->g, u->s, u->v, u->info) < 0) { -+ *ad = SSL_AD_INTERNAL_ERROR; -+ return SSL3_AL_FATAL; -+ } -+ -+ /* reset all other options */ -+ SSL_set_verify(ssl, SSL_VERIFY_NONE, ssl_callback_SSLVerify); -+ return SSL_ERROR_NONE; -+} -+ -+#endif /* OPENSSL_NO_SRP */ -diff --git a/modules/ssl/ssl_engine_log.c b/modules/ssl/ssl_engine_log.c -index 31861ca..3f6d6ed 100644 ---- a/modules/ssl/ssl_engine_log.c -+++ b/modules/ssl/ssl_engine_log.c -@@ -63,12 +63,23 @@ static const char *ssl_log_annotation(const char *error) - return ssl_log_annotate[i].cpAnnotation; - } - --void ssl_die(void) -+void ssl_die(server_rec *s) - { -+ if (s != NULL && s->is_virtual && s->error_fname != NULL) -+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL, APLOGNO(02311) -+ "Fatal error initialising mod_ssl, exiting. " -+ "See %s for more information", -+ ap_server_root_relative(s->process->pool, -+ s->error_fname)); -+ else -+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, NULL, APLOGNO(02312) -+ "Fatal error initialising mod_ssl, exiting."); -+ - /* - * This is used for fatal errors and here - * it is common module practice to really - * exit from the complete program. -+ * XXX: The config hooks should return errors instead of calling exit(). - */ - exit(1); - } -diff --git a/modules/ssl/ssl_engine_pphrase.c b/modules/ssl/ssl_engine_pphrase.c -index 1fa4a2e..23ccaf4 100644 ---- a/modules/ssl/ssl_engine_pphrase.c -+++ b/modules/ssl/ssl_engine_pphrase.c -@@ -196,7 +196,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p) - "Server should be SSL-aware but has no certificate " - "configured [Hint: SSLCertificateFile] (%s:%d)", - pServ->defn_name, pServ->defn_line_number); -- ssl_die(); -+ ssl_die(pServ); - } - - /* Bitmasks for all key algorithms configured for this server; -@@ -225,14 +225,14 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p) - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02201) - "Init: Can't open server certificate file %s", - szPath); -- ssl_die(); -+ ssl_die(s); - } - if ((pX509Cert = SSL_read_X509(szPath, NULL, NULL)) == NULL) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02241) - "Init: Unable to read server certificate from" - " file %s", szPath); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02202) - "Init: Read server certificate from '%s'", -@@ -249,7 +249,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p) - "Init: Multiple %s server certificates not " - "allowed", an); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - algoCert |= at; - -@@ -328,7 +328,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p) - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02243) - "Init: Can't open server private key file " - "%s",szPath); -- ssl_die(); -+ ssl_die(s); - } - - /* -@@ -425,7 +425,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p) - "Init: SSLPassPhraseDialog builtin is not " - "supported on Win32 (key file " - "%s)", szPath); -- ssl_die(); -+ ssl_die(s); - } - #endif /* WIN32 */ - -@@ -464,7 +464,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p) - apr_file_printf(writetty, "**Stopped\n"); - } - } -- ssl_die(); -+ ssl_die(pServ); - } - - /* If a cached private key was found, nothing more to do -@@ -479,7 +479,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p) - "file %s [Hint: Perhaps it is in a separate file? " - " See SSLCertificateKeyFile]", szPath); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - - /* -@@ -493,7 +493,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p) - "Init: Multiple %s server private keys not " - "allowed", an); - ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -- ssl_die(); -+ ssl_die(s); - } - algoKey |= at; - -diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c -index febc176..8af1c26 100644 ---- a/modules/ssl/ssl_engine_vars.c -+++ b/modules/ssl/ssl_engine_vars.c -@@ -395,6 +395,18 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, request_rec *r, - #endif - result = apr_pstrdup(p, flag ? "true" : "false"); - } -+#ifndef OPENSSL_NO_SRP -+ else if (ssl != NULL && strcEQ(var, "SRP_USER")) { -+ if ((result = SSL_get_srp_username(ssl)) != NULL) { -+ result = apr_pstrdup(p, result); -+ } -+ } -+ else if (ssl != NULL && strcEQ(var, "SRP_USERINFO")) { -+ if ((result = SSL_get_srp_userinfo(ssl)) != NULL) { -+ result = apr_pstrdup(p, result); -+ } -+ } -+#endif - - return result; - } -diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h -index 1b5d042..63e401d 100644 ---- a/modules/ssl/ssl_private.h -+++ b/modules/ssl/ssl_private.h -@@ -139,6 +139,11 @@ - #define HAVE_FIPS - #endif - -+#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_NEXTPROTONEG) \ -+ && !defined(OPENSSL_NO_TLSEXT) -+#define HAVE_TLS_NPN -+#endif -+ - #if (OPENSSL_VERSION_NUMBER >= 0x10000000) - #define MODSSL_SSL_CIPHER_CONST const - #define MODSSL_SSL_METHOD_CONST const -@@ -180,6 +185,20 @@ - #define HAVE_TLSV1_X - #endif - -+#if !defined(OPENSSL_NO_COMP) && !defined(SSL_OP_NO_COMPRESSION) \ -+ && OPENSSL_VERSION_NUMBER < 0x00908000L -+#define OPENSSL_NO_COMP -+#endif -+ -+/* SRP support came in OpenSSL 1.0.1 */ -+#ifndef OPENSSL_NO_SRP -+#ifdef SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB -+#include -+#else -+#define OPENSSL_NO_SRP -+#endif -+#endif -+ - /* mod_ssl headers */ - #include "ssl_util_ssl.h" - -@@ -454,7 +473,11 @@ typedef struct { - int verify_depth; - int is_proxy; - int disabled; -- int non_ssl_request; -+ enum { -+ NON_SSL_OK = 0, /* is SSL request, or error handling completed */ -+ NON_SSL_SEND_HDR_SEP, /* Need to send the header separator */ -+ NON_SSL_SET_ERROR_MSG /* Need to set the error message */ -+ } non_ssl_request; - - /* Track the handshake/renegotiation state for the connection so - * that all client-initiated renegotiations can be rejected, as a -@@ -638,6 +661,17 @@ typedef struct { - const char *stapling_force_url; - #endif - -+#ifndef OPENSSL_NO_SRP -+ char *srp_vfile; -+ char *srp_unknown_user_seed; -+ SRP_VBASE *srp_vbase; -+#endif -+ -+ /** RFC 5878 */ -+ const char *rsa_authz_file; -+ const char *dsa_authz_file; -+ const char *ec_authz_file; -+ - modssl_auth_ctx_t auth; - - BOOL ocsp_enabled; /* true if OCSP verification enabled */ -@@ -669,6 +703,9 @@ struct SSLSrvConfigRec { - #ifdef HAVE_FIPS - BOOL fips; - #endif -+#ifndef OPENSSL_NO_COMP -+ BOOL compression; -+#endif + #ifndef OPENSSL_NO_TLSEXT + /* + * This callback function is executed when OpenSSL encounters an extended +Index: modules/ssl/mod_ssl.c +=================================================================== +--- modules/ssl/mod_ssl.c (revision 1202283) ++++ modules/ssl/mod_ssl.c (working copy) +@@ -220,6 +220,18 @@ + AP_END_CMD }; - /** -@@ -711,6 +748,9 @@ const char *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *); - const char *ssl_cmd_SSLEngine(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *); -+const char *ssl_cmd_SSLRSAAuthzFile(cmd_parms *, void *, const char *); -+const char *ssl_cmd_SSLDSAAuthzFile(cmd_parms *, void *, const char *); -+const char *ssl_cmd_SSLECAuthzFile(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLCertificateFile(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *, void *, const char *); -@@ -723,6 +763,7 @@ const char *ssl_cmd_SSLCARevocationPath(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLCARevocationFile(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag); -+const char *ssl_cmd_SSLCompression(cmd_parms *, void *, int flag); - const char *ssl_cmd_SSLVerifyClient(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLVerifyDepth(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLSessionCache(cmd_parms *, void *, const char *); -@@ -762,6 +803,11 @@ const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char - const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg); - const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag); - -+#ifndef OPENSSL_NO_SRP -+const char *ssl_cmd_SSLSRPVerifierFile(cmd_parms *cmd, void *dcfg, const char *arg); -+const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg, const char *arg); -+#endif ++/* Implement 'ssl_run_npn_advertise_protos_hook'. */ ++APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL( ++ ssl, AP, int, npn_advertise_protos_hook, ++ (conn_rec* connection, apr_array_header_t* protos), ++ (connection, protos), OK, DECLINED); + - const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag); - - /** module initialization */ -@@ -807,6 +853,7 @@ int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *); - int ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *, - EVP_CIPHER_CTX *, HMAC_CTX *, int); - #endif -+int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data, unsigned int *len, void *arg); - - /** Session Cache Support */ - void ssl_scache_init(server_rec *, apr_pool_t *); -@@ -838,6 +885,9 @@ void modssl_init_stapling(server_rec *, apr_pool_t *, apr_pool_t *, mods - void ssl_stapling_ex_init(void); - int ssl_stapling_init_cert(server_rec *s, modssl_ctx_t *mctx, X509 *x); - #endif -+#ifndef OPENSSL_NO_SRP -+int ssl_callback_SRPServerParams(SSL *, int *, void *); -+#endif - - /** I/O */ - void ssl_io_filter_init(conn_rec *, request_rec *r, SSL *); -@@ -902,7 +952,7 @@ int ssl_stapling_mutex_reinit(server_rec *, apr_pool_t *); - #define SSL_STAPLING_MUTEX_TYPE "ssl-stapling" - - /** Logfile Support */ --void ssl_die(void); -+void ssl_die(server_rec *); - void ssl_log_ssl_error(const char *, int, int, server_rec *); - - /* ssl_log_xerror, ssl_log_cxerror and ssl_log_rxerror are wrappers for the -diff --git a/modules/ssl/ssl_scache.c b/modules/ssl/ssl_scache.c -index 2c8d1bc..d32f8e1 100644 ---- a/modules/ssl/ssl_scache.c -+++ b/modules/ssl/ssl_scache.c -@@ -63,7 +63,7 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p) - if (rv) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01872) - "Could not initialize stapling cache. Exiting."); -- ssl_die(); -+ ssl_die(s); - } - } - #endif -@@ -88,7 +88,7 @@ void ssl_scache_init(server_rec *s, apr_pool_t *p) - if (rv) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01874) - "Could not initialize session cache. Exiting."); -- ssl_die(); -+ ssl_die(s); - } - } - -diff --git a/modules/ssl/ssl_util.c b/modules/ssl/ssl_util.c -index 6b5a7de..475fe4d 100644 ---- a/modules/ssl/ssl_util.c -+++ b/modules/ssl/ssl_util.c -@@ -76,8 +76,7 @@ apr_file_t *ssl_util_ppopen(server_rec *s, apr_pool_t *p, const char *cmd, - return NULL; - if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS) - return NULL; -- if ((proc = (apr_proc_t *)apr_pcalloc(p, sizeof(apr_proc_t))) == NULL) -- return NULL; -+ proc = apr_pcalloc(p, sizeof(apr_proc_t)); - if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS) - return NULL; - return proc->out; -@@ -287,7 +286,7 @@ STACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7) - f = fopen(pkcs7, "r"); - if (!f) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02212) "Can't open %s", pkcs7); -- ssl_die(); -+ ssl_die(s); - } - - p7 = PEM_read_PKCS7(f, NULL, NULL, NULL); -@@ -314,13 +313,13 @@ STACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7) - default: - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02213) - "Don't understand PKCS7 file %s", pkcs7); -- ssl_die(); -+ ssl_die(s); - } - - if (!certs) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02214) - "No certificates in %s", pkcs7); -- ssl_die(); -+ ssl_die(s); - } - - fclose(f); -@@ -376,24 +375,11 @@ static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file, - * allocated memory from a pool, create a subpool that we can blow - * away in the destruction callback. - */ -- rv = apr_pool_create(&p, dynlockpool); -- if (rv != APR_SUCCESS) { -- ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, dynlockpool, -- APLOGNO(02183) "Failed to create subpool for dynamic lock"); -- return NULL; -- } -- -+ apr_pool_create(&p, dynlockpool); - ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, p, - "Creating dynamic lock"); - -- value = (struct CRYPTO_dynlock_value *)apr_palloc(p, -- sizeof(struct CRYPTO_dynlock_value)); -- if (!value) { -- ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, 0, p, -- APLOGNO(02185) "Failed to allocate dynamic lock structure"); -- return NULL; -- } -- -+ value = apr_palloc(p, sizeof(struct CRYPTO_dynlock_value)); - value->pool = p; - /* Keep our own copy of the place from which we were created, - using our own pool. */ -diff --git a/modules/ssl/ssl_util_ocsp.c b/modules/ssl/ssl_util_ocsp.c -index 94ef4cd..e5c5e58 100644 ---- a/modules/ssl/ssl_util_ocsp.c -+++ b/modules/ssl/ssl_util_ocsp.c -@@ -153,7 +153,13 @@ static char *get_line(apr_bucket_brigade *bbout, apr_bucket_brigade *bbin, - return NULL; - } - -- if (len && line[len-1] != APR_ASCII_LF) { -+ if (len == 0) { -+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(02321) -+ "empty response from OCSP server"); -+ return NULL; -+ } ++/* Implement 'ssl_run_npn_proto_negotiated_hook'. */ ++APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL( ++ ssl, AP, int, npn_proto_negotiated_hook, ++ (conn_rec* connection, char* proto_name, apr_size_t proto_name_len), ++ (connection, proto_name, proto_name_len), OK, DECLINED); + -+ if (line[len-1] != APR_ASCII_LF) { - ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01979) - "response header line too long from OCSP server"); - return NULL; -diff --git a/modules/ssl/ssl_util_stapling.c b/modules/ssl/ssl_util_stapling.c -index 3ff08dc..89be7f5 100644 ---- a/modules/ssl/ssl_util_stapling.c -+++ b/modules/ssl/ssl_util_stapling.c -@@ -662,12 +662,12 @@ void modssl_init_stapling(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, - if (mc->stapling_cache == NULL) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01958) - "SSLStapling: no stapling cache available"); -- ssl_die(); -+ ssl_die(s); - } - if (ssl_stapling_mutex_init(s, ptemp) == FALSE) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01959) - "SSLStapling: cannot initialise stapling mutex"); -- ssl_die(); -+ ssl_die(s); - } - /* Set some default values for parameters if they are not set */ - if (mctx->stapling_resptime_skew == UNSET) { + /* + * the various processing hooks + */ +Index: modules/ssl/mod_ssl.h +=================================================================== +--- modules/ssl/mod_ssl.h (revision 1202283) ++++ modules/ssl/mod_ssl.h (working copy) +@@ -60,5 +60,26 @@ + + APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, ssl_extlist_by_oid, (request_rec *r, const char *oidstr)); + ++/** The npn_advertise_protos optional hook allows other modules to add entries ++ * to the list of protocol names advertised by the server during the Next ++ * Protocol Negotiation (NPN) portion of the SSL handshake. The hook callee is ++ * given the connection and an APR array; it should push one or more char*'s ++ * pointing to null-terminated strings (such as "http/1.1" or "spdy/2") onto ++ * the array and return OK, or do nothing and return DECLINED. */ ++APR_DECLARE_EXTERNAL_HOOK(ssl, AP, int, npn_advertise_protos_hook, ++ (conn_rec* connection, apr_array_header_t* protos)); ++ ++/** The npn_proto_negotiated optional hook allows other modules to discover the ++ * name of the protocol that was chosen during the Next Protocol Negotiation ++ * (NPN) portion of the SSL handshake. Note that this may be the empty string ++ * (in which case modules should probably assume HTTP), or it may be a protocol ++ * that was never even advertised by the server. The hook callee is given the ++ * connection, a non-null-terminated string containing the protocol name, and ++ * the length of the string; it should do something appropriate (i.e. insert or ++ * remove filters) and return OK, or do nothing and return DECLINED. */ ++APR_DECLARE_EXTERNAL_HOOK(ssl, AP, int, npn_proto_negotiated_hook, ++ (conn_rec* connection, char* proto_name, ++ apr_size_t proto_name_len)); ++ + #endif /* __MOD_SSL_H__ */ + /** @} */ diff --git a/apache2.4-mpm-itk-2.4.2-01.patch b/apache2.2-mpm-itk-20090414-00.patch similarity index 62% rename from apache2.4-mpm-itk-2.4.2-01.patch rename to apache2.2-mpm-itk-20090414-00.patch index ba21410..7948309 100644 --- a/apache2.4-mpm-itk-2.4.2-01.patch +++ b/apache2.2-mpm-itk-20090414-00.patch @@ -1,32 +1,21 @@ -Index: httpd-2.4.2/server/mpm/itk/Makefile.in -=================================================================== +unchanged: --- /dev/null -+++ httpd-2.4.2/server/mpm/itk/Makefile.in -@@ -0,0 +1 @@ -+include $(top_srcdir)/build/special.mk -Index: httpd-2.4.2/server/mpm/itk/config.m4 -=================================================================== ++++ server/mpm/experimental/itk/Makefile.in +@@ -0,0 +1,5 @@ ++ ++LTLIBRARY_NAME = libitk.la ++LTLIBRARY_SOURCES = itk.c ++ ++include $(top_srcdir)/build/ltlib.mk --- /dev/null -+++ httpd-2.4.2/server/mpm/itk/config.m4 -@@ -0,0 +1,7 @@ -+AC_MSG_CHECKING(if itk MPM supports this platform) -+if test $forking_mpms_supported != yes; then -+ AC_MSG_RESULT(no - This is not a forking platform) -+else -+ AC_MSG_RESULT(yes) -+ APACHE_MPM_SUPPORTED(itk, yes, no) ++++ server/mpm/experimental/itk/config.m4 +@@ -0,0 +1,3 @@ ++if test "$MPM_NAME" = "itk" ; then ++ APACHE_FAST_OUTPUT(server/mpm/$MPM_SUBDIR_NAME/Makefile) +fi -Index: httpd-2.4.2/server/mpm/itk/config3.m4 -=================================================================== --- /dev/null -+++ httpd-2.4.2/server/mpm/itk/config3.m4 -@@ -0,0 +1 @@ -+APACHE_MPM_MODULE(itk, $enable_mpm_itk) -Index: httpd-2.4.2/server/mpm/itk/itk.c -=================================================================== ---- /dev/null -+++ httpd-2.4.2/server/mpm/itk/itk.c -@@ -0,0 +1,1917 @@ ++++ server/mpm/experimental/itk/itk.c +@@ -0,0 +1,1740 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. @@ -42,7 +31,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + * See the License for the specific language governing permissions and + * limitations under the License. + * -+ * Portions copyright 2005-2012 Steinar H. Gunderson . ++ * Portions copyright 2005-2009 Steinar H. Gunderson . + * Licensed under the same terms as the rest of Apache. + * + * Portions copyright 2008 Knut Auvor Grythe . @@ -70,8 +59,8 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c +#if APR_HAVE_SYS_TYPES_H +#include +#endif -+#include -+#include ++ ++#define CORE_PRIVATE + +#include "ap_config.h" +#include "httpd.h" @@ -81,16 +70,18 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c +#include "http_config.h" +#include "http_core.h" /* for get_remote_host */ +#include "http_connection.h" ++#include "http_request.h" /* for ap_hook_post_perdir_config */ +#include "scoreboard.h" +#include "ap_mpm.h" -+#include "util_mutex.h" +#include "unixd.h" +#include "mpm_common.h" +#include "ap_listen.h" +#include "ap_mmn.h" +#include "apr_poll.h" -+#include "ap_expr.h" + ++#ifdef HAVE_BSTRING_H ++#include /* for IRIX, FD_SET calls bzero() */ ++#endif +#ifdef HAVE_TIME_H +#include +#endif @@ -105,9 +96,6 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c +#include +#include + -+/* Import our private hook. */ -+AP_DECLARE_HOOK(int,post_perdir_config,(request_rec *r)) -+ +/* Limit on the total --- clients will be locked out if more servers than + * this are needed. It is intended solely to keep the server from crashing + * when things get out of hand. @@ -136,46 +124,25 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + +/* config globals */ + ++int ap_threads_per_child=0; /* Worker threads per child */ +static apr_proc_mutex_t *accept_mutex; +static int ap_daemons_to_start=0; +static int ap_daemons_min_free=0; +static int ap_daemons_max_free=0; -+static int ap_daemons_limit=0; /* MaxRequestWorkers */ -+static int server_limit = 0; ++static int ap_daemons_limit=0; /* MaxClients */ ++static int server_limit = DEFAULT_SERVER_LIMIT; ++static int first_server_limit = 0; ++static int changed_limit_at_restart; +static int mpm_state = AP_MPMQ_STARTING; +static ap_pod_t *pod; + -+/* data retained by itk across load/unload of the module -+ * allocated on first call to pre-config hook; located on -+ * subsequent calls to pre-config hook ++/* ++ * The max child slot ever assigned, preserved across restarts. Necessary ++ * to deal with MaxClients changes across AP_SIG_GRACEFUL restarts. We ++ * use this value to optimize routines that have to scan the entire scoreboard. + */ -+typedef struct itk_retained_data { -+ int first_server_limit; -+ int module_loads; -+ ap_generation_t my_generation; -+ int volatile is_graceful; /* set from signal handler */ -+ int maxclients_reported; -+ /* -+ * The max child slot ever assigned, preserved across restarts. Necessary -+ * to deal with MaxRequestWorkers changes across AP_SIG_GRACEFUL restarts. We -+ * use this value to optimize routines that have to scan the entire scoreboard. -+ */ -+ int max_daemons_limit; -+ /* -+ * idle_spawn_rate is the number of children that will be spawned on the -+ * next maintenance cycle if there aren't enough idle servers. It is -+ * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by -+ * without the need to spawn. -+ */ -+ int idle_spawn_rate; -+#ifndef MAX_SPAWN_RATE -+#define MAX_SPAWN_RATE (32) -+#endif -+ int hold_off_on_exponential_spawning; -+} itk_retained_data; -+static itk_retained_data *retained; -+ -+#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) ++int ap_max_daemons_limit = -1; ++server_rec *ap_server_conf; + +/* one_process --- debugging mode variable; can be set from the command line + * with the -X flag. If set, this gets you the child_main loop running @@ -195,7 +162,17 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + +static pid_t ap_my_pid; /* it seems silly to call getpid all the time */ +static pid_t parent_pid; ++#ifndef MULTITHREAD +static int my_child_num; ++#endif ++ap_generation_t volatile ap_my_generation=0; ++ ++#ifdef TPF ++int tpf_child = 0; ++char tpf_server_name[INETD_SERVNAME_LENGTH+1]; ++#endif /* TPF */ ++ ++static volatile int die_now = 0; + +#define UNSET_NICE_VALUE 100 + @@ -205,8 +182,6 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + gid_t gid; + char *username; + int nice_value; -+ ap_expr_info_t *uid_expr; -+ ap_expr_info_t *gid_expr; +} itk_per_dir_conf; + +typedef struct @@ -215,7 +190,6 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c +} itk_server_conf; + +module AP_MODULE_DECLARE_DATA mpm_itk_module; -+extern AP_DECLARE_DATA int ap_running_under_mpm_itk; + +#ifdef GPROF +/* @@ -227,7 +201,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c +static void chdir_for_gprof(void) +{ + core_server_config *sconf = -+ ap_get_core_module_config(ap_server_conf->module_config); ++ ap_get_module_config(ap_server_conf->module_config, &core_module); + char *dir = sconf->gprof_dir; + const char *use_dir; + @@ -245,7 +219,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + APR_GREAD | APR_GEXECUTE | + APR_WREAD | APR_WEXECUTE, pconf); + if(res != APR_SUCCESS && !APR_STATUS_IS_EEXIST(res)) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, res, ap_server_conf, APLOGNO(00142) ++ ap_log_error(APLOG_MARK, APLOG_ERR, res, ap_server_conf, + "gprof: error creating directory %s", dir); + } + } @@ -259,24 +233,9 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c +#define chdir_for_gprof() +#endif + -+static void itk_note_child_killed(int childnum, pid_t pid, -+ ap_generation_t gen) -+{ -+ AP_DEBUG_ASSERT(childnum != -1); /* no scoreboard squatting with this MPM */ -+ ap_run_child_status(ap_server_conf, -+ ap_scoreboard_image->parent[childnum].pid, -+ ap_scoreboard_image->parent[childnum].generation, -+ childnum, MPM_CHILD_EXITED); -+ ap_scoreboard_image->parent[childnum].pid = 0; -+} -+ -+static void itk_note_child_started(int slot, pid_t pid) -+{ -+ ap_scoreboard_image->parent[slot].pid = pid; -+ ap_run_child_status(ap_server_conf, -+ ap_scoreboard_image->parent[slot].pid, -+ retained->my_generation, slot, MPM_CHILD_STARTED); -+} ++/* XXX - I don't know if TPF will ever use this module or not, so leave ++ * the ap_check_signals calls in but disable them - manoj */ ++#define ap_check_signals() + +/* a clean exit from a child with proper cleanup */ +static void clean_child_exit(int code) __attribute__ ((noreturn)); @@ -287,11 +246,6 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + if (pchild) { + apr_pool_destroy(pchild); + } -+ -+ if (one_process) { -+ itk_note_child_killed(/* slot */ 0, 0, 0); -+ } -+ + ap_mpm_pod_close(pod); + chdir_for_gprof(); + exit(code); @@ -303,13 +257,13 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + if (rv != APR_SUCCESS) { + const char *msg = "couldn't grab the accept mutex"; + -+ if (retained->my_generation != ++ if (ap_my_generation != + ap_scoreboard_image->global->running_generation) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00143) "%s", msg); ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, "%s", msg); + clean_child_exit(0); + } + else { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(00144) "%s", msg); ++ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, "%s", msg); + exit(APEXIT_CHILDFATAL); + } + } @@ -321,16 +275,16 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + if (rv != APR_SUCCESS) { + const char *msg = "couldn't release the accept mutex"; + -+ if (retained->my_generation != ++ if (ap_my_generation != + ap_scoreboard_image->global->running_generation) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, ap_server_conf, APLOGNO(00145) "%s", msg); ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, NULL, "%s", msg); + /* don't exit here... we have a connection to + * process, after which point we'll see that the + * generation changed and we'll exit cleanly + */ + } + else { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, APLOGNO(00146) "%s", msg); ++ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, "%s", msg); + exit(APEXIT_CHILDFATAL); + } + } @@ -347,63 +301,74 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c +#define SAFE_ACCEPT(stmt) do {stmt;} while(0) +#endif + -+static int itk_query(int query_code, int *result, apr_status_t *rv) ++AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) +{ -+ *rv = APR_SUCCESS; + switch(query_code){ + case AP_MPMQ_MAX_DAEMON_USED: + *result = ap_daemons_limit; -+ break; ++ return APR_SUCCESS; + case AP_MPMQ_IS_THREADED: + *result = AP_MPMQ_NOT_SUPPORTED; -+ break; ++ return APR_SUCCESS; + case AP_MPMQ_IS_FORKED: + *result = AP_MPMQ_DYNAMIC; -+ break; ++ return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_DAEMONS: + *result = server_limit; -+ break; ++ return APR_SUCCESS; + case AP_MPMQ_HARD_LIMIT_THREADS: + *result = HARD_THREAD_LIMIT; -+ break; ++ return APR_SUCCESS; + case AP_MPMQ_MAX_THREADS: -+ *result = 1; -+ break; ++ *result = 0; ++ return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_DAEMONS: + *result = ap_daemons_min_free; -+ break; ++ return APR_SUCCESS; + case AP_MPMQ_MIN_SPARE_THREADS: + *result = 0; -+ break; ++ return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_DAEMONS: + *result = ap_daemons_max_free; -+ break; ++ return APR_SUCCESS; + case AP_MPMQ_MAX_SPARE_THREADS: + *result = 0; -+ break; ++ return APR_SUCCESS; + case AP_MPMQ_MAX_REQUESTS_DAEMON: + *result = ap_max_requests_per_child; -+ break; ++ return APR_SUCCESS; + case AP_MPMQ_MAX_DAEMONS: -+ *result = ap_daemons_limit; -+ break; ++ *result = server_limit; ++ return APR_SUCCESS; + case AP_MPMQ_MPM_STATE: + *result = mpm_state; -+ break; -+ case AP_MPMQ_GENERATION: -+ *result = retained->my_generation; -+ break; -+ default: -+ *rv = APR_ENOTIMPL; -+ break; ++ return APR_SUCCESS; + } -+ return OK; ++ return APR_ENOTIMPL; +} + -+static const char *itk_get_name(void) ++#if defined(NEED_WAITPID) ++/* ++ Systems without a real waitpid sometimes lose a child's exit while waiting ++ for another. Search through the scoreboard for missing children. ++ */ ++int reap_children(int *exitcode, apr_exit_why_e *status) +{ -+ return "itk"; ++ int n, pid; ++ ++ for (n = 0; n < ap_max_daemons_limit; ++n) { ++ if (ap_scoreboard_image->servers[n][0].status != SERVER_DEAD && ++ kill((pid = ap_scoreboard_image->parent[n].pid), 0) == -1) { ++ ap_update_child_status_from_indexes(n, 0, SERVER_DEAD, NULL); ++ /* just mark it as having a successful exit status */ ++ *status = APR_PROC_EXIT; ++ *exitcode = 0; ++ return(pid); ++ } ++ } ++ return 0; +} ++#endif + +/***************************************************************** + * Connection structures and accounting... @@ -414,20 +379,19 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + clean_child_exit(0); +} + -+/* volatile because they're updated from a signal handler */ -+static int volatile shutdown_pending; -+static int volatile restart_pending; -+static int volatile die_now = 0; -+ +static void stop_listening(int sig) +{ -+ mpm_state = AP_MPMQ_STOPPING; + ap_close_listeners(); + + /* For a graceful stop, we want the child to exit when done */ + die_now = 1; +} + ++/* volatile just in case */ ++static int volatile shutdown_pending; ++static int volatile restart_pending; ++static int volatile is_graceful; ++ +static void sig_term(int sig) +{ + if (shutdown_pending == 1) { @@ -437,9 +401,8 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + */ + return; + } -+ mpm_state = AP_MPMQ_STOPPING; + shutdown_pending = 1; -+ retained->is_graceful = (sig == AP_SIG_GRACEFUL_STOP); ++ is_graceful = (sig == AP_SIG_GRACEFUL_STOP); +} + +/* restart() is the signal handler for SIGHUP and AP_SIG_GRACEFUL @@ -451,9 +414,8 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + /* Probably not an error - don't bother reporting it */ + return; + } -+ mpm_state = AP_MPMQ_STOPPING; + restart_pending = 1; -+ retained->is_graceful = (sig == AP_SIG_GRACEFUL); ++ is_graceful = (sig == AP_SIG_GRACEFUL); +} + +static void set_signals(void) @@ -472,33 +434,30 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + + sa.sa_handler = sig_term; + if (sigaction(SIGTERM, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00147) "sigaction(SIGTERM)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGTERM)"); +#ifdef AP_SIG_GRACEFUL_STOP + if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00148) ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, + "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")"); +#endif +#ifdef SIGINT + if (sigaction(SIGINT, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00149) "sigaction(SIGINT)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGINT)"); +#endif +#ifdef SIGXCPU + sa.sa_handler = SIG_DFL; + if (sigaction(SIGXCPU, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00150) "sigaction(SIGXCPU)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXCPU)"); +#endif +#ifdef SIGXFSZ -+ /* For systems following the LFS standard, ignoring SIGXFSZ allows -+ * a write() beyond the 2GB limit to fail gracefully with E2BIG -+ * rather than terminate the process. */ -+ sa.sa_handler = SIG_IGN; ++ sa.sa_handler = SIG_DFL; + if (sigaction(SIGXFSZ, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00151) "sigaction(SIGXFSZ)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGXFSZ)"); +#endif +#ifdef SIGPIPE + sa.sa_handler = SIG_IGN; + if (sigaction(SIGPIPE, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00152) "sigaction(SIGPIPE)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGPIPE)"); +#endif + + /* we want to ignore HUPs and AP_SIG_GRACEFUL while we're busy @@ -508,16 +467,16 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + sigaddset(&sa.sa_mask, AP_SIG_GRACEFUL); + sa.sa_handler = restart; + if (sigaction(SIGHUP, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00153) "sigaction(SIGHUP)"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(SIGHUP)"); + if (sigaction(AP_SIG_GRACEFUL, &sa, NULL) < 0) -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00154) "sigaction(" AP_SIG_GRACEFUL_STRING ")"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "sigaction(" AP_SIG_GRACEFUL_STRING ")"); +#else + if (!one_process) { +#ifdef SIGXCPU + apr_signal(SIGXCPU, SIG_DFL); +#endif /* SIGXCPU */ +#ifdef SIGXFSZ -+ apr_signal(SIGXFSZ, SIG_IGN); ++ apr_signal(SIGXFSZ, SIG_DFL); +#endif /* SIGXFSZ */ + } + @@ -547,12 +506,16 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c +static int requests_this_child; +static int num_listensocks = 0; + ++ ++int ap_graceful_stop_signalled(void) ++{ ++ /* not ever called anymore... */ ++ return 0; ++} ++ ++ +static void child_main(int child_num_arg) +{ -+#if APR_HAS_THREADS -+ apr_thread_t *thd = NULL; -+ apr_os_thread_t osthd; -+#endif + apr_pool_t *ptrans; + apr_allocator_t *allocator; + apr_status_t status; @@ -562,23 +525,21 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + ap_sb_handle_t *sbh; + apr_bucket_alloc_t *bucket_alloc; + int last_poll_idx = 0; -+ const char *lockfile; + +#if HAVE_LIBCAP + cap_t caps; + cap_value_t suidcaps[] = { + CAP_SETUID, + CAP_SETGID, -+ CAP_DAC_READ_SEARCH, ++ CAP_DAC_READ_SEARCH, + CAP_SYS_NICE, + }; -+#endif ++#endif + + mpm_state = AP_MPMQ_STARTING; /* for benefit of any hooks that run as this + * child initializes + */ + -+ ap_running_under_mpm_itk = 1; + my_child_num = child_num_arg; + ap_my_pid = getpid(); + requests_this_child = 0; @@ -592,28 +553,17 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + apr_allocator_max_free_set(allocator, ap_max_mem_free); + apr_pool_create_ex(&pchild, pconf, NULL, allocator); + apr_allocator_owner_set(allocator, pchild); -+ apr_pool_tag(pchild, "pchild"); -+ -+#if APR_HAS_THREADS -+ osthd = apr_os_thread_current(); -+ apr_os_thread_put(&thd, &osthd, pchild); -+#endif + + apr_pool_create(&ptrans, pchild); + apr_pool_tag(ptrans, "transaction"); + + /* needs to be done before we switch UIDs so we have permissions */ + ap_reopen_scoreboard(pchild, NULL, 0); -+ lockfile = apr_proc_mutex_lockfile(accept_mutex); -+ status = apr_proc_mutex_child_init(&accept_mutex, -+ lockfile, -+ pchild); ++ status = apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, pchild); + if (status != APR_SUCCESS) { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, APLOGNO(00155) ++ ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, + "Couldn't initialize cross-process lock in child " -+ "(%s) (%s)", -+ lockfile ? lockfile : "none", -+ apr_proc_mutex_name(accept_mutex)); ++ "(%s) (%d)", ap_lock_fname, ap_accept_lock_mech); + clean_child_exit(APEXIT_CHILDFATAL); + } + @@ -624,12 +574,8 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + (void) ap_update_child_status(sbh, SERVER_READY, (request_rec *) NULL); + + /* Set up the pollfd array */ -+ status = apr_pollset_create(&pollset, num_listensocks, pchild, 0); -+ if (status != APR_SUCCESS) { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, APLOGNO(00156) -+ "Couldn't create pollset in child; check system or user limits"); -+ clean_child_exit(APEXIT_CHILDSICK); /* assume temporary resource issue */ -+ } ++ /* ### check the status */ ++ (void) apr_pollset_create(&pollset, num_listensocks, pchild, 0); + + for (lr = ap_listeners, i = num_listensocks; i--; lr = lr->next) { + apr_pollfd_t pfd = { 0 }; @@ -639,21 +585,15 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + pfd.reqevents = APR_POLLIN; + pfd.client_data = lr; + -+ status = apr_pollset_add(pollset, &pfd); -+ if (status != APR_SUCCESS) { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf, APLOGNO(00157) -+ "Couldn't add listener to pollset; check system or user limits"); -+ clean_child_exit(APEXIT_CHILDSICK); -+ } -+ -+ lr->accept_func = ap_unixd_accept; ++ /* ### check the status */ ++ (void) apr_pollset_add(pollset, &pfd); + } + +#if HAVE_LIBCAP + /* Drop as many privileges as we can. We'll still + * access files with uid=0, and we can setuid() to anything, but + * at least there's tons of other evilness (like loading kernel -+ * modules) we can't do directly. (The setuid() capability will ++ * modules) we can't do directly. (The setuid() capability will + * go away automatically when we setuid() or exec() -- the former + * is likely to come first.) + */ @@ -663,7 +603,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + cap_set_flag(caps, CAP_EFFECTIVE, sizeof(suidcaps)/sizeof(cap_value_t), suidcaps, CAP_SET); + cap_set_proc(caps); + cap_free(caps); -+#endif ++#endif + + mpm_state = AP_MPMQ_RUNNING; + @@ -706,23 +646,19 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + apr_int32_t numdesc; + const apr_pollfd_t *pdesc; + -+ /* check for termination first so we don't sleep for a while in -+ * poll if already signalled -+ */ -+ if (die_now /* in graceful stop/restart */ -+ || (one_process && shutdown_pending)) { -+ SAFE_ACCEPT(accept_mutex_off()); -+ clean_child_exit(0); -+ } -+ -+ /* timeout == 10 seconds to avoid a hang at graceful restart/stop -+ * caused by the closing of sockets by the signal handler -+ */ -+ status = apr_pollset_poll(pollset, apr_time_from_sec(10), -+ &numdesc, &pdesc); ++ /* timeout == -1 == wait forever */ ++ status = apr_pollset_poll(pollset, -1, &numdesc, &pdesc); + if (status != APR_SUCCESS) { -+ if (APR_STATUS_IS_TIMEUP(status) || -+ APR_STATUS_IS_EINTR(status)) { ++ if (APR_STATUS_IS_EINTR(status)) { ++ if (one_process && shutdown_pending) { ++ return; ++ } ++ else if (die_now) { ++ /* In graceful stop/restart; drop the mutex ++ * and terminate the child. */ ++ SAFE_ACCEPT(accept_mutex_off()); ++ clean_child_exit(0); ++ } + continue; + } + /* Single Unix documents select as returning errnos @@ -732,7 +668,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + * occasionally, and we'd loop forever due to it. + */ + ap_log_error(APLOG_MARK, APLOG_ERR, status, -+ ap_server_conf, APLOGNO(00158) "apr_pollset_poll: (listen)"); ++ ap_server_conf, "apr_pollset_poll: (listen)"); + SAFE_ACCEPT(accept_mutex_off()); + clean_child_exit(1); + } @@ -790,15 +726,13 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + ap_log_error(APLOG_MARK, APLOG_ERR, errno, NULL, "fork: Unable to fork new process"); + break; + case 0: /* child */ ++ apr_proc_mutex_child_init(&accept_mutex, ap_lock_fname, pchild); + current_conn = ap_run_create_connection(ptrans, ap_server_conf, csd, my_child_num, sbh, bucket_alloc); + if (current_conn) { -+#if APR_HAS_THREADS -+ current_conn->current_thread = thd; -+#endif + ap_process_connection(current_conn, csd); + ap_lingering_close(current_conn); + } -+ clean_child_exit(0); ++ exit(0); + default: /* parent; just wait for child to be done */ + do { + child_pid = waitpid(pid, &status, 0); @@ -826,7 +760,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + if (ap_mpm_pod_check(pod) == APR_SUCCESS) { /* selected as idle? */ + die_now = 1; + } -+ else if (retained->my_generation != ++ else if (ap_my_generation != + ap_scoreboard_image->global->running_generation) { /* restart? */ + /* yeah, this could be non-graceful restart, in which case the + * parent will kill us soon enough, but why bother checking? @@ -838,7 +772,6 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + if (getuid()) + die_now = 1; + } -+ apr_pool_clear(ptrans); /* kludge to avoid crash in APR reslist cleanup code */ + clean_child_exit(0); +} + @@ -847,8 +780,8 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c +{ + int pid; + -+ if (slot + 1 > retained->max_daemons_limit) { -+ retained->max_daemons_limit = slot + 1; ++ if (slot + 1 > ap_max_daemons_limit) { ++ ap_max_daemons_limit = slot + 1; + } + + if (one_process) { @@ -859,9 +792,8 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + apr_signal(SIGQUIT, SIG_DFL); +#endif + apr_signal(SIGTERM, sig_term); -+ itk_note_child_started(slot, getpid()); + child_main(slot); -+ /* NOTREACHED */ ++ return 0; + } + + (void) ap_update_child_status_from_indexes(slot, 0, SERVER_STARTING, @@ -870,11 +802,13 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + +#ifdef _OSD_POSIX + /* BS2000 requires a "special" version of fork() before a setuid() call */ -+ if ((pid = os_fork(ap_unixd_config.user_name)) == -1) { ++ if ((pid = os_fork(unixd_config.user_name)) == -1) { ++#elif defined(TPF) ++ if ((pid = os_fork(s, slot)) == -1) { +#else + if ((pid = fork()) == -1) { +#endif -+ ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, APLOGNO(00159) "fork: Unable to fork new process"); ++ ap_log_error(APLOG_MARK, APLOG_ERR, errno, s, "fork: Unable to fork new process"); + + /* fork didn't succeed. Fix the scoreboard or else + * it will say SERVER_STARTING forever and ever @@ -899,8 +833,8 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + int status = bindprocessor(BINDPROCESS, (int)getpid(), + PROCESSOR_CLASS_ANY); + if (status != OK) { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, errno, -+ ap_server_conf, APLOGNO(00160) "processor unbind failed"); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ++ ap_server_conf, "processor unbind failed %d", status); + } +#endif + RAISE_SIGSTOP(MAKE_CHILD); @@ -917,7 +851,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + child_main(slot); + } + -+ itk_note_child_started(slot, pid); ++ ap_scoreboard_image->parent[slot].pid = pid; + + return 0; +} @@ -939,9 +873,23 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + } +} + ++ ++/* ++ * idle_spawn_rate is the number of children that will be spawned on the ++ * next maintenance cycle if there aren't enough idle servers. It is ++ * doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by ++ * without the need to spawn. ++ */ ++static int idle_spawn_rate = 1; ++#ifndef MAX_SPAWN_RATE ++#define MAX_SPAWN_RATE (32) ++#endif ++static int hold_off_on_exponential_spawning; ++ +static void perform_idle_server_maintenance(apr_pool_t *p) +{ + int i; ++ int to_kill; + int idle_count; + worker_score *ws; + int free_length; @@ -952,6 +900,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + /* initialize the free_list */ + free_length = 0; + ++ to_kill = -1; + idle_count = 0; + last_non_dead = -1; + total_non_dead = 0; @@ -959,13 +908,13 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + for (i = 0; i < ap_daemons_limit; ++i) { + int status; + -+ if (i >= retained->max_daemons_limit && free_length == retained->idle_spawn_rate) ++ if (i >= ap_max_daemons_limit && free_length == idle_spawn_rate) + break; + ws = &ap_scoreboard_image->servers[i][0]; + status = ws->status; + if (status == SERVER_DEAD) { + /* try to keep children numbers as low as possible */ -+ if (free_length < retained->idle_spawn_rate) { ++ if (free_length < idle_spawn_rate) { + free_slots[free_length] = i; + ++free_length; + } @@ -979,58 +928,77 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + */ + if (status <= SERVER_READY) { + ++ idle_count; ++ /* always kill the highest numbered child if we have to... ++ * no really well thought out reason ... other than observing ++ * the server behaviour under linux where lower numbered children ++ * tend to service more hits (and hence are more likely to have ++ * their data in cpu caches). ++ */ ++ to_kill = i; + } + + ++total_non_dead; + last_non_dead = i; + } + } -+ retained->max_daemons_limit = last_non_dead + 1; ++ ap_max_daemons_limit = last_non_dead + 1; + if (idle_count > ap_daemons_max_free) { + /* kill off one child... we use the pod because that'll cause it to + * shut down gracefully, in case it happened to pick up a request + * while we were counting + */ + ap_mpm_pod_signal(pod); -+ retained->idle_spawn_rate = 1; ++ idle_spawn_rate = 1; + } + else if (idle_count < ap_daemons_min_free) { + /* terminate the free list */ + if (free_length == 0) { + /* only report this condition once */ -+ if (!retained->maxclients_reported) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, APLOGNO(00161) -+ "server reached MaxRequestWorkers setting, consider" -+ " raising the MaxRequestWorkers setting"); -+ retained->maxclients_reported = 1; ++ static int reported = 0; ++ ++ if (!reported) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ap_server_conf, ++ "server reached MaxClients setting, consider" ++ " raising the MaxClients setting"); ++ reported = 1; + } -+ retained->idle_spawn_rate = 1; ++ idle_spawn_rate = 1; + } + else { -+ if (retained->idle_spawn_rate >= 8) { -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00162) ++ if (idle_spawn_rate >= 8) { ++ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "server seems busy, (you may need " + "to increase StartServers, or Min/MaxSpareServers), " + "spawning %d children, there are %d idle, and " -+ "%d total children", retained->idle_spawn_rate, ++ "%d total children", idle_spawn_rate, + idle_count, total_non_dead); + } + for (i = 0; i < free_length; ++i) { ++#ifdef TPF ++ if (make_child(ap_server_conf, free_slots[i]) == -1) { ++ if(free_length == 1) { ++ shutdown_pending = 1; ++ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, ap_server_conf, ++ "No active child processes: shutting down"); ++ } ++ } ++#else + make_child(ap_server_conf, free_slots[i]); ++#endif /* TPF */ + } + /* the next time around we want to spawn twice as many if this + * wasn't good enough, but not if we've just done a graceful + */ -+ if (retained->hold_off_on_exponential_spawning) { -+ --retained->hold_off_on_exponential_spawning; ++ if (hold_off_on_exponential_spawning) { ++ --hold_off_on_exponential_spawning; + } -+ else if (retained->idle_spawn_rate < MAX_SPAWN_RATE) { -+ retained->idle_spawn_rate *= 2; ++ else if (idle_spawn_rate < MAX_SPAWN_RATE) { ++ idle_spawn_rate *= 2; + } + } + } + else { -+ retained->idle_spawn_rate = 1; ++ idle_spawn_rate = 1; + } +} + @@ -1038,7 +1006,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + * Executive routines. + */ + -+static int itk_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) ++int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) +{ + int index; + int remaining_children_to_start; @@ -1046,32 +1014,61 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + + ap_log_pid(pconf, ap_pid_fname); + -+ /* Initialize cross-process accept lock */ -+ rv = ap_proc_mutex_create(&accept_mutex, NULL, AP_ACCEPT_MUTEX_TYPE, NULL, -+ s, _pconf, 0); -+ if (rv != APR_SUCCESS) { -+ mpm_state = AP_MPMQ_STOPPING; -+ return DONE; ++ first_server_limit = server_limit; ++ if (changed_limit_at_restart) { ++ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, ++ "WARNING: Attempt to change ServerLimit " ++ "ignored during restart"); ++ changed_limit_at_restart = 0; + } + -+ if (!retained->is_graceful) { ++ /* Initialize cross-process accept lock */ ++ ap_lock_fname = apr_psprintf(_pconf, "%s.%" APR_PID_T_FMT, ++ ap_server_root_relative(_pconf, ap_lock_fname), ++ ap_my_pid); ++ ++ rv = apr_proc_mutex_create(&accept_mutex, ap_lock_fname, ++ ap_accept_lock_mech, _pconf); ++ if (rv != APR_SUCCESS) { ++ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, ++ "Couldn't create accept lock (%s) (%d)", ++ ap_lock_fname, ap_accept_lock_mech); ++ mpm_state = AP_MPMQ_STOPPING; ++ return 1; ++ } ++ ++#if APR_USE_SYSVSEM_SERIALIZE ++ if (ap_accept_lock_mech == APR_LOCK_DEFAULT || ++ ap_accept_lock_mech == APR_LOCK_SYSVSEM) { ++#else ++ if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { ++#endif ++ rv = unixd_set_proc_mutex_perms(accept_mutex); ++ if (rv != APR_SUCCESS) { ++ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, ++ "Couldn't set permissions on cross-process lock; " ++ "check User and Group directives"); ++ mpm_state = AP_MPMQ_STOPPING; ++ return 1; ++ } ++ } ++ ++ if (!is_graceful) { + if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) { + mpm_state = AP_MPMQ_STOPPING; -+ return DONE; ++ return 1; + } + /* fix the generation number in the global score; we just got a new, + * cleared scoreboard + */ -+ ap_scoreboard_image->global->running_generation = retained->my_generation; ++ ap_scoreboard_image->global->running_generation = ap_my_generation; + } + -+ restart_pending = shutdown_pending = 0; + set_signals(); + + if (one_process) { + AP_MONCONTROL(1); + make_child(ap_server_conf, 0); -+ /* NOTREACHED */ + } + else { + if (ap_daemons_max_free < ap_daemons_min_free + 1) /* Don't thrash... */ @@ -1089,7 +1086,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + if (remaining_children_to_start > ap_daemons_limit) { + remaining_children_to_start = ap_daemons_limit; + } -+ if (!retained->is_graceful) { ++ if (!is_graceful) { + startup_children(remaining_children_to_start); + remaining_children_to_start = 0; + } @@ -1097,19 +1094,21 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + /* give the system some time to recover before kicking into + * exponential mode + */ -+ retained->hold_off_on_exponential_spawning = 10; ++ hold_off_on_exponential_spawning = 10; + } + -+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00163) ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "%s configured -- resuming normal operations", + ap_get_server_description()); -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, APLOGNO(00164) ++ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf, + "Server built: %s", ap_get_server_built()); -+ ap_log_command_line(plog, s); -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00165) -+ "Accept mutex: %s (default: %s)", ++#ifdef AP_MPM_WANT_SET_ACCEPT_LOCK_MECH ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, ++ "AcceptMutex: %s (default: %s)", + apr_proc_mutex_name(accept_mutex), + apr_proc_mutex_defname()); ++#endif ++ restart_pending = shutdown_pending = 0; + + mpm_state = AP_MPMQ_RUNNING; + @@ -1120,7 +1119,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + /* this is a memory leak, but I'll fix it later. */ + apr_proc_t pid; + -+ ap_wait_or_timeout(&exitwhy, &status, &pid, pconf, ap_server_conf); ++ ap_wait_or_timeout(&exitwhy, &status, &pid, pconf); + + /* XXX: if it takes longer than 1 second for all our children + * to start up and get into IDLE state then we may spawn an @@ -1128,37 +1127,21 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + */ + if (pid.pid != -1) { + processed_status = ap_process_child_status(&pid, exitwhy, status); -+ child_slot = ap_find_child_by_pid(&pid); + if (processed_status == APEXIT_CHILDFATAL) { -+ /* fix race condition found in PR 39311 -+ * A child created at the same time as a graceful happens -+ * can find the lock missing and create a fatal error. -+ * It is not fatal for the last generation to be in this state. -+ */ -+ if (child_slot < 0 -+ || ap_get_scoreboard_process(child_slot)->generation -+ == retained->my_generation) { -+ mpm_state = AP_MPMQ_STOPPING; -+ return DONE; -+ } -+ else { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, ap_server_conf, APLOGNO(00166) -+ "Ignoring fatal error in child of previous " -+ "generation (pid %ld).", -+ (long)pid.pid); -+ } ++ mpm_state = AP_MPMQ_STOPPING; ++ return 1; + } + + /* non-fatal death... note that it's gone in the scoreboard. */ ++ child_slot = find_child_by_pid(&pid); + if (child_slot >= 0) { + (void) ap_update_child_status_from_indexes(child_slot, 0, SERVER_DEAD, + (request_rec *) NULL); -+ itk_note_child_killed(child_slot, 0, 0); + if (processed_status == APEXIT_CHILDSICK) { + /* child detected a resource shortage (E[NM]FILE, ENOBUFS, etc) + * cut the fork rate to the minimum + */ -+ retained->idle_spawn_rate = 1; ++ idle_spawn_rate = 1; + } + else if (remaining_children_to_start + && child_slot < ap_daemons_limit) { @@ -1174,13 +1157,13 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + /* handled */ +#endif + } -+ else if (retained->is_graceful) { ++ else if (is_graceful) { + /* Great, we've probably just lost a slot in the + * scoreboard. Somehow we don't know about this + * child. + */ + ap_log_error(APLOG_MARK, APLOG_WARNING, -+ 0, ap_server_conf, APLOGNO(00167) ++ 0, ap_server_conf, + "long lost child came home! (pid %ld)", (long)pid.pid); + } + /* Don't perform idle maintenance when a child dies, @@ -1205,27 +1188,40 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + } + + perform_idle_server_maintenance(pconf); ++#ifdef TPF ++ shutdown_pending = os_check_server(tpf_server_name); ++ ap_check_signals(); ++ sleep(1); ++#endif /*TPF */ + } + } /* one_process */ + + mpm_state = AP_MPMQ_STOPPING; + -+ if (shutdown_pending && !retained->is_graceful) { ++ if (shutdown_pending && !is_graceful) { + /* Time to shut down: + * Kill child processes, tell them to call child_exit, etc... + */ -+ if (ap_unixd_killpg(getpgrp(), SIGTERM) < 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00168) "killpg SIGTERM"); ++ if (unixd_killpg(getpgrp(), SIGTERM) < 0) { ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGTERM"); + } -+ ap_reclaim_child_processes(1, /* Start with SIGTERM */ -+ itk_note_child_killed); ++ ap_reclaim_child_processes(1); /* Start with SIGTERM */ + + /* cleanup pid file on normal shutdown */ -+ ap_remove_pid(pconf, ap_pid_fname); -+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00169) ++ { ++ const char *pidfile = NULL; ++ pidfile = ap_server_root_relative (pconf, ap_pid_fname); ++ if ( pidfile != NULL && unlink(pidfile) == 0) ++ ap_log_error(APLOG_MARK, APLOG_INFO, ++ 0, ap_server_conf, ++ "removed PID file %s (pid=%ld)", ++ pidfile, (long)getpid()); ++ } ++ ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "caught SIGTERM, shutting down"); + -+ return DONE; ++ return 1; + } else if (shutdown_pending) { + /* Time to perform a graceful shut down: + * Reap the inactive children, and ask the active ones @@ -1239,7 +1235,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + ap_close_listeners(); + + /* kill off the idle ones */ -+ ap_mpm_pod_killpg(pod, retained->max_daemons_limit); ++ ap_mpm_pod_killpg(pod, ap_max_daemons_limit); + + /* Send SIGUSR1 to the active children */ + active_children = 0; @@ -1252,11 +1248,20 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + } + + /* Allow each child which actually finished to exit */ -+ ap_relieve_child_processes(itk_note_child_killed); ++ ap_relieve_child_processes(); + + /* cleanup pid file */ -+ ap_remove_pid(pconf, ap_pid_fname); -+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00170) ++ { ++ const char *pidfile = NULL; ++ pidfile = ap_server_root_relative (pconf, ap_pid_fname); ++ if ( pidfile != NULL && unlink(pidfile) == 0) ++ ap_log_error(APLOG_MARK, APLOG_INFO, ++ 0, ap_server_conf, ++ "removed PID file %s (pid=%ld)", ++ pidfile, (long)getpid()); ++ } ++ ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "caught " AP_SIG_GRACEFUL_STOP_STRING ", shutting down gracefully"); + + if (ap_graceful_shutdown_timeout) { @@ -1271,7 +1276,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + sleep(1); + + /* Relieve any children which have now exited */ -+ ap_relieve_child_processes(itk_note_child_killed); ++ ap_relieve_child_processes(); + + active_children = 0; + for (index = 0; index < ap_daemons_limit; ++index) { @@ -1288,9 +1293,9 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + * way, try and make sure that all of our processes are + * really dead. + */ -+ ap_unixd_killpg(getpgrp(), SIGTERM); ++ unixd_killpg(getpgrp(), SIGTERM); + -+ return DONE; ++ return 1; + } + + /* we've been told to restart */ @@ -1298,22 +1303,22 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + apr_signal(AP_SIG_GRACEFUL, SIG_IGN); + if (one_process) { + /* not worth thinking about */ -+ return DONE; ++ return 1; + } + + /* advance to the next generation */ + /* XXX: we really need to make sure this new generation number isn't in + * use by any of the children. + */ -+ ++retained->my_generation; -+ ap_scoreboard_image->global->running_generation = retained->my_generation; ++ ++ap_my_generation; ++ ap_scoreboard_image->global->running_generation = ap_my_generation; + -+ if (retained->is_graceful) { -+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00171) ++ if (is_graceful) { ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "Graceful restart requested, doing restart"); + + /* kill off the idle ones */ -+ ap_mpm_pod_killpg(pod, retained->max_daemons_limit); ++ ap_mpm_pod_killpg(pod, ap_max_daemons_limit); + + /* This is mostly for debugging... so that we know what is still + * gracefully dealing with existing request. This will break @@ -1336,16 +1341,15 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + } + else { + /* Kill 'em off */ -+ if (ap_unixd_killpg(getpgrp(), SIGHUP) < 0) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00172) "killpg SIGHUP"); ++ if (unixd_killpg(getpgrp(), SIGHUP) < 0) { ++ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, "killpg SIGHUP"); + } -+ ap_reclaim_child_processes(0, /* Not when just starting up */ -+ itk_note_child_killed); -+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00173) ++ ap_reclaim_child_processes(0); /* Not when just starting up */ ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, + "SIGHUP received. Attempting to restart"); + } + -+ return OK; ++ return 0; +} + +/* This really should be a post_config hook, but the error log is already @@ -1353,29 +1357,20 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + */ +static int itk_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) +{ -+ int startup = 0; -+ int level_flags = 0; + apr_status_t rv; + + pconf = p; -+ -+ /* the reverse of pre_config, we want this only the first time around */ -+ if (retained->module_loads == 1) { -+ startup = 1; -+ level_flags |= APLOG_STARTUP; -+ } ++ ap_server_conf = s; + + if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) { -+ ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0, -+ (startup ? NULL : s), -+ "no listening sockets available, shutting down"); ++ ap_log_error(APLOG_MARK, APLOG_ALERT|APLOG_STARTUP, 0, ++ NULL, "no listening sockets available, shutting down"); + return DONE; + } + + if ((rv = ap_mpm_pod_open(pconf, &pod))) { -+ ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv, -+ (startup ? NULL : s), -+ "could not open pipe-of-death"); ++ ap_log_error(APLOG_MARK, APLOG_CRIT|APLOG_STARTUP, rv, NULL, ++ "Could not open pipe-of-death."); + return DONE; + } + return OK; @@ -1383,9 +1378,9 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + +static int itk_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) +{ ++ static int restart_num = 0; + int no_detach, debug, foreground; + apr_status_t rv; -+ const char *userdata_key = "mpm_itk_module"; + + mpm_state = AP_MPMQ_STARTING; + @@ -1402,161 +1397,38 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + foreground = ap_exists_config_define("FOREGROUND"); + } + -+ ap_mutex_register(p, AP_ACCEPT_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0); -+ + /* sigh, want this only the second time around */ -+ retained = ap_retained_data_get(userdata_key); -+ if (!retained) { -+ retained = ap_retained_data_create(userdata_key, sizeof(*retained)); -+ retained->max_daemons_limit = -1; -+ retained->idle_spawn_rate = 1; -+ } -+ ++retained->module_loads; -+ if (retained->module_loads == 2) { ++ if (restart_num++ == 1) { ++ is_graceful = 0; ++ + if (!one_process && !foreground) { -+ /* before we detach, setup crash handlers to log to errorlog */ -+ ap_fatal_signal_setup(ap_server_conf, pconf); + rv = apr_proc_detach(no_detach ? APR_PROC_DETACH_FOREGROUND + : APR_PROC_DETACH_DAEMONIZE); + if (rv != APR_SUCCESS) { -+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, APLOGNO(00174) ++ ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL, + "apr_proc_detach failed"); + return HTTP_INTERNAL_SERVER_ERROR; + } + } ++ ++ parent_pid = ap_my_pid = getpid(); + } + -+ parent_pid = ap_my_pid = getpid(); -+ ++ unixd_pre_config(ptemp); + ap_listen_pre_config(); + ap_daemons_to_start = DEFAULT_START_DAEMON; + ap_daemons_min_free = DEFAULT_MIN_FREE_DAEMON; + ap_daemons_max_free = DEFAULT_MAX_FREE_DAEMON; -+ server_limit = DEFAULT_SERVER_LIMIT; + ap_daemons_limit = server_limit; ++ ap_pid_fname = DEFAULT_PIDLOG; ++ ap_lock_fname = DEFAULT_LOCKFILE; ++ ap_max_requests_per_child = DEFAULT_MAX_REQUESTS_PER_CHILD; + ap_extended_status = 0; ++#ifdef AP_MPM_WANT_SET_MAX_MEM_FREE ++ ap_max_mem_free = APR_ALLOCATOR_MAX_FREE_UNLIMITED; ++#endif + -+ return OK; -+} -+ -+static int itk_check_config(apr_pool_t *p, apr_pool_t *plog, -+ apr_pool_t *ptemp, server_rec *s) -+{ -+ int startup = 0; -+ -+ /* the reverse of pre_config, we want this only the first time around */ -+ if (retained->module_loads == 1) { -+ startup = 1; -+ } -+ -+ if (server_limit > MAX_SERVER_LIMIT) { -+ if (startup) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00175) -+ "WARNING: ServerLimit of %d exceeds compile-time " -+ "limit of", server_limit); -+ ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, -+ " %d servers, decreasing to %d.", -+ MAX_SERVER_LIMIT, MAX_SERVER_LIMIT); -+ } else { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00176) -+ "ServerLimit of %d exceeds compile-time limit " -+ "of %d, decreasing to match", -+ server_limit, MAX_SERVER_LIMIT); -+ } -+ server_limit = MAX_SERVER_LIMIT; -+ } -+ else if (server_limit < 1) { -+ if (startup) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00177) -+ "WARNING: ServerLimit of %d not allowed, " -+ "increasing to 1.", server_limit); -+ } else { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00178) -+ "ServerLimit of %d not allowed, increasing to 1", -+ server_limit); -+ } -+ server_limit = 1; -+ } -+ -+ /* you cannot change ServerLimit across a restart; ignore -+ * any such attempts -+ */ -+ if (!retained->first_server_limit) { -+ retained->first_server_limit = server_limit; -+ } -+ else if (server_limit != retained->first_server_limit) { -+ /* don't need a startup console version here */ -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00179) -+ "changing ServerLimit to %d from original value of %d " -+ "not allowed during restart", -+ server_limit, retained->first_server_limit); -+ server_limit = retained->first_server_limit; -+ } -+ -+ if (ap_daemons_limit > server_limit) { -+ if (startup) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00180) -+ "WARNING: MaxRequestWorkers of %d exceeds ServerLimit " -+ "value of", ap_daemons_limit); -+ ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, -+ " %d servers, decreasing MaxRequestWorkers to %d.", -+ server_limit, server_limit); -+ ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, -+ " To increase, please see the ServerLimit " -+ "directive."); -+ } else { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00181) -+ "MaxRequestWorkers of %d exceeds ServerLimit value " -+ "of %d, decreasing to match", -+ ap_daemons_limit, server_limit); -+ } -+ ap_daemons_limit = server_limit; -+ } -+ else if (ap_daemons_limit < 1) { -+ if (startup) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00182) -+ "WARNING: MaxRequestWorkers of %d not allowed, " -+ "increasing to 1.", ap_daemons_limit); -+ } else { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00183) -+ "MaxRequestWorkers of %d not allowed, increasing to 1", -+ ap_daemons_limit); -+ } -+ ap_daemons_limit = 1; -+ } -+ -+ /* ap_daemons_to_start > ap_daemons_limit checked in itk_run() */ -+ if (ap_daemons_to_start < 0) { -+ if (startup) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00184) -+ "WARNING: StartServers of %d not allowed, " -+ "increasing to 1.", ap_daemons_to_start); -+ } else { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00185) -+ "StartServers of %d not allowed, increasing to 1", -+ ap_daemons_to_start); -+ } -+ ap_daemons_to_start = 1; -+ } -+ -+ if (ap_daemons_min_free < 1) { -+ if (startup) { -+ ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00186) -+ "WARNING: MinSpareServers of %d not allowed, " -+ "increasing to 1", ap_daemons_min_free); -+ ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, -+ " to avoid almost certain server failure."); -+ ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, -+ " Please read the documentation."); -+ } else { -+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(00187) -+ "MinSpareServers of %d not allowed, increasing to 1", -+ ap_daemons_min_free); -+ } -+ ap_daemons_min_free = 1; -+ } -+ -+ /* ap_daemons_max_free < ap_daemons_min_free + 1 checked in itk_run() */ ++ apr_cpystrn(ap_coredump_dir, ap_server_root, sizeof(ap_coredump_dir)); + + return OK; +} @@ -1570,7 +1442,6 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + + itk_server_conf *sconf = + (itk_server_conf *) ap_get_module_config(r->server->module_config, &mpm_itk_module); -+ itk_per_dir_conf *dconf; + + /* Enforce MaxClientsVhost. */ + if (sconf->max_clients_vhost > 0) { @@ -1589,7 +1460,8 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + } + } + -+ dconf = (itk_per_dir_conf *) ap_get_module_config(r->per_dir_config, &mpm_itk_module); ++ itk_per_dir_conf *dconf = ++ (itk_per_dir_conf *) ap_get_module_config(r->per_dir_config, &mpm_itk_module); + + strncpy(ap_scoreboard_image->servers[my_child_num][0].vhost, r->server->server_hostname, 31); + ap_scoreboard_image->servers[my_child_num][0].vhost[31] = 0; @@ -1605,51 +1477,9 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + wanted_username = dconf->username; + + if (wanted_uid == -1 || wanted_gid == -1) { -+ wanted_uid = ap_unixd_config.user_id; -+ wanted_gid = ap_unixd_config.group_id; -+ wanted_username = ap_unixd_config.user_name; -+ } -+ -+ /* AssignUserIDExpr and AssignGroupIDExpr override AssignUserID and defaults. */ -+ if (dconf->uid_expr != NULL) { -+ struct passwd *ent; -+ const char *err; -+ wanted_username = ap_expr_str_exec(r, dconf->uid_expr, &err); -+ if (err) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, \ -+ "Error while parsing AssignUserIDExpr expression: %s", -+ err); -+ return HTTP_INTERNAL_SERVER_ERROR; -+ } -+ -+ if (!(ent = getpwnam(wanted_username))) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, \ -+ "AssignUserIDExpr returned '%s', which is not a valid user name", -+ wanted_username); -+ return HTTP_INTERNAL_SERVER_ERROR; -+ } -+ -+ wanted_uid = ent->pw_uid; -+ } -+ if (dconf->gid_expr != NULL) { -+ struct group *ent; -+ const char *err; -+ const char *wanted_groupname = ap_expr_str_exec(r, dconf->gid_expr, &err); -+ if (err) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, \ -+ "Error while parsing AssignGroupIDExpr expression: %s", -+ err); -+ return HTTP_INTERNAL_SERVER_ERROR; -+ } -+ -+ if (!(ent = getgrnam(wanted_groupname))) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, \ -+ "AssignGroupIDExpr returned '%s', which is not a valid group name", -+ wanted_username); -+ return HTTP_INTERNAL_SERVER_ERROR; -+ } -+ -+ wanted_gid = ent->gr_gid; ++ wanted_uid = unixd_config.user_id; ++ wanted_gid = unixd_config.group_id; ++ wanted_username = unixd_config.user_name; + } + + if (!err && wanted_uid != -1 && wanted_gid != -1 && (getuid() != wanted_uid || getgid() != wanted_gid)) { @@ -1681,23 +1511,23 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + +static void itk_hooks(apr_pool_t *p) +{ -+ /* Our open_logs hook function must run before the core's, or stderr ++ /* The itk open_logs phase must run before the core's, or stderr + * will be redirected to a file, and the messages won't print to the + * console. + */ + static const char *const aszSucc[] = {"core.c", NULL}; + -+ ap_hook_open_logs(itk_open_logs, NULL, aszSucc, APR_HOOK_REALLY_FIRST); ++#ifdef AUX3 ++ (void) set42sig(); ++#endif ++ ++ ap_hook_open_logs(itk_open_logs, NULL, aszSucc, APR_HOOK_MIDDLE); + /* we need to set the MPM state before other pre-config hooks use MPM query + * to retrieve it, so register as REALLY_FIRST + */ + ap_hook_pre_config(itk_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); -+ ap_hook_check_config(itk_check_config, NULL, NULL, APR_HOOK_MIDDLE); -+ ap_hook_mpm(itk_run, NULL, NULL, APR_HOOK_MIDDLE); -+ ap_hook_mpm_query(itk_query, NULL, NULL, APR_HOOK_MIDDLE); -+ ap_hook_mpm_get_name(itk_get_name, NULL, NULL, APR_HOOK_MIDDLE); + -+ /* set the uid as fast as possible, but not before merging per-dir config */ ++ /* set the uid as fast as possible, but not before merging per-dit config */ + ap_hook_header_parser(itk_post_perdir_config, NULL, NULL, APR_HOOK_REALLY_FIRST); +} + @@ -1720,6 +1550,16 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + } + + ap_daemons_min_free = atoi(arg); ++ if (ap_daemons_min_free <= 0) { ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: detected MinSpareServers set to non-positive."); ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "Resetting to 1 to avoid almost certain Apache failure."); ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "Please read the documentation."); ++ ap_daemons_min_free = 1; ++ } ++ + return NULL; +} + @@ -1740,88 +1580,76 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + if (err != NULL) { + return err; + } -+ if (!strcasecmp(cmd->cmd->name, "MaxClients")) { -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, APLOGNO(00188) -+ "MaxClients is deprecated, use MaxRequestWorkers " -+ "instead."); -+ } ++ + ap_daemons_limit = atoi(arg); ++ if (ap_daemons_limit > server_limit) { ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: MaxClients of %d exceeds ServerLimit value " ++ "of %d servers,", ap_daemons_limit, server_limit); ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ " lowering MaxClients to %d. To increase, please " ++ "see the ServerLimit", server_limit); ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ " directive."); ++ ap_daemons_limit = server_limit; ++ } ++ else if (ap_daemons_limit < 1) { ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: Require MaxClients > 0, setting to 1"); ++ ap_daemons_limit = 1; ++ } + return NULL; +} + +static const char *set_server_limit (cmd_parms *cmd, void *dummy, const char *arg) +{ ++ int tmp_server_limit; ++ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + -+ server_limit = atoi(arg); ++ tmp_server_limit = atoi(arg); ++ /* you cannot change ServerLimit across a restart; ignore ++ * any such attempts ++ */ ++ if (first_server_limit && ++ tmp_server_limit != server_limit) { ++ /* how do we log a message? the error log is a bit bucket at this ++ * point; we'll just have to set a flag so that ap_mpm_run() ++ * logs a warning later ++ */ ++ changed_limit_at_restart = 1; ++ return NULL; ++ } ++ server_limit = tmp_server_limit; ++ ++ if (server_limit > MAX_SERVER_LIMIT) { ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: ServerLimit of %d exceeds compile time limit " ++ "of %d servers,", server_limit, MAX_SERVER_LIMIT); ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ " lowering ServerLimit to %d.", MAX_SERVER_LIMIT); ++ server_limit = MAX_SERVER_LIMIT; ++ } ++ else if (server_limit < 1) { ++ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, ++ "WARNING: Require ServerLimit > 0, setting to 1"); ++ server_limit = 1; ++ } + return NULL; +} + +static const char *assign_user_id (cmd_parms *cmd, void *ptr, const char *user_name, const char *group_name) +{ + itk_per_dir_conf *dconf = (itk_per_dir_conf *) ptr; -+ -+ const char *err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS); -+ if (err) { -+ return err; -+ } -+ + dconf->username = apr_pstrdup(cmd->pool, user_name); + dconf->uid = ap_uname2id(user_name); + dconf->gid = ap_gname2id(group_name); + return NULL; +} + -+static const char *assign_user_id_expr (cmd_parms *cmd, void *ptr, const char *user_name_expr) -+{ -+ itk_per_dir_conf *dconf = (itk_per_dir_conf *) ptr; -+ -+ const char *err; -+ -+ err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS); -+ if (err) { -+ return err; -+ } -+ -+ dconf->uid_expr = ap_expr_parse_cmd_mi(cmd, -+ user_name_expr, -+ AP_EXPR_FLAG_STRING_RESULT, -+ &err, -+ NULL, -+ AP_CORE_MODULE_INDEX); -+ if (err) { -+ return err; -+ } -+ -+ return NULL; -+} -+ -+static const char *assign_group_id_expr (cmd_parms *cmd, void *ptr, const char *group_name_expr) -+{ -+ itk_per_dir_conf *dconf = (itk_per_dir_conf *) ptr; -+ -+ const char *err; -+ -+ err = ap_check_cmd_context(cmd, NOT_IN_HTACCESS); -+ if (err) { -+ return err; -+ } -+ -+ dconf->gid_expr = ap_expr_parse_cmd_mi(cmd, -+ group_name_expr, -+ AP_EXPR_FLAG_STRING_RESULT, -+ &err, -+ NULL, -+ AP_CORE_MODULE_INDEX); -+ if (err) { -+ return err; -+ } -+ return NULL; -+} -+ +static const char *set_max_clients_vhost (cmd_parms *cmd, void *dummy, const char *arg) +{ + itk_server_conf *sconf = @@ -1852,6 +1680,7 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c +} + +static const command_rec itk_cmds[] = { ++UNIX_DAEMON_COMMANDS, +LISTEN_COMMANDS, +AP_INIT_TAKE1("StartServers", set_daemons_to_start, NULL, RSRC_CONF, + "Number of child processes launched at server startup"), @@ -1860,17 +1689,11 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c +AP_INIT_TAKE1("MaxSpareServers", set_max_free_servers, NULL, RSRC_CONF, + "Maximum number of idle children"), +AP_INIT_TAKE1("MaxClients", set_max_clients, NULL, RSRC_CONF, -+ "Deprecated name of MaxRequestWorkers"), -+AP_INIT_TAKE1("MaxRequestWorkers", set_max_clients, NULL, RSRC_CONF, + "Maximum number of children alive at the same time"), +AP_INIT_TAKE1("ServerLimit", set_server_limit, NULL, RSRC_CONF, -+ "Maximum value of MaxRequestWorkers for this run of Apache"), ++ "Maximum value of MaxClients for this run of Apache"), +AP_INIT_TAKE2("AssignUserID", assign_user_id, NULL, RSRC_CONF|ACCESS_CONF, + "Tie a virtual host to a specific child process."), -+AP_INIT_RAW_ARGS("AssignUserIDExpr", assign_user_id_expr, NULL, RSRC_CONF|ACCESS_CONF, -+ "Choose user ID given an expression. Will override AssignUserID."), -+AP_INIT_RAW_ARGS("AssignGroupIDExpr", assign_group_id_expr, NULL, RSRC_CONF|ACCESS_CONF, -+ "Choose group ID given an expression. Will override AssignUserID."), +AP_INIT_TAKE1("MaxClientsVHost", set_max_clients_vhost, NULL, RSRC_CONF, + "Maximum number of children alive at the same time for this virtual host."), +AP_INIT_TAKE1("NiceValue", set_nice_value, NULL, RSRC_CONF|ACCESS_CONF, @@ -1885,7 +1708,6 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + itk_per_dir_conf *c = (itk_per_dir_conf *) + apr_pcalloc(p, sizeof(itk_per_dir_conf)); + c->uid = c->gid = -1; -+ c->uid_expr = c->gid_expr = NULL; + c->nice_value = UNSET_NICE_VALUE; + return c; +} @@ -1899,24 +1721,14 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + itk_per_dir_conf *child = (itk_per_dir_conf *) child_ptr; + + if (child->username != NULL) { -+ c->username = child->username; ++ c->username = apr_pstrdup(p, child->username); + c->uid = child->uid; + c->gid = child->gid; -+ } else { -+ c->username = parent->username; ++ } else if (parent->username != NULL) { ++ c->username = apr_pstrdup(p, parent->username); + c->uid = parent->uid; + c->gid = parent->gid; + } -+ if (child->uid_expr != NULL) { -+ c->uid_expr = child->uid_expr; -+ } else { -+ c->uid_expr = parent->uid_expr; -+ } -+ if (child->gid_expr != NULL) { -+ c->gid_expr = child->gid_expr; -+ } else { -+ c->gid_expr = parent->gid_expr; -+ } + if (child->nice_value != UNSET_NICE_VALUE) { + c->nice_value = child->nice_value; + } else { @@ -1934,9 +1746,9 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + return c; +} + -+AP_DECLARE_MODULE(mpm_itk) = { ++module AP_MODULE_DECLARE_DATA mpm_itk_module = { + MPM20_MODULE_STUFF, -+ NULL, /* hook to run before apache parses args */ ++ ap_mpm_rewrite_args, /* hook to run before apache parses args */ + itk_create_dir_config, /* create per-directory config structure */ + itk_merge_dir_config, /* merge per-directory config structures */ + itk_create_server_config, /* create per-server config structure */ @@ -1944,11 +1756,80 @@ Index: httpd-2.4.2/server/mpm/itk/itk.c + itk_cmds, /* command apr_table_t */ + itk_hooks, /* register hooks */ +}; -Index: httpd-2.4.2/server/mpm/itk/mpm_default.h -=================================================================== --- /dev/null -+++ httpd-2.4.2/server/mpm/itk/mpm_default.h -@@ -0,0 +1,57 @@ ++++ server/mpm/experimental/itk/mpm.h +@@ -0,0 +1,68 @@ ++/* Licensed to the Apache Software Foundation (ASF) under one or more ++ * contributor license agreements. See the NOTICE file distributed with ++ * this work for additional information regarding copyright ownership. ++ * The ASF licenses this file to You under the Apache License, Version 2.0 ++ * (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ * ++ * Portions copyright 2005-2009 Steinar H. Gunderson . ++ * Licensed under the same terms as the rest of Apache. ++ * ++ * Portions copyright 2008 Knut Auvor Grythe . ++ * Licensed under the same terms as the rest of Apache. ++ */ ++ ++/** ++ * @file itk/mpm.h ++ * @brief ITK MPM (setuid per-vhost, no threads) ++ * ++ * @defgroup APACHE_MPM_ITK Apache ITK ++ * @ingroup APACHE_MPM APACHE_OS_UNIX ++ * @{ ++ */ ++ ++#include "httpd.h" ++#include "mpm_default.h" ++#include "scoreboard.h" ++#include "unixd.h" ++ ++#ifndef APACHE_MPM_ITK_H ++#define APACHE_MPM_ITK_H ++ ++#define ITK_MPM ++ ++#define MPM_NAME "ITK" ++ ++#define AP_MPM_WANT_RECLAIM_CHILD_PROCESSES ++#define AP_MPM_WANT_WAIT_OR_TIMEOUT ++#define AP_MPM_WANT_PROCESS_CHILD_STATUS ++#define AP_MPM_WANT_SET_PIDFILE ++#define AP_MPM_WANT_SET_SCOREBOARD ++#define AP_MPM_WANT_SET_LOCKFILE ++#define AP_MPM_WANT_SET_MAX_REQUESTS ++#define AP_MPM_WANT_SET_COREDUMPDIR ++#define AP_MPM_WANT_SET_ACCEPT_LOCK_MECH ++#define AP_MPM_WANT_SIGNAL_SERVER ++#define AP_MPM_WANT_SET_MAX_MEM_FREE ++#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER ++#define AP_MPM_WANT_SET_GRACEFUL_SHUTDOWN ++#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK ++ ++#define AP_MPM_USES_POD 1 ++#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid) ++#define MPM_NOTE_CHILD_KILLED(i) (MPM_CHILD_PID(i) = 0) ++#define MPM_ACCEPT_FUNC unixd_accept ++ ++extern int ap_threads_per_child; ++extern int ap_max_daemons_limit; ++extern server_rec *ap_server_conf; ++#endif /* APACHE_MPM_ITK_H */ ++/** @} */ +--- /dev/null ++++ server/mpm/experimental/itk/mpm_default.h +@@ -0,0 +1,80 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. @@ -1964,9 +1845,9 @@ Index: httpd-2.4.2/server/mpm/itk/mpm_default.h + * See the License for the specific language governing permissions and + * limitations under the License. + * -+ * Portions copyright 2005-2012 Steinar H. Gunderson . ++ * Portions copyright 2005-2009 Steinar H. Gunderson . + * Licensed under the same terms as the rest of Apache. -+ * ++ * + * Portions copyright 2008 Knut Auvor Grythe . + * Licensed under the same terms as the rest of Apache. + */ @@ -1975,8 +1856,7 @@ Index: httpd-2.4.2/server/mpm/itk/mpm_default.h + * @file itk/mpm_default.h + * @brief ITK MPM defaults + * -+ * @defgroup APACHE_MPM_ITK Apache ITK -+ * @ingroup APACHE_INTERNAL ++ * @addtogroup APACHE_MPM_ITK + * @{ + */ + @@ -2004,48 +1884,111 @@ Index: httpd-2.4.2/server/mpm/itk/mpm_default.h +#define DEFAULT_MIN_FREE_DAEMON 5 +#endif + ++/* File used for accept locking, when we use a file */ ++#ifndef DEFAULT_LOCKFILE ++#define DEFAULT_LOCKFILE DEFAULT_REL_RUNTIMEDIR "/accept.lock" ++#endif ++ ++/* Where the main/parent process's pid is logged */ ++#ifndef DEFAULT_PIDLOG ++#define DEFAULT_PIDLOG DEFAULT_REL_RUNTIMEDIR "/httpd.pid" ++#endif ++ ++/* ++ * Interval, in microseconds, between scoreboard maintenance. ++ */ ++#ifndef SCOREBOARD_MAINTENANCE_INTERVAL ++#define SCOREBOARD_MAINTENANCE_INTERVAL 1000000 ++#endif ++ ++/* Number of requests to try to handle in a single process. If <= 0, ++ * the children don't die off. ++ */ ++#ifndef DEFAULT_MAX_REQUESTS_PER_CHILD ++#define DEFAULT_MAX_REQUESTS_PER_CHILD 10000 ++#endif ++ +#endif /* AP_MPM_DEFAULT_H */ +/** @} */ -Index: httpd-2.4.2/server/mpm/config2.m4 -=================================================================== ---- httpd-2.4.2.orig/server/mpm/config2.m4 -+++ httpd-2.4.2/server/mpm/config2.m4 +--- server/mpm/config.m4.orig ++++ server/mpm/config.m4 @@ -1,7 +1,7 @@ - AC_MSG_CHECKING(which MPM to use by default) + AC_MSG_CHECKING(which MPM to use) AC_ARG_WITH(mpm, - APACHE_HELP_STRING(--with-mpm=MPM,Choose the process model for Apache to use by default. -- MPM={event|worker|prefork|winnt} -+ MPM={event|worker|prefork|winnt|itk} - This will be statically linked as the only available MPM unless - --enable-mpms-shared is also specified. - ),[ -@@ -66,6 +66,9 @@ for i in $ap_enabled_mpms; do + APACHE_HELP_STRING(--with-mpm=MPM,Choose the process model for Apache to use. +- MPM={beos|event|worker|prefork|mpmt_os2|winnt}),[ ++ MPM={beos|event|worker|prefork|mpmt_os2|winnt|itk}),[ + APACHE_MPM=$withval + ],[ + if test "x$APACHE_MPM" = "x"; then +@@ -23,7 +23,7 @@ ap_mpm_is_threaded () + + ap_mpm_is_experimental () + { +- if test "$apache_cv_mpm" = "event" ; then ++ if test "$apache_cv_mpm" = "event" -o "$apache_cv_mpm" = "itk" ; then + return 0 else - AC_MSG_ERROR([MPM $i is not supported on this platform.]) - fi -+ if test "$i" = "itk" ; then -+ AC_CHECK_LIB(cap, cap_init) -+ fi - done - - if test $mpm_build = "shared"; then -Index: httpd-2.4.2/modules/arch/unix/config5.m4 -=================================================================== ---- httpd-2.4.2.orig/modules/arch/unix/config5.m4 -+++ httpd-2.4.2/modules/arch/unix/config5.m4 -@@ -3,6 +3,7 @@ APACHE_MODPATH_INIT(arch/unix) - - if ap_mpm_is_enabled "worker" \ - || ap_mpm_is_enabled "event" \ -+ || ap_mpm_is_enabled "itk" \ - || ap_mpm_is_enabled "prefork"; then - unixd_mods_enable=yes + return 1 +@@ -66,6 +66,11 @@ if ap_mpm_is_experimental; then else -Index: httpd-2.4.2/server/request.c -=================================================================== ---- httpd-2.4.2.orig/server/request.c -+++ httpd-2.4.2/server/request.c -@@ -69,6 +69,7 @@ APR_HOOK_STRUCT( + MPM_SUBDIR_NAME=$MPM_NAME + fi ++ ++if test "$apache_cv_mpm" = "itk" ; then ++ AC_CHECK_LIB(cap, cap_init) ++fi ++ + MPM_DIR=server/mpm/$MPM_SUBDIR_NAME + MPM_LIB=$MPM_DIR/lib${MPM_NAME}.la + +--- include/http_request.h.orig ++++ include/http_request.h +@@ -12,6 +12,12 @@ + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. ++ * ++ * Portions copyright 2005-2009 Steinar H. Gunderson . ++ * Licensed under the same terms as the rest of Apache. ++ * ++ * Portions copyright 2008 Knut Auvor Grythe . ++ * Licensed under the same terms as the rest of Apache. + */ + + /** +@@ -350,6 +356,15 @@ AP_DECLARE_HOOK(int,auth_checker,(reques + */ + AP_DECLARE_HOOK(void,insert_filter,(request_rec *r)) + ++/** ++ * This hook allows modules to affect the request immediately after the ++ * per-directory configuration for the request has been generated. This allows ++ * modules to make decisions based upon the current directory configuration ++ * @param r The current request ++ * @return OK or DECLINED ++ */ ++AP_DECLARE_HOOK(int,post_perdir_config,(request_rec *r)) ++ + AP_DECLARE(int) ap_location_walk(request_rec *r); + AP_DECLARE(int) ap_directory_walk(request_rec *r); + AP_DECLARE(int) ap_file_walk(request_rec *r); +--- server/request.c.orig ++++ server/request.c +@@ -12,6 +12,12 @@ + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. ++ * ++ * Portions copyright 2005-2009 Steinar H. Gunderson . ++ * Licensed under the same terms as the rest of Apache. ++ * ++ * Portions copyright 2008 Knut Auvor Grythe . ++ * Licensed under the same terms as the rest of Apache. + */ + + /* +@@ -61,6 +67,7 @@ APR_HOOK_STRUCT( APR_HOOK_LINK(auth_checker) APR_HOOK_LINK(insert_filter) APR_HOOK_LINK(create_request) @@ -2053,35 +1996,17 @@ Index: httpd-2.4.2/server/request.c ) AP_IMPLEMENT_HOOK_RUN_FIRST(int,translate_name, -@@ -91,10 +92,26 @@ AP_IMPLEMENT_HOOK_VOID(insert_filter, (r +@@ -80,6 +87,8 @@ AP_IMPLEMENT_HOOK_RUN_FIRST(int,auth_che + AP_IMPLEMENT_HOOK_VOID(insert_filter, (request_rec *r), (r)) AP_IMPLEMENT_HOOK_RUN_ALL(int, create_request, (request_rec *r), (r), OK, DECLINED) - -+/** -+ * This hook allows modules to affect the request immediately after the -+ * per-directory configuration for the request has been generated. This allows -+ * modules to make decisions based upon the current directory configuration -+ * -+ * This hook is private to mpm-itk, so it is not exposed in http_request.h. -+ * -+ * @param r The current request -+ * @return OK or DECLINED -+ */ -+AP_DECLARE_HOOK(int,post_perdir_config,(request_rec *r)) -+ +AP_IMPLEMENT_HOOK_RUN_ALL(int,post_perdir_config, + (request_rec *r), (r), OK, DECLINED) -+ - static int auth_internal_per_conf = 0; - static int auth_internal_per_conf_hooks = 0; - static int auth_internal_per_conf_providers = 0; -+extern AP_DECLARE_DATA int ap_running_under_mpm_itk; - static int decl_die(int status, const char *phase, request_rec *r) - { -@@ -191,6 +208,13 @@ AP_DECLARE(int) ap_process_request_inter - r->log = d->log; + static int decl_die(int status, char *phase, request_rec *r) +@@ -158,6 +167,13 @@ AP_DECLARE(int) ap_process_request_inter + return access_status; } + /* First chance to handle the request after per-directory configuration is @@ -2094,66 +2019,3 @@ Index: httpd-2.4.2/server/request.c /* Only on the main request! */ if (r->main == NULL) { if ((access_status = ap_run_header_parser(r))) { -@@ -1093,6 +1117,16 @@ AP_DECLARE(int) ap_directory_walk(reques - break; - } - else if (APR_STATUS_IS_EACCES(rv)) { -+ /* See the corresponding section in server/config.c for the rationale -+ * behind this logic. -+ */ -+ if (ap_running_under_mpm_itk && r->main == NULL && getuid() != 0) { -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, -+ "Access to %s denied, closing connection.", -+ r->filename); -+ ap_lingering_close(r->connection); -+ exit(0); -+ } - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(00035) - "access to %s denied (filesystem path '%s') " - "because search permissions are missing on a " -Index: httpd-2.4.2/server/config.c -=================================================================== ---- httpd-2.4.2.orig/server/config.c -+++ httpd-2.4.2/server/config.c -@@ -69,6 +69,8 @@ AP_DECLARE_DATA apr_array_header_t *ap_s - - AP_DECLARE_DATA ap_directive_t *ap_conftree = NULL; - -+AP_DECLARE_DATA int ap_running_under_mpm_itk = 0; -+ - APR_HOOK_STRUCT( - APR_HOOK_LINK(header_parser) - APR_HOOK_LINK(pre_config) -@@ -2129,6 +2131,32 @@ AP_CORE_DECLARE(int) ap_parse_htaccess(a - else { - if (!APR_STATUS_IS_ENOENT(status) - && !APR_STATUS_IS_ENOTDIR(status)) { -+ /* -+ * If we are in a persistent connection, we might end up in a state -+ * where we can no longer read .htaccess files because we have already -+ * setuid(). This can either be because the previous request was for -+ * another vhost (basically the same problem as when setuid() fails in -+ * itk.c), or it can be because a .htaccess file is readable only by -+ * root. -+ * -+ * In any case, we don't want to give out a 403, since the request has -+ * a very real chance of succeeding on a fresh connection (where -+ * presumably uid=0). Thus, we give up serving the request on this -+ * TCP connection, and do a hard close of the socket. As long as we're -+ * in a persistent connection (and there _should_ not be a way this -+ * would happen on the first request in a connection, save for subrequests, -+ * which we special-case), this is allowed, as it is what happens on -+ * a timeout. The browser will simply open a new connection and try -+ * again (there's of course a performance hit, though, both due to -+ * the new connection setup and the fork() of a new server child). -+ */ -+ if (ap_running_under_mpm_itk && r->main == NULL && getuid() != 0) { -+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, status, r, -+ "Couldn't read %s, closing connection.", -+ filename); -+ ap_lingering_close(r->connection); -+ exit(0); -+ } - ap_log_rerror(APLOG_MARK, APLOG_CRIT, status, r, APLOGNO(00529) - "%s pcfg_openfile: unable to check htaccess file, " - "ensure it is readable and that '%s' " diff --git a/apache2.changes b/apache2.changes index 9164e2a..11bf6f7 100644 --- a/apache2.changes +++ b/apache2.changes @@ -1,28 +1,3 @@ -------------------------------------------------------------------- -Wed Aug 1 04:10:13 UTC 2012 - crrodriguez@opensuse.org - -- Fix factory-auto (aka r2dbag) complains about URL. -- Provide a symlink for apxs2 new location otherwise - all buggy spec files of external modules will break. - -------------------------------------------------------------------- -Wed Aug 1 02:21:34 UTC 2012 - crrodriguez@opensuse.org - -- BuildRequire xz explicitly, fix build in !Factory -- Drop more old, unused patches - -------------------------------------------------------------------- -Wed Aug 1 01:14:35 UTC 2012 - crrodriguez@opensuse.org - -- Upgrade to apache 2.4.2 -** ATTENTION, before installing this update YOU MUST -READ http://httpd.apache.org/docs/2.4/upgrading.html -CAREFULLY otherwise your server will most likely -fail to start due to backward incompatible changes. - -* You can read the huge complete list of changes - at http://httpd.apache.org/docs/2.4/new_features_2_4.html - ------------------------------------------------------------------- Wed Jul 25 11:32:34 UTC 2012 - saschpe@suse.de diff --git a/apache2.spec b/apache2.spec index f36750f..6b7bf9b 100644 --- a/apache2.spec +++ b/apache2.spec @@ -25,7 +25,6 @@ BuildRequires: libapr1-devel >= 1.4.2 BuildRequires: openldap2-devel BuildRequires: openssl-devel BuildRequires: pcre-devel -BuildRequires: xz BuildRequires: zlib-devel %if %{?suse_version:1}0 && 0%{?sles_version} == 9 BuildRequires: libcap @@ -48,7 +47,7 @@ BuildRequires: expat-devel %define pname apache2 %define vers 2 %define httpd httpd2 -%define apache_mmn %(test -s %{S:0} && { echo -n apache_mmn_; xzcat %{S:0} | awk '/^#define MODULE_MAGIC_NUMBER_MAJOR/ {printf "%d", $3}'; }) +%define apache_mmn %(test -s %{S:0} && { echo -n apache_mmn_; bzcat %{S:0} | awk '/^#define MODULE_MAGIC_NUMBER_MAJOR/ {printf "%d", $3}'; }) %define default_mpm prefork %{!?prefork:%define prefork 1} %{!?worker:%define worker 1} @@ -75,13 +74,14 @@ BuildRequires: expat-devel # "Server:" header %define VENDOR SUSE %define platform_string Linux/%VENDOR -%define realver 2.4.2 -Version: 2.4.2 +%define realver 2.2.22 +Version: 2.2.22 Release: 0 #Source0: http://www.apache.org/dist/httpd-%{version}.tar.bz2 -Source0: httpd-%{realver}.tar.xz +Source0: http://httpd.apache.org/dev/dist/httpd-%{realver}.tar.bz2 # Add file to take mtime from it in prep section Source1: apache2.changes +Source5: http://httpd.apache.org/dev/dist/httpd-%{realver}.tar.bz2.asc Source6: 60C5442D.key Source10: SUSE-NOTICE Source11: rc.%{pname} @@ -139,8 +139,14 @@ Patch66: httpd-2.0.54-envvars.dif Patch67: httpd-2.2.0-apxs-a2enmod.dif Patch68: httpd-2.x.x-logresolve.patch Patch69: httpd-2.2.x-bnc690734.patch -Patch100: apache2.4-mpm-itk-2.4.2-01.patch +Patch100: apache2.2-mpm-itk-20090414-00.patch Patch101: httpd-2.2.19-linux3.patch +Patch102: httpd-keepalivetimeout-millisecs.patch +Patch104: httpd-mod_deflate_head.patch +Patch105: ssl-mode-release-buffers.patch +Patch106: httpd-2.2.x-CVE-2011-3368-server_protocl_c.diff +# PATCH-FIX-UPSTREAM https://issues.apache.org/bugzilla/show_bug.cgi?id=52623 +Patch107: httpd-new_pcre.patch # PATCH-FEATURE-UPSTREAM apache2-mod_ssl_npn.patch dimstar@opensuse.org -- Add npn support to mod_ssl (needed for spdy) Patch108: apache2-mod_ssl_npn.patch Provides: apache2(mod_ssl+npn) @@ -356,15 +362,22 @@ to administrators of web servers in general. # %setup -q -n httpd-%{realver} %patch2 -p1 -%patch23 +%patch23 -p1 %patch65 -p1 -%patch66 +%patch66 -p1 %patch67 -p1 %patch68 -p1 %patch69 -%patch100 -p1 +%patch100 %patch101 -%patch108 -p1 +%patch102 +%patch104 +%patch105 +%patch106 +%if 0%{?suse_version} >= 1220 +%patch107 +%endif +%patch108 # cat $RPM_SOURCE_DIR/SUSE-NOTICE >> NOTICE @@ -467,8 +480,7 @@ function configure { --with-suexec-userdir=%{userdir} \ --with-suexec-uidmin=96 \ --with-suexec-gidmin=96 \ - --with-suexec-safepath=%{suexec_safepath} \ - --disable-heartbeat + --with-suexec-safepath=%{suexec_safepath} } # @@ -725,21 +737,17 @@ pushd $RPM_BUILD_ROOT/%{_mandir} mv $i ${i%.*}%{vers}.${i#*.*.} || true done popd - -pushd $RPM_BUILD_ROOT/%{_bindir} -for i in ab dbmmanage htdbm htdigest htpasswd logresolve;do -mv $i ${i}%{vers} || true -done -popd - pushd $RPM_BUILD_ROOT/%{_sbindir} - for i in rotatelogs suexec; do + for i in ab dbmmanage htdbm htdigest htpasswd logresolve rotatelogs suexec; do mv $i ${i}%{vers} || true done mv apachectl apachectl.tmp; mv apachectl.tmp apache%{vers}ctl + for i in dbmmanage htdbm htdigest htpasswd; do + mv ${i}%{vers} ../bin/ + done popd # fix up apxs -pushd $RPM_BUILD_ROOT/%{_bindir} +pushd $RPM_BUILD_ROOT/%{_sbindir} for mpm in %{mpms_to_build}; do cat <<-EOT_ED | ed -s apxs H @@ -768,7 +776,7 @@ popd install -d $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/ install -m 644 %{S:49} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/%{name} install -m 644 %{S:50} $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/SuSEfirewall2.d/services/%{name}-ssl -ln -sf %{_bindir}/apxs%{vers} %{buildroot}%{_sbindir} + # # filelists # @@ -777,7 +785,7 @@ for mpm in %{mpms_to_build}; do echo %dir %{_libdir}/%{pname}-$mpm >> filelist ( echo %dir %{includedir}-$mpm - echo %{_bindir}/apxs%{vers}-$mpm + echo %{_sbindir}/apxs%{vers}-$mpm ) >> filelist-devel done find $RPM_BUILD_ROOT/%{includedir}/.. -type f -o -type l \ @@ -819,7 +827,6 @@ sed -e 's+/usr/%_lib+'$RPM_BUILD_ROOT'/usr/%_lib+' \ -e 's+%{sysconfdir}+'$RPM_BUILD_ROOT'%{sysconfdir}+' \ -e 's+%{datadir}+'$RPM_BUILD_ROOT'%{datadir}+' \ -e 's+\.conf$+&.test+' \ - -e 's+/var/log+'$RPM_BUILD_ROOT'/var/log+' \ httpd.conf > httpd.conf.test sed -e 's+%{sysconfdir}+'$RPM_BUILD_ROOT'%{sysconfdir}+' \ default-server.conf > default-server.conf.test @@ -966,7 +973,6 @@ mv $RPM_BUILD_ROOT/%{sysconfdir}/original . %dir %{_prefix}/share/%{pname} %dir %{installbuilddir} %dir %{includedir} -%{_bindir}/apxs%{vers} %{_sbindir}/apxs%{vers} %files doc @@ -993,8 +999,6 @@ mv $RPM_BUILD_ROOT/%{sysconfdir}/original . %doc %{_mandir}/man?/logresolve%{vers}.?.* %doc %{_mandir}/man?/rotatelogs%{vers}.?.* %doc %{_mandir}/man?/suexec%{vers}.?.* -%{_sbindir}/fcgistarter -%{_mandir}/man8/fcgistarter2.8.* %{_bindir}/check_forensic%{vers} %{_bindir}/dbmmanage%{vers} %{_bindir}/gensslcert @@ -1002,10 +1006,10 @@ mv $RPM_BUILD_ROOT/%{sysconfdir}/original . %{_bindir}/htdigest%{vers} %{_bindir}/htpasswd%{vers} %{_bindir}/split-logfile%{vers} -%{_bindir}/ab%{vers} -%{_bindir}/httxt2dbm +%{_sbindir}/ab%{vers} +%{_sbindir}/httxt2dbm %{_sbindir}/logresolve.pl%{vers} -%{_bindir}/logresolve%{vers} +%{_sbindir}/logresolve%{vers} %{_sbindir}/rotatelogs%{vers} %verify(not mode) %attr(0755,root,root) %_sbindir/suexec2 %if %prefork diff --git a/httpd-2.0.54-envvars.dif b/httpd-2.0.54-envvars.dif index 7e0ea8e..7c1f3fe 100644 --- a/httpd-2.0.54-envvars.dif +++ b/httpd-2.0.54-envvars.dif @@ -1,17 +1,11 @@ ---- support/envvars-std.in.orig -+++ support/envvars-std.in -@@ -18,11 +18,9 @@ - # +diff -uNr httpd-2.0.54.orig/support/envvars-std.in httpd-2.0.54/support/envvars-std.in +--- httpd-2.0.54.orig/support/envvars-std.in 2005-02-04 21:21:18.000000000 +0100 ++++ httpd-2.0.54/support/envvars-std.in 2005-10-07 13:56:49.223546288 +0200 +@@ -19,6 +19,6 @@ # This file is generated from envvars-std.in # --if test "x$@SHLIBPATH_VAR@" != "x" ; then -- @SHLIBPATH_VAR@="@exp_libdir@:$@SHLIBPATH_VAR@" --else -- @SHLIBPATH_VAR@="@exp_libdir@" --fi -+ +-@SHLIBPATH_VAR@="@exp_libdir@:$@SHLIBPATH_VAR@" +@SHLIBPATH_VAR@="@exp_libdir@${@SHLIBPATH_VAR@+:$@SHLIBPATH_VAR@}" -+ export @SHLIBPATH_VAR@ # @OS_SPECIFIC_VARS@ diff --git a/httpd-2.1.9-apachectl.dif b/httpd-2.1.9-apachectl.dif index abe1651..3d25d4c 100644 --- a/httpd-2.1.9-apachectl.dif +++ b/httpd-2.1.9-apachectl.dif @@ -1,6 +1,7 @@ ---- support/apachectl.in.orig -+++ support/apachectl.in -@@ -42,17 +42,32 @@ ARGV="$@" +diff -uNr httpd-2.1.3-alpha.orig/support/apachectl.in httpd-2.1.3-alpha/support/apachectl.in +--- httpd-2.1.3-alpha.orig/support/apachectl.in 2005-02-04 21:28:49.000000000 +0100 ++++ httpd-2.1.3-alpha/support/apachectl.in 2005-02-25 02:52:49.203566813 +0100 +@@ -41,17 +41,32 @@ # -------------------- -------------------- # # the path to your httpd binary, including options if necessary @@ -35,16 +36,16 @@ # # the URL to your server's mod_status status page. If you do not # have one, then status and fullstatus will not work. -@@ -78,7 +93,7 @@ fi +@@ -77,7 +92,7 @@ - case $ACMD in + case $ARGV in start|stop|restart|graceful|graceful-stop) - $HTTPD -k $ARGV + $HTTPD ${httpd_conf+-f $httpd_conf} -k $ARGV ERROR=$? ;; startssl|sslstart|start-SSL) -@@ -88,7 +103,7 @@ startssl|sslstart|start-SSL) +@@ -87,7 +102,7 @@ ERROR=2 ;; configtest) @@ -53,3 +54,12 @@ ERROR=$? ;; status) +@@ -97,7 +112,7 @@ + $LYNX $STATUSURL + ;; + *) +- $HTTPD $ARGV ++ $HTTPD ${httpd_conf+-f $httpd_conf} $ARGV + ERROR=$? + esac + diff --git a/httpd-2.2.22.tar.bz2 b/httpd-2.2.22.tar.bz2 new file mode 100644 index 0000000..01c3754 --- /dev/null +++ b/httpd-2.2.22.tar.bz2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dcdc9f1dc722f84798caf69d69dca78daa5e09a4269060045aeca7e4f44cb231 +size 5378934 diff --git a/httpd-2.2.22.tar.bz2.asc b/httpd-2.2.22.tar.bz2.asc new file mode 100644 index 0000000000000000000000000000000000000000000000000000000000000000..b8ef53be8e5a843edf4fed8cf0b458cac42076d48c92ba03797aa588c6e5719f GIT binary patch literal 678 zcmV;X0$KeZiwFP!0000018tMHlA~Av0CT=V;cZbf=;7I_3-Cq=FF<5~5Kef{*YE7b z*I|cU)n8vfaH6al7fZG-t|}X>_i)6&`U~>2aVop^_eE|OOTMh&8~XT zRWq$a6L}4H+eCuZVQtI+0W%e&34hvECoYfUJspDN6>KNHPF#23zB+Ad-=WSdSNd@0 zYiK^gLBg#;0YQ3#y{v9tBCtDb4TOejgM-t1>Iq{s!b2wP4XxjX`K>}6-EUaLhe5Jz zfk@o}@;-7qjiZykV)Bu6&7vHwTQ&1B6|)n~!Sre2|{%J6|%$phKV~O0Y?Z?bd z`OgdFKBk9O8PjItp5+FpN+y7lehjAC#K>5Mz0J6lFQCNyjAU9k!4{Ibm%=RZTyT44 z%;z&Mb089!!-*Lw^yuuLoRPggIq?E8F$9B;CCdnDPK&^jy)9QC)%Nm9_2G@I7Qb=T z&EPBanPud@MhuGQ?}hFC*Iw7RNW!_#+QbQ&O3UiwZg6d|$304KRpq5uE@ literal 0 HcmV?d00001 diff --git a/httpd-2.2.x-CVE-2011-3368-server_protocl_c.diff b/httpd-2.2.x-CVE-2011-3368-server_protocl_c.diff new file mode 100644 index 0000000..63b9b6f --- /dev/null +++ b/httpd-2.2.x-CVE-2011-3368-server_protocl_c.diff @@ -0,0 +1,68 @@ +diff -rNU 20 ../httpd-2.2.21-o/server/protocol.c ./server/protocol.c +--- ../httpd-2.2.21-o/server/protocol.c 2011-05-07 13:39:29.000000000 +0200 ++++ ./server/protocol.c 2011-10-07 17:10:46.000000000 +0200 +@@ -623,40 +623,64 @@ + + #if 0 + /* XXX If we want to keep track of the Method, the protocol module should do + * it. That support isn't in the scoreboard yet. Hopefully next week + * sometime. rbb */ + ap_update_connection_status(AP_CHILD_THREAD_FROM_ID(conn->id), "Method", + r->method); + #endif + + uri = ap_getword_white(r->pool, &ll); + + /* Provide quick information about the request method as soon as known */ + + r->method_number = ap_method_number_of(r->method); + if (r->method_number == M_GET && r->method[0] == 'H') { + r->header_only = 1; + } + + ap_parse_uri(r, uri); + ++/* ++ https://svn.apache.org/viewvc/httpd/httpd/trunk/server/protocol.c?r1=1178566&r2=1179239&pathrev=1179239&view=patch ++ This is the fix for CVE-2011-3368; via bnc#722545. ++ */ ++ ++ /* RFC 2616: ++ * Request-URI = "*" | absoluteURI | abs_path | authority ++ * ++ * authority is a special case for CONNECT. If the request is not ++ * using CONNECT, and the parsed URI does not have scheme, and ++ * it does not begin with '/', and it is not '*', then, fail ++ * and give a 400 response. */ ++ if (r->method_number != M_CONNECT ++ && !r->parsed_uri.scheme ++ && uri[0] != '/' ++ && !(uri[0] == '*' && uri[1] == '\0')) { ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, ++ "invalid request-URI %s", uri); ++ r->args = NULL; ++ r->hostname = NULL; ++ r->status = HTTP_BAD_REQUEST; ++ r->uri = apr_pstrdup(r->pool, uri); ++ } ++ + if (ll[0]) { + r->assbackwards = 0; + pro = ll; + len = strlen(ll); + } else { + r->assbackwards = 1; + pro = "HTTP/0.9"; + len = 8; + } + r->protocol = apr_pstrmemdup(r->pool, pro, len); + + /* XXX ap_update_connection_status(conn->id, "Protocol", r->protocol); */ + + /* Avoid sscanf in the common case */ + if (len == 8 + && pro[0] == 'H' && pro[1] == 'T' && pro[2] == 'T' && pro[3] == 'P' + && pro[4] == '/' && apr_isdigit(pro[5]) && pro[6] == '.' + && apr_isdigit(pro[7])) { + r->proto_num = HTTP_VERSION(pro[5] - '0', pro[7] - '0'); + } diff --git a/httpd-2.2.x-bnc690734.patch b/httpd-2.2.x-bnc690734.patch index 87ce840..68e142a 100644 --- a/httpd-2.2.x-bnc690734.patch +++ b/httpd-2.2.x-bnc690734.patch @@ -1,6 +1,7 @@ ---- server/util_script.c.orig -+++ server/util_script.c -@@ -415,6 +415,7 @@ AP_DECLARE(int) ap_scan_script_header_er +diff -ruN ../httpd-2.2.17-o/server/util_script.c ./server/util_script.c +--- ../httpd-2.2.17-o/server/util_script.c 2009-01-12 14:59:56.000000000 +0100 ++++ ./server/util_script.c 2011-07-26 15:39:50.000000000 +0200 +@@ -406,6 +406,7 @@ { char x[MAX_STRING_LEN]; char *w, *l; @@ -8,7 +9,7 @@ int p; int cgi_status = HTTP_UNSET; apr_table_t *merge; -@@ -425,7 +426,14 @@ AP_DECLARE(int) ap_scan_script_header_er +@@ -414,7 +415,14 @@ if (buffer) { *buffer = '\0'; } @@ -24,17 +25,17 @@ /* temporary place to hold headers to merge in later */ merge = apr_table_make(r->pool, 10); -@@ -441,7 +449,7 @@ AP_DECLARE(int) ap_scan_script_header_er +@@ -430,7 +438,7 @@ while (1) { - int rv = (*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data); + int rv = (*getsfunc) (w, wlen - 1, getsfunc_data); if (rv == 0) { - const char *msg = "Premature end of script headers"; - if (first_header) -@@ -553,9 +561,12 @@ AP_DECLARE(int) ap_scan_script_header_er - if (!(l = strchr(w, ':'))) { + ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, + "Premature end of script headers: %s", +@@ -537,9 +545,12 @@ + if (!buffer) { /* Soak up all the script output - may save an outright kill */ - while ((*getsfunc) (w, MAX_STRING_LEN - 1, getsfunc_data)) { @@ -46,4 +47,4 @@ + buffer[MAX_STRING_LEN - 1] = 0; } - ap_log_rerror(SCRIPT_LOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, + ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_TOCLIENT, 0, r, diff --git a/httpd-2.4.2.tar.xz b/httpd-2.4.2.tar.xz deleted file mode 100644 index b80724c..0000000 --- a/httpd-2.4.2.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:932c695ff1ff7c907f67bed7462faf567d99744306b8491ba9db6bb0e8135905 -size 3645528 diff --git a/httpd-keepalivetimeout-millisecs.patch b/httpd-keepalivetimeout-millisecs.patch new file mode 100644 index 0000000..2970a91 --- /dev/null +++ b/httpd-keepalivetimeout-millisecs.patch @@ -0,0 +1,20 @@ +--- modules/http/http_core.c.orig ++++ modules/http/http_core.c +@@ -47,12 +47,15 @@ static int ap_process_http_connection(co + static const char *set_keep_alive_timeout(cmd_parms *cmd, void *dummy, + const char *arg) + { ++ apr_interval_time_t timeout; + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); + if (err != NULL) { + return err; + } +- +- cmd->server->keep_alive_timeout = apr_time_from_sec(atoi(arg)); ++ /* Stolen from mod_proxy.c */ ++ if (ap_timeout_parameter_parse(arg, &timeout, "s") != APR_SUCCESS) ++ return "KeepAliveTimeout has wrong format"; ++ cmd->server->keep_alive_timeout = timeout; + return NULL; + } + diff --git a/httpd-mod_deflate_head.patch b/httpd-mod_deflate_head.patch new file mode 100644 index 0000000..6d4011a --- /dev/null +++ b/httpd-mod_deflate_head.patch @@ -0,0 +1,23 @@ +--- modules/filters/mod_deflate.c.orig ++++ modules/filters/mod_deflate.c +@@ -582,6 +582,20 @@ static apr_status_t deflate_out_filter(a + apr_bucket *b; + apr_size_t len; + ++ /* ++ * Optimization: If we are a HEAD request and bytes_sent is not zero ++ * it means that we have passed the content-length filter once and ++ * have more data to sent. This means that the content-length filter ++ * could not determine our content-length for the response to the ++ * HEAD request anyway (the associated GET request would deliver the ++ * body in chunked encoding) and we can stop compressing. ++ */ ++ if (r->header_only && r->bytes_sent) { ++ ap_remove_output_filter(f); ++ return ap_pass_brigade(f->next, bb); ++ } ++ ++ + e = APR_BRIGADE_FIRST(bb); + + if (APR_BUCKET_IS_EOS(e)) { diff --git a/httpd-new_pcre.patch b/httpd-new_pcre.patch new file mode 100644 index 0000000..dd558af --- /dev/null +++ b/httpd-new_pcre.patch @@ -0,0 +1,23 @@ +Index: server/util_pcre.c +=================================================================== +--- server/util_pcre.c.orig 2012-02-11 10:07:31.000000000 +0100 ++++ server/util_pcre.c 2012-02-11 10:08:23.062838133 +0100 +@@ -128,6 +128,7 @@ AP_DECLARE(int) ap_regcomp(ap_regex_t *p + const char *errorptr; + int erroffset; + int options = 0; ++int nsub; + + if ((cflags & AP_REG_ICASE) != 0) options |= PCRE_CASELESS; + if ((cflags & AP_REG_NEWLINE) != 0) options |= PCRE_MULTILINE; +@@ -137,7 +138,9 @@ preg->re_erroffset = erroffset; + + if (preg->re_pcre == NULL) return AP_REG_INVARG; + +-preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL); ++pcre_fullinfo((const pcre *)preg->re_pcre, NULL, ++ PCRE_INFO_CAPTURECOUNT, &nsub); ++preg->re_nsub = nsub; + return 0; + } + diff --git a/ssl-mode-release-buffers.patch b/ssl-mode-release-buffers.patch new file mode 100644 index 0000000..5898966 --- /dev/null +++ b/ssl-mode-release-buffers.patch @@ -0,0 +1,13 @@ +--- modules/ssl/ssl_engine_init.c.orig ++++ modules/ssl/ssl_engine_init.c +@@ -482,7 +482,9 @@ static void ssl_init_ctx_protocol(server + } + + mctx->ssl_ctx = ctx; +- ++#ifdef SSL_MODE_RELEASE_BUFFERS ++ SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS); ++#endif + SSL_CTX_set_options(ctx, SSL_OP_ALL); + + if (!(protocol & SSL_PROTOCOL_SSLV2)) {