diff --git a/.fmf/version b/.fmf/version
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/.fmf/version
@@ -0,0 +1 @@
+1
diff --git a/.gitignore b/.gitignore
index bdeafe7..8df7f18 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,3 +33,26 @@ x86_64
/results_httpd
/htcacheclean.service.8
/httpd.conf.5
+/httpd-2.4.41.tar.bz2.asc
+/apachectl.8
+/httpd-2.4.43.tar.bz2.asc
+/KEYS
+/httpd-2.4.46.tar.bz2.asc
+/httpd-2.4.48.tar.bz2.asc
+/httpd-2.4.49.tar.bz2.asc
+/httpd-2.4.50.tar.bz2.asc
+/httpd-2.4.51.tar.bz2.asc
+/httpd-2.4.52.tar.bz2.asc
+/httpd-2.4.53.tar.bz2.asc
+/httpd-2.4.54.tar.bz2.asc
+/httpd-2.4.55.tar.bz2.asc
+/httpd-2.4.56.tar.bz2.asc
+/httpd-2.4.57.tar.bz2.asc
+/httpd-2.4.58.tar.bz2.asc
+/httpd-2.4.59.tar.bz2.asc
+/httpd-2.4.61.tar.bz2.asc
+/httpd-2.4.62.tar.bz2.asc
+/httpd-2.4.63.tar.bz2.asc
+/httpd-2.4.64.tar.bz2.asc
+/httpd-2.4.65.tar.bz2.asc
+/httpd-2.4.66.tar.bz2.asc
diff --git a/00-base.conf b/00-base.conf
index 7cabce0..bae2bf6 100644
--- a/00-base.conf
+++ b/00-base.conf
@@ -15,6 +15,7 @@ LoadModule authn_dbd_module modules/mod_authn_dbd.so
LoadModule authn_dbm_module modules/mod_authn_dbm.so
LoadModule authn_file_module modules/mod_authn_file.so
LoadModule authn_socache_module modules/mod_authn_socache.so
+LoadModule authnz_fcgi_module modules/mod_authnz_fcgi.so
LoadModule authz_core_module modules/mod_authz_core.so
LoadModule authz_dbd_module modules/mod_authz_dbd.so
LoadModule authz_dbm_module modules/mod_authz_dbm.so
@@ -23,7 +24,6 @@ LoadModule authz_host_module modules/mod_authz_host.so
LoadModule authz_owner_module modules/mod_authz_owner.so
LoadModule authz_user_module modules/mod_authz_user.so
LoadModule autoindex_module modules/mod_autoindex.so
-LoadModule brotli_module modules/mod_brotli.so
LoadModule cache_module modules/mod_cache.so
LoadModule cache_disk_module modules/mod_cache_disk.so
LoadModule cache_socache_module modules/mod_cache_socache.so
diff --git a/00-brotli.conf b/00-brotli.conf
new file mode 100644
index 0000000..c2e0e9e
--- /dev/null
+++ b/00-brotli.conf
@@ -0,0 +1 @@
+LoadModule brotli_module modules/mod_brotli.so
diff --git a/apache-poweredby.png b/apache-poweredby.png
new file mode 100644
index 0000000..5663a23
Binary files /dev/null and b/apache-poweredby.png differ
diff --git a/apachectl.sh b/apachectl.sh
index e0f6f78..823db3b 100755
--- a/apachectl.sh
+++ b/apachectl.sh
@@ -15,6 +15,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+###
+### NOTE: This is a replacement version of the "apachectl" script with
+### some differences in behaviour to the version distributed with
+### Apache httpd. Please read the apachectl(8) man page for more
+### information.
+###
+
if [ "x$1" = "x-k" ]; then
shift
fi
@@ -39,14 +46,14 @@ start|stop|restart|status)
;;
graceful)
if /usr/bin/systemctl -q is-active $SVC; then
- /usr/bin/systemctl kill --signal=SIGUSR1 $SVC
+ /usr/bin/systemctl kill --signal=SIGUSR1 --kill-who=main $SVC
else
/usr/bin/systemctl start $SVC
fi
ERROR=$?
;;
graceful-stop)
- /usr/bin/systemctl kill --signal=SIGWINCH $SVC
+ /usr/bin/systemctl kill --signal=SIGWINCH --kill-who=main $SVC
ERROR=$?
;;
configtest|-t)
diff --git a/apachectl.xml b/apachectl.xml
new file mode 100644
index 0000000..217fbda
--- /dev/null
+++ b/apachectl.xml
@@ -0,0 +1,192 @@
+
+[
+
+]>
+
+
+
+ apachectl
+ httpd
+ Apache man pageApache Software Foundation contributors
+ Fedora man pageDanaFrank
+
+
+
+ apachectl
+ 8
+
+
+
+ apachectl
+ Server control interface for httpd
+
+
+
+
+ apachectl
+ command
+
+
+
+
+
+
+ Description
+
+ apachectl is a front end to the Apache HyperText
+ Transfer Protocol (HTTP) server. It is designed to help the
+ administrator control the functioning of the Apache
+ httpd daemon.
+
+ The apachectl script takes one-word arguments like
+ ,
+ , and
+ , and translates them
+ into appropriate signals to httpd.
+
+ The apachectl script returns a 0 exit value on
+ success, and >0 if an error occurs.
+
+
+ Compatibility
+
+ The version of apachectl used on this
+ system is a replacement script intended to be mostly (but not
+ completely) compatible with the version provided with
+ Apache httpd. This
+ apachectl mostly acts as a wrapper around
+ systemctl and manipulates the
+ systemd service for httpd.
+ The interface to the Apache version of
+ apachectl is described at .
+
+ The following differences are present in the version of
+ apachectl present on this system:
+
+
+ Option arguments passed when starting
+ httpd are not allowed. These should be
+ configured in the systemd service directly (see httpd.service8).
+
+ The "fullstatus" option is
+ not available.
+
+ The "status" option does
+ not use or rely on the running server's
+ server-status output.
+
+
+
+
+
+
+
+ Options
+
+
+
+
+ Start the Apache httpd daemon. Gives an error if it
+ is already running. This is equivalent to systemctl start httpd.service.
+
+
+
+
+
+
+ Stops the Apache httpd daemon. This is equivalent to
+ systemctl stop httpd.service.
+
+
+
+
+
+
+ Restarts the Apache httpd daemon. If the daemon is
+ not running, it is started. This is equivalent
+ to systemctl restart httpd.service.
+
+
+
+
+
+
+ Displays a brief status report. This is equivalent to systemctl status httpd.service.
+
+
+
+
+
+
+ Gracefully restarts the Apache httpd daemon. If the
+ daemon is not running, it is started. This differs from a normal
+ restart in that currently open connections are not aborted. A side
+ effect is that old log files will not be closed immediately. This
+ means that if used in a log rotation script, a substantial delay may
+ be necessary to ensure that the old log files are closed before
+ processing them. This is equivalent to
+ systemctl kill --signal=SIGUSR1 --kill-who=main httpd.service.
+
+
+
+
+
+
+ Gracefully stops the Apache httpd daemon.
+ This differs from a normal stop in that currently open connections are not
+ aborted. A side effect is that old log files will not be closed immediately.
+ This is equivalent to
+ systemctl kill --signal=SIGWINCH --kill-who=main httpd.service.
+
+
+
+
+ |
+
+ Run a configuration file syntax test. It parses the configuration
+ files and either reports Syntax OK
+ or detailed information about the particular syntax error. This is
+ equivalent to httpd -t.
+
+
+
+
+
+
+ Reporting Bugs
+ Please report bugs by filing an issue in @BUG_REPORT_URL@.
+
+
+
+ See also
+
+
+ httpd8,
+ httpd.conf5,
+ systemd1,
+ systemctl1,
+ httpd.service8
+
+
+
+
diff --git a/ci.fmf b/ci.fmf
new file mode 100644
index 0000000..c5aa0e0
--- /dev/null
+++ b/ci.fmf
@@ -0,0 +1 @@
+resultsdb-testcase: separate
diff --git a/gating.yaml b/gating.yaml
new file mode 100644
index 0000000..fb11fa9
--- /dev/null
+++ b/gating.yaml
@@ -0,0 +1,27 @@
+--- !Policy
+product_versions:
+ - fedora-*
+decision_contexts: [bodhi_update_push_testing]
+subject_type: koji_build
+rules:
+ - !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/tier1-public.functional}
+
+#gating rawhide
+--- !Policy
+product_versions:
+ - fedora-*
+decision_contexts: [bodhi_update_push_stable]
+subject_type: koji_build
+rules:
+ - !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/tier1-public.functional}
+
+#gating rhel
+--- !Policy
+product_versions:
+ - rhel-*
+decision_context: osci_compose_gate
+rules:
+ - !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}
+ - !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier2.functional}
+ - !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier3.functional}
+ - !PassingTestCaseRule {test_case_name: osci.brew-build./plans/tier1-internal.functional}
diff --git a/htcacheclean.service b/htcacheclean.service
index d1e9d60..e3eeef9 100644
--- a/htcacheclean.service
+++ b/htcacheclean.service
@@ -7,5 +7,10 @@ Documentation=man:htcacheclean.service(8)
Type=forking
User=apache
PIDFile=/run/httpd/htcacheclean/pid
+Environment=LANG=C
EnvironmentFile=/etc/sysconfig/htcacheclean
ExecStart=/usr/sbin/htcacheclean -P /run/httpd/htcacheclean/pid -d $INTERVAL -p $CACHE_ROOT -l $LIMIT $OPTIONS
+PrivateTmp=true
+
+[Install]
+WantedBy=multi-user.target
diff --git a/htcacheclean.service.xml b/htcacheclean.service.xml
index 01b68e4..c2a98d1 100644
--- a/htcacheclean.service.xml
+++ b/htcacheclean.service.xml
@@ -106,6 +106,11 @@
/etc/sysconfig/htcacheclean
+
+ Reporting Bugs
+ Please report bugs by filing an issue in @BUG_REPORT_URL@.
+
+
See also
diff --git a/httpd-2.4.17-socket-activation.patch b/httpd-2.4.17-socket-activation.patch
deleted file mode 100644
index dbdd80c..0000000
--- a/httpd-2.4.17-socket-activation.patch
+++ /dev/null
@@ -1,300 +0,0 @@
-diff --git a/server/listen.c b/server/listen.c
-index a8e9e6f..1a6c1d3 100644
---- a/server/listen.c
-+++ b/server/listen.c
-@@ -34,6 +34,10 @@
- #include
- #endif
-
-+#ifdef HAVE_SYSTEMD
-+#include
-+#endif
-+
- /* we know core's module_index is 0 */
- #undef APLOG_MODULE_INDEX
- #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
-@@ -59,9 +63,12 @@ static int ap_listenbacklog;
- static int ap_listencbratio;
- static int send_buffer_size;
- static int receive_buffer_size;
-+#ifdef HAVE_SYSTEMD
-+static int use_systemd = -1;
-+#endif
-
- /* TODO: make_sock is just begging and screaming for APR abstraction */
--static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
-+static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_listen)
- {
- apr_socket_t *s = server->sd;
- int one = 1;
-@@ -94,20 +101,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
- return stat;
- }
-
--#if APR_HAVE_IPV6
-- if (server->bind_addr->family == APR_INET6) {
-- stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting);
-- if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
-- ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069)
-- "make_sock: for address %pI, apr_socket_opt_set: "
-- "(IPV6_V6ONLY)",
-- server->bind_addr);
-- apr_socket_close(s);
-- return stat;
-- }
-- }
--#endif
--
- /*
- * To send data over high bandwidth-delay connections at full
- * speed we must force the TCP window to open wide enough to keep the
-@@ -169,21 +162,37 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
- }
- #endif
-
-- if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
-- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072)
-- "make_sock: could not bind to address %pI",
-- server->bind_addr);
-- apr_socket_close(s);
-- return stat;
-- }
-+ if (do_bind_listen) {
-+#if APR_HAVE_IPV6
-+ if (server->bind_addr->family == APR_INET6) {
-+ stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting);
-+ if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
-+ ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069)
-+ "make_sock: for address %pI, apr_socket_opt_set: "
-+ "(IPV6_V6ONLY)",
-+ server->bind_addr);
-+ apr_socket_close(s);
-+ return stat;
-+ }
-+ }
-+#endif
-
-- if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
-- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073)
-- "make_sock: unable to listen for connections "
-- "on address %pI",
-- server->bind_addr);
-- apr_socket_close(s);
-- return stat;
-+ if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
-+ ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072)
-+ "make_sock: could not bind to address %pI",
-+ server->bind_addr);
-+ apr_socket_close(s);
-+ return stat;
-+ }
-+
-+ if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
-+ ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073)
-+ "make_sock: unable to listen for connections "
-+ "on address %pI",
-+ server->bind_addr);
-+ apr_socket_close(s);
-+ return stat;
-+ }
- }
-
- #ifdef WIN32
-@@ -315,6 +324,123 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
- return found;
- }
-
-+#ifdef HAVE_SYSTEMD
-+
-+static int find_systemd_socket(process_rec * process, apr_port_t port) {
-+ int fdcount, fd;
-+ int sdc = sd_listen_fds(0);
-+
-+ if (sdc < 0) {
-+ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486)
-+ "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d",
-+ sdc);
-+ return -1;
-+ }
-+
-+ if (sdc == 0) {
-+ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487)
-+ "find_systemd_socket: At least one socket must be set.");
-+ return -1;
-+ }
-+
-+ fdcount = atoi(getenv("LISTEN_FDS"));
-+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) {
-+ if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) {
-+ return fd;
-+ }
-+ }
-+
-+ return -1;
-+}
-+
-+static apr_status_t alloc_systemd_listener(process_rec * process,
-+ int fd, const char *proto,
-+ ap_listen_rec **out_rec)
-+{
-+ apr_status_t rv;
-+ struct sockaddr sa;
-+ socklen_t len = sizeof(struct sockaddr);
-+ apr_os_sock_info_t si;
-+ ap_listen_rec *rec;
-+ *out_rec = NULL;
-+
-+ memset(&si, 0, sizeof(si));
-+
-+ rv = getsockname(fd, &sa, &len);
-+
-+ if (rv != 0) {
-+ rv = apr_get_netos_error();
-+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02489)
-+ "getsockname on %d failed.", fd);
-+ return rv;
-+ }
-+
-+ si.os_sock = &fd;
-+ si.family = sa.sa_family;
-+ si.local = &sa;
-+ si.type = SOCK_STREAM;
-+ si.protocol = APR_PROTO_TCP;
-+
-+ rec = apr_palloc(process->pool, sizeof(ap_listen_rec));
-+ rec->active = 0;
-+ rec->next = 0;
-+
-+
-+ rv = apr_os_sock_make(&rec->sd, &si, process->pool);
-+ if (rv != APR_SUCCESS) {
-+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02490)
-+ "apr_os_sock_make on %d failed.", fd);
-+ return rv;
-+ }
-+
-+ rv = apr_socket_addr_get(&rec->bind_addr, APR_LOCAL, rec->sd);
-+ if (rv != APR_SUCCESS) {
-+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02491)
-+ "apr_socket_addr_get on %d failed.", fd);
-+ return rv;
-+ }
-+
-+ rec->protocol = apr_pstrdup(process->pool, proto);
-+
-+ *out_rec = rec;
-+
-+ return make_sock(process->pool, rec, 0);
-+}
-+
-+static const char *set_systemd_listener(process_rec *process, apr_port_t port,
-+ const char *proto)
-+{
-+ ap_listen_rec *last, *new;
-+ apr_status_t rv;
-+ int fd = find_systemd_socket(process, port);
-+ if (fd < 0) {
-+ return "Systemd socket activation is used, but this port is not "
-+ "configured in systemd";
-+ }
-+
-+ last = ap_listeners;
-+ while (last && last->next) {
-+ last = last->next;
-+ }
-+
-+ rv = alloc_systemd_listener(process, fd, proto, &new);
-+ if (rv != APR_SUCCESS) {
-+ return "Failed to setup socket passed by systemd using socket activation";
-+ }
-+
-+ if (last == NULL) {
-+ ap_listeners = last = new;
-+ }
-+ else {
-+ last->next = new;
-+ last = new;
-+ }
-+
-+ return NULL;
-+}
-+
-+#endif /* HAVE_SYSTEMD */
-+
- static const char *alloc_listener(process_rec *process, const char *addr,
- apr_port_t port, const char* proto,
- void *slave)
-@@ -495,7 +621,7 @@ static int open_listeners(apr_pool_t *pool)
- }
- }
- #endif
-- if (make_sock(pool, lr) == APR_SUCCESS) {
-+ if (make_sock(pool, lr, 1) == APR_SUCCESS) {
- ++num_open;
- }
- else {
-@@ -607,8 +733,28 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
- }
- }
-
-- if (open_listeners(s->process->pool)) {
-- return 0;
-+#ifdef HAVE_SYSTEMD
-+ if (use_systemd) {
-+ const char *userdata_key = "ap_open_systemd_listeners";
-+ void *data;
-+ /* clear the enviroment on our second run
-+ * so that none of our future children get confused.
-+ */
-+ apr_pool_userdata_get(&data, userdata_key, s->process->pool);
-+ if (!data) {
-+ apr_pool_userdata_set((const void *)1, userdata_key,
-+ apr_pool_cleanup_null, s->process->pool);
-+ }
-+ else {
-+ sd_listen_fds(1);
-+ }
-+ }
-+ else
-+#endif
-+ {
-+ if (open_listeners(s->process->pool)) {
-+ return 0;
-+ }
- }
-
- for (lr = ap_listeners; lr; lr = lr->next) {
-@@ -698,7 +844,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
- duplr->bind_addr);
- return stat;
- }
-- make_sock(p, duplr);
-+ make_sock(p, duplr, 1);
- #if AP_NONBLOCK_WHEN_MULTI_LISTEN
- use_nonblock = (ap_listeners && ap_listeners->next);
- stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock);
-@@ -825,6 +971,11 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
- if (argc < 1 || argc > 2) {
- return "Listen requires 1 or 2 arguments.";
- }
-+#ifdef HAVE_SYSTEMD
-+ if (use_systemd == -1) {
-+ use_systemd = sd_listen_fds(0) > 0;
-+ }
-+#endif
-
- rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool);
- if (rv != APR_SUCCESS) {
-@@ -856,6 +1007,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
- ap_str_tolower(proto);
- }
-
-+#ifdef HAVE_SYSTEMD
-+ if (use_systemd) {
-+ return set_systemd_listener(cmd->server->process, port, proto);
-+ }
-+#endif
-+
- return alloc_listener(cmd->server->process, host, port, proto, NULL);
- }
-
diff --git a/httpd-2.4.2-icons.patch b/httpd-2.4.2-icons.patch
deleted file mode 100644
index 1341999..0000000
--- a/httpd-2.4.2-icons.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-
-- 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
- Alias /icons/ "@exp_iconsdir@/"
-
-
-- Options Indexes MultiViews
-+ Options Indexes MultiViews FollowSymlinks
- AllowOverride None
- Require all granted
-
-@@ -53,7 +53,7 @@ AddIcon /icons/dvi.gif .dvi
- AddIcon /icons/uuencoded.gif .uu
- AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
- AddIcon /icons/tex.gif .tex
--AddIcon /icons/bomb.gif core
-+AddIcon /icons/bomb.gif core.
-
- AddIcon /icons/back.gif ..
- AddIcon /icons/hand.right.gif README
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.25-selinux.patch b/httpd-2.4.25-selinux.patch
deleted file mode 100644
index fa4614a..0000000
--- a/httpd-2.4.25-selinux.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-
-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
- dnl confirm that a void pointer is large enough to store a long integer
- APACHE_CHECK_VOID_PTR_LEN
-
-+AC_CHECK_LIB(selinux, is_selinux_enabled, [
-+ AC_DEFINE(HAVE_SELINUX, 1, [Defined if SELinux is supported])
-+ APR_ADDTO(HTTPD_LIBS, [-lselinux])
-+])
-+
- 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 @@
- #include
- #endif
-
-+#ifdef HAVE_SELINUX
-+#include
-+#endif
-+
- /* 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 *
- }
- #endif
-
-+#ifdef HAVE_SELINUX
-+ {
-+ static int already_warned = 0;
-+ int is_enabled = is_selinux_enabled() > 0;
-+
-+ if (is_enabled && !already_warned) {
-+ security_context_t con;
-+
-+ if (getcon(&con) == 0) {
-+
-+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
-+ "SELinux policy enabled; "
-+ "httpd running as context %s", con);
-+
-+ already_warned = 1;
-+
-+ freecon(con);
-+ }
-+ }
-+ }
-+#endif
-+
- return OK;
- }
-
diff --git a/httpd-2.4.33-sslmultiproxy.patch b/httpd-2.4.33-sslmultiproxy.patch
deleted file mode 100644
index 679f229..0000000
--- a/httpd-2.4.33-sslmultiproxy.patch
+++ /dev/null
@@ -1,126 +0,0 @@
-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 @@
- 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)
- {
- SSLConnRec *sslconn = myConnConfig(c);
- SSLSrvConfigRec *sc;
-
-+ if (othermod_engine_disable) {
-+ othermod_engine_disable(c);
-+ }
-+
- if (sslconn) {
- return sslconn;
- }
-@@ -508,6 +515,10 @@
- {
- SSLConnRec *sslconn;
- int status;
-+
-+ if (othermod_engine_set) {
-+ return othermod_engine_set(c, per_dir_config, proxy, enable);
-+ }
-
- if (proxy) {
- sslconn = ssl_init_connection_ctx(c, per_dir_config);
-@@ -537,12 +548,18 @@
-
- static int ssl_proxy_enable(conn_rec *c)
- {
-- return ssl_engine_set(c, NULL, 1, 1);
-+ if (othermod_engine_set)
-+ return othermod_engine_set(c, NULL, 1, 1);
-+ else
-+ return ssl_engine_set(c, NULL, 1, 1);
- }
-
- static int ssl_engine_disable(conn_rec *c)
- {
-- return ssl_engine_set(c, NULL, 0, 0);
-+ if (othermod_engine_set)
-+ return othermod_engine_set(c, NULL, 0, 0);
-+ else
-+ return ssl_engine_set(c, NULL, 0, 0);
- }
-
- int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
-@@ -730,6 +747,9 @@
- APR_HOOK_MIDDLE);
-
- ssl_var_register(p);
-+
-+ othermod_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
-+ othermod_engine_set = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_set);
-
- 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 @@
- 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);
-+static APR_OPTIONAL_FN_TYPE(ssl_is_https) *othermod_is_https;
-+static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *othermod_var_lookup;
-
- static SSLConnRec *ssl_get_effective_config(conn_rec *c)
- {
-@@ -68,7 +70,9 @@
- static int ssl_is_https(conn_rec *c)
- {
- SSLConnRec *sslconn = ssl_get_effective_config(c);
-- return sslconn && sslconn->ssl;
-+
-+ return (sslconn && sslconn->ssl)
-+ || (othermod_is_https && othermod_is_https(c));
- }
-
- static const char var_interface[] = "mod_ssl/" AP_SERVER_BASEREVISION;
-@@ -137,6 +141,9 @@
- {
- char *cp, *cp2;
-
-+ othermod_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
-+ othermod_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
-+
- 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 @@
- */
- if (result == NULL && c != NULL) {
- SSLConnRec *sslconn = ssl_get_effective_config(c);
-+
-+ if (strlen(var) > 4 && strcEQn(var, "SSL_", 4)
-+ && (!sslconn || !sslconn->ssl) && othermod_var_lookup) {
-+ /* For an SSL_* variable, if mod_ssl is not enabled for
-+ * this connection and another SSL module is present, pass
-+ * through to that module. */
-+ return othermod_var_lookup(p, s, c, r, var);
-+ }
-+
- if (strlen(var) > 4 && strcEQn(var, "SSL_", 4)
- && sslconn && sslconn->ssl)
- result = ssl_var_lookup_ssl(p, sslconn, r, var+4);
diff --git a/httpd-2.4.33-systemd.patch b/httpd-2.4.33-systemd.patch
deleted file mode 100644
index 7f5ee3b..0000000
--- a/httpd-2.4.33-systemd.patch
+++ /dev/null
@@ -1,245 +0,0 @@
---- httpd-2.4.33/modules/arch/unix/config5.m4.systemd
-+++ httpd-2.4.33/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.33/modules/arch/unix/mod_systemd.c.systemd
-+++ httpd-2.4.33/modules/arch/unix/mod_systemd.c
-@@ -0,0 +1,223 @@
-+/* 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);
-+}
-+
-+static int systemd_post_config(apr_pool_t *pconf, apr_pool_t *plog,
-+ apr_pool_t *ptemp, server_rec *s)
-+{
-+ 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_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)
-+{
-+ int rv;
-+
-+ mainpid = getpid();
-+
-+ rv = sd_notifyf(0, "READY=1\n"
-+ "STATUS=Started, listening on: %s\n"
-+ "MAINPID=%" APR_PID_T_FMT,
-+ describe_listeners, mainpid);
-+ if (rv < 0) {
-+ ap_log_perror(APLOG_MARK, APLOG_ERR, 0, p, APLOGNO(02395)
-+ "sd_notifyf returned an error %d", rv);
-+ }
-+
-+ 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];
-+ int rv;
-+
-+ if (!ap_extended_status) {
-+ /* Nothing useful to report if ExtendedStatus disabled. */
-+ return DECLINED;
-+ }
-+
-+ ap_get_sload(&sload);
-+
-+ if (sload.access_count == 0) {
-+ rv = 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);
-+
-+ rv = 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);
-+ }
-+
-+ if (rv < 0) {
-+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02396)
-+ "sd_notifyf returned an error %d", rv);
-+ }
-+
-+ /* 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) {
-+ rv = sd_notifyf(0, "READY=1\n"
-+ "STATUS=Stopped as result of IdleShutdown "
-+ "timeout.");
-+ if (rv < 0) {
-+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02804)
-+ "sd_notifyf returned an error %d", rv);
-+ }
-+ 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_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.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.37-r1828172+.patch b/httpd-2.4.37-r1828172+.patch
deleted file mode 100644
index 822cccf..0000000
--- a/httpd-2.4.37-r1828172+.patch
+++ /dev/null
@@ -1,1069 +0,0 @@
-# ./pullrev.sh 1828172 1862968 1863191
-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
-
---- httpd-2.4.37/modules/generators/mod_cgi.c
-+++ httpd-2.4.37/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);
- }
- }
- }
-@@ -563,189 +590,7 @@
- }
-
- #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
--};
--
-+#include "cgi_common.h"
- #endif
-
- static int cgi_handler(request_rec *r)
-@@ -766,6 +611,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;
-@@ -928,7 +775,7 @@
- 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
-@@ -985,7 +832,7 @@
- * stderr output, as normal. */
- discard_script_output(bb);
- apr_brigade_destroy(bb);
-- apr_file_pipe_timeout_set(script_err, r->server->timeout);
-+ apr_file_pipe_timeout_set(script_err, timeout);
- log_script_err(r, script_err);
- }
-
-@@ -1036,7 +883,7 @@
- * 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);
-+ apr_file_pipe_timeout_set(script_err, timeout);
- log_script_err(r, script_err);
- }
-
-@@ -1277,7 +1124,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.37/modules/generators/mod_cgid.c
-+++ httpd-2.4.37/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,52 @@
- }
- } 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;
-+
-+ msg.msg_control = u.buf;
-+ msg.msg_controllen = sizeof(u.buf);
-+
-+ if (errfd) *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;
-+ }
-+
-+ cmsg = CMSG_FIRSTHDR(&msg);
-+ if (errfd
-+ && cmsg
-+ && 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 +431,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 +446,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 +487,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 +498,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 +556,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 +585,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 +614,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 +665,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 +766,7 @@
- }
-
- while (!daemon_should_exit) {
-- int errfileno = STDERR_FILENO;
-+ int errfileno;
- char *argv0 = NULL;
- char **env = NULL;
- const char * const *argv;
-@@ -709,7 +806,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 +838,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 +907,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 +1209,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 +1341,11 @@
- return ret;
- }
-
-+#ifdef HAVE_CGID_FDPASSING
-+/* Pull in CGI bucket implementation. */
-+#include "cgi_common.h"
-+#endif
-+
- static int connect_to_daemon(int *sdptr, request_rec *r,
- cgid_server_conf *conf)
- {
-@@ -1395,6 +1537,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 +1547,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 +1560,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 +1613,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 +1636,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 +1667,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,23 +1759,28 @@
- */
- shutdown(sd, 1);
-
-+ 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);
-+
- /* 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 = log_script(r, conf, ret, dbuf, sbuf, bb, script_err);
-
- /*
- * ret could be HTTP_NOT_MODIFIED in the case that the CGI script
-@@ -1658,6 +1817,11 @@
- /* Soak up all the script output */
- discard_script_output(bb);
- apr_brigade_destroy(bb);
-+ if (script_err) {
-+ apr_file_pipe_timeout_set(script_err, timeout);
-+ log_script_err(r, script_err);
-+ }
-+
- /* This redirect needs to be a GET no matter what the original
- * method was.
- */
-@@ -1690,7 +1854,6 @@
- }
-
- if (nph) {
-- conn_rec *c = r->connection;
- struct ap_filter_t *cur;
-
- /* get rid of all filters up through protocol... since we
-@@ -1704,14 +1867,20 @@
- }
- 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);
-+ 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 (script_err && rv == APR_SUCCESS && !r->connection->aborted) {
-+ apr_file_pipe_timeout_set(script_err, timeout);
-+ log_script_err(r, script_err);
-+ }
-+
-+ if (script_err) apr_file_close(script_err);
-+
- return OK; /* NOT r->status, even if it has changed. */
- }
-
-@@ -1829,7 +1998,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.37/modules/generators/config5.m4
-+++ httpd-2.4.37/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.37/modules/generators/cgi_common.h
-+++ httpd-2.4.37/modules/generators/cgi_common.h
-@@ -0,0 +1,216 @@
-+/* 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 "apr.h"
-+#include "apr_strings.h"
-+#include "apr_buckets.h"
-+#include "apr_lib.h"
-+#include "apr_poll.h"
-+
-+#define APR_WANT_STRFUNC
-+#define APR_WANT_MEMFUNC
-+#include "apr_want.h"
-+
-+#include "httpd.h"
-+#include "util_filter.h"
-+
-+/* 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;
-+ apr_interval_time_t timeout;
-+};
-+
-+/* 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_interval_time_t timeout,
-+ 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;
-+ data->timeout = timeout;
-+ 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 = 0;
-+ apr_status_t rv;
-+ int gotdata = 0;
-+
-+ if (block != APR_NONBLOCK_READ) {
-+ timeout = data->timeout > 0 ? data->timeout : 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
-+};
-+
diff --git a/httpd-2.4.37-r1861793+.patch b/httpd-2.4.37-r1861793+.patch
deleted file mode 100644
index 22886e2..0000000
--- a/httpd-2.4.37-r1861793+.patch
+++ /dev/null
@@ -1,270 +0,0 @@
-# ./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 @@
- AC_SEARCH_LIBS(crypt, crypt)
- CRYPT_LIBS="$LIBS"
- APACHE_SUBST(CRYPT_LIBS)
-+
-+if test "$ac_cv_search_crypt" != "no"; then
-+ # Test crypt() with the SHA-512 test vector from https://akkadia.org/drepper/SHA-crypt.txt
-+ AC_CACHE_CHECK([whether crypt() supports SHA-2], [ap_cv_crypt_sha2], [
-+ AC_RUN_IFELSE([AC_LANG_PROGRAM([[
-+#include
-+#include
-+#include
-+
-+#define PASSWD_0 "Hello world!"
-+#define SALT_0 "\$6\$saltstring"
-+#define EXPECT_0 "\$6\$saltstring\$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu" \
-+ "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1"
-+]], [char *result = crypt(PASSWD_0, SALT_0);
-+ if (!result) return 1;
-+ if (strcmp(result, EXPECT_0)) return 2;
-+])], [ap_cv_crypt_sha2=yes], [ap_cv_crypt_sha2=no])])
-+ if test "$ap_cv_crypt_sha2" = yes; then
-+ AC_DEFINE([HAVE_CRYPT_SHA2], 1, [Define if crypt() supports SHA-2 hashes])
-+ fi
-+fi
-+
- 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 @@
- "for it." NL
- " -i Read password from stdin without verification (for script usage)." NL
- " -m Force MD5 encryption of the password (default)." NL
-- " -B Force bcrypt encryption of the password (very secure)." NL
-+ " -2 Force SHA-256 crypt() hash of the password (very secure)." NL
-+ " -5 Force SHA-512 crypt() hash of the password (very secure)." NL
-+ " -B Force bcrypt aencryption of the password (very secure)." NL
- " -C Set the computing time used for the bcrypt algorithm" NL
- " (higher is more secure but slower, default: %d, valid: 4 to 17)." NL
-+ " -r Set the number of rounds used for the SHA-256, SHA-512 algorithms" NL
-+ " (higher is more secure but slower, default: 5000)." NL
- " -d Force CRYPT encryption of the password (8 chars max, insecure)." NL
-- " -s Force SHA encryption of the password (insecure)." NL
-+ " -s Force SHA-1 encryption of the password (insecure)." NL
- " -p Do not encrypt the password (plaintext, insecure)." NL
- " -D Delete the specified user." NL
- " -v Verify password for the specified user." NL
- "On other systems than Windows and NetWare the '-p' flag will "
- "probably not work." NL
-- "The SHA algorithm does not use a salt and is less secure than the "
-+ "The SHA-1 algorithm does not use a salt and is less secure than the "
- "MD5 algorithm." NL,
- BCRYPT_DEFAULT_COST
- );
-@@ -178,7 +182,7 @@
- if (rv != APR_SUCCESS)
- exit(ERR_SYNTAX);
-
-- while ((rv = apr_getopt(state, "cnmspdBbDiC:v", &opt, &opt_arg)) == APR_SUCCESS) {
-+ while ((rv = apr_getopt(state, "cnmspdBbDi25C:r:v", &opt, &opt_arg)) == APR_SUCCESS) {
- 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 @@
- #if CRYPT_ALGO_SUPPORTED
- char *cbuf;
- #endif
-+#ifdef HAVE_CRYPT_SHA2
-+ const char *setting;
-+ char method;
-+#endif
-
-- if (ctx->cost != 0 && ctx->alg != ALG_BCRYPT) {
-+ if (ctx->cost != 0 && ctx->alg != ALG_BCRYPT
-+ && ctx->alg != ALG_CRYPT_SHA256 && ctx->alg != ALG_CRYPT_SHA512 ) {
- apr_file_printf(errfile,
-- "Warning: Ignoring -C argument for this algorithm." NL);
-+ "Warning: Ignoring -C/-r argument for this algorithm." NL);
- }
-
- if (ctx->passwd == NULL) {
-@@ -246,6 +251,34 @@
- break;
- #endif /* CRYPT_ALGO_SUPPORTED */
-
-+#ifdef HAVE_CRYPT_SHA2
-+ case ALG_CRYPT_SHA256:
-+ case ALG_CRYPT_SHA512:
-+ ret = generate_salt(salt, 16, &ctx->errstr, ctx->pool);
-+ if (ret != 0)
-+ break;
-+
-+ method = ctx->alg == ALG_CRYPT_SHA256 ? '5': '6';
-+
-+ if (ctx->cost)
-+ setting = apr_psprintf(ctx->pool, "$%c$rounds=%d$%s",
-+ method, ctx->cost, salt);
-+ else
-+ setting = apr_psprintf(ctx->pool, "$%c$%s",
-+ method, salt);
-+
-+ cbuf = crypt(pw, setting);
-+ if (cbuf == NULL) {
-+ rv = APR_FROM_OS_ERROR(errno);
-+ ctx->errstr = apr_psprintf(ctx->pool, "crypt() failed: %pm", &rv);
-+ ret = ERR_PWMISMATCH;
-+ break;
-+ }
-+
-+ apr_cpystrn(ctx->out, cbuf, ctx->out_len - 1);
-+ break;
-+#endif /* HAVE_CRYPT_SHA2 */
-+
- #if BCRYPT_ALGO_SUPPORTED
- case ALG_BCRYPT:
- rv = apr_generate_random_bytes((unsigned char*)salt, 16);
-@@ -294,6 +327,19 @@
- case 's':
- ctx->alg = ALG_APSHA;
- break;
-+#ifdef HAVE_CRYPT_SHA2
-+ case '2':
-+ ctx->alg = ALG_CRYPT_SHA256;
-+ break;
-+ case '5':
-+ ctx->alg = ALG_CRYPT_SHA512;
-+ break;
-+#else
-+ case '2':
-+ case '5':
-+ ctx->errstr = "SHA-2 crypt() algorithms are not supported on this platform.";
-+ return ERR_ALG_NOT_SUPP;
-+#endif
- case 'p':
- ctx->alg = ALG_PLAIN;
- #if !PLAIN_ALGO_SUPPORTED
-@@ -324,11 +370,12 @@
- return ERR_ALG_NOT_SUPP;
- #endif
- break;
-- case 'C': {
-+ case 'C':
-+ case 'r': {
- char *endptr;
- long num = strtol(opt_arg, &endptr, 10);
- if (*endptr != '\0' || num <= 0) {
-- ctx->errstr = "argument to -C must be a positive integer";
-+ ctx->errstr = "argument to -C/-r must be a positive integer";
- return ERR_SYNTAX;
- }
- ctx->cost = num;
---- httpd-2.4.37/support/passwd_common.h
-+++ httpd-2.4.37/support/passwd_common.h
-@@ -28,6 +28,8 @@
- #include "apu_version.h"
- #endif
-
-+#include "ap_config_auto.h"
-+
- #define MAX_STRING_LEN 256
-
- #define ALG_PLAIN 0
-@@ -35,6 +37,8 @@
- #define ALG_APMD5 2
- #define ALG_APSHA 3
- #define ALG_BCRYPT 4
-+#define ALG_CRYPT_SHA256 5
-+#define ALG_CRYPT_SHA512 6
-
- #define BCRYPT_DEFAULT_COST 5
-
-@@ -84,7 +88,7 @@
- apr_size_t out_len;
- char *passwd;
- int alg;
-- int cost;
-+ int cost; /* cost for bcrypt, rounds for SHA-2 */
- 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.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.39-r1861269.patch b/httpd-2.4.39-r1861269.patch
deleted file mode 100644
index 4142e3c..0000000
--- a/httpd-2.4.39-r1861269.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-# ./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 @@
- static const char *ssl_cmd_check_file(cmd_parms *parms,
- const char **file)
- {
-- const char *filepath = ap_server_root_relative(parms->pool, *file);
-+ const char *filepath;
-
-+ /* If only dumping the config, don't verify the paths */
-+ if (ap_state_query(AP_SQ_RUN_MODE) == AP_SQ_RM_CONFIG_DUMP) {
-+ return NULL;
-+ }
-+
-+ filepath = ap_server_root_relative(parms->pool, *file);
- if (!filepath) {
- return apr_pstrcat(parms->pool, parms->cmd->name,
- ": Invalid file path ", *file, NULL);
diff --git a/httpd-2.4.4-r1337344+.patch b/httpd-2.4.4-r1337344+.patch
deleted file mode 100644
index 6e5c3e7..0000000
--- a/httpd-2.4.4-r1337344+.patch
+++ /dev/null
@@ -1,250 +0,0 @@
-# ./pullrev.sh 1337344 1341905 1342065 1341930
-
-suexec enhancements:
-
-1) use syslog for logging
-2) use capabilities not setuid/setgid root binary
-
-http://svn.apache.org/viewvc?view=revision&revision=1337344
-http://svn.apache.org/viewvc?view=revision&revision=1341905
-http://svn.apache.org/viewvc?view=revision&revision=1342065
-http://svn.apache.org/viewvc?view=revision&revision=1341930
-
---- httpd-2.4.4/configure.in.r1337344+
-+++ httpd-2.4.4/configure.in
-@@ -734,7 +734,24 @@ APACHE_HELP_STRING(--with-suexec-gidmin,
-
- AC_ARG_WITH(suexec-logfile,
- APACHE_HELP_STRING(--with-suexec-logfile,Set the logfile),[
-- AC_DEFINE_UNQUOTED(AP_LOG_EXEC, "$withval", [SuExec log file] ) ] )
-+ if test "x$withval" = "xyes"; then
-+ AC_DEFINE_UNQUOTED(AP_LOG_EXEC, "$withval", [SuExec log file])
-+ fi
-+])
-+
-+AC_ARG_WITH(suexec-syslog,
-+APACHE_HELP_STRING(--with-suexec-syslog,Set the logfile),[
-+ if test $withval = "yes"; then
-+ if test "x${with_suexec_logfile}" != "xno"; then
-+ AC_MSG_NOTICE([hint: use "--without-suexec-logfile --with-suexec-syslog"])
-+ AC_MSG_ERROR([suexec does not support both logging to file and syslog])
-+ fi
-+ AC_CHECK_FUNCS([vsyslog], [], [
-+ AC_MSG_ERROR([cannot support syslog from suexec without vsyslog()])])
-+ AC_DEFINE(AP_LOG_SYSLOG, 1, [SuExec log to syslog])
-+ fi
-+])
-+
-
- AC_ARG_WITH(suexec-safepath,
- APACHE_HELP_STRING(--with-suexec-safepath,Set the safepath),[
-@@ -744,6 +761,15 @@ AC_ARG_WITH(suexec-umask,
- APACHE_HELP_STRING(--with-suexec-umask,umask for suexec'd process),[
- AC_DEFINE_UNQUOTED(AP_SUEXEC_UMASK, 0$withval, [umask for suexec'd process] ) ] )
-
-+INSTALL_SUEXEC=setuid
-+AC_ARG_ENABLE([suexec-capabilities],
-+APACHE_HELP_STRING(--enable-suexec-capabilities,Use Linux capability bits not setuid root suexec), [
-+INSTALL_SUEXEC=caps
-+AC_DEFINE(AP_SUEXEC_CAPABILITIES, 1,
-+ [Enable if suexec is installed with Linux capabilities, not setuid])
-+])
-+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
- AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool`"
---- httpd-2.4.4/docs/manual/suexec.html.en.r1337344+
-+++ httpd-2.4.4/docs/manual/suexec.html.en
-@@ -372,6 +372,21 @@
- together with the --enable-suexec option to let
- APACI accept your request for using the suEXEC feature.
-
-+
--enable-suexec-capabilities
-+
-+
Linux specific: Normally,
-+ the suexec binary is installed "setuid/setgid
-+ root", which allows it to run with the full privileges of the
-+ root user. If this option is used, the suexec
-+ binary will instead be installed with only the setuid/setgid
-+ "capability" bits set, which is the subset of full root
-+ priviliges required for suexec operation. Note that
-+ the suexec binary may not be able to write to a log
-+ file in this mode; it is recommended that the
-+ --with-suexec-syslog --without-suexec-logfile
-+ options are used in conjunction with this mode, so that syslog
-+ logging is used instead.
-+
-
--with-suexec-bin=PATH
-
-
The path to the suexec binary must be hard-coded
-@@ -433,6 +448,12 @@
- "suexec_log" and located in your standard logfile
- directory (--logfiledir).
-
-+
--with-suexec-syslog
-+
-+
If defined, suexec will log notices and errors to syslog
-+ instead of a logfile. This option must be combined
-+ with --without-suexec-logfile.
-+
-
--with-suexec-safepath=PATH
-
-
Define a safe PATH environment to pass to CGI
-@@ -550,9 +571,12 @@ Group webgroup
-
-
The suEXEC wrapper will write log information
- to the file defined with the --with-suexec-logfile
-- option as indicated above. If you feel you have configured and
-- installed the wrapper properly, have a look at this log and the
-- error_log for the server to see where you may have gone astray.
-+ option as indicated above, or to syslog if --with-suexec-syslog
-+ is used. If you feel you have configured and
-+ installed the wrapper properly, have a look at the log and the
-+ error_log for the server to see where you may have gone astray.
-+ The output of "suexec -V" will show the options
-+ used to compile suexec, if using a binary distribution.