diff --git a/.gitignore b/.gitignore index 351e025..b337b6b 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,5 @@ x86_64 /httpd.conf.5 /httpd-2.4.41.tar.bz2.asc /apachectl.8 +/httpd-2.4.43.tar.bz2.asc +/KEYS diff --git a/httpd-2.4.25-detect-systemd.patch b/httpd-2.4.25-detect-systemd.patch deleted file mode 100644 index f8e302b..0000000 --- a/httpd-2.4.25-detect-systemd.patch +++ /dev/null @@ -1,75 +0,0 @@ -diff -uap httpd-2.4.25/acinclude.m4.detectsystemd httpd-2.4.25/acinclude.m4 -diff -uap httpd-2.4.25/acinclude.m4.detectsystemd httpd-2.4.25/acinclude.m4 -diff -uap httpd-2.4.25/acinclude.m4.detectsystemd httpd-2.4.25/acinclude.m4 ---- httpd-2.4.25/acinclude.m4.detectsystemd -+++ httpd-2.4.25/acinclude.m4 -@@ -604,6 +604,30 @@ - fi - ]) - -+AC_DEFUN(APACHE_CHECK_SYSTEMD, [ -+dnl Check for systemd support for listen.c's socket activation. -+case $host in -+*-linux-*) -+ if test -n "$PKGCONFIG" && $PKGCONFIG --exists libsystemd; then -+ SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd` -+ elif test -n "$PKGCONFIG" && $PKGCONFIG --exists libsystemd-daemon; then -+ SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd-daemon` -+ else -+ AC_CHECK_LIB(systemd-daemon, sd_notify, SYSTEMD_LIBS="-lsystemd-daemon") -+ fi -+ if test -n "$SYSTEMD_LIBS"; then -+ AC_CHECK_HEADERS(systemd/sd-daemon.h) -+ if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then -+ AC_MSG_WARN([Your system does not support systemd.]) -+ else -+ APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS]) -+ AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported]) -+ fi -+ fi -+ ;; -+esac -+]) -+ - dnl - dnl APACHE_EXPORT_ARGUMENTS - dnl Export (via APACHE_SUBST) the various path-related variables that -diff -uap httpd-2.4.25/configure.in.detectsystemd httpd-2.4.25/configure.in ---- httpd-2.4.25/configure.in.detectsystemd -+++ httpd-2.4.25/configure.in -@@ -234,6 +234,7 @@ - AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG]) - APR_ADDTO(PCRE_INCLUDES, [`$PCRE_CONFIG --cflags`]) - APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs`]) -+ APR_ADDTO(HTTPD_LIBS, [\$(PCRE_LIBS)]) - else - AC_MSG_ERROR([pcre-config for libpcre not found. PCRE is required and available from http://pcre.org/]) - fi -@@ -504,6 +510,8 @@ - AC_DEFINE(HAVE_GMTOFF, 1, [Define if struct tm has a tm_gmtoff field]) - fi - -+APACHE_CHECK_SYSTEMD -+ - dnl ## Set up any appropriate OS-specific environment variables for apachectl - - case $host in -@@ -668,6 +676,7 @@ - APACHE_SUBST(BUILTIN_LIBS) - APACHE_SUBST(SHLIBPATH_VAR) - APACHE_SUBST(OS_SPECIFIC_VARS) -+APACHE_SUBST(HTTPD_LIBS) - - PRE_SHARED_CMDS='echo ""' - POST_SHARED_CMDS='echo ""' ---- httpd-2.4.25/Makefile.in.detectsystemd -+++ httpd-2.4.25/Makefile.in -@@ -4,7 +4,7 @@ - - PROGRAM_NAME = $(progname) - PROGRAM_SOURCES = modules.c --PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(PCRE_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) -+PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) - PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c - PROGRAM_DEPENDENCIES = \ - server/libmain.la \ diff --git a/httpd-2.4.34-r1738878.patch b/httpd-2.4.34-r1738878.patch deleted file mode 100644 index 5af48f5..0000000 --- a/httpd-2.4.34-r1738878.patch +++ /dev/null @@ -1,130 +0,0 @@ ---- httpd-2.4.34/modules/proxy/ajp_header.c.r1738878 -+++ httpd-2.4.34/modules/proxy/ajp_header.c -@@ -213,7 +213,8 @@ - - static apr_status_t ajp_marshal_into_msgb(ajp_msg_t *msg, - request_rec *r, -- apr_uri_t *uri) -+ apr_uri_t *uri, -+ const char *secret) - { - int method; - apr_uint32_t i, num_headers = 0; -@@ -293,17 +294,15 @@ - i, elts[i].key, elts[i].val); - } - --/* XXXX need to figure out how to do this -- if (s->secret) { -+ if (secret) { - if (ajp_msg_append_uint8(msg, SC_A_SECRET) || -- ajp_msg_append_string(msg, s->secret)) { -+ ajp_msg_append_string(msg, secret)) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(03228) -- "Error ajp_marshal_into_msgb - " -+ "ajp_marshal_into_msgb: " - "Error appending secret"); - return APR_EGENERAL; - } - } -- */ - - if (r->user) { - if (ajp_msg_append_uint8(msg, SC_A_REMOTE_USER) || -@@ -671,7 +670,8 @@ - apr_status_t ajp_send_header(apr_socket_t *sock, - request_rec *r, - apr_size_t buffsize, -- apr_uri_t *uri) -+ apr_uri_t *uri, -+ const char *secret) - { - ajp_msg_t *msg; - apr_status_t rc; -@@ -683,7 +683,7 @@ - return rc; - } - -- rc = ajp_marshal_into_msgb(msg, r, uri); -+ rc = ajp_marshal_into_msgb(msg, r, uri, secret); - if (rc != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00988) - "ajp_send_header: ajp_marshal_into_msgb failed"); ---- httpd-2.4.34/modules/proxy/ajp.h.r1738878 -+++ httpd-2.4.34/modules/proxy/ajp.h -@@ -413,12 +413,14 @@ - * @param sock backend socket - * @param r current request - * @param buffsize max size of the AJP packet. -+ * @param secret authentication secret - * @param uri requested uri - * @return APR_SUCCESS or error - */ - apr_status_t ajp_send_header(apr_socket_t *sock, request_rec *r, - apr_size_t buffsize, -- apr_uri_t *uri); -+ apr_uri_t *uri, -+ const char *secret); - - /** - * Read the ajp message and return the type of the message. ---- httpd-2.4.34/modules/proxy/mod_proxy_ajp.c.r1738878 -+++ httpd-2.4.34/modules/proxy/mod_proxy_ajp.c -@@ -193,6 +193,7 @@ - apr_off_t content_length = 0; - int original_status = r->status; - const char *original_status_line = r->status_line; -+ const char *secret = NULL; - - if (psf->io_buffer_size_set) - maxsize = psf->io_buffer_size; -@@ -202,12 +203,15 @@ - maxsize = AJP_MSG_BUFFER_SZ; - maxsize = APR_ALIGN(maxsize, 1024); - -+ if (*conn->worker->s->secret) -+ secret = conn->worker->s->secret; -+ - /* - * Send the AJP request to the remote server - */ - - /* send request headers */ -- status = ajp_send_header(conn->sock, r, maxsize, uri); -+ status = ajp_send_header(conn->sock, r, maxsize, uri, secret); - if (status != APR_SUCCESS) { - conn->close = 1; - ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00868) ---- httpd-2.4.34/modules/proxy/mod_proxy.c.r1738878 -+++ httpd-2.4.34/modules/proxy/mod_proxy.c -@@ -319,6 +319,12 @@ - (int)sizeof(worker->s->upgrade)); - } - } -+ else if (!strcasecmp(key, "secret")) { -+ if (PROXY_STRNCPY(worker->s->secret, val) != APR_SUCCESS) { -+ return apr_psprintf(p, "Secret length must be < %d characters", -+ (int)sizeof(worker->s->secret)); -+ } -+ } - else if (!strcasecmp(key, "responsefieldsize")) { - long s = atol(val); - if (s < 0) { ---- httpd-2.4.34/modules/proxy/mod_proxy.h.r1738878 -+++ httpd-2.4.34/modules/proxy/mod_proxy.h -@@ -357,6 +357,7 @@ - #define PROXY_WORKER_MAX_HOSTNAME_SIZE 64 - #define PROXY_BALANCER_MAX_HOSTNAME_SIZE PROXY_WORKER_MAX_HOSTNAME_SIZE - #define PROXY_BALANCER_MAX_STICKY_SIZE 64 -+#define PROXY_WORKER_MAX_SECRET_SIZE 64 - - #define PROXY_RFC1035_HOSTNAME_SIZE 256 - -@@ -453,6 +454,7 @@ - char hostname_ex[PROXY_RFC1035_HOSTNAME_SIZE]; /* RFC1035 compliant version of the remote backend address */ - apr_size_t response_field_size; /* Size of proxy response buffer in bytes. */ - unsigned int response_field_size_set:1; -+ char secret[PROXY_WORKER_MAX_SECRET_SIZE]; /* authentication secret (e.g. AJP13) */ - } proxy_worker_shared; - - #define ALIGNED_PROXY_WORKER_SHARED_SIZE (APR_ALIGN_DEFAULT(sizeof(proxy_worker_shared))) diff --git a/httpd-2.4.38-r1830819+.patch b/httpd-2.4.38-r1830819+.patch deleted file mode 100644 index 7df5ff6..0000000 --- a/httpd-2.4.38-r1830819+.patch +++ /dev/null @@ -1,677 +0,0 @@ -# ./pullrev.sh 1830819 1830836 1830912 1830913 1830927 1831168 1831173 - -http://svn.apache.org/viewvc?view=revision&revision=1830819 -http://svn.apache.org/viewvc?view=revision&revision=1830912 -http://svn.apache.org/viewvc?view=revision&revision=1830913 -http://svn.apache.org/viewvc?view=revision&revision=1830927 -http://svn.apache.org/viewvc?view=revision&revision=1831168 -http://svn.apache.org/viewvc?view=revision&revision=1831173 -http://svn.apache.org/viewvc?view=revision&revision=1835240 -http://svn.apache.org/viewvc?view=revision&revision=1835242 - -diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c -index d276fea..5467d23 100644 ---- httpd-2.4.38/modules/ssl/ssl_engine_config.c.r1830819+ -+++ httpd-2.4.38/modules/ssl/ssl_engine_config.c -@@ -916,7 +916,9 @@ - SSLSrvConfigRec *sc = mySrvConfig(cmd->server); - const char *err; - -- if ((err = ssl_cmd_check_file(cmd, &arg))) { -+ /* Only check for non-ENGINE based certs. */ -+ if (!modssl_is_engine_id(arg) -+ && (err = ssl_cmd_check_file(cmd, &arg))) { - return err; - } - -@@ -932,7 +934,9 @@ - SSLSrvConfigRec *sc = mySrvConfig(cmd->server); - const char *err; - -- if ((err = ssl_cmd_check_file(cmd, &arg))) { -+ /* Check keyfile exists for non-ENGINE keys. */ -+ if (!modssl_is_engine_id(arg) -+ && (err = ssl_cmd_check_file(cmd, &arg))) { - return err; - } - ---- httpd-2.4.38/modules/ssl/ssl_engine_init.c.r1830819+ -+++ httpd-2.4.38/modules/ssl/ssl_engine_init.c -@@ -1228,12 +1228,18 @@ - (certfile = APR_ARRAY_IDX(mctx->pks->cert_files, i, - const char *)); - i++) { -+ EVP_PKEY *pkey; -+ const char *engine_certfile = NULL; -+ - key_id = apr_psprintf(ptemp, "%s:%d", vhost_id, i); - - ERR_clear_error(); - - /* first the certificate (public key) */ -- if (mctx->cert_chain) { -+ if (modssl_is_engine_id(certfile)) { -+ engine_certfile = certfile; -+ } -+ else if (mctx->cert_chain) { - if ((SSL_CTX_use_certificate_file(mctx->ssl_ctx, certfile, - SSL_FILETYPE_PEM) < 1)) { - ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02561) -@@ -1262,12 +1268,46 @@ - - ERR_clear_error(); - -- if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile, -- SSL_FILETYPE_PEM) < 1) && -- (ERR_GET_FUNC(ERR_peek_last_error()) -- != X509_F_X509_CHECK_PRIVATE_KEY)) { -+ if (modssl_is_engine_id(keyfile)) { -+ apr_status_t rv; -+ -+ cert = NULL; -+ -+ if ((rv = modssl_load_engine_keypair(s, ptemp, vhost_id, -+ engine_certfile, keyfile, -+ &cert, &pkey))) { -+ return rv; -+ } -+ -+ if (cert) { -+ if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) < 1) { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10137) -+ "Failed to configure engine certificate %s, check %s", -+ key_id, certfile); -+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -+ return APR_EGENERAL; -+ } -+ -+ /* SSL_CTX now owns the cert. */ -+ X509_free(cert); -+ } -+ -+ if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1) { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10130) -+ "Failed to configure private key %s from engine", -+ keyfile); -+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -+ return APR_EGENERAL; -+ } -+ -+ /* SSL_CTX now owns the key */ -+ EVP_PKEY_free(pkey); -+ } -+ else if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile, -+ SSL_FILETYPE_PEM) < 1) -+ && (ERR_GET_FUNC(ERR_peek_last_error()) -+ != X509_F_X509_CHECK_PRIVATE_KEY)) { - ssl_asn1_t *asn1; -- EVP_PKEY *pkey; - const unsigned char *ptr; - - ERR_clear_error(); -@@ -1354,8 +1394,9 @@ - /* - * Try to read DH parameters from the (first) SSLCertificateFile - */ -- if ((certfile = APR_ARRAY_IDX(mctx->pks->cert_files, 0, const char *)) && -- (dhparams = ssl_dh_GetParamFromFile(certfile))) { -+ certfile = APR_ARRAY_IDX(mctx->pks->cert_files, 0, const char *); -+ if (certfile && !modssl_is_engine_id(certfile) -+ && (dhparams = ssl_dh_GetParamFromFile(certfile))) { - SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dhparams); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02540) - "Custom DH parameters (%d bits) for %s loaded from %s", -@@ -1367,10 +1408,10 @@ - /* - * Similarly, try to read the ECDH curve name from SSLCertificateFile... - */ -- if ((certfile != NULL) && -- (ecparams = ssl_ec_GetParamFromFile(certfile)) && -- (nid = EC_GROUP_get_curve_name(ecparams)) && -- (eckey = EC_KEY_new_by_curve_name(nid))) { -+ if (certfile && !modssl_is_engine_id(certfile) -+ && (ecparams = ssl_ec_GetParamFromFile(certfile)) -+ && (nid = EC_GROUP_get_curve_name(ecparams)) -+ && (eckey = EC_KEY_new_by_curve_name(nid))) { - SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey); - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02541) - "ECDH curve %s for %s specified in %s", ---- httpd-2.4.38/modules/ssl/ssl_engine_pphrase.c.r1830819+ -+++ httpd-2.4.38/modules/ssl/ssl_engine_pphrase.c -@@ -143,8 +143,6 @@ - const char *key_id = asn1_table_vhost_key(mc, p, sc->vhost_id, idx); - EVP_PKEY *pPrivateKey = NULL; - ssl_asn1_t *asn1; -- unsigned char *ucp; -- long int length; - int nPassPhrase = (*pphrases)->nelts; - int nPassPhraseRetry = 0; - apr_time_t pkey_mtime = 0; -@@ -221,7 +219,7 @@ - * is not empty. */ - ERR_clear_error(); - -- pPrivateKey = modssl_read_privatekey(ppcb_arg.pkey_file, NULL, -+ pPrivateKey = modssl_read_privatekey(ppcb_arg.pkey_file, - ssl_pphrase_Handle_CB, &ppcb_arg); - /* If the private key was successfully read, nothing more to - do here. */ -@@ -351,19 +349,12 @@ - nPassPhrase++; - } - -- /* -- * Insert private key into the global module configuration -- * (we convert it to a stand-alone DER byte sequence -- * because the SSL library uses static variables inside a -- * RSA structure which do not survive DSO reloads!) -- */ -- length = i2d_PrivateKey(pPrivateKey, NULL); -- ucp = ssl_asn1_table_set(mc->tPrivateKey, key_id, length); -- (void)i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */ -+ /* Cache the private key in the global module configuration so it -+ * can be used after subsequent reloads. */ -+ asn1 = ssl_asn1_table_set(mc->tPrivateKey, key_id, pPrivateKey); - - if (ppcb_arg.nPassPhraseDialogCur != 0) { - /* remember mtime of encrypted keys */ -- asn1 = ssl_asn1_table_get(mc->tPrivateKey, key_id); - asn1->source_mtime = pkey_mtime; - } - -@@ -614,3 +605,288 @@ - */ - return (len); - } -+ -+ -+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) -+ -+/* OpenSSL UI implementation for passphrase entry; largely duplicated -+ * from ssl_pphrase_Handle_CB but adjusted for UI API. TODO: Might be -+ * worth trying to shift pphrase handling over to the UI API -+ * completely. */ -+static int passphrase_ui_open(UI *ui) -+{ -+ pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui); -+ SSLSrvConfigRec *sc = mySrvConfig(ppcb->s); -+ -+ ppcb->nPassPhraseDialog++; -+ ppcb->nPassPhraseDialogCur++; -+ -+ /* -+ * Builtin or Pipe dialog -+ */ -+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN -+ || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) { -+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) { -+ if (!readtty) { -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, -+ APLOGNO(10143) -+ "Init: Creating pass phrase dialog pipe child " -+ "'%s'", sc->server->pphrase_dialog_path); -+ if (ssl_pipe_child_create(ppcb->p, -+ sc->server->pphrase_dialog_path) -+ != APR_SUCCESS) { -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ppcb->s, -+ APLOGNO(10144) -+ "Init: Failed to create pass phrase pipe '%s'", -+ sc->server->pphrase_dialog_path); -+ return 0; -+ } -+ } -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO(10145) -+ "Init: Requesting pass phrase via piped dialog"); -+ } -+ else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */ -+#ifdef WIN32 -+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ppcb->s, APLOGNO(10146) -+ "Init: Failed to create pass phrase pipe '%s'", -+ sc->server->pphrase_dialog_path); -+ return 0; -+#else -+ /* -+ * stderr has already been redirected to the error_log. -+ * rather than attempting to temporarily rehook it to the terminal, -+ * we print the prompt to stdout before EVP_read_pw_string turns -+ * off tty echo -+ */ -+ apr_file_open_stdout(&writetty, ppcb->p); -+ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO(10147) -+ "Init: Requesting pass phrase via builtin terminal " -+ "dialog"); -+#endif -+ } -+ -+ /* -+ * The first time display a header to inform the user about what -+ * program he actually speaks to, which module is responsible for -+ * this terminal dialog and why to the hell he has to enter -+ * something... -+ */ -+ if (ppcb->nPassPhraseDialog == 1) { -+ apr_file_printf(writetty, "%s mod_ssl (Pass Phrase Dialog)\n", -+ AP_SERVER_BASEVERSION); -+ apr_file_printf(writetty, -+ "A pass phrase is required to access the private key.\n"); -+ } -+ if (ppcb->bPassPhraseDialogOnce) { -+ ppcb->bPassPhraseDialogOnce = FALSE; -+ apr_file_printf(writetty, "\n"); -+ apr_file_printf(writetty, "Private key %s (%s)\n", -+ ppcb->key_id, ppcb->pkey_file); -+ } -+ } -+ -+ return 1; -+} -+ -+static int passphrase_ui_read(UI *ui, UI_STRING *uis) -+{ -+ pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui); -+ SSLSrvConfigRec *sc = mySrvConfig(ppcb->s); -+ const char *prompt; -+ int i; -+ int bufsize; -+ int len; -+ char *buf; -+ -+ prompt = UI_get0_output_string(uis); -+ if (prompt == NULL) { -+ prompt = "Enter pass phrase:"; -+ } -+ -+ /* -+ * Get the maximum expected size and allocate the buffer -+ */ -+ bufsize = UI_get_result_maxsize(uis); -+ buf = apr_pcalloc(ppcb->p, bufsize); -+ -+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN -+ || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) { -+ /* -+ * Get the pass phrase through a callback. -+ * Empty input is not accepted. -+ */ -+ for (;;) { -+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) { -+ i = pipe_get_passwd_cb(buf, bufsize, "", FALSE); -+ } -+ else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */ -+ i = EVP_read_pw_string(buf, bufsize, "", FALSE); -+ } -+ if (i != 0) { -+ OPENSSL_cleanse(buf, bufsize); -+ return 0; -+ } -+ len = strlen(buf); -+ if (len < 1){ -+ apr_file_printf(writetty, "Apache:mod_ssl:Error: Pass phrase" -+ "empty (needs to be at least 1 character).\n"); -+ apr_file_puts(prompt, writetty); -+ } -+ else { -+ break; -+ } -+ } -+ } -+ /* -+ * Filter program -+ */ -+ else if (sc->server->pphrase_dialog_type == SSL_PPTYPE_FILTER) { -+ const char *cmd = sc->server->pphrase_dialog_path; -+ const char **argv = apr_palloc(ppcb->p, sizeof(char *) * 3); -+ char *result; -+ -+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO(10148) -+ "Init: Requesting pass phrase from dialog filter " -+ "program (%s)", cmd); -+ -+ argv[0] = cmd; -+ argv[1] = ppcb->key_id; -+ argv[2] = NULL; -+ -+ result = ssl_util_readfilter(ppcb->s, ppcb->p, cmd, argv); -+ apr_cpystrn(buf, result, bufsize); -+ len = strlen(buf); -+ } -+ -+ /* -+ * Ok, we now have the pass phrase, so give it back -+ */ -+ ppcb->cpPassPhraseCur = apr_pstrdup(ppcb->p, buf); -+ UI_set_result(ui, uis, buf); -+ -+ /* Clear sensitive data. */ -+ OPENSSL_cleanse(buf, bufsize); -+ return 1; -+} -+ -+static int passphrase_ui_write(UI *ui, UI_STRING *uis) -+{ -+ pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui); -+ SSLSrvConfigRec *sc; -+ const char *prompt; -+ -+ sc = mySrvConfig(ppcb->s); -+ -+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN -+ || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) { -+ prompt = UI_get0_output_string(uis); -+ apr_file_puts(prompt, writetty); -+ } -+ -+ return 1; -+} -+ -+static int passphrase_ui_close(UI *ui) -+{ -+ /* -+ * Close the pipes if they were opened -+ */ -+ if (readtty) { -+ apr_file_close(readtty); -+ apr_file_close(writetty); -+ readtty = writetty = NULL; -+ } -+ return 1; -+} -+ -+static apr_status_t pp_ui_method_cleanup(void *uip) -+{ -+ UI_METHOD *uim = uip; -+ -+ UI_destroy_method(uim); -+ -+ return APR_SUCCESS; -+} -+ -+static UI_METHOD *get_passphrase_ui(apr_pool_t *p) -+{ -+ UI_METHOD *ui_method = UI_create_method("Passphrase UI"); -+ -+ UI_method_set_opener(ui_method, passphrase_ui_open); -+ UI_method_set_reader(ui_method, passphrase_ui_read); -+ UI_method_set_writer(ui_method, passphrase_ui_write); -+ UI_method_set_closer(ui_method, passphrase_ui_close); -+ -+ apr_pool_cleanup_register(p, ui_method, pp_ui_method_cleanup, -+ pp_ui_method_cleanup); -+ -+ return ui_method; -+} -+ -+ -+apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p, -+ const char *vhostid, -+ const char *certid, const char *keyid, -+ X509 **pubkey, EVP_PKEY **privkey) -+{ -+ SSLModConfigRec *mc = myModConfig(s); -+ ENGINE *e; -+ UI_METHOD *ui_method = get_passphrase_ui(p); -+ pphrase_cb_arg_t ppcb; -+ -+ memset(&ppcb, 0, sizeof ppcb); -+ ppcb.s = s; -+ ppcb.p = p; -+ ppcb.bPassPhraseDialogOnce = TRUE; -+ ppcb.key_id = vhostid; -+ ppcb.pkey_file = keyid; -+ -+ if (!mc->szCryptoDevice) { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10131) -+ "Init: Cannot load private key `%s' without engine", -+ keyid); -+ return ssl_die(s); -+ } -+ -+ if (!(e = ENGINE_by_id(mc->szCryptoDevice))) { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10132) -+ "Init: Failed to load Crypto Device API `%s'", -+ mc->szCryptoDevice); -+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -+ return ssl_die(s); -+ } -+ -+ if (APLOGdebug(s)) { -+ ENGINE_ctrl_cmd_string(e, "VERBOSE", NULL, 0); -+ } -+ -+ if (certid) { -+ struct { -+ const char *cert_id; -+ X509 *cert; -+ } params = { certid, NULL }; -+ -+ if (!ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10136) -+ "Init: Unable to get the certificate"); -+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -+ return ssl_die(s); -+ } -+ -+ *pubkey = params.cert; -+ } -+ -+ *privkey = ENGINE_load_private_key(e, keyid, ui_method, &ppcb); -+ if (*privkey == NULL) { -+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10133) -+ "Init: Unable to get the private key"); -+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s); -+ return ssl_die(s); -+ } -+ -+ ENGINE_free(e); -+ -+ return APR_SUCCESS; -+} -+#endif ---- httpd-2.4.38/modules/ssl/ssl_private.h.r1830819+ -+++ httpd-2.4.38/modules/ssl/ssl_private.h -@@ -1002,21 +1002,28 @@ - apr_status_t ssl_load_encrypted_pkey(server_rec *, apr_pool_t *, int, - const char *, apr_array_header_t **); - -+/* Load public and/or private key from the configured ENGINE. Private -+ * key returned as *pkey. certid can be NULL, in which case *pubkey -+ * is not altered. Errors logged on failure. */ -+apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p, -+ const char *vhostid, -+ const char *certid, const char *keyid, -+ X509 **pubkey, EVP_PKEY **privkey); -+ - /** Diffie-Hellman Parameter Support */ - DH *ssl_dh_GetParamFromFile(const char *); - #ifdef HAVE_ECC - EC_GROUP *ssl_ec_GetParamFromFile(const char *); - #endif - --unsigned char *ssl_asn1_table_set(apr_hash_t *table, -- const char *key, -- long int length); -- --ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table, -- const char *key); -- --void ssl_asn1_table_unset(apr_hash_t *table, -- const char *key); -+/* Store the EVP_PKEY key (serialized into DER) in the hash table with -+ * key, returning the ssl_asn1_t structure pointer. */ -+ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key, -+ EVP_PKEY *pkey); -+/* Retrieve the ssl_asn1_t structure with given key from the hash. */ -+ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table, const char *key); -+/* Remove and free the ssl_asn1_t structure with given key. */ -+void ssl_asn1_table_unset(apr_hash_t *table, const char *key); - - /** Mutex Support */ - int ssl_mutex_init(server_rec *, apr_pool_t *); -@@ -1109,6 +1116,10 @@ - int ssl_is_challenge(conn_rec *c, const char *servername, - X509 **pcert, EVP_PKEY **pkey); - -+/* Returns non-zero if the cert/key filename should be handled through -+ * the configured ENGINE. */ -+int modssl_is_engine_id(const char *name); -+ - #endif /* SSL_PRIVATE_H */ - /** @} */ - ---- httpd-2.4.38/modules/ssl/ssl_util.c.r1830819+ -+++ httpd-2.4.38/modules/ssl/ssl_util.c -@@ -192,45 +192,37 @@ - return TRUE; - } - --/* -- * certain key data needs to survive restarts, -- * which are stored in the user data table of s->process->pool. -- * to prevent "leaking" of this data, we use malloc/free -- * rather than apr_palloc and these wrappers to help make sure -- * we do not leak the malloc-ed data. -- */ --unsigned char *ssl_asn1_table_set(apr_hash_t *table, -- const char *key, -- long int length) -+/* Decrypted private keys are cached to survive restarts. The cached -+ * data must have lifetime of the process (hence malloc/free rather -+ * than pools), and uses raw DER since the EVP_PKEY structure -+ * internals may not survive across a module reload. */ -+ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key, -+ EVP_PKEY *pkey) - { - apr_ssize_t klen = strlen(key); - ssl_asn1_t *asn1 = apr_hash_get(table, key, klen); -+ apr_size_t length = i2d_PrivateKey(pkey, NULL); -+ unsigned char *p; - -- /* -- * if a value for this key already exists, -- * reuse as much of the already malloc-ed data -- * as possible. -- */ -+ /* Re-use structure if cached previously. */ - if (asn1) { - if (asn1->nData != length) { -- free(asn1->cpData); /* XXX: realloc? */ -- asn1->cpData = NULL; -+ asn1->cpData = ap_realloc(asn1->cpData, length); - } - } - else { - asn1 = ap_malloc(sizeof(*asn1)); - asn1->source_mtime = 0; /* used as a note for encrypted private keys */ -- asn1->cpData = NULL; -- } -- -- asn1->nData = length; -- if (!asn1->cpData) { - asn1->cpData = ap_malloc(length); -+ -+ apr_hash_set(table, key, klen, asn1); - } - -- apr_hash_set(table, key, klen, asn1); -+ asn1->nData = length; -+ p = asn1->cpData; -+ i2d_PrivateKey(pkey, &p); /* increases p by length */ - -- return asn1->cpData; /* caller will assign a value to this */ -+ return asn1; - } - - ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table, -@@ -480,3 +472,13 @@ - } - - #endif /* #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API */ -+ -+int modssl_is_engine_id(const char *name) -+{ -+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) -+ /* ### Can handle any other special ENGINE key names here? */ -+ return strncmp(name, "pkcs11:", 7) == 0; -+#else -+ return 0; -+#endif -+} ---- httpd-2.4.38/modules/ssl/ssl_util_ssl.c.r1830819+ -+++ httpd-2.4.38/modules/ssl/ssl_util_ssl.c -@@ -74,7 +74,7 @@ - ** _________________________________________________________________ - */ - --EVP_PKEY *modssl_read_privatekey(const char* filename, EVP_PKEY **key, pem_password_cb *cb, void *s) -+EVP_PKEY *modssl_read_privatekey(const char *filename, pem_password_cb *cb, void *s) - { - EVP_PKEY *rc; - BIO *bioS; -@@ -83,7 +83,7 @@ - /* 1. try PEM (= DER+Base64+headers) */ - if ((bioS=BIO_new_file(filename, "r")) == NULL) - return NULL; -- rc = PEM_read_bio_PrivateKey(bioS, key, cb, s); -+ rc = PEM_read_bio_PrivateKey(bioS, NULL, cb, s); - BIO_free(bioS); - - if (rc == NULL) { -@@ -107,41 +107,9 @@ - BIO_free(bioS); - } - } -- if (rc != NULL && key != NULL) { -- if (*key != NULL) -- EVP_PKEY_free(*key); -- *key = rc; -- } - return rc; - } - --typedef struct { -- const char *pass; -- int pass_len; --} pass_ctx; -- --static int provide_pass(char *buf, int size, int rwflag, void *baton) --{ -- pass_ctx *ctx = baton; -- if (ctx->pass_len > 0) { -- if (ctx->pass_len < size) { -- size = (int)ctx->pass_len; -- } -- memcpy(buf, ctx->pass, size); -- } -- return ctx->pass_len; --} -- --EVP_PKEY *modssl_read_encrypted_pkey(const char *filename, EVP_PKEY **key, -- const char *pass, apr_size_t pass_len) --{ -- pass_ctx ctx; -- -- ctx.pass = pass; -- ctx.pass_len = pass_len; -- return modssl_read_privatekey(filename, key, provide_pass, &ctx); --} -- - /* _________________________________________________________________ - ** - ** Smart shutdown ---- httpd-2.4.38/modules/ssl/ssl_util_ssl.h.r1830819+ -+++ httpd-2.4.38/modules/ssl/ssl_util_ssl.h -@@ -64,8 +64,11 @@ - void modssl_init_app_data2_idx(void); - void *modssl_get_app_data2(SSL *); - void modssl_set_app_data2(SSL *, void *); --EVP_PKEY *modssl_read_privatekey(const char *, EVP_PKEY **, pem_password_cb *, void *); --EVP_PKEY *modssl_read_encrypted_pkey(const char *, EVP_PKEY **, const char *, apr_size_t); -+ -+/* Read private key from filename in either PEM or raw base64(DER) -+ * format, using password entry callback cb and userdata. */ -+EVP_PKEY *modssl_read_privatekey(const char *filename, pem_password_cb *cb, void *ud); -+ - int modssl_smart_shutdown(SSL *ssl); - BOOL modssl_X509_getBC(X509 *, int *, int *); - char *modssl_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne, diff --git a/httpd-2.4.41-r1865749.patch b/httpd-2.4.41-r1865749.patch deleted file mode 100644 index d79a559..0000000 --- a/httpd-2.4.41-r1865749.patch +++ /dev/null @@ -1,14 +0,0 @@ -# ./pullrev.sh 1865749 -http://svn.apache.org/viewvc?view=revision&revision=1865749 - ---- httpd-2.4.41/modules/proxy/mod_proxy_balancer.c.r1865749 -+++ httpd-2.4.41/modules/proxy/mod_proxy_balancer.c -@@ -1104,7 +1104,7 @@ - if (apr_uri_parse(r->pool, ref, &uri) || !uri.hostname) - return 0; - -- return strcmp(uri.hostname, ap_get_server_name(r)) == 0; -+ return strcasecmp(uri.hostname, ap_get_server_name(r)) == 0; - } - - /* Manages the loadfactors and member status diff --git a/httpd-2.4.41-systemd.patch b/httpd-2.4.41-systemd.patch deleted file mode 100644 index 5369bd9..0000000 --- a/httpd-2.4.41-systemd.patch +++ /dev/null @@ -1,240 +0,0 @@ ---- httpd-2.4.41/modules/arch/unix/config5.m4.systemd -+++ httpd-2.4.41/modules/arch/unix/config5.m4 -@@ -18,6 +18,16 @@ - fi - ]) - -+APACHE_MODULE(systemd, Systemd support, , , all, [ -+ if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then -+ AC_MSG_WARN([Your system does not support systemd.]) -+ enable_systemd="no" -+ else -+ APR_ADDTO(MOD_SYSTEMD_LDADD, [$SYSTEMD_LIBS]) -+ enable_systemd="yes" -+ fi -+]) -+ - APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current]) - - APACHE_MODPATH_FINISH ---- httpd-2.4.41/modules/arch/unix/mod_systemd.c.systemd -+++ httpd-2.4.41/modules/arch/unix/mod_systemd.c -@@ -0,0 +1,218 @@ -+/* 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. -+ * -+ */ -+ -+#include -+#include -+#include "ap_mpm.h" -+#include -+#include -+#include -+#include -+#include -+#include -+#include "unixd.h" -+#include "scoreboard.h" -+#include "mpm_common.h" -+ -+#include "systemd/sd-daemon.h" -+#include "systemd/sd-journal.h" -+ -+#if APR_HAVE_UNISTD_H -+#include -+#endif -+ -+static int shutdown_timer = 0; -+static int shutdown_counter = 0; -+static unsigned long bytes_served; -+static pid_t mainpid; -+static char describe_listeners[50]; -+ -+static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog, -+ apr_pool_t *ptemp) -+{ -+ sd_notify(0, -+ "RELOADING=1\n" -+ "STATUS=Reading configuration...\n"); -+ ap_extended_status = 1; -+ return OK; -+} -+ -+static char *dump_listener(ap_listen_rec *lr, apr_pool_t *p) -+{ -+ apr_sockaddr_t *sa = lr->bind_addr; -+ char addr[128]; -+ -+ if (apr_sockaddr_is_wildcard(sa)) { -+ return apr_pstrcat(p, "port ", apr_itoa(p, sa->port), NULL); -+ } -+ -+ apr_sockaddr_ip_getbuf(addr, sizeof addr, sa); -+ -+ return apr_psprintf(p, "%s port %u", addr, sa->port); -+} -+ -+/* Report the service is ready in post_config, which could be during -+ * startup or after a reload. The server could still hit a fatal -+ * startup error after this point during ap_run_mpm(), so this is -+ * perhaps too early, but by post_config listen() has been called on -+ * the TCP ports so new connections will not be rejected. There will -+ * always be a possible async failure event simultaneous to the -+ * service reporting "ready", so this should be good enough. */ -+static int systemd_post_config(apr_pool_t *pconf, apr_pool_t *plog, -+ apr_pool_t *ptemp, server_rec *main_server) -+{ -+ ap_listen_rec *lr; -+ apr_size_t plen = sizeof describe_listeners; -+ char *p = describe_listeners; -+ -+ if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) -+ return OK; -+ -+ for (lr = ap_listeners; lr; lr = lr->next) { -+ char *s = dump_listener(lr, ptemp); -+ -+ if (strlen(s) + 3 < plen) { -+ char *newp = apr_cpystrn(p, s, plen); -+ if (lr->next) -+ newp = apr_cpystrn(newp, ", ", 3); -+ plen -= newp - p; -+ p = newp; -+ } -+ else { -+ if (plen < 4) { -+ p = describe_listeners + sizeof describe_listeners - 4; -+ plen = 4; -+ } -+ apr_cpystrn(p, "...", plen); -+ break; -+ } -+ } -+ -+ sd_notify(0, "READY=1\n" -+ "STATUS=Configuration loaded.\n"); -+ -+ sd_journal_print(LOG_INFO, "Server configured, listening on: %s", -+ describe_listeners); -+ -+ return OK; -+} -+ -+static int systemd_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type) -+{ -+ mainpid = getpid(); -+ -+ sd_notifyf(0, "READY=1\n" -+ "STATUS=Started, listening on: %s\n" -+ "MAINPID=%" APR_PID_T_FMT, -+ describe_listeners, mainpid); -+ -+ return OK; -+} -+ -+static int systemd_monitor(apr_pool_t *p, server_rec *s) -+{ -+ ap_sload_t sload; -+ apr_interval_time_t up_time; -+ char bps[5]; -+ -+ if (!ap_extended_status) { -+ /* Nothing useful to report with ExtendedStatus disabled. */ -+ return DECLINED; -+ } -+ -+ ap_get_sload(&sload); -+ -+ if (sload.access_count == 0) { -+ sd_notifyf(0, "READY=1\n" -+ "STATUS=Running, listening on: %s\n", -+ describe_listeners); -+ } -+ else { -+ /* up_time in seconds */ -+ up_time = (apr_uint32_t) apr_time_sec(apr_time_now() - -+ ap_scoreboard_image->global->restart_time); -+ -+ apr_strfsize((unsigned long)((float) (sload.bytes_served) -+ / (float) up_time), bps); -+ -+ sd_notifyf(0, "READY=1\n" -+ "STATUS=Total requests: %lu; Idle/Busy workers %d/%d;" -+ "Requests/sec: %.3g; Bytes served/sec: %sB/sec\n", -+ sload.access_count, sload.idle, sload.busy, -+ ((float) sload.access_count) / (float) up_time, bps); -+ } -+ -+ /* Shutdown httpd when nothing is sent for shutdown_timer seconds. */ -+ if (sload.bytes_served == bytes_served) { -+ /* mpm_common.c: INTERVAL_OF_WRITABLE_PROBES is 10 */ -+ shutdown_counter += 10; -+ if (shutdown_timer > 0 && shutdown_counter >= shutdown_timer) { -+ sd_notifyf(0, "READY=1\n" -+ "STATUS=Stopped as result of IdleShutdown " -+ "timeout."); -+ kill(mainpid, AP_SIG_GRACEFUL); -+ } -+ } -+ else { -+ shutdown_counter = 0; -+ } -+ -+ bytes_served = sload.bytes_served; -+ -+ return DECLINED; -+} -+ -+static void systemd_register_hooks(apr_pool_t *p) -+{ -+ /* Enable ap_extended_status. */ -+ ap_hook_pre_config(systemd_pre_config, NULL, NULL, APR_HOOK_LAST); -+ /* Grab the listener config. */ -+ ap_hook_post_config(systemd_post_config, NULL, NULL, APR_HOOK_REALLY_LAST); -+ /* We know the PID in this hook ... */ -+ ap_hook_pre_mpm(systemd_pre_mpm, NULL, NULL, APR_HOOK_LAST); -+ /* Used to update httpd's status line using sd_notifyf */ -+ ap_hook_monitor(systemd_monitor, NULL, NULL, APR_HOOK_MIDDLE); -+} -+ -+static const char *set_shutdown_timer(cmd_parms *cmd, void *dummy, -+ const char *arg) -+{ -+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); -+ if (err != NULL) { -+ return err; -+ } -+ -+ shutdown_timer = atoi(arg); -+ return NULL; -+} -+ -+static const command_rec systemd_cmds[] = -+{ -+AP_INIT_TAKE1("IdleShutdown", set_shutdown_timer, NULL, RSRC_CONF, -+ "Number of seconds in idle-state after which httpd is shutdown"), -+ {NULL} -+}; -+ -+AP_DECLARE_MODULE(systemd) = { -+ STANDARD20_MODULE_STUFF, -+ NULL, -+ NULL, -+ NULL, -+ NULL, -+ systemd_cmds, -+ systemd_register_hooks, -+}; diff --git a/httpd-2.4.9-apxs.patch b/httpd-2.4.43-apxs.patch similarity index 85% rename from httpd-2.4.9-apxs.patch rename to httpd-2.4.43-apxs.patch index 7016dec..b1185b2 100644 --- a/httpd-2.4.9-apxs.patch +++ b/httpd-2.4.43-apxs.patch @@ -1,8 +1,8 @@ diff --git a/support/apxs.in b/support/apxs.in -index ad1287f..efcfcf6 100644 +index b2705fa..c331631 100644 --- a/support/apxs.in +++ b/support/apxs.in -@@ -25,7 +25,18 @@ package apxs; +@@ -35,7 +35,18 @@ if ($ddi >= 0) { my %config_vars = (); @@ -19,10 +19,10 @@ index ad1287f..efcfcf6 100644 + +my $installbuilddir = $libdir . "/httpd/build"; + - get_config_vars("$installbuilddir/config_vars.mk",\%config_vars); + get_config_vars($destdir . "$installbuilddir/config_vars.mk",\%config_vars); # read the configuration variables once -@@ -275,7 +286,7 @@ if ($opt_g) { +@@ -285,7 +296,7 @@ if ($opt_g) { $data =~ s|%NAME%|$name|sg; $data =~ s|%TARGET%|$CFG_TARGET|sg; $data =~ s|%PREFIX%|$prefix|sg; @@ -31,7 +31,7 @@ index ad1287f..efcfcf6 100644 my ($mkf, $mods, $src) = ($data =~ m|^(.+)-=#=-\n(.+)-=#=-\n(.+)|s); -@@ -453,11 +464,11 @@ if ($opt_c) { +@@ -463,11 +474,11 @@ if ($opt_c) { my $ldflags = "$CFG_LDFLAGS"; if ($opt_p == 1) { @@ -45,7 +45,7 @@ index ad1287f..efcfcf6 100644 chomp($apu_libs); } -@@ -672,8 +683,8 @@ __DATA__ +@@ -682,8 +693,8 @@ __DATA__ builddir=. top_srcdir=%PREFIX% diff --git a/httpd-2.4.4-cachehardmax.patch b/httpd-2.4.43-cachehardmax.patch similarity index 86% rename from httpd-2.4.4-cachehardmax.patch rename to httpd-2.4.43-cachehardmax.patch index de360ce..755f822 100644 --- a/httpd-2.4.4-cachehardmax.patch +++ b/httpd-2.4.43-cachehardmax.patch @@ -1,8 +1,8 @@ diff --git a/modules/cache/cache_util.h b/modules/cache/cache_util.h -index eec38f3..1a2d5ee 100644 +index 6b92151..4c42a8e 100644 --- a/modules/cache/cache_util.h +++ b/modules/cache/cache_util.h -@@ -194,6 +194,9 @@ typedef struct { +@@ -195,6 +195,9 @@ typedef struct { unsigned int store_nostore_set:1; unsigned int enable_set:1; unsigned int disable_set:1; @@ -13,10 +13,10 @@ index eec38f3..1a2d5ee 100644 /* A linked-list of authn providers. */ diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c -index 4f2d3e0..30c88f4 100644 +index 3b9aa4f..8268503 100644 --- a/modules/cache/mod_cache.c +++ b/modules/cache/mod_cache.c -@@ -1299,6 +1299,11 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in) +@@ -1455,6 +1455,11 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in) exp = date + dconf->defex; } } @@ -28,7 +28,7 @@ index 4f2d3e0..30c88f4 100644 info->expire = exp; /* We found a stale entry which wasn't really stale. */ -@@ -1717,7 +1722,9 @@ static void *create_dir_config(apr_pool_t *p, char *dummy) +@@ -1954,7 +1959,9 @@ static void *create_dir_config(apr_pool_t *p, char *dummy) /* array of providers for this URL space */ dconf->cacheenable = apr_array_make(p, 10, sizeof(struct cache_enable)); @@ -39,7 +39,7 @@ index 4f2d3e0..30c88f4 100644 return dconf; } -@@ -1767,7 +1774,10 @@ static void *merge_dir_config(apr_pool_t *p, void *basev, void *addv) { +@@ -2004,7 +2011,10 @@ static void *merge_dir_config(apr_pool_t *p, void *basev, void *addv) { new->enable_set = add->enable_set || base->enable_set; new->disable = (add->disable_set == 0) ? base->disable : add->disable; new->disable_set = add->disable_set || base->disable_set; @@ -51,7 +51,7 @@ index 4f2d3e0..30c88f4 100644 return new; } -@@ -2096,12 +2106,18 @@ static const char *add_cache_disable(cmd_parms *parms, void *dummy, +@@ -2332,12 +2342,18 @@ static const char *add_cache_disable(cmd_parms *parms, void *dummy, } static const char *set_cache_maxex(cmd_parms *parms, void *dummy, @@ -71,7 +71,7 @@ index 4f2d3e0..30c88f4 100644 return NULL; } -@@ -2309,7 +2325,7 @@ static const command_rec cache_cmds[] = +@@ -2545,7 +2561,7 @@ static const command_rec cache_cmds[] = "caching is enabled"), AP_INIT_TAKE1("CacheDisable", add_cache_disable, NULL, RSRC_CONF|ACCESS_CONF, "A partial URL prefix below which caching is disabled"), diff --git a/httpd-2.4.1-corelimit.patch b/httpd-2.4.43-corelimit.patch similarity index 72% rename from httpd-2.4.1-corelimit.patch rename to httpd-2.4.43-corelimit.patch index 96f8486..dd4b874 100644 --- a/httpd-2.4.1-corelimit.patch +++ b/httpd-2.4.43-corelimit.patch @@ -1,13 +1,8 @@ - -Bump up the core size limit if CoreDumpDirectory is -configured. - -Upstream-Status: Was discussed but there are competing desires; - there are portability oddities here too. - ---- httpd-2.4.1/server/core.c.corelimit -+++ httpd-2.4.1/server/core.c -@@ -4433,6 +4433,25 @@ static int core_post_config(apr_pool_t * +diff --git a/server/core.c b/server/core.c +index 79b2a82..dc0f17a 100644 +--- a/server/core.c ++++ b/server/core.c +@@ -4996,6 +4996,25 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte } apr_pool_cleanup_register(pconf, NULL, ap_mpm_end_gen_helper, apr_pool_cleanup_null); diff --git a/httpd-2.4.1-deplibs.patch b/httpd-2.4.43-deplibs.patch similarity index 70% rename from httpd-2.4.1-deplibs.patch rename to httpd-2.4.43-deplibs.patch index b73c21d..c60f5a5 100644 --- a/httpd-2.4.1-deplibs.patch +++ b/httpd-2.4.43-deplibs.patch @@ -1,11 +1,8 @@ - -Link straight against .la files. - -Upstream-Status: vendor specific - ---- httpd-2.4.1/configure.in.deplibs -+++ httpd-2.4.1/configure.in -@@ -707,9 +707,9 @@ APACHE_HELP_STRING(--with-suexec-umask,u +diff --git a/configure.in b/configure.in +index f8f9442..f276550 100644 +--- a/configure.in ++++ b/configure.in +@@ -786,9 +786,9 @@ APACHE_SUBST(INSTALL_SUEXEC) dnl APR should go after the other libs, so the right symbols can be picked up if test x${apu_found} != xobsolete; then diff --git a/httpd-2.4.43-detect-systemd.patch b/httpd-2.4.43-detect-systemd.patch new file mode 100644 index 0000000..448f7d7 --- /dev/null +++ b/httpd-2.4.43-detect-systemd.patch @@ -0,0 +1,33 @@ +diff --git a/Makefile.in b/Makefile.in +index ea8366e..06b8c5a 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -4,7 +4,7 @@ CLEAN_SUBDIRS = test + + PROGRAM_NAME = $(progname) + PROGRAM_SOURCES = modules.c +-PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(PCRE_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) ++PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) + PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c + PROGRAM_DEPENDENCIES = \ + server/libmain.la \ +diff --git a/configure.in b/configure.in +index f276550..a63eada 100644 +--- a/configure.in ++++ b/configure.in +@@ -234,6 +234,7 @@ if test "$PCRE_CONFIG" != "false"; then + AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG]) + APR_ADDTO(PCRE_INCLUDES, [`$PCRE_CONFIG --cflags`]) + APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs`]) ++ APR_ADDTO(HTTPD_LIBS, [\$(PCRE_LIBS)]) + else + AC_MSG_ERROR([pcre-config for libpcre not found. PCRE is required and available from http://pcre.org/]) + fi +@@ -679,6 +682,7 @@ APACHE_SUBST(OS_DIR) + APACHE_SUBST(BUILTIN_LIBS) + APACHE_SUBST(SHLIBPATH_VAR) + APACHE_SUBST(OS_SPECIFIC_VARS) ++APACHE_SUBST(HTTPD_LIBS) + + PRE_SHARED_CMDS='echo ""' + POST_SHARED_CMDS='echo ""' diff --git a/httpd-2.4.34-enable-sslv3.patch b/httpd-2.4.43-enable-sslv3.patch similarity index 76% rename from httpd-2.4.34-enable-sslv3.patch rename to httpd-2.4.43-enable-sslv3.patch index a2eba80..2861605 100644 --- a/httpd-2.4.34-enable-sslv3.patch +++ b/httpd-2.4.43-enable-sslv3.patch @@ -1,9 +1,8 @@ - -https://bugzilla.redhat.com/show_bug.cgi?id=1623165 - ---- httpd-2.4.34/modules/ssl/ssl_engine_config.c.enable-sslv3 -+++ httpd-2.4.34/modules/ssl/ssl_engine_config.c -@@ -1474,6 +1474,10 @@ +diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c +index 979489c..3d6443b 100644 +--- a/modules/ssl/ssl_engine_config.c ++++ b/modules/ssl/ssl_engine_config.c +@@ -1485,6 +1485,10 @@ static const char *ssl_cmd_protocol_parse(cmd_parms *parms, #endif else if (strcEQ(w, "all")) { thisopt = SSL_PROTOCOL_ALL; @@ -14,9 +13,11 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1623165 } else { return apr_pstrcat(parms->temp_pool, ---- httpd-2.4.34/modules/ssl/ssl_engine_init.c.enable-sslv3 -+++ httpd-2.4.34/modules/ssl/ssl_engine_init.c -@@ -537,6 +537,28 @@ +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index b0fcf81..ab6f263 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -568,6 +568,28 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s, } #endif @@ -45,7 +46,7 @@ https://bugzilla.redhat.com/show_bug.cgi?id=1623165 static apr_status_t ssl_init_ctx_protocol(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, -@@ -687,9 +709,13 @@ +@@ -735,9 +757,13 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, } if (prot == TLS1_1_VERSION && protocol & SSL_PROTOCOL_TLSV1) { prot = TLS1_VERSION; diff --git a/httpd-2.4.39-export.patch b/httpd-2.4.43-export.patch similarity index 77% rename from httpd-2.4.39-export.patch rename to httpd-2.4.43-export.patch index b20a6e7..0d9fd72 100644 --- a/httpd-2.4.39-export.patch +++ b/httpd-2.4.43-export.patch @@ -5,9 +5,11 @@ to do so indirectly. Upstream: https://svn.apache.org/r1861685 (as new default-off configure option) ---- httpd-2.4.39/Makefile.in.export -+++ httpd-2.4.39/Makefile.in -@@ -4,8 +4,15 @@ +diff --git a/Makefile.in b/Makefile.in +index 9eeb5c7..8746a10 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -4,8 +4,15 @@ CLEAN_SUBDIRS = test PROGRAM_NAME = $(progname) PROGRAM_SOURCES = modules.c @@ -24,9 +26,24 @@ Upstream: https://svn.apache.org/r1861685 (as new default-off configure option) PROGRAM_DEPENDENCIES = \ server/libmain.la \ $(BUILTIN_LIBS) \ ---- httpd-2.4.39/server/main.c.export -+++ httpd-2.4.39/server/main.c -@@ -835,17 +835,3 @@ +diff --git a/server/Makefile.in b/server/Makefile.in +index 1fa3344..116850b 100644 +--- a/server/Makefile.in ++++ b/server/Makefile.in +@@ -12,7 +12,7 @@ LTLIBRARY_SOURCES = \ + connection.c listen.c util_mutex.c \ + mpm_common.c mpm_unix.c mpm_fdqueue.c \ + util_charset.c util_cookies.c util_debug.c util_xml.c \ +- util_filter.c util_pcre.c util_regex.c exports.c \ ++ util_filter.c util_pcre.c util_regex.c \ + scoreboard.c error_bucket.c protocol.c core.c request.c provider.c \ + eoc_bucket.c eor_bucket.c core_filters.c \ + util_expr_parse.c util_expr_scan.c util_expr_eval.c +diff --git a/server/main.c b/server/main.c +index 62e06df..17c09ee 100644 +--- a/server/main.c ++++ b/server/main.c +@@ -835,17 +835,3 @@ int main(int argc, const char * const argv[]) return !OK; } @@ -44,14 +61,3 @@ Upstream: https://svn.apache.org/r1861685 (as new default-off configure option) - return ap_ugly_hack; -} -#endif ---- httpd-2.4.39/server/Makefile.in.export -+++ httpd-2.4.39/server/Makefile.in -@@ -12,7 +12,7 @@ - connection.c listen.c util_mutex.c \ - mpm_common.c mpm_unix.c mpm_fdqueue.c \ - util_charset.c util_cookies.c util_debug.c util_xml.c \ -- util_filter.c util_pcre.c util_regex.c exports.c \ -+ util_filter.c util_pcre.c util_regex.c \ - scoreboard.c error_bucket.c protocol.c core.c request.c provider.c \ - eoc_bucket.c eor_bucket.c core_filters.c \ - util_expr_parse.c util_expr_scan.c util_expr_eval.c diff --git a/httpd-2.4.2-icons.patch b/httpd-2.4.43-icons.patch similarity index 59% rename from httpd-2.4.2-icons.patch rename to httpd-2.4.43-icons.patch index 1341999..21518d7 100644 --- a/httpd-2.4.2-icons.patch +++ b/httpd-2.4.43-icons.patch @@ -1,12 +1,8 @@ - -- Fix config for /icons/ dir to allow symlink to poweredby.png. -- Avoid using coredump GIF for a directory called "core" - -Upstream-Status: vendor specific patch - ---- httpd-2.4.2/docs/conf/extra/httpd-autoindex.conf.in.icons -+++ httpd-2.4.2/docs/conf/extra/httpd-autoindex.conf.in -@@ -21,7 +21,7 @@ IndexOptions FancyIndexing HTMLTable Ver +diff --git a/docs/conf/extra/httpd-autoindex.conf.in b/docs/conf/extra/httpd-autoindex.conf.in +index 51b02ed..0e8b626 100644 +--- a/docs/conf/extra/httpd-autoindex.conf.in ++++ b/docs/conf/extra/httpd-autoindex.conf.in +@@ -21,7 +21,7 @@ IndexOptions FancyIndexing HTMLTable VersionSort Alias /icons/ "@exp_iconsdir@/" diff --git a/httpd-2.4.41-r1828172+.patch b/httpd-2.4.43-r1828172+.patch similarity index 92% rename from httpd-2.4.41-r1828172+.patch rename to httpd-2.4.43-r1828172+.patch index 72b124b..3487600 100644 --- a/httpd-2.4.41-r1828172+.patch +++ b/httpd-2.4.43-r1828172+.patch @@ -1,1063 +1,8 @@ -# ./pullrev.sh 1828172 1862968 1863191 1867878 1867882 1867968 1867970 1867971 -http://svn.apache.org/viewvc?view=revision&revision=1828172 -http://svn.apache.org/viewvc?view=revision&revision=1862968 -http://svn.apache.org/viewvc?view=revision&revision=1863191 -http://svn.apache.org/viewvc?view=revision&revision=1867878 -http://svn.apache.org/viewvc?view=revision&revision=1867882 -http://svn.apache.org/viewvc?view=revision&revision=1867968 -http://svn.apache.org/viewvc?view=revision&revision=1867970 -http://svn.apache.org/viewvc?view=revision&revision=1867971 - ---- httpd-2.4.41/modules/generators/mod_cgi.c -+++ httpd-2.4.41/modules/generators/mod_cgi.c -@@ -92,6 +92,10 @@ - apr_size_t bufbytes; - } cgi_server_conf; - -+typedef struct { -+ apr_interval_time_t timeout; -+} cgi_dirconf; -+ - static void *create_cgi_config(apr_pool_t *p, server_rec *s) - { - cgi_server_conf *c = -@@ -112,6 +116,12 @@ - return overrides->logname ? overrides : base; - } - -+static void *create_cgi_dirconf(apr_pool_t *p, char *dummy) -+{ -+ cgi_dirconf *c = (cgi_dirconf *) apr_pcalloc(p, sizeof(cgi_dirconf)); -+ return c; -+} -+ - static const char *set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg) - { - server_rec *s = cmd->server; -@@ -150,6 +160,17 @@ - return NULL; - } - -+static const char *set_script_timeout(cmd_parms *cmd, void *dummy, const char *arg) -+{ -+ cgi_dirconf *dc = dummy; -+ -+ if (ap_timeout_parameter_parse(arg, &dc->timeout, "s") != APR_SUCCESS) { -+ return "CGIScriptTimeout has wrong format"; -+ } -+ -+ return NULL; -+} -+ - static const command_rec cgi_cmds[] = - { - AP_INIT_TAKE1("ScriptLog", set_scriptlog, NULL, RSRC_CONF, -@@ -158,6 +179,9 @@ - "the maximum length (in bytes) of the script debug log"), - AP_INIT_TAKE1("ScriptLogBuffer", set_scriptlog_buffer, NULL, RSRC_CONF, - "the maximum size (in bytes) to record of a POST request"), -+AP_INIT_TAKE1("CGIScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_CONF, -+ "The amount of time to wait between successful reads from " -+ "the CGI script, in seconds."), - {NULL} - }; - -@@ -471,23 +495,26 @@ - apr_filepath_name_get(r->filename)); - } - else { -+ cgi_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgi_module); -+ apr_interval_time_t timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout; -+ - apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT); - - *script_in = procnew->out; - if (!*script_in) - return APR_EBADF; -- apr_file_pipe_timeout_set(*script_in, r->server->timeout); -+ apr_file_pipe_timeout_set(*script_in, timeout); - - if (e_info->prog_type == RUN_AS_CGI) { - *script_out = procnew->in; - if (!*script_out) - return APR_EBADF; -- apr_file_pipe_timeout_set(*script_out, r->server->timeout); -+ apr_file_pipe_timeout_set(*script_out, timeout); - - *script_err = procnew->err; - if (!*script_err) - return APR_EBADF; -- apr_file_pipe_timeout_set(*script_err, r->server->timeout); -+ apr_file_pipe_timeout_set(*script_err, timeout); - } - } - } -@@ -541,212 +568,10 @@ - return APR_SUCCESS; - } - --static void discard_script_output(apr_bucket_brigade *bb) --{ -- apr_bucket *e; -- const char *buf; -- apr_size_t len; -- apr_status_t rv; -- -- for (e = APR_BRIGADE_FIRST(bb); -- e != APR_BRIGADE_SENTINEL(bb); -- e = APR_BUCKET_NEXT(e)) -- { -- if (APR_BUCKET_IS_EOS(e)) { -- break; -- } -- rv = apr_bucket_read(e, &buf, &len, APR_BLOCK_READ); -- if (rv != APR_SUCCESS) { -- break; -- } -- } --} -- - #if APR_FILES_AS_SOCKETS -- --/* A CGI bucket type is needed to catch any output to stderr from the -- * script; see PR 22030. */ --static const apr_bucket_type_t bucket_type_cgi; -- --struct cgi_bucket_data { -- apr_pollset_t *pollset; -- request_rec *r; --}; -- --/* Create a CGI bucket using pipes from script stdout 'out' -- * and stderr 'err', for request 'r'. */ --static apr_bucket *cgi_bucket_create(request_rec *r, -- apr_file_t *out, apr_file_t *err, -- apr_bucket_alloc_t *list) --{ -- apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); -- apr_status_t rv; -- apr_pollfd_t fd; -- struct cgi_bucket_data *data = apr_palloc(r->pool, sizeof *data); -- -- APR_BUCKET_INIT(b); -- b->free = apr_bucket_free; -- b->list = list; -- b->type = &bucket_type_cgi; -- b->length = (apr_size_t)(-1); -- b->start = -1; -- -- /* Create the pollset */ -- rv = apr_pollset_create(&data->pollset, 2, r->pool, 0); -- if (rv != APR_SUCCESS) { -- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01217) -- "apr_pollset_create(); check system or user limits"); -- return NULL; -- } -- -- fd.desc_type = APR_POLL_FILE; -- fd.reqevents = APR_POLLIN; -- fd.p = r->pool; -- fd.desc.f = out; /* script's stdout */ -- fd.client_data = (void *)1; -- rv = apr_pollset_add(data->pollset, &fd); -- if (rv != APR_SUCCESS) { -- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01218) -- "apr_pollset_add(); check system or user limits"); -- return NULL; -- } -- -- fd.desc.f = err; /* script's stderr */ -- fd.client_data = (void *)2; -- rv = apr_pollset_add(data->pollset, &fd); -- if (rv != APR_SUCCESS) { -- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01219) -- "apr_pollset_add(); check system or user limits"); -- return NULL; -- } -- -- data->r = r; -- b->data = data; -- return b; --} -- --/* Create a duplicate CGI bucket using given bucket data */ --static apr_bucket *cgi_bucket_dup(struct cgi_bucket_data *data, -- apr_bucket_alloc_t *list) --{ -- apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); -- APR_BUCKET_INIT(b); -- b->free = apr_bucket_free; -- b->list = list; -- b->type = &bucket_type_cgi; -- b->length = (apr_size_t)(-1); -- b->start = -1; -- b->data = data; -- return b; --} -- --/* Handle stdout from CGI child. Duplicate of logic from the _read -- * method of the real APR pipe bucket implementation. */ --static apr_status_t cgi_read_stdout(apr_bucket *a, apr_file_t *out, -- const char **str, apr_size_t *len) --{ -- char *buf; -- apr_status_t rv; -- -- *str = NULL; -- *len = APR_BUCKET_BUFF_SIZE; -- buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */ -- -- rv = apr_file_read(out, buf, len); -- -- if (rv != APR_SUCCESS && rv != APR_EOF) { -- apr_bucket_free(buf); -- return rv; -- } -- -- if (*len > 0) { -- struct cgi_bucket_data *data = a->data; -- apr_bucket_heap *h; -- -- /* Change the current bucket to refer to what we read */ -- a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free); -- h = a->data; -- h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */ -- *str = buf; -- APR_BUCKET_INSERT_AFTER(a, cgi_bucket_dup(data, a->list)); -- } -- else { -- apr_bucket_free(buf); -- a = apr_bucket_immortal_make(a, "", 0); -- *str = a->data; -- } -- return rv; --} -- --/* Read method of CGI bucket: polls on stderr and stdout of the child, -- * sending any stderr output immediately away to the error log. */ --static apr_status_t cgi_bucket_read(apr_bucket *b, const char **str, -- apr_size_t *len, apr_read_type_e block) --{ -- struct cgi_bucket_data *data = b->data; -- apr_interval_time_t timeout; -- apr_status_t rv; -- int gotdata = 0; -- -- timeout = block == APR_NONBLOCK_READ ? 0 : data->r->server->timeout; -- -- do { -- const apr_pollfd_t *results; -- apr_int32_t num; -- -- rv = apr_pollset_poll(data->pollset, timeout, &num, &results); -- if (APR_STATUS_IS_TIMEUP(rv)) { -- if (timeout) { -- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, data->r, APLOGNO(01220) -- "Timeout waiting for output from CGI script %s", -- data->r->filename); -- return rv; -- } -- else { -- return APR_EAGAIN; -- } -- } -- else if (APR_STATUS_IS_EINTR(rv)) { -- continue; -- } -- else if (rv != APR_SUCCESS) { -- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, data->r, APLOGNO(01221) -- "poll failed waiting for CGI child"); -- return rv; -- } -- -- for (; num; num--, results++) { -- if (results[0].client_data == (void *)1) { -- /* stdout */ -- rv = cgi_read_stdout(b, results[0].desc.f, str, len); -- if (APR_STATUS_IS_EOF(rv)) { -- rv = APR_SUCCESS; -- } -- gotdata = 1; -- } else { -- /* stderr */ -- apr_status_t rv2 = log_script_err(data->r, results[0].desc.f); -- if (APR_STATUS_IS_EOF(rv2)) { -- apr_pollset_remove(data->pollset, &results[0]); -- } -- } -- } -- -- } while (!gotdata); -- -- return rv; --} -- --static const apr_bucket_type_t bucket_type_cgi = { -- "CGI", 5, APR_BUCKET_DATA, -- apr_bucket_destroy_noop, -- cgi_bucket_read, -- apr_bucket_setaside_notimpl, -- apr_bucket_split_notimpl, -- apr_bucket_copy_notimpl --}; -- -+#define WANT_CGI_BUCKET - #endif -+#include "cgi_common.h" - - static int cgi_handler(request_rec *r) - { -@@ -766,6 +591,8 @@ - apr_status_t rv; - cgi_exec_info_t e_info; - conn_rec *c; -+ cgi_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgi_module); -+ apr_interval_time_t timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout; - - if (strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) { - return DECLINED; -@@ -925,10 +752,7 @@ - AP_DEBUG_ASSERT(script_in != NULL); - - #if APR_FILES_AS_SOCKETS -- apr_file_pipe_timeout_set(script_in, 0); -- apr_file_pipe_timeout_set(script_err, 0); -- -- b = cgi_bucket_create(r, script_in, script_err, c->bucket_alloc); -+ b = cgi_bucket_create(r, dc->timeout, script_in, script_err, c->bucket_alloc); - if (b == NULL) - return HTTP_INTERNAL_SERVER_ERROR; - #else -@@ -938,111 +762,7 @@ - b = apr_bucket_eos_create(c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(bb, b); - -- /* Handle script return... */ -- if (!nph) { -- const char *location; -- char sbuf[MAX_STRING_LEN]; -- int ret; -- -- if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, -- APLOG_MODULE_INDEX))) -- { -- ret = log_script(r, conf, ret, dbuf, sbuf, bb, script_err); -- -- /* -- * ret could be HTTP_NOT_MODIFIED in the case that the CGI script -- * does not set an explicit status and ap_meets_conditions, which -- * is called by ap_scan_script_header_err_brigade, detects that -- * the conditions of the requests are met and the response is -- * not modified. -- * In this case set r->status and return OK in order to prevent -- * running through the error processing stack as this would -- * break with mod_cache, if the conditions had been set by -- * mod_cache itself to validate a stale entity. -- * BTW: We circumvent the error processing stack anyway if the -- * CGI script set an explicit status code (whatever it is) and -- * the only possible values for ret here are: -- * -- * HTTP_NOT_MODIFIED (set by ap_meets_conditions) -- * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions) -- * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the -- * processing of the response of the CGI script, e.g broken headers -- * or a crashed CGI process). -- */ -- if (ret == HTTP_NOT_MODIFIED) { -- r->status = ret; -- return OK; -- } -- -- return ret; -- } -- -- location = apr_table_get(r->headers_out, "Location"); -- -- if (location && r->status == 200) { -- /* For a redirect whether internal or not, discard any -- * remaining stdout from the script, and log any remaining -- * stderr output, as normal. */ -- discard_script_output(bb); -- apr_brigade_destroy(bb); -- apr_file_pipe_timeout_set(script_err, r->server->timeout); -- log_script_err(r, script_err); -- } -- -- if (location && location[0] == '/' && r->status == 200) { -- /* This redirect needs to be a GET no matter what the original -- * method was. -- */ -- r->method = "GET"; -- r->method_number = M_GET; -- -- /* We already read the message body (if any), so don't allow -- * the redirected request to think it has one. We can ignore -- * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. -- */ -- apr_table_unset(r->headers_in, "Content-Length"); -- -- ap_internal_redirect_handler(location, r); -- return OK; -- } -- else if (location && r->status == 200) { -- /* XXX: Note that if a script wants to produce its own Redirect -- * body, it now has to explicitly *say* "Status: 302" -- */ -- return HTTP_MOVED_TEMPORARILY; -- } -- -- rv = ap_pass_brigade(r->output_filters, bb); -- } -- else /* nph */ { -- struct ap_filter_t *cur; -- -- /* get rid of all filters up through protocol... since we -- * haven't parsed off the headers, there is no way they can -- * work -- */ -- -- cur = r->proto_output_filters; -- while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { -- cur = cur->next; -- } -- r->output_filters = r->proto_output_filters = cur; -- -- rv = ap_pass_brigade(r->output_filters, bb); -- } -- -- /* don't soak up script output if errors occurred writing it -- * out... otherwise, we prolong the life of the script when the -- * connection drops or we stopped sending output for some other -- * reason */ -- if (rv == APR_SUCCESS && !r->connection->aborted) { -- apr_file_pipe_timeout_set(script_err, r->server->timeout); -- log_script_err(r, script_err); -- } -- -- apr_file_close(script_err); -- -- return OK; /* NOT r->status, even if it has changed. */ -+ return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err); - } - - /*============================================================================ -@@ -1277,7 +997,7 @@ - AP_DECLARE_MODULE(cgi) = - { - STANDARD20_MODULE_STUFF, -- NULL, /* dir config creater */ -+ create_cgi_dirconf, /* dir config creater */ - NULL, /* dir merger --- default is to override */ - create_cgi_config, /* server config */ - merge_cgi_config, /* merge server config */ ---- httpd-2.4.41/modules/generators/config5.m4 -+++ httpd-2.4.41/modules/generators/config5.m4 -@@ -78,4 +78,15 @@ - - APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current]) - -+AC_ARG_ENABLE(cgid-fdpassing, -+ [APACHE_HELP_STRING(--enable-cgid-fdpassing,Enable experimental mod_cgid support for fd passing)], -+ [if test "$enableval" = "yes"; then -+ AC_CHECK_DECL(CMSG_DATA, -+ [AC_DEFINE([HAVE_CGID_FDPASSING], 1, [Enable FD passing support in mod_cgid])], -+ [AC_MSG_ERROR([cannot support mod_cgid fd-passing on this system])], [ -+#include -+#include ]) -+ fi -+]) -+ - APACHE_MODPATH_FINISH ---- httpd-2.4.41/modules/generators/mod_cgid.c -+++ httpd-2.4.41/modules/generators/mod_cgid.c -@@ -342,15 +342,19 @@ - return close(fd); - } - --/* deal with incomplete reads and signals -- * assume you really have to read buf_size bytes -- */ --static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) -+/* Read from the socket dealing with incomplete messages and signals. -+ * Returns 0 on success or errno on failure. Stderr fd passed as -+ * auxiliary data from other end is written to *errfd, or else stderr -+ * fileno if not present. */ -+static apr_status_t sock_readhdr(int fd, int *errfd, void *vbuf, size_t buf_size) - { -- char *buf = vbuf; - int rc; -+#ifndef HAVE_CGID_FDPASSING -+ char *buf = vbuf; - size_t bytes_read = 0; - -+ if (errfd) *errfd = 0; -+ - do { - do { - rc = read(fd, buf + bytes_read, buf_size - bytes_read); -@@ -365,9 +369,60 @@ - } - } while (bytes_read < buf_size); - -+ -+#else /* with FD passing */ -+ struct msghdr msg = {0}; -+ struct iovec vec = {vbuf, buf_size}; -+ struct cmsghdr *cmsg; -+ union { /* union to ensure alignment */ -+ struct cmsghdr cm; -+ char buf[CMSG_SPACE(sizeof(int))]; -+ } u; -+ -+ msg.msg_iov = &vec; -+ msg.msg_iovlen = 1; -+ -+ if (errfd) { -+ msg.msg_control = u.buf; -+ msg.msg_controllen = sizeof(u.buf); -+ *errfd = 0; -+ } -+ -+ /* use MSG_WAITALL to skip loop on truncated reads */ -+ do { -+ rc = recvmsg(fd, &msg, MSG_WAITALL); -+ } while (rc < 0 && errno == EINTR); -+ -+ if (rc == 0) { -+ return ECONNRESET; -+ } -+ else if (rc < 0) { -+ return errno; -+ } -+ else if (rc != buf_size) { -+ /* MSG_WAITALL should ensure the recvmsg blocks until the -+ * entire length is read, but let's be paranoid. */ -+ return APR_INCOMPLETE; -+ } -+ -+ if (errfd -+ && (cmsg = CMSG_FIRSTHDR(&msg)) != NULL -+ && cmsg->cmsg_len == CMSG_LEN(sizeof(*errfd)) -+ && cmsg->cmsg_level == SOL_SOCKET -+ && cmsg->cmsg_type == SCM_RIGHTS) { -+ *errfd = *((int *) CMSG_DATA(cmsg)); -+ } -+#endif -+ - return APR_SUCCESS; - } - -+/* As sock_readhdr but without auxiliary fd passing. */ -+static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) -+{ -+ return sock_readhdr(fd, NULL, vbuf, buf_size); -+} -+ - /* deal with signals - */ - static apr_status_t sock_write(int fd, const void *buf, size_t buf_size) -@@ -384,7 +439,7 @@ - return APR_SUCCESS; - } - --static apr_status_t sock_writev(int fd, request_rec *r, int count, ...) -+static apr_status_t sock_writev(int fd, int auxfd, request_rec *r, int count, ...) - { - va_list ap; - int rc; -@@ -399,9 +454,39 @@ - } - va_end(ap); - -+#ifndef HAVE_CGID_FDPASSING - do { - rc = writev(fd, vec, count); - } while (rc < 0 && errno == EINTR); -+#else -+ { -+ struct msghdr msg = { 0 }; -+ struct cmsghdr *cmsg; -+ union { /* union for alignment */ -+ char buf[CMSG_SPACE(sizeof(int))]; -+ struct cmsghdr align; -+ } u; -+ -+ msg.msg_iov = vec; -+ msg.msg_iovlen = count; -+ -+ if (auxfd) { -+ msg.msg_control = u.buf; -+ msg.msg_controllen = sizeof(u.buf); -+ -+ cmsg = CMSG_FIRSTHDR(&msg); -+ cmsg->cmsg_level = SOL_SOCKET; -+ cmsg->cmsg_type = SCM_RIGHTS; -+ cmsg->cmsg_len = CMSG_LEN(sizeof(int)); -+ *((int *) CMSG_DATA(cmsg)) = auxfd; -+ } -+ -+ do { -+ rc = sendmsg(fd, &msg, 0); -+ } while (rc < 0 && errno == EINTR); -+ } -+#endif -+ - if (rc < 0) { - return errno; - } -@@ -410,7 +495,7 @@ - } - - static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, -- cgid_req_t *req) -+ int *errfd, cgid_req_t *req) - { - int i; - char **environ; -@@ -421,7 +506,7 @@ - r->server = apr_pcalloc(r->pool, sizeof(server_rec)); - - /* read the request header */ -- stat = sock_read(fd, req, sizeof(*req)); -+ stat = sock_readhdr(fd, errfd, req, sizeof(*req)); - if (stat != APR_SUCCESS) { - return stat; - } -@@ -479,14 +564,15 @@ - return APR_SUCCESS; - } - --static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, -- int req_type) -+static apr_status_t send_req(int fd, apr_file_t *errpipe, request_rec *r, -+ char *argv0, char **env, int req_type) - { - int i; - cgid_req_t req = {0}; - apr_status_t stat; - ap_unix_identity_t * ugid = ap_run_get_suexec_identity(r); - core_dir_config *core_conf = ap_get_core_module_config(r->per_dir_config); -+ int errfd; - - - if (ugid == NULL) { -@@ -507,16 +593,21 @@ - req.args_len = r->args ? strlen(r->args) : 0; - req.loglevel = r->server->log.level; - -+ if (errpipe) -+ apr_os_file_get(&errfd, errpipe); -+ else -+ errfd = 0; -+ - /* Write the request header */ - if (req.args_len) { -- stat = sock_writev(fd, r, 5, -+ stat = sock_writev(fd, errfd, r, 5, - &req, sizeof(req), - r->filename, req.filename_len, - argv0, req.argv0_len, - r->uri, req.uri_len, - r->args, req.args_len); - } else { -- stat = sock_writev(fd, r, 4, -+ stat = sock_writev(fd, errfd, r, 4, - &req, sizeof(req), - r->filename, req.filename_len, - argv0, req.argv0_len, -@@ -531,7 +622,7 @@ - for (i = 0; i < req.env_count; i++) { - apr_size_t curlen = strlen(env[i]); - -- if ((stat = sock_writev(fd, r, 2, &curlen, sizeof(curlen), -+ if ((stat = sock_writev(fd, 0, r, 2, &curlen, sizeof(curlen), - env[i], curlen)) != APR_SUCCESS) { - return stat; - } -@@ -582,20 +673,34 @@ - } - } - -+/* Callback executed in the forked child process if exec of the CGI -+ * script fails. For the fd-passing case, output to stderr goes to -+ * the client (request handling thread) and is logged via -+ * ap_log_rerror there. For the non-fd-passing case, the "fake" -+ * request_rec passed via userdata is used to log. */ - static void cgid_child_errfn(apr_pool_t *pool, apr_status_t err, - const char *description) - { -- request_rec *r; - void *vr; - - apr_pool_userdata_get(&vr, ERRFN_USERDATA_KEY, pool); -- r = vr; -- -- /* sure we got r, but don't call ap_log_rerror() because we don't -- * have r->headers_in and possibly other storage referenced by -- * ap_log_rerror() -- */ -- ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, APLOGNO(01241) "%s", description); -+ if (vr) { -+ request_rec *r = vr; -+ -+ /* sure we got r, but don't call ap_log_rerror() because we don't -+ * have r->headers_in and possibly other storage referenced by -+ * ap_log_rerror() -+ */ -+ ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, APLOGNO(01241) "%s", description); -+ } -+ else { -+ const char *logstr; -+ -+ logstr = apr_psprintf(pool, APLOGNO(01241) "error spawning CGI child: %s (%pm)\n", -+ description, &err); -+ fputs(logstr, stderr); -+ fflush(stderr); -+ } - } - - static int cgid_server(void *data) -@@ -669,7 +774,7 @@ - } - - while (!daemon_should_exit) { -- int errfileno = STDERR_FILENO; -+ int errfileno; - char *argv0 = NULL; - char **env = NULL; - const char * const *argv; -@@ -709,7 +814,7 @@ - r = apr_pcalloc(ptrans, sizeof(request_rec)); - procnew = apr_pcalloc(ptrans, sizeof(*procnew)); - r->pool = ptrans; -- stat = get_req(sd2, r, &argv0, &env, &cgid_req); -+ stat = get_req(sd2, r, &argv0, &env, &errfileno, &cgid_req); - if (stat != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_ERR, stat, - main_server, APLOGNO(01248) -@@ -741,6 +846,16 @@ - continue; - } - -+ if (errfileno == 0) { -+ errfileno = STDERR_FILENO; -+ } -+ else { -+ ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, main_server, -+ "using passed fd %d as stderr", errfileno); -+ /* Limit the received fd lifetime to pool lifetime */ -+ apr_pool_cleanup_register(ptrans, (void *)((long)errfileno), -+ close_unix_socket, close_unix_socket); -+ } - apr_os_file_put(&r->server->error_log, &errfileno, 0, r->pool); - apr_os_file_put(&inout, &sd2, 0, r->pool); - -@@ -800,7 +915,10 @@ - close(sd2); - } - else { -- apr_pool_userdata_set(r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ptrans); -+ if (errfileno == STDERR_FILENO) { -+ /* Used by cgid_child_errfn without fd-passing. */ -+ apr_pool_userdata_set(r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ptrans); -+ } - - argv = (const char * const *)create_argv(r->pool, NULL, NULL, NULL, argv0, r->args); - -@@ -1099,6 +1217,33 @@ - return ret; - } - -+/* Soak up stderr from a script and redirect it to the error log. -+ * TODO: log_scripterror() and this could move to cgi_common.h. */ -+static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err) -+{ -+ char argsbuffer[HUGE_STRING_LEN]; -+ char *newline; -+ apr_status_t rv; -+ cgid_server_conf *conf = ap_get_module_config(r->server->module_config, &cgid_module); -+ -+ while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN, -+ script_err)) == APR_SUCCESS) { -+ -+ newline = strchr(argsbuffer, '\n'); -+ if (newline) { -+ char *prev = newline - 1; -+ if (prev >= argsbuffer && *prev == '\r') { -+ newline = prev; -+ } -+ -+ *newline = '\0'; -+ } -+ log_scripterror(r, conf, r->status, 0, argsbuffer); -+ } -+ -+ return rv; -+} -+ - static int log_script(request_rec *r, cgid_server_conf * conf, int ret, - char *dbuf, const char *sbuf, apr_bucket_brigade *bb, - apr_file_t *script_err) -@@ -1204,6 +1349,13 @@ - return ret; - } - -+/* Pull in CGI bucket implementation. */ -+#define cgi_server_conf cgid_server_conf -+#ifdef HAVE_CGID_FDPASSING -+#define WANT_CGI_BUCKET -+#endif -+#include "cgi_common.h" -+ - static int connect_to_daemon(int *sdptr, request_rec *r, - cgid_server_conf *conf) - { -@@ -1270,27 +1422,6 @@ - return OK; - } - --static void discard_script_output(apr_bucket_brigade *bb) --{ -- apr_bucket *e; -- const char *buf; -- apr_size_t len; -- apr_status_t rv; -- -- for (e = APR_BRIGADE_FIRST(bb); -- e != APR_BRIGADE_SENTINEL(bb); -- e = APR_BUCKET_NEXT(e)) -- { -- if (APR_BUCKET_IS_EOS(e)) { -- break; -- } -- rv = apr_bucket_read(e, &buf, &len, APR_BLOCK_READ); -- if (rv != APR_SUCCESS) { -- break; -- } -- } --} -- - /**************************************************************** - * - * Actual cgid handling... -@@ -1395,6 +1526,7 @@ - - static int cgid_handler(request_rec *r) - { -+ conn_rec *c = r->connection; - int retval, nph, dbpos; - char *argv0, *dbuf; - apr_bucket_brigade *bb; -@@ -1404,10 +1536,11 @@ - int seen_eos, child_stopped_reading; - int sd; - char **env; -- apr_file_t *tempsock; -+ apr_file_t *tempsock, *script_err, *errpipe_out; - struct cleanup_script_info *info; - apr_status_t rv; - cgid_dirconf *dc; -+ apr_interval_time_t timeout; - - if (strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) { - return DECLINED; -@@ -1416,7 +1549,7 @@ - conf = ap_get_module_config(r->server->module_config, &cgid_module); - dc = ap_get_module_config(r->per_dir_config, &cgid_module); - -- -+ timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout; - is_included = !strcmp(r->protocol, "INCLUDED"); - - if ((argv0 = strrchr(r->filename, '/')) != NULL) { -@@ -1469,6 +1602,17 @@ - } - */ - -+#ifdef HAVE_CGID_FDPASSING -+ rv = apr_file_pipe_create(&script_err, &errpipe_out, r->pool); -+ if (rv) { -+ return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10176) -+ "could not create pipe for stderr"); -+ } -+#else -+ script_err = NULL; -+ errpipe_out = NULL; -+#endif -+ - /* - * httpd core function used to add common environment variables like - * DOCUMENT_ROOT. -@@ -1481,12 +1625,16 @@ - return retval; - } - -- rv = send_req(sd, r, argv0, env, CGI_REQ); -+ rv = send_req(sd, errpipe_out, r, argv0, env, CGI_REQ); - if (rv != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01268) - "write to cgi daemon process"); - } - -+ /* The write-end of the pipe is only used by the server, so close -+ * it here. */ -+ if (errpipe_out) apr_file_close(errpipe_out); -+ - info = apr_palloc(r->pool, sizeof(struct cleanup_script_info)); - info->conf = conf; - info->r = r; -@@ -1508,12 +1656,7 @@ - */ - - apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool); -- if (dc->timeout > 0) { -- apr_file_pipe_timeout_set(tempsock, dc->timeout); -- } -- else { -- apr_file_pipe_timeout_set(tempsock, r->server->timeout); -- } -+ apr_file_pipe_timeout_set(tempsock, timeout); - apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket); - - /* Transfer any put/post args, CERN style... -@@ -1605,114 +1748,19 @@ - */ - shutdown(sd, 1); - -- /* Handle script return... */ -- if (!nph) { -- conn_rec *c = r->connection; -- const char *location; -- char sbuf[MAX_STRING_LEN]; -- int ret; -- -- bb = apr_brigade_create(r->pool, c->bucket_alloc); -- b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); -- APR_BRIGADE_INSERT_TAIL(bb, b); -- b = apr_bucket_eos_create(c->bucket_alloc); -- APR_BRIGADE_INSERT_TAIL(bb, b); -- -- if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, -- APLOG_MODULE_INDEX))) -- { -- ret = log_script(r, conf, ret, dbuf, sbuf, bb, NULL); -- -- /* -- * ret could be HTTP_NOT_MODIFIED in the case that the CGI script -- * does not set an explicit status and ap_meets_conditions, which -- * is called by ap_scan_script_header_err_brigade, detects that -- * the conditions of the requests are met and the response is -- * not modified. -- * In this case set r->status and return OK in order to prevent -- * running through the error processing stack as this would -- * break with mod_cache, if the conditions had been set by -- * mod_cache itself to validate a stale entity. -- * BTW: We circumvent the error processing stack anyway if the -- * CGI script set an explicit status code (whatever it is) and -- * the only possible values for ret here are: -- * -- * HTTP_NOT_MODIFIED (set by ap_meets_conditions) -- * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions) -- * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the -- * processing of the response of the CGI script, e.g broken headers -- * or a crashed CGI process). -- */ -- if (ret == HTTP_NOT_MODIFIED) { -- r->status = ret; -- return OK; -- } -- -- return ret; -- } -- -- location = apr_table_get(r->headers_out, "Location"); -- -- if (location && location[0] == '/' && r->status == 200) { -- -- /* Soak up all the script output */ -- discard_script_output(bb); -- apr_brigade_destroy(bb); -- /* This redirect needs to be a GET no matter what the original -- * method was. -- */ -- r->method = "GET"; -- r->method_number = M_GET; -- -- /* We already read the message body (if any), so don't allow -- * the redirected request to think it has one. We can ignore -- * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. -- */ -- apr_table_unset(r->headers_in, "Content-Length"); -- -- ap_internal_redirect_handler(location, r); -- return OK; -- } -- else if (location && r->status == 200) { -- /* XXX: Note that if a script wants to produce its own Redirect -- * body, it now has to explicitly *say* "Status: 302" -- */ -- discard_script_output(bb); -- apr_brigade_destroy(bb); -- return HTTP_MOVED_TEMPORARILY; -- } -- -- rv = ap_pass_brigade(r->output_filters, bb); -- if (rv != APR_SUCCESS) { -- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r, -- "Failed to flush CGI output to client"); -- } -- } -- -- if (nph) { -- conn_rec *c = r->connection; -- struct ap_filter_t *cur; -- -- /* get rid of all filters up through protocol... since we -- * haven't parsed off the headers, there is no way they can -- * work -- */ -- -- cur = r->proto_output_filters; -- while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { -- cur = cur->next; -- } -- r->output_filters = r->proto_output_filters = cur; -- -- bb = apr_brigade_create(r->pool, c->bucket_alloc); -- b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); -- APR_BRIGADE_INSERT_TAIL(bb, b); -- b = apr_bucket_eos_create(c->bucket_alloc); -- APR_BRIGADE_INSERT_TAIL(bb, b); -- ap_pass_brigade(r->output_filters, bb); -- } -+ bb = apr_brigade_create(r->pool, c->bucket_alloc); -+#ifdef HAVE_CGID_FDPASSING -+ b = cgi_bucket_create(r, dc->timeout, tempsock, script_err, c->bucket_alloc); -+ if (b == NULL) -+ return HTTP_INTERNAL_SERVER_ERROR; /* should call log_scripterror() w/ _UNAVAILABLE? */ -+#else -+ b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); -+#endif -+ APR_BRIGADE_INSERT_TAIL(bb, b); -+ b = apr_bucket_eos_create(c->bucket_alloc); -+ APR_BRIGADE_INSERT_TAIL(bb, b); - -- return OK; /* NOT r->status, even if it has changed. */ -+ return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err); - } - - -@@ -1829,7 +1877,7 @@ - return retval; - } - -- send_req(sd, r, command, env, SSI_REQ); -+ send_req(sd, NULL, r, command, env, SSI_REQ); - - info = apr_palloc(r->pool, sizeof(struct cleanup_script_info)); - info->conf = conf; ---- httpd-2.4.41/modules/generators/cgi_common.h -+++ httpd-2.4.41/modules/generators/cgi_common.h +diff --git a/modules/generators/cgi_common.h b/modules/generators/cgi_common.h +new file mode 100644 +index 0000000..85c9685 +--- /dev/null ++++ b/modules/generators/cgi_common.h @@ -0,0 +1,359 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with @@ -1418,3 +363,1051 @@ http://svn.apache.org/viewvc?view=revision&revision=1867971 + + return OK; /* NOT r->status, even if it has changed. */ +} +diff --git a/modules/generators/config5.m4 b/modules/generators/config5.m4 +index bf29521..0863553 100644 +--- a/modules/generators/config5.m4 ++++ b/modules/generators/config5.m4 +@@ -78,4 +78,15 @@ fi + + APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current]) + ++AC_ARG_ENABLE(cgid-fdpassing, ++ [APACHE_HELP_STRING(--enable-cgid-fdpassing,Enable experimental mod_cgid support for fd passing)], ++ [if test "$enableval" = "yes"; then ++ AC_CHECK_DECL(CMSG_DATA, ++ [AC_DEFINE([HAVE_CGID_FDPASSING], 1, [Enable FD passing support in mod_cgid])], ++ [AC_MSG_ERROR([cannot support mod_cgid fd-passing on this system])], [ ++#include ++#include ]) ++ fi ++]) ++ + APACHE_MODPATH_FINISH +diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c +index 7e4b126..f438b35 100644 +--- a/modules/generators/mod_cgi.c ++++ b/modules/generators/mod_cgi.c +@@ -92,6 +92,10 @@ typedef struct { + apr_size_t bufbytes; + } cgi_server_conf; + ++typedef struct { ++ apr_interval_time_t timeout; ++} cgi_dirconf; ++ + static void *create_cgi_config(apr_pool_t *p, server_rec *s) + { + cgi_server_conf *c = +@@ -112,6 +116,12 @@ static void *merge_cgi_config(apr_pool_t *p, void *basev, void *overridesv) + return overrides->logname ? overrides : base; + } + ++static void *create_cgi_dirconf(apr_pool_t *p, char *dummy) ++{ ++ cgi_dirconf *c = (cgi_dirconf *) apr_pcalloc(p, sizeof(cgi_dirconf)); ++ return c; ++} ++ + static const char *set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg) + { + server_rec *s = cmd->server; +@@ -150,6 +160,17 @@ static const char *set_scriptlog_buffer(cmd_parms *cmd, void *dummy, + return NULL; + } + ++static const char *set_script_timeout(cmd_parms *cmd, void *dummy, const char *arg) ++{ ++ cgi_dirconf *dc = dummy; ++ ++ if (ap_timeout_parameter_parse(arg, &dc->timeout, "s") != APR_SUCCESS) { ++ return "CGIScriptTimeout has wrong format"; ++ } ++ ++ return NULL; ++} ++ + static const command_rec cgi_cmds[] = + { + AP_INIT_TAKE1("ScriptLog", set_scriptlog, NULL, RSRC_CONF, +@@ -158,6 +179,9 @@ AP_INIT_TAKE1("ScriptLogLength", set_scriptlog_length, NULL, RSRC_CONF, + "the maximum length (in bytes) of the script debug log"), + AP_INIT_TAKE1("ScriptLogBuffer", set_scriptlog_buffer, NULL, RSRC_CONF, + "the maximum size (in bytes) to record of a POST request"), ++AP_INIT_TAKE1("CGIScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_CONF, ++ "The amount of time to wait between successful reads from " ++ "the CGI script, in seconds."), + {NULL} + }; + +@@ -466,23 +490,26 @@ static apr_status_t run_cgi_child(apr_file_t **script_out, + apr_filepath_name_get(r->filename)); + } + else { ++ cgi_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgi_module); ++ apr_interval_time_t timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout; ++ + apr_pool_note_subprocess(p, procnew, APR_KILL_AFTER_TIMEOUT); + + *script_in = procnew->out; + if (!*script_in) + return APR_EBADF; +- apr_file_pipe_timeout_set(*script_in, r->server->timeout); ++ apr_file_pipe_timeout_set(*script_in, timeout); + + if (e_info->prog_type == RUN_AS_CGI) { + *script_out = procnew->in; + if (!*script_out) + return APR_EBADF; +- apr_file_pipe_timeout_set(*script_out, r->server->timeout); ++ apr_file_pipe_timeout_set(*script_out, timeout); + + *script_err = procnew->err; + if (!*script_err) + return APR_EBADF; +- apr_file_pipe_timeout_set(*script_err, r->server->timeout); ++ apr_file_pipe_timeout_set(*script_err, timeout); + } + } + } +@@ -536,209 +563,12 @@ static apr_status_t default_build_command(const char **cmd, const char ***argv, + return APR_SUCCESS; + } + +-static void discard_script_output(apr_bucket_brigade *bb) +-{ +- apr_bucket *e; +- const char *buf; +- apr_size_t len; +- +- for (e = APR_BRIGADE_FIRST(bb); +- e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e); +- e = APR_BRIGADE_FIRST(bb)) +- { +- if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) { +- break; +- } +- apr_bucket_delete(e); +- } +-} +- + #if APR_FILES_AS_SOCKETS +- +-/* A CGI bucket type is needed to catch any output to stderr from the +- * script; see PR 22030. */ +-static const apr_bucket_type_t bucket_type_cgi; +- +-struct cgi_bucket_data { +- apr_pollset_t *pollset; +- request_rec *r; +-}; +- +-/* Create a CGI bucket using pipes from script stdout 'out' +- * and stderr 'err', for request 'r'. */ +-static apr_bucket *cgi_bucket_create(request_rec *r, +- apr_file_t *out, apr_file_t *err, +- apr_bucket_alloc_t *list) +-{ +- apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); +- apr_status_t rv; +- apr_pollfd_t fd; +- struct cgi_bucket_data *data = apr_palloc(r->pool, sizeof *data); +- +- APR_BUCKET_INIT(b); +- b->free = apr_bucket_free; +- b->list = list; +- b->type = &bucket_type_cgi; +- b->length = (apr_size_t)(-1); +- b->start = -1; +- +- /* Create the pollset */ +- rv = apr_pollset_create(&data->pollset, 2, r->pool, 0); +- if (rv != APR_SUCCESS) { +- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01217) +- "apr_pollset_create(); check system or user limits"); +- return NULL; +- } +- +- fd.desc_type = APR_POLL_FILE; +- fd.reqevents = APR_POLLIN; +- fd.p = r->pool; +- fd.desc.f = out; /* script's stdout */ +- fd.client_data = (void *)1; +- rv = apr_pollset_add(data->pollset, &fd); +- if (rv != APR_SUCCESS) { +- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01218) +- "apr_pollset_add(); check system or user limits"); +- return NULL; +- } +- +- fd.desc.f = err; /* script's stderr */ +- fd.client_data = (void *)2; +- rv = apr_pollset_add(data->pollset, &fd); +- if (rv != APR_SUCCESS) { +- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01219) +- "apr_pollset_add(); check system or user limits"); +- return NULL; +- } +- +- data->r = r; +- b->data = data; +- return b; +-} +- +-/* Create a duplicate CGI bucket using given bucket data */ +-static apr_bucket *cgi_bucket_dup(struct cgi_bucket_data *data, +- apr_bucket_alloc_t *list) +-{ +- apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); +- APR_BUCKET_INIT(b); +- b->free = apr_bucket_free; +- b->list = list; +- b->type = &bucket_type_cgi; +- b->length = (apr_size_t)(-1); +- b->start = -1; +- b->data = data; +- return b; +-} +- +-/* Handle stdout from CGI child. Duplicate of logic from the _read +- * method of the real APR pipe bucket implementation. */ +-static apr_status_t cgi_read_stdout(apr_bucket *a, apr_file_t *out, +- const char **str, apr_size_t *len) +-{ +- char *buf; +- apr_status_t rv; +- +- *str = NULL; +- *len = APR_BUCKET_BUFF_SIZE; +- buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */ +- +- rv = apr_file_read(out, buf, len); +- +- if (rv != APR_SUCCESS && rv != APR_EOF) { +- apr_bucket_free(buf); +- return rv; +- } +- +- if (*len > 0) { +- struct cgi_bucket_data *data = a->data; +- apr_bucket_heap *h; +- +- /* Change the current bucket to refer to what we read */ +- a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free); +- h = a->data; +- h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */ +- *str = buf; +- APR_BUCKET_INSERT_AFTER(a, cgi_bucket_dup(data, a->list)); +- } +- else { +- apr_bucket_free(buf); +- a = apr_bucket_immortal_make(a, "", 0); +- *str = a->data; +- } +- return rv; +-} +- +-/* Read method of CGI bucket: polls on stderr and stdout of the child, +- * sending any stderr output immediately away to the error log. */ +-static apr_status_t cgi_bucket_read(apr_bucket *b, const char **str, +- apr_size_t *len, apr_read_type_e block) +-{ +- struct cgi_bucket_data *data = b->data; +- apr_interval_time_t timeout; +- apr_status_t rv; +- int gotdata = 0; +- +- timeout = block == APR_NONBLOCK_READ ? 0 : data->r->server->timeout; +- +- do { +- const apr_pollfd_t *results; +- apr_int32_t num; +- +- rv = apr_pollset_poll(data->pollset, timeout, &num, &results); +- if (APR_STATUS_IS_TIMEUP(rv)) { +- if (timeout) { +- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, data->r, APLOGNO(01220) +- "Timeout waiting for output from CGI script %s", +- data->r->filename); +- return rv; +- } +- else { +- return APR_EAGAIN; +- } +- } +- else if (APR_STATUS_IS_EINTR(rv)) { +- continue; +- } +- else if (rv != APR_SUCCESS) { +- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, data->r, APLOGNO(01221) +- "poll failed waiting for CGI child"); +- return rv; +- } +- +- for (; num; num--, results++) { +- if (results[0].client_data == (void *)1) { +- /* stdout */ +- rv = cgi_read_stdout(b, results[0].desc.f, str, len); +- if (APR_STATUS_IS_EOF(rv)) { +- rv = APR_SUCCESS; +- } +- gotdata = 1; +- } else { +- /* stderr */ +- apr_status_t rv2 = log_script_err(data->r, results[0].desc.f); +- if (APR_STATUS_IS_EOF(rv2)) { +- apr_pollset_remove(data->pollset, &results[0]); +- } +- } +- } +- +- } while (!gotdata); +- +- return rv; +-} +- +-static const apr_bucket_type_t bucket_type_cgi = { +- "CGI", 5, APR_BUCKET_DATA, +- apr_bucket_destroy_noop, +- cgi_bucket_read, +- apr_bucket_setaside_notimpl, +- apr_bucket_split_notimpl, +- apr_bucket_copy_notimpl +-}; +- ++#define WANT_CGI_BUCKET + #endif + ++#include "cgi_common.h" ++ + static int cgi_handler(request_rec *r) + { + int nph; +@@ -757,6 +587,8 @@ static int cgi_handler(request_rec *r) + apr_status_t rv; + cgi_exec_info_t e_info; + conn_rec *c; ++ cgi_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgi_module); ++ apr_interval_time_t timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout; + + if (strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) { + return DECLINED; +@@ -916,10 +748,7 @@ static int cgi_handler(request_rec *r) + AP_DEBUG_ASSERT(script_in != NULL); + + #if APR_FILES_AS_SOCKETS +- apr_file_pipe_timeout_set(script_in, 0); +- apr_file_pipe_timeout_set(script_err, 0); +- +- b = cgi_bucket_create(r, script_in, script_err, c->bucket_alloc); ++ b = cgi_bucket_create(r, dc->timeout, script_in, script_err, c->bucket_alloc); + if (b == NULL) + return HTTP_INTERNAL_SERVER_ERROR; + #else +@@ -929,111 +758,7 @@ static int cgi_handler(request_rec *r) + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + +- /* Handle script return... */ +- if (!nph) { +- const char *location; +- char sbuf[MAX_STRING_LEN]; +- int ret; +- +- if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, +- APLOG_MODULE_INDEX))) +- { +- ret = log_script(r, conf, ret, dbuf, sbuf, bb, script_err); +- +- /* +- * ret could be HTTP_NOT_MODIFIED in the case that the CGI script +- * does not set an explicit status and ap_meets_conditions, which +- * is called by ap_scan_script_header_err_brigade, detects that +- * the conditions of the requests are met and the response is +- * not modified. +- * In this case set r->status and return OK in order to prevent +- * running through the error processing stack as this would +- * break with mod_cache, if the conditions had been set by +- * mod_cache itself to validate a stale entity. +- * BTW: We circumvent the error processing stack anyway if the +- * CGI script set an explicit status code (whatever it is) and +- * the only possible values for ret here are: +- * +- * HTTP_NOT_MODIFIED (set by ap_meets_conditions) +- * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions) +- * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the +- * processing of the response of the CGI script, e.g broken headers +- * or a crashed CGI process). +- */ +- if (ret == HTTP_NOT_MODIFIED) { +- r->status = ret; +- return OK; +- } +- +- return ret; +- } +- +- location = apr_table_get(r->headers_out, "Location"); +- +- if (location && r->status == 200) { +- /* For a redirect whether internal or not, discard any +- * remaining stdout from the script, and log any remaining +- * stderr output, as normal. */ +- discard_script_output(bb); +- apr_brigade_destroy(bb); +- apr_file_pipe_timeout_set(script_err, r->server->timeout); +- log_script_err(r, script_err); +- } +- +- if (location && location[0] == '/' && r->status == 200) { +- /* This redirect needs to be a GET no matter what the original +- * method was. +- */ +- r->method = "GET"; +- r->method_number = M_GET; +- +- /* We already read the message body (if any), so don't allow +- * the redirected request to think it has one. We can ignore +- * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. +- */ +- apr_table_unset(r->headers_in, "Content-Length"); +- +- ap_internal_redirect_handler(location, r); +- return OK; +- } +- else if (location && r->status == 200) { +- /* XXX: Note that if a script wants to produce its own Redirect +- * body, it now has to explicitly *say* "Status: 302" +- */ +- return HTTP_MOVED_TEMPORARILY; +- } +- +- rv = ap_pass_brigade(r->output_filters, bb); +- } +- else /* nph */ { +- struct ap_filter_t *cur; +- +- /* get rid of all filters up through protocol... since we +- * haven't parsed off the headers, there is no way they can +- * work +- */ +- +- cur = r->proto_output_filters; +- while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { +- cur = cur->next; +- } +- r->output_filters = r->proto_output_filters = cur; +- +- rv = ap_pass_brigade(r->output_filters, bb); +- } +- +- /* don't soak up script output if errors occurred writing it +- * out... otherwise, we prolong the life of the script when the +- * connection drops or we stopped sending output for some other +- * reason */ +- if (rv == APR_SUCCESS && !r->connection->aborted) { +- apr_file_pipe_timeout_set(script_err, r->server->timeout); +- log_script_err(r, script_err); +- } +- +- apr_file_close(script_err); +- +- return OK; /* NOT r->status, even if it has changed. */ ++ return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err); + } + + /*============================================================================ +@@ -1268,7 +993,7 @@ static void register_hooks(apr_pool_t *p) + AP_DECLARE_MODULE(cgi) = + { + STANDARD20_MODULE_STUFF, +- NULL, /* dir config creater */ ++ create_cgi_dirconf, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + create_cgi_config, /* server config */ + merge_cgi_config, /* merge server config */ +diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c +index 9f4282c..102d2b3 100644 +--- a/modules/generators/mod_cgid.c ++++ b/modules/generators/mod_cgid.c +@@ -342,15 +342,19 @@ static apr_status_t close_unix_socket(void *thefd) + return close(fd); + } + +-/* deal with incomplete reads and signals +- * assume you really have to read buf_size bytes +- */ +-static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) ++/* Read from the socket dealing with incomplete messages and signals. ++ * Returns 0 on success or errno on failure. Stderr fd passed as ++ * auxiliary data from other end is written to *errfd, or else stderr ++ * fileno if not present. */ ++static apr_status_t sock_readhdr(int fd, int *errfd, void *vbuf, size_t buf_size) + { +- char *buf = vbuf; + int rc; ++#ifndef HAVE_CGID_FDPASSING ++ char *buf = vbuf; + size_t bytes_read = 0; + ++ if (errfd) *errfd = 0; ++ + do { + do { + rc = read(fd, buf + bytes_read, buf_size - bytes_read); +@@ -365,9 +369,60 @@ static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) + } + } while (bytes_read < buf_size); + ++ ++#else /* with FD passing */ ++ struct msghdr msg = {0}; ++ struct iovec vec = {vbuf, buf_size}; ++ struct cmsghdr *cmsg; ++ union { /* union to ensure alignment */ ++ struct cmsghdr cm; ++ char buf[CMSG_SPACE(sizeof(int))]; ++ } u; ++ ++ msg.msg_iov = &vec; ++ msg.msg_iovlen = 1; ++ ++ if (errfd) { ++ msg.msg_control = u.buf; ++ msg.msg_controllen = sizeof(u.buf); ++ *errfd = 0; ++ } ++ ++ /* use MSG_WAITALL to skip loop on truncated reads */ ++ do { ++ rc = recvmsg(fd, &msg, MSG_WAITALL); ++ } while (rc < 0 && errno == EINTR); ++ ++ if (rc == 0) { ++ return ECONNRESET; ++ } ++ else if (rc < 0) { ++ return errno; ++ } ++ else if (rc != buf_size) { ++ /* MSG_WAITALL should ensure the recvmsg blocks until the ++ * entire length is read, but let's be paranoid. */ ++ return APR_INCOMPLETE; ++ } ++ ++ if (errfd ++ && (cmsg = CMSG_FIRSTHDR(&msg)) != NULL ++ && cmsg->cmsg_len == CMSG_LEN(sizeof(*errfd)) ++ && cmsg->cmsg_level == SOL_SOCKET ++ && cmsg->cmsg_type == SCM_RIGHTS) { ++ *errfd = *((int *) CMSG_DATA(cmsg)); ++ } ++#endif ++ + return APR_SUCCESS; + } + ++/* As sock_readhdr but without auxiliary fd passing. */ ++static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) ++{ ++ return sock_readhdr(fd, NULL, vbuf, buf_size); ++} ++ + /* deal with signals + */ + static apr_status_t sock_write(int fd, const void *buf, size_t buf_size) +@@ -384,7 +439,7 @@ static apr_status_t sock_write(int fd, const void *buf, size_t buf_size) + return APR_SUCCESS; + } + +-static apr_status_t sock_writev(int fd, request_rec *r, int count, ...) ++static apr_status_t sock_writev(int fd, int auxfd, request_rec *r, int count, ...) + { + va_list ap; + int rc; +@@ -399,9 +454,39 @@ static apr_status_t sock_writev(int fd, request_rec *r, int count, ...) + } + va_end(ap); + ++#ifndef HAVE_CGID_FDPASSING + do { + rc = writev(fd, vec, count); + } while (rc < 0 && errno == EINTR); ++#else ++ { ++ struct msghdr msg = { 0 }; ++ struct cmsghdr *cmsg; ++ union { /* union for alignment */ ++ char buf[CMSG_SPACE(sizeof(int))]; ++ struct cmsghdr align; ++ } u; ++ ++ msg.msg_iov = vec; ++ msg.msg_iovlen = count; ++ ++ if (auxfd) { ++ msg.msg_control = u.buf; ++ msg.msg_controllen = sizeof(u.buf); ++ ++ cmsg = CMSG_FIRSTHDR(&msg); ++ cmsg->cmsg_level = SOL_SOCKET; ++ cmsg->cmsg_type = SCM_RIGHTS; ++ cmsg->cmsg_len = CMSG_LEN(sizeof(int)); ++ *((int *) CMSG_DATA(cmsg)) = auxfd; ++ } ++ ++ do { ++ rc = sendmsg(fd, &msg, 0); ++ } while (rc < 0 && errno == EINTR); ++ } ++#endif ++ + if (rc < 0) { + return errno; + } +@@ -410,7 +495,7 @@ static apr_status_t sock_writev(int fd, request_rec *r, int count, ...) + } + + static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, +- cgid_req_t *req) ++ int *errfd, cgid_req_t *req) + { + int i; + char **environ; +@@ -421,7 +506,7 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, + r->server = apr_pcalloc(r->pool, sizeof(server_rec)); + + /* read the request header */ +- stat = sock_read(fd, req, sizeof(*req)); ++ stat = sock_readhdr(fd, errfd, req, sizeof(*req)); + if (stat != APR_SUCCESS) { + return stat; + } +@@ -479,14 +564,15 @@ static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, + return APR_SUCCESS; + } + +-static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, +- int req_type) ++static apr_status_t send_req(int fd, apr_file_t *errpipe, request_rec *r, ++ char *argv0, char **env, int req_type) + { + int i; + cgid_req_t req = {0}; + apr_status_t stat; + ap_unix_identity_t * ugid = ap_run_get_suexec_identity(r); + core_dir_config *core_conf = ap_get_core_module_config(r->per_dir_config); ++ int errfd; + + + if (ugid == NULL) { +@@ -507,16 +593,21 @@ static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, + req.args_len = r->args ? strlen(r->args) : 0; + req.loglevel = r->server->log.level; + ++ if (errpipe) ++ apr_os_file_get(&errfd, errpipe); ++ else ++ errfd = 0; ++ + /* Write the request header */ + if (req.args_len) { +- stat = sock_writev(fd, r, 5, ++ stat = sock_writev(fd, errfd, r, 5, + &req, sizeof(req), + r->filename, req.filename_len, + argv0, req.argv0_len, + r->uri, req.uri_len, + r->args, req.args_len); + } else { +- stat = sock_writev(fd, r, 4, ++ stat = sock_writev(fd, errfd, r, 4, + &req, sizeof(req), + r->filename, req.filename_len, + argv0, req.argv0_len, +@@ -531,7 +622,7 @@ static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, + for (i = 0; i < req.env_count; i++) { + apr_size_t curlen = strlen(env[i]); + +- if ((stat = sock_writev(fd, r, 2, &curlen, sizeof(curlen), ++ if ((stat = sock_writev(fd, 0, r, 2, &curlen, sizeof(curlen), + env[i], curlen)) != APR_SUCCESS) { + return stat; + } +@@ -582,20 +673,34 @@ static void daemon_signal_handler(int sig) + } + } + ++/* Callback executed in the forked child process if exec of the CGI ++ * script fails. For the fd-passing case, output to stderr goes to ++ * the client (request handling thread) and is logged via ++ * ap_log_rerror there. For the non-fd-passing case, the "fake" ++ * request_rec passed via userdata is used to log. */ + static void cgid_child_errfn(apr_pool_t *pool, apr_status_t err, + const char *description) + { +- request_rec *r; + void *vr; + + apr_pool_userdata_get(&vr, ERRFN_USERDATA_KEY, pool); +- r = vr; +- +- /* sure we got r, but don't call ap_log_rerror() because we don't +- * have r->headers_in and possibly other storage referenced by +- * ap_log_rerror() +- */ +- ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, APLOGNO(01241) "%s", description); ++ if (vr) { ++ request_rec *r = vr; ++ ++ /* sure we got r, but don't call ap_log_rerror() because we don't ++ * have r->headers_in and possibly other storage referenced by ++ * ap_log_rerror() ++ */ ++ ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, APLOGNO(01241) "%s", description); ++ } ++ else { ++ const char *logstr; ++ ++ logstr = apr_psprintf(pool, APLOGNO(01241) "error spawning CGI child: %s (%pm)\n", ++ description, &err); ++ fputs(logstr, stderr); ++ fflush(stderr); ++ } + } + + static int cgid_server(void *data) +@@ -669,7 +774,7 @@ static int cgid_server(void *data) + } + + while (!daemon_should_exit) { +- int errfileno = STDERR_FILENO; ++ int errfileno; + char *argv0 = NULL; + char **env = NULL; + const char * const *argv; +@@ -709,7 +814,7 @@ static int cgid_server(void *data) + r = apr_pcalloc(ptrans, sizeof(request_rec)); + procnew = apr_pcalloc(ptrans, sizeof(*procnew)); + r->pool = ptrans; +- stat = get_req(sd2, r, &argv0, &env, &cgid_req); ++ stat = get_req(sd2, r, &argv0, &env, &errfileno, &cgid_req); + if (stat != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, stat, + main_server, APLOGNO(01248) +@@ -741,6 +846,16 @@ static int cgid_server(void *data) + continue; + } + ++ if (errfileno == 0) { ++ errfileno = STDERR_FILENO; ++ } ++ else { ++ ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, main_server, ++ "using passed fd %d as stderr", errfileno); ++ /* Limit the received fd lifetime to pool lifetime */ ++ apr_pool_cleanup_register(ptrans, (void *)((long)errfileno), ++ close_unix_socket, close_unix_socket); ++ } + apr_os_file_put(&r->server->error_log, &errfileno, 0, r->pool); + apr_os_file_put(&inout, &sd2, 0, r->pool); + +@@ -800,7 +915,10 @@ static int cgid_server(void *data) + close(sd2); + } + else { +- apr_pool_userdata_set(r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ptrans); ++ if (errfileno == STDERR_FILENO) { ++ /* Used by cgid_child_errfn without fd-passing. */ ++ apr_pool_userdata_set(r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ptrans); ++ } + + argv = (const char * const *)create_argv(r->pool, NULL, NULL, NULL, argv0, r->args); + +@@ -1099,6 +1217,33 @@ static int log_scripterror(request_rec *r, cgid_server_conf * conf, int ret, + return ret; + } + ++/* Soak up stderr from a script and redirect it to the error log. ++ * TODO: log_scripterror() and this could move to cgi_common.h. */ ++static apr_status_t log_script_err(request_rec *r, apr_file_t *script_err) ++{ ++ char argsbuffer[HUGE_STRING_LEN]; ++ char *newline; ++ apr_status_t rv; ++ cgid_server_conf *conf = ap_get_module_config(r->server->module_config, &cgid_module); ++ ++ while ((rv = apr_file_gets(argsbuffer, HUGE_STRING_LEN, ++ script_err)) == APR_SUCCESS) { ++ ++ newline = strchr(argsbuffer, '\n'); ++ if (newline) { ++ char *prev = newline - 1; ++ if (prev >= argsbuffer && *prev == '\r') { ++ newline = prev; ++ } ++ ++ *newline = '\0'; ++ } ++ log_scripterror(r, conf, r->status, 0, argsbuffer); ++ } ++ ++ return rv; ++} ++ + static int log_script(request_rec *r, cgid_server_conf * conf, int ret, + char *dbuf, const char *sbuf, apr_bucket_brigade *bb, + apr_file_t *script_err) +@@ -1204,6 +1349,13 @@ static int log_script(request_rec *r, cgid_server_conf * conf, int ret, + return ret; + } + ++/* Pull in CGI bucket implementation. */ ++#define cgi_server_conf cgid_server_conf ++#ifdef HAVE_CGID_FDPASSING ++#define WANT_CGI_BUCKET ++#endif ++#include "cgi_common.h" ++ + static int connect_to_daemon(int *sdptr, request_rec *r, + cgid_server_conf *conf) + { +@@ -1270,23 +1422,6 @@ static int connect_to_daemon(int *sdptr, request_rec *r, + return OK; + } + +-static void discard_script_output(apr_bucket_brigade *bb) +-{ +- apr_bucket *e; +- const char *buf; +- apr_size_t len; +- +- for (e = APR_BRIGADE_FIRST(bb); +- e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e); +- e = APR_BRIGADE_FIRST(bb)) +- { +- if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) { +- break; +- } +- apr_bucket_delete(e); +- } +-} +- + /**************************************************************** + * + * Actual cgid handling... +@@ -1391,6 +1526,7 @@ static apr_status_t cleanup_script(void *vptr) + + static int cgid_handler(request_rec *r) + { ++ conn_rec *c = r->connection; + int retval, nph, dbpos; + char *argv0, *dbuf; + apr_bucket_brigade *bb; +@@ -1400,10 +1536,11 @@ static int cgid_handler(request_rec *r) + int seen_eos, child_stopped_reading; + int sd; + char **env; +- apr_file_t *tempsock; ++ apr_file_t *tempsock, *script_err, *errpipe_out; + struct cleanup_script_info *info; + apr_status_t rv; + cgid_dirconf *dc; ++ apr_interval_time_t timeout; + + if (strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) { + return DECLINED; +@@ -1412,7 +1549,7 @@ static int cgid_handler(request_rec *r) + conf = ap_get_module_config(r->server->module_config, &cgid_module); + dc = ap_get_module_config(r->per_dir_config, &cgid_module); + +- ++ timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout; + is_included = !strcmp(r->protocol, "INCLUDED"); + + if ((argv0 = strrchr(r->filename, '/')) != NULL) { +@@ -1465,6 +1602,17 @@ static int cgid_handler(request_rec *r) + } + */ + ++#ifdef HAVE_CGID_FDPASSING ++ rv = apr_file_pipe_create(&script_err, &errpipe_out, r->pool); ++ if (rv) { ++ return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, rv, APLOGNO(10176) ++ "could not create pipe for stderr"); ++ } ++#else ++ script_err = NULL; ++ errpipe_out = NULL; ++#endif ++ + /* + * httpd core function used to add common environment variables like + * DOCUMENT_ROOT. +@@ -1477,12 +1625,16 @@ static int cgid_handler(request_rec *r) + return retval; + } + +- rv = send_req(sd, r, argv0, env, CGI_REQ); ++ rv = send_req(sd, errpipe_out, r, argv0, env, CGI_REQ); + if (rv != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01268) + "write to cgi daemon process"); + } + ++ /* The write-end of the pipe is only used by the server, so close ++ * it here. */ ++ if (errpipe_out) apr_file_close(errpipe_out); ++ + info = apr_palloc(r->pool, sizeof(struct cleanup_script_info)); + info->conf = conf; + info->r = r; +@@ -1504,12 +1656,7 @@ static int cgid_handler(request_rec *r) + */ + + apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool); +- if (dc->timeout > 0) { +- apr_file_pipe_timeout_set(tempsock, dc->timeout); +- } +- else { +- apr_file_pipe_timeout_set(tempsock, r->server->timeout); +- } ++ apr_file_pipe_timeout_set(tempsock, timeout); + apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket); + + /* Transfer any put/post args, CERN style... +@@ -1601,114 +1748,19 @@ static int cgid_handler(request_rec *r) + */ + shutdown(sd, 1); + +- /* Handle script return... */ +- if (!nph) { +- conn_rec *c = r->connection; +- const char *location; +- char sbuf[MAX_STRING_LEN]; +- int ret; +- +- bb = apr_brigade_create(r->pool, c->bucket_alloc); +- b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(bb, b); +- b = apr_bucket_eos_create(c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(bb, b); +- +- if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, +- APLOG_MODULE_INDEX))) +- { +- ret = log_script(r, conf, ret, dbuf, sbuf, bb, NULL); +- +- /* +- * ret could be HTTP_NOT_MODIFIED in the case that the CGI script +- * does not set an explicit status and ap_meets_conditions, which +- * is called by ap_scan_script_header_err_brigade, detects that +- * the conditions of the requests are met and the response is +- * not modified. +- * In this case set r->status and return OK in order to prevent +- * running through the error processing stack as this would +- * break with mod_cache, if the conditions had been set by +- * mod_cache itself to validate a stale entity. +- * BTW: We circumvent the error processing stack anyway if the +- * CGI script set an explicit status code (whatever it is) and +- * the only possible values for ret here are: +- * +- * HTTP_NOT_MODIFIED (set by ap_meets_conditions) +- * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions) +- * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the +- * processing of the response of the CGI script, e.g broken headers +- * or a crashed CGI process). +- */ +- if (ret == HTTP_NOT_MODIFIED) { +- r->status = ret; +- return OK; +- } +- +- return ret; +- } +- +- location = apr_table_get(r->headers_out, "Location"); +- +- if (location && location[0] == '/' && r->status == 200) { +- +- /* Soak up all the script output */ +- discard_script_output(bb); +- apr_brigade_destroy(bb); +- /* This redirect needs to be a GET no matter what the original +- * method was. +- */ +- r->method = "GET"; +- r->method_number = M_GET; +- +- /* We already read the message body (if any), so don't allow +- * the redirected request to think it has one. We can ignore +- * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. +- */ +- apr_table_unset(r->headers_in, "Content-Length"); +- +- ap_internal_redirect_handler(location, r); +- return OK; +- } +- else if (location && r->status == 200) { +- /* XXX: Note that if a script wants to produce its own Redirect +- * body, it now has to explicitly *say* "Status: 302" +- */ +- discard_script_output(bb); +- apr_brigade_destroy(bb); +- return HTTP_MOVED_TEMPORARILY; +- } +- +- rv = ap_pass_brigade(r->output_filters, bb); +- if (rv != APR_SUCCESS) { +- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r, +- "Failed to flush CGI output to client"); +- } +- } +- +- if (nph) { +- conn_rec *c = r->connection; +- struct ap_filter_t *cur; +- +- /* get rid of all filters up through protocol... since we +- * haven't parsed off the headers, there is no way they can +- * work +- */ +- +- cur = r->proto_output_filters; +- while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { +- cur = cur->next; +- } +- r->output_filters = r->proto_output_filters = cur; +- +- bb = apr_brigade_create(r->pool, c->bucket_alloc); +- b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(bb, b); +- b = apr_bucket_eos_create(c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(bb, b); +- ap_pass_brigade(r->output_filters, bb); +- } ++ bb = apr_brigade_create(r->pool, c->bucket_alloc); ++#ifdef HAVE_CGID_FDPASSING ++ b = cgi_bucket_create(r, dc->timeout, tempsock, script_err, c->bucket_alloc); ++ if (b == NULL) ++ return HTTP_INTERNAL_SERVER_ERROR; /* should call log_scripterror() w/ _UNAVAILABLE? */ ++#else ++ b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); ++#endif ++ APR_BRIGADE_INSERT_TAIL(bb, b); ++ b = apr_bucket_eos_create(c->bucket_alloc); ++ APR_BRIGADE_INSERT_TAIL(bb, b); + +- return OK; /* NOT r->status, even if it has changed. */ ++ return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err); + } + + +@@ -1825,7 +1877,7 @@ static int include_cmd(include_ctx_t *ctx, ap_filter_t *f, + return retval; + } + +- send_req(sd, r, command, env, SSI_REQ); ++ send_req(sd, NULL, r, command, env, SSI_REQ); + + info = apr_palloc(r->pool, sizeof(struct cleanup_script_info)); + info->conf = conf; diff --git a/httpd-2.4.39-r1842929+.patch b/httpd-2.4.43-r1842929+.patch similarity index 75% rename from httpd-2.4.39-r1842929+.patch rename to httpd-2.4.43-r1842929+.patch index 0bf7292..b926195 100644 --- a/httpd-2.4.39-r1842929+.patch +++ b/httpd-2.4.43-r1842929+.patch @@ -1,13 +1,20 @@ -# ./pullrev.sh 1842929 1842931 1852982 1853631 1857731 -http://svn.apache.org/viewvc?view=revision&revision=1842929 -http://svn.apache.org/viewvc?view=revision&revision=1842931 -http://svn.apache.org/viewvc?view=revision&revision=1852982 -http://svn.apache.org/viewvc?view=revision&revision=1857731 -http://svn.apache.org/viewvc?view=revision&revision=1853631 - ---- httpd-2.4.39/acinclude.m4.r1842929+ -+++ httpd-2.4.39/acinclude.m4 -@@ -45,6 +45,7 @@ +diff --git a/Makefile.in b/Makefile.in +index 06b8c5a..9eeb5c7 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -213,6 +213,7 @@ install-cgi: + install-other: + @test -d $(DESTDIR)$(logfiledir) || $(MKINSTALLDIRS) $(DESTDIR)$(logfiledir) + @test -d $(DESTDIR)$(runtimedir) || $(MKINSTALLDIRS) $(DESTDIR)$(runtimedir) ++ @test -d $(DESTDIR)$(statedir) || $(MKINSTALLDIRS) $(DESTDIR)$(statedir) + @for ext in dll x; do \ + file=apachecore.$$ext; \ + if test -f $$file; then \ +diff --git a/acinclude.m4 b/acinclude.m4 +index 95232f5..5d9d669 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -45,6 +45,7 @@ AC_DEFUN([APACHE_GEN_CONFIG_VARS],[ APACHE_SUBST(installbuilddir) APACHE_SUBST(runtimedir) APACHE_SUBST(proxycachedir) @@ -15,7 +22,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 APACHE_SUBST(other_targets) APACHE_SUBST(progname) APACHE_SUBST(prefix) -@@ -663,6 +664,7 @@ +@@ -688,6 +689,7 @@ AC_DEFUN([APACHE_EXPORT_ARGUMENTS],[ APACHE_SUBST_EXPANDED_ARG(runtimedir) APACHE_SUBST_EXPANDED_ARG(logfiledir) APACHE_SUBST_EXPANDED_ARG(proxycachedir) @@ -23,9 +30,11 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 ]) dnl ---- httpd-2.4.39/configure.in.r1842929+ -+++ httpd-2.4.39/configure.in -@@ -41,7 +41,7 @@ +diff --git a/configure.in b/configure.in +index a63eada..c8f9aa2 100644 +--- a/configure.in ++++ b/configure.in +@@ -41,7 +41,7 @@ dnl Something seems broken here. AC_PREFIX_DEFAULT(/usr/local/apache2) dnl Get the layout here, so we can pass the required variables to apr @@ -34,8 +43,10 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 dnl reparse the configure arguments. APR_PARSE_ARGUMENTS ---- httpd-2.4.39/include/ap_config_layout.h.in.r1842929+ -+++ httpd-2.4.39/include/ap_config_layout.h.in +diff --git a/include/ap_config_layout.h.in b/include/ap_config_layout.h.in +index 2b4a70c..e076f41 100644 +--- a/include/ap_config_layout.h.in ++++ b/include/ap_config_layout.h.in @@ -60,5 +60,7 @@ #define DEFAULT_REL_LOGFILEDIR "@rel_logfiledir@" #define DEFAULT_EXP_PROXYCACHEDIR "@exp_proxycachedir@" @@ -44,9 +55,11 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 +#define DEFAULT_REL_STATEDIR "@rel_statedir@" #endif /* AP_CONFIG_LAYOUT_H */ ---- httpd-2.4.39/include/http_config.h.r1842929+ -+++ httpd-2.4.39/include/http_config.h -@@ -757,6 +757,14 @@ +diff --git a/include/http_config.h b/include/http_config.h +index f9c2d77..c229bc9 100644 +--- a/include/http_config.h ++++ b/include/http_config.h +@@ -757,6 +757,14 @@ AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *fname); */ AP_DECLARE(char *) ap_runtime_dir_relative(apr_pool_t *p, const char *fname); @@ -61,19 +74,11 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 /* Finally, the hook for dynamically loading modules in... */ /** ---- httpd-2.4.39/Makefile.in.r1842929+ -+++ httpd-2.4.39/Makefile.in -@@ -213,6 +213,7 @@ - install-other: - @test -d $(DESTDIR)$(logfiledir) || $(MKINSTALLDIRS) $(DESTDIR)$(logfiledir) - @test -d $(DESTDIR)$(runtimedir) || $(MKINSTALLDIRS) $(DESTDIR)$(runtimedir) -+ @test -d $(DESTDIR)$(statedir) || $(MKINSTALLDIRS) $(DESTDIR)$(statedir) - @for ext in dll x; do \ - file=apachecore.$$ext; \ - if test -f $$file; then \ ---- httpd-2.4.39/modules/dav/fs/mod_dav_fs.c.r1842929+ -+++ httpd-2.4.39/modules/dav/fs/mod_dav_fs.c -@@ -29,6 +29,10 @@ +diff --git a/modules/dav/fs/mod_dav_fs.c b/modules/dav/fs/mod_dav_fs.c +index addfd7e..2389f8f 100644 +--- a/modules/dav/fs/mod_dav_fs.c ++++ b/modules/dav/fs/mod_dav_fs.c +@@ -29,6 +29,10 @@ typedef struct { extern module AP_MODULE_DECLARE_DATA dav_fs_module; @@ -84,7 +89,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 const char *dav_get_lockdb_path(const request_rec *r) { dav_fs_server_conf *conf; -@@ -57,6 +61,24 @@ +@@ -57,6 +61,24 @@ static void *dav_fs_merge_server_config(apr_pool_t *p, return newconf; } @@ -109,7 +114,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 /* * Command handler for the DAVLockDB directive, which is TAKE1 */ -@@ -87,6 +109,8 @@ +@@ -87,6 +109,8 @@ static const command_rec dav_fs_cmds[] = static void register_hooks(apr_pool_t *p) { @@ -118,9 +123,11 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 dav_hook_gather_propsets(dav_fs_gather_propsets, NULL, NULL, APR_HOOK_MIDDLE); dav_hook_find_liveprop(dav_fs_find_liveprop, NULL, NULL, APR_HOOK_MIDDLE); ---- httpd-2.4.39/server/core.c.r1842929+ -+++ httpd-2.4.39/server/core.c -@@ -129,6 +129,8 @@ +diff --git a/server/core.c b/server/core.c +index 3db9d61..79b2a82 100644 +--- a/server/core.c ++++ b/server/core.c +@@ -129,6 +129,8 @@ AP_DECLARE_DATA int ap_main_state = AP_SQ_MS_INITIAL_STARTUP; AP_DECLARE_DATA int ap_run_mode = AP_SQ_RM_UNKNOWN; AP_DECLARE_DATA int ap_config_generation = 0; @@ -129,7 +136,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 static void *create_core_dir_config(apr_pool_t *a, char *dir) { core_dir_config *conf; -@@ -1409,12 +1411,15 @@ +@@ -1409,12 +1411,15 @@ AP_DECLARE(const char *) ap_resolve_env(apr_pool_t *p, const char * word) return res_buf; } @@ -147,7 +154,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 } /* -@@ -3113,6 +3118,24 @@ +@@ -3120,6 +3125,24 @@ static const char *set_runtime_dir(cmd_parms *cmd, void *dummy, const char *arg) return NULL; } @@ -172,7 +179,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg) { const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT); -@@ -4407,6 +4430,8 @@ +@@ -4414,6 +4437,8 @@ AP_INIT_TAKE1("ServerRoot", set_server_root, NULL, RSRC_CONF | EXEC_ON_READ, "Common directory of server-related files (logs, confs, etc.)"), AP_INIT_TAKE1("DefaultRuntimeDir", set_runtime_dir, NULL, RSRC_CONF | EXEC_ON_READ, "Common directory for run-time files (shared memory, locks, etc.)"), @@ -181,7 +188,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 AP_INIT_TAKE1("ErrorLog", set_server_string_slot, (void *)APR_OFFSETOF(server_rec, error_fname), RSRC_CONF, "The filename of the error log"), -@@ -4934,8 +4959,7 @@ +@@ -4941,8 +4966,7 @@ static int core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptem if (!saved_server_config_defines) init_config_defines(pconf); @@ -189,9 +196,9 @@ http://svn.apache.org/viewvc?view=revision&revision=1853631 - apr_pool_cleanup_null); + apr_pool_cleanup_register(pconf, NULL, reset_config, apr_pool_cleanup_null); - ap_regcomp_set_default_cflags(AP_REG_DOLLAR_ENDONLY); + ap_regcomp_set_default_cflags(AP_REG_DEFAULT); -@@ -5163,6 +5187,27 @@ +@@ -5170,6 +5194,27 @@ AP_DECLARE(int) ap_state_query(int query) } } diff --git a/httpd-2.4.39-r1861269.patch b/httpd-2.4.43-r1861269.patch similarity index 66% rename from httpd-2.4.39-r1861269.patch rename to httpd-2.4.43-r1861269.patch index 4142e3c..9bff242 100644 --- a/httpd-2.4.39-r1861269.patch +++ b/httpd-2.4.43-r1861269.patch @@ -1,12 +1,8 @@ -# ./pullrev.sh r1861269 -http://svn.apache.org/viewvc?view=revision&revision=r1861269 - -Allows "httpd -L" etc to work before httpd-init.service has run, -if mod_ssl is installed. - ---- httpd-2.4.37/modules/ssl/ssl_engine_config.c -+++ httpd-2.4.37/modules/ssl/ssl_engine_config.c -@@ -904,8 +904,14 @@ +diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c +index b53f3f8..979489c 100644 +--- a/modules/ssl/ssl_engine_config.c ++++ b/modules/ssl/ssl_engine_config.c +@@ -812,8 +812,14 @@ const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd, static const char *ssl_cmd_check_file(cmd_parms *parms, const char **file) { diff --git a/httpd-2.4.37-r1861793+.patch b/httpd-2.4.43-r1861793+.patch similarity index 88% rename from httpd-2.4.37-r1861793+.patch rename to httpd-2.4.43-r1861793+.patch index 22886e2..d1afb60 100644 --- a/httpd-2.4.37-r1861793+.patch +++ b/httpd-2.4.43-r1861793+.patch @@ -1,12 +1,8 @@ -# ./pullrev.sh 1861793 1862611 1862612 -http://svn.apache.org/viewvc?view=revision&revision=1861793 - -http://svn.apache.org/viewvc?view=revision&revision=1862611 -http://svn.apache.org/viewvc?view=revision&revision=1862612 - ---- httpd-2.4.37/configure.in -+++ httpd-2.4.37/configure.in -@@ -500,6 +500,28 @@ +diff --git a/configure.in b/configure.in +index cb43246..0bb6b0d 100644 +--- a/configure.in ++++ b/configure.in +@@ -465,6 +465,28 @@ LIBS="" AC_SEARCH_LIBS(crypt, crypt) CRYPT_LIBS="$LIBS" APACHE_SUBST(CRYPT_LIBS) @@ -35,9 +31,89 @@ http://svn.apache.org/viewvc?view=revision&revision=1862612 LIBS="$saved_LIBS" dnl See Comment #Spoon ---- httpd-2.4.37/support/htpasswd.c -+++ httpd-2.4.37/support/htpasswd.c -@@ -109,17 +109,21 @@ +diff --git a/docs/man/htpasswd.1 b/docs/man/htpasswd.1 +index d0ad7e8..2bf8405 100644 +--- a/docs/man/htpasswd.1 ++++ b/docs/man/htpasswd.1 +@@ -27,16 +27,16 @@ htpasswd \- Manage user files for basic authentication + .SH "SYNOPSIS" + + .PP +-\fB\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR\fR ++\fB\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR\fR + + .PP +-\fB\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR\fR ++\fB\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR\fR + + .PP +-\fB\fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR\fR ++\fB\fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR\fR + + .PP +-\fB\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR \fIpassword\fR\fR ++\fB\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR \fIpassword\fR\fR + + + .SH "SUMMARY" +@@ -48,7 +48,7 @@ htpasswd \- Manage user files for basic authentication + Resources available from the Apache HTTP server can be restricted to just the users listed in the files created by \fBhtpasswd\fR\&. This program can only manage usernames and passwords stored in a flat-file\&. It can encrypt and display password information for use in other types of data stores, though\&. To use a DBM database see dbmmanage or htdbm\&. + + .PP +-\fBhtpasswd\fR encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA1, or the system's \fBcrypt()\fR routine\&. Files managed by \fBhtpasswd\fR may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-encrypted passwords while others in the same file may have passwords encrypted with \fBcrypt()\fR\&. ++\fBhtpasswd\fR encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA-1, or the system's \fBcrypt()\fR routine\&. SHA-2-based hashes (SHA-256 and SHA-512) are supported for \fBcrypt()\fR\&. Files managed by \fBhtpasswd\fR may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-encrypted passwords while others in the same file may have passwords encrypted with \fBcrypt()\fR\&. + + .PP + This manual page only lists the command line arguments\&. For details of the directives necessary to configure user authentication in httpd see the Apache manual, which is part of the Apache distribution or can be found at http://httpd\&.apache\&.org/\&. +@@ -73,17 +73,26 @@ Display the results on standard output rather than updating a file\&. This is us + \fB-m\fR + Use MD5 encryption for passwords\&. This is the default (since version 2\&.2\&.18)\&. + .TP ++\fB-2\fR ++Use SHA-256 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&. ++.TP ++\fB-5\fR ++Use SHA-512 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&. ++.TP + \fB-B\fR + Use bcrypt encryption for passwords\&. This is currently considered to be very secure\&. + .TP + \fB-C\fR + This flag is only allowed in combination with \fB-B\fR (bcrypt encryption)\&. It sets the computing time used for the bcrypt algorithm (higher is more secure but slower, default: 5, valid: 4 to 17)\&. + .TP ++\fB-r\fR ++This flag is only allowed in combination with \fB-2\fR or \fB-5\fR\&. It sets the number of hash rounds used for the SHA-2 algorithms (higher is more secure but slower; the default is 5,000)\&. ++.TP + \fB-d\fR + Use \fBcrypt()\fR encryption for passwords\&. This is not supported by the httpd server on Windows and Netware\&. This algorithm limits the password length to 8 characters\&. This algorithm is \fBinsecure\fR by today's standards\&. It used to be the default algorithm until version 2\&.2\&.17\&. + .TP + \fB-s\fR +-Use SHA encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&. ++Use SHA-1 (160-bit) encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&. + .TP + \fB-p\fR + Use plaintext passwords\&. Though \fBhtpasswd\fR will support creation on all platforms, the httpd daemon will only accept plain text passwords on Windows and Netware\&. +@@ -152,10 +161,13 @@ The use of the \fB-b\fR option is discouraged, since when it is used the unencry + When using the \fBcrypt()\fR algorithm, note that only the first 8 characters of the password are used to form the password\&. If the supplied password is longer, the extra characters will be silently discarded\&. + + .PP +-The SHA encryption format does not use salting: for a given password, there is only one encrypted representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&. ++The SHA-1 encryption format does not use salting: for a given password, there is only one encrypted representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&. ++ ++.PP ++The SHA-1 and \fBcrypt()\fR formats are insecure by today's standards\&. + + .PP +-The SHA and \fBcrypt()\fR formats are insecure by today's standards\&. ++The SHA-2-based \fBcrypt()\fR formats (SHA-256 and SHA-512) are supported on most modern Unix systems, and follow the specification at https://www\&.akkadia\&.org/drepper/SHA-crypt\&.txt\&. + + .SH "RESTRICTIONS" + +diff --git a/support/htpasswd.c b/support/htpasswd.c +index 73b291d..7366dcb 100644 +--- a/support/htpasswd.c ++++ b/support/htpasswd.c +@@ -109,17 +109,21 @@ static void usage(void) "for it." NL " -i Read password from stdin without verification (for script usage)." NL " -m Force MD5 encryption of the password (default)." NL @@ -62,7 +138,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1862612 "MD5 algorithm." NL, BCRYPT_DEFAULT_COST ); -@@ -178,7 +182,7 @@ +@@ -178,7 +182,7 @@ static void check_args(int argc, const char *const argv[], if (rv != APR_SUCCESS) exit(ERR_SYNTAX); @@ -71,9 +147,11 @@ http://svn.apache.org/viewvc?view=revision&revision=1862612 switch (opt) { case 'c': *mask |= APHTP_NEWFILE; ---- httpd-2.4.37/support/passwd_common.c -+++ httpd-2.4.37/support/passwd_common.c -@@ -185,10 +185,15 @@ +diff --git a/support/passwd_common.c b/support/passwd_common.c +index 664e509..d45657c 100644 +--- a/support/passwd_common.c ++++ b/support/passwd_common.c +@@ -185,10 +185,15 @@ int mkhash(struct passwd_ctx *ctx) #if CRYPT_ALGO_SUPPORTED char *cbuf; #endif @@ -91,7 +169,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1862612 } if (ctx->passwd == NULL) { -@@ -246,6 +251,34 @@ +@@ -246,6 +251,34 @@ int mkhash(struct passwd_ctx *ctx) break; #endif /* CRYPT_ALGO_SUPPORTED */ @@ -126,7 +204,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1862612 #if BCRYPT_ALGO_SUPPORTED case ALG_BCRYPT: rv = apr_generate_random_bytes((unsigned char*)salt, 16); -@@ -294,6 +327,19 @@ +@@ -294,6 +327,19 @@ int parse_common_options(struct passwd_ctx *ctx, char opt, case 's': ctx->alg = ALG_APSHA; break; @@ -146,7 +224,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1862612 case 'p': ctx->alg = ALG_PLAIN; #if !PLAIN_ALGO_SUPPORTED -@@ -324,11 +370,12 @@ +@@ -324,11 +370,12 @@ int parse_common_options(struct passwd_ctx *ctx, char opt, return ERR_ALG_NOT_SUPP; #endif break; @@ -161,8 +239,10 @@ http://svn.apache.org/viewvc?view=revision&revision=1862612 return ERR_SYNTAX; } ctx->cost = num; ---- httpd-2.4.37/support/passwd_common.h -+++ httpd-2.4.37/support/passwd_common.h +diff --git a/support/passwd_common.h b/support/passwd_common.h +index 660081e..f1b3cd7 100644 +--- a/support/passwd_common.h ++++ b/support/passwd_common.h @@ -28,6 +28,8 @@ #include "apu_version.h" #endif @@ -181,7 +261,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1862612 #define BCRYPT_DEFAULT_COST 5 -@@ -84,7 +88,7 @@ +@@ -84,7 +88,7 @@ struct passwd_ctx { apr_size_t out_len; char *passwd; int alg; @@ -190,81 +270,3 @@ http://svn.apache.org/viewvc?view=revision&revision=1862612 enum { PW_PROMPT = 0, PW_ARG, ---- httpd-2.4.37/docs/man/htpasswd.1 -+++ httpd-2.4.37/docs/man/htpasswd.1 -@@ -27,16 +27,16 @@ - .SH "SYNOPSIS" - - .PP --\fB\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR\fR -+\fB\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR\fR - - .PP --\fB\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR\fR -+\fB\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR\fR - - .PP --\fB\fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR\fR -+\fB\fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR\fR - - .PP --\fB\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR \fIpassword\fR\fR -+\fB\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR \fIpassword\fR\fR - - - .SH "SUMMARY" -@@ -48,7 +48,7 @@ - Resources available from the Apache HTTP server can be restricted to just the users listed in the files created by \fBhtpasswd\fR\&. This program can only manage usernames and passwords stored in a flat-file\&. It can encrypt and display password information for use in other types of data stores, though\&. To use a DBM database see dbmmanage or htdbm\&. - - .PP --\fBhtpasswd\fR encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA1, or the system's \fBcrypt()\fR routine\&. Files managed by \fBhtpasswd\fR may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-encrypted passwords while others in the same file may have passwords encrypted with \fBcrypt()\fR\&. -+\fBhtpasswd\fR encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA-1, or the system's \fBcrypt()\fR routine\&. SHA-2-based hashes (SHA-256 and SHA-512) are supported for \fBcrypt()\fR\&. Files managed by \fBhtpasswd\fR may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-encrypted passwords while others in the same file may have passwords encrypted with \fBcrypt()\fR\&. - - .PP - This manual page only lists the command line arguments\&. For details of the directives necessary to configure user authentication in httpd see the Apache manual, which is part of the Apache distribution or can be found at http://httpd\&.apache\&.org/\&. -@@ -73,6 +73,12 @@ - \fB-m\fR - Use MD5 encryption for passwords\&. This is the default (since version 2\&.2\&.18)\&. - .TP -+\fB-2\fR -+Use SHA-256 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&. -+.TP -+\fB-5\fR -+Use SHA-512 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&. -+.TP - \fB-B\fR - Use bcrypt encryption for passwords\&. This is currently considered to be very secure\&. - .TP -@@ -79,11 +85,14 @@ - \fB-C\fR - This flag is only allowed in combination with \fB-B\fR (bcrypt encryption)\&. It sets the computing time used for the bcrypt algorithm (higher is more secure but slower, default: 5, valid: 4 to 17)\&. - .TP -+\fB-r\fR -+This flag is only allowed in combination with \fB-2\fR or \fB-5\fR\&. It sets the number of hash rounds used for the SHA-2 algorithms (higher is more secure but slower; the default is 5,000)\&. -+.TP - \fB-d\fR - Use \fBcrypt()\fR encryption for passwords\&. This is not supported by the httpd server on Windows and Netware\&. This algorithm limits the password length to 8 characters\&. This algorithm is \fBinsecure\fR by today's standards\&. It used to be the default algorithm until version 2\&.2\&.17\&. - .TP - \fB-s\fR --Use SHA encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&. -+Use SHA-1 (160-bit) encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&. - .TP - \fB-p\fR - Use plaintext passwords\&. Though \fBhtpasswd\fR will support creation on all platforms, the httpd daemon will only accept plain text passwords on Windows and Netware\&. -@@ -152,11 +161,14 @@ - When using the \fBcrypt()\fR algorithm, note that only the first 8 characters of the password are used to form the password\&. If the supplied password is longer, the extra characters will be silently discarded\&. - - .PP --The SHA encryption format does not use salting: for a given password, there is only one encrypted representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&. -+The SHA-1 encryption format does not use salting: for a given password, there is only one encrypted representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&. - - .PP --The SHA and \fBcrypt()\fR formats are insecure by today's standards\&. -+The SHA-1 and \fBcrypt()\fR formats are insecure by today's standards\&. - -+.PP -+The SHA-2-based \fBcrypt()\fR formats (SHA-256 and SHA-512) are supported on most modern Unix systems, and follow the specification at https://www\&.akkadia\&.org/drepper/SHA-crypt\&.txt\&. -+ - .SH "RESTRICTIONS" - - .PP diff --git a/httpd-2.4.41-r1870095+.patch b/httpd-2.4.43-r1870095+.patch similarity index 89% rename from httpd-2.4.41-r1870095+.patch rename to httpd-2.4.43-r1870095+.patch index f29e6f2..3fc8dfb 100644 --- a/httpd-2.4.41-r1870095+.patch +++ b/httpd-2.4.43-r1870095+.patch @@ -1,10 +1,8 @@ -# ./pullrev.sh 1870095 1870097 -http://svn.apache.org/viewvc?view=revision&revision=1870095 -http://svn.apache.org/viewvc?view=revision&revision=1870097 - ---- httpd-2.4.41/modules/ssl/ssl_engine_kernel.c -+++ httpd-2.4.41/modules/ssl/ssl_engine_kernel.c -@@ -114,6 +114,45 @@ +diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c +index cbab6a3..765aa4b 100644 +--- a/modules/ssl/ssl_engine_kernel.c ++++ b/modules/ssl/ssl_engine_kernel.c +@@ -114,6 +114,45 @@ static int has_buffered_data(request_rec *r) return result; } @@ -50,7 +48,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1870097 #ifdef HAVE_TLSEXT static int ap_array_same_str_set(apr_array_header_t *s1, apr_array_header_t *s2) { -@@ -814,41 +853,14 @@ +@@ -814,41 +853,14 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo } } @@ -97,7 +95,7 @@ http://svn.apache.org/viewvc?view=revision&revision=1870097 } } -@@ -1132,6 +1144,17 @@ +@@ -1132,6 +1144,17 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon } } diff --git a/httpd-2.4.25-selinux.patch b/httpd-2.4.43-selinux.patch similarity index 76% rename from httpd-2.4.25-selinux.patch rename to httpd-2.4.43-selinux.patch index fa4614a..3c3176f 100644 --- a/httpd-2.4.25-selinux.patch +++ b/httpd-2.4.43-selinux.patch @@ -1,11 +1,8 @@ - -Log the SELinux context at startup. - -Upstream-Status: unlikely to be any interest in this upstream - ---- httpd-2.4.1/configure.in.selinux -+++ httpd-2.4.1/configure.in -@@ -458,6 +458,11 @@ fopen64 +diff --git a/configure.in b/configure.in +index c8f9aa2..cb43246 100644 +--- a/configure.in ++++ b/configure.in +@@ -484,6 +484,11 @@ getloadavg dnl confirm that a void pointer is large enough to store a long integer APACHE_CHECK_VOID_PTR_LEN @@ -17,9 +14,11 @@ Upstream-Status: unlikely to be any interest in this upstream AC_CACHE_CHECK([for gettid()], ac_cv_gettid, [AC_TRY_RUN(#define _GNU_SOURCE #include ---- httpd-2.4.1/server/core.c.selinux -+++ httpd-2.4.1/server/core.c -@@ -58,6 +58,10 @@ +diff --git a/server/core.c b/server/core.c +index dc0f17a..7ed9527 100644 +--- a/server/core.c ++++ b/server/core.c +@@ -59,6 +59,10 @@ #include #endif @@ -30,7 +29,7 @@ Upstream-Status: unlikely to be any interest in this upstream /* LimitRequestBody handling */ #define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1) #define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0) -@@ -4452,6 +4456,28 @@ static int core_post_config(apr_pool_t * +@@ -5015,6 +5019,28 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte } #endif diff --git a/httpd-2.4.17-socket-activation.patch b/httpd-2.4.43-socket-activation.patch similarity index 99% rename from httpd-2.4.17-socket-activation.patch rename to httpd-2.4.43-socket-activation.patch index dbdd80c..511f476 100644 --- a/httpd-2.4.17-socket-activation.patch +++ b/httpd-2.4.43-socket-activation.patch @@ -1,5 +1,5 @@ diff --git a/server/listen.c b/server/listen.c -index a8e9e6f..1a6c1d3 100644 +index 5242c2a..e2e028a 100644 --- a/server/listen.c +++ b/server/listen.c @@ -34,6 +34,10 @@ diff --git a/httpd-2.4.34-sslciphdefault.patch b/httpd-2.4.43-sslciphdefault.patch similarity index 75% rename from httpd-2.4.34-sslciphdefault.patch rename to httpd-2.4.43-sslciphdefault.patch index 6060f24..85ae568 100644 --- a/httpd-2.4.34-sslciphdefault.patch +++ b/httpd-2.4.43-sslciphdefault.patch @@ -1,11 +1,8 @@ - -https://bugzilla.redhat.com/show_bug.cgi?id=1109119 - -Don't prepend !aNULL etc if PROFILE= is used with SSLCipherSuite. - ---- httpd-2.4.34/modules/ssl/ssl_engine_config.c.sslciphdefault -+++ httpd-2.4.34/modules/ssl/ssl_engine_config.c -@@ -774,9 +774,11 @@ +diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c +index 97778a8..27e7a53 100644 +--- a/modules/ssl/ssl_engine_config.c ++++ b/modules/ssl/ssl_engine_config.c +@@ -778,9 +778,11 @@ const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd, } if (!strcmp("SSL", arg1)) { @@ -19,7 +16,7 @@ Don't prepend !aNULL etc if PROFILE= is used with SSLCipherSuite. dc->szCipherSuite = arg2; } else { -@@ -1540,8 +1542,10 @@ +@@ -1544,8 +1546,10 @@ const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd, } if (!strcmp("SSL", arg1)) { diff --git a/httpd-2.4.33-sslmultiproxy.patch b/httpd-2.4.43-sslmultiproxy.patch similarity index 70% rename from httpd-2.4.33-sslmultiproxy.patch rename to httpd-2.4.43-sslmultiproxy.patch index 679f229..349c4ae 100644 --- a/httpd-2.4.33-sslmultiproxy.patch +++ b/httpd-2.4.43-sslmultiproxy.patch @@ -1,39 +1,30 @@ -From ce2d1d7d4b2bebe34cf37fdeb30d35050092c5b5 Mon Sep 17 00:00:00 2001 -From: Rob Crittenden -Date: Thu, 12 Apr 2018 14:36:28 -0400 -Subject: [PATCH] httpd-2.4.18-sslmultiproxy.patch - ---- - modules/ssl/mod_ssl.c | 24 ++++++++++++++++++++++-- - modules/ssl/ssl_engine_vars.c | 18 +++++++++++++++++- - 2 files changed, 39 insertions(+), 3 deletions(-) - diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c -index 48d64cb..42e85a3 100644 -diff -uap httpd-2.4.33/modules/ssl/mod_ssl.c.sslmultiproxy httpd-2.4.33/modules/ssl/mod_ssl.c ---- httpd-2.4.33/modules/ssl/mod_ssl.c.sslmultiproxy -+++ httpd-2.4.33/modules/ssl/mod_ssl.c -@@ -444,12 +444,19 @@ +index 12617b2..0fe7464 100644 +--- a/modules/ssl/mod_ssl.c ++++ b/modules/ssl/mod_ssl.c +@@ -459,6 +459,10 @@ static int ssl_hook_pre_config(apr_pool_t *pconf, return OK; } +static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *othermod_engine_disable; +static APR_OPTIONAL_FN_TYPE(ssl_engine_set) *othermod_engine_set; ++ + static SSLConnRec *ssl_init_connection_ctx(conn_rec *c, - ap_conf_vector_t *per_dir_config) - { + ap_conf_vector_t *per_dir_config, + int new_proxy) +@@ -466,6 +470,10 @@ static SSLConnRec *ssl_init_connection_ctx(conn_rec *c, SSLConnRec *sslconn = myConnConfig(c); - SSLSrvConfigRec *sc; + int need_setup = 0; + if (othermod_engine_disable) { + othermod_engine_disable(c); + } + - if (sslconn) { - return sslconn; - } -@@ -508,6 +515,10 @@ + /* mod_proxy's (r->)per_dir_config has the lifetime of the request, thus + * it uses ssl_engine_set() to reset sslconn->dc when reusing SSL backend + * connections, so we must fall through here. But in the case where we are +@@ -544,6 +552,10 @@ static int ssl_engine_set(conn_rec *c, { SSLConnRec *sslconn; int status; @@ -43,8 +34,8 @@ diff -uap httpd-2.4.33/modules/ssl/mod_ssl.c.sslmultiproxy httpd-2.4.33/modules/ + } if (proxy) { - sslconn = ssl_init_connection_ctx(c, per_dir_config); -@@ -537,12 +548,18 @@ + sslconn = ssl_init_connection_ctx(c, per_dir_config, 1); +@@ -572,12 +584,18 @@ static int ssl_engine_set(conn_rec *c, static int ssl_proxy_enable(conn_rec *c) { @@ -65,7 +56,7 @@ diff -uap httpd-2.4.33/modules/ssl/mod_ssl.c.sslmultiproxy httpd-2.4.33/modules/ } int ssl_init_ssl_connection(conn_rec *c, request_rec *r) -@@ -730,6 +747,9 @@ +@@ -753,6 +771,9 @@ static void ssl_register_hooks(apr_pool_t *p) APR_HOOK_MIDDLE); ssl_var_register(p); @@ -75,10 +66,11 @@ diff -uap httpd-2.4.33/modules/ssl/mod_ssl.c.sslmultiproxy httpd-2.4.33/modules/ APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable); APR_REGISTER_OPTIONAL_FN(ssl_engine_disable); -diff -uap httpd-2.4.33/modules/ssl/ssl_engine_vars.c.sslmultiproxy httpd-2.4.33/modules/ssl/ssl_engine_vars.c ---- httpd-2.4.33/modules/ssl/ssl_engine_vars.c.sslmultiproxy -+++ httpd-2.4.33/modules/ssl/ssl_engine_vars.c -@@ -54,6 +54,8 @@ +diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c +index 5724f18..81c56ba 100644 +--- a/modules/ssl/ssl_engine_vars.c ++++ b/modules/ssl/ssl_engine_vars.c +@@ -54,6 +54,8 @@ static char *ssl_var_lookup_ssl_cipher(apr_pool_t *p, SSLConnRec *sslconn, char static void ssl_var_lookup_ssl_cipher_bits(SSL *ssl, int *usekeysize, int *algkeysize); static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var); static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl); @@ -87,7 +79,7 @@ diff -uap httpd-2.4.33/modules/ssl/ssl_engine_vars.c.sslmultiproxy httpd-2.4.33/ static SSLConnRec *ssl_get_effective_config(conn_rec *c) { -@@ -68,7 +70,9 @@ +@@ -68,7 +70,9 @@ static SSLConnRec *ssl_get_effective_config(conn_rec *c) static int ssl_is_https(conn_rec *c) { SSLConnRec *sslconn = ssl_get_effective_config(c); @@ -98,7 +90,7 @@ diff -uap httpd-2.4.33/modules/ssl/ssl_engine_vars.c.sslmultiproxy httpd-2.4.33/ } static const char var_interface[] = "mod_ssl/" AP_SERVER_BASEREVISION; -@@ -137,6 +141,9 @@ +@@ -137,6 +141,9 @@ void ssl_var_register(apr_pool_t *p) { char *cp, *cp2; @@ -108,7 +100,7 @@ diff -uap httpd-2.4.33/modules/ssl/ssl_engine_vars.c.sslmultiproxy httpd-2.4.33/ APR_REGISTER_OPTIONAL_FN(ssl_is_https); APR_REGISTER_OPTIONAL_FN(ssl_var_lookup); APR_REGISTER_OPTIONAL_FN(ssl_ext_list); -@@ -271,6 +278,15 @@ +@@ -271,6 +278,15 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, */ if (result == NULL && c != NULL) { SSLConnRec *sslconn = ssl_get_effective_config(c); diff --git a/httpd-2.4.37-sslprotdefault.patch b/httpd-2.4.43-sslprotdefault.patch similarity index 85% rename from httpd-2.4.37-sslprotdefault.patch rename to httpd-2.4.43-sslprotdefault.patch index 546fa1f..d089823 100644 --- a/httpd-2.4.37-sslprotdefault.patch +++ b/httpd-2.4.43-sslprotdefault.patch @@ -1,5 +1,5 @@ diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c -index 55c237e..5467d23 100644 +index 27e7a53..b53f3f8 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -119,7 +119,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p) @@ -11,19 +11,20 @@ index 55c237e..5467d23 100644 mctx->protocol_set = 0; mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET; -@@ -262,6 +262,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p, - { +@@ -263,6 +263,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p, if (add->protocol_set) { + mrg->protocol_set = 1; mrg->protocol = add->protocol; + mrg->protocol_set = 1; } else { - mrg->protocol = base->protocol; + mrg->protocol_set = base->protocol_set; + diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c -index e3f62fe..31fc0e6 100644 +index bfad47a..b0fcf81 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c -@@ -568,6 +568,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, +@@ -577,6 +577,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, MODSSL_SSL_METHOD_CONST SSL_METHOD *method = NULL; char *cp; int protocol = mctx->protocol; @@ -31,7 +32,7 @@ index e3f62fe..31fc0e6 100644 SSLSrvConfigRec *sc = mySrvConfig(s); #if OPENSSL_VERSION_NUMBER >= 0x10100000L int prot; -@@ -577,12 +578,18 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, +@@ -586,12 +587,18 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, * Create the new per-server SSL context */ if (protocol == SSL_PROTOCOL_NONE) { @@ -55,7 +56,7 @@ index e3f62fe..31fc0e6 100644 #ifndef OPENSSL_NO_SSL3 (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""), #endif -@@ -595,7 +602,8 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, +@@ -604,7 +611,8 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, #endif #endif NULL); @@ -65,7 +66,7 @@ index e3f62fe..31fc0e6 100644 ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s, "Creating new SSL context (protocols: %s)", cp); -@@ -696,13 +704,15 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, +@@ -705,13 +713,15 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, prot = SSL3_VERSION; #endif } else { @@ -87,7 +88,7 @@ index e3f62fe..31fc0e6 100644 /* Next we scan for the minimal protocol version we should provide, * but we do not allow holes between max and min */ -@@ -726,7 +736,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, +@@ -731,7 +741,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, prot = SSL3_VERSION; } #endif diff --git a/httpd.spec b/httpd.spec index 2d5e847..6c16a2d 100644 --- a/httpd.spec +++ b/httpd.spec @@ -12,8 +12,8 @@ Summary: Apache HTTP Server Name: httpd -Version: 2.4.41 -Release: 13%{?dist} +Version: 2.4.43 +Release: 1%{?dist} URL: https://httpd.apache.org/ Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2 Source1: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2.asc @@ -62,33 +62,29 @@ Source46: apachectl.sh Source47: apachectl.xml # build/scripts patches -Patch2: httpd-2.4.9-apxs.patch -Patch3: httpd-2.4.1-deplibs.patch +Patch2: httpd-2.4.43-apxs.patch +Patch3: httpd-2.4.43-deplibs.patch # Needed for socket activation and mod_systemd patch -Patch19: httpd-2.4.25-detect-systemd.patch +Patch19: httpd-2.4.43-detect-systemd.patch # Features/functional changes -Patch21: httpd-2.4.39-r1842929+.patch -Patch23: httpd-2.4.39-export.patch -Patch24: httpd-2.4.1-corelimit.patch -Patch25: httpd-2.4.25-selinux.patch -Patch27: httpd-2.4.2-icons.patch -Patch29: httpd-2.4.41-systemd.patch -Patch30: httpd-2.4.4-cachehardmax.patch -Patch31: httpd-2.4.33-sslmultiproxy.patch -Patch34: httpd-2.4.17-socket-activation.patch -Patch36: httpd-2.4.38-r1830819+.patch -Patch38: httpd-2.4.34-sslciphdefault.patch -Patch39: httpd-2.4.37-sslprotdefault.patch -Patch40: httpd-2.4.39-r1861269.patch -Patch41: httpd-2.4.37-r1861793+.patch -Patch42: httpd-2.4.41-r1828172+.patch +Patch21: httpd-2.4.43-r1842929+.patch +Patch23: httpd-2.4.43-export.patch +Patch24: httpd-2.4.43-corelimit.patch +Patch25: httpd-2.4.43-selinux.patch +Patch27: httpd-2.4.43-icons.patch +Patch30: httpd-2.4.43-cachehardmax.patch +Patch31: httpd-2.4.43-sslmultiproxy.patch +Patch34: httpd-2.4.43-socket-activation.patch +Patch38: httpd-2.4.43-sslciphdefault.patch +Patch39: httpd-2.4.43-sslprotdefault.patch +Patch40: httpd-2.4.43-r1861269.patch +Patch41: httpd-2.4.43-r1861793+.patch +Patch42: httpd-2.4.43-r1828172+.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 -Patch58: httpd-2.4.34-r1738878.patch -Patch60: httpd-2.4.34-enable-sslv3.patch -Patch61: httpd-2.4.41-r1865749.patch -Patch62: httpd-2.4.41-r1870095+.patch +Patch60: httpd-2.4.43-enable-sslv3.patch +Patch62: httpd-2.4.43-r1870095+.patch # Security fixes @@ -215,20 +211,16 @@ interface for storing and accessing per-user session data. %patch24 -p1 -b .corelimit %patch25 -p1 -b .selinux %patch27 -p1 -b .icons -%patch29 -p1 -b .systemd %patch30 -p1 -b .cachehardmax #patch31 -p1 -b .sslmultiproxy %patch34 -p1 -b .socketactivation -%patch36 -p1 -b .r1830819+ %patch38 -p1 -b .sslciphdefault %patch39 -p1 -b .sslprotdefault %patch40 -p1 -b .r1861269 %patch41 -p1 -b .r1861793+ %patch42 -p1 -b .r1828172+ -%patch58 -p1 -b .r1738878 %patch60 -p1 -b .enable-sslv3 -%patch61 -p1 -b .r1865749 %patch62 -p1 -b .r1870095 # Patch in the vendor string @@ -329,6 +321,7 @@ export LYNX_PATH=/usr/bin/links --enable-cgid --enable-cgi \ --enable-cgid-fdpassing \ --enable-authn-anon --enable-authn-alias \ + --enable-systemd \ --disable-imagemap --disable-file-cache \ --disable-http2 \ --disable-md \ @@ -753,6 +746,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Tue Mar 31 2020 Lubos Uhliarik - 2.4.43-1 +- new version 2.4.43 (#1819023) + * Wed Jan 29 2020 Fedora Release Engineering - 2.4.41-13 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild diff --git a/sources b/sources index 974c309..9c6c825 100644 --- a/sources +++ b/sources @@ -1,2 +1,3 @@ -SHA512 (httpd-2.4.41.tar.bz2) = 350cc7dcd2c439e0590338fa6da3f44df44f9bb885c381e91f91b14c2f48597f6f0bbac0ea118a8a67eaa70ae7edbb769beace368643ed73f6daee44c307b335 -SHA512 (httpd-2.4.41.tar.bz2.asc) = 3c9173dcaf4e170d87f7cca99e6878424b01d009869742b9077421dbae60acbd102d696e03fccd927f9d688e30f07f9d2d78473ce0bbfbb4a3090ae365121c44 +SHA512 (httpd-2.4.43.tar.bz2) = 16cfeecc8f6fab6eca478065a384bdf1872f7ac42206b0bc2bcac6c0d9c576f392c07107201f39e0601dec1bbafcb33d66153544de4d87d79b9a52094d334b64 +SHA512 (httpd-2.4.43.tar.bz2.asc) = 7a1a12d6f58d8235dcf8b23bae3960e99dc99764928752f870f32e654aa5e3cf78a38fb14f3cb84c5a8ab9b05095beec4739a50c6efcf22e3ecbdf0255ac783d +SHA512 (KEYS) = b776ca20863f8d9e4f66e8b56cbe020de34af5b268e93776d482392171f0e0aeee4f8d74477d128dc9fd24b30bbe33b39439964f1bd22a99782f1e4a08c85056