commit f6f9a1666a03ce28621dfa8e5a9426e4d5de887c Author: Toshaan Bharvani Date: Thu May 30 09:46:11 2024 +0200 initial package creation Signed-off-by: Toshaan Bharvani diff --git a/SOURCES/00-base.conf b/SOURCES/00-base.conf new file mode 100644 index 0000000..d0123d1 --- /dev/null +++ b/SOURCES/00-base.conf @@ -0,0 +1,68 @@ +# +# This file loads most of the modules included with the Apache HTTP +# Server itself. +# + +LoadModule access_compat_module modules/mod_access_compat.so +LoadModule actions_module modules/mod_actions.so +LoadModule alias_module modules/mod_alias.so +LoadModule allowmethods_module modules/mod_allowmethods.so +LoadModule auth_basic_module modules/mod_auth_basic.so +LoadModule auth_digest_module modules/mod_auth_digest.so +LoadModule authn_anon_module modules/mod_authn_anon.so +LoadModule authn_core_module modules/mod_authn_core.so +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 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 +LoadModule authz_groupfile_module modules/mod_authz_groupfile.so +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 cache_module modules/mod_cache.so +LoadModule cache_disk_module modules/mod_cache_disk.so +LoadModule cache_socache_module modules/mod_cache_socache.so +LoadModule data_module modules/mod_data.so +LoadModule dbd_module modules/mod_dbd.so +LoadModule deflate_module modules/mod_deflate.so +LoadModule dir_module modules/mod_dir.so +LoadModule dumpio_module modules/mod_dumpio.so +LoadModule echo_module modules/mod_echo.so +LoadModule env_module modules/mod_env.so +LoadModule expires_module modules/mod_expires.so +LoadModule ext_filter_module modules/mod_ext_filter.so +LoadModule filter_module modules/mod_filter.so +LoadModule headers_module modules/mod_headers.so +LoadModule include_module modules/mod_include.so +LoadModule info_module modules/mod_info.so +LoadModule log_config_module modules/mod_log_config.so +LoadModule logio_module modules/mod_logio.so +LoadModule macro_module modules/mod_macro.so +LoadModule mime_magic_module modules/mod_mime_magic.so +LoadModule mime_module modules/mod_mime.so +LoadModule negotiation_module modules/mod_negotiation.so +LoadModule remoteip_module modules/mod_remoteip.so +LoadModule reqtimeout_module modules/mod_reqtimeout.so +LoadModule request_module modules/mod_request.so +LoadModule rewrite_module modules/mod_rewrite.so +LoadModule setenvif_module modules/mod_setenvif.so +LoadModule slotmem_plain_module modules/mod_slotmem_plain.so +LoadModule slotmem_shm_module modules/mod_slotmem_shm.so +LoadModule socache_dbm_module modules/mod_socache_dbm.so +LoadModule socache_memcache_module modules/mod_socache_memcache.so +LoadModule socache_redis_module modules/mod_socache_redis.so +LoadModule socache_shmcb_module modules/mod_socache_shmcb.so +LoadModule status_module modules/mod_status.so +LoadModule substitute_module modules/mod_substitute.so +LoadModule suexec_module modules/mod_suexec.so +LoadModule unique_id_module modules/mod_unique_id.so +LoadModule unixd_module modules/mod_unixd.so +LoadModule userdir_module modules/mod_userdir.so +LoadModule version_module modules/mod_version.so +LoadModule vhost_alias_module modules/mod_vhost_alias.so +LoadModule watchdog_module modules/mod_watchdog.so + diff --git a/SOURCES/00-brotli.conf b/SOURCES/00-brotli.conf new file mode 100644 index 0000000..c2e0e9e --- /dev/null +++ b/SOURCES/00-brotli.conf @@ -0,0 +1 @@ +LoadModule brotli_module modules/mod_brotli.so diff --git a/SOURCES/00-dav.conf b/SOURCES/00-dav.conf new file mode 100644 index 0000000..e6af8de --- /dev/null +++ b/SOURCES/00-dav.conf @@ -0,0 +1,3 @@ +LoadModule dav_module modules/mod_dav.so +LoadModule dav_fs_module modules/mod_dav_fs.so +LoadModule dav_lock_module modules/mod_dav_lock.so diff --git a/SOURCES/00-lua.conf b/SOURCES/00-lua.conf new file mode 100644 index 0000000..9e0d0db --- /dev/null +++ b/SOURCES/00-lua.conf @@ -0,0 +1 @@ +LoadModule lua_module modules/mod_lua.so diff --git a/SOURCES/00-mpm.conf b/SOURCES/00-mpm.conf new file mode 100644 index 0000000..a4a70b8 --- /dev/null +++ b/SOURCES/00-mpm.conf @@ -0,0 +1,23 @@ +# Select the MPM module which should be used by uncommenting exactly +# one of the following LoadModule lines. See the httpd.conf(5) man +# page for more information on changing the MPM. + +# prefork MPM: Implements a non-threaded, pre-forking web server +# See: http://httpd.apache.org/docs/2.4/mod/prefork.html +# +# NOTE: If enabling prefork, the httpd_graceful_shutdown SELinux +# boolean should be enabled, to allow graceful stop/shutdown. +# +#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so + +# worker MPM: Multi-Processing Module implementing a hybrid +# multi-threaded multi-process web server +# See: http://httpd.apache.org/docs/2.4/mod/worker.html +# +#LoadModule mpm_worker_module modules/mod_mpm_worker.so + +# event MPM: A variant of the worker MPM with the goal of consuming +# threads only for connections with active processing +# See: http://httpd.apache.org/docs/2.4/mod/event.html +# +#LoadModule mpm_event_module modules/mod_mpm_event.so diff --git a/SOURCES/00-optional.conf b/SOURCES/00-optional.conf new file mode 100644 index 0000000..53b6bb6 --- /dev/null +++ b/SOURCES/00-optional.conf @@ -0,0 +1,19 @@ +# +# This file lists modules included with the Apache HTTP Server +# which are not enabled by default. +# + +#LoadModule asis_module modules/mod_asis.so +#LoadModule authnz_fcgi_module modules/mod_authnz_fcgi.so +#LoadModule buffer_module modules/mod_buffer.so +#LoadModule heartbeat_module modules/mod_heartbeat.so +#LoadModule heartmonitor_module modules/mod_heartmonitor.so +#LoadModule usertrack_module modules/mod_usertrack.so +#LoadModule dialup_module modules/mod_dialup.so +#LoadModule charset_lite_module modules/mod_charset_lite.so +#LoadModule log_debug_module modules/mod_log_debug.so +#LoadModule log_forensic_module modules/mod_log_forensic.so +#LoadModule ratelimit_module modules/mod_ratelimit.so +#LoadModule reflector_module modules/mod_reflector.so +#LoadModule sed_module modules/mod_sed.so +#LoadModule speling_module modules/mod_speling.so diff --git a/SOURCES/00-proxy.conf b/SOURCES/00-proxy.conf new file mode 100644 index 0000000..f0f84c2 --- /dev/null +++ b/SOURCES/00-proxy.conf @@ -0,0 +1,18 @@ +# This file configures all the proxy modules: +LoadModule proxy_module modules/mod_proxy.so +LoadModule lbmethod_bybusyness_module modules/mod_lbmethod_bybusyness.so +LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so +LoadModule lbmethod_bytraffic_module modules/mod_lbmethod_bytraffic.so +LoadModule lbmethod_heartbeat_module modules/mod_lbmethod_heartbeat.so +LoadModule proxy_ajp_module modules/mod_proxy_ajp.so +LoadModule proxy_balancer_module modules/mod_proxy_balancer.so +LoadModule proxy_connect_module modules/mod_proxy_connect.so +LoadModule proxy_express_module modules/mod_proxy_express.so +LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so +LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so +LoadModule proxy_ftp_module modules/mod_proxy_ftp.so +LoadModule proxy_http_module modules/mod_proxy_http.so +LoadModule proxy_hcheck_module modules/mod_proxy_hcheck.so +LoadModule proxy_scgi_module modules/mod_proxy_scgi.so +LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so +LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so diff --git a/SOURCES/00-proxyhtml.conf b/SOURCES/00-proxyhtml.conf new file mode 100644 index 0000000..9a9b107 --- /dev/null +++ b/SOURCES/00-proxyhtml.conf @@ -0,0 +1,3 @@ +# This file configures mod_proxy_html and mod_xml2enc: +LoadModule xml2enc_module modules/mod_xml2enc.so +LoadModule proxy_html_module modules/mod_proxy_html.so diff --git a/SOURCES/00-ssl.conf b/SOURCES/00-ssl.conf new file mode 100644 index 0000000..53235cd --- /dev/null +++ b/SOURCES/00-ssl.conf @@ -0,0 +1 @@ +LoadModule ssl_module modules/mod_ssl.so diff --git a/SOURCES/00-systemd.conf b/SOURCES/00-systemd.conf new file mode 100644 index 0000000..b208c97 --- /dev/null +++ b/SOURCES/00-systemd.conf @@ -0,0 +1,2 @@ +# This file configures systemd module: +LoadModule systemd_module modules/mod_systemd.so diff --git a/SOURCES/01-cgi.conf b/SOURCES/01-cgi.conf new file mode 100644 index 0000000..4b680cf --- /dev/null +++ b/SOURCES/01-cgi.conf @@ -0,0 +1,11 @@ +# This configuration file loads a CGI module appropriate to the MPM +# which has been configured in 00-mpm.conf. mod_cgid should be used +# with a threaded MPM; mod_cgi with the prefork MPM. + + + LoadModule cgid_module modules/mod_cgid.so + + + LoadModule cgi_module modules/mod_cgi.so + + diff --git a/SOURCES/01-ldap.conf b/SOURCES/01-ldap.conf new file mode 100644 index 0000000..f2ac2a2 --- /dev/null +++ b/SOURCES/01-ldap.conf @@ -0,0 +1,3 @@ +# This file configures the LDAP modules: +LoadModule ldap_module modules/mod_ldap.so +LoadModule authnz_ldap_module modules/mod_authnz_ldap.so diff --git a/SOURCES/01-session.conf b/SOURCES/01-session.conf new file mode 100644 index 0000000..f8d4d92 --- /dev/null +++ b/SOURCES/01-session.conf @@ -0,0 +1,6 @@ +LoadModule session_module modules/mod_session.so +LoadModule session_cookie_module modules/mod_session_cookie.so +LoadModule session_dbd_module modules/mod_session_dbd.so +LoadModule auth_form_module modules/mod_auth_form.so + +#LoadModule session_crypto_module modules/mod_session_crypto.so diff --git a/SOURCES/10-listen443.conf b/SOURCES/10-listen443.conf new file mode 100644 index 0000000..7e2df97 --- /dev/null +++ b/SOURCES/10-listen443.conf @@ -0,0 +1,5 @@ +# This file is part of mod_ssl. It enables listening on port 443 when +# socket activation is used. + +[Socket] +ListenStream=443 diff --git a/SOURCES/README.confd b/SOURCES/README.confd new file mode 100644 index 0000000..6071deb --- /dev/null +++ b/SOURCES/README.confd @@ -0,0 +1,9 @@ + +This directory holds configuration files for the Apache HTTP Server; +any files in this directory which have the ".conf" extension will be +processed as httpd configuration files. The directory is used in +addition to the directory /etc/httpd/conf.modules.d/, which contains +configuration files necessary to load modules. + +Files are processed in sorted order. See httpd.conf(5) for more +information. diff --git a/SOURCES/README.confmod b/SOURCES/README.confmod new file mode 100644 index 0000000..f4b055d --- /dev/null +++ b/SOURCES/README.confmod @@ -0,0 +1,10 @@ + +This directory holds configuration files for the Apache HTTP Server; +any files in this directory which have the ".conf" extension will be +processed as httpd configuration files. This directory contains +configuration fragments necessary only to load modules. +Administrators should use the directory "/etc/httpd/conf.d" to modify +the configuration of httpd, or any modules. + +Files are processed in sorted order and should have a two digit +numeric prefix. See httpd.conf(5) for more information. diff --git a/SOURCES/action-configtest.sh b/SOURCES/action-configtest.sh new file mode 100644 index 0000000..711d9cd --- /dev/null +++ b/SOURCES/action-configtest.sh @@ -0,0 +1,2 @@ +#!/bin/sh +exec /usr/sbin/httpd -t diff --git a/SOURCES/action-graceful.sh b/SOURCES/action-graceful.sh new file mode 100644 index 0000000..4976087 --- /dev/null +++ b/SOURCES/action-graceful.sh @@ -0,0 +1,2 @@ +#!/bin/sh +exec /sbin/apachectl graceful diff --git a/SOURCES/apache-poweredby.png b/SOURCES/apache-poweredby.png new file mode 100644 index 0000000..5663a23 Binary files /dev/null and b/SOURCES/apache-poweredby.png differ diff --git a/SOURCES/apachectl.sh b/SOURCES/apachectl.sh new file mode 100755 index 0000000..823db3b --- /dev/null +++ b/SOURCES/apachectl.sh @@ -0,0 +1,74 @@ +#!/usr/bin/sh +# +# 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. + +### +### 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 + +ACMD="$1" +ARGV="$@" +SVC='httpd.service' +HTTPD='@HTTPDBIN@' + +if [ "x$2" != "x" ] ; then + echo Passing arguments to httpd using apachectl is no longer supported. + echo You can only start/stop/restart httpd using this script. + echo To pass extra arguments to httpd, see the $SVC'(8)' + echo man page. + exit 1 +fi + +case $ACMD in +start|stop|restart|status) + /usr/bin/systemctl --no-pager $ACMD $SVC + ERROR=$? + ;; +graceful) + if /usr/bin/systemctl -q is-active $SVC; then + /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 --kill-who=main $SVC + ERROR=$? + ;; +configtest|-t) + $HTTPD -t + ERROR=$? + ;; +-v|-V) + $HTTPD $ACMD + ERROR=$? + ;; +*) + echo apachectl: The \"$ACMD\" option is not supported. 1>&2 + ERROR=2 + ;; +esac + +exit $ERROR + diff --git a/SOURCES/apachectl.xml b/SOURCES/apachectl.xml new file mode 100644 index 0000000..5e40832 --- /dev/null +++ b/SOURCES/apachectl.xml @@ -0,0 +1,191 @@ + +[ + +]> + + + + 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 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. + + + + + + + Bugs + Please report bugs by filing an issue in Bugzilla via . + + + + See also + + + httpd8, + httpd.conf5, + systemd1, + systemctl1, + httpd.service8 + + + + diff --git a/SOURCES/config.layout b/SOURCES/config.layout new file mode 100644 index 0000000..3a9f6c8 --- /dev/null +++ b/SOURCES/config.layout @@ -0,0 +1,24 @@ +# Layout used in Fedora httpd packaging. + + prefix: /etc/httpd + localstatedir: /var + exec_prefix: /usr + bindir: ${exec_prefix}/bin + sbindir: ${exec_prefix}/sbin + libdir: ${exec_prefix}/lib + libexecdir: ${exec_prefix}/libexec + mandir: ${exec_prefix}/man + sysconfdir: /etc/httpd/conf + datadir: ${exec_prefix}/share/httpd + installbuilddir: ${libdir}/httpd/build + errordir: ${datadir}/error + iconsdir: ${datadir}/icons + htdocsdir: ${localstatedir}/www/html + manualdir: ${datadir}/manual + cgidir: ${localstatedir}/www/cgi-bin + includedir: ${exec_prefix}/include/httpd + runtimedir: ${prefix}/run + logfiledir: ${localstatedir}/log/httpd + statedir: ${prefix}/state + proxycachedir: ${localstatedir}/cache/httpd/proxy + diff --git a/SOURCES/htcacheclean.service b/SOURCES/htcacheclean.service new file mode 100644 index 0000000..d1e9d60 --- /dev/null +++ b/SOURCES/htcacheclean.service @@ -0,0 +1,11 @@ +[Unit] +Description=Disk Cache Cleaning Daemon for the Apache HTTP Server +After=httpd.service +Documentation=man:htcacheclean.service(8) + +[Service] +Type=forking +User=apache +PIDFile=/run/httpd/htcacheclean/pid +EnvironmentFile=/etc/sysconfig/htcacheclean +ExecStart=/usr/sbin/htcacheclean -P /run/httpd/htcacheclean/pid -d $INTERVAL -p $CACHE_ROOT -l $LIMIT $OPTIONS diff --git a/SOURCES/htcacheclean.service.xml b/SOURCES/htcacheclean.service.xml new file mode 100644 index 0000000..01b68e4 --- /dev/null +++ b/SOURCES/htcacheclean.service.xml @@ -0,0 +1,123 @@ + + + + + + htcacheclean systemd unit + httpd + AuthorOrtonJoejorton@redhat.com + + + + htcacheclean.service + 8 + + + + htcacheclean.service + htcacheclean unit file for systemd + + + + + /usr/lib/systemd/system/htcacheclean.service + + + + + Description + + This manual page describes the systemd + unit file for the htcacheclean daemon. This + unit file provides a service which runs + htcacheclean in daemon mode, + periodically cleaning the disk cache root to ensure disk space + usage is within configured limits. + + + + + Options + + The service is configured by configuration file + /etc/sysconfig/htcacheclean. The following + variables are used, following standard systemd + EnvironmentFile= syntax: + + + + INTERVAL= + + Sets the interval between cache clean runs, in + minutes. By default this is configured as + 15. + + + + CACHE_ROOT= + + Sets the directory name used for the cache + root. By default this is configured as + /var/cache/httpd/proxy. + + + + LIMIT= + + Sets the total disk cache space limit, in + bytes. Use a K or M + suffix to signify kilobytes or megabytes. By default this is + set to 100M. + + + + OPTIONS= + + Any other options to pass to + htcacheclean. + + + + + + Files + + /usr/lib/systemd/system/htcacheclean.service, + /etc/sysconfig/htcacheclean + + + + See also + + + htcacheclean8, + httpd8, + httpd.service8, + systemd.exec8 + + + + + + diff --git a/SOURCES/htcacheclean.sysconf b/SOURCES/htcacheclean.sysconf new file mode 100644 index 0000000..fffa17b --- /dev/null +++ b/SOURCES/htcacheclean.sysconf @@ -0,0 +1,16 @@ +# +# Configuration options for systemd service, htcacheclean.service. +# See htcacheclean(8) for more information on available options. +# + +# Interval between cache clean runs, in minutes +INTERVAL=15 + +# Default cache root. +CACHE_ROOT=/var/cache/httpd/proxy + +# Cache size limit in bytes (K=Kbytes, M=Mbytes) +LIMIT=100M + +# Any other options... +OPTIONS= diff --git a/SOURCES/httpd-2.4.43-apxs.patch b/SOURCES/httpd-2.4.43-apxs.patch new file mode 100644 index 0000000..b1185b2 --- /dev/null +++ b/SOURCES/httpd-2.4.43-apxs.patch @@ -0,0 +1,58 @@ +diff --git a/support/apxs.in b/support/apxs.in +index b2705fa..c331631 100644 +--- a/support/apxs.in ++++ b/support/apxs.in +@@ -35,7 +35,18 @@ if ($ddi >= 0) { + + my %config_vars = (); + +-my $installbuilddir = "@exp_installbuilddir@"; ++# Awful hack to make apxs libdir-agnostic: ++my $pkg_config = "/usr/bin/pkg-config"; ++if (! -x "$pkg_config") { ++ error("$pkg_config not found!"); ++ exit(1); ++} ++ ++my $libdir = `pkg-config --variable=libdir apr-1`; ++chomp $libdir; ++ ++my $installbuilddir = $libdir . "/httpd/build"; ++ + get_config_vars($destdir . "$installbuilddir/config_vars.mk",\%config_vars); + + # read the configuration variables once +@@ -285,7 +296,7 @@ if ($opt_g) { + $data =~ s|%NAME%|$name|sg; + $data =~ s|%TARGET%|$CFG_TARGET|sg; + $data =~ s|%PREFIX%|$prefix|sg; +- $data =~ s|%INSTALLBUILDDIR%|$installbuilddir|sg; ++ $data =~ s|%LIBDIR%|$libdir|sg; + + my ($mkf, $mods, $src) = ($data =~ m|^(.+)-=#=-\n(.+)-=#=-\n(.+)|s); + +@@ -463,11 +474,11 @@ if ($opt_c) { + my $ldflags = "$CFG_LDFLAGS"; + if ($opt_p == 1) { + +- my $apr_libs=`$apr_config --cflags --ldflags --link-libtool --libs`; ++ my $apr_libs=`$apr_config --cflags --ldflags --link-libtool`; + chomp($apr_libs); + my $apu_libs=""; + if ($apr_major_version < 2) { +- $apu_libs=`$apu_config --ldflags --link-libtool --libs`; ++ $apu_libs=`$apu_config --ldflags --link-libtool`; + chomp($apu_libs); + } + +@@ -682,8 +693,8 @@ __DATA__ + + builddir=. + top_srcdir=%PREFIX% +-top_builddir=%PREFIX% +-include %INSTALLBUILDDIR%/special.mk ++top_builddir=%LIBDIR%/httpd ++include %LIBDIR%/httpd/build/special.mk + + # the used tools + APACHECTL=apachectl diff --git a/SOURCES/httpd-2.4.43-cachehardmax.patch b/SOURCES/httpd-2.4.43-cachehardmax.patch new file mode 100644 index 0000000..755f822 --- /dev/null +++ b/SOURCES/httpd-2.4.43-cachehardmax.patch @@ -0,0 +1,82 @@ +diff --git a/modules/cache/cache_util.h b/modules/cache/cache_util.h +index 6b92151..4c42a8e 100644 +--- a/modules/cache/cache_util.h ++++ b/modules/cache/cache_util.h +@@ -195,6 +195,9 @@ typedef struct { + unsigned int store_nostore_set:1; + unsigned int enable_set:1; + unsigned int disable_set:1; ++ /* treat maxex as hard limit */ ++ unsigned int hardmaxex:1; ++ unsigned int hardmaxex_set:1; + } cache_dir_conf; + + /* A linked-list of authn providers. */ +diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c +index 3b9aa4f..8268503 100644 +--- a/modules/cache/mod_cache.c ++++ b/modules/cache/mod_cache.c +@@ -1455,6 +1455,11 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in) + exp = date + dconf->defex; + } + } ++ /* else, forcibly cap the expiry date if required */ ++ else if (dconf->hardmaxex && (date + dconf->maxex) < exp) { ++ exp = date + dconf->maxex; ++ } ++ + info->expire = exp; + + /* We found a stale entry which wasn't really stale. */ +@@ -1954,7 +1959,9 @@ static void *create_dir_config(apr_pool_t *p, char *dummy) + + /* array of providers for this URL space */ + dconf->cacheenable = apr_array_make(p, 10, sizeof(struct cache_enable)); +- ++ /* flag; treat maxex as hard limit */ ++ dconf->hardmaxex = 0; ++ dconf->hardmaxex_set = 0; + return dconf; + } + +@@ -2004,7 +2011,10 @@ static void *merge_dir_config(apr_pool_t *p, void *basev, void *addv) { + new->enable_set = add->enable_set || base->enable_set; + new->disable = (add->disable_set == 0) ? base->disable : add->disable; + new->disable_set = add->disable_set || base->disable_set; +- ++ new->hardmaxex = ++ (add->hardmaxex_set == 0) ++ ? base->hardmaxex ++ : add->hardmaxex; + return new; + } + +@@ -2332,12 +2342,18 @@ static const char *add_cache_disable(cmd_parms *parms, void *dummy, + } + + static const char *set_cache_maxex(cmd_parms *parms, void *dummy, +- const char *arg) ++ const char *arg, const char *hard) + { + cache_dir_conf *dconf = (cache_dir_conf *)dummy; + + dconf->maxex = (apr_time_t) (atol(arg) * MSEC_ONE_SEC); + dconf->maxex_set = 1; ++ ++ if (hard && strcasecmp(hard, "hard") == 0) { ++ dconf->hardmaxex = 1; ++ dconf->hardmaxex_set = 1; ++ } ++ + return NULL; + } + +@@ -2545,7 +2561,7 @@ static const command_rec cache_cmds[] = + "caching is enabled"), + AP_INIT_TAKE1("CacheDisable", add_cache_disable, NULL, RSRC_CONF|ACCESS_CONF, + "A partial URL prefix below which caching is disabled"), +- AP_INIT_TAKE1("CacheMaxExpire", set_cache_maxex, NULL, RSRC_CONF|ACCESS_CONF, ++ AP_INIT_TAKE12("CacheMaxExpire", set_cache_maxex, NULL, RSRC_CONF|ACCESS_CONF, + "The maximum time in seconds to cache a document"), + AP_INIT_TAKE1("CacheMinExpire", set_cache_minex, NULL, RSRC_CONF|ACCESS_CONF, + "The minimum time in seconds to cache a document"), diff --git a/SOURCES/httpd-2.4.43-corelimit.patch b/SOURCES/httpd-2.4.43-corelimit.patch new file mode 100644 index 0000000..dd4b874 --- /dev/null +++ b/SOURCES/httpd-2.4.43-corelimit.patch @@ -0,0 +1,30 @@ +diff --git a/server/core.c b/server/core.c +index 79b2a82..dc0f17a 100644 +--- a/server/core.c ++++ b/server/core.c +@@ -4996,6 +4996,25 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte + } + apr_pool_cleanup_register(pconf, NULL, ap_mpm_end_gen_helper, + apr_pool_cleanup_null); ++ ++#ifdef RLIMIT_CORE ++ if (ap_coredumpdir_configured) { ++ struct rlimit lim; ++ ++ if (getrlimit(RLIMIT_CORE, &lim) == 0 && lim.rlim_cur == 0) { ++ lim.rlim_cur = lim.rlim_max; ++ if (setrlimit(RLIMIT_CORE, &lim) == 0) { ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, ++ "core dump file size limit raised to %lu bytes", ++ lim.rlim_cur); ++ } else { ++ ap_log_error(APLOG_MARK, APLOG_NOTICE, errno, NULL, ++ "core dump file size is zero, setrlimit failed"); ++ } ++ } ++ } ++#endif ++ + return OK; + } + diff --git a/SOURCES/httpd-2.4.43-deplibs.patch b/SOURCES/httpd-2.4.43-deplibs.patch new file mode 100644 index 0000000..c60f5a5 --- /dev/null +++ b/SOURCES/httpd-2.4.43-deplibs.patch @@ -0,0 +1,16 @@ +diff --git a/configure.in b/configure.in +index f8f9442..f276550 100644 +--- a/configure.in ++++ b/configure.in +@@ -786,9 +786,9 @@ APACHE_SUBST(INSTALL_SUEXEC) + + dnl APR should go after the other libs, so the right symbols can be picked up + if test x${apu_found} != xobsolete; then +- AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool --libs`" ++ AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool`" + fi +-AP_LIBS="$AP_LIBS `$apr_config --link-libtool --libs`" ++AP_LIBS="$AP_LIBS `$apr_config --link-libtool`" + APACHE_SUBST(AP_LIBS) + APACHE_SUBST(AP_BUILD_SRCLIB_DIRS) + APACHE_SUBST(AP_CLEAN_SRCLIB_DIRS) diff --git a/SOURCES/httpd-2.4.43-enable-sslv3.patch b/SOURCES/httpd-2.4.43-enable-sslv3.patch new file mode 100644 index 0000000..2861605 --- /dev/null +++ b/SOURCES/httpd-2.4.43-enable-sslv3.patch @@ -0,0 +1,62 @@ +diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c +index 979489c..3d6443b 100644 +--- a/modules/ssl/ssl_engine_config.c ++++ b/modules/ssl/ssl_engine_config.c +@@ -1485,6 +1485,10 @@ static const char *ssl_cmd_protocol_parse(cmd_parms *parms, + #endif + else if (strcEQ(w, "all")) { + thisopt = SSL_PROTOCOL_ALL; ++#ifndef OPENSSL_NO_SSL3 ++ /* by default, ALL kw doesn't turn on SSLv3 */ ++ thisopt &= ~SSL_PROTOCOL_SSLV3; ++#endif + } + else { + return apr_pstrcat(parms->temp_pool, +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index b0fcf81..ab6f263 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -568,6 +568,28 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s, + } + #endif + ++/* ++ * Enable/disable SSLProtocol. If the mod_ssl enables protocol ++ * which is disabled by default by OpenSSL, show a warning. ++ * "option" is for example SSL_OP_NO_SSLv3. ++ */ ++static void ssl_set_ctx_protocol_option(server_rec *s, ++ SSL_CTX *ctx, ++ long option, ++ int enabled, ++ const char *name) ++{ ++ if (!enabled) { ++ SSL_CTX_set_options(ctx, option); ++ } ++ else if (SSL_CTX_get_options(ctx) & option) { ++ SSL_CTX_clear_options(ctx, option); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02904) ++ "Allowing SSLProtocol %s even though it is disabled " ++ "by OpenSSL by default on this system", name); ++ } ++} ++ + static apr_status_t ssl_init_ctx_protocol(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, +@@ -735,9 +757,13 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, + } + if (prot == TLS1_1_VERSION && protocol & SSL_PROTOCOL_TLSV1) { + prot = TLS1_VERSION; ++ ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_TLSv1, ++ protocol & SSL_PROTOCOL_TLSV1, "TLSv1"); + } + #ifndef OPENSSL_NO_SSL3 + if (prot == TLS1_VERSION && protocol & SSL_PROTOCOL_SSLV3) { ++ ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_SSLv3, ++ protocol & SSL_PROTOCOL_SSLV3, "SSLv3"); + prot = SSL3_VERSION; + } + #endif diff --git a/SOURCES/httpd-2.4.43-logjournal.patch b/SOURCES/httpd-2.4.43-logjournal.patch new file mode 100644 index 0000000..cfbd9dc --- /dev/null +++ b/SOURCES/httpd-2.4.43-logjournal.patch @@ -0,0 +1,87 @@ +diff --git a/modules/loggers/config.m4 b/modules/loggers/config.m4 +index 762e773..0848d2e 100644 +--- a/modules/loggers/config.m4 ++++ b/modules/loggers/config.m4 +@@ -5,6 +5,8 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + APACHE_MODPATH_INIT(loggers) + + APACHE_MODULE(log_config, logging configuration. You won't be able to log requests to the server without this module., , , yes) ++APR_ADDTO(MOD_LOG_CONFIG_LDADD, [$SYSTEMD_LIBS]) ++ + APACHE_MODULE(log_debug, configurable debug logging, , , most) + APACHE_MODULE(log_forensic, forensic logging) + +diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c +index 996c09c..50a056a 100644 +--- a/modules/loggers/mod_log_config.c ++++ b/modules/loggers/mod_log_config.c +@@ -172,6 +172,10 @@ + #include + #endif + ++#ifdef HAVE_SYSTEMD ++#include ++#endif ++ + #define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b" + + module AP_MODULE_DECLARE_DATA log_config_module; +@@ -1638,6 +1642,25 @@ static apr_status_t ap_default_log_writer( request_rec *r, + + return rv; + } ++ ++static apr_status_t wrap_journal_stream(apr_pool_t *p, apr_file_t **outfd, ++ int priority) ++{ ++#ifdef HAVE_SYSTEMD ++ int fd; ++ ++ fd = sd_journal_stream_fd("httpd", priority, 0); ++ if (fd < 0) return fd; ++ ++ /* This is an AF_UNIX socket fd so is more pipe-like than ++ * file-like (the fd is neither seekable or readable), and use of ++ * apr_os_pipe_put_ex() allows cleanup registration. */ ++ return apr_os_pipe_put_ex(outfd, &fd, 1, p); ++#else ++ return APR_ENOTIMPL; ++#endif ++} ++ + static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s, + const char* name) + { +@@ -1650,6 +1673,32 @@ static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s, + } + return ap_piped_log_write_fd(pl); + } ++ else if (strncasecmp(name, "journald:", 9) == 0) { ++ int priority; ++ const char *err = ap_parse_log_level(name + 9, &priority); ++ apr_status_t rv; ++ apr_file_t *fd; ++ ++ if (err == NULL && priority > LOG_DEBUG) { ++ err = "TRACE level debugging not supported with journald"; ++ } ++ ++ if (err) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, ++ "invalid journald log priority name %s: %s", ++ name, err); ++ return NULL; ++ } ++ ++ rv = wrap_journal_stream(p, &fd, priority); ++ if (rv) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, ++ "could not open journald log stream"); ++ return NULL; ++ } ++ ++ return fd; ++ } + else { + const char *fname = ap_server_root_relative(p, name); + apr_file_t *fd; diff --git a/SOURCES/httpd-2.4.43-mod_systemd.patch b/SOURCES/httpd-2.4.43-mod_systemd.patch new file mode 100644 index 0000000..8d7922e --- /dev/null +++ b/SOURCES/httpd-2.4.43-mod_systemd.patch @@ -0,0 +1,96 @@ + +More verbose startup logging for mod_systemd. + +--- httpd-2.4.43/modules/arch/unix/mod_systemd.c.mod_systemd ++++ httpd-2.4.43/modules/arch/unix/mod_systemd.c +@@ -29,11 +29,14 @@ + #include "mpm_common.h" + + #include "systemd/sd-daemon.h" ++#include "systemd/sd-journal.h" + + #if APR_HAVE_UNISTD_H + #include + #endif + ++static char describe_listeners[30]; ++ + static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) + { +@@ -44,6 +47,20 @@ + return OK; + } + ++static char *dump_listener(ap_listen_rec *lr, apr_pool_t *p) ++{ ++ apr_sockaddr_t *sa = lr->bind_addr; ++ char addr[128]; ++ ++ if (apr_sockaddr_is_wildcard(sa)) { ++ return apr_pstrcat(p, "port ", apr_itoa(p, sa->port), NULL); ++ } ++ ++ apr_sockaddr_ip_getbuf(addr, sizeof addr, sa); ++ ++ return apr_psprintf(p, "%s port %u", addr, sa->port); ++} ++ + /* Report the service is ready in post_config, which could be during + * startup or after a reload. The server could still hit a fatal + * startup error after this point during ap_run_mpm(), so this is +@@ -51,19 +68,51 @@ + * the TCP ports so new connections will not be rejected. There will + * always be a possible async failure event simultaneous to the + * service reporting "ready", so this should be good enough. */ +-static int systemd_post_config(apr_pool_t *p, apr_pool_t *plog, ++static int systemd_post_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *main_server) + { ++ ap_listen_rec *lr; ++ apr_size_t plen = sizeof describe_listeners; ++ char *p = describe_listeners; ++ ++ if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) ++ return OK; ++ ++ for (lr = ap_listeners; lr; lr = lr->next) { ++ char *s = dump_listener(lr, ptemp); ++ ++ if (strlen(s) + 3 < plen) { ++ char *newp = apr_cpystrn(p, s, plen); ++ if (lr->next) ++ newp = apr_cpystrn(newp, ", ", 3); ++ plen -= newp - p; ++ p = newp; ++ } ++ else { ++ if (plen < 4) { ++ p = describe_listeners + sizeof describe_listeners - 4; ++ plen = 4; ++ } ++ apr_cpystrn(p, "...", plen); ++ break; ++ } ++ } ++ + sd_notify(0, "READY=1\n" + "STATUS=Configuration loaded.\n"); ++ ++ sd_journal_print(LOG_INFO, "Server configured, listening on: %s", ++ describe_listeners); ++ + return OK; + } + + static int systemd_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type) + { + sd_notifyf(0, "READY=1\n" +- "STATUS=Processing requests...\n" +- "MAINPID=%" APR_PID_T_FMT, getpid()); ++ "STATUS=Started, listening on: %s\n" ++ "MAINPID=%" APR_PID_T_FMT, ++ describe_listeners, getpid()); + + return OK; + } diff --git a/SOURCES/httpd-2.4.43-r1861793+.patch b/SOURCES/httpd-2.4.43-r1861793+.patch new file mode 100644 index 0000000..08e96cb --- /dev/null +++ b/SOURCES/httpd-2.4.43-r1861793+.patch @@ -0,0 +1,271 @@ +diff --git a/configure.in b/configure.in +index cb43246..0bb6b0d 100644 +--- httpd-2.4.43/configure.in.r1861793+ ++++ httpd-2.4.43/configure.in +@@ -465,6 +465,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.43/docs/man/htpasswd.1.r1861793+ ++++ httpd-2.4.43/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,17 +73,26 @@ + \fB-m\fR + Use MD5 encryption for passwords\&. This is the default (since version 2\&.2\&.18)\&. + .TP ++\fB-2\fR ++Use SHA-256 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&. ++.TP ++\fB-5\fR ++Use SHA-512 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&. ++.TP + \fB-B\fR + Use bcrypt encryption for passwords\&. This is currently considered to be very secure\&. + .TP + \fB-C\fR + This flag is only allowed in combination with \fB-B\fR (bcrypt encryption)\&. It sets the computing time used for the bcrypt algorithm (higher is more secure but slower, default: 5, valid: 4 to 17)\&. + .TP ++\fB-r\fR ++This flag is only allowed in combination with \fB-2\fR or \fB-5\fR\&. It sets the number of hash rounds used for the SHA-2 algorithms (higher is more secure but slower; the default is 5,000)\&. ++.TP + \fB-d\fR + Use \fBcrypt()\fR encryption for passwords\&. This is not supported by the httpd server on Windows and Netware\&. This algorithm limits the password length to 8 characters\&. This algorithm is \fBinsecure\fR by today's standards\&. It used to be the default algorithm until version 2\&.2\&.17\&. + .TP + \fB-s\fR +-Use SHA encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&. ++Use SHA-1 (160-bit) encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&. + .TP + \fB-p\fR + Use plaintext passwords\&. Though \fBhtpasswd\fR will support creation on all platforms, the httpd daemon will only accept plain text passwords on Windows and Netware\&. +@@ -152,10 +161,13 @@ + When using the \fBcrypt()\fR algorithm, note that only the first 8 characters of the password are used to form the password\&. If the supplied password is longer, the extra characters will be silently discarded\&. + + .PP +-The SHA encryption format does not use salting: for a given password, there is only one encrypted representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&. ++The SHA-1 encryption format does not use salting: for a given password, there is only one encrypted representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&. ++ ++.PP ++The SHA-1 and \fBcrypt()\fR formats are insecure by today's standards\&. + + .PP +-The SHA and \fBcrypt()\fR formats are insecure by today's standards\&. ++The SHA-2-based \fBcrypt()\fR formats (SHA-256 and SHA-512) are supported on most modern Unix systems, and follow the specification at https://www\&.akkadia\&.org/drepper/SHA-crypt\&.txt\&. + + .SH "RESTRICTIONS" + +--- httpd-2.4.43/support/htpasswd.c.r1861793+ ++++ httpd-2.4.43/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 encryption 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.43/support/passwd_common.c.r1861793+ ++++ httpd-2.4.43/support/passwd_common.c +@@ -179,16 +179,21 @@ + int mkhash(struct passwd_ctx *ctx) + { + char *pw; +- char salt[16]; ++ char salt[17]; + apr_status_t rv; + int ret = 0; + #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.43/support/passwd_common.h.r1861793+ ++++ httpd-2.4.43/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, diff --git a/SOURCES/httpd-2.4.43-socket-activation.patch b/SOURCES/httpd-2.4.43-socket-activation.patch new file mode 100644 index 0000000..511f476 --- /dev/null +++ b/SOURCES/httpd-2.4.43-socket-activation.patch @@ -0,0 +1,300 @@ +diff --git a/server/listen.c b/server/listen.c +index 5242c2a..e2e028a 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/SOURCES/httpd-2.4.43-sslciphdefault.patch b/SOURCES/httpd-2.4.43-sslciphdefault.patch new file mode 100644 index 0000000..85ae568 --- /dev/null +++ b/SOURCES/httpd-2.4.43-sslciphdefault.patch @@ -0,0 +1,31 @@ +diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c +index 97778a8..27e7a53 100644 +--- a/modules/ssl/ssl_engine_config.c ++++ b/modules/ssl/ssl_engine_config.c +@@ -778,9 +778,11 @@ const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd, + } + + if (!strcmp("SSL", arg1)) { +- /* always disable null and export ciphers */ +- arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL); + if (cmd->path) { ++ /* Disable null and export ciphers by default, except for PROFILE= ++ * configs where the parser doesn't cope. */ ++ if (strncmp(arg2, "PROFILE=", 8) != 0) ++ arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL); + dc->szCipherSuite = arg2; + } + else { +@@ -1544,8 +1546,10 @@ const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd, + } + + if (!strcmp("SSL", arg1)) { +- /* always disable null and export ciphers */ +- arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL); ++ /* Disable null and export ciphers by default, except for PROFILE= ++ * configs where the parser doesn't cope. */ ++ if (strncmp(arg2, "PROFILE=", 8) != 0) ++ arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL); + dc->proxy->auth.cipher_suite = arg2; + return NULL; + } diff --git a/SOURCES/httpd-2.4.43-sslprotdefault.patch b/SOURCES/httpd-2.4.43-sslprotdefault.patch new file mode 100644 index 0000000..d089823 --- /dev/null +++ b/SOURCES/httpd-2.4.43-sslprotdefault.patch @@ -0,0 +1,99 @@ +diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c +index 27e7a53..b53f3f8 100644 +--- a/modules/ssl/ssl_engine_config.c ++++ b/modules/ssl/ssl_engine_config.c +@@ -119,7 +119,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p) + mctx->ticket_key = NULL; + #endif + +- mctx->protocol = SSL_PROTOCOL_DEFAULT; ++ mctx->protocol = SSL_PROTOCOL_NONE; + mctx->protocol_set = 0; + + mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET; +@@ -263,6 +263,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p, + if (add->protocol_set) { + mrg->protocol_set = 1; + mrg->protocol = add->protocol; ++ mrg->protocol_set = 1; + } + else { + mrg->protocol_set = base->protocol_set; + +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index bfad47a..b0fcf81 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -577,6 +577,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, + MODSSL_SSL_METHOD_CONST SSL_METHOD *method = NULL; + char *cp; + int protocol = mctx->protocol; ++ int protocol_set = mctx->protocol_set; + SSLSrvConfigRec *sc = mySrvConfig(s); + #if OPENSSL_VERSION_NUMBER >= 0x10100000L + int prot; +@@ -586,12 +587,18 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, + * Create the new per-server SSL context + */ + if (protocol == SSL_PROTOCOL_NONE) { +- ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231) +- "No SSL protocols available [hint: SSLProtocol]"); +- return ssl_die(s); +- } ++ if (protocol_set) { ++ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231) ++ "No SSL protocols available [hint: SSLProtocol]"); ++ return ssl_die(s); ++ } + +- cp = apr_pstrcat(p, ++ ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s, ++ "Using OpenSSL/system default SSL/TLS protocols"); ++ cp = "default"; ++ } ++ else { ++ cp = apr_pstrcat(p, + #ifndef OPENSSL_NO_SSL3 + (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""), + #endif +@@ -604,7 +611,8 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, + #endif + #endif + NULL); +- cp[strlen(cp)-2] = NUL; ++ cp[strlen(cp)-2] = NUL; ++ } + + ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s, + "Creating new SSL context (protocols: %s)", cp); +@@ -705,13 +713,15 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, + prot = SSL3_VERSION; + #endif + } else { +- SSL_CTX_free(ctx); +- mctx->ssl_ctx = NULL; +- ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(03378) +- "No SSL protocols available [hint: SSLProtocol]"); +- return ssl_die(s); ++ if (protocol_set) { ++ SSL_CTX_free(ctx); ++ mctx->ssl_ctx = NULL; ++ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(03378) ++ "No SSL protocols available [hint: SSLProtocol]"); ++ return ssl_die(s); ++ } + } +- SSL_CTX_set_max_proto_version(ctx, prot); ++ if (protocol != SSL_PROTOCOL_NONE) SSL_CTX_set_max_proto_version(ctx, prot); + + /* Next we scan for the minimal protocol version we should provide, + * but we do not allow holes between max and min */ +@@ -731,7 +741,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, + prot = SSL3_VERSION; + } + #endif +- SSL_CTX_set_min_proto_version(ctx, prot); ++ if (protocol != SSL_PROTOCOL_NONE) SSL_CTX_set_min_proto_version(ctx, prot); + #endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L */ + + #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE diff --git a/SOURCES/httpd-2.4.46-freebind.patch b/SOURCES/httpd-2.4.46-freebind.patch new file mode 100644 index 0000000..b348dcc --- /dev/null +++ b/SOURCES/httpd-2.4.46-freebind.patch @@ -0,0 +1,124 @@ +diff --git a/docs/manual/mod/mpm_common.html.en b/docs/manual/mod/mpm_common.html.en +index e7af21d..01d54b7 100644 +--- a/docs/manual/mod/mpm_common.html.en ++++ b/docs/manual/mod/mpm_common.html.en +@@ -42,6 +42,7 @@ more than one multi-processing module (MPM) +
  • EnableExceptionHook
  • +
  • GracefulShutdownTimeout
  • +
  • Listen
  • ++
  • ListenFree
  • +
  • ListenBackLog
  • +
  • ListenCoresBucketsRatio
  • +
  • MaxConnectionsPerChild
  • +@@ -244,6 +245,31 @@ discussion of the Address already in use error message, + including other causes. + + ++ ++
    top
    ++

    ListenFree Directive

    ++ ++ ++ ++ ++ ++ ++ ++
    Description:IP addresses and ports that the server ++listens to. Doesn't require IP address to be up
    Syntax:ListenFree [IP-address:]portnumber [protocol]
    Context:server config
    Status:MPM
    Module:event, worker, prefork, mpm_winnt, mpm_netware, mpmt_os2
    Compatibility:This directive is currently available only in Red Hat Enterprise Linux
    ++

    The ListenFree directive is ++ identical to the Listen directive. ++ The only difference is in the usage of the IP_FREEBIND socket ++ option, which is enabled by default with ListenFree. ++ If IP_FREEBIND is enabled, it allows httpd to bind to an IP ++ address that is nonlocal or does not (yet) exist. This allows httpd to ++ listen on a socket without requiring the underlying network interface ++ or the specified dynamic IP address to be up at the time when httpd ++ is trying to bind to it. ++

    ++
    ++ ++ +
    top
    +

    ListenBackLog Directive

    + +diff --git a/include/ap_listen.h b/include/ap_listen.h +index 58c2574..1a53292 100644 +--- a/include/ap_listen.h ++++ b/include/ap_listen.h +@@ -137,6 +137,9 @@ AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy + AP_DECLARE_NONSTD(const char *) ap_set_listencbratio(cmd_parms *cmd, void *dummy, const char *arg); + AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, + int argc, char *const argv[]); ++AP_DECLARE_NONSTD(const char *) ap_set_freelistener(cmd_parms *cmd, void *dummy, ++ int argc, char *const argv[]); ++ + AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, void *dummy, + const char *arg); + AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, +@@ -150,6 +153,8 @@ AP_INIT_TAKE1("ListenCoresBucketsRatio", ap_set_listencbratio, NULL, RSRC_CONF, + "Ratio between the number of CPU cores (online) and the number of listeners buckets"), \ + AP_INIT_TAKE_ARGV("Listen", ap_set_listener, NULL, RSRC_CONF, \ + "A port number or a numeric IP address and a port number, and an optional protocol"), \ ++AP_INIT_TAKE_ARGV("ListenFree", ap_set_freelistener, NULL, RSRC_CONF, \ ++ "A port number or a numeric IP address and a port number, and an optional protocol"), \ + AP_INIT_TAKE1("SendBufferSize", ap_set_send_buffer_size, NULL, RSRC_CONF, \ + "Send buffer size in bytes"), \ + AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \ +diff --git a/server/listen.c b/server/listen.c +index e2e028a..6ef664b 100644 +--- a/server/listen.c ++++ b/server/listen.c +@@ -63,6 +63,7 @@ static int ap_listenbacklog; + static int ap_listencbratio; + static int send_buffer_size; + static int receive_buffer_size; ++static int ap_listenfreebind; + #ifdef HAVE_SYSTEMD + static int use_systemd = -1; + #endif +@@ -162,6 +163,21 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_ + } + #endif + ++ ++#if defined(APR_SO_FREEBIND) ++ if (ap_listenfreebind) { ++ if (apr_socket_opt_set(s, APR_SO_FREEBIND, one) < 0) { ++ stat = apr_get_netos_error(); ++ ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(02182) ++ "make_sock: apr_socket_opt_set: " ++ "error setting APR_SO_FREEBIND"); ++ apr_socket_close(s); ++ return stat; ++ } ++ } ++#endif ++ ++ + if (do_bind_listen) { + #if APR_HAVE_IPV6 + if (server->bind_addr->family == APR_INET6) { +@@ -956,6 +972,7 @@ AP_DECLARE(void) ap_listen_pre_config(void) + } + } + ++ + AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, + int argc, char *const argv[]) + { +@@ -1016,6 +1033,14 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, + return alloc_listener(cmd->server->process, host, port, proto, NULL); + } + ++AP_DECLARE_NONSTD(const char *) ap_set_freelistener(cmd_parms *cmd, void *dummy, ++ int argc, ++ char *const argv[]) ++{ ++ ap_listenfreebind = 1; ++ return ap_set_listener(cmd, dummy, argc, argv); ++} ++ + AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, + void *dummy, + const char *arg) diff --git a/SOURCES/httpd-2.4.46-htcacheclean-dont-break.patch b/SOURCES/httpd-2.4.46-htcacheclean-dont-break.patch new file mode 100644 index 0000000..e52318a --- /dev/null +++ b/SOURCES/httpd-2.4.46-htcacheclean-dont-break.patch @@ -0,0 +1,13 @@ +diff --git a/support/htcacheclean.c b/support/htcacheclean.c +index 958ba6d..0a7fe3c 100644 +--- a/support/htcacheclean.c ++++ b/support/htcacheclean.c +@@ -557,8 +557,6 @@ static int list_urls(char *path, apr_pool_t *pool, apr_off_t round) + } + } + } +- +- break; + } + } + } diff --git a/SOURCES/httpd-2.4.48-export.patch b/SOURCES/httpd-2.4.48-export.patch new file mode 100644 index 0000000..439f768 --- /dev/null +++ b/SOURCES/httpd-2.4.48-export.patch @@ -0,0 +1,63 @@ + +Reduce size of httpd binary by telling linker to export all symbols +from libmain.a, rather than bloating the symbol table with ap_hack_* +to do so indirectly. + +Upstream: https://svn.apache.org/r1861685 (as new default-off configure option) + +diff --git a/Makefile.in b/Makefile.in +index 40c7076..ac98e5f 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -4,8 +4,15 @@ CLEAN_SUBDIRS = test + + PROGRAM_NAME = $(progname) + PROGRAM_SOURCES = modules.c +-PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) ++PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) \ ++ $(PROGRAM_LDDEPS) \ ++ $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) + PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c ++PROGRAM_LDDEPS = \ ++ $(BUILTIN_LIBS) \ ++ $(MPM_LIB) \ ++ -Wl,--whole-archive,server/.libs/libmain.a,--no-whole-archive \ ++ os/$(OS_DIR)/libos.la + PROGRAM_DEPENDENCIES = \ + server/libmain.la \ + $(BUILTIN_LIBS) \ +diff --git a/server/Makefile.in b/server/Makefile.in +index 8111877..f00bb3f 100644 +--- a/server/Makefile.in ++++ b/server/Makefile.in +@@ -12,7 +12,7 @@ LTLIBRARY_SOURCES = \ + connection.c listen.c util_mutex.c \ + mpm_common.c mpm_unix.c mpm_fdqueue.c \ + util_charset.c util_cookies.c util_debug.c util_xml.c \ +- util_filter.c util_pcre.c util_regex.c exports.c \ ++ util_filter.c util_pcre.c util_regex.c \ + scoreboard.c error_bucket.c protocol.c core.c request.c ssl.c provider.c \ + eoc_bucket.c eor_bucket.c core_filters.c \ + util_expr_parse.c util_expr_scan.c util_expr_eval.c +diff --git a/server/main.c b/server/main.c +index 62e06df..17c09ee 100644 +--- a/server/main.c ++++ b/server/main.c +@@ -835,17 +835,3 @@ int main(int argc, const char * const argv[]) + return !OK; + } + +-#ifdef AP_USING_AUTOCONF +-/* This ugly little hack pulls any function referenced in exports.c into +- * the web server. exports.c is generated during the build, and it +- * has all of the APR functions specified by the apr/apr.exports and +- * apr-util/aprutil.exports files. +- */ +-const void *ap_suck_in_APR(void); +-const void *ap_suck_in_APR(void) +-{ +- extern const void *ap_ugly_hack; +- +- return ap_ugly_hack; +-} +-#endif diff --git a/SOURCES/httpd-2.4.48-full-release.patch b/SOURCES/httpd-2.4.48-full-release.patch new file mode 100644 index 0000000..6e31cc7 --- /dev/null +++ b/SOURCES/httpd-2.4.48-full-release.patch @@ -0,0 +1,46 @@ +diff --git a/server/core.c b/server/core.c +index c36ff26..621c82a 100644 +--- a/server/core.c ++++ b/server/core.c +@@ -3569,6 +3569,7 @@ enum server_token_type { + SrvTk_MINIMAL, /* eg: Apache/2.0.41 */ + SrvTk_OS, /* eg: Apache/2.0.41 (UNIX) */ + SrvTk_FULL, /* eg: Apache/2.0.41 (UNIX) PHP/4.2.2 FooBar/1.2b */ ++ SrvTk_FULL_RELEASE, /* eg: Apache/2.0.41 (UNIX) (Release 32.el7) PHP/4.2.2 FooBar/1.2b */ + SrvTk_PRODUCT_ONLY /* eg: Apache */ + }; + static enum server_token_type ap_server_tokens = SrvTk_FULL; +@@ -3645,7 +3646,10 @@ static void set_banner(apr_pool_t *pconf) + else if (ap_server_tokens == SrvTk_MAJOR) { + ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MAJORVERSION); + } +- else { ++ else if (ap_server_tokens == SrvTk_FULL_RELEASE) { ++ ap_add_version_component(pconf, AP_SERVER_BASEVERSION " (" PLATFORM ") (Release @RELEASE@)"); ++ } ++ else { + ap_add_version_component(pconf, AP_SERVER_BASEVERSION " (" PLATFORM ")"); + } + +@@ -3653,7 +3657,7 @@ static void set_banner(apr_pool_t *pconf) + * Lock the server_banner string if we're not displaying + * the full set of tokens + */ +- if (ap_server_tokens != SrvTk_FULL) { ++ if (ap_server_tokens != SrvTk_FULL && ap_server_tokens != SrvTk_FULL_RELEASE) { + banner_locked++; + } + server_description = AP_SERVER_BASEVERSION " (" PLATFORM ")"; +@@ -3686,8 +3690,11 @@ static const char *set_serv_tokens(cmd_parms *cmd, void *dummy, + else if (!ap_cstr_casecmp(arg, "Full")) { + ap_server_tokens = SrvTk_FULL; + } ++ else if (!strcasecmp(arg, "Full-Release")) { ++ ap_server_tokens = SrvTk_FULL_RELEASE; ++ } + else { +- return "ServerTokens takes 1 argument: 'Prod(uctOnly)', 'Major', 'Minor', 'Min(imal)', 'OS', or 'Full'"; ++ return "ServerTokens takes 1 argument: 'Prod(uctOnly)', 'Major', 'Minor', 'Min(imal)', 'OS', 'Full' or 'Full-Release'"; + } + + return NULL; diff --git a/SOURCES/httpd-2.4.48-proxy-ws-idle-timeout.patch b/SOURCES/httpd-2.4.48-proxy-ws-idle-timeout.patch new file mode 100644 index 0000000..d04dc68 --- /dev/null +++ b/SOURCES/httpd-2.4.48-proxy-ws-idle-timeout.patch @@ -0,0 +1,109 @@ +diff --git a/docs/manual/mod/mod_proxy_wstunnel.html.en b/docs/manual/mod/mod_proxy_wstunnel.html.en +index 9f2c120..61ff7de 100644 +--- a/docs/manual/mod/mod_proxy_wstunnel.html.en ++++ b/docs/manual/mod/mod_proxy_wstunnel.html.en +@@ -83,6 +83,7 @@ in the response Upgrade

    +
    Support Apache!

    Directives

    + +

    Bugfix checklist

    See also

    +
      +@@ -108,6 +109,23 @@ in the response Upgrade

      + WebSocket requests as in httpd 2.4.46 and earlier.

      + +
    ++ ++
    ++ ++ ++ ++ ++ ++ ++
    Description:Sets the maximum amount of time to wait for data on the websockets tunnel
    Syntax:ProxyWebsocketIdleTimeout num[ms]
    Default:ProxyWebsocketIdleTimeout 0
    Context:server config, virtual host
    Status:Extension
    Module:mod_proxy_wstunnel
    ++

    This directive imposes a maximum amount of time for the tunnel to be ++ left open while idle. The timeout is considered in seconds by default, but ++ it is possible to increase the time resolution to milliseconds ++ adding the ms suffix.

    ++ ++
    ++ + +
    +

    Available Languages:  en  | +diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c +index bcbba42..c29ded1 100644 +--- a/modules/proxy/mod_proxy_wstunnel.c ++++ b/modules/proxy/mod_proxy_wstunnel.c +@@ -22,6 +22,7 @@ module AP_MODULE_DECLARE_DATA proxy_wstunnel_module; + typedef struct { + unsigned int fallback_to_proxy_http :1, + fallback_to_proxy_http_set :1; ++ apr_time_t idle_timeout; + } proxyws_dir_conf; + + static int can_fallback_to_proxy_http; +@@ -152,6 +153,8 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r, + conn_rec *c = r->connection; + apr_socket_t *sock = conn->sock; + conn_rec *backconn = conn->connection; ++ proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config, ++ &proxy_wstunnel_module); + char *buf; + apr_bucket_brigade *header_brigade; + apr_bucket *e; +@@ -229,10 +232,13 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r, + c->keepalive = AP_CONN_CLOSE; + + do { /* Loop until done (one side closes the connection, or an error) */ +- rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled); ++ rv = apr_pollset_poll(pollset, dconf->idle_timeout, &pollcnt, &signalled); + if (rv != APR_SUCCESS) { + if (APR_STATUS_IS_EINTR(rv)) { + continue; ++ } else if(APR_STATUS_IS_TIMEUP(rv)){ ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "RH: the connection has timed out"); ++ return HTTP_REQUEST_TIME_OUT; + } + ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02444) "error apr_poll()"); + return HTTP_INTERNAL_SERVER_ERROR; +@@ -418,11 +424,26 @@ cleanup: + return status; + } + ++static const char * proxyws_set_idle(cmd_parms *cmd, void *conf, const char *val) ++{ ++ proxyws_dir_conf *dconf = conf; ++ if (ap_timeout_parameter_parse(val, &(dconf->idle_timeout), "s") != APR_SUCCESS) ++ return "ProxyWebsocketIdleTimeout timeout has wrong format"; ++ ++ if (dconf->idle_timeout < 0) ++ return "ProxyWebsocketIdleTimeout timeout has to be a non-negative number"; ++ ++ if (!dconf->idle_timeout) dconf->idle_timeout = -1; /* loop indefinitely */ ++ ++ return NULL; ++} ++ + static void *create_proxyws_dir_config(apr_pool_t *p, char *dummy) + { + proxyws_dir_conf *new = + (proxyws_dir_conf *) apr_pcalloc(p, sizeof(proxyws_dir_conf)); + ++ new->idle_timeout = -1; /* no timeout */ + new->fallback_to_proxy_http = 1; + + return (void *) new; +@@ -465,7 +486,8 @@ static const command_rec ws_proxy_cmds[] = + proxyws_fallback_to_proxy_http, NULL, RSRC_CONF|ACCESS_CONF, + "whether to let mod_proxy_http handle the upgrade and tunneling, " + "On by default"), +- ++ AP_INIT_TAKE1("ProxyWebsocketIdleTimeout", proxyws_set_idle, NULL, RSRC_CONF|ACCESS_CONF, ++ "timeout for activity in either direction, unlimited by default."), + {NULL} + }; + diff --git a/SOURCES/httpd-2.4.48-r1828172+.patch b/SOURCES/httpd-2.4.48-r1828172+.patch new file mode 100644 index 0000000..2b99d69 --- /dev/null +++ b/SOURCES/httpd-2.4.48-r1828172+.patch @@ -0,0 +1,1411 @@ +--- httpd-2.4.48/modules/generators/cgi_common.h.r1828172+ ++++ httpd-2.4.48/modules/generators/cgi_common.h +@@ -0,0 +1,366 @@ ++/* 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" ++ ++static void discard_script_output(apr_bucket_brigade *bb) ++{ ++ apr_bucket *e; ++ const char *buf; ++ apr_size_t len; ++ ++ for (e = APR_BRIGADE_FIRST(bb); ++ e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e); ++ e = APR_BRIGADE_FIRST(bb)) ++ { ++ if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) { ++ break; ++ } ++ apr_bucket_delete(e); ++ } ++} ++ ++#ifdef WANT_CGI_BUCKET ++/* 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); ++ ++ /* Disable APR timeout handling since we'll use poll() entirely. */ ++ apr_file_pipe_timeout_set(out, 0); ++ apr_file_pipe_timeout_set(err, 0); ++ ++ 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 ++}; ++ ++#endif /* WANT_CGI_BUCKET */ ++ ++/* Handle the CGI response output, having set up the brigade with the ++ * CGI or PIPE bucket as appropriate. */ ++static int cgi_handle_response(request_rec *r, int nph, apr_bucket_brigade *bb, ++ apr_interval_time_t timeout, cgi_server_conf *conf, ++ char *logdata, apr_file_t *script_err) ++{ ++ apr_status_t rv; ++ ++ /* Handle script return... */ ++ if (!nph) { ++ const char *location; ++ char sbuf[MAX_STRING_LEN]; ++ int ret; ++ ++ if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, ++ APLOG_MODULE_INDEX))) ++ { ++ /* In the case of a timeout reading script output, clear ++ * the brigade to avoid a second attempt to read the ++ * output. */ ++ if (ret == HTTP_GATEWAY_TIME_OUT) { ++ apr_brigade_cleanup(bb); ++ } ++ ++ ret = log_script(r, conf, ret, logdata, sbuf, bb, script_err); ++ ++ /* ++ * ret could be HTTP_NOT_MODIFIED in the case that the CGI script ++ * does not set an explicit status and ap_meets_conditions, which ++ * is called by ap_scan_script_header_err_brigade, detects that ++ * the conditions of the requests are met and the response is ++ * not modified. ++ * In this case set r->status and return OK in order to prevent ++ * running through the error processing stack as this would ++ * break with mod_cache, if the conditions had been set by ++ * mod_cache itself to validate a stale entity. ++ * BTW: We circumvent the error processing stack anyway if the ++ * CGI script set an explicit status code (whatever it is) and ++ * the only possible values for ret here are: ++ * ++ * HTTP_NOT_MODIFIED (set by ap_meets_conditions) ++ * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions) ++ * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the ++ * processing of the response of the CGI script, e.g broken headers ++ * or a crashed CGI process). ++ */ ++ if (ret == HTTP_NOT_MODIFIED) { ++ r->status = ret; ++ return OK; ++ } ++ ++ return ret; ++ } ++ ++ location = apr_table_get(r->headers_out, "Location"); ++ ++ if (location && r->status == 200) { ++ /* For a redirect whether internal or not, discard any ++ * remaining stdout from the script, and log any remaining ++ * stderr output, as normal. */ ++ discard_script_output(bb); ++ apr_brigade_destroy(bb); ++ ++ if (script_err) { ++ apr_file_pipe_timeout_set(script_err, timeout); ++ log_script_err(r, script_err); ++ } ++ } ++ ++ if (location && location[0] == '/' && r->status == 200) { ++ /* This redirect needs to be a GET no matter what the original ++ * method was. ++ */ ++ r->method = "GET"; ++ r->method_number = M_GET; ++ ++ /* We already read the message body (if any), so don't allow ++ * the redirected request to think it has one. We can ignore ++ * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. ++ */ ++ apr_table_unset(r->headers_in, "Content-Length"); ++ ++ ap_internal_redirect_handler(location, r); ++ return OK; ++ } ++ else if (location && r->status == 200) { ++ /* XXX: Note that if a script wants to produce its own Redirect ++ * body, it now has to explicitly *say* "Status: 302" ++ */ ++ discard_script_output(bb); ++ apr_brigade_destroy(bb); ++ return HTTP_MOVED_TEMPORARILY; ++ } ++ ++ rv = ap_pass_brigade(r->output_filters, bb); ++ } ++ else /* nph */ { ++ struct ap_filter_t *cur; ++ ++ /* get rid of all filters up through protocol... since we ++ * haven't parsed off the headers, there is no way they can ++ * work ++ */ ++ ++ cur = r->proto_output_filters; ++ while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { ++ cur = cur->next; ++ } ++ r->output_filters = r->proto_output_filters = cur; ++ ++ rv = ap_pass_brigade(r->output_filters, bb); ++ } ++ ++ /* don't soak up script output if errors occurred writing it ++ * out... otherwise, we prolong the life of the script when the ++ * connection drops or we stopped sending output for some other ++ * reason */ ++ if (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. */ ++} +--- httpd-2.4.48/modules/generators/config5.m4.r1828172+ ++++ httpd-2.4.48/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.48/modules/generators/mod_cgi.c.r1828172+ ++++ httpd-2.4.48/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} + }; + +@@ -466,23 +490,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); + } + } + } +@@ -536,209 +563,12 @@ + return APR_SUCCESS; + } + +-static void discard_script_output(apr_bucket_brigade *bb) +-{ +- apr_bucket *e; +- const char *buf; +- apr_size_t len; +- +- for (e = APR_BRIGADE_FIRST(bb); +- e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e); +- e = APR_BRIGADE_FIRST(bb)) +- { +- if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) { +- break; +- } +- apr_bucket_delete(e); +- } +-} +- + #if APR_FILES_AS_SOCKETS +- +-/* A CGI bucket type is needed to catch any output to stderr from the +- * script; see PR 22030. */ +-static const apr_bucket_type_t bucket_type_cgi; +- +-struct cgi_bucket_data { +- apr_pollset_t *pollset; +- request_rec *r; +-}; +- +-/* Create a CGI bucket using pipes from script stdout 'out' +- * and stderr 'err', for request 'r'. */ +-static apr_bucket *cgi_bucket_create(request_rec *r, +- apr_file_t *out, apr_file_t *err, +- apr_bucket_alloc_t *list) +-{ +- apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); +- apr_status_t rv; +- apr_pollfd_t fd; +- struct cgi_bucket_data *data = apr_palloc(r->pool, sizeof *data); +- +- APR_BUCKET_INIT(b); +- b->free = apr_bucket_free; +- b->list = list; +- b->type = &bucket_type_cgi; +- b->length = (apr_size_t)(-1); +- b->start = -1; +- +- /* Create the pollset */ +- rv = apr_pollset_create(&data->pollset, 2, r->pool, 0); +- if (rv != APR_SUCCESS) { +- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01217) +- "apr_pollset_create(); check system or user limits"); +- return NULL; +- } +- +- fd.desc_type = APR_POLL_FILE; +- fd.reqevents = APR_POLLIN; +- fd.p = r->pool; +- fd.desc.f = out; /* script's stdout */ +- fd.client_data = (void *)1; +- rv = apr_pollset_add(data->pollset, &fd); +- if (rv != APR_SUCCESS) { +- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01218) +- "apr_pollset_add(); check system or user limits"); +- return NULL; +- } +- +- fd.desc.f = err; /* script's stderr */ +- fd.client_data = (void *)2; +- rv = apr_pollset_add(data->pollset, &fd); +- if (rv != APR_SUCCESS) { +- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01219) +- "apr_pollset_add(); check system or user limits"); +- return NULL; +- } +- +- data->r = r; +- b->data = data; +- return b; +-} +- +-/* Create a duplicate CGI bucket using given bucket data */ +-static apr_bucket *cgi_bucket_dup(struct cgi_bucket_data *data, +- apr_bucket_alloc_t *list) +-{ +- apr_bucket *b = apr_bucket_alloc(sizeof(*b), list); +- APR_BUCKET_INIT(b); +- b->free = apr_bucket_free; +- b->list = list; +- b->type = &bucket_type_cgi; +- b->length = (apr_size_t)(-1); +- b->start = -1; +- b->data = data; +- return b; +-} +- +-/* Handle stdout from CGI child. Duplicate of logic from the _read +- * method of the real APR pipe bucket implementation. */ +-static apr_status_t cgi_read_stdout(apr_bucket *a, apr_file_t *out, +- const char **str, apr_size_t *len) +-{ +- char *buf; +- apr_status_t rv; +- +- *str = NULL; +- *len = APR_BUCKET_BUFF_SIZE; +- buf = apr_bucket_alloc(*len, a->list); /* XXX: check for failure? */ +- +- rv = apr_file_read(out, buf, len); +- +- if (rv != APR_SUCCESS && rv != APR_EOF) { +- apr_bucket_free(buf); +- return rv; +- } +- +- if (*len > 0) { +- struct cgi_bucket_data *data = a->data; +- apr_bucket_heap *h; +- +- /* Change the current bucket to refer to what we read */ +- a = apr_bucket_heap_make(a, buf, *len, apr_bucket_free); +- h = a->data; +- h->alloc_len = APR_BUCKET_BUFF_SIZE; /* note the real buffer size */ +- *str = buf; +- APR_BUCKET_INSERT_AFTER(a, cgi_bucket_dup(data, a->list)); +- } +- else { +- apr_bucket_free(buf); +- a = apr_bucket_immortal_make(a, "", 0); +- *str = a->data; +- } +- return rv; +-} +- +-/* Read method of CGI bucket: polls on stderr and stdout of the child, +- * sending any stderr output immediately away to the error log. */ +-static apr_status_t cgi_bucket_read(apr_bucket *b, const char **str, +- apr_size_t *len, apr_read_type_e block) +-{ +- struct cgi_bucket_data *data = b->data; +- apr_interval_time_t timeout; +- apr_status_t rv; +- int gotdata = 0; +- +- timeout = block == APR_NONBLOCK_READ ? 0 : data->r->server->timeout; +- +- do { +- const apr_pollfd_t *results; +- apr_int32_t num; +- +- rv = apr_pollset_poll(data->pollset, timeout, &num, &results); +- if (APR_STATUS_IS_TIMEUP(rv)) { +- if (timeout) { +- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, data->r, APLOGNO(01220) +- "Timeout waiting for output from CGI script %s", +- data->r->filename); +- return rv; +- } +- else { +- return APR_EAGAIN; +- } +- } +- else if (APR_STATUS_IS_EINTR(rv)) { +- continue; +- } +- else if (rv != APR_SUCCESS) { +- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, data->r, APLOGNO(01221) +- "poll failed waiting for CGI child"); +- return rv; +- } +- +- for (; num; num--, results++) { +- if (results[0].client_data == (void *)1) { +- /* stdout */ +- rv = cgi_read_stdout(b, results[0].desc.f, str, len); +- if (APR_STATUS_IS_EOF(rv)) { +- rv = APR_SUCCESS; +- } +- gotdata = 1; +- } else { +- /* stderr */ +- apr_status_t rv2 = log_script_err(data->r, results[0].desc.f); +- if (APR_STATUS_IS_EOF(rv2)) { +- apr_pollset_remove(data->pollset, &results[0]); +- } +- } +- } +- +- } while (!gotdata); +- +- return rv; +-} +- +-static const apr_bucket_type_t bucket_type_cgi = { +- "CGI", 5, APR_BUCKET_DATA, +- apr_bucket_destroy_noop, +- cgi_bucket_read, +- apr_bucket_setaside_notimpl, +- apr_bucket_split_notimpl, +- apr_bucket_copy_notimpl +-}; +- ++#define WANT_CGI_BUCKET + #endif + ++#include "cgi_common.h" ++ + static int cgi_handler(request_rec *r) + { + int nph; +@@ -757,6 +587,8 @@ + apr_status_t rv; + cgi_exec_info_t e_info; + conn_rec *c; ++ cgi_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgi_module); ++ apr_interval_time_t timeout = dc->timeout > 0 ? dc->timeout : r->server->timeout; + + if (strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) { + return DECLINED; +@@ -916,10 +748,7 @@ + AP_DEBUG_ASSERT(script_in != NULL); + + #if APR_FILES_AS_SOCKETS +- apr_file_pipe_timeout_set(script_in, 0); +- apr_file_pipe_timeout_set(script_err, 0); +- +- b = cgi_bucket_create(r, script_in, script_err, c->bucket_alloc); ++ b = cgi_bucket_create(r, dc->timeout, script_in, script_err, c->bucket_alloc); + if (b == NULL) + return HTTP_INTERNAL_SERVER_ERROR; + #else +@@ -929,111 +758,7 @@ + b = apr_bucket_eos_create(c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, b); + +- /* Handle script return... */ +- if (!nph) { +- const char *location; +- char sbuf[MAX_STRING_LEN]; +- int ret; +- +- if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, +- APLOG_MODULE_INDEX))) +- { +- ret = log_script(r, conf, ret, dbuf, sbuf, bb, script_err); +- +- /* +- * ret could be HTTP_NOT_MODIFIED in the case that the CGI script +- * does not set an explicit status and ap_meets_conditions, which +- * is called by ap_scan_script_header_err_brigade, detects that +- * the conditions of the requests are met and the response is +- * not modified. +- * In this case set r->status and return OK in order to prevent +- * running through the error processing stack as this would +- * break with mod_cache, if the conditions had been set by +- * mod_cache itself to validate a stale entity. +- * BTW: We circumvent the error processing stack anyway if the +- * CGI script set an explicit status code (whatever it is) and +- * the only possible values for ret here are: +- * +- * HTTP_NOT_MODIFIED (set by ap_meets_conditions) +- * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions) +- * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the +- * processing of the response of the CGI script, e.g broken headers +- * or a crashed CGI process). +- */ +- if (ret == HTTP_NOT_MODIFIED) { +- r->status = ret; +- return OK; +- } +- +- return ret; +- } +- +- location = apr_table_get(r->headers_out, "Location"); +- +- if (location && r->status == 200) { +- /* For a redirect whether internal or not, discard any +- * remaining stdout from the script, and log any remaining +- * stderr output, as normal. */ +- discard_script_output(bb); +- apr_brigade_destroy(bb); +- apr_file_pipe_timeout_set(script_err, r->server->timeout); +- log_script_err(r, script_err); +- } +- +- if (location && location[0] == '/' && r->status == 200) { +- /* This redirect needs to be a GET no matter what the original +- * method was. +- */ +- r->method = "GET"; +- r->method_number = M_GET; +- +- /* We already read the message body (if any), so don't allow +- * the redirected request to think it has one. We can ignore +- * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. +- */ +- apr_table_unset(r->headers_in, "Content-Length"); +- +- ap_internal_redirect_handler(location, r); +- return OK; +- } +- else if (location && r->status == 200) { +- /* XXX: Note that if a script wants to produce its own Redirect +- * body, it now has to explicitly *say* "Status: 302" +- */ +- return HTTP_MOVED_TEMPORARILY; +- } +- +- rv = ap_pass_brigade(r->output_filters, bb); +- } +- else /* nph */ { +- struct ap_filter_t *cur; +- +- /* get rid of all filters up through protocol... since we +- * haven't parsed off the headers, there is no way they can +- * work +- */ +- +- cur = r->proto_output_filters; +- while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { +- cur = cur->next; +- } +- r->output_filters = r->proto_output_filters = cur; +- +- rv = ap_pass_brigade(r->output_filters, bb); +- } +- +- /* don't soak up script output if errors occurred writing it +- * out... otherwise, we prolong the life of the script when the +- * connection drops or we stopped sending output for some other +- * reason */ +- if (rv == APR_SUCCESS && !r->connection->aborted) { +- apr_file_pipe_timeout_set(script_err, r->server->timeout); +- log_script_err(r, script_err); +- } +- +- apr_file_close(script_err); +- +- return OK; /* NOT r->status, even if it has changed. */ ++ return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err); + } + + /*============================================================================ +@@ -1268,7 +993,7 @@ + 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.48/modules/generators/mod_cgid.c.r1828172+ ++++ httpd-2.4.48/modules/generators/mod_cgid.c +@@ -342,15 +342,19 @@ + return close(fd); + } + +-/* deal with incomplete reads and signals +- * assume you really have to read buf_size bytes +- */ +-static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) ++/* Read from the socket dealing with incomplete messages and signals. ++ * Returns 0 on success or errno on failure. Stderr fd passed as ++ * auxiliary data from other end is written to *errfd, or else stderr ++ * fileno if not present. */ ++static apr_status_t sock_readhdr(int fd, int *errfd, void *vbuf, size_t buf_size) + { +- char *buf = vbuf; + int rc; ++#ifndef HAVE_CGID_FDPASSING ++ char *buf = vbuf; + size_t bytes_read = 0; + ++ if (errfd) *errfd = 0; ++ + do { + do { + rc = read(fd, buf + bytes_read, buf_size - bytes_read); +@@ -365,9 +369,60 @@ + } + } while (bytes_read < buf_size); + ++ ++#else /* with FD passing */ ++ struct msghdr msg = {0}; ++ struct iovec vec = {vbuf, buf_size}; ++ struct cmsghdr *cmsg; ++ union { /* union to ensure alignment */ ++ struct cmsghdr cm; ++ char buf[CMSG_SPACE(sizeof(int))]; ++ } u; ++ ++ msg.msg_iov = &vec; ++ msg.msg_iovlen = 1; ++ ++ if (errfd) { ++ msg.msg_control = u.buf; ++ msg.msg_controllen = sizeof(u.buf); ++ *errfd = 0; ++ } ++ ++ /* use MSG_WAITALL to skip loop on truncated reads */ ++ do { ++ rc = recvmsg(fd, &msg, MSG_WAITALL); ++ } while (rc < 0 && errno == EINTR); ++ ++ if (rc == 0) { ++ return ECONNRESET; ++ } ++ else if (rc < 0) { ++ return errno; ++ } ++ else if (rc != buf_size) { ++ /* MSG_WAITALL should ensure the recvmsg blocks until the ++ * entire length is read, but let's be paranoid. */ ++ return APR_INCOMPLETE; ++ } ++ ++ if (errfd ++ && (cmsg = CMSG_FIRSTHDR(&msg)) != NULL ++ && cmsg->cmsg_len == CMSG_LEN(sizeof(*errfd)) ++ && cmsg->cmsg_level == SOL_SOCKET ++ && cmsg->cmsg_type == SCM_RIGHTS) { ++ *errfd = *((int *) CMSG_DATA(cmsg)); ++ } ++#endif ++ + return APR_SUCCESS; + } + ++/* As sock_readhdr but without auxiliary fd passing. */ ++static apr_status_t sock_read(int fd, void *vbuf, size_t buf_size) ++{ ++ return sock_readhdr(fd, NULL, vbuf, buf_size); ++} ++ + /* deal with signals + */ + static apr_status_t sock_write(int fd, const void *buf, size_t buf_size) +@@ -384,7 +439,7 @@ + return APR_SUCCESS; + } + +-static apr_status_t sock_writev(int fd, request_rec *r, int count, ...) ++static apr_status_t sock_writev(int fd, int auxfd, request_rec *r, int count, ...) + { + va_list ap; + int rc; +@@ -399,9 +454,39 @@ + } + va_end(ap); + ++#ifndef HAVE_CGID_FDPASSING + do { + rc = writev(fd, vec, count); + } while (rc < 0 && errno == EINTR); ++#else ++ { ++ struct msghdr msg = { 0 }; ++ struct cmsghdr *cmsg; ++ union { /* union for alignment */ ++ char buf[CMSG_SPACE(sizeof(int))]; ++ struct cmsghdr align; ++ } u; ++ ++ msg.msg_iov = vec; ++ msg.msg_iovlen = count; ++ ++ if (auxfd) { ++ msg.msg_control = u.buf; ++ msg.msg_controllen = sizeof(u.buf); ++ ++ cmsg = CMSG_FIRSTHDR(&msg); ++ cmsg->cmsg_level = SOL_SOCKET; ++ cmsg->cmsg_type = SCM_RIGHTS; ++ cmsg->cmsg_len = CMSG_LEN(sizeof(int)); ++ *((int *) CMSG_DATA(cmsg)) = auxfd; ++ } ++ ++ do { ++ rc = sendmsg(fd, &msg, 0); ++ } while (rc < 0 && errno == EINTR); ++ } ++#endif ++ + if (rc < 0) { + return errno; + } +@@ -410,7 +495,7 @@ + } + + static apr_status_t get_req(int fd, request_rec *r, char **argv0, char ***env, +- cgid_req_t *req) ++ int *errfd, cgid_req_t *req) + { + int i; + char **environ; +@@ -421,7 +506,7 @@ + r->server = apr_pcalloc(r->pool, sizeof(server_rec)); + + /* read the request header */ +- stat = sock_read(fd, req, sizeof(*req)); ++ stat = sock_readhdr(fd, errfd, req, sizeof(*req)); + if (stat != APR_SUCCESS) { + return stat; + } +@@ -479,14 +564,15 @@ + return APR_SUCCESS; + } + +-static apr_status_t send_req(int fd, request_rec *r, char *argv0, char **env, +- int req_type) ++static apr_status_t send_req(int fd, apr_file_t *errpipe, request_rec *r, ++ char *argv0, char **env, int req_type) + { + int i; + cgid_req_t req = {0}; + apr_status_t stat; + ap_unix_identity_t * ugid = ap_run_get_suexec_identity(r); + core_dir_config *core_conf = ap_get_core_module_config(r->per_dir_config); ++ int errfd; + + + if (ugid == NULL) { +@@ -507,16 +593,21 @@ + req.args_len = r->args ? strlen(r->args) : 0; + req.loglevel = r->server->log.level; + ++ if (errpipe) ++ apr_os_file_get(&errfd, errpipe); ++ else ++ errfd = 0; ++ + /* Write the request header */ + if (req.args_len) { +- stat = sock_writev(fd, r, 5, ++ stat = sock_writev(fd, errfd, r, 5, + &req, sizeof(req), + r->filename, req.filename_len, + argv0, req.argv0_len, + r->uri, req.uri_len, + r->args, req.args_len); + } else { +- stat = sock_writev(fd, r, 4, ++ stat = sock_writev(fd, errfd, r, 4, + &req, sizeof(req), + r->filename, req.filename_len, + argv0, req.argv0_len, +@@ -531,7 +622,7 @@ + for (i = 0; i < req.env_count; i++) { + apr_size_t curlen = strlen(env[i]); + +- if ((stat = sock_writev(fd, r, 2, &curlen, sizeof(curlen), ++ if ((stat = sock_writev(fd, 0, r, 2, &curlen, sizeof(curlen), + env[i], curlen)) != APR_SUCCESS) { + return stat; + } +@@ -582,20 +673,34 @@ + } + } + ++/* Callback executed in the forked child process if exec of the CGI ++ * script fails. For the fd-passing case, output to stderr goes to ++ * the client (request handling thread) and is logged via ++ * ap_log_rerror there. For the non-fd-passing case, the "fake" ++ * request_rec passed via userdata is used to log. */ + static void cgid_child_errfn(apr_pool_t *pool, apr_status_t err, + const char *description) + { +- request_rec *r; + void *vr; + + apr_pool_userdata_get(&vr, ERRFN_USERDATA_KEY, pool); +- r = vr; +- +- /* sure we got r, but don't call ap_log_rerror() because we don't +- * have r->headers_in and possibly other storage referenced by +- * ap_log_rerror() +- */ +- ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, APLOGNO(01241) "%s", description); ++ if (vr) { ++ request_rec *r = vr; ++ ++ /* sure we got r, but don't call ap_log_rerror() because we don't ++ * have r->headers_in and possibly other storage referenced by ++ * ap_log_rerror() ++ */ ++ ap_log_error(APLOG_MARK, APLOG_ERR, err, r->server, APLOGNO(01241) "%s", description); ++ } ++ else { ++ const char *logstr; ++ ++ logstr = apr_psprintf(pool, APLOGNO(01241) "error spawning CGI child: %s (%pm)\n", ++ description, &err); ++ fputs(logstr, stderr); ++ fflush(stderr); ++ } + } + + static int cgid_server(void *data) +@@ -670,7 +775,7 @@ + } + + while (!daemon_should_exit) { +- int errfileno = STDERR_FILENO; ++ int errfileno; + char *argv0 = NULL; + char **env = NULL; + const char * const *argv; +@@ -710,7 +815,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) +@@ -742,6 +847,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); + +@@ -801,7 +916,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); + +@@ -1101,6 +1219,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) +@@ -1206,6 +1351,13 @@ + return ret; + } + ++/* Pull in CGI bucket implementation. */ ++#define cgi_server_conf cgid_server_conf ++#ifdef HAVE_CGID_FDPASSING ++#define WANT_CGI_BUCKET ++#endif ++#include "cgi_common.h" ++ + static int connect_to_daemon(int *sdptr, request_rec *r, + cgid_server_conf *conf) + { +@@ -1272,23 +1424,6 @@ + return OK; + } + +-static void discard_script_output(apr_bucket_brigade *bb) +-{ +- apr_bucket *e; +- const char *buf; +- apr_size_t len; +- +- for (e = APR_BRIGADE_FIRST(bb); +- e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e); +- e = APR_BRIGADE_FIRST(bb)) +- { +- if (apr_bucket_read(e, &buf, &len, APR_BLOCK_READ)) { +- break; +- } +- apr_bucket_delete(e); +- } +-} +- + /**************************************************************** + * + * Actual cgid handling... +@@ -1393,6 +1528,7 @@ + + static int cgid_handler(request_rec *r) + { ++ conn_rec *c = r->connection; + int retval, nph, dbpos; + char *argv0, *dbuf; + apr_bucket_brigade *bb; +@@ -1402,10 +1538,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; +@@ -1414,7 +1551,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) { +@@ -1467,6 +1604,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. +@@ -1479,12 +1627,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; +@@ -1506,12 +1658,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... +@@ -1603,114 +1750,19 @@ + */ + shutdown(sd, 1); + +- /* Handle script return... */ +- if (!nph) { +- conn_rec *c = r->connection; +- const char *location; +- char sbuf[MAX_STRING_LEN]; +- int ret; +- +- bb = apr_brigade_create(r->pool, c->bucket_alloc); +- b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(bb, b); +- b = apr_bucket_eos_create(c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(bb, b); +- +- if ((ret = ap_scan_script_header_err_brigade_ex(r, bb, sbuf, +- APLOG_MODULE_INDEX))) +- { +- ret = log_script(r, conf, ret, dbuf, sbuf, bb, NULL); +- +- /* +- * ret could be HTTP_NOT_MODIFIED in the case that the CGI script +- * does not set an explicit status and ap_meets_conditions, which +- * is called by ap_scan_script_header_err_brigade, detects that +- * the conditions of the requests are met and the response is +- * not modified. +- * In this case set r->status and return OK in order to prevent +- * running through the error processing stack as this would +- * break with mod_cache, if the conditions had been set by +- * mod_cache itself to validate a stale entity. +- * BTW: We circumvent the error processing stack anyway if the +- * CGI script set an explicit status code (whatever it is) and +- * the only possible values for ret here are: +- * +- * HTTP_NOT_MODIFIED (set by ap_meets_conditions) +- * HTTP_PRECONDITION_FAILED (set by ap_meets_conditions) +- * HTTP_INTERNAL_SERVER_ERROR (if something went wrong during the +- * processing of the response of the CGI script, e.g broken headers +- * or a crashed CGI process). +- */ +- if (ret == HTTP_NOT_MODIFIED) { +- r->status = ret; +- return OK; +- } +- +- return ret; +- } +- +- location = apr_table_get(r->headers_out, "Location"); +- +- if (location && location[0] == '/' && r->status == 200) { +- +- /* Soak up all the script output */ +- discard_script_output(bb); +- apr_brigade_destroy(bb); +- /* This redirect needs to be a GET no matter what the original +- * method was. +- */ +- r->method = "GET"; +- r->method_number = M_GET; +- +- /* We already read the message body (if any), so don't allow +- * the redirected request to think it has one. We can ignore +- * Transfer-Encoding, since we used REQUEST_CHUNKED_ERROR. +- */ +- apr_table_unset(r->headers_in, "Content-Length"); +- +- ap_internal_redirect_handler(location, r); +- return OK; +- } +- else if (location && r->status == 200) { +- /* XXX: Note that if a script wants to produce its own Redirect +- * body, it now has to explicitly *say* "Status: 302" +- */ +- discard_script_output(bb); +- apr_brigade_destroy(bb); +- return HTTP_MOVED_TEMPORARILY; +- } +- +- rv = ap_pass_brigade(r->output_filters, bb); +- if (rv != APR_SUCCESS) { +- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, rv, r, +- "Failed to flush CGI output to client"); +- } +- } +- +- if (nph) { +- conn_rec *c = r->connection; +- struct ap_filter_t *cur; +- +- /* get rid of all filters up through protocol... since we +- * haven't parsed off the headers, there is no way they can +- * work +- */ +- +- cur = r->proto_output_filters; +- while (cur && cur->frec->ftype < AP_FTYPE_CONNECTION) { +- cur = cur->next; +- } +- r->output_filters = r->proto_output_filters = cur; +- +- bb = apr_brigade_create(r->pool, c->bucket_alloc); +- b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(bb, b); +- b = apr_bucket_eos_create(c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(bb, b); +- ap_pass_brigade(r->output_filters, bb); +- } ++ bb = apr_brigade_create(r->pool, c->bucket_alloc); ++#ifdef HAVE_CGID_FDPASSING ++ b = cgi_bucket_create(r, dc->timeout, tempsock, script_err, c->bucket_alloc); ++ if (b == NULL) ++ return HTTP_INTERNAL_SERVER_ERROR; /* should call log_scripterror() w/ _UNAVAILABLE? */ ++#else ++ b = apr_bucket_pipe_create(tempsock, c->bucket_alloc); ++#endif ++ APR_BRIGADE_INSERT_TAIL(bb, b); ++ b = apr_bucket_eos_create(c->bucket_alloc); ++ APR_BRIGADE_INSERT_TAIL(bb, b); + +- return OK; /* NOT r->status, even if it has changed. */ ++ return cgi_handle_response(r, nph, bb, timeout, conf, dbuf, script_err); + } + + +@@ -1827,7 +1879,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; diff --git a/SOURCES/httpd-2.4.48-r1842929+.patch b/SOURCES/httpd-2.4.48-r1842929+.patch new file mode 100644 index 0000000..f83a21d --- /dev/null +++ b/SOURCES/httpd-2.4.48-r1842929+.patch @@ -0,0 +1,229 @@ +diff --git a/Makefile.in b/Makefile.in +index 6747aea..40c7076 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -233,6 +233,7 @@ install-cgi: + install-other: + @test -d $(DESTDIR)$(logfiledir) || $(MKINSTALLDIRS) $(DESTDIR)$(logfiledir) + @test -d $(DESTDIR)$(runtimedir) || $(MKINSTALLDIRS) $(DESTDIR)$(runtimedir) ++ @test -d $(DESTDIR)$(statedir) || $(MKINSTALLDIRS) $(DESTDIR)$(statedir) + @for ext in dll x; do \ + file=apachecore.$$ext; \ + if test -f $$file; then \ +diff --git a/acinclude.m4 b/acinclude.m4 +index b6ef442..98f1441 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -45,6 +45,7 @@ AC_DEFUN([APACHE_GEN_CONFIG_VARS],[ + APACHE_SUBST(installbuilddir) + APACHE_SUBST(runtimedir) + APACHE_SUBST(proxycachedir) ++ APACHE_SUBST(statedir) + APACHE_SUBST(other_targets) + APACHE_SUBST(progname) + APACHE_SUBST(prefix) +@@ -665,6 +666,7 @@ AC_DEFUN([APACHE_EXPORT_ARGUMENTS],[ + APACHE_SUBST_EXPANDED_ARG(runtimedir) + APACHE_SUBST_EXPANDED_ARG(logfiledir) + APACHE_SUBST_EXPANDED_ARG(proxycachedir) ++ APACHE_SUBST_EXPANDED_ARG(statedir) + ]) + + dnl +diff --git a/configure.in b/configure.in +index 37346b2..f303784 100644 +--- a/configure.in ++++ b/configure.in +@@ -41,7 +41,7 @@ dnl Something seems broken here. + AC_PREFIX_DEFAULT(/usr/local/apache2) + + dnl Get the layout here, so we can pass the required variables to apr +-APR_ENABLE_LAYOUT(Apache, [errordir iconsdir htdocsdir cgidir]) ++APR_ENABLE_LAYOUT(Apache, [errordir iconsdir htdocsdir cgidir statedir]) + + dnl reparse the configure arguments. + APR_PARSE_ARGUMENTS +diff --git a/include/ap_config_layout.h.in b/include/ap_config_layout.h.in +index 2b4a70c..e076f41 100644 +--- a/include/ap_config_layout.h.in ++++ b/include/ap_config_layout.h.in +@@ -60,5 +60,7 @@ + #define DEFAULT_REL_LOGFILEDIR "@rel_logfiledir@" + #define DEFAULT_EXP_PROXYCACHEDIR "@exp_proxycachedir@" + #define DEFAULT_REL_PROXYCACHEDIR "@rel_proxycachedir@" ++#define DEFAULT_EXP_STATEDIR "@exp_statedir@" ++#define DEFAULT_REL_STATEDIR "@rel_statedir@" + + #endif /* AP_CONFIG_LAYOUT_H */ +diff --git a/include/http_config.h b/include/http_config.h +index 77657ae..384a90f 100644 +--- a/include/http_config.h ++++ b/include/http_config.h +@@ -757,6 +757,14 @@ AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *fname); + */ + AP_DECLARE(char *) ap_runtime_dir_relative(apr_pool_t *p, const char *fname); + ++/** ++ * Compute the name of a persistent state file (e.g. a database or ++ * long-lived cache) relative to the appropriate state directory. ++ * Absolute paths are returned as-is. The state directory is ++ * configured via the DefaultStateDir directive or at build time. ++ */ ++AP_DECLARE(char *) ap_state_dir_relative(apr_pool_t *p, const char *fname); ++ + /* Finally, the hook for dynamically loading modules in... */ + + /** +diff --git a/modules/dav/fs/mod_dav_fs.c b/modules/dav/fs/mod_dav_fs.c +index addfd7e..2389f8f 100644 +--- a/modules/dav/fs/mod_dav_fs.c ++++ b/modules/dav/fs/mod_dav_fs.c +@@ -29,6 +29,10 @@ typedef struct { + + extern module AP_MODULE_DECLARE_DATA dav_fs_module; + ++#ifndef DEFAULT_DAV_LOCKDB ++#define DEFAULT_DAV_LOCKDB "davlockdb" ++#endif ++ + const char *dav_get_lockdb_path(const request_rec *r) + { + dav_fs_server_conf *conf; +@@ -57,6 +61,24 @@ static void *dav_fs_merge_server_config(apr_pool_t *p, + return newconf; + } + ++static apr_status_t dav_fs_post_config(apr_pool_t *p, apr_pool_t *plog, ++ apr_pool_t *ptemp, server_rec *base_server) ++{ ++ server_rec *s; ++ ++ for (s = base_server; s; s = s->next) { ++ dav_fs_server_conf *conf; ++ ++ conf = ap_get_module_config(s->module_config, &dav_fs_module); ++ ++ if (!conf->lockdb_path) { ++ conf->lockdb_path = ap_state_dir_relative(p, DEFAULT_DAV_LOCKDB); ++ } ++ } ++ ++ return OK; ++} ++ + /* + * Command handler for the DAVLockDB directive, which is TAKE1 + */ +@@ -87,6 +109,8 @@ static const command_rec dav_fs_cmds[] = + + static void register_hooks(apr_pool_t *p) + { ++ ap_hook_post_config(dav_fs_post_config, NULL, NULL, APR_HOOK_MIDDLE); ++ + dav_hook_gather_propsets(dav_fs_gather_propsets, NULL, NULL, + APR_HOOK_MIDDLE); + dav_hook_find_liveprop(dav_fs_find_liveprop, NULL, NULL, APR_HOOK_MIDDLE); +diff --git a/server/core.c b/server/core.c +index d135764..c2176b9 100644 +--- a/server/core.c ++++ b/server/core.c +@@ -142,6 +142,8 @@ AP_DECLARE_DATA int ap_main_state = AP_SQ_MS_INITIAL_STARTUP; + AP_DECLARE_DATA int ap_run_mode = AP_SQ_RM_UNKNOWN; + AP_DECLARE_DATA int ap_config_generation = 0; + ++static const char *core_state_dir; ++ + static void *create_core_dir_config(apr_pool_t *a, char *dir) + { + core_dir_config *conf; +@@ -1444,13 +1446,16 @@ AP_DECLARE(const char *) ap_resolve_env(apr_pool_t *p, const char * word) + return res_buf; + } + +-static int reset_config_defines(void *dummy) ++/* pconf cleanup - clear global variables set from config here. */ ++static apr_status_t reset_config(void *dummy) + { + ap_server_config_defines = saved_server_config_defines; + saved_server_config_defines = NULL; + server_config_defined_vars = NULL; + ap_runtime_dir = NULL; +- return OK; ++ core_state_dir = NULL; ++ ++ return APR_SUCCESS; + } + + /* +@@ -3220,6 +3225,24 @@ static const char *set_runtime_dir(cmd_parms *cmd, void *dummy, const char *arg) + return NULL; + } + ++static const char *set_state_dir(cmd_parms *cmd, void *dummy, const char *arg) ++{ ++ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); ++ ++ if (err != NULL) { ++ return err; ++ } ++ ++ if ((apr_filepath_merge((char**)&core_state_dir, NULL, ++ ap_server_root_relative(cmd->temp_pool, arg), ++ APR_FILEPATH_TRUENAME, cmd->pool) != APR_SUCCESS) ++ || !ap_is_directory(cmd->temp_pool, core_state_dir)) { ++ return "DefaultStateDir must be a valid directory, absolute or relative to ServerRoot"; ++ } ++ ++ return NULL; ++} ++ + static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg) + { + const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT); +@@ -4521,6 +4544,8 @@ AP_INIT_TAKE1("ServerRoot", set_server_root, NULL, RSRC_CONF | EXEC_ON_READ, + "Common directory of server-related files (logs, confs, etc.)"), + AP_INIT_TAKE1("DefaultRuntimeDir", set_runtime_dir, NULL, RSRC_CONF | EXEC_ON_READ, + "Common directory for run-time files (shared memory, locks, etc.)"), ++AP_INIT_TAKE1("DefaultStateDir", set_state_dir, NULL, RSRC_CONF | EXEC_ON_READ, ++ "Common directory for persistent state (databases, long-lived caches, etc.)"), + AP_INIT_TAKE1("ErrorLog", set_server_string_slot, + (void *)APR_OFFSETOF(server_rec, error_fname), RSRC_CONF, + "The filename of the error log"), +@@ -5055,8 +5080,7 @@ static int core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptem + + if (!saved_server_config_defines) + init_config_defines(pconf); +- apr_pool_cleanup_register(pconf, NULL, reset_config_defines, +- apr_pool_cleanup_null); ++ apr_pool_cleanup_register(pconf, NULL, reset_config, apr_pool_cleanup_null); + + ap_regcomp_set_default_cflags(AP_REG_DEFAULT); + +@@ -5303,6 +5327,27 @@ AP_DECLARE(int) ap_state_query(int query) + } + } + ++AP_DECLARE(char *) ap_state_dir_relative(apr_pool_t *p, const char *file) ++{ ++ char *newpath = NULL; ++ apr_status_t rv; ++ const char *state_dir; ++ ++ state_dir = core_state_dir ++ ? core_state_dir ++ : ap_server_root_relative(p, DEFAULT_REL_STATEDIR); ++ ++ rv = apr_filepath_merge(&newpath, state_dir, file, APR_FILEPATH_TRUENAME, p); ++ if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv) ++ || APR_STATUS_IS_ENOENT(rv) ++ || APR_STATUS_IS_ENOTDIR(rv))) { ++ return newpath; ++ } ++ else { ++ return NULL; ++ } ++} ++ + static apr_random_t *rng = NULL; + #if APR_HAS_THREADS + static apr_thread_mutex_t *rng_mutex = NULL; diff --git a/SOURCES/httpd-2.4.48-ssl-proxy-chains.patch b/SOURCES/httpd-2.4.48-ssl-proxy-chains.patch new file mode 100644 index 0000000..95c31c8 --- /dev/null +++ b/SOURCES/httpd-2.4.48-ssl-proxy-chains.patch @@ -0,0 +1,79 @@ +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index 15f68f9..e67c81d 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -1682,6 +1682,10 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s, + STACK_OF(X509) *chain; + X509_STORE_CTX *sctx; + X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx); ++ int addl_chain = 0; /* non-zero if additional chain certs were ++ * added to store */ ++ ++ ap_assert(store != NULL); /* safe to assume always non-NULL? */ + + #if OPENSSL_VERSION_NUMBER >= 0x1010100fL + /* For OpenSSL >=1.1.1, turn on client cert support which is +@@ -1707,20 +1711,28 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s, + ssl_init_ca_cert_path(s, ptemp, pkp->cert_path, NULL, sk); + } + +- if ((ncerts = sk_X509_INFO_num(sk)) <= 0) { +- sk_X509_INFO_free(sk); +- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206) +- "no client certs found for SSL proxy"); +- return APR_SUCCESS; +- } +- + /* Check that all client certs have got certificates and private +- * keys. */ +- for (n = 0; n < ncerts; n++) { ++ * keys. Note the number of certs in the stack may decrease ++ * during the loop. */ ++ for (n = 0; n < sk_X509_INFO_num(sk); n++) { + X509_INFO *inf = sk_X509_INFO_value(sk, n); ++ int has_privkey = inf->x_pkey && inf->x_pkey->dec_pkey; + +- if (!inf->x509 || !inf->x_pkey || !inf->x_pkey->dec_pkey || +- inf->enc_data) { ++ /* For a lone certificate in the file, trust it as a ++ * CA/intermediate certificate. */ ++ if (inf->x509 && !has_privkey && !inf->enc_data) { ++ ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, inf->x509, ++ APLOGNO(10261) "Trusting non-leaf certificate"); ++ X509_STORE_add_cert(store, inf->x509); /* increments inf->x509 */ ++ /* Delete from the stack and iterate again. */ ++ X509_INFO_free(inf); ++ sk_X509_INFO_delete(sk, n); ++ n--; ++ addl_chain = 1; ++ continue; ++ } ++ ++ if (!has_privkey || inf->enc_data) { + sk_X509_INFO_free(sk); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252) + "incomplete client cert configured for SSL proxy " +@@ -1737,13 +1749,21 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s, + } + } + ++ if ((ncerts = sk_X509_INFO_num(sk)) <= 0) { ++ sk_X509_INFO_free(sk); ++ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206) ++ "no client certs found for SSL proxy"); ++ return APR_SUCCESS; ++ } ++ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02207) + "loaded %d client certs for SSL proxy", + ncerts); + pkp->certs = sk; + +- +- if (!pkp->ca_cert_file || !store) { ++ /* If any chain certs are configured, build the ->ca_certs chains ++ * corresponding to the loaded keypairs. */ ++ if (!pkp->ca_cert_file && !addl_chain) { + return APR_SUCCESS; + } + diff --git a/SOURCES/httpd-2.4.51-r1811831.patch b/SOURCES/httpd-2.4.51-r1811831.patch new file mode 100644 index 0000000..b8d8215 --- /dev/null +++ b/SOURCES/httpd-2.4.51-r1811831.patch @@ -0,0 +1,81 @@ +diff --git a/server/util_script.c b/server/util_script.c +index 4121ae0..b7f8674 100644 +--- a/server/util_script.c ++++ b/server/util_script.c +@@ -92,9 +92,21 @@ static void add_unless_null(apr_table_t *table, const char *name, const char *va + } + } + +-static void env2env(apr_table_t *table, const char *name) ++/* Sets variable @name in table @dest from r->subprocess_env if ++ * available, else from the environment, else from @fallback if ++ * non-NULL. */ ++static void env2env(apr_table_t *dest, request_rec *r, ++ const char *name, const char *fallback) + { +- add_unless_null(table, name, getenv(name)); ++ const char *val; ++ ++ val = apr_table_get(r->subprocess_env, name); ++ if (!val) ++ val = apr_pstrdup(r->pool, getenv(name)); ++ if (!val) ++ val = apr_pstrdup(r->pool, fallback); ++ if (val) ++ apr_table_addn(dest, name, val); + } + + AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t) +@@ -211,37 +223,29 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r) + add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val); + } + +- env_temp = apr_table_get(r->subprocess_env, "PATH"); +- if (env_temp == NULL) { +- env_temp = getenv("PATH"); +- } +- if (env_temp == NULL) { +- env_temp = DEFAULT_PATH; +- } +- apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_temp)); +- ++ env2env(e, r, "PATH", DEFAULT_PATH); + #if defined(WIN32) +- env2env(e, "SystemRoot"); +- env2env(e, "COMSPEC"); +- env2env(e, "PATHEXT"); +- env2env(e, "WINDIR"); ++ env2env(e, r, "SystemRoot", NULL); ++ env2env(e, r, "COMSPEC", NULL); ++ env2env(e, r, "PATHEXT", NULL); ++ env2env(e, r, "WINDIR", NULL); + #elif defined(OS2) +- env2env(e, "COMSPEC"); +- env2env(e, "ETC"); +- env2env(e, "DPATH"); +- env2env(e, "PERLLIB_PREFIX"); ++ env2env(e, r, "COMSPEC", NULL); ++ env2env(e, r, "ETC", NULL); ++ env2env(e, r, "DPATH", NULL); ++ env2env(e, r, "PERLLIB_PREFIX", NULL); + #elif defined(BEOS) +- env2env(e, "LIBRARY_PATH"); ++ env2env(e, r, "LIBRARY_PATH", NULL); + #elif defined(DARWIN) +- env2env(e, "DYLD_LIBRARY_PATH"); ++ env2env(e, r, "DYLD_LIBRARY_PATH", NULL); + #elif defined(_AIX) +- env2env(e, "LIBPATH"); ++ env2env(e, r, "LIBPATH", NULL); + #elif defined(__HPUX__) + /* HPUX PARISC 2.0W knows both, otherwise redundancy is harmless */ +- env2env(e, "SHLIB_PATH"); +- env2env(e, "LD_LIBRARY_PATH"); ++ env2env(e, r, "SHLIB_PATH", NULL); ++ env2env(e, r, "LD_LIBRARY_PATH", NULL); + #else /* Some Unix */ +- env2env(e, "LD_LIBRARY_PATH"); ++ env2env(e, r, "LD_LIBRARY_PATH", NULL); + #endif + + apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r)); diff --git a/SOURCES/httpd-2.4.51-r1877397.patch b/SOURCES/httpd-2.4.51-r1877397.patch new file mode 100644 index 0000000..f629317 --- /dev/null +++ b/SOURCES/httpd-2.4.51-r1877397.patch @@ -0,0 +1,249 @@ +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index 211ebff..c8cb1af 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -871,6 +871,13 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, + SSL_CTX_set_keylog_callback(ctx, modssl_callback_keylog); + } + #endif ++ ++#ifdef SSL_OP_NO_RENEGOTIATION ++ /* For server-side SSL_CTX, disable renegotiation by default.. */ ++ if (!mctx->pkp) { ++ SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION); ++ } ++#endif + + return APR_SUCCESS; + } +@@ -892,6 +899,14 @@ static void ssl_init_ctx_session_cache(server_rec *s, + } + } + ++#ifdef SSL_OP_NO_RENEGOTIATION ++/* OpenSSL-level renegotiation protection. */ ++#define MODSSL_BLOCKS_RENEG (0) ++#else ++/* mod_ssl-level renegotiation protection. */ ++#define MODSSL_BLOCKS_RENEG (1) ++#endif ++ + static void ssl_init_ctx_callbacks(server_rec *s, + apr_pool_t *p, + apr_pool_t *ptemp, +@@ -905,7 +920,13 @@ static void ssl_init_ctx_callbacks(server_rec *s, + SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); + #endif + +- SSL_CTX_set_info_callback(ctx, ssl_callback_Info); ++ /* The info callback is used for debug-level tracing. For OpenSSL ++ * versions where SSL_OP_NO_RENEGOTIATION is not available, the ++ * callback is also used to prevent use of client-initiated ++ * renegotiation. Enable it in either case. */ ++ if (APLOGdebug(s) || MODSSL_BLOCKS_RENEG) { ++ SSL_CTX_set_info_callback(ctx, ssl_callback_Info); ++ } + + #ifdef HAVE_TLS_ALPN + SSL_CTX_set_alpn_select_cb(ctx, ssl_callback_alpn_select, NULL); +diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c +index 79b9a70..3a0c22a 100644 +--- a/modules/ssl/ssl_engine_io.c ++++ b/modules/ssl/ssl_engine_io.c +@@ -209,11 +209,13 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl) + + BIO_clear_retry_flags(bio); + ++#ifndef SSL_OP_NO_RENEGOTIATION + /* Abort early if the client has initiated a renegotiation. */ + if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) { + outctx->rc = APR_ECONNABORTED; + return -1; + } ++#endif + + ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c, + "bio_filter_out_write: %i bytes", inl); +@@ -474,11 +476,13 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen) + + BIO_clear_retry_flags(bio); + ++#ifndef SSL_OP_NO_RENEGOTIATION + /* Abort early if the client has initiated a renegotiation. */ + if (inctx->filter_ctx->config->reneg_state == RENEG_ABORT) { + inctx->rc = APR_ECONNABORTED; + return -1; + } ++#endif + + if (!inctx->bb) { + inctx->rc = APR_EOF; +diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c +index 591f6ae..8416864 100644 +--- a/modules/ssl/ssl_engine_kernel.c ++++ b/modules/ssl/ssl_engine_kernel.c +@@ -992,7 +992,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo + + /* Toggle the renegotiation state to allow the new + * handshake to proceed. */ +- sslconn->reneg_state = RENEG_ALLOW; ++ modssl_set_reneg_state(sslconn, RENEG_ALLOW); + + SSL_renegotiate(ssl); + SSL_do_handshake(ssl); +@@ -1019,7 +1019,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo + */ + SSL_peek(ssl, peekbuf, 0); + +- sslconn->reneg_state = RENEG_REJECT; ++ modssl_set_reneg_state(sslconn, RENEG_REJECT); + + if (!SSL_is_init_finished(ssl)) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02261) +@@ -1078,7 +1078,7 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon + (sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) { + int vmode_inplace, vmode_needed; + int change_vmode = FALSE; +- int old_state, n, rc; ++ int n, rc; + + vmode_inplace = SSL_get_verify_mode(ssl); + vmode_needed = SSL_VERIFY_NONE; +@@ -1180,8 +1180,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon + return HTTP_FORBIDDEN; + } + +- old_state = sslconn->reneg_state; +- sslconn->reneg_state = RENEG_ALLOW; + modssl_set_app_data2(ssl, r); + + SSL_do_handshake(ssl); +@@ -1191,7 +1189,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon + */ + SSL_peek(ssl, peekbuf, 0); + +- sslconn->reneg_state = old_state; + modssl_set_app_data2(ssl, NULL); + + /* +@@ -2263,8 +2260,8 @@ static void log_tracing_state(const SSL *ssl, conn_rec *c, + /* + * This callback function is executed while OpenSSL processes the SSL + * handshake and does SSL record layer stuff. It's used to trap +- * client-initiated renegotiations, and for dumping everything to the +- * log. ++ * client-initiated renegotiations (where SSL_OP_NO_RENEGOTIATION is ++ * not available), and for dumping everything to the log. + */ + void ssl_callback_Info(const SSL *ssl, int where, int rc) + { +@@ -2276,14 +2273,12 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc) + return; + } + +- /* With TLS 1.3 this callback may be called multiple times on the first +- * negotiation, so the below logic to detect renegotiations can't work. +- * Fortunately renegotiations are forbidden starting with TLS 1.3, and +- * this is enforced by OpenSSL so there's nothing to be done here. +- */ +-#if SSL_HAVE_PROTOCOL_TLSV1_3 +- if (SSL_version(ssl) < TLS1_3_VERSION) +-#endif ++#ifndef SSL_OP_NO_RENEGOTIATION ++ /* With OpenSSL < 1.1.1 (implying TLS v1.2 or earlier), this ++ * callback is used to block client-initiated renegotiation. With ++ * TLSv1.3 it is unnecessary since renegotiation is forbidden at ++ * protocol level. Otherwise (TLSv1.2 with OpenSSL >=1.1.1), ++ * SSL_OP_NO_RENEGOTIATION is used to block renegotiation. */ + { + SSLConnRec *sslconn; + +@@ -2308,6 +2303,7 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc) + sslconn->reneg_state = RENEG_REJECT; + } + } ++#endif + + s = mySrvFromConn(c); + if (s && APLOGdebug(s)) { +diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h +index a329d99..7666c31 100644 +--- a/modules/ssl/ssl_private.h ++++ b/modules/ssl/ssl_private.h +@@ -512,6 +512,16 @@ typedef struct { + apr_time_t source_mtime; + } ssl_asn1_t; + ++typedef enum { ++ RENEG_INIT = 0, /* Before initial handshake */ ++ RENEG_REJECT, /* After initial handshake; any client-initiated ++ * renegotiation should be rejected */ ++ RENEG_ALLOW, /* A server-initiated renegotiation is taking ++ * place (as dictated by configuration) */ ++ RENEG_ABORT /* Renegotiation initiated by client, abort the ++ * connection */ ++} modssl_reneg_state; ++ + /** + * Define the mod_ssl per-module configuration structure + * (i.e. the global configuration for each httpd process) +@@ -543,18 +553,13 @@ typedef struct { + NON_SSL_SET_ERROR_MSG /* Need to set the error message */ + } non_ssl_request; + +- /* Track the handshake/renegotiation state for the connection so +- * that all client-initiated renegotiations can be rejected, as a +- * partial fix for CVE-2009-3555. */ +- enum { +- RENEG_INIT = 0, /* Before initial handshake */ +- RENEG_REJECT, /* After initial handshake; any client-initiated +- * renegotiation should be rejected */ +- RENEG_ALLOW, /* A server-initiated renegotiation is taking +- * place (as dictated by configuration) */ +- RENEG_ABORT /* Renegotiation initiated by client, abort the +- * connection */ +- } reneg_state; ++#ifndef SSL_OP_NO_RENEGOTIATION ++ /* For OpenSSL < 1.1.1, track the handshake/renegotiation state ++ * for the connection to block client-initiated renegotiations. ++ * For OpenSSL >=1.1.1, the SSL_OP_NO_RENEGOTIATION flag is used in ++ * the SSL * options state with equivalent effect. */ ++ modssl_reneg_state reneg_state; ++#endif + + server_rec *server; + SSLDirConfigRec *dc; +@@ -1158,6 +1163,9 @@ int ssl_is_challenge(conn_rec *c, const char *servername, + * the configured ENGINE. */ + int modssl_is_engine_id(const char *name); + ++/* Set the renegotation state for connection. */ ++void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state); ++ + #endif /* SSL_PRIVATE_H */ + /** @} */ + +diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c +index 38079a9..dafb833 100644 +--- a/modules/ssl/ssl_util_ssl.c ++++ b/modules/ssl/ssl_util_ssl.c +@@ -589,3 +589,19 @@ cleanup: + } + return rv; + } ++ ++void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state) ++{ ++#ifdef SSL_OP_NO_RENEGOTIATION ++ switch (state) { ++ case RENEG_ALLOW: ++ SSL_clear_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION); ++ break; ++ default: ++ SSL_set_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION); ++ break; ++ } ++#else ++ sslconn->reneg_state = state; ++#endif ++} diff --git a/SOURCES/httpd-2.4.51-r1892413+.patch b/SOURCES/httpd-2.4.51-r1892413+.patch new file mode 100644 index 0000000..59e2319 --- /dev/null +++ b/SOURCES/httpd-2.4.51-r1892413+.patch @@ -0,0 +1,156 @@ +# ./pullrev.sh 1892413 1895552 + +https://bugzilla.redhat.com/show_bug.cgi?id=1938740 + +http://svn.apache.org/viewvc?view=revision&revision=1892413 +http://svn.apache.org/viewvc?view=revision&revision=1895552 + +- also mod_cgi/mod_cgid log_flags fix from r1881559 + +--- httpd-2.4.51/modules/filters/mod_deflate.c.r1892413+ ++++ httpd-2.4.51/modules/filters/mod_deflate.c +@@ -1275,44 +1275,46 @@ + if (APR_BUCKET_IS_FLUSH(bkt)) { + apr_bucket *tmp_b; + +- ctx->inflate_total += ctx->stream.avail_out; +- zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH); +- ctx->inflate_total -= ctx->stream.avail_out; +- if (zRC != Z_OK) { +- inflateEnd(&ctx->stream); +- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01391) +- "Zlib error %d inflating data (%s)", zRC, +- ctx->stream.msg); +- return APR_EGENERAL; +- } ++ if (!ctx->done) { ++ ctx->inflate_total += ctx->stream.avail_out; ++ zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH); ++ ctx->inflate_total -= ctx->stream.avail_out; ++ if (zRC != Z_OK) { ++ inflateEnd(&ctx->stream); ++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01391) ++ "Zlib error %d inflating data (%s)", zRC, ++ ctx->stream.msg); ++ return APR_EGENERAL; ++ } + +- if (inflate_limit && ctx->inflate_total > inflate_limit) { +- inflateEnd(&ctx->stream); +- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02647) +- "Inflated content length of %" APR_OFF_T_FMT +- " is larger than the configured limit" +- " of %" APR_OFF_T_FMT, +- ctx->inflate_total, inflate_limit); +- return APR_ENOSPC; +- } ++ if (inflate_limit && ctx->inflate_total > inflate_limit) { ++ inflateEnd(&ctx->stream); ++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02647) ++ "Inflated content length of %" APR_OFF_T_FMT ++ " is larger than the configured limit" ++ " of %" APR_OFF_T_FMT, ++ ctx->inflate_total, inflate_limit); ++ return APR_ENOSPC; ++ } + +- if (!check_ratio(r, ctx, dc)) { +- inflateEnd(&ctx->stream); +- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02805) +- "Inflated content ratio is larger than the " +- "configured limit %i by %i time(s)", +- dc->ratio_limit, dc->ratio_burst); +- return APR_EINVAL; +- } ++ if (!check_ratio(r, ctx, dc)) { ++ inflateEnd(&ctx->stream); ++ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02805) ++ "Inflated content ratio is larger than the " ++ "configured limit %i by %i time(s)", ++ dc->ratio_limit, dc->ratio_burst); ++ return APR_EINVAL; ++ } + +- len = c->bufferSize - ctx->stream.avail_out; +- ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); +- tmp_b = apr_bucket_heap_create((char *)ctx->buffer, len, +- NULL, f->c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_b); ++ len = c->bufferSize - ctx->stream.avail_out; ++ ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); ++ tmp_b = apr_bucket_heap_create((char *)ctx->buffer, len, ++ NULL, f->c->bucket_alloc); ++ APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_b); + +- ctx->stream.next_out = ctx->buffer; +- ctx->stream.avail_out = c->bufferSize; ++ ctx->stream.next_out = ctx->buffer; ++ ctx->stream.avail_out = c->bufferSize; ++ } + + /* Flush everything so far in the returning brigade, but continue + * reading should EOS/more follow (don't lose them). +--- httpd-2.4.51/modules/generators/mod_cgi.c.r1892413+ ++++ httpd-2.4.51/modules/generators/mod_cgi.c +@@ -191,11 +191,10 @@ + apr_file_t *f = NULL; + apr_finfo_t finfo; + char time_str[APR_CTIME_LEN]; +- int log_flags = rv ? APLOG_ERR : APLOG_ERR; + + /* Intentional no APLOGNO */ + /* Callee provides APLOGNO in error text */ +- ap_log_rerror(APLOG_MARK, log_flags, rv, r, ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "%s%s: %s", logno ? logno : "", error, r->filename); + + /* XXX Very expensive mainline case! Open, then getfileinfo! */ +--- httpd-2.4.51/modules/generators/mod_cgid.c.r1892413+ ++++ httpd-2.4.51/modules/generators/mod_cgid.c +@@ -1190,11 +1190,10 @@ + apr_file_t *f = NULL; + struct stat finfo; + char time_str[APR_CTIME_LEN]; +- int log_flags = rv ? APLOG_ERR : APLOG_ERR; + + /* Intentional no APLOGNO */ + /* Callee provides APLOGNO in error text */ +- ap_log_rerror(APLOG_MARK, log_flags, rv, r, ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, + "%s: %s", error, r->filename); + + /* XXX Very expensive mainline case! Open, then getfileinfo! */ +--- httpd-2.4.51/server/mpm_unix.c.r1892413+ ++++ httpd-2.4.51/server/mpm_unix.c +@@ -259,10 +259,12 @@ + while (cur_extra) { + ap_generation_t old_gen; + extra_process_t *next = cur_extra->next; ++ pid_t pid = cur_extra->pid; + +- if (reclaim_one_pid(cur_extra->pid, action_table[cur_action].action)) { +- if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) { +- mpm_callback(-1, cur_extra->pid, old_gen); ++ if (reclaim_one_pid(pid, action_table[cur_action].action)) { ++ if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) { ++ /* cur_extra dangling pointer from here. */ ++ mpm_callback(-1, pid, old_gen); + } + else { + AP_DEBUG_ASSERT(1 == 0); +@@ -307,10 +309,12 @@ + while (cur_extra) { + ap_generation_t old_gen; + extra_process_t *next = cur_extra->next; ++ pid_t pid = cur_extra->pid; + +- if (reclaim_one_pid(cur_extra->pid, DO_NOTHING)) { +- if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) { +- mpm_callback(-1, cur_extra->pid, old_gen); ++ if (reclaim_one_pid(pid, DO_NOTHING)) { ++ if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) { ++ /* cur_extra dangling pointer from here. */ ++ mpm_callback(-1, pid, old_gen); + } + else { + AP_DEBUG_ASSERT(1 == 0); diff --git a/SOURCES/httpd-2.4.53-detect-systemd.patch b/SOURCES/httpd-2.4.53-detect-systemd.patch new file mode 100644 index 0000000..d501b06 --- /dev/null +++ b/SOURCES/httpd-2.4.53-detect-systemd.patch @@ -0,0 +1,45 @@ +diff --git a/Makefile.in b/Makefile.in +index a2e9c82..bd8045c 100644 +--- a/Makefile.in ++++ b/Makefile.in +@@ -4,7 +4,7 @@ CLEAN_SUBDIRS = test + + PROGRAM_NAME = $(progname) + PROGRAM_SOURCES = modules.c +-PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(PCRE_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) ++PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS) + PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c + PROGRAM_DEPENDENCIES = \ + server/libmain.la \ +diff --git a/acinclude.m4 b/acinclude.m4 +index 97484c9..05abe18 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -631,6 +631,7 @@ case $host in + 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 +diff --git a/configure.in b/configure.in +index cf437fe..521fc45 100644 +--- a/configure.in ++++ b/configure.in +@@ -239,6 +239,7 @@ if test "x$PCRE_CONFIG" != "x"; then + AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG]) + APR_ADDTO(PCRE_INCLUDES, [`$PCRE_CONFIG --cflags`]) + APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs8 2>/dev/null || $PCRE_CONFIG --libs`]) ++ APR_ADDTO(HTTPD_LIBS, [\$(PCRE_LIBS)]) + else + AC_MSG_ERROR([pcre(2)-config for libpcre not found. PCRE is required and available from http://pcre.org/]) + fi +@@ -734,6 +735,7 @@ APACHE_SUBST(OS_DIR) + APACHE_SUBST(BUILTIN_LIBS) + APACHE_SUBST(SHLIBPATH_VAR) + APACHE_SUBST(OS_SPECIFIC_VARS) ++APACHE_SUBST(HTTPD_LIBS) + + PRE_SHARED_CMDS='echo ""' + POST_SHARED_CMDS='echo ""' diff --git a/SOURCES/httpd-2.4.53-icons.patch b/SOURCES/httpd-2.4.53-icons.patch new file mode 100644 index 0000000..efc0c4d --- /dev/null +++ b/SOURCES/httpd-2.4.53-icons.patch @@ -0,0 +1,49 @@ +diff --git a/docs/conf/extra/httpd-autoindex.conf.in b/docs/conf/extra/httpd-autoindex.conf.in +index 51b02ed..93a2b87 100644 +--- a/docs/conf/extra/httpd-autoindex.conf.in ++++ b/docs/conf/extra/httpd-autoindex.conf.in +@@ -21,7 +21,7 @@ IndexOptions FancyIndexing HTMLTable VersionSort + Alias /icons/ "@exp_iconsdir@/" + + +- Options Indexes MultiViews ++ Options Indexes MultiViews FollowSymlinks + AllowOverride None + Require all granted + +@@ -37,6 +37,7 @@ AddIconByType (TXT,/icons/text.gif) text/* + AddIconByType (IMG,/icons/image2.gif) image/* + AddIconByType (SND,/icons/sound2.gif) audio/* + AddIconByType (VID,/icons/movie.gif) video/* ++AddIconByType /icons/bomb.gif application/x-coredump + + AddIcon /icons/binary.gif .bin .exe + AddIcon /icons/binhex.gif .hqx +@@ -53,7 +54,6 @@ 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/back.gif .. + AddIcon /icons/hand.right.gif README +diff --git a/docs/conf/magic b/docs/conf/magic +index bc891d9..9a41b44 100644 +--- a/docs/conf/magic ++++ b/docs/conf/magic +@@ -383,3 +383,15 @@ + 4 string moov video/quicktime + 4 string mdat video/quicktime + ++ ++#------------------------------------------------------------------------------ ++# application/x-coredump for LE/BE ELF ++# ++0 string \177ELF ++>5 byte 1 ++>16 leshort 4 application/x-coredump ++ ++0 string \177ELF ++>5 byte 2 ++>16 beshort 4 application/x-coredump ++ diff --git a/SOURCES/httpd-2.4.53-r1878890.patch b/SOURCES/httpd-2.4.53-r1878890.patch new file mode 100644 index 0000000..945c498 --- /dev/null +++ b/SOURCES/httpd-2.4.53-r1878890.patch @@ -0,0 +1,116 @@ +diff --git a/include/util_ldap.h b/include/util_ldap.h +index 28e0760..edb8a81 100644 +--- a/include/util_ldap.h ++++ b/include/util_ldap.h +@@ -32,7 +32,6 @@ + #if APR_MAJOR_VERSION < 2 + /* The LDAP API is currently only present in APR 1.x */ + #include "apr_ldap.h" +-#include "apr_ldap_rebind.h" + #else + #define APR_HAS_LDAP 0 + #endif +diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c +index 4d92ec9..864bd62 100644 +--- a/modules/ldap/util_ldap.c ++++ b/modules/ldap/util_ldap.c +@@ -154,6 +154,38 @@ static int util_ldap_handler(request_rec *r) + return OK; + } + ++/* For OpenLDAP with the 3-arg version of ldap_set_rebind_proc(), use ++ * a simpler rebind callback than the implementation in APR-util. ++ * Testing for API version >= 3001 appears safe although OpenLDAP ++ * 2.1.x (API version = 2004) also has the 3-arg API. */ ++#if APR_HAS_OPENLDAP_LDAPSDK && defined(LDAP_API_VERSION) && LDAP_API_VERSION >= 3001 ++ ++#define uldap_rebind_init(p) APR_SUCCESS /* noop */ ++ ++static int uldap_rebind_proc(LDAP *ld, const char *url, ber_tag_t request, ++ ber_int_t msgid, void *params) ++{ ++ util_ldap_connection_t *ldc = params; ++ ++ return ldap_bind_s(ld, ldc->binddn, ldc->bindpw, LDAP_AUTH_SIMPLE); ++} ++ ++static apr_status_t uldap_rebind_add(util_ldap_connection_t *ldc) ++{ ++ ldap_set_rebind_proc(ldc->ldap, uldap_rebind_proc, ldc); ++ return APR_SUCCESS; ++} ++ ++#else /* !APR_HAS_OPENLDAP_LDAPSDK */ ++ ++#define USE_APR_LDAP_REBIND ++#include ++ ++#define uldap_rebind_init(p) apr_ldap_rebind_init(p) ++#define uldap_rebind_add(ldc) apr_ldap_rebind_add((ldc)->rebind_pool, \ ++ (ldc)->ldap, (ldc)->binddn, \ ++ (ldc)->bindpw) ++#endif + + + /* ------------------------------------------------------------------ */ +@@ -195,6 +227,13 @@ static apr_status_t uldap_connection_unbind(void *param) + util_ldap_connection_t *ldc = param; + + if (ldc) { ++#ifdef USE_APR_LDAP_REBIND ++ /* forget the rebind info for this conn */ ++ if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) { ++ apr_pool_clear(ldc->rebind_pool); ++ } ++#endif ++ + if (ldc->ldap) { + if (ldc->r) { + ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp unbind", ldc); +@@ -203,12 +242,6 @@ static apr_status_t uldap_connection_unbind(void *param) + ldc->ldap = NULL; + } + ldc->bound = 0; +- +- /* forget the rebind info for this conn */ +- if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) { +- apr_ldap_rebind_remove(ldc->ldap); +- apr_pool_clear(ldc->rebind_pool); +- } + } + + return APR_SUCCESS; +@@ -344,7 +377,7 @@ static int uldap_connection_init(request_rec *r, + + if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) { + /* Now that we have an ldap struct, add it to the referral list for rebinds. */ +- rc = apr_ldap_rebind_add(ldc->rebind_pool, ldc->ldap, ldc->binddn, ldc->bindpw); ++ rc = uldap_rebind_add(ldc); + if (rc != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server, APLOGNO(01277) + "LDAP: Unable to add rebind cross reference entry. Out of memory?"); +@@ -870,6 +903,7 @@ static util_ldap_connection_t * + /* whether or not to keep this connection in the pool when it's returned */ + l->keep = (st->connection_pool_ttl == 0) ? 0 : 1; + ++#ifdef USE_APR_LDAP_REBIND + if (l->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) { + if (apr_pool_create(&(l->rebind_pool), l->pool) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01286) +@@ -881,6 +915,7 @@ static util_ldap_connection_t * + } + apr_pool_tag(l->rebind_pool, "util_ldap_rebind"); + } ++#endif + + if (p) { + p->next = l; +@@ -3068,7 +3103,7 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog, + } + + /* Initialize the rebind callback's cross reference list. */ +- apr_ldap_rebind_init (p); ++ (void) uldap_rebind_init(p); + + #ifdef AP_LDAP_OPT_DEBUG + if (st->debug_level > 0) { diff --git a/SOURCES/httpd-2.4.53-separate-systemd-fns.patch b/SOURCES/httpd-2.4.53-separate-systemd-fns.patch new file mode 100644 index 0000000..88b99ff --- /dev/null +++ b/SOURCES/httpd-2.4.53-separate-systemd-fns.patch @@ -0,0 +1,286 @@ +diff --git a/acinclude.m4 b/acinclude.m4 +index 05abe18..97484c9 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -631,7 +631,6 @@ case $host in + 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 +diff --git a/include/ap_listen.h b/include/ap_listen.h +index 58c2574..d5ed968 100644 +--- a/include/ap_listen.h ++++ b/include/ap_listen.h +@@ -29,6 +29,7 @@ + #include "apr_network_io.h" + #include "httpd.h" + #include "http_config.h" ++#include "apr_optional.h" + + #ifdef __cplusplus + extern "C" { +@@ -143,6 +144,15 @@ AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, + void *dummy, + const char *arg); + ++#ifdef HAVE_SYSTEMD ++APR_DECLARE_OPTIONAL_FN(int, ++ ap_find_systemd_socket, (process_rec *, apr_port_t)); ++ ++APR_DECLARE_OPTIONAL_FN(int, ++ ap_systemd_listen_fds, (int)); ++#endif ++ ++ + #define LISTEN_COMMANDS \ + AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \ + "Maximum length of the queue of pending connections, as used by listen(2)"), \ +diff --git a/modules/arch/unix/mod_systemd.c b/modules/arch/unix/mod_systemd.c +index eda1272..fc059fc 100644 +--- a/modules/arch/unix/mod_systemd.c ++++ b/modules/arch/unix/mod_systemd.c +@@ -35,6 +35,15 @@ + #include + #endif + ++APR_DECLARE_OPTIONAL_FN(int, ++ ap_find_systemd_socket, (process_rec *, apr_port_t)); ++ ++APR_DECLARE_OPTIONAL_FN(int, ++ ap_systemd_listen_fds, (int)); ++ ++APR_DECLARE_OPTIONAL_FN(int, ++ ap_systemd_journal_stream_fd, (const char *, int, int)); ++ + static char describe_listeners[30]; + + static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog, +@@ -145,8 +154,47 @@ static int systemd_monitor(apr_pool_t *p, server_rec *s) + return DECLINED; + } + ++static int ap_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 int ap_systemd_listen_fds(int unset_environment){ ++ return sd_listen_fds(unset_environment); ++} ++ ++static int ap_systemd_journal_stream_fd(const char *identifier, int priority, int level_prefix){ ++ return sd_journal_stream_fd("httpd", priority, 0); ++} ++ + static void systemd_register_hooks(apr_pool_t *p) + { ++ APR_REGISTER_OPTIONAL_FN(ap_systemd_listen_fds); ++ APR_REGISTER_OPTIONAL_FN(ap_find_systemd_socket); ++ APR_REGISTER_OPTIONAL_FN(ap_systemd_journal_stream_fd); ++ + /* Enable ap_extended_status. */ + ap_hook_pre_config(systemd_pre_config, NULL, NULL, APR_HOOK_LAST); + /* Signal service is ready. */ +diff --git a/modules/loggers/config.m4 b/modules/loggers/config.m4 +index 0848d2e..8af2299 100644 +--- a/modules/loggers/config.m4 ++++ b/modules/loggers/config.m4 +@@ -5,7 +5,6 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + APACHE_MODPATH_INIT(loggers) + + APACHE_MODULE(log_config, logging configuration. You won't be able to log requests to the server without this module., , , yes) +-APR_ADDTO(MOD_LOG_CONFIG_LDADD, [$SYSTEMD_LIBS]) + + APACHE_MODULE(log_debug, configurable debug logging, , , most) + APACHE_MODULE(log_forensic, forensic logging) +diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c +index 0b11f60..c3f0a51 100644 +--- a/modules/loggers/mod_log_config.c ++++ b/modules/loggers/mod_log_config.c +@@ -172,10 +172,6 @@ + #include + #endif + +-#ifdef HAVE_SYSTEMD +-#include +-#endif +- + #define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b" + + module AP_MODULE_DECLARE_DATA log_config_module; +@@ -1640,8 +1636,15 @@ static apr_status_t wrap_journal_stream(apr_pool_t *p, apr_file_t **outfd, + { + #ifdef HAVE_SYSTEMD + int fd; ++ APR_OPTIONAL_FN_TYPE(ap_systemd_journal_stream_fd) *systemd_journal_stream_fd; ++ ++ systemd_journal_stream_fd = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_journal_stream_fd); ++ if (systemd_journal_stream_fd == NULL) { ++ return APR_ENOTIMPL; ++ } + +- fd = sd_journal_stream_fd("httpd", priority, 0); ++ fd = systemd_journal_stream_fd("httpd", priority, 0); ++ + if (fd < 0) return fd; + + /* This is an AF_UNIX socket fd so is more pipe-like than +diff --git a/modules/loggers/mod_log_config.h b/modules/loggers/mod_log_config.h +index 877a593..bd52a98 100644 +--- a/modules/loggers/mod_log_config.h ++++ b/modules/loggers/mod_log_config.h +@@ -69,6 +69,10 @@ APR_DECLARE_OPTIONAL_FN(ap_log_writer_init*, ap_log_set_writer_init,(ap_log_writ + */ + APR_DECLARE_OPTIONAL_FN(ap_log_writer*, ap_log_set_writer, (ap_log_writer* func)); + ++#ifdef HAVE_SYSTEMD ++APR_DECLARE_OPTIONAL_FN(int, ap_systemd_journal_stream_fd, (const char *, int, int)); ++#endif ++ + #endif /* MOD_LOG_CONFIG */ + /** @} */ + +diff --git a/server/listen.c b/server/listen.c +index e2e028a..5d1c0e1 100644 +--- a/server/listen.c ++++ b/server/listen.c +@@ -34,10 +34,6 @@ + #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 +@@ -325,34 +321,6 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to, + } + + #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) +@@ -412,6 +380,14 @@ static const char *set_systemd_listener(process_rec *process, apr_port_t port, + { + ap_listen_rec *last, *new; + apr_status_t rv; ++ APR_OPTIONAL_FN_TYPE(ap_find_systemd_socket) *find_systemd_socket; ++ ++ find_systemd_socket = APR_RETRIEVE_OPTIONAL_FN(ap_find_systemd_socket); ++ ++ if (!find_systemd_socket) ++ return "Systemd socket activation is used, but mod_systemd is probably " ++ "not loaded"; ++ + int fd = find_systemd_socket(process, port); + if (fd < 0) { + return "Systemd socket activation is used, but this port is not " +@@ -438,7 +414,6 @@ static const char *set_systemd_listener(process_rec *process, apr_port_t port, + + return NULL; + } +- + #endif /* HAVE_SYSTEMD */ + + static const char *alloc_listener(process_rec *process, const char *addr, +@@ -707,6 +682,9 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s) + int num_listeners = 0; + const char* proto; + int found; ++#ifdef HAVE_SYSTEMD ++ APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds; ++#endif + + for (ls = s; ls; ls = ls->next) { + proto = ap_get_server_protocol(ls); +@@ -746,7 +724,10 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s) + apr_pool_cleanup_null, s->process->pool); + } + else { +- sd_listen_fds(1); ++ systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds); ++ if (systemd_listen_fds != NULL) { ++ systemd_listen_fds(1); ++ } + } + } + else +@@ -963,6 +944,9 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, + apr_port_t port; + apr_status_t rv; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); ++#ifdef HAVE_SYSTEMD ++ APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds; ++#endif + + if (err != NULL) { + return err; +@@ -973,7 +957,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, + } + #ifdef HAVE_SYSTEMD + if (use_systemd == -1) { +- use_systemd = sd_listen_fds(0) > 0; ++ systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds); ++ if (systemd_listen_fds != NULL) { ++ use_systemd = systemd_listen_fds(0) > 0; ++ } else { ++ use_systemd = 0; ++ } + } + #endif + diff --git a/SOURCES/httpd-2.4.57-CVE-2023-31122.patch b/SOURCES/httpd-2.4.57-CVE-2023-31122.patch new file mode 100644 index 0000000..c2aa207 --- /dev/null +++ b/SOURCES/httpd-2.4.57-CVE-2023-31122.patch @@ -0,0 +1,11 @@ +--- a/modules/core/mod_macro.c 2023/10/16 06:19:16 1912992 ++++ b/modules/core/mod_macro.c 2023/10/16 06:38:32 1912993 +@@ -483,7 +483,7 @@ + for (i = 0; i < contents->nelts; i++) { + const char *errmsg; + /* copy the line and substitute macro parameters */ +- strncpy(line, ((char **) contents->elts)[i], MAX_STRING_LEN - 1); ++ apr_cpystrn(line, ((char **) contents->elts)[i], MAX_STRING_LEN); + errmsg = substitute_macro_args(line, MAX_STRING_LEN, + macro, replacements, used); + if (errmsg) { diff --git a/SOURCES/httpd-2.4.57-covscan.patch b/SOURCES/httpd-2.4.57-covscan.patch new file mode 100644 index 0000000..6a65ee1 --- /dev/null +++ b/SOURCES/httpd-2.4.57-covscan.patch @@ -0,0 +1,14 @@ +diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c +index f93f23f..4be51de 100644 +--- a/modules/mappers/mod_rewrite.c ++++ b/modules/mappers/mod_rewrite.c +@@ -4758,8 +4758,8 @@ static int hook_uri2file(request_rec *r) + } + + if (rulestatus) { +- unsigned skip_absolute = is_absolute_uri(r->filename, NULL); + apr_size_t flen = r->filename ? strlen(r->filename) : 0; ++ unsigned skip_absolute = flen ? is_absolute_uri(r->filename, NULL) : 0; + int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0); + int will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE); + diff --git a/SOURCES/httpd-2.4.57-davenoent.patch b/SOURCES/httpd-2.4.57-davenoent.patch new file mode 100644 index 0000000..874f766 --- /dev/null +++ b/SOURCES/httpd-2.4.57-davenoent.patch @@ -0,0 +1,51 @@ +--- httpd-2.4.57/modules/dav/fs/repos.c.davenoent ++++ httpd-2.4.57/modules/dav/fs/repos.c +@@ -35,6 +35,7 @@ + #include "mod_dav.h" + #include "repos.h" + ++APLOG_USE_MODULE(dav_fs); + + /* to assist in debugging mod_dav's GET handling */ + #define DEBUG_GET_HANDLER 0 +@@ -1586,6 +1587,19 @@ + status = apr_stat(&fsctx->info1.finfo, fsctx->path1.buf, + DAV_FINFO_MASK, pool); + if (status != APR_SUCCESS && status != APR_INCOMPLETE) { ++ dav_resource_private *ctx = params->root->info; ++ ++ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, ctx->r, ++ APLOGNO(10472) "could not access file (%s) during directory walk", ++ fsctx->path1.buf); ++ ++ /* If being tolerant, ignore failure due to losing a race ++ * with some other process deleting files out from under ++ * the directory walk. */ ++ if ((params->walk_type & DAV_WALKTYPE_TOLERANT) ++ && APR_STATUS_IS_ENOENT(status)) { ++ continue; ++ } + /* woah! where'd it go? */ + /* ### should have a better error here */ + err = dav_new_error(pool, HTTP_NOT_FOUND, 0, status, NULL); +--- httpd-2.4.57/modules/dav/main/mod_dav.c.davenoent ++++ httpd-2.4.57/modules/dav/main/mod_dav.c +@@ -2187,7 +2187,7 @@ + return HTTP_BAD_REQUEST; + } + +- ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH; ++ ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH | DAV_WALKTYPE_TOLERANT; + ctx.w.func = dav_propfind_walker; + ctx.w.walk_ctx = &ctx; + ctx.w.pool = r->pool; +--- httpd-2.4.57/modules/dav/main/mod_dav.h.davenoent ++++ httpd-2.4.57/modules/dav/main/mod_dav.h +@@ -1823,6 +1823,7 @@ + #define DAV_WALKTYPE_AUTH 0x0001 /* limit to authorized files */ + #define DAV_WALKTYPE_NORMAL 0x0002 /* walk normal files */ + #define DAV_WALKTYPE_LOCKNULL 0x0004 /* walk locknull resources */ ++#define DAV_WALKTYPE_TOLERANT 0x0008 /* tolerate non-fatal errors */ + + /* callback function and a client context for the walk */ + dav_error * (*func)(dav_walk_resource *wres, int calltype); diff --git a/SOURCES/httpd-2.4.57-gettid.patch b/SOURCES/httpd-2.4.57-gettid.patch new file mode 100644 index 0000000..7530449 --- /dev/null +++ b/SOURCES/httpd-2.4.57-gettid.patch @@ -0,0 +1,81 @@ +diff --git a/configure.in b/configure.in +index a3c994b..9a4351a 100644 +--- a/configure.in ++++ b/configure.in +@@ -524,7 +524,8 @@ prctl \ + timegm \ + getpgid \ + fopen64 \ +-getloadavg ++getloadavg \ ++gettid + ) + + dnl confirm that a void pointer is large enough to store a long integer +@@ -535,16 +536,19 @@ AC_CHECK_LIB(selinux, is_selinux_enabled, [ + APR_ADDTO(HTTPD_LIBS, [-lselinux]) + ]) + +-AC_CACHE_CHECK([for gettid()], ac_cv_gettid, ++if test $ac_cv_func_gettid = no; then ++ # On Linux before glibc 2.30, gettid() is only usable via syscall() ++ AC_CACHE_CHECK([for gettid() via syscall], ap_cv_gettid, + [AC_TRY_RUN(#define _GNU_SOURCE + #include + #include + #include + int main(int argc, char **argv) { + pid_t t = syscall(SYS_gettid); return t == -1 ? 1 : 0; }, +-[ac_cv_gettid=yes], [ac_cv_gettid=no], [ac_cv_gettid=no])]) +-if test "$ac_cv_gettid" = "yes"; then +- AC_DEFINE(HAVE_GETTID, 1, [Define if you have gettid()]) ++ [ap_cv_gettid=yes], [ap_cv_gettid=no], [ap_cv_gettid=no])]) ++ if test "$ap_cv_gettid" = "yes"; then ++ AC_DEFINE(HAVE_SYS_GETTID, 1, [Define if you have gettid() via syscall()]) ++ fi + fi + + dnl ## Check for the tm_gmtoff field in struct tm to get the timezone diffs +diff --git a/server/log.c b/server/log.c +index cc04c38..ed3b920 100644 +--- a/server/log.c ++++ b/server/log.c +@@ -55,7 +55,7 @@ + #include "ap_mpm.h" + #include "ap_listen.h" + +-#if HAVE_GETTID ++#if HAVE_SYS_GETTID + #include + #include + #endif +@@ -627,14 +627,18 @@ static int log_tid(const ap_errorlog_info *info, const char *arg, + #if APR_HAS_THREADS + int result; + #endif +-#if HAVE_GETTID ++#if defined(HAVE_GETTID) || defined(HAVE_SYS_GETTID) + if (arg && *arg == 'g') { ++#ifdef HAVE_GETTID ++ pid_t tid = gettid(); ++#else + pid_t tid = syscall(SYS_gettid); ++#endif + if (tid == -1) + return 0; + return apr_snprintf(buf, buflen, "%"APR_PID_T_FMT, tid); + } +-#endif ++#endif /* HAVE_GETTID || HAVE_SYS_GETTID */ + #if APR_HAS_THREADS + if (ap_mpm_query(AP_MPMQ_IS_THREADED, &result) == APR_SUCCESS + && result != AP_MPMQ_NOT_SUPPORTED) +@@ -968,7 +972,7 @@ static int do_errorlog_default(const ap_errorlog_info *info, char *buf, + #if APR_HAS_THREADS + field_start = len; + len += cpystrn(buf + len, ":tid ", buflen - len); +- item_len = log_tid(info, NULL, buf + len, buflen - len); ++ item_len = log_tid(info, "g", buf + len, buflen - len); + if (!item_len) + len = field_start; + else diff --git a/SOURCES/httpd-2.4.57-mod_status-duplicate-key.patch b/SOURCES/httpd-2.4.57-mod_status-duplicate-key.patch new file mode 100644 index 0000000..57b3726 --- /dev/null +++ b/SOURCES/httpd-2.4.57-mod_status-duplicate-key.patch @@ -0,0 +1,170 @@ +commit af065bb14238c2877f16dc955f6db69579d45b03 +Author: Tomas Korbar +Date: Thu Jul 20 09:48:17 2023 +0200 + + Fix duplicate presence of keys printed by mod_status + +diff --git a/modules/generators/mod_status.c b/modules/generators/mod_status.c +index 5917953..5bada07 100644 +--- a/modules/generators/mod_status.c ++++ b/modules/generators/mod_status.c +@@ -186,7 +186,8 @@ static int status_handler(request_rec *r) + apr_uint32_t up_time; + ap_loadavg_t t; + int j, i, res, written; +- int ready; ++ int idle; ++ int graceful; + int busy; + unsigned long count; + unsigned long lres, my_lres, conn_lres; +@@ -203,6 +204,7 @@ static int status_handler(request_rec *r) + char *stat_buffer; + pid_t *pid_buffer, worker_pid; + int *thread_idle_buffer = NULL; ++ int *thread_graceful_buffer = NULL; + int *thread_busy_buffer = NULL; + clock_t tu, ts, tcu, tcs; + clock_t gu, gs, gcu, gcs; +@@ -231,7 +233,8 @@ static int status_handler(request_rec *r) + #endif + #endif + +- ready = 0; ++ idle = 0; ++ graceful = 0; + busy = 0; + count = 0; + bcount = 0; +@@ -250,6 +253,7 @@ static int status_handler(request_rec *r) + stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char)); + if (is_async) { + thread_idle_buffer = apr_palloc(r->pool, server_limit * sizeof(int)); ++ thread_graceful_buffer = apr_palloc(r->pool, server_limit * sizeof(int)); + thread_busy_buffer = apr_palloc(r->pool, server_limit * sizeof(int)); + } + +@@ -318,6 +322,7 @@ static int status_handler(request_rec *r) + ps_record = ap_get_scoreboard_process(i); + if (is_async) { + thread_idle_buffer[i] = 0; ++ thread_graceful_buffer[i] = 0; + thread_busy_buffer[i] = 0; + } + for (j = 0; j < thread_limit; ++j) { +@@ -336,18 +341,20 @@ static int status_handler(request_rec *r) + && ps_record->pid) { + if (res == SERVER_READY) { + if (ps_record->generation == mpm_generation) +- ready++; ++ idle++; + if (is_async) + thread_idle_buffer[i]++; + } + else if (res != SERVER_DEAD && + res != SERVER_STARTING && + res != SERVER_IDLE_KILL) { +- busy++; +- if (is_async) { +- if (res == SERVER_GRACEFUL) +- thread_idle_buffer[i]++; +- else ++ if (res == SERVER_GRACEFUL) { ++ graceful++; ++ if (is_async) ++ thread_graceful_buffer[i]++; ++ } else { ++ busy++; ++ if (is_async) + thread_busy_buffer[i]++; + } + } +@@ -548,10 +555,10 @@ static int status_handler(request_rec *r) + } /* ap_extended_status */ + + if (!short_report) +- ap_rprintf(r, "

    %d requests currently being processed, " +- "%d idle workers
    \n", busy, ready); ++ ap_rprintf(r, "
    %d requests currently being processed, %d workers gracefully restarting, " ++ "%d idle workers
    \n", busy, graceful, idle); + else +- ap_rprintf(r, "BusyWorkers: %d\nIdleWorkers: %d\n", busy, ready); ++ ap_rprintf(r, "BusyWorkers: %d\nGracefulWorkers: %d\nIdleWorkers: %d\n", busy, graceful, idle); + + if (!short_report) + ap_rputs("", r); +@@ -559,11 +566,6 @@ static int status_handler(request_rec *r) + if (is_async) { + int write_completion = 0, lingering_close = 0, keep_alive = 0, + connections = 0, stopping = 0, procs = 0; +- /* +- * These differ from 'busy' and 'ready' in how gracefully finishing +- * threads are counted. XXX: How to make this clear in the html? +- */ +- int busy_workers = 0, idle_workers = 0; + if (!short_report) + ap_rputs("\n\n\n" + "" +@@ -573,7 +575,7 @@ static int status_handler(request_rec *r) + "" + "\n" + "" +- "" ++ "" + "\n", r); + for (i = 0; i < server_limit; ++i) { + ps_record = ap_get_scoreboard_process(i); +@@ -582,8 +584,6 @@ static int status_handler(request_rec *r) + write_completion += ps_record->write_completion; + keep_alive += ps_record->keep_alive; + lingering_close += ps_record->lingering_close; +- busy_workers += thread_busy_buffer[i]; +- idle_workers += thread_idle_buffer[i]; + procs++; + if (ps_record->quiescing) { + stopping++; +@@ -599,7 +599,7 @@ static int status_handler(request_rec *r) + ap_rprintf(r, "" + "" + "" +- "" ++ "" + "" + "\n", + i, ps_record->pid, +@@ -607,6 +607,7 @@ static int status_handler(request_rec *r) + ps_record->connections, + ps_record->not_accepting ? "no" : "yes", + thread_busy_buffer[i], ++ thread_graceful_buffer[i], + thread_idle_buffer[i], + ps_record->write_completion, + ps_record->keep_alive, +@@ -618,25 +619,22 @@ static int status_handler(request_rec *r) + ap_rprintf(r, "" + "" + "" +- "" ++ "" + "" + "\n
    SlotThreadsAsync connections
    totalacceptingbusyidlebusygracefulidlewritingkeep-aliveclosing
    %u%" APR_PID_T_FMT "%s%s%u%s%u%u%u%u%u%u%u%u
    Sum%d%d%d %d%d%d%d%d%d%d%d
    \n", + procs, stopping, + connections, +- busy_workers, idle_workers, ++ busy, graceful, idle, + write_completion, keep_alive, lingering_close); + } + else { + ap_rprintf(r, "Processes: %d\n" + "Stopping: %d\n" +- "BusyWorkers: %d\n" +- "IdleWorkers: %d\n" + "ConnsTotal: %d\n" + "ConnsAsyncWriting: %d\n" + "ConnsAsyncKeepAlive: %d\n" + "ConnsAsyncClosing: %d\n", + procs, stopping, +- busy_workers, idle_workers, + connections, + write_completion, keep_alive, lingering_close); + } diff --git a/SOURCES/httpd-2.4.57-pr37355.patch b/SOURCES/httpd-2.4.57-pr37355.patch new file mode 100644 index 0000000..7f57e2b --- /dev/null +++ b/SOURCES/httpd-2.4.57-pr37355.patch @@ -0,0 +1,143 @@ +diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c +index 537c3c2..596320d 100644 +--- a/modules/proxy/mod_proxy.c ++++ b/modules/proxy/mod_proxy.c +@@ -1460,11 +1460,20 @@ static int proxy_handler(request_rec *r) + /* handle the scheme */ + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01142) + "Trying to run scheme_handler against proxy"); ++ ++ if (ents[i].creds) { ++ apr_table_set(r->notes, "proxy-basic-creds", ents[i].creds); ++ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, ++ "Using proxy auth creds %s", ents[i].creds); ++ } ++ + access_status = proxy_run_scheme_handler(r, worker, + conf, url, + ents[i].hostname, + ents[i].port); + ++ if (ents[i].creds) apr_table_unset(r->notes, "proxy-basic-creds"); ++ + /* Did the scheme handler process the request? */ + if (access_status != DECLINED) { + const char *cl_a; +@@ -1902,8 +1911,8 @@ static void *merge_proxy_dir_config(apr_pool_t *p, void *basev, void *addv) + return new; + } + +-static const char * +- add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1, int regex) ++static const char *add_proxy(cmd_parms *cmd, void *dummy, const char *f1, ++ const char *r1, const char *creds, int regex) + { + server_rec *s = cmd->server; + proxy_server_conf *conf = +@@ -1961,19 +1970,24 @@ static const char * + new->port = port; + new->regexp = reg; + new->use_regex = regex; ++ if (creds) { ++ new->creds = apr_pstrcat(cmd->pool, "Basic ", ++ ap_pbase64encode(cmd->pool, (char *)creds), ++ NULL); ++ } + return NULL; + } + +-static const char * +- add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1) ++static const char *add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1, ++ const char *r1, const char *creds) + { +- return add_proxy(cmd, dummy, f1, r1, 0); ++ return add_proxy(cmd, dummy, f1, r1, creds, 0); + } + +-static const char * +- add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1) ++static const char *add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1, ++ const char *r1, const char *creds) + { +- return add_proxy(cmd, dummy, f1, r1, 1); ++ return add_proxy(cmd, dummy, f1, r1, creds, 1); + } + + PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url) +@@ -3012,9 +3026,9 @@ static const command_rec proxy_cmds[] = + "location, in regular expression syntax"), + AP_INIT_FLAG("ProxyRequests", set_proxy_req, NULL, RSRC_CONF, + "on if the true proxy requests should be accepted"), +- AP_INIT_TAKE2("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF, ++ AP_INIT_TAKE23("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF, + "a scheme, partial URL or '*' and a proxy server"), +- AP_INIT_TAKE2("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF, ++ AP_INIT_TAKE23("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF, + "a regex pattern and a proxy server"), + AP_INIT_FLAG("ProxyPassInterpolateEnv", ap_set_flag_slot_char, + (void*)APR_OFFSETOF(proxy_dir_conf, interpolate_env), +diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h +index c51145e..eaf431d 100644 +--- a/modules/proxy/mod_proxy.h ++++ b/modules/proxy/mod_proxy.h +@@ -121,6 +121,7 @@ struct proxy_remote { + const char *protocol; /* the scheme used to talk to this proxy */ + const char *hostname; /* the hostname of this proxy */ + ap_regex_t *regexp; /* compiled regex (if any) for the remote */ ++ const char *creds; /* auth credentials (if any) for the proxy */ + int use_regex; /* simple boolean. True if we have a regex pattern */ + apr_port_t port; /* the port for this proxy */ + }; +diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c +index caafde0..ea36465 100644 +--- a/modules/proxy/proxy_util.c ++++ b/modules/proxy/proxy_util.c +@@ -2708,11 +2708,14 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, + * So let's make it configurable by env. + * The logic here is the same used in mod_proxy_http. + */ +- proxy_auth = apr_table_get(r->headers_in, "Proxy-Authorization"); ++ proxy_auth = apr_table_get(r->notes, "proxy-basic-creds"); ++ if (proxy_auth == NULL) ++ proxy_auth = apr_table_get(r->headers_in, "Proxy-Authorization"); ++ + if (proxy_auth != NULL && + proxy_auth[0] != '\0' && +- r->user == NULL && /* we haven't yet authenticated */ +- apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) { ++ (r->user == NULL /* we haven't yet authenticated */ ++ || apr_table_get(r->subprocess_env, "Proxy-Chain-Auth"))) { + forward->proxy_auth = apr_pstrdup(conn->pool, proxy_auth); + } + } +@@ -2948,7 +2951,8 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend, + nbytes = apr_snprintf(buffer, sizeof(buffer), + "CONNECT %s:%d HTTP/1.0" CRLF, + forward->target_host, forward->target_port); +- /* Add proxy authorization from the initial request if necessary */ ++ /* Add proxy authorization from the configuration, or initial ++ * request if necessary */ + if (forward->proxy_auth != NULL) { + nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes, + "Proxy-Authorization: %s" CRLF, +@@ -3909,6 +3913,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, + int force10 = 0, do_100_continue = 0; + conn_rec *origin = p_conn->connection; + const char *host, *val; ++ const char *creds; + proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &proxy_module); + + /* +@@ -4131,6 +4136,11 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, + /* run hook to fixup the request we are about to send */ + proxy_run_fixups(r); + ++ creds = apr_table_get(r->notes, "proxy-basic-creds"); ++ if (creds) { ++ apr_table_mergen(r->headers_in, "Proxy-Authorization", creds); ++ } ++ + /* We used to send `Host: ` always first, so let's keep it that + * way. No telling which legacy backend is relying on this. + * If proxy_run_fixups() changed the value, use it (though removal diff --git a/SOURCES/httpd-2.4.57-r1825120.patch b/SOURCES/httpd-2.4.57-r1825120.patch new file mode 100644 index 0000000..4eb0a59 --- /dev/null +++ b/SOURCES/httpd-2.4.57-r1825120.patch @@ -0,0 +1,99 @@ +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index 4e2e80d..10a2c86 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -2256,51 +2256,6 @@ int ssl_proxy_section_post_config(apr_pool_t *p, apr_pool_t *plog, + return OK; + } + +-static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a, +- const X509_NAME * const *b) +-{ +- return(X509_NAME_cmp(*a, *b)); +-} +- +-static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list, +- server_rec *s, apr_pool_t *ptemp, +- const char *file) +-{ +- int n; +- STACK_OF(X509_NAME) *sk; +- +- sk = (STACK_OF(X509_NAME) *) +- SSL_load_client_CA_file(file); +- +- if (!sk) { +- return; +- } +- +- for (n = 0; n < sk_X509_NAME_num(sk); n++) { +- X509_NAME *name = sk_X509_NAME_value(sk, n); +- +- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02209) +- "CA certificate: %s", +- modssl_X509_NAME_to_string(ptemp, name, 0)); +- +- /* +- * note that SSL_load_client_CA_file() checks for duplicates, +- * but since we call it multiple times when reading a directory +- * we must also check for duplicates ourselves. +- */ +- +- if (sk_X509_NAME_find(ca_list, name) < 0) { +- /* this will be freed when ca_list is */ +- sk_X509_NAME_push(ca_list, name); +- } +- else { +- /* need to free this ourselves, else it will leak */ +- X509_NAME_free(name); +- } +- } +- +- sk_X509_NAME_free(sk); +-} + + static apr_status_t ssl_init_ca_cert_path(server_rec *s, + apr_pool_t *ptemp, +@@ -2324,7 +2279,7 @@ static apr_status_t ssl_init_ca_cert_path(server_rec *s, + } + file = apr_pstrcat(ptemp, path, "/", direntry.name, NULL); + if (ca_list) { +- ssl_init_PushCAList(ca_list, s, ptemp, file); ++ SSL_add_file_cert_subjects_to_stack(ca_list, file); + } + if (xi_list) { + load_x509_info(ptemp, xi_list, file); +@@ -2341,19 +2296,13 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, + const char *ca_file, + const char *ca_path) + { +- STACK_OF(X509_NAME) *ca_list; +- +- /* +- * Start with a empty stack/list where new +- * entries get added in sorted order. +- */ +- ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp); ++ STACK_OF(X509_NAME) *ca_list = sk_X509_NAME_new_null();; + + /* + * Process CA certificate bundle file + */ + if (ca_file) { +- ssl_init_PushCAList(ca_list, s, ptemp, ca_file); ++ SSL_add_file_cert_subjects_to_stack(ca_list, ca_file); + /* + * If ca_list is still empty after trying to load ca_file + * then the file failed to load, and users should hear about that. +@@ -2377,11 +2326,6 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, + return NULL; + } + +- /* +- * Cleanup +- */ +- (void) sk_X509_NAME_set_cmp_func(ca_list, NULL); +- + return ca_list; + } + diff --git a/SOURCES/httpd-2.4.57-r1884505+.patch b/SOURCES/httpd-2.4.57-r1884505+.patch new file mode 100644 index 0000000..97bc6a8 --- /dev/null +++ b/SOURCES/httpd-2.4.57-r1884505+.patch @@ -0,0 +1,39 @@ +# ./pullrev.sh 1884505 1915625 +http://svn.apache.org/viewvc?view=revision&revision=1884505 +http://svn.apache.org/viewvc?view=revision&revision=1915625 + +--- httpd-2.4.57/modules/filters/mod_xml2enc.c ++++ httpd-2.4.57/modules/filters/mod_xml2enc.c +@@ -329,7 +329,7 @@ + apr_bucket* bstart; + apr_size_t insz = 0; + int pending_meta = 0; +- char *ctype; ++ char *mtype; + char *p; + + if (!ctx || !f->r->content_type) { +@@ -338,13 +338,17 @@ + return ap_pass_brigade(f->next, bb) ; + } + +- ctype = apr_pstrdup(f->r->pool, f->r->content_type); +- for (p = ctype; *p; ++p) +- if (isupper(*p)) +- *p = tolower(*p); ++ /* Extract the media type, ignoring parameters in content-type. */ ++ mtype = apr_pstrdup(f->r->pool, f->r->content_type); ++ if ((p = ap_strchr(mtype, ';')) != NULL) *p = '\0'; ++ ap_str_tolower(mtype); + +- /* only act if starts-with "text/" or contains "xml" */ +- if (strncmp(ctype, "text/", 5) && !strstr(ctype, "xml")) { ++ /* Accept text/ types, plus any XML media type per RFC 7303. */ ++ if (!(strncmp(mtype, "text/", 5) == 0 ++ || strcmp(mtype, "application/xml") == 0 ++ || (strlen(mtype) > 7 /* minimum 'a/b+xml' length */ ++ && (p = strstr(mtype, "+xml")) != NULL ++ && strlen(p) == 4 /* ensures +xml is a suffix */))) { + ap_remove_output_filter(f); + return ap_pass_brigade(f->next, bb) ; + } diff --git a/SOURCES/httpd-2.4.57-r1912081.patch b/SOURCES/httpd-2.4.57-r1912081.patch new file mode 100644 index 0000000..111e5ac --- /dev/null +++ b/SOURCES/httpd-2.4.57-r1912081.patch @@ -0,0 +1,91 @@ +# ./pullrev.sh 1912081 +http://svn.apache.org/viewvc?view=revision&revision=1912081 + +Upstream-Status: merged in 2.4.58 + +--- httpd-2.4.57/modules/dav/main/mod_dav.c ++++ httpd-2.4.57/modules/dav/main/mod_dav.c +@@ -81,6 +81,7 @@ + const char *provider_name; + const dav_provider *provider; + const char *dir; ++ const char *base; + int locktimeout; + int allow_depthinfinity; + int allow_lockdiscovery; +@@ -196,6 +197,7 @@ + + newconf->locktimeout = DAV_INHERIT_VALUE(parent, child, locktimeout); + newconf->dir = DAV_INHERIT_VALUE(parent, child, dir); ++ newconf->base = DAV_INHERIT_VALUE(parent, child, base); + newconf->allow_depthinfinity = DAV_INHERIT_VALUE(parent, child, + allow_depthinfinity); + newconf->allow_lockdiscovery = DAV_INHERIT_VALUE(parent, child, +@@ -283,6 +285,18 @@ + } + + /* ++ * Command handler for the DAVBasePath directive, which is TAKE1 ++ */ ++static const char *dav_cmd_davbasepath(cmd_parms *cmd, void *config, const char *arg1) ++{ ++ dav_dir_conf *conf = config; ++ ++ conf->base = arg1; ++ ++ return NULL; ++} ++ ++/* + * Command handler for the DAVDepthInfinity directive, which is FLAG. + */ + static const char *dav_cmd_davdepthinfinity(cmd_parms *cmd, void *config, +@@ -748,7 +762,7 @@ + int use_checked_in, dav_resource **res_p) + { + dav_dir_conf *conf; +- const char *label = NULL; ++ const char *label = NULL, *base; + dav_error *err; + + /* if the request target can be overridden, get any target selector */ +@@ -765,11 +779,27 @@ + ap_escape_html(r->pool, r->uri))); + } + ++ /* Take the repos root from DAVBasePath if configured, else the ++ * path of the enclosing section. */ ++ base = conf->base ? conf->base : conf->dir; ++ + /* resolve the resource */ +- err = (*conf->provider->repos->get_resource)(r, conf->dir, ++ err = (*conf->provider->repos->get_resource)(r, base, + label, use_checked_in, + res_p); + if (err != NULL) { ++ /* In the error path, give a hint that DavBasePath needs to be ++ * used if the location was configured via a regex match. */ ++ if (!conf->base) { ++ core_dir_config *cdc = ap_get_core_module_config(r->per_dir_config); ++ ++ if (cdc->r) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(10484) ++ "failed to find repository for location configured " ++ "via regex match - missing DAVBasePath?"); ++ } ++ } ++ + err = dav_push_error(r->pool, err->status, 0, + "Could not fetch resource information.", err); + return err; +@@ -5164,6 +5194,10 @@ + AP_INIT_TAKE1("DAV", dav_cmd_dav, NULL, ACCESS_CONF, + "specify the DAV provider for a directory or location"), + ++ /* per directory/location */ ++ AP_INIT_TAKE1("DAVBasePath", dav_cmd_davbasepath, NULL, ACCESS_CONF, ++ "specify the DAV repository base URL"), ++ + /* per directory/location, or per server */ + AP_INIT_TAKE1("DAVMinTimeout", dav_cmd_davmintimeout, NULL, + ACCESS_CONF|RSRC_CONF, diff --git a/SOURCES/httpd-2.4.57-r1912477+.patch b/SOURCES/httpd-2.4.57-r1912477+.patch new file mode 100644 index 0000000..6458df8 --- /dev/null +++ b/SOURCES/httpd-2.4.57-r1912477+.patch @@ -0,0 +1,381 @@ +# ./pullrev.sh 1912477 1912571 1912718 1913654 1914438 +http://svn.apache.org/viewvc?view=revision&revision=1912477 +http://svn.apache.org/viewvc?view=revision&revision=1912571 +http://svn.apache.org/viewvc?view=revision&revision=1912718 +http://svn.apache.org/viewvc?view=revision&revision=1913654 +http://svn.apache.org/viewvc?view=revision&revision=1914438 + +--- httpd-2.4.58/modules/dav/fs/config6.m4.r1912477+ ++++ httpd-2.4.58/modules/dav/fs/config6.m4 +@@ -20,4 +20,10 @@ + + APACHE_MODULE(dav_fs, DAV provider for the filesystem. --enable-dav also enables mod_dav_fs., $dav_fs_objects, , $dav_fs_enable,,dav) + ++if test "x$enable_dav_fs" = "xshared"; then ++ # The only symbol which needs to be exported is the module ++ # structure, so ask libtool to hide everything else: ++ APR_ADDTO(MOD_DAV_FS_LDADD, [-export-symbols-regex dav_fs_module]) ++fi ++ + APACHE_MODPATH_FINISH +--- httpd-2.4.58/modules/dav/fs/dbm.c.r1912477+ ++++ httpd-2.4.58/modules/dav/fs/dbm.c +@@ -47,6 +47,10 @@ + #include "http_log.h" + #include "http_main.h" /* for ap_server_conf */ + ++#ifndef DEFAULT_PROPDB_DBM_TYPE ++#define DEFAULT_PROPDB_DBM_TYPE "default" ++#endif ++ + APLOG_USE_MODULE(dav_fs); + + struct dav_db { +@@ -100,7 +104,7 @@ + /* There might not be a if we had problems creating it. */ + if (db == NULL) { + errcode = 1; +- errstr = "Could not open property database."; ++ errstr = "Could not open database."; + if (APR_STATUS_IS_EDSOOPEN(status)) + ap_log_error(APLOG_MARK, APLOG_CRIT, status, ap_server_conf, APLOGNO(00576) + "The DBM driver could not be loaded"); +@@ -129,10 +133,10 @@ + /* dav_dbm_open_direct: Opens a *dbm database specified by path. + * ro = boolean read-only flag. + */ +-dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro, +- dav_db **pdb) ++dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, ++ const char *dbmtype, int ro, dav_db **pdb) + { +-#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7) ++#if APR_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7) + const apr_dbm_driver_t *driver; + const apu_err_t *err; + #endif +@@ -141,13 +145,13 @@ + + *pdb = NULL; + +-#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7) +- if ((status = apr_dbm_get_driver(&driver, NULL, &err, p)) != APR_SUCCESS) { ++#if APR_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7) ++ if ((status = apr_dbm_get_driver(&driver, dbmtype, &err, p)) != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf, APLOGNO(10289) +- "mod_dav_fs: The DBM library '%s' could not be loaded: %s", +- err->reason, err->msg); ++ "mod_dav_fs: The DBM library '%s' for '%s' could not be loaded: %s", ++ err->reason, dbmtype, err->msg); + return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 1, status, +- "Could not load library for property database."); ++ "Could not load library for database."); + } + if ((status = apr_dbm_open2(&file, driver, pathname, + ro ? APR_DBM_READONLY : APR_DBM_RWCREATE, +@@ -156,7 +160,7 @@ + return dav_fs_dbm_error(NULL, p, status); + } + #else +- if ((status = apr_dbm_open(&file, pathname, ++ if ((status = apr_dbm_open_ex(&file, dbmtype, pathname, + ro ? APR_DBM_READONLY : APR_DBM_RWCREATE, + APR_OS_DEFAULT, p)) + != APR_SUCCESS +@@ -206,7 +210,7 @@ + + /* ### do we need to deal with the umask? */ + +- return dav_dbm_open_direct(p, pathname, ro, pdb); ++ return dav_dbm_open_direct(p, pathname, DEFAULT_PROPDB_DBM_TYPE, ro, pdb); + } + + void dav_dbm_close(dav_db *db) +--- httpd-2.4.58/modules/dav/fs/lock.c.r1912477+ ++++ httpd-2.4.58/modules/dav/fs/lock.c +@@ -181,8 +181,7 @@ + { + request_rec *r; /* for accessing the uuid state */ + apr_pool_t *pool; /* a pool to use */ +- const char *lockdb_path; /* where is the lock database? */ +- ++ const dav_fs_server_conf *conf; /* lock database config & metadata */ + int opened; /* we opened the database */ + dav_db *db; /* if non-NULL, the lock database */ + }; +@@ -292,6 +291,19 @@ + return dav_compare_locktoken(lt1, lt2); + } + ++static apr_status_t dav_fs_lockdb_cleanup(void *data) ++{ ++ dav_lockdb *lockdb = data; ++ ++ apr_global_mutex_unlock(lockdb->info->conf->lockdb_mutex); ++ ++ if (lockdb->info->db) { ++ dav_dbm_close(lockdb->info->db); ++ } ++ ++ return APR_SUCCESS; ++} ++ + /* + ** dav_fs_really_open_lockdb: + ** +@@ -300,15 +312,27 @@ + static dav_error * dav_fs_really_open_lockdb(dav_lockdb *lockdb) + { + dav_error *err; ++ apr_status_t rv; + + if (lockdb->info->opened) + return NULL; + ++ rv = apr_global_mutex_lock(lockdb->info->conf->lockdb_mutex); ++ if (rv) { ++ return dav_new_error(lockdb->info->pool, ++ HTTP_INTERNAL_SERVER_ERROR, ++ DAV_ERR_LOCK_OPENDB, rv, ++ "Could not lock mutex for lock database."); ++ } ++ + err = dav_dbm_open_direct(lockdb->info->pool, +- lockdb->info->lockdb_path, ++ lockdb->info->conf->lockdb_path, ++ lockdb->info->conf->lockdb_type, + lockdb->ro, + &lockdb->info->db); + if (err != NULL) { ++ apr_global_mutex_unlock(lockdb->info->conf->lockdb_mutex); ++ + return dav_push_error(lockdb->info->pool, + HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_OPENDB, +@@ -316,6 +340,10 @@ + err); + } + ++ apr_pool_cleanup_register(lockdb->info->pool, lockdb, ++ dav_fs_lockdb_cleanup, ++ dav_fs_lockdb_cleanup); ++ + /* all right. it is opened now. */ + lockdb->info->opened = 1; + +@@ -341,9 +369,9 @@ + comb->pub.info = &comb->priv; + comb->priv.r = r; + comb->priv.pool = r->pool; +- +- comb->priv.lockdb_path = dav_get_lockdb_path(r); +- if (comb->priv.lockdb_path == NULL) { ++ comb->priv.conf = dav_fs_get_server_conf(r); ++ ++ if (comb->priv.conf == NULL || comb->priv.conf->lockdb_path == NULL) { + return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, + DAV_ERR_LOCK_NO_DB, 0, + "A lock database was not specified with the " +@@ -369,8 +397,8 @@ + */ + static void dav_fs_close_lockdb(dav_lockdb *lockdb) + { +- if (lockdb->info->db != NULL) +- dav_dbm_close(lockdb->info->db); ++ apr_pool_cleanup_run(lockdb->info->pool, lockdb, ++ dav_fs_lockdb_cleanup); + } + + /* +--- httpd-2.4.58/modules/dav/fs/mod_dav_fs.c.r1912477+ ++++ httpd-2.4.58/modules/dav/fs/mod_dav_fs.c +@@ -14,31 +14,35 @@ + * limitations under the License. + */ + ++#if !defined(_MSC_VER) && !defined(NETWARE) ++#include "ap_config_auto.h" ++#endif ++ + #include "httpd.h" + #include "http_config.h" ++#include "http_core.h" ++#include "http_log.h" + #include "apr_strings.h" + + #include "mod_dav.h" + #include "repos.h" + +-/* per-server configuration */ +-typedef struct { +- const char *lockdb_path; +- +-} dav_fs_server_conf; +- + extern module AP_MODULE_DECLARE_DATA dav_fs_module; + + #ifndef DEFAULT_DAV_LOCKDB + #define DEFAULT_DAV_LOCKDB "davlockdb" + #endif ++#ifndef DEFAULT_DAV_LOCKDB_TYPE ++#define DEFAULT_DAV_LOCKDB_TYPE "default" ++#endif + +-const char *dav_get_lockdb_path(const request_rec *r) +-{ +- dav_fs_server_conf *conf; ++static const char dav_fs_mutexid[] = "dav_fs-lockdb"; + +- conf = ap_get_module_config(r->server->module_config, &dav_fs_module); +- return conf->lockdb_path; ++static apr_global_mutex_t *dav_fs_lockdb_mutex; ++ ++const dav_fs_server_conf *dav_fs_get_server_conf(const request_rec *r) ++{ ++ return ap_get_module_config(r->server->module_config, &dav_fs_module); + } + + static void *dav_fs_create_server_config(apr_pool_t *p, server_rec *s) +@@ -57,15 +61,50 @@ + + newconf->lockdb_path = + child->lockdb_path ? child->lockdb_path : parent->lockdb_path; ++ newconf->lockdb_type = ++ child->lockdb_type ? child->lockdb_type : parent->lockdb_type; + + return newconf; + } + ++static int dav_fs_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) ++{ ++ if (ap_mutex_register(pconf, dav_fs_mutexid, NULL, APR_LOCK_DEFAULT, 0)) ++ return !OK; ++ return OK; ++} ++ ++static void dav_fs_child_init(apr_pool_t *p, server_rec *s) ++{ ++ apr_status_t rv; ++ ++ rv = apr_global_mutex_child_init(&dav_fs_lockdb_mutex, ++ apr_global_mutex_lockfile(dav_fs_lockdb_mutex), ++ p); ++ if (rv) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, ++ APLOGNO(10488) "child init failed for mutex"); ++ } ++} ++ + static apr_status_t dav_fs_post_config(apr_pool_t *p, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *base_server) + { + server_rec *s; ++ apr_status_t rv; + ++ /* Ignore first pass through the config. */ ++ if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) ++ return OK; ++ ++ rv = ap_global_mutex_create(&dav_fs_lockdb_mutex, NULL, dav_fs_mutexid, NULL, ++ base_server, p, 0); ++ if (rv) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, rv, base_server, ++ APLOGNO(10489) "could not create lock mutex"); ++ return !OK; ++ } ++ + for (s = base_server; s; s = s->next) { + dav_fs_server_conf *conf; + +@@ -74,6 +113,13 @@ + if (!conf->lockdb_path) { + conf->lockdb_path = ap_state_dir_relative(p, DEFAULT_DAV_LOCKDB); + } ++ if (!conf->lockdb_type) { ++ conf->lockdb_type = DEFAULT_DAV_LOCKDB_TYPE; ++ } ++ ++ /* Mutex is common across all vhosts, but could have one per ++ * vhost if required. */ ++ conf->lockdb_mutex = dav_fs_lockdb_mutex; + } + + return OK; +@@ -98,19 +144,36 @@ + return NULL; + } + ++/* ++ * Command handler for the DAVLockDBType directive, which is TAKE1 ++ */ ++static const char *dav_fs_cmd_davlockdbtype(cmd_parms *cmd, void *config, ++ const char *arg1) ++{ ++ dav_fs_server_conf *conf = ap_get_module_config(cmd->server->module_config, ++ &dav_fs_module); ++ conf->lockdb_type = arg1; ++ ++ return NULL; ++} ++ + static const command_rec dav_fs_cmds[] = + { + /* per server */ + AP_INIT_TAKE1("DAVLockDB", dav_fs_cmd_davlockdb, NULL, RSRC_CONF, + "specify a lock database"), ++ AP_INIT_TAKE1("DAVLockDBType", dav_fs_cmd_davlockdbtype, NULL, RSRC_CONF, ++ "specify a lock database DBM type"), + + { NULL } + }; + + static void register_hooks(apr_pool_t *p) + { ++ ap_hook_pre_config(dav_fs_pre_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(dav_fs_post_config, NULL, NULL, APR_HOOK_MIDDLE); +- ++ ap_hook_child_init(dav_fs_child_init, NULL, NULL, APR_HOOK_MIDDLE); ++ + dav_hook_gather_propsets(dav_fs_gather_propsets, NULL, NULL, + APR_HOOK_MIDDLE); + dav_hook_find_liveprop(dav_fs_find_liveprop, NULL, NULL, APR_HOOK_MIDDLE); +--- httpd-2.4.58/modules/dav/fs/repos.h.r1912477+ ++++ httpd-2.4.58/modules/dav/fs/repos.h +@@ -25,6 +25,8 @@ + #ifndef _DAV_FS_REPOS_H_ + #define _DAV_FS_REPOS_H_ + ++#include "util_mutex.h" ++ + /* the subdirectory to hold all DAV-related information for a directory */ + #define DAV_FS_STATE_DIR ".DAV" + #define DAV_FS_STATE_FILE_FOR_DIR ".state_for_dir" +@@ -53,8 +55,8 @@ + /* DBM functions used by the repository and locking providers */ + extern const dav_hooks_db dav_hooks_db_dbm; + +-dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro, +- dav_db **pdb); ++dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, ++ const char *dbmtype, int ro, dav_db **pdb); + void dav_dbm_get_statefiles(apr_pool_t *p, const char *fname, + const char **state1, const char **state2); + dav_error * dav_dbm_delete(dav_db *db, apr_datum_t key); +@@ -64,8 +66,15 @@ + int dav_dbm_exists(dav_db *db, apr_datum_t key); + void dav_dbm_close(dav_db *db); + +-/* where is the lock database located? */ +-const char *dav_get_lockdb_path(const request_rec *r); ++/* Per-server configuration. */ ++typedef struct { ++ const char *lockdb_path; ++ const char *lockdb_type; ++ apr_global_mutex_t *lockdb_mutex; ++} dav_fs_server_conf; ++ ++/* Returns server configuration for the request. */ ++const dav_fs_server_conf *dav_fs_get_server_conf(const request_rec *r); + + const dav_hooks_locks *dav_fs_get_lock_hooks(request_rec *r); + const dav_hooks_propdb *dav_fs_get_propdb_hooks(request_rec *r); diff --git a/SOURCES/httpd-2.4.57-selinux.patch b/SOURCES/httpd-2.4.57-selinux.patch new file mode 100644 index 0000000..b28bcee --- /dev/null +++ b/SOURCES/httpd-2.4.57-selinux.patch @@ -0,0 +1,60 @@ +diff --git a/configure.in b/configure.in +index 1e342bb..a3c994b 100644 +--- a/configure.in ++++ b/configure.in +@@ -530,6 +530,11 @@ getloadavg + 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 +diff --git a/server/core.c b/server/core.c +index ca33d94..41e9bdc 100644 +--- a/server/core.c ++++ b/server/core.c +@@ -65,6 +65,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) 1<<30) /* 1GB */ +@@ -5157,6 +5161,28 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte + } + #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/SOURCES/httpd-init.service b/SOURCES/httpd-init.service new file mode 100644 index 0000000..704c314 --- /dev/null +++ b/SOURCES/httpd-init.service @@ -0,0 +1,13 @@ +[Unit] +Description=One-time temporary TLS key generation for httpd.service +Documentation=man:httpd-init.service(8) + +ConditionPathExists=|!/etc/pki/tls/certs/localhost.crt +ConditionPathExists=|!/etc/pki/tls/private/localhost.key + +[Service] +Type=oneshot +RemainAfterExit=no +PrivateTmp=true + +ExecStart=/usr/libexec/httpd-ssl-gencerts diff --git a/SOURCES/httpd-ssl-gencerts b/SOURCES/httpd-ssl-gencerts new file mode 100755 index 0000000..5c271f7 --- /dev/null +++ b/SOURCES/httpd-ssl-gencerts @@ -0,0 +1,40 @@ +#!/usr/bin/bash + +set -e + +FQDN=`hostname` +ssldotconf=/etc/httpd/conf.d/ssl.conf + +if test -f /etc/pki/tls/certs/localhost.crt -a \ + -f /etc/pki/tls/private/localhost.key; then + exit 0 +fi + +if test -f /etc/pki/tls/certs/localhost.crt -a \ + ! -f /etc/pki/tls/private/localhost.key; then + echo "Missing certificate key!" + exit 1 +fi + +if test ! -f /etc/pki/tls/certs/localhost.crt -a \ + -f /etc/pki/tls/private/localhost.key; then + echo "Missing certificate, but key is present!" + exit 1 +fi + +if ! test -f ${ssldotconf} || \ + ! grep -q '^SSLCertificateFile /etc/pki/tls/certs/localhost.crt' ${ssldotconf} || \ + ! grep -q '^SSLCertificateKeyFile /etc/pki/tls/private/localhost.key' ${ssldotconf}; then + # Non-default configuration, do nothing. + exit 0 +fi + +sscg -q \ + --cert-file /etc/pki/tls/certs/localhost.crt \ + --cert-key-file /etc/pki/tls/private/localhost.key \ + --ca-file /etc/pki/tls/certs/localhost.crt \ + --dhparams-file /tmp/dhparams.pem \ + --lifetime 365 \ + --hostname $FQDN \ + --email root@$FQDN + diff --git a/SOURCES/httpd-ssl-pass-dialog b/SOURCES/httpd-ssl-pass-dialog new file mode 100755 index 0000000..79318a6 --- /dev/null +++ b/SOURCES/httpd-ssl-pass-dialog @@ -0,0 +1,3 @@ +#!/bin/sh + +exec /bin/systemd-ask-password "Enter TLS private key passphrase for $1 ($2) : " diff --git a/SOURCES/httpd.conf b/SOURCES/httpd.conf new file mode 100644 index 0000000..609b2e2 --- /dev/null +++ b/SOURCES/httpd.conf @@ -0,0 +1,358 @@ +# +# This is the main Apache HTTP server configuration file. It contains the +# configuration directives that give the server its instructions. +# See for detailed information. +# In particular, see +# +# for a discussion of each configuration directive. +# +# See the httpd.conf(5) man page for more information on this configuration, +# and httpd.service(8) on using and configuring the httpd service. +# +# Do NOT simply read the instructions in here without understanding +# what they do. They're here only as hints or reminders. If you are unsure +# consult the online docs. You have been warned. +# +# Configuration and logfile names: If the filenames you specify for many +# of the server's control files begin with "/" (or "drive:/" for Win32), the +# server will use that explicit path. If the filenames do *not* begin +# with "/", the value of ServerRoot is prepended -- so 'log/access_log' +# with ServerRoot set to '/www' will be interpreted by the +# server as '/www/log/access_log', where as '/log/access_log' will be +# interpreted as '/log/access_log'. + +# +# ServerRoot: The top of the directory tree under which the server's +# configuration, error, and log files are kept. +# +# Do not add a slash at the end of the directory path. If you point +# ServerRoot at a non-local disk, be sure to specify a local disk on the +# Mutex directive, if file-based mutexes are used. If you wish to share the +# same ServerRoot for multiple httpd daemons, you will need to change at +# least PidFile. +# +ServerRoot "/etc/httpd" + +# +# Listen: Allows you to bind Apache to specific IP addresses and/or +# ports, instead of the default. See also the +# directive. +# +# Change this to Listen on a specific IP address, but note that if +# httpd.service is enabled to run at boot time, the address may not be +# available when the service starts. See the httpd.service(8) man +# page for more information. +# +#Listen 12.34.56.78:80 +Listen 80 + +# +# Dynamic Shared Object (DSO) Support +# +# To be able to use the functionality of a module which was built as a DSO you +# have to place corresponding `LoadModule' lines at this location so the +# directives contained in it are actually available _before_ they are used. +# Statically compiled modules (those listed by `httpd -l') do not need +# to be loaded here. +# +# Example: +# LoadModule foo_module modules/mod_foo.so +# +Include conf.modules.d/*.conf + +# +# If you wish httpd to run as a different user or group, you must run +# httpd as root initially and it will switch. +# +# User/Group: The name (or #number) of the user/group to run httpd as. +# It is usually good practice to create a dedicated user and group for +# running httpd, as with most system services. +# +User apache +Group apache + +# 'Main' server configuration +# +# The directives in this section set up the values used by the 'main' +# server, which responds to any requests that aren't handled by a +# definition. These values also provide defaults for +# any containers you may define later in the file. +# +# All of these directives may appear inside containers, +# in which case these default settings will be overridden for the +# virtual host being defined. +# + +# +# ServerAdmin: Your address, where problems with the server should be +# e-mailed. This address appears on some server-generated pages, such +# as error documents. e.g. admin@your-domain.com +# +ServerAdmin root@localhost + +# +# ServerName gives the name and port that the server uses to identify itself. +# This can often be determined automatically, but we recommend you specify +# it explicitly to prevent problems during startup. +# +# If your host doesn't have a registered DNS name, enter its IP address here. +# +#ServerName www.example.com:80 + +# +# Deny access to the entirety of your server's filesystem. You must +# explicitly permit access to web content directories in other +# blocks below. +# + + AllowOverride none + Require all denied + + +# +# Note that from this point forward you must specifically allow +# particular features to be enabled - so if something's not working as +# you might expect, make sure that you have specifically enabled it +# below. +# + +# +# DocumentRoot: The directory out of which you will serve your +# documents. By default, all requests are taken from this directory, but +# symbolic links and aliases may be used to point to other locations. +# +DocumentRoot "/var/www/html" + +# +# Relax access to content within /var/www. +# + + AllowOverride None + # Allow open access: + Require all granted + + +# Further relax access to the default document root: + + # + # Possible values for the Options directive are "None", "All", + # or any combination of: + # Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews + # + # Note that "MultiViews" must be named *explicitly* --- "Options All" + # doesn't give it to you. + # + # The Options directive is both complicated and important. Please see + # http://httpd.apache.org/docs/2.4/mod/core.html#options + # for more information. + # + Options Indexes FollowSymLinks + + # + # AllowOverride controls what directives may be placed in .htaccess files. + # It can be "All", "None", or any combination of the keywords: + # Options FileInfo AuthConfig Limit + # + AllowOverride None + + # + # Controls who can get stuff from this server. + # + Require all granted + + +# +# DirectoryIndex: sets the file that Apache will serve if a directory +# is requested. +# + + DirectoryIndex index.html + + +# +# The following lines prevent .htaccess and .htpasswd files from being +# viewed by Web clients. +# + + Require all denied + + +# +# ErrorLog: The location of the error log file. +# If you do not specify an ErrorLog directive within a +# container, error messages relating to that virtual host will be +# logged here. If you *do* define an error logfile for a +# container, that host's errors will be logged there and not here. +# +ErrorLog "logs/error_log" + +# +# LogLevel: Control the number of messages logged to the error_log. +# Possible values include: debug, info, notice, warn, error, crit, +# alert, emerg. +# +LogLevel warn + + + # + # The following directives define some format nicknames for use with + # a CustomLog directive (see below). + # + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b" common + + + # You need to enable mod_logio.c to use %I and %O + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio + + + # + # The location and format of the access logfile (Common Logfile Format). + # If you do not define any access logfiles within a + # container, they will be logged here. Contrariwise, if you *do* + # define per- access logfiles, transactions will be + # logged therein and *not* in this file. + # + #CustomLog "logs/access_log" common + + # + # If you prefer a logfile with access, agent, and referer information + # (Combined Logfile Format) you can use the following directive. + # + CustomLog "logs/access_log" combined + + + + # + # Redirect: Allows you to tell clients about documents that used to + # exist in your server's namespace, but do not anymore. The client + # will make a new request for the document at its new location. + # Example: + # Redirect permanent /foo http://www.example.com/bar + + # + # Alias: Maps web paths into filesystem paths and is used to + # access content that does not live under the DocumentRoot. + # Example: + # Alias /webpath /full/filesystem/path + # + # If you include a trailing / on /webpath then the server will + # require it to be present in the URL. You will also likely + # need to provide a section to allow access to + # the filesystem path. + + # + # ScriptAlias: This controls which directories contain server scripts. + # ScriptAliases are essentially the same as Aliases, except that + # documents in the target directory are treated as applications and + # run by the server when requested rather than as documents sent to the + # client. The same rules about trailing "/" apply to ScriptAlias + # directives as to Alias. + # + ScriptAlias /cgi-bin/ "/var/www/cgi-bin/" + + + +# +# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased +# CGI directory exists, if you have that configured. +# + + AllowOverride None + Options None + Require all granted + + + + # + # TypesConfig points to the file containing the list of mappings from + # filename extension to MIME-type. + # + TypesConfig /etc/mime.types + + # + # AddType allows you to add to or override the MIME configuration + # file specified in TypesConfig for specific file types. + # + #AddType application/x-gzip .tgz + # + # AddEncoding allows you to have certain browsers uncompress + # information on the fly. Note: Not all browsers support this. + # + #AddEncoding x-compress .Z + #AddEncoding x-gzip .gz .tgz + # + # If the AddEncoding directives above are commented-out, then you + # probably should define those extensions to indicate media types: + # + AddType application/x-compress .Z + AddType application/x-gzip .gz .tgz + + # + # AddHandler allows you to map certain file extensions to "handlers": + # actions unrelated to filetype. These can be either built into the server + # or added with the Action directive (see below) + # + # To use CGI scripts outside of ScriptAliased directories: + # (You will also need to add "ExecCGI" to the "Options" directive.) + # + #AddHandler cgi-script .cgi + + # For type maps (negotiated resources): + #AddHandler type-map var + + # + # Filters allow you to process content before it is sent to the client. + # + # To parse .shtml files for server-side includes (SSI): + # (You will also need to add "Includes" to the "Options" directive.) + # + AddType text/html .shtml + AddOutputFilter INCLUDES .shtml + + +# +# Specify a default charset for all content served; this enables +# interpretation of all content as UTF-8 by default. To use the +# default browser choice (ISO-8859-1), or to allow the META tags +# in HTML content to override this choice, comment out this +# directive: +# +AddDefaultCharset UTF-8 + + + # + # The mod_mime_magic module allows the server to use various hints from the + # contents of the file itself to determine its type. The MIMEMagicFile + # directive tells the module where the hint definitions are located. + # + MIMEMagicFile conf/magic + + +# +# Customizable error responses come in three flavors: +# 1) plain text 2) local redirects 3) external redirects +# +# Some examples: +#ErrorDocument 500 "The server made a boo boo." +#ErrorDocument 404 /missing.html +#ErrorDocument 404 "/cgi-bin/missing_handler.pl" +#ErrorDocument 402 http://www.example.com/subscription_info.html +# + +# +# EnableMMAP and EnableSendfile: On systems that support it, +# memory-mapping or the sendfile syscall may be used to deliver +# files. This usually improves server performance, but must +# be turned off when serving from networked-mounted +# filesystems or if support for these functions is otherwise +# broken on your system. +# Defaults if commented: EnableMMAP On, EnableSendfile Off +# +#EnableMMAP off +EnableSendfile on + +# Supplemental configuration +# +# Load config files in the "/etc/httpd/conf.d" directory, if any. +IncludeOptional conf.d/*.conf diff --git a/SOURCES/httpd.conf.xml b/SOURCES/httpd.conf.xml new file mode 100644 index 0000000..13e5d69 --- /dev/null +++ b/SOURCES/httpd.conf.xml @@ -0,0 +1,259 @@ + + + + + + + httpd.conf + httpd + AuthorOrtonJoejorton@redhat.com + + + + httpd.conf + 5 + + + + httpd.conf + Configuration files for httpd + + + + + /etc/httpd/conf/httpd.conf, + /etc/httpd/conf.modules.d, + /etc/httpd/conf.d + + + + + Description + + The main configuration file for the httpd daemon is + /etc/httpd/conf/httpd.conf. The syntax of + this file is described at , and + the full set of available directives is listed at . + + + + Configuration structure + + The main configuration file + (httpd.conf) sets up various defaults and + includes configuration files from two directories - + /etc/httpd/conf.modules.d and + /etc/httpd/conf.d. Packages containing + loadable modules (like ) place files + in the conf.modules.d directory with the + appropriate directive so that module + is loaded by default. + + Some notable configured defaults are: + + + + + The default document root from which content + is served. + + + + The daemon listens on TCP port 80. + + + + Error messages are logged to + @LOGDIR@/error_log. + + + + CGI scripts are served via the URL-path . + + + + + To remove any of the default configuration provided in + separate files covered below, replace that file with an empty + file rather than removing it from the filesystem, otherwise it + may be restored to the original when the package which provides + it is upgraded. + + + + + MPM configuration + + The configuration file at + /etc/httpd/conf.modules.d/00-mpm.conf is + used to select the multi-processing module (MPM), which governs + how httpd divides work between processes + and/or threads at run-time. Exactly one + directive must be uncommented in + this file; by default the MPM is enabled. + For more information on MPMs, see . + + If using the prefork MPM, the + "httpd_graceful_shutdown" SELinux boolean should also be + enabled, since with this MPM, httpd needs to establish TCP + connections to local ports to successfully complete a graceful + restart or shutdown. This boolean can be enabled by running the + command: semanage boolean -m --on + httpd_graceful_shutdown + + + + Module configuration files + + Module configuration files are provided in the + /etc/httpd/conf.modules.d/ directory. + Filenames in this directory are by convention prefixed with two + digit numeric prefix to ensure they are processed in the desired + order. Core modules provided with the httpd + package are loaded by files with a prefix + to ensure these load first. Only filenames with a + suffix in this directory will be + processed. + + Other provided configuration files are listed below. + + + + /etc/httpd/conf.modules.d/00-base.conf + The set of core modules included with + httpd which are all loaded by + default. + + + + /etc/httpd/conf.modules.d/00-optional.conf + The set of non-core modules included with + httpd which are not + loaded by default. + + + + + /etc/httpd/conf.modules.d/00-systemd.conf + This file loads + which is necessary for the correct operation of the + httpd.service systemd unit, and should + not be removed or disabled. + + + + + + + Other configuration files + + Default module configuration files and site-specific + configuration files are loaded from the + /etc/httpd/conf.d/ directory. Only files + with a suffix will be loaded. The + following files are provided: + + + + /etc/httpd/conf.d/userdir.conf + This file gives an example configuration for + to map URLs such as + to + /home/jim/public_html/. Userdir mapping + is disabled by default. + + + + /etc/httpd/conf.d/autoindex.conf + This file provides the default configuration + for which generates HTML + directory listings when enabled. It also makes file icon + image files available at the + URL-path. + + + + /etc/httpd/conf.d/welcome.conf + This file enables a "welcome page" at + if no content is present + in the default documentation root + /var/www/html. + + + + /etc/httpd/conf.d/ssl.conf (present only if is installed) + This file configures a TLS + listening on port + . If the default configuration is used, + the referenced test certificate and private key are + generated the first time httpd.service is + started; see + httpd-init.service8 + for more information. + + + + + + + Instantiated services + + As an alternative to (or in addition to) the + httpd.service unit, the instantiated template + service httpd@.service unit file can be used, + which starts httpd using a different + configuration file to the default. For example, + systemctl start httpd@foobar.service will + start httpd using the configuration file + /etc/httpd/conf/foobar.conf. See httpd@.service8 for more information. + + + + + Files + + + /etc/httpd/conf/httpd.conf, + /etc/httpd/conf.d, + /etc/httpd/conf.modules.d + + + + + See also + + + httpd8, + httpd.service8, + , + + + + + + + diff --git a/SOURCES/httpd.logrotate b/SOURCES/httpd.logrotate new file mode 100644 index 0000000..c5a008c --- /dev/null +++ b/SOURCES/httpd.logrotate @@ -0,0 +1,11 @@ +# Note that logs are not compressed unless "compress" is configured, +# which can be done either here or globally in /etc/logrotate.conf. +/var/log/httpd/*log { + missingok + notifempty + sharedscripts + delaycompress + postrotate + /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true + endscript +} diff --git a/SOURCES/httpd.service b/SOURCES/httpd.service new file mode 100644 index 0000000..c5b5e08 --- /dev/null +++ b/SOURCES/httpd.service @@ -0,0 +1,33 @@ +# See httpd.service(8) for more information on using the httpd service. + +# Modifying this file in-place is not recommended, because changes +# will be overwritten during package upgrades. To customize the +# behaviour, run "systemctl edit httpd" to create an override unit. + +# For example, to pass additional options (such as -D definitions) to +# the httpd binary at startup, create an override unit (as is done by +# systemctl edit) and enter the following: + +# [Service] +# Environment=OPTIONS=-DMY_DEFINE + +[Unit] +Description=The Apache HTTP Server +Wants=httpd-init.service +After=network.target remote-fs.target nss-lookup.target httpd-init.service +Documentation=man:httpd.service(8) + +[Service] +Type=notify +Environment=LANG=C + +ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND +ExecReload=/usr/sbin/httpd $OPTIONS -k graceful +# Send SIGWINCH for graceful stop +KillSignal=SIGWINCH +KillMode=mixed +PrivateTmp=true +OOMPolicy=continue + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/httpd.service.xml b/SOURCES/httpd.service.xml new file mode 100644 index 0000000..c6bf865 --- /dev/null +++ b/SOURCES/httpd.service.xml @@ -0,0 +1,374 @@ + + + + + + + httpd systemd units + httpd + AuthorOrtonJoejorton@redhat.com + + + + httpd.service + 8 + + + + httpd.service + httpd@.service + httpd.socket + httpd-init.service + httpd unit files for systemd + + + + + /usr/lib/systemd/system/httpd.service, + /usr/lib/systemd/system/httpd@.service, + /usr/lib/systemd/system/httpd-init.service, + /usr/lib/systemd/system/httpd.socket + + + + + Description + + This manual page describes the systemd + unit files used to integrate the httpd daemon + with systemd. Two main unit files are + available: httpd.service allows the + httpd daemon to be run as a system service, and + httpd.socket allows httpd to be started via + socket-based activation. Most systems will use + httpd.service. + + The apachectl command has been modified + to invoke systemctl for most uses, so for + example, running apachectl start is equivalent + to running systemctl start httpd.service. This + ensures that the running httpd daemon is tracked and managed by + systemd. In contrast, running + httpd directly from a root shell will start the + service outside of systemd; in this case, + default security restrictions described below (including, but not + limited to, SELinux) will not be enforced. + + + Changing default behaviour + + To change the default behaviour of the httpd service, an + over-ride file should be created, rather + than changing + /usr/lib/systemd/system/httpd.service + directly, since such changes would be lost over package + upgrades. Running systemctl edit + httpd.service or systemctl edit + httpd.socket as root will create a drop-in file (in + the former case, in + /etc/systemd/system/httpd.service.d) which + over-rides the system defaults. + + For example, to set the + environment variable for the daemon, run systemctl edit + httpd.service and enter: + + [Service] +Environment=LD_LIBRARY_PATH=/opt/vendor/lib + + + + Starting the service at boot time + + The httpd.service and httpd.socket units are + disabled by default. To start the httpd + service at boot time, run: systemctl enable + httpd.service. In the default configuration, the + httpd daemon will accept connections on port 80 (and, if mod_ssl + is installed, TLS connections on port 443) for any configured + IPv4 or IPv6 address. + + If httpd is configured to depend on any specific IP + address (for example, with a "Listen" directive) which may only + become available during start-up, or if httpd depends on other + services (such as a database daemon), the service + must be configured to ensure correct + start-up ordering. + + For example, to ensure httpd is only running after all + configured network interfaces are configured, create a drop-in + file (as described above) with the following section: + + [Unit] +After=network-online.target +Wants=network-online.target + + See + for more information on start-up ordering with systemd. + + + + + SSL/TLS certificate generation + + The httpd-init.service unit is provided + with the mod_ssl package. This oneshot unit automatically + creates a TLS server certificate and key (using a generated + self-signed CA certificate and key) for testing purposes before + httpd is started. To inhibit certificate generation, use + systemctl mask httpd-init.service after + installing mod_ssl, and adjust the mod_ssl configuration to use + an appropriate certificate and key. + + + + + Reloading and stopping the service + + When running systemctl reload + httpd.service, a graceful + restart is used, which sends a signal to the httpd parent + process to reload the configuration and re-open log files. Any + children with open connections at the time of reload will + terminate only once they have completed serving requests. This + prevents users of the server seeing errors (or potentially + losing data) due to the reload, but means some there is some + delay before any configuration changes take effect for all + users. + + Similarly, a graceful stop is used + when systemctl stop httpd.service is run, + which terminates the server only once active connections have + been processed. + + To "ungracefully" stop the server without waiting for + requests to complete, use systemctl kill + --kill-who=main httpd; similarly to "ungracefully" + reload the configuration, use systemctl kill + --kill-who=main --signal=HUP httpd. + + + + Automated service restarts + + System packages (including the httpd package itself) may + restart the httpd service automatically after packages are + upgraded, installed, or removed. This is done using the + systemctl try-restart httpd.service, which + stops then starts the service if it is running. + + To disable automatic restarts, create the file + /etc/sysconfig/httpd-disable-posttrans. + When httpd interfaces are added in an update, + it may not be safe to reload a running + service after upgrading, if updated modules require interfaces + only available in the updated httpd. It is recommended to allow + automatic restarts for this reason. + + + + Changing the default MPM (Multi-Processing Module) + + httpd offers a choice of multi-processing modules (MPMs), + which can be configured in + /etc/httpd/conf.modules.d/00-mpm.conf. + See + httpd.conf5 + for more information on changing the MPM. + + + + systemd integration and mod_systemd + + The httpd service uses the systemd + service type. The mod_systemd module must be + loaded (as in the default configuration) for this to work + correctly - the service will fail if this module is not + loaded. mod_systemd also makes worker and + request statistics available when running systemctl status + httpd. See + systemd.exec5 + for more information on systemd service types. + + + + Security and SELinux + + The default SELinux policy restricts the httpd service in + various ways. For example, the default policy limits the ports + to which httpd can bind (using the Listen + directive), which parts of the filesystem can be accessed, and + whether outgoing TCP connections are possible. Many of these + restrictions can be relaxed or adjusted by using + semanage to change booleans or other + types. See + httpd_selinux8 + for more information. + + + + Process policies and restrictions + + The httpd service uses the following options: + + + PrivateTmp is enabled by + default. The /tmp and + /var/tmp directories available within the + httpd process (and CGI scripts, etc) are not shared by other + processes. + + OOMPolicy is set to + continue by default. Under the default + Out-of-Memory policy, the entire service will be terminated if + any process is killed by the kernel OOM killer. By setting + the policy to continue, httpd will + continue to run (and recover) if a single child is terminated + because of excess memory consumption. + + + See + systemd.exec5 + and + systemd.service5 + for more information. + + + + Logging and log file rotation + + The httpd daemon is configured to log + to the /var/log/httpd directory by default, + and a drop-in for logrotate is provided at + /etc/logrotate.d/httpd to enable log file + rotation. The httpd.service systemd unit is + reloaded after a logrotate run. + + Log file compression is not enabled by default; since + httpd can continue writing to open log files + for some time after a reload (graceful restart), if compression + is enabled the delaycompress option must be + present (as in the default) to delay compression of log files to + a later rotation run. + + + + Socket activation + + Socket activation (see + systemd.socket5 + for more information) can be used with httpd + by enabling the httpd.socket unit. The + httpd listener configuration must exactly + match the ListenStream options configured for + the httpd.socket unit. The default + httpd.socket has a + ListenStream=80 and, if mod_ssl is installed, + ListenStream=443 by a drop-in file. If + additional Listen directives are added to the + httpd configuration, corresponding + ListenStream options should be added via + drop-in files, for example via systemctl edit + httpd.socket. + + If using socket activation with httpd, only one listener + on any given TCP port is supported; a configuration with both + "Listen 127.0.0.1:80" and "Listen + 192.168.1.2:80" will not work. + + + + Instantiated services + + The httpd@.service unit is a template + for creating instantiated services. An instance of this unit + will be started using the configuration file + /etc/httpd/conf/INSTANCE.conf, where + INSTANCE is replaced with the instance + name. For example, systemctl start + httpd@foobar.service will start httpd using the + configuration file + /etc/httpd/conf/foobar.conf. The + environment variable is set to + the instance name by the unit and is available for use within + the configuration file. + + To allow multiple instances of httpd to run + simultaneously, a number of configuration directives must be + changed, such as PidFile and + DefaultRuntimeDir to pick non-conflicting + paths, and Listen to choose different ports. + The example configuration file + /usr/share/doc/httpd/instance.conf + demonstrates how to make such changes using the + variable. + + It can be useful to configure instances of + httpd@.service to reload when + httpd.service is reloaded; for example, + logrotate will reload only + httpd.service when logs are rotated. If this + behaviour is required, create a drop-in file for the instance as + follows: + + [Unit] +ReloadPropagatedFrom=httpd.service + + As with normal units, drop-in files for instances can be created + using systemctl edit, e.g. systemctl edit + httpd@foobar.service. + + + + + + Files + + /usr/lib/systemd/system/httpd.service, + /usr/lib/systemd/system/httpd.socket, + /usr/lib/systemd/system/httpd@.service, + /etc/systemd/systemd/httpd.service.d + + + + See also + + + httpd8, + httpd.conf5, + systemd1, + systemctl1, + systemd.service5, + systemd.exec5, + systemd.socket5, + httpd_selinux8, + semanage8, + logrotate8 + + + + + + diff --git a/SOURCES/httpd.socket b/SOURCES/httpd.socket new file mode 100644 index 0000000..074695e --- /dev/null +++ b/SOURCES/httpd.socket @@ -0,0 +1,13 @@ +# See httpd.socket(8) for more information on using the httpd service. + +[Unit] +Description=Apache httpd Server Socket +Documentation=man:httpd.socket(8) + +[Socket] +ListenStream=80 +NoDelay=true +DeferAcceptSec=30 + +[Install] +WantedBy=sockets.target diff --git a/SOURCES/httpd.tmpfiles b/SOURCES/httpd.tmpfiles new file mode 100644 index 0000000..f148886 --- /dev/null +++ b/SOURCES/httpd.tmpfiles @@ -0,0 +1,2 @@ +d /run/httpd 710 root apache +d /run/httpd/htcacheclean 700 apache apache diff --git a/SOURCES/httpd@.service b/SOURCES/httpd@.service new file mode 100644 index 0000000..84424fb --- /dev/null +++ b/SOURCES/httpd@.service @@ -0,0 +1,26 @@ +# This is a template for httpd instances. +# See httpd@.service(8) for more information. + +[Unit] +Description=The Apache HTTP Server +After=network.target remote-fs.target nss-lookup.target +Documentation=man:httpd@.service(8) + +[Service] +Type=notify +Environment=LANG=C +Environment=HTTPD_INSTANCE=%i +ExecStartPre=/bin/mkdir -m 710 -p /run/httpd/instance-%i +ExecStartPre=/bin/chown root.apache /run/httpd/instance-%i +ExecStartPre=/bin/mkdir -m 700 -p /var/lib/httpd/instance-%i +ExecStartPre=/bin/chown apache.apache /var/lib/httpd/instance-%i +ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND -f conf/%i.conf +ExecReload=/usr/sbin/httpd $OPTIONS -k graceful -f conf/%i.conf +# Send SIGWINCH for graceful stop +KillSignal=SIGWINCH +KillMode=mixed +PrivateTmp=true +OOMPolicy=continue + +[Install] +WantedBy=multi-user.target diff --git a/SOURCES/instance.conf b/SOURCES/instance.conf new file mode 100644 index 0000000..074fb66 --- /dev/null +++ b/SOURCES/instance.conf @@ -0,0 +1,24 @@ +# +# This is an example instance-specific configuration file. See the +# httpd@.service(8) man page for detailed information on using the +# the httpd@.service with instances. +# +# To use this example, copy instance.conf to /etc/httpd/conf/foobar.conf +# This config will then used as the default configuration when +# running: +# +# # systemctl start httpd@foobar.service +# +# The changes compared to the default are: +# - DefaultRuntime, DefaultStateDir and Pidfile renamed to instance-specific +# - default logfile names are prefixed with the instance name +# - /etc/httpd/conf.d is NOT included by default (conf.modules.d still is) +# +# Further customisations will be required for an instance to run +# simultaneously to httpd.service under the default configuration, +# e.g. changing the port used with Listen. +# + +DefaultRuntimeDir /run/httpd/instance-${HTTPD_INSTANCE} +DefaultStateDir /var/lib/httpd/instance-${HTTPD_INSTANCE} +PidFile /run/httpd/instance-${HTTPD_INSTANCE}.pid diff --git a/SOURCES/lighttpd-1.4.65-defaultconf.patch b/SOURCES/lighttpd-1.4.65-defaultconf.patch new file mode 100644 index 0000000..013dcd8 --- /dev/null +++ b/SOURCES/lighttpd-1.4.65-defaultconf.patch @@ -0,0 +1,33 @@ +--- doc/config/lighttpd.conf~ 2021-12-02 09:34:06.450352761 -0600 ++++ doc/config/lighttpd.conf 2021-12-02 09:36:04.345770602 -0600 +@@ -14,8 +14,8 @@ + ## chroot example as well. + ## + var.log_root = "/var/log/lighttpd" +-var.server_root = "/srv/www" +-var.state_dir = "/run" ++var.server_root = "/var/www" ++var.state_dir = "/run/lighttpd" + var.home_dir = "/var/lib/lighttpd" + var.conf_dir = "/etc/lighttpd" + +@@ -436,7 +436,7 @@ + ## # Check your cipher list with: openssl ciphers -v '...' + ## # (use single quotes with: openssl ciphers -v '...' + ## # as your shell won't like ! in double quotes) +-## #ssl.cipher-list = "HIGH" # default ++## #ssl.cipher-list = "PROFILE=SYSTEM" + ## + ## # (recommended to accept only TLSv1.2 and TLSv1.3) + ## #ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.2") # default +--- doc/config/lighttpd.conf~ 2022-07-28 10:49:14.928564535 -0500 ++++ doc/config/lighttpd.conf 2022-07-28 10:49:47.161444622 -0500 +@@ -118,7 +118,7 @@ + ## + ## Document root + ## +-server.document-root = server_root + "/htdocs" ++server.document-root = server_root + "/lighttpd" + + ## + ## The value for the "Server:" response field. diff --git a/SOURCES/manual.conf b/SOURCES/manual.conf new file mode 100644 index 0000000..133652b --- /dev/null +++ b/SOURCES/manual.conf @@ -0,0 +1,13 @@ +# +# This configuration file allows the manual to be accessed at +# http://localhost/manual/ +# +Alias /manual /usr/share/httpd/manual + + + Options Indexes + AllowOverride None + Require all granted + + RedirectMatch 301 ^/manual/(?:da|de|en|es|fr|ja|ko|pt-br|ru|tr|zh-cn)(/.*)$ "/manual$1" + diff --git a/SOURCES/server-status.conf b/SOURCES/server-status.conf new file mode 100644 index 0000000..be98f1b --- /dev/null +++ b/SOURCES/server-status.conf @@ -0,0 +1,10 @@ +# +# Lua-based server-status page; requires mod_lua to be loaded +# as per default configuration. +# +LuaMapHandler ^/server-status$ /usr/share/httpd/server-status/server-status.lua + + + AllowOverride None + Require local + diff --git a/SOURCES/ssl.conf b/SOURCES/ssl.conf new file mode 100644 index 0000000..d28adf3 --- /dev/null +++ b/SOURCES/ssl.conf @@ -0,0 +1,203 @@ +# +# When we also provide SSL we have to listen to the +# standard HTTPS port in addition. +# +Listen 443 https + +## +## SSL Global Context +## +## All SSL configuration in this context applies both to +## the main server and all SSL-enabled virtual hosts. +## + +# Pass Phrase Dialog: +# Configure the pass phrase gathering process. +# The filtering dialog program (`builtin' is a internal +# terminal dialog) has to provide the pass phrase on stdout. +SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog + +# Inter-Process Session Cache: +# Configure the SSL Session Cache: First the mechanism +# to use and second the expiring timeout (in seconds). +SSLSessionCache shmcb:/run/httpd/sslcache(512000) +SSLSessionCacheTimeout 300 + +# +# Use "SSLCryptoDevice" to enable any supported hardware +# accelerators. Use "openssl engine -v" to list supported +# engine names. NOTE: If you enable an accelerator and the +# server does not start, consult the error logs and ensure +# your accelerator is functioning properly. +# +SSLCryptoDevice builtin +#SSLCryptoDevice ubsec + +## +## SSL Virtual Host Context +## + + + +# General setup for the virtual host, inherited from global configuration +#DocumentRoot "/var/www/html" +#ServerName www.example.com:443 + +# Use separate log files for the SSL virtual host; note that LogLevel +# is not inherited from httpd.conf. +ErrorLog logs/ssl_error_log +TransferLog logs/ssl_access_log +LogLevel warn + +# SSL Engine Switch: +# Enable/Disable SSL for this virtual host. +SSLEngine on + +# List the protocol versions which clients are allowed to connect with. +# The OpenSSL system profile is used by default. See +# update-crypto-policies(8) for more details. +#SSLProtocol all -SSLv3 +#SSLProxyProtocol all -SSLv3 + +# User agents such as web browsers are not configured for the user's +# own preference of either security or performance, therefore this +# must be the prerogative of the web server administrator who manages +# cpu load versus confidentiality, so enforce the server's cipher order. +SSLHonorCipherOrder on + +# SSL Cipher Suite: +# List the ciphers that the client is permitted to negotiate. +# See the mod_ssl documentation for a complete list. +# The OpenSSL system profile is configured by default. See +# update-crypto-policies(8) for more details. +SSLCipherSuite PROFILE=SYSTEM +SSLProxyCipherSuite PROFILE=SYSTEM + +# Point SSLCertificateFile at a PEM encoded certificate. If +# the certificate is encrypted, then you will be prompted for a +# pass phrase. Note that restarting httpd will prompt again. Keep +# in mind that if you have both an RSA and a DSA certificate you +# can configure both in parallel (to also allow the use of DSA +# ciphers, etc.) +# Some ECC cipher suites (http://www.ietf.org/rfc/rfc4492.txt) +# require an ECC certificate which can also be configured in +# parallel. +SSLCertificateFile /etc/pki/tls/certs/localhost.crt + +# Server Private Key: +# If the key is not combined with the certificate, use this +# directive to point at the key file. Keep in mind that if +# you've both a RSA and a DSA private key you can configure +# both in parallel (to also allow the use of DSA ciphers, etc.) +# ECC keys, when in use, can also be configured in parallel +SSLCertificateKeyFile /etc/pki/tls/private/localhost.key + +# Server Certificate Chain: +# Point SSLCertificateChainFile at a file containing the +# concatenation of PEM encoded CA certificates which form the +# certificate chain for the server certificate. Alternatively +# the referenced file can be the same as SSLCertificateFile +# when the CA certificates are directly appended to the server +# certificate for convenience. +#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt + +# Certificate Authority (CA): +# Set the CA certificate verification path where to find CA +# certificates for client authentication or alternatively one +# huge file containing all of them (file must be PEM encoded) +#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt + +# Client Authentication (Type): +# Client certificate verification type and depth. Types are +# none, optional, require and optional_no_ca. Depth is a +# number which specifies how deeply to verify the certificate +# issuer chain before deciding the certificate is not valid. +#SSLVerifyClient require +#SSLVerifyDepth 10 + +# Access Control: +# With SSLRequire you can do per-directory access control based +# on arbitrary complex boolean expressions containing server +# variable checks and other lookup directives. The syntax is a +# mixture between C and Perl. See the mod_ssl documentation +# for more details. +# +#SSLRequire ( %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \ +# and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \ +# and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \ +# and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \ +# and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20 ) \ +# or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/ +# + +# SSL Engine Options: +# Set various options for the SSL engine. +# o FakeBasicAuth: +# Translate the client X.509 into a Basic Authorisation. This means that +# the standard Auth/DBMAuth methods can be used for access control. The +# user name is the `one line' version of the client's X.509 certificate. +# Note that no password is obtained from the user. Every entry in the user +# file needs this password: `xxj31ZMTZzkVA'. +# o ExportCertData: +# This exports two additional environment variables: SSL_CLIENT_CERT and +# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the +# server (always existing) and the client (only existing when client +# authentication is used). This can be used to import the certificates +# into CGI scripts. +# o StdEnvVars: +# This exports the standard SSL/TLS related `SSL_*' environment variables. +# Per default this exportation is switched off for performance reasons, +# because the extraction step is an expensive operation and is usually +# useless for serving static content. So one usually enables the +# exportation for CGI and SSI requests only. +# o StrictRequire: +# This denies access when "SSLRequireSSL" or "SSLRequire" applied even +# under a "Satisfy any" situation, i.e. when it applies access is denied +# and no other module can change it. +# o OptRenegotiate: +# This enables optimized SSL connection renegotiation handling when SSL +# directives are used in per-directory context. +#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire + + SSLOptions +StdEnvVars + + + SSLOptions +StdEnvVars + + +# SSL Protocol Adjustments: +# The safe and default but still SSL/TLS standard compliant shutdown +# approach is that mod_ssl sends the close notify alert but doesn't wait for +# the close notify alert from client. When you need a different shutdown +# approach you can use one of the following variables: +# o ssl-unclean-shutdown: +# This forces an unclean shutdown when the connection is closed, i.e. no +# SSL close notify alert is sent or allowed to be received. This violates +# the SSL/TLS standard but is needed for some brain-dead browsers. Use +# this when you receive I/O errors because of the standard approach where +# mod_ssl sends the close notify alert. +# o ssl-accurate-shutdown: +# This forces an accurate shutdown when the connection is closed, i.e. a +# SSL close notify alert is sent and mod_ssl waits for the close notify +# alert of the client. This is 100% SSL/TLS standard compliant, but in +# practice often causes hanging connections with brain-dead browsers. Use +# this only for browsers where you know that their SSL implementation +# works correctly. +# Notice: Most problems of broken clients are also related to the HTTP +# keep-alive facility, so you usually additionally want to disable +# keep-alive for those clients, too. Use variable "nokeepalive" for this. +# Similarly, one has to force some clients to use HTTP/1.0 to workaround +# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and +# "force-response-1.0" for this. +BrowserMatch "MSIE [2-5]" \ + nokeepalive ssl-unclean-shutdown \ + downgrade-1.0 force-response-1.0 + +# Per-Server Logging: +# The home of a custom SSL log file. Use this when you want a +# compact non-error SSL logfile on a virtual host basis. +CustomLog logs/ssl_request_log \ + "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" + + + diff --git a/SOURCES/userdir.conf b/SOURCES/userdir.conf new file mode 100644 index 0000000..b5d7a49 --- /dev/null +++ b/SOURCES/userdir.conf @@ -0,0 +1,36 @@ +# +# UserDir: The name of the directory that is appended onto a user's home +# directory if a ~user request is received. +# +# The path to the end user account 'public_html' directory must be +# accessible to the webserver userid. This usually means that ~userid +# must have permissions of 711, ~userid/public_html must have permissions +# of 755, and documents contained therein must be world-readable. +# Otherwise, the client will only receive a "403 Forbidden" message. +# + + # + # UserDir is disabled by default since it can confirm the presence + # of a username on the system (depending on home directory + # permissions). + # + UserDir disabled + + # + # To enable requests to /~user/ to serve the user's public_html + # directory, remove the "UserDir disabled" line above, and uncomment + # the following line instead: + # + #UserDir public_html + + +# +# Control access to UserDir directories. The following is an example +# for a site where these directories are restricted to read-only. +# + + AllowOverride FileInfo AuthConfig Limit Indexes + Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec + Require method GET POST OPTIONS + + diff --git a/SOURCES/welcome.conf b/SOURCES/welcome.conf new file mode 100644 index 0000000..232c251 --- /dev/null +++ b/SOURCES/welcome.conf @@ -0,0 +1,20 @@ +# +# This configuration file enables the default "Welcome" page if there +# is no default index page present for the root URL. To disable the +# Welcome page, comment out all the lines below. +# +# NOTE: if this file is removed, it will be restored on upgrades. +# + + Options -Indexes + ErrorDocument 403 /.noindex.html + + + + AllowOverride None + Require all granted + + +Alias /.noindex.html /usr/share/httpd/noindex/index.html +Alias /poweredby.png /usr/share/httpd/icons/apache_pb3.png +Alias /system_noindex_logo.png /usr/share/httpd/icons/system_noindex_logo.png diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec new file mode 100644 index 0000000..48dc06c --- /dev/null +++ b/SPECS/httpd.spec @@ -0,0 +1,1834 @@ +%define contentdir %{_datadir}/httpd +%define docroot /var/www +%define suexec_caller apache +%define mmn 20120211 +%define mmnisa %{mmn}%{__isa_name}%{__isa_bits} +%define vstring %(source /etc/os-release; echo ${NAME}) +%if 0%{?fedora} > 26 || 0%{?rhel} > 7 +%global mpm event +%else +%global mpm prefork +%endif + +Summary: Apache HTTP Server +Name: httpd +Version: 2.4.57 +Release: 8%{?dist} +URL: https://httpd.apache.org/ +Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2 +Source1: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2.asc +# gpg key file downloaded and verified by luhliarik +# https://httpd.apache.org/dev/verification.html +Source2: https://dist.apache.org/repos/dist/release/httpd/KEYS +Source3: httpd.logrotate +Source4: instance.conf +Source5: httpd-ssl-pass-dialog +Source6: httpd.tmpfiles +Source7: httpd.service +Source8: action-graceful.sh +Source9: action-configtest.sh +Source10: server-status.conf +Source11: httpd.conf +Source12: 00-base.conf +Source13: 00-mpm.conf +Source14: 00-lua.conf +Source15: 01-cgi.conf +Source16: 00-dav.conf +Source17: 00-proxy.conf +Source18: 00-ssl.conf +Source19: 01-ldap.conf +Source20: 00-proxyhtml.conf +Source21: userdir.conf +Source22: ssl.conf +Source23: welcome.conf +Source24: manual.conf +Source25: 00-systemd.conf +Source26: 01-session.conf +Source27: 10-listen443.conf +Source28: httpd.socket +Source29: 00-optional.conf +Source30: README.confd +Source31: README.confmod +Source32: httpd.service.xml +Source33: htcacheclean.service.xml +Source34: httpd.conf.xml +Source35: 00-brotli.conf +Source40: htcacheclean.service +Source41: htcacheclean.sysconf +Source42: httpd-init.service +Source43: httpd-ssl-gencerts +Source44: httpd@.service +Source45: config.layout +Source46: apachectl.sh +Source47: apachectl.xml +Source48: apache-poweredby.png + +# build/scripts patches +Patch2: httpd-2.4.43-apxs.patch +Patch3: httpd-2.4.43-deplibs.patch +# Needed for socket activation and mod_systemd patch +Patch19: httpd-2.4.53-detect-systemd.patch +# Features/functional changes +Patch21: httpd-2.4.48-r1842929+.patch +Patch22: httpd-2.4.43-mod_systemd.patch +Patch23: httpd-2.4.48-export.patch +Patch24: httpd-2.4.43-corelimit.patch +Patch25: httpd-2.4.57-selinux.patch +Patch26: httpd-2.4.57-gettid.patch +Patch27: httpd-2.4.53-icons.patch +Patch30: httpd-2.4.43-cachehardmax.patch +Patch34: httpd-2.4.43-socket-activation.patch +Patch38: httpd-2.4.43-sslciphdefault.patch +Patch39: httpd-2.4.43-sslprotdefault.patch +Patch41: httpd-2.4.43-r1861793+.patch +Patch42: httpd-2.4.48-r1828172+.patch +Patch45: httpd-2.4.43-logjournal.patch +Patch46: httpd-2.4.48-proxy-ws-idle-timeout.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1949969 +Patch47: httpd-2.4.57-pr37355.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1949606 +Patch48: httpd-2.4.46-freebind.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1950021 +Patch49: httpd-2.4.48-ssl-proxy-chains.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2004143 +Patch50: httpd-2.4.57-r1825120.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2065677 +Patch52: httpd-2.4.53-separate-systemd-fns.patch +# https://issues.redhat.com/browse/RHEL-5071 +Patch53: httpd-2.4.57-r1912477+.patch +# https://issues.redhat.com/browse/RHEL-6600 +Patch54: httpd-2.4.57-r1912081.patch + + +# Bug fixes +# https://bugzilla.redhat.com/show_bug.cgi?id=1397243 +Patch60: httpd-2.4.43-enable-sslv3.patch +Patch61: httpd-2.4.46-htcacheclean-dont-break.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1932442 +Patch64: httpd-2.4.48-full-release.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1950011 +Patch65: httpd-2.4.51-r1877397.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1938740 +Patch66: httpd-2.4.51-r1892413+.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2073459 +Patch67: httpd-2.4.51-r1811831.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2098056 +Patch68: httpd-2.4.53-r1878890.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2186645 +Patch69: httpd-2.4.57-covscan.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2222001 +Patch70: httpd-2.4.57-mod_status-duplicate-key.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2217726 +Patch71: httpd-2.4.57-davenoent.patch +# https://issues.redhat.com/browse/RHEL-17686 +Patch72: httpd-2.4.57-r1884505+.patch + +# Security fixes +# https://bugzilla.redhat.com/show_bug.cgi?id=... +# +# https://bugzilla.redhat.com/show_bug.cgi?id=2245332 +Patch200: httpd-2.4.57-CVE-2023-31122.patch + + +License: ASL 2.0 +BuildRequires: gcc, autoconf, pkgconfig, findutils, xmlto +BuildRequires: perl-interpreter, perl-generators, systemd-devel +BuildRequires: zlib-devel, libselinux-devel, lua-devel, brotli-devel +BuildRequires: apr-devel >= 1.5.0, apr-util-devel >= 1.5.0, pcre-devel >= 5.0 +BuildRequires: gnupg2 +Requires: system-logos-httpd +Provides: webserver +Requires: httpd-core = 0:%{version}-%{release} +Recommends: mod_http2, mod_lua +Requires(preun): systemd-units +Requires(postun): systemd-units +Requires(post): systemd-units + +%description +The Apache HTTP Server is a powerful, efficient, and extensible +web server. + +%package core +Summary: httpd minimal core +Provides: mod_dav = %{version}-%{release}, httpd-suexec = %{version}-%{release} +Provides: httpd-mmn = %{mmn}, httpd-mmn = %{mmnisa} +Provides: mod_proxy_uwsgi = %{version}-%{release} +Requires: /etc/mime.types +Requires: httpd-tools = %{version}-%{release} +Requires: httpd-filesystem = %{version}-%{release} +Requires(pre): httpd-filesystem +Conflicts: apr < 1.5.0-1 +Conflicts: httpd < 2.4.53-3 +Conflicts: mod_http2 < 1.15.19-3 +Obsoletes: mod_proxy_uwsgi < 2.0.17.1-2 + +%description core +The httpd-core package contains essential httpd binaries. + +%package devel +Summary: Development interfaces for the Apache HTTP Server +Requires: apr-devel, apr-util-devel, pkgconfig +Requires: httpd-core = %{version}-%{release} + +%description devel +The httpd-devel package contains the APXS binary and other files +that you need to build Dynamic Shared Objects (DSOs) for the +Apache HTTP Server. + +If you are installing the Apache HTTP Server and you want to be +able to compile or develop additional modules for Apache, you need +to install this package. + +%package manual +Summary: Documentation for the Apache HTTP Server +Requires: httpd-core = 0:%{version}-%{release} +BuildArch: noarch + +%description manual +The httpd-manual package contains the complete manual and +reference guide for the Apache HTTP Server. The information can +also be found at https://httpd.apache.org/docs/2.4/. + +%package filesystem +Summary: The basic directory layout for the Apache HTTP Server +BuildArch: noarch +Requires(pre): /usr/sbin/useradd + +%description filesystem +The httpd-filesystem package contains the basic directory layout +for the Apache HTTP Server including the correct permissions +for the directories. + +%package tools +Summary: Tools for use with the Apache HTTP Server + +%description tools +The httpd-tools package contains tools which can be used with +the Apache HTTP Server. + +%package -n mod_ssl +Summary: SSL/TLS module for the Apache HTTP Server +Epoch: 1 +BuildRequires: openssl-devel +Requires(pre): httpd-filesystem +Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} +Requires: sscg >= 3.0.0-7, /usr/bin/hostname +# Require an OpenSSL which supports PROFILE=SYSTEM +Conflicts: openssl-libs < 1:1.0.1h-4 + +%description -n mod_ssl +The mod_ssl module provides strong cryptography for the Apache HTTP +server via the Secure Sockets Layer (SSL) and Transport Layer +Security (TLS) protocols. + +%package -n mod_proxy_html +Summary: HTML and XML content filters for the Apache HTTP Server +Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} +BuildRequires: libxml2-devel +BuildRequires: make +Epoch: 1 +Obsoletes: mod_proxy_html < 1:2.4.1-2 + +%description -n mod_proxy_html +The mod_proxy_html and mod_xml2enc modules provide filters which can +transform and modify HTML and XML content. + +%package -n mod_ldap +Summary: LDAP authentication modules for the Apache HTTP Server +Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} +Requires: apr-util-ldap + +%description -n mod_ldap +The mod_ldap and mod_authnz_ldap modules add support for LDAP +authentication to the Apache HTTP Server. + +%package -n mod_session +Summary: Session interface for the Apache HTTP Server +Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} + +%description -n mod_session +The mod_session module and associated backends provide an abstract +interface for storing and accessing per-user session data. + +%package -n mod_lua +Summary: Lua scripting support for the Apache HTTP Server +Requires: httpd-core = 0:%{version}-%{release}, httpd-mmn = %{mmnisa} + +%description -n mod_lua +The mod_lua module allows the server to be extended with scripts +written in the Lua programming language. + +%prep +%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' +%setup -q +%patch2 -p1 -b .apxs +%patch3 -p1 -b .deplibs + +%patch19 -p1 -b .detectsystemd + +%patch21 -p1 -b .r1842929+ +%patch22 -p1 -b .mod_systemd +%patch23 -p1 -b .export +%patch24 -p1 -b .corelimit +%patch25 -p1 -b .selinux +%patch26 -p1 -b .gettid +%patch27 -p1 -b .icons +%patch30 -p1 -b .cachehardmax +%patch34 -p1 -b .socketactivation +%patch38 -p1 -b .sslciphdefault +%patch39 -p1 -b .sslprotdefault +%patch41 -p1 -b .r1861793+ +%patch42 -p1 -b .r1828172+ +%patch45 -p1 -b .logjournal +%patch46 -p1 -b .proxy-ws-idle-timeout +%patch47 -p1 -b .pr37355 +%patch48 -p1 -b .freebind +%patch49 -p1 -b .ssl-proxy-chains +%patch50 -p1 -b .r1825120 +%patch52 -p1 -b .separatesystemd +%patch53 -p1 -b .r1912477+ +%patch54 -p1 -b .r1912081 + +%patch60 -p1 -b .enable-sslv3 +%patch61 -p1 -b .htcacheclean-dont-break +%patch64 -p1 -b .full-release +%patch65 -p1 -b .r1877397 +%patch66 -p1 -b .r1892413+ +%patch67 -p1 -b .r1811831 +%patch68 -p1 -b .r1878890 +%patch69 -p1 -b .covstan +%patch70 -p1 -b .duplicate-key +%patch71 -p1 -b .davenoent +%patch72 -p1 -b .r1884505+ + +%patch200 -p1 -b .CVE-2023-31122 + +# Patch in the vendor string +sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h +sed -i 's/@RELEASE@/%{release}/' server/core.c + +# Prevent use of setcap in "install-suexec-caps" target. +sed -i '/suexec/s,setcap ,echo Skipping setcap for ,' Makefile.in + +# Example conf for instances +cp $RPM_SOURCE_DIR/instance.conf . +sed < $RPM_SOURCE_DIR/httpd.conf >> instance.conf ' +0,/^ServerRoot/d; +/# Supplemental configuration/,$d +/^ *CustomLog .logs/s,logs/,logs/${HTTPD_INSTANCE}_, +/^ *ErrorLog .logs/s,logs/,logs/${HTTPD_INSTANCE}_, +' +touch -r $RPM_SOURCE_DIR/instance.conf instance.conf +cp -p $RPM_SOURCE_DIR/server-status.conf server-status.conf + +# Safety check: prevent build if defined MMN does not equal upstream MMN. +vmmn=`echo MODULE_MAGIC_NUMBER_MAJOR | cpp -include include/ap_mmn.h | sed -n '/^2/p'` +if test "x${vmmn}" != "x%{mmn}"; then + : Error: Upstream MMN is now ${vmmn}, packaged MMN is %{mmn} + : Update the mmn macro and rebuild. + exit 1 +fi + +# A new logo which comes together with a new test page +cp %{SOURCE48} ./docs/icons/apache_pb3.png + +# Provide default layout +cp $RPM_SOURCE_DIR/config.layout . + +sed ' +s,@MPM@,%{mpm},g +s,@DOCROOT@,%{docroot},g +s,@LOGDIR@,%{_localstatedir}/log/httpd,g +' < $RPM_SOURCE_DIR/httpd.conf.xml \ + > httpd.conf.xml + +xmlto man ./httpd.conf.xml +xmlto man $RPM_SOURCE_DIR/htcacheclean.service.xml +xmlto man $RPM_SOURCE_DIR/httpd.service.xml + +# apachectl.xml => apachectl.8 +xmlto man %{SOURCE47} + +: Building with MMN %{mmn}, MMN-ISA %{mmnisa} +: Default MPM is %{mpm}, vendor string is '%{vstring}' + +%build +# forcibly prevent use of bundled apr, apr-util, pcre +rm -rf srclib/{apr,apr-util,pcre} + +# regenerate configure scripts +autoheader && autoconf || exit 1 + +# Before configure; fix location of build dir in generated apxs +%{__perl} -pi -e "s:\@exp_installbuilddir\@:%{_libdir}/httpd/build:g" \ + support/apxs.in + +export CFLAGS=$RPM_OPT_FLAGS +export LDFLAGS="-Wl,-z,relro,-z,now" + +# Hard-code path to links to avoid unnecessary builddep +export LYNX_PATH=/usr/bin/links + +# Build the daemon +./configure \ + --prefix=%{_sysconfdir}/httpd \ + --exec-prefix=%{_prefix} \ + --bindir=%{_bindir} \ + --sbindir=%{_sbindir} \ + --mandir=%{_mandir} \ + --libdir=%{_libdir} \ + --sysconfdir=%{_sysconfdir}/httpd/conf \ + --includedir=%{_includedir}/httpd \ + --libexecdir=%{_libdir}/httpd/modules \ + --datadir=%{contentdir} \ + --enable-layout=Fedora \ + --with-installbuilddir=%{_libdir}/httpd/build \ + --enable-mpms-shared=all \ + --with-apr=%{_prefix} --with-apr-util=%{_prefix} \ + --enable-suexec --with-suexec \ + --enable-suexec-capabilities \ + --with-suexec-caller=%{suexec_caller} \ + --with-suexec-docroot=%{docroot} \ + --without-suexec-logfile \ + --with-suexec-syslog \ + --with-suexec-bin=%{_sbindir}/suexec \ + --with-suexec-uidmin=1000 --with-suexec-gidmin=1000 \ + --with-brotli \ + --enable-pie \ + --with-pcre=/usr/bin/pcre-config \ + --enable-mods-shared=all \ + --enable-ssl --with-ssl --disable-distcache \ + --enable-proxy --enable-proxy-fdpass \ + --enable-cache \ + --enable-disk-cache \ + --enable-ldap --enable-authnz-ldap \ + --enable-cgid --enable-cgi \ + --enable-cgid-fdpassing \ + --enable-authn-anon --enable-authn-alias \ + --enable-authnz-fcgi \ + --enable-systemd \ + --disable-imagemap --disable-file-cache \ + --disable-http2 \ + --disable-md \ + $* +%make_build + +%install +rm -rf $RPM_BUILD_ROOT + +%make_install + +# Install systemd service files +mkdir -p $RPM_BUILD_ROOT%{_unitdir} +for s in httpd.service htcacheclean.service httpd.socket \ + httpd@.service httpd-init.service; do + install -p -m 644 $RPM_SOURCE_DIR/${s} \ + $RPM_BUILD_ROOT%{_unitdir}/${s} +done + +# install conf file/directory +mkdir $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d \ + $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d +install -m 644 $RPM_SOURCE_DIR/README.confd \ + $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/README +install -m 644 $RPM_SOURCE_DIR/README.confmod \ + $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/README +for f in 00-base.conf 00-mpm.conf 00-lua.conf 01-cgi.conf 00-dav.conf \ + 00-proxy.conf 00-ssl.conf 01-ldap.conf 00-proxyhtml.conf \ + 01-ldap.conf 00-systemd.conf 01-session.conf 00-optional.conf \ + 00-brotli.conf; do + install -m 644 -p $RPM_SOURCE_DIR/$f \ + $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/$f +done + +sed -i '/^#LoadModule mpm_%{mpm}_module /s/^#//' \ + $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/00-mpm.conf +touch -r $RPM_SOURCE_DIR/00-mpm.conf \ + $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/00-mpm.conf + +# install systemd override drop directory +# Web application packages can drop snippets into this location if +# they need ExecStart[pre|post]. +mkdir $RPM_BUILD_ROOT%{_unitdir}/httpd.service.d +mkdir $RPM_BUILD_ROOT%{_unitdir}/httpd.socket.d + +install -m 644 -p $RPM_SOURCE_DIR/10-listen443.conf \ + $RPM_BUILD_ROOT%{_unitdir}/httpd.socket.d/10-listen443.conf + +for f in welcome.conf ssl.conf manual.conf userdir.conf; do + install -m 644 -p $RPM_SOURCE_DIR/$f \ + $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/$f +done + +# Split-out extra config shipped as default in conf.d: +for f in autoindex; do + install -m 644 docs/conf/extra/httpd-${f}.conf \ + $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/${f}.conf +done + +# Extra config trimmed: +rm -v docs/conf/extra/httpd-{ssl,userdir}.conf + +rm $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf/*.conf +install -m 644 -p $RPM_SOURCE_DIR/httpd.conf \ + $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf/httpd.conf + +mkdir $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig +install -m 644 -p $RPM_SOURCE_DIR/htcacheclean.sysconf \ + $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/htcacheclean + +# tmpfiles.d configuration +mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/tmpfiles.d +install -m 644 -p $RPM_SOURCE_DIR/httpd.tmpfiles \ + $RPM_BUILD_ROOT%{_prefix}/lib/tmpfiles.d/httpd.conf + +# Other directories +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/lib/httpd \ + $RPM_BUILD_ROOT/run/httpd/htcacheclean + +# Substitute in defaults which are usually done (badly) by "make install" +sed -i \ + "/^DavLockDB/d; + s,@@ServerRoot@@/user.passwd,/etc/httpd/conf/user.passwd,; + s,@@ServerRoot@@/docs,%{docroot},; + s,@@ServerRoot@@,%{docroot},; + s,@@Port@@,80,;" \ + docs/conf/extra/*.conf + +# Set correct path for httpd binary in apachectl script +sed 's,@HTTPDBIN@,%{_sbindir}/httpd,g' $RPM_SOURCE_DIR/apachectl.sh \ + > apachectl.sh + +# Create cache directory +mkdir -p $RPM_BUILD_ROOT%{_localstatedir}/cache/httpd \ + $RPM_BUILD_ROOT%{_localstatedir}/cache/httpd/proxy \ + $RPM_BUILD_ROOT%{_localstatedir}/cache/httpd/ssl + +# Make the MMN accessible to module packages +echo %{mmnisa} > $RPM_BUILD_ROOT%{_includedir}/httpd/.mmn +mkdir -p $RPM_BUILD_ROOT%{_rpmconfigdir}/macros.d +cat > $RPM_BUILD_ROOT%{_rpmconfigdir}/macros.d/macros.httpd < $RPM_BUILD_ROOT%{_mandir}/man8/httpd.8 + +# Make ap_config_layout.h libdir-agnostic +sed -i '/.*DEFAULT_..._LIBEXECDIR/d;/DEFAULT_..._INSTALLBUILDDIR/d' \ + $RPM_BUILD_ROOT%{_includedir}/httpd/ap_config_layout.h + +# Fix path to instdso in special.mk +sed -i '/instdso/s,top_srcdir,top_builddir,' \ + $RPM_BUILD_ROOT%{_libdir}/httpd/build/special.mk + +# vendor-apxs uses an unsanitized config_vars.mk which may +# have dependencies on redhat-rpm-config. apxs uses the +# config_vars.mk with a sanitized config_vars.mk +cp -p $RPM_BUILD_ROOT%{_libdir}/httpd/build/config_vars.mk \ + $RPM_BUILD_ROOT%{_libdir}/httpd/build/vendor_config_vars.mk + +# Sanitize CFLAGS in standard config_vars.mk +sed '/^CFLAGS/s,=.*$,= -O2 -g -Wall,' \ + -i $RPM_BUILD_ROOT%{_libdir}/httpd/build/config_vars.mk + +sed 's/config_vars.mk/vendor_config_vars.mk/' \ + $RPM_BUILD_ROOT%{_bindir}/apxs \ + > $RPM_BUILD_ROOT%{_libdir}/httpd/build/vendor-apxs +touch -r $RPM_BUILD_ROOT%{_bindir}/apxs \ + $RPM_BUILD_ROOT%{_libdir}/httpd/build/vendor-apxs +chmod 755 $RPM_BUILD_ROOT%{_libdir}/httpd/build/vendor-apxs + +# Remove unpackaged files +rm -vf \ + $RPM_BUILD_ROOT%{_libdir}/*.exp \ + $RPM_BUILD_ROOT/etc/httpd/conf/mime.types \ + $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.exp \ + $RPM_BUILD_ROOT%{_libdir}/httpd/build/config.nice \ + $RPM_BUILD_ROOT%{_bindir}/{ap?-config,dbmmanage} \ + $RPM_BUILD_ROOT%{_sbindir}/{checkgid,envvars*} \ + $RPM_BUILD_ROOT%{contentdir}/htdocs/* \ + $RPM_BUILD_ROOT%{_mandir}/man1/dbmmanage.* \ + $RPM_BUILD_ROOT%{contentdir}/cgi-bin/* + +rm -rf $RPM_BUILD_ROOT/etc/httpd/conf/{original,extra} + +%pre filesystem +getent group apache >/dev/null || groupadd -g 48 -r apache +getent passwd apache >/dev/null || \ + useradd -r -u 48 -g apache -s /sbin/nologin \ + -d %{contentdir} -c "Apache" apache +exit 0 + +%post +%systemd_post httpd.service htcacheclean.service httpd.socket + +%preun +%systemd_preun httpd.service htcacheclean.service httpd.socket + +%postun +%systemd_postun httpd.service htcacheclean.service httpd.socket + +%posttrans +test -f /etc/sysconfig/httpd-disable-posttrans || \ + /bin/systemctl try-restart --no-block httpd.service htcacheclean.service >/dev/null 2>&1 || : + +%check +make -C server exports.o +nm --defined httpd > exports-actual.list +set +x +rv=0 +nm --defined-only server/exports.o | \ + sed -n '/ap_hack_/{s/.* ap_hack_//;/^ap[ru]/d;p;}' | \ + while read sym; do + if ! grep -q " "$sym\$ exports-actual.list; then + echo ERROR: Symbol $sym missing in httpd exports + rv=1 + fi + done +if [ $rv -eq 0 ]; then + echo PASS: Symbol export list verified. +fi +# Check the built modules are all PIC +if readelf -d $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.so | grep TEXTREL; then + echo FAIL: Modules contain non-relocatable code + rv=1 +else + echo PASS: No non-relocatable code in module builds +fi +# Ensure every mod_* that's built is loaded. +for f in $RPM_BUILD_ROOT%{_libdir}/httpd/modules/*.so; do + m=${f##*/} + if ! grep -q $m $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/*.conf; then + echo FAIL: Module $m not configured. Disable it, or load it. + rv=1 + else + echo PASS: Module $m is configured and loaded. + fi +done +# Ensure every loaded mod_* is actually built +mods=`grep -h ^LoadModule $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.modules.d/*.conf | sed 's,.*modules/,,'` +for m in $mods; do + f=$RPM_BUILD_ROOT%{_libdir}/httpd/modules/${m} + if ! test -x $f; then + echo FAIL: Module $m is configured but not built. + rv=1 + else + echo PASS: Loaded module $m is installed. + fi +done +set -x +exit $rv + +%files +%{_mandir}/man8/* +%{_mandir}/man5/* +%exclude %{_mandir}/man8/httpd-init.* + +%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-brotli.conf +%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-systemd.conf + +%{_libdir}/httpd/modules/mod_brotli.so +%{_libdir}/httpd/modules/mod_systemd.so + +%{_unitdir}/httpd.service +%{_unitdir}/httpd@.service +%{_unitdir}/htcacheclean.service +%{_unitdir}/*.socket + +%files core + +%doc ABOUT_APACHE README CHANGES LICENSE VERSIONING NOTICE +%doc docs/conf/extra/*.conf +%doc instance.conf server-status.conf + +%{_sysconfdir}/httpd/modules +%{_sysconfdir}/httpd/logs +%{_sysconfdir}/httpd/state +%{_sysconfdir}/httpd/run +%dir %{_sysconfdir}/httpd/conf +%config(noreplace) %{_sysconfdir}/httpd/conf/httpd.conf +%config(noreplace) %{_sysconfdir}/httpd/conf/magic + +%config(noreplace) %{_sysconfdir}/logrotate.d/httpd + +%config(noreplace) %{_sysconfdir}/httpd/conf.d/*.conf +%exclude %{_sysconfdir}/httpd/conf.d/ssl.conf +%exclude %{_sysconfdir}/httpd/conf.d/manual.conf + +%dir %{_sysconfdir}/httpd/conf.modules.d +%{_sysconfdir}/httpd/conf.modules.d/README + +%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/*.conf +%exclude %{_sysconfdir}/httpd/conf.modules.d/00-brotli.conf +%exclude %{_sysconfdir}/httpd/conf.modules.d/00-systemd.conf +%exclude %{_sysconfdir}/httpd/conf.modules.d/00-ssl.conf +%exclude %{_sysconfdir}/httpd/conf.modules.d/00-proxyhtml.conf +%exclude %{_sysconfdir}/httpd/conf.modules.d/00-lua.conf +%exclude %{_sysconfdir}/httpd/conf.modules.d/01-ldap.conf +%exclude %{_sysconfdir}/httpd/conf.modules.d/01-session.conf + +%config(noreplace) %{_sysconfdir}/sysconfig/htcacheclean +%{_prefix}/lib/tmpfiles.d/httpd.conf + +%dir %{_libexecdir}/initscripts/legacy-actions/httpd +%{_libexecdir}/initscripts/legacy-actions/httpd/* + +%{_sbindir}/ht* +%{_sbindir}/fcgistarter +%{_sbindir}/apachectl +%{_sbindir}/rotatelogs +%caps(cap_setuid,cap_setgid+pe) %attr(510,root,%{suexec_caller}) %{_sbindir}/suexec + +%dir %{_libdir}/httpd +%dir %{_libdir}/httpd/modules +%{_libdir}/httpd/modules/mod*.so +%exclude %{_libdir}/httpd/modules/mod_brotli.so +%exclude %{_libdir}/httpd/modules/mod_systemd.so +%exclude %{_libdir}/httpd/modules/mod_auth_form.so +%exclude %{_libdir}/httpd/modules/mod_ssl.so +%exclude %{_libdir}/httpd/modules/mod_*ldap.so +%exclude %{_libdir}/httpd/modules/mod_proxy_html.so +%exclude %{_libdir}/httpd/modules/mod_xml2enc.so +%exclude %{_libdir}/httpd/modules/mod_session*.so +%exclude %{_libdir}/httpd/modules/mod_lua.so + +%dir %{contentdir}/error +%dir %{contentdir}/error/include +%dir %{contentdir}/noindex +%dir %{contentdir}/server-status +%{contentdir}/icons/* +%{contentdir}/error/README +%{contentdir}/error/*.var +%{contentdir}/error/include/*.html +%{contentdir}/noindex/index.html +%{contentdir}/server-status/* + +%attr(0710,root,apache) %dir /run/httpd +%attr(0700,apache,apache) %dir /run/httpd/htcacheclean +%attr(0700,root,root) %dir %{_localstatedir}/log/httpd +%attr(0700,apache,apache) %dir %{_localstatedir}/lib/httpd +%attr(0700,apache,apache) %dir %{_localstatedir}/cache/httpd +%attr(0700,apache,apache) %dir %{_localstatedir}/cache/httpd/proxy + +%files filesystem +%dir %{_sysconfdir}/httpd +%dir %{_sysconfdir}/httpd/conf.d +%{_sysconfdir}/httpd/conf.d/README +%dir %{docroot} +%dir %{docroot}/cgi-bin +%dir %{docroot}/html +%dir %{contentdir} +%dir %{contentdir}/icons +%attr(755,root,root) %dir %{_unitdir}/httpd.service.d +%attr(755,root,root) %dir %{_unitdir}/httpd.socket.d + +%files tools +%{_bindir}/* +%{_mandir}/man1/* +%doc LICENSE NOTICE +%exclude %{_bindir}/apxs +%exclude %{_mandir}/man1/apxs.1* + +%files manual +%{contentdir}/manual +%config(noreplace) %{_sysconfdir}/httpd/conf.d/manual.conf + +%files -n mod_ssl +%{_libdir}/httpd/modules/mod_ssl.so +%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-ssl.conf +%config(noreplace) %{_sysconfdir}/httpd/conf.d/ssl.conf +%attr(0700,apache,root) %dir %{_localstatedir}/cache/httpd/ssl +%{_unitdir}/httpd-init.service +%{_libexecdir}/httpd-ssl-pass-dialog +%{_libexecdir}/httpd-ssl-gencerts +%{_unitdir}/httpd.socket.d/10-listen443.conf +%{_mandir}/man8/httpd-init.* + +%files -n mod_proxy_html +%{_libdir}/httpd/modules/mod_proxy_html.so +%{_libdir}/httpd/modules/mod_xml2enc.so +%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-proxyhtml.conf + +%files -n mod_ldap +%{_libdir}/httpd/modules/mod_*ldap.so +%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/01-ldap.conf + +%files -n mod_session +%{_libdir}/httpd/modules/mod_session*.so +%{_libdir}/httpd/modules/mod_auth_form.so +%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/01-session.conf + +%files -n mod_lua +%{_libdir}/httpd/modules/mod_lua.so +%config(noreplace) %{_sysconfdir}/httpd/conf.modules.d/00-lua.conf + +%files devel +%{_includedir}/httpd +%{_bindir}/apxs +%{_mandir}/man1/apxs.1* +%dir %{_libdir}/httpd/build +%{_libdir}/httpd/build/*.mk +%{_libdir}/httpd/build/*.sh +%{_libdir}/httpd/build/vendor-apxs +%{_rpmconfigdir}/macros.d/macros.httpd + +%changelog +* Wed Feb 7 2024 Joe Orton - 2.4.57-8 +- mod_xml2enc: fix media type handling + Resolves: RHEL-17686 +- mod_dav: add DavBasePath + Resolves: RHEL-6600 + +* Mon Feb 05 2024 Luboš Uhliarik - 2.4.57-7 +- Resolves: RHEL-14447 - httpd: mod_macro: out-of-bounds read + vulnerability (CVE-2023-31122) + +* Wed Oct 4 2023 Joe Orton - 2.4.57-6 +- Resolves: RHEL-5071 - mod_dav_fs: add DavLockDBType +- mod_dav_fs: add global mutex around lockdb interaction + +* Thu Jul 20 2023 Tomas Korbar - 2.4.57-5 +- Fix issue found by covscan +- Related: #2222001 + +* Tue Jul 18 2023 Joe Orton - 2.4.57-4 +- Resolves: #2217726 - Make PROPFIND tolerant of deletion race + +* Tue Jul 11 2023 Tomas Korbar - 2.4.57-3 +- Resolves: #2222001 - mod_status lists BusyWorkers IdleWorkers keys twice + +* Fri Apr 14 2023 Luboš Uhliarik - 2.4.57-2 +- Resolves: #2186645 - Fix issue found by covscan in httpd package +- Resolves: #2173295 - Include Apache httpd module mod_authnz_fcgi + +* Tue Apr 11 2023 Luboš Uhliarik - 2.4.57-1 +- Resolves: #2184403 - rebase httpd to 2.4.57 +- Resolves: #2177753 - CVE-2023-25690 httpd: HTTP request splitting with + mod_rewrite and mod_proxy + +* Mon Jan 30 2023 Luboš Uhliarik - 2.4.53-11 +- Resolves: #2162500 - CVE-2006-20001 httpd: mod_dav: out-of-bounds read/write + of zero byte +- Resolves: #2162486 - CVE-2022-37436 httpd: mod_proxy: HTTP response splitting +- Resolves: #2162510 - CVE-2022-36760 httpd: mod_proxy_ajp: Possible request + smuggling + +* Tue Jan 24 2023 Luboš Uhliarik - 2.4.53-10 +- Resolves: #2160667 - prevent sscg creating /dhparams.pem + +* Thu Dec 08 2022 Luboš Uhliarik - 2.4.53-9 +- Resolves: #2143176 - Dependency from mod_http2 on httpd broken + +* Tue Dec 06 2022 Luboš Uhliarik - 2.4.53-8 +- Resolves: #2151313 - reduce AH03408 log level from WARNING to INFO + +* Wed Jul 20 2022 Luboš Uhliarik - 2.4.53-7 +- Resolves: #2094997 - CVE-2022-26377 httpd: mod_proxy_ajp: Possible request + smuggling +- Resolves: #2097032 - CVE-2022-28615 httpd: out-of-bounds read in + ap_strcmp_match() +- Resolves: #2098248 - CVE-2022-31813 httpd: mod_proxy: X-Forwarded-For dropped + by hop-by-hop mechanism +- Resolves: #2097016 - CVE-2022-28614 httpd: out-of-bounds read via ap_rwrite() +- Resolves: #2097452 - CVE-2022-29404 httpd: mod_lua: DoS in r:parsebody +- Resolves: #2097459 - CVE-2022-30522 httpd: mod_sed: DoS vulnerability +- Resolves: #2097481 - CVE-2022-30556 httpd: mod_lua: Information disclosure + with websockets + +* Mon Jun 27 2022 Luboš Uhliarik - 2.4.53-6 +- Related: #2065677 - httpd minimisation for ubi-micro + +* Fri Jun 24 2022 Luboš Uhliarik - 2.4.53-5 +- Resolves: #2098056 - mod_ldap: High CPU usage at apr_ldap_rebind_remove() + +* Thu Jun 16 2022 Luboš Uhliarik - 2.4.53-4 +- Resolves: #2095838 - mod_mime_magic: invalid type 0 in mconvert() + +* Wed Jun 01 2022 Luboš Uhliarik - 2.4.53-3 +- Resolves: #2065677 - httpd minimisation for ubi-micro +- minimize httpd dependencies (new httpd-core package) +- mod_systemd and mod_brotli are now packaged in the main httpd package + +* Tue May 31 2022 Luboš Uhliarik - 2.4.53-1 +- new version 2.4.53 +- Resolves: #2079939 - httpd rebase to 2.4.53 +- Resolves: #2075406 - httpd.conf uses icon bomb.gif for all files/dirs ending + with core + +* Mon Apr 11 2022 Luboš Uhliarik - 2.4.51-8 +- Resolves: #2073459 - Cannot override LD_LIBARY_PATH in Apache HTTPD using + SetEnv or PassEnv + +* Mon Mar 21 2022 Luboš Uhliarik - 2.4.51-7 +- Resolves: #2065251 - CVE-2022-22720 httpd: HTTP request smuggling + vulnerability in Apache HTTP Server 2.4.52 and earlier +- Resolves: #2066311 - CVE-2021-44224 httpd: possible NULL dereference or SSRF + in forward proxy configurations + +* Mon Jan 10 2022 Luboš Uhliarik - 2.4.51-5 +- Resolves: #2035064 - CVE-2021-44790 httpd: mod_lua: possible buffer overflow + when parsing multipart content + +* Mon Dec 06 2021 Neal Gompa - 2.4.51-4 +- Use NAME from os-release(5) for vendor string + Resolves: #2029071 - httpd on CentOS identifies as RHEL + +* Fri Dec 3 2021 Joe Orton - 2.4.51-3 +- add fixes for static analyzer issues (#1938740) + +* Mon Nov 08 2021 Luboš Uhliarik - 2.4.51-2 +- Resolves: #2005416 - httpd default configuration changes + +* Tue Oct 19 2021 Luboš Uhliarik - 2.4.51-1 +- new version 2.4.51 (#2011090) + +* Fri Sep 17 2021 Luboš Uhliarik - 2.4.49-1 +- new version 2.4.49 (#2005339) + +* Wed Sep 15 2021 Luboš Uhliarik - 2.4.48-18 +- Resolves: #2004143 - RFE: mod_ssl: allow sending multiple CA names which + differ only in case + +* Mon Aug 09 2021 Mohan Boddu - 2.4.48-17 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Fri Aug 06 2021 Luboš Uhliarik - 2.4.48-16 +- Resolves: #1956386 - Apache trademark update - new logo + +* Fri Aug 6 2021 Florian Weimer - 2.4.48-14 +- Rebuild to pick up new build flags from redhat-rpm-config (#1984652) + +* Wed Jul 28 2021 Joe Orton - 2.4.48-13 +- mod_ssl: OpenSSL 3 compatibility update (#1986822) + +* Thu Jul 15 2021 Joe Orton - 2.4.48-12 +- mod_ssl: add SSLKEYLOGFILE support (#1982656) + +* Mon Jul 12 2021 Joe Orton - 2.4.48-11 +- mod_cgid: fix doubled script timeout (#1977234) + +* Fri Jul 9 2021 Joe Orton - 2.4.48-10 +- fix release in ServerTokens Full-Release (#1932442) + +* Wed Jul 7 2021 Joe Orton - 2.4.48-9 +- use OOMPolicy=continue in httpd.service, httpd@.service (#1947475) + +* Thu Jul 01 2021 Luboš Uhliarik - 2.4.48-8 +- Resolves: #1950021 - [RFE] Update httpd directive SSLProxyMachineCertificateFile + to be able to handle certs without matching private key + +* Thu Jul 01 2021 Luboš Uhliarik - 2.4.48-7 +- Resolves: #1950011 - unorderly connection close when client attempts + renegotiation + +* Thu Jul 01 2021 Luboš Uhliarik - 2.4.48-6 +- Resolves: #1932442 - "ServerTokens Full-Release" support + +* Fri Jun 25 2021 Joe Orton - 2.4.48-5 +- mod_ssl: fix loading encrypted privkeys with OpenSSL 3.0 (#1976080) + +* Fri Jun 25 2021 Joe Orton - 2.4.48-4 +- add OpenSSL v3 compatibility fixes (#1975201) + +* Wed Jun 16 2021 Mohan Boddu - 2.4.48-3 +- Rebuilt for RHEL 9 BETA for openssl 3.0 + Related: rhbz#1971065 + +* Tue Jun 08 2021 Luboš Uhliarik - 2.4.48-2 +- Resolves: #1947099 - centralizing default index.html for httpd + +* Wed Jun 02 2021 Luboš Uhliarik - 2.4.48-1 +- new version 2.4.48 +- Resolves: #1952817 - rebase to 2.4.48 + +* Wed May 26 2021 Luboš Uhliarik - 2.4.46-15 +- Resolves: #1949606 - RFE: httpd, add IP_FREEBIND support for Listen + +* Wed May 19 2021 Lubos Uhliarik - 2.4.46-14 +- Resolves: #1949969 - httpd : mod_proxy should allow to specify + Proxy-Authorization in ProxyRemote directive + +* Thu Apr 22 2021 Lubos Uhliarik - 2.4.46-13 +- Resolves: #1952546 - mod_proxy_wstunnel.html is a malformed XML + +* Fri Apr 16 2021 Mohan Boddu - 2.4.46-12 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* Tue Apr 13 2021 Lubos Uhliarik - 2.4.46-11 +- Resolves: #1947496 - [RFE] ProxyWebsocketIdleTimeout from httpd mod_proxy_wstunnel + +* Wed Mar 31 2021 Lubos Uhliarik - 2.4.46-10 +- Resolves: #1934739 - Apache trademark update - new logo + +* Mon Feb 01 2021 Lubos Uhliarik - 2.4.46-9 +- Resolves: #1914182 - RFE: CustomLog should be able to use journald + +* Tue Jan 26 2021 Fedora Release Engineering - 2.4.46-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Wed Jan 20 2021 Artem Egorenkov - 2.4.46-7 +- prevent htcacheclean from while break when first file processed + +* Thu Dec 17 2020 Joe Orton - 2.4.46-6 +- move mod_lua to a subpackage +- Recommends: both mod_lua and mod_http2 + +* Fri Nov 6 2020 Joe Orton - 2.4.46-5 +- add %%_httpd_requires to macros + +* Thu Aug 27 2020 Joe Orton - 2.4.46-4 +- use make macros (Tom Stellard) + +* Thu Aug 27 2020 Joe Orton - 2.4.46-3 +- strip /usr/bin/apxs CFLAGS further + +* Thu Aug 27 2020 Joe Orton - 2.4.46-2 +- sanitize CFLAGS used by /usr/bin/apxs by default (#1873020) +- add $libdir/httpd/build/vendor-apxs which exposes full CFLAGS +- redefine _httpd_apxs RPM macro to use vendor-apxs + +* Tue Aug 25 2020 Lubos Uhliarik - 2.4.46-1 +- new version 2.4.46 +- remove obsolete parts of this spec file +- fix systemd detection patch + +* Tue Jul 28 2020 Fedora Release Engineering - 2.4.43-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Thu Jul 09 2020 Lubos Uhliarik - 2.4.43-6 +- fix macro in mod_lua for lua 4.5 + +* Thu Jul 09 2020 Lubos Uhliarik - 2.4.43-5 +- Remove %ghosted /etc/sysconfig/httpd file (#1850082) + +* Tue Jul 7 2020 Joe Orton - 2.4.43-4 +- use gettid() directly and use it for built-in ErrorLogFormat + +* Fri Apr 17 2020 Joe Orton - 2.4.43-3 +- mod_ssl: updated coalescing filter to improve TLS efficiency + +* Fri Apr 17 2020 Joe Orton - 2.4.43-2 +- mod_ssl: fix leak in OCSP stapling code (PR 63687, r1876548) +- mod_systemd: restore descriptive startup logging + +* Tue Mar 31 2020 Lubos Uhliarik - 2.4.43-1 +- new version 2.4.43 (#1819023) + +* Wed Jan 29 2020 Fedora Release Engineering - 2.4.41-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Mon Jan 20 2020 Joe Orton - 2.4.41-12 +- mod_systemd: fix timeouts on reload w/ExtendedStatus off (#1590877) + +* Mon Jan 6 2020 Joe Orton - 2.4.41-11 +- apachectl(8): update authors + +* Sat Dec 7 2019 FeRD (Frank Dana) - 2.4.41-10 +- apachectl: Add man page for Fedora version + +* Thu Nov 21 2019 Joe Orton - 2.4.41-9 +- mod_ssl: fix request body buffering w/TLSv1.3 PHA (#1775146) + +* Wed Nov 13 2019 Joe Orton - 2.4.41-8 +- apachectl: in graceful/graceful-stop, only signal main process (#1758798) + +* Mon Nov 11 2019 Lubos Uhliarik - 2.4.41-7 +- add automatic source tarball signature verification in %prep section + +* Fri Oct 4 2019 Joe Orton - 2.4.41-6 +- mod_cgid/mod_cgi: further upstream consolidation patches + +* Thu Oct 3 2019 Joe Orton - 2.4.41-5 +- mod_proxy_balancer: fix balancer-manager XSRF check (PR 63688) + +* Wed Oct 2 2019 Joe Orton - 2.4.41-4 +- mod_cgid: possible stdout timeout handling fix (#1757683) + +* Wed Sep 25 2019 Joe Orton - 2.4.41-3 +- mod_ssl: restore dependency on /usr/bin/hostname (#1135118) + +* Thu Sep 19 2019 Stephen Gallagher - 2.4.41-2 +- Use testpage from system-logos-httpd for proper branding + +* Thu Aug 15 2019 Joe Orton - 2.4.41-1 +- update to 2.4.41 + +* Thu Jul 25 2019 Fedora Release Engineering - 2.4.39-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Tue Jul 23 2019 Joe Orton - 2.4.39-12 +- drop /var/lib/dav directory, since mod_dav_fs uses statedir + +* Wed Jul 17 2019 Joe Orton - 2.4.39-11 +- mod_cgid: use fd passing to fix script stderr handling (#1591157) + +* Mon Jul 8 2019 Joe Orton - 2.4.39-10 +- htpasswd: add SHA-256/512 support +- apachectl: restore -V/-v/-t support (#1727434) + +* Fri Jun 21 2019 Joe Orton - 2.4.39-9 +- create instance-specific StateDir in httpd@.service, instance.conf + +* Thu Jun 20 2019 Joe Orton - 2.4.39-8 +- remove superfluous ap_hack_ symbols from httpd binary +- more verbose %%check section + +* Thu Jun 13 2019 Lubos Uhliarik - 2.4.39-7 +- remove bundled mod_md module + +* Thu Jun 13 2019 Joe Orton - 2.4.39-6 +- mod_ssl: fix "httpd -L" (etc) before httpd-init.service runs + +* Wed Jun 12 2019 Joe Orton - 2.4.39-5 +- fixes for StateDir directive (upstream r1857731, r1857731) + +* Thu May 02 2019 Lubos Uhliarik - 2.4.39-4 +- httpd dependency on initscripts is unspecified (#1705188) + +* Tue Apr 9 2019 Joe Orton - 2.4.39-3 +- fix statedir symlink to point to /var/lib/httpd (#1697662) +- mod_reqtimeout: fix default values regression (PR 63325) + +* Tue Apr 02 2019 Lubos Uhliarik - 2.4.39-2 +- update to 2.4.39 + +* Thu Feb 28 2019 Joe Orton - 2.4.38-6 +- apachectl: cleanup and replace script wholesale (#1641237) + * drop "apachectl fullstatus" support + * run systemctl with --no-pager option + * implement graceful&graceful-stop by signal directly +- run "httpd -t" from legacy action script + +* Tue Feb 05 2019 Lubos Uhliarik - 2.4.38-5 +- segmentation fault fix (FIPS) + +* Tue Feb 5 2019 Joe Orton - 2.4.38-4 +- use serverroot-relative statedir, rundir by default + +* Fri Feb 01 2019 Fedora Release Engineering - 2.4.38-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Wed Jan 23 2019 Lubos Uhliarik - 2.4.38-2 +- new version 2.4.38 (#1668125) + +* Mon Jan 14 2019 Björn Esser - 2.4.37-6 +- Rebuilt for libcrypt.so.2 (#1666033) + +* Thu Nov 22 2018 Luboš Uhliarik - 2.4.37-5 +- Resolves: #1652678 - TLS connection allowed while all protocols are forbidden + +* Thu Nov 8 2018 Joe Orton - 2.4.37-4 +- add httpd.conf(5) (#1611361) + +* Wed Nov 07 2018 Luboš Uhliarik - 2.4.37-3 +- Resolves: #1647241 - fix apachectl script + +* Wed Oct 31 2018 Joe Orton - 2.4.37-2 +- add DefaultStateDir/ap_state_dir_relative() +- mod_dav_fs: use state dir for default DAVLockDB +- mod_md: use state dir for default MDStoreDir + +* Wed Oct 31 2018 Joe Orton - 2.4.37-1 +- update to 2.4.37 + +* Wed Oct 31 2018 Joe Orton - 2.4.34-11 +- add htcacheclean.service(8) man page + +* Fri Sep 28 2018 Joe Orton - 2.4.34-10 +- apachectl: don't read /etc/sysconfig/httpd + +* Tue Sep 25 2018 Joe Orton - 2.4.34-9 +- fix build if OpenSSL built w/o SSLv3 support + +* Fri Sep 21 2018 Joe Orton - 2.4.34-8 +- comment-out SSLProtocol, SSLProxyProtocol from ssl.conf in + default configuration; now follow OpenSSL system default (#1468322) + +* Fri Sep 21 2018 Joe Orton - 2.4.34-7 +- mod_ssl: follow OpenSSL protocol defaults if SSLProtocol + is not configured (Rob Crittenden, #1618371) + +* Tue Aug 28 2018 Luboš Uhliarik - 2.4.34-6 +- mod_ssl: enable SSLv3 and change behavior of "SSLProtocol All" + configuration (#1624777) + +* Tue Aug 21 2018 Joe Orton - 2.4.34-5 +- mod_ssl: further TLSv1.3 fix (#1619389) + +* Mon Aug 13 2018 Joe Orton - 2.4.34-4 +- mod_ssl: backport TLSv1.3 support changes from upstream (#1615059) + +* Fri Jul 20 2018 Joe Orton - 2.4.34-3 +- mod_ssl: fix OCSP regression (upstream r1555631) + +* Wed Jul 18 2018 Joe Orton - 2.4.34-2 +- update Obsoletes for mod_proxy_uswgi (#1599113) + +* Wed Jul 18 2018 Joe Orton - 2.4.34-1 +- update to 2.4.34 (#1601160) + +* Mon Jul 16 2018 Joe Orton - 2.4.33-10 +- don't block on service try-restart in posttrans scriptlet +- add Lua-based /server-status example page to docs +- obsoletes: and provides: for mod_proxy_uswgi (#1599113) + +* Fri Jul 13 2018 Fedora Release Engineering - 2.4.33-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Fri Jul 6 2018 Joe Orton - 2.4.33-8 +- add per-request memory leak fix (upstream r1833014) + +* Fri Jul 6 2018 Joe Orton - 2.4.33-7 +- mod_ssl: add PKCS#11 cert/key support (Anderson Sasaki) + +* Tue Jun 12 2018 Joe Orton - 2.4.33-6 +- mod_systemd: show bound ports in status and log to journal + at startup. + +* Thu Apr 19 2018 Joe Orton - 2.4.33-5 +- add httpd@.service; update httpd.service(8) and add new stub + +* Mon Apr 16 2018 Joe Orton - 2.4.33-4 +- mod_md: change hard-coded default MdStoreDir to state/md (#1563846) + +* Thu Apr 12 2018 Joe Orton - 2.4.33-3 +- mod_ssl: drop implicit 'SSLEngine on' for vhost w/o certs (#1564537) + +* Fri Mar 30 2018 Adam Williamson - 2.4.33-2 +- Exclude mod_md config file from main package (#1562413) + +* Wed Mar 28 2018 Joe Orton - 2.4.33-1 +- rebase to 2.4.33 (#1560174) +- add mod_md subpackage; load mod_proxy_uwsgi by default + +* Mon Mar 05 2018 Jitka Plesnikova - 2.4.29-8 +- Rebuilt with brotli 1.0.3 + +* Mon Feb 26 2018 Joe Orton - 2.4.29-7 +- simplify liblua detection in configure + +* Wed Feb 07 2018 Fedora Release Engineering - 2.4.29-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Sat Jan 27 2018 Joe Orton - 2.4.29-5 +- link mod_lua against -lcrypt (#1538992) + +* Fri Jan 26 2018 Paul Howarth - 2.4.29-4 +- Rebuild with updated flags to work around compiler issues on i686 + (#1538648, #1538693) + +* Sat Jan 20 2018 Björn Esser - 2.4.29-3 +- Rebuilt for switch to libxcrypt + +* Thu Nov 23 2017 Joe Orton - 2.4.29-2 +- build and load mod_brotli + +* Wed Oct 25 2017 Luboš Uhliarik - 2.4.29-1 +- new version 2.4.29 + +* Tue Oct 10 2017 Joe Orton - 2.4.28-3 +- drop obsolete Obsoletes +- update docs, Summary +- trim %%changelog + +* Tue Oct 10 2017 Patrick Uiterwijk - 2.4.28-2 +- Backport patch for fixing ticket key usage + +* Fri Oct 06 2017 Luboš Uhliarik - 2.4.28-1 +- new version 2.4.28 + +* Tue Oct 3 2017 Joe Orton - 2.4.27-14 +- add notes on enabling httpd_graceful_shutdown boolean for prefork + +* Fri Sep 22 2017 Joe Orton - 2.4.27-13 +- drop Requires(post) for mod_ssl + +* Fri Sep 22 2017 Joe Orton - 2.4.27-12 +- better error handling in httpd-ssl-gencerts (#1494556) + +* Thu Sep 21 2017 Stephen Gallagher - 2.4.27-11 +- Require sscg 2.2.0 for creating service and CA certificates together + +* Thu Sep 21 2017 Jeroen van Meeuwen - 2.4.27-10 +- Address CVE-2017-9798 by applying patch from upstream (#1490344) + +* Thu Sep 21 2017 Joe Orton - 2.4.27-9 +- use sscg defaults; append CA cert to generated cert +- document httpd-init.service in httpd-init.service(8) + +* Wed Sep 20 2017 Stephen Gallagher - 2.4.27-8.1 +- Generate SSL certificates on service start, not %%posttrans + +* Tue Sep 19 2017 Joe Orton - 2.4.27-8 +- move httpd.service.d, httpd.socket.d dirs to -filesystem + +* Wed Sep 13 2017 Joe Orton - 2.4.27-7 +- add new content-length filter (upstream PR 61222) + +* Wed Aug 02 2017 Fedora Release Engineering - 2.4.27-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 2.4.27-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue Jul 18 2017 Joe Orton - 2.4.27-4 +- update mod_systemd (r1802251) + +* Mon Jul 17 2017 Joe Orton - 2.4.27-3 +- switch to event by default for Fedora 27 and later (#1471708) + +* Wed Jul 12 2017 Luboš Uhliarik - 2.4.27-2 +- Resolves: #1469959 - httpd update cleaned out /etc/sysconfig + +* Mon Jul 10 2017 Luboš Uhliarik - 2.4.27-1 +- new version 2.4.27 + +* Fri Jun 30 2017 Joe Orton - 2.4.26-2 +- mod_proxy_fcgi: fix further regressions (PR 61202) + +* Mon Jun 19 2017 Luboš Uhliarik - 2.4.26-1 +- new version 2.4.26 + +* Mon Jun 5 2017 Joe Orton - 2.4.25-10 +- move unit man pages to section 8, add as Documentation= in units + +* Fri May 19 2017 Joe Orton - 2.4.25-9 +- add httpd.service(5) and httpd.socket(5) man pages + +* Tue May 16 2017 Joe Orton - 2.4.25-8 +- require mod_http2, now packaged separately + +* Wed Mar 29 2017 Luboš Uhliarik - 2.4.25-7 +- Resolves: #1397243 - Backport Apache Bug 53098 - mod_proxy_ajp: + patch to set worker secret passed to tomcat + +* Tue Mar 28 2017 Luboš Uhliarik - 2.4.25-6 +- Resolves: #1434916 - httpd.service: Failed with result timeout + +* Fri Mar 24 2017 Joe Orton - 2.4.25-5 +- link only httpd, not support/* against -lselinux -lsystemd + +* Fri Feb 10 2017 Fedora Release Engineering - 2.4.25-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Jan 12 2017 Joe Orton - 2.4.25-3 +- mod_watchdog: restrict thread lifetime (#1410883) + +* Thu Dec 22 2016 Luboš Uhliarik - 2.4.25-2 +- Resolves: #1358875 - require nghttp2 >= 1.5.0 + +* Thu Dec 22 2016 Luboš Uhliarik - 2.4.25-1 +- new version 2.4.25 + +* Mon Dec 05 2016 Luboš Uhliarik - 2.4.23-7 +- Resolves: #1401530 - CVE-2016-8740 httpd: Incomplete handling of + LimitRequestFields directive in mod_http2 + +* Mon Nov 14 2016 Joe Orton - 2.4.23-6 +- fix build with OpenSSL 1.1 (#1392900) +- fix typos in ssl.conf (josef randinger, #1379407) + +* Wed Nov 2 2016 Joe Orton - 2.4.23-5 +- no longer package /etc/sysconfig/httpd +- synch ssl.conf with upstream + +* Mon Jul 18 2016 Joe Orton - 2.4.23-4 +- add security fix for CVE-2016-5387 + +* Thu Jul 7 2016 Joe Orton - 2.4.23-3 +- load mod_watchdog by default (#1353582) + +* Thu Jul 7 2016 Joe Orton - 2.4.23-2 +- restore build of mod_proxy_fdpass (#1325883) +- improve check tests to catch configured-but-not-built modules + +* Thu Jul 7 2016 Joe Orton - 2.4.23-1 +- update to 2.4.23 (#1325883, #1353203) +- load mod_proxy_hcheck +- recommend use of "systemctl edit" in httpd.service + +* Thu Apr 7 2016 Joe Orton - 2.4.18-6 +- have "apachectl graceful" start httpd if not running, per man page + +* Wed Apr 6 2016 Joe Orton - 2.4.18-5 +- use redirects for lang-specific /manual/ URLs + +* Fri Mar 18 2016 Joe Orton - 2.4.18-4 +- fix welcome page HTML validity (Ville Skyttä) + +* Fri Mar 18 2016 Joe Orton - 2.4.18-3 +- remove httpd pre script (duplicate of httpd-filesystem's) +- in httpd-filesystem pre script, create group/user iff non-existent + +* Wed Feb 03 2016 Fedora Release Engineering - 2.4.18-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Dec 14 2015 Jan Kaluza - 2.4.18-1 +- update to new version 2.4.18 + +* Wed Dec 9 2015 Joe Orton - 2.4.17-4 +- re-enable mod_asis due to popular demand (#1284315) + +* Mon Oct 26 2015 Jan Kaluza - 2.4.17-3 +- fix crash when using -X argument (#1272234) + +* Wed Oct 14 2015 Jan Kaluza - 2.4.17-2 +- rebase socket activation patch to 2.4.17 + +* Tue Oct 13 2015 Joe Orton - 2.4.17-1 +- update to 2.4.17 (#1271224) +- build, load mod_http2 +- don't build mod_asis, mod_file_cache +- load mod_cache_socache, mod_proxy_wstunnel by default +- check every built mod_* is configured +- synch ssl.conf with upstream; disable SSLv3 by default + +* Wed Jul 15 2015 Jan Kaluza - 2.4.12-4 +- update to 2.4.16 + +* Tue Jul 7 2015 Joe Orton - 2.4.12-3 +- mod_ssl: use "localhost" in the dummy SSL cert if len(FQDN) > 59 chars + +* Wed Jun 17 2015 Fedora Release Engineering - 2.4.12-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Fri Mar 27 2015 Jan Kaluza - 2.4.12-1 +- update to 2.4.12 + +* Tue Mar 24 2015 Jan Kaluza - 2.4.10-17 +- fix compilation with lua-5.3 + +* Tue Mar 24 2015 Jan Kaluza - 2.4.10-16 +- remove filter for auto-provides of httpd modules, it is not needed since F20 + +* Wed Dec 17 2014 Jan Kaluza - 2.4.10-15 +- core: fix bypassing of mod_headers rules via chunked requests (CVE-2013-5704) +- mod_cache: fix NULL pointer dereference on empty Content-Type (CVE-2014-3581) +- mod_proxy_fcgi: fix a potential crash with long headers (CVE-2014-3583) +- mod_lua: fix handling of the Require line when a LuaAuthzProvider is used + in multiple Require directives with different arguments (CVE-2014-8109) + +* Tue Oct 14 2014 Joe Orton - 2.4.10-14 +- require apr-util 1.5.x + +* Thu Sep 18 2014 Jan Kaluza - 2.4.10-13 +- use NoDelay and DeferAcceptSec in httpd.socket + +* Mon Sep 08 2014 Jan Kaluza - 2.4.10-12 +- increase suexec minimum acceptable uid/gid to 1000 (#1136391) + +* Wed Sep 03 2014 Jan Kaluza - 2.4.10-11 +- fix hostname requirement and conflict with openssl-libs + +* Mon Sep 01 2014 Jan Kaluza - 2.4.10-10 +- use KillMode=mixed in httpd.service (#1135122) + +* Fri Aug 29 2014 Joe Orton - 2.4.10-9 +- set vstring based on /etc/os-release (Pat Riehecky, #1114539) + +* Fri Aug 29 2014 Joe Orton - 2.4.10-8 +- pull in httpd-filesystem as Requires(pre) (#1128328) +- fix cipher selection in default ssl.conf, depend on new OpenSSL (#1134348) +- require hostname for mod_ssl post script (#1135118) + +* Fri Aug 22 2014 Jan Kaluza - 2.4.10-7 +- mod_systemd: updated to the latest version +- use -lsystemd instead of -lsystemd-daemon (#1125084) +- fix possible crash in SIGINT handling (#958934) + +* Thu Aug 21 2014 Joe Orton - 2.4.10-6 +- mod_ssl: treat "SSLCipherSuite PROFILE=..." as special (#1109119) +- switch default ssl.conf to use PROFILE=SYSTEM (#1109119) + +* Sat Aug 16 2014 Fedora Release Engineering - 2.4.10-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Fri Aug 15 2014 Jan Kaluza - 2.4.10-4 +- add /usr/bin/useradd dependency to -filesystem requires + +* Thu Aug 14 2014 Jan Kaluza - 2.4.10-3 +- fix creating apache user in pre script (#1128328) + +* Thu Jul 31 2014 Joe Orton - 2.4.10-2 +- enable mod_request by default for mod_auth_form +- move disabled-by-default modules from 00-base.conf to 00-optional.conf + +* Mon Jul 21 2014 Joe Orton - 2.4.10-1 +- update to 2.4.10 +- expand variables in docdir example configs + +* Tue Jul 08 2014 Jan Kaluza - 2.4.9-8 +- add support for systemd socket activation (#1111648) + +* Mon Jul 07 2014 Jan Kaluza - 2.4.9-7 +- remove conf.modules.d from httpd-filesystem subpackage (#1081453) + +* Mon Jul 07 2014 Jan Kaluza - 2.4.9-6 +- add httpd-filesystem subpackage (#1081453) + +* Fri Jun 20 2014 Joe Orton - 2.4.9-5 +- mod_ssl: don't use the default OpenSSL cipher suite in ssl.conf (#1109119) + +* Sat Jun 07 2014 Fedora Release Engineering - 2.4.9-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Fri Mar 28 2014 Jan Kaluza - 2.4.9-3 +- add support for SetHandler + proxy (#1078970) + +* Thu Mar 27 2014 Jan Kaluza - 2.4.9-2 +- move macros from /etc/rpm to macros.d (#1074277) +- remove unused patches + +* Mon Mar 17 2014 Jan Kaluza - 2.4.9-1 +- update to 2.4.9 + +* Fri Feb 28 2014 Joe Orton - 2.4.7-6 +- use 2048-bit RSA key with SHA-256 signature in dummy certificate + +* Fri Feb 28 2014 Stephen Gallagher 2.4.7-5 +- Create drop directory for systemd snippets + +* Thu Feb 27 2014 Jan Kaluza - 2.4.7-4 +- remove provides of old MMN, because it contained double-dash (#1068851) + +* Thu Feb 20 2014 Jan Kaluza - 2.4.7-3 +- fix graceful restart using legacy actions + +* Thu Dec 12 2013 Joe Orton - 2.4.7-2 +- conflict with pre-1.5.0 APR +- fix sslsninotreq patch + +* Wed Nov 27 2013 Joe Orton - 2.4.7-1 +- update to 2.4.7 (#1034071) + +* Fri Nov 22 2013 Joe Orton - 2.4.6-10 +- switch to requiring system-logos-httpd (#1031288) + +* Tue Nov 12 2013 Joe Orton - 2.4.6-9 +- change mmnisa to drop "-" altogether + +* Tue Nov 12 2013 Joe Orton - 2.4.6-8 +- drop ambiguous invalid "-" in RHS of httpd-mmn Provide, keeping old Provide + for transition + +* Fri Nov 1 2013 Jan Kaluza - 2.4.6-7 +- systemd: use {MAINPID} notation to ensure /bin/kill has always the second arg + +* Thu Oct 31 2013 Joe Orton - 2.4.6-6 +- mod_ssl: allow SSLEngine to override Listen-based default (r1537535) + +* Thu Oct 24 2013 Jan kaluza - 2.4.6-5 +- systemd: send SIGWINCH signal without httpd -k in ExecStop + +* Mon Oct 21 2013 Joe Orton - 2.4.6-4 +- load mod_macro by default (#998452) +- add README to conf.modules.d +- mod_proxy_http: add possible fix for threading issues (r1534321) +- core: add fix for truncated output with CGI scripts (r1530793) + +* Thu Oct 10 2013 Jan Kaluza - 2.4.6-3 +- require fedora-logos-httpd (#1009162) + +* Wed Jul 31 2013 Jan Kaluza - 2.4.6-2 +- revert fix for dumping vhosts twice + +* Mon Jul 22 2013 Joe Orton - 2.4.6-1 +- update to 2.4.6 +- mod_ssl: use revised NPN API (r1487772) + +* Thu Jul 11 2013 Jan Kaluza - 2.4.4-12 +- mod_unique_id: replace use of hostname + pid with PRNG output (#976666) +- apxs: mention -p option in manpage + +* Tue Jul 2 2013 Joe Orton - 2.4.4-11 +- add patch for aarch64 (Dennis Gilmore, #925558) + +* Mon Jul 1 2013 Joe Orton - 2.4.4-10 +- remove duplicate apxs man page from httpd-tools + +* Mon Jun 17 2013 Joe Orton - 2.4.4-9 +- remove zombie dbmmanage script + +* Fri May 31 2013 Jan Kaluza - 2.4.4-8 +- return 400 Bad Request on malformed Host header + +* Fri May 24 2013 Jan Kaluza - 2.4.4-7 +- ignore /etc/sysconfig/httpd and document systemd way of setting env variables + in this file + +* Mon May 20 2013 Jan Kaluza - 2.4.4-6 +- htpasswd/htdbm: fix hash generation bug (#956344) +- do not dump vhosts twice in httpd -S output (#928761) +- mod_cache: fix potential crash caused by uninitialized variable (#954109) + +* Thu Apr 18 2013 Jan Kaluza - 2.4.4-5 +- execute systemctl reload as result of apachectl graceful +- mod_ssl: ignore SNI hints unless required by config +- mod_cache: forward-port CacheMaxExpire "hard" option +- mod_ssl: fall back on another module's proxy hook if mod_ssl proxy + is not configured. + +* Tue Apr 16 2013 Jan Kaluza - 2.4.4-4 +- fix service file to not send SIGTERM after ExecStop (#906321, #912288) + +* Tue Mar 26 2013 Jan Kaluza - 2.4.4-3 +- protect MIMEMagicFile with IfModule (#893949) + +* Tue Feb 26 2013 Joe Orton - 2.4.4-2 +- really package mod_auth_form in mod_session (#915438) + +* Tue Feb 26 2013 Joe Orton - 2.4.4-1 +- update to 2.4.4 +- fix duplicate ownership of mod_session config (#914901) + +* Fri Feb 22 2013 Joe Orton - 2.4.3-17 +- add mod_session subpackage, move mod_auth_form there (#894500) + +* Thu Feb 14 2013 Fedora Release Engineering - 2.4.3-16 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Tue Jan 8 2013 Joe Orton - 2.4.3-15 +- add systemd service for htcacheclean + +* Tue Nov 13 2012 Joe Orton - 2.4.3-14 +- drop patch for r1344712 + +* Tue Nov 13 2012 Joe Orton - 2.4.3-13 +- filter mod_*.so auto-provides (thanks to rcollet) +- pull in syslog logging fix from upstream (r1344712) + +* Fri Oct 26 2012 Joe Orton - 2.4.3-12 +- rebuild to pick up new apr-util-ldap + +* Tue Oct 23 2012 Joe Orton - 2.4.3-11 +- rebuild + +* Wed Oct 3 2012 Joe Orton - 2.4.3-10 +- pull upstream patch r1392850 in addition to r1387633 + +* Mon Oct 1 2012 Joe Orton - 2.4.3-9 +- define PLATFORM in os.h using vendor string + +* Mon Oct 1 2012 Joe Orton - 2.4.3-8 +- use systemd script unconditionally (#850149) + +* Mon Oct 1 2012 Joe Orton - 2.4.3-7 +- use systemd scriptlets if available (#850149) +- don't run posttrans restart if /etc/sysconfig/httpd-disable-posttrans exists + +* Mon Oct 01 2012 Jan Kaluza - 2.4.3-6 +- use systemctl from apachectl (#842736) + +* Wed Sep 19 2012 Joe Orton - 2.4.3-5 +- fix some error log spam with graceful-stop (r1387633) +- minor mod_systemd tweaks + +* Thu Sep 13 2012 Joe Orton - 2.4.3-4 +- use IncludeOptional for conf.d/*.conf inclusion + +* Fri Sep 07 2012 Jan Kaluza - 2.4.3-3 +- adding mod_systemd to integrate with systemd better + +* Tue Aug 21 2012 Joe Orton - 2.4.3-2 +- mod_ssl: add check for proxy keypair match (upstream r1374214) + +* Tue Aug 21 2012 Joe Orton - 2.4.3-1 +- update to 2.4.3 (#849883) +- own the docroot (#848121) + +* Mon Aug 6 2012 Joe Orton - 2.4.2-23 +- add mod_proxy fixes from upstream (r1366693, r1365604) + +* Thu Jul 19 2012 Fedora Release Engineering - 2.4.2-22 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri Jul 6 2012 Joe Orton - 2.4.2-21 +- drop explicit version requirement on initscripts + +* Thu Jul 5 2012 Joe Orton - 2.4.2-20 +- mod_ext_filter: fix error_log warnings + +* Mon Jul 2 2012 Joe Orton - 2.4.2-19 +- support "configtest" and "graceful" as initscripts "legacy actions" + +* Fri Jun 8 2012 Joe Orton - 2.4.2-18 +- avoid use of "core" GIF for a "core" directory (#168776) +- drop use of "syslog.target" in systemd unit file + +* Thu Jun 7 2012 Joe Orton - 2.4.2-17 +- use _unitdir for systemd unit file +- use /run in unit file, ssl.conf + +* Thu Jun 7 2012 Joe Orton - 2.4.2-16 +- mod_ssl: fix NPN patch merge + +* Wed Jun 6 2012 Joe Orton - 2.4.2-15 +- move tmpfiles.d fragment into /usr/lib per new guidelines +- package /run/httpd not /var/run/httpd +- set runtimedir to /run/httpd likewise + +* Wed Jun 6 2012 Joe Orton - 2.4.2-14 +- fix htdbm/htpasswd crash on crypt() failure (#818684) + +* Wed Jun 6 2012 Joe Orton - 2.4.2-13 +- pull fix for NPN patch from upstream (r1345599) + +* Thu May 31 2012 Joe Orton - 2.4.2-12 +- update suexec patch to use LOG_AUTHPRIV facility + +* Thu May 24 2012 Joe Orton - 2.4.2-11 +- really fix autoindex.conf (thanks to remi@) + +* Thu May 24 2012 Joe Orton - 2.4.2-10 +- fix autoindex.conf to allow symlink to poweredby.png + +* Wed May 23 2012 Joe Orton - 2.4.2-9 +- suexec: use upstream version of patch for capability bit support + +* Wed May 23 2012 Joe Orton - 2.4.2-8 +- suexec: use syslog rather than suexec.log, drop dac_override capability + +* Tue May 1 2012 Joe Orton - 2.4.2-7 +- mod_ssl: add TLS NPN support (r1332643, #809599) + +* Tue May 1 2012 Joe Orton - 2.4.2-6 +- add BR on APR >= 1.4.0 + +* Fri Apr 27 2012 Joe Orton - 2.4.2-5 +- use systemctl from logrotate (#221073) + +* Fri Apr 27 2012 Joe Orton - 2.4.2-4 +- pull from upstream: + * use TLS close_notify alert for dummy_connection (r1326980+) + * cleanup symbol exports (r1327036+) + +* Fri Apr 20 2012 Joe Orton - 2.4.2-3 +- really fix restart + +* Fri Apr 20 2012 Joe Orton - 2.4.2-2 +- tweak default ssl.conf +- fix restart handling (#814645) +- use graceful restart by default + +* Wed Apr 18 2012 Jan Kaluza - 2.4.2-1 +- update to 2.4.2 + +* Fri Mar 23 2012 Joe Orton - 2.4.1-6 +- fix macros + +* Fri Mar 23 2012 Joe Orton - 2.4.1-5 +- add _httpd_moddir to macros + +* Tue Mar 13 2012 Joe Orton - 2.4.1-4 +- fix symlink for poweredby.png +- fix manual.conf + +* Tue Mar 13 2012 Joe Orton - 2.4.1-3 +- add mod_proxy_html subpackage (w/mod_proxy_html + mod_xml2enc) +- move mod_ldap, mod_authnz_ldap to mod_ldap subpackage + +* Tue Mar 13 2012 Joe Orton - 2.4.1-2 +- clean docroot better +- ship proxy, ssl directories within /var/cache/httpd +- default config: + * unrestricted access to (only) /var/www + * remove (commented) Mutex, MaxRanges, ScriptSock + * split autoindex config to conf.d/autoindex.conf +- ship additional example configs in docdir + +* Tue Mar 6 2012 Joe Orton - 2.4.1-1 +- update to 2.4.1 +- adopt upstream default httpd.conf (almost verbatim) +- split all LoadModules to conf.modules.d/*.conf +- include conf.d/*.conf at end of httpd.conf +- trim %%changelog