Upstream release: 2.4.37-43.module+el8.5.0+14370+51c6d843.2
This commit is contained in:
parent
5897347d31
commit
3c6e15b921
68
00-base.conf
Normal file
68
00-base.conf
Normal file
@ -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 brotli_module modules/mod_brotli.so
|
||||
LoadModule cache_module modules/mod_cache.so
|
||||
LoadModule cache_disk_module modules/mod_cache_disk.so
|
||||
LoadModule cache_socache_module modules/mod_cache_socache.so
|
||||
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_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
|
||||
|
3
00-dav.conf
Normal file
3
00-dav.conf
Normal file
@ -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
|
1
00-lua.conf
Normal file
1
00-lua.conf
Normal file
@ -0,0 +1 @@
|
||||
LoadModule lua_module modules/mod_lua.so
|
23
00-mpm.conf
Normal file
23
00-mpm.conf
Normal file
@ -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
|
18
00-optional.conf
Normal file
18
00-optional.conf
Normal file
@ -0,0 +1,18 @@
|
||||
#
|
||||
# This file lists modules included with the Apache HTTP Server
|
||||
# which are not enabled by default.
|
||||
#
|
||||
|
||||
#LoadModule asis_module modules/mod_asis.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
|
18
00-proxy.conf
Normal file
18
00-proxy.conf
Normal file
@ -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
|
3
00-proxyhtml.conf
Normal file
3
00-proxyhtml.conf
Normal file
@ -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
|
1
00-ssl.conf
Normal file
1
00-ssl.conf
Normal file
@ -0,0 +1 @@
|
||||
LoadModule ssl_module modules/mod_ssl.so
|
2
00-systemd.conf
Normal file
2
00-systemd.conf
Normal file
@ -0,0 +1,2 @@
|
||||
# This file configures systemd module:
|
||||
LoadModule systemd_module modules/mod_systemd.so
|
14
01-cgi.conf
Normal file
14
01-cgi.conf
Normal file
@ -0,0 +1,14 @@
|
||||
# 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.
|
||||
|
||||
<IfModule mpm_worker_module>
|
||||
LoadModule cgid_module modules/mod_cgid.so
|
||||
</IfModule>
|
||||
<IfModule mpm_event_module>
|
||||
LoadModule cgid_module modules/mod_cgid.so
|
||||
</IfModule>
|
||||
<IfModule mpm_prefork_module>
|
||||
LoadModule cgi_module modules/mod_cgi.so
|
||||
</IfModule>
|
||||
|
3
01-ldap.conf
Normal file
3
01-ldap.conf
Normal file
@ -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
|
6
01-session.conf
Normal file
6
01-session.conf
Normal file
@ -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
|
5
10-listen443.conf
Normal file
5
10-listen443.conf
Normal file
@ -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
|
9
README.confd
Normal file
9
README.confd
Normal file
@ -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.
|
10
README.confmod
Normal file
10
README.confmod
Normal file
@ -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.
|
2
action-configtest.sh
Normal file
2
action-configtest.sh
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
exec /sbin/apachectl configtest "$@"
|
2
action-graceful.sh
Normal file
2
action-graceful.sh
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
exec /sbin/apachectl graceful "$@"
|
BIN
apache-poweredby.png
Normal file
BIN
apache-poweredby.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
24
config.layout
Normal file
24
config.layout
Normal file
@ -0,0 +1,24 @@
|
||||
# Layout used in Fedora httpd packaging.
|
||||
<Layout Fedora>
|
||||
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
|
||||
</Layout>
|
11
htcacheclean.service
Normal file
11
htcacheclean.service
Normal file
@ -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
|
123
htcacheclean.service.xml
Normal file
123
htcacheclean.service.xml
Normal file
@ -0,0 +1,123 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
|
||||
]>
|
||||
<!--
|
||||
Copyright 2018 Red Hat, Inc.
|
||||
|
||||
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 overning permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<title>htcacheclean systemd unit</title>
|
||||
<productname>httpd</productname>
|
||||
<author><contrib>Author</contrib><surname>Orton</surname><firstname>Joe</firstname><email>jorton@redhat.com</email></author>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>htcacheclean.service</refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>htcacheclean.service</refname>
|
||||
<refpurpose>htcacheclean unit file for systemd</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<para>
|
||||
<filename>/usr/lib/systemd/system/htcacheclean.service</filename>
|
||||
</para>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para>This manual page describes the <command>systemd</command>
|
||||
unit file for the <command>htcacheclean</command> daemon. This
|
||||
unit file provides a service which runs
|
||||
<command>htcacheclean</command> in daemon mode,
|
||||
periodically cleaning the disk cache root to ensure disk space
|
||||
usage is within configured limits.</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Options</title>
|
||||
|
||||
<para>The service is configured by configuration file
|
||||
<filename>/etc/sysconfig/htcacheclean</filename>. The following
|
||||
variables are used, following standard <command>systemd</command>
|
||||
<varname>EnvironmentFile=</varname> syntax:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><varname>INTERVAL=</varname></term>
|
||||
|
||||
<listitem><para>Sets the interval between cache clean runs, in
|
||||
minutes. By default this is configured as
|
||||
<emphasis>15</emphasis>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>CACHE_ROOT=</varname></term>
|
||||
|
||||
<listitem><para>Sets the directory name used for the cache
|
||||
root. By default this is configured as
|
||||
<filename>/var/cache/httpd/proxy</filename>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>LIMIT=</varname></term>
|
||||
|
||||
<listitem><para>Sets the total disk cache space limit, in
|
||||
bytes. Use a <emphasis>K</emphasis> or <emphasis>M</emphasis>
|
||||
suffix to signify kilobytes or megabytes. By default this is
|
||||
set to <emphasis>100M</emphasis>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>OPTIONS=</varname></term>
|
||||
|
||||
<listitem><para>Any other options to pass to
|
||||
<command>htcacheclean</command>.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Files</title>
|
||||
|
||||
<para><filename>/usr/lib/systemd/system/htcacheclean.service</filename>,
|
||||
<filename>/etc/sysconfig/htcacheclean</filename></para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See also</title>
|
||||
|
||||
<para>
|
||||
<citerefentry><refentrytitle>htcacheclean</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>httpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>httpd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
|
||||
<!-- LocalWords: systemd httpd htcacheclean
|
||||
-->
|
16
htcacheclean.sysconf
Normal file
16
htcacheclean.sysconf
Normal file
@ -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=
|
58
httpd-2.4.28-apxs.patch
Normal file
58
httpd-2.4.28-apxs.patch
Normal file
@ -0,0 +1,58 @@
|
||||
diff --git a/support/apxs.in b/support/apxs.in
|
||||
index ad1287f..efcfcf6 100644
|
||||
--- a/support/apxs.in
|
||||
+++ b/support/apxs.in
|
||||
@@ -25,7 +25,18 @@ package apxs;
|
||||
|
||||
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("$installbuilddir/config_vars.mk",\%config_vars);
|
||||
|
||||
# read the configuration variables once
|
||||
@@ -275,7 +286,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);
|
||||
|
||||
@@ -453,11 +464,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);
|
||||
}
|
||||
|
||||
@@ -672,8 +683,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
|
29
httpd-2.4.28-icons.patch
Normal file
29
httpd-2.4.28-icons.patch
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
- Fix config for /icons/ dir to allow symlink to poweredby.png
|
||||
- Avoid using coredump GIF for a directory called "core"
|
||||
|
||||
Upstream-Status: vendor specific patch
|
||||
|
||||
diff --git a/docs/conf/extra/httpd-autoindex.conf.in b/docs/conf/extra/httpd-autoindex.conf.in
|
||||
index 51b02ed..dd6f2c6 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@/"
|
||||
|
||||
<Directory "@exp_iconsdir@">
|
||||
- Options Indexes MultiViews
|
||||
+ Options Indexes MultiViews FollowSymlinks
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
@@ -53,7 +53,8 @@ AddIcon /icons/dvi.gif .dvi
|
||||
AddIcon /icons/uuencoded.gif .uu
|
||||
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
|
||||
AddIcon /icons/tex.gif .tex
|
||||
-AddIcon /icons/bomb.gif core
|
||||
+AddIcon /icons/bomb.gif /core
|
||||
+AddIcon /icons/bomb.gif */core.*
|
||||
|
||||
AddIcon /icons/back.gif ..
|
||||
AddIcon /icons/hand.right.gif README
|
81
httpd-2.4.28-r1811831.patch
Normal file
81
httpd-2.4.28-r1811831.patch
Normal file
@ -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));
|
300
httpd-2.4.28-socket-activation.patch
Normal file
300
httpd-2.4.28-socket-activation.patch
Normal file
@ -0,0 +1,300 @@
|
||||
diff --git a/server/listen.c b/server/listen.c
|
||||
index a8e9e6f..1a6c1d3 100644
|
||||
--- a/server/listen.c
|
||||
+++ b/server/listen.c
|
||||
@@ -34,6 +34,10 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+#include <systemd/sd-daemon.h>
|
||||
+#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);
|
||||
}
|
||||
|
16
httpd-2.4.28-statements-comment.patch
Normal file
16
httpd-2.4.28-statements-comment.patch
Normal file
@ -0,0 +1,16 @@
|
||||
diff --git a/modules/aaa/mod_access_compat.c b/modules/aaa/mod_access_compat.c
|
||||
index 3023803..2edf440 100644
|
||||
--- a/modules/aaa/mod_access_compat.c
|
||||
+++ b/modules/aaa/mod_access_compat.c
|
||||
@@ -152,6 +152,11 @@ static const char *allow_cmd(cmd_parms *cmd, void *dv, const char *from,
|
||||
if (strcasecmp(from, "from"))
|
||||
return "allow and deny must be followed by 'from'";
|
||||
|
||||
+ s = ap_strchr(where, '#');
|
||||
+ if (s) {
|
||||
+ *s = '\0';
|
||||
+ }
|
||||
+
|
||||
a = (allowdeny *) apr_array_push(cmd->info ? d->allows : d->denys);
|
||||
a->x.from = where;
|
||||
a->limited = cmd->limited;
|
22
httpd-2.4.32-export.patch
Normal file
22
httpd-2.4.32-export.patch
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
There is no need to "suck in" the apr/apr-util symbols when using
|
||||
a shared libapr{,util}, it just bloats the symbol table; so don't.
|
||||
|
||||
Upstream-HEAD: needed
|
||||
Upstream-2.0: omit
|
||||
Upstream-Status: EXPORT_DIRS change is conditional on using shared apr
|
||||
|
||||
diff --git a/server/Makefile.in b/server/Makefile.in
|
||||
index 1fa3344..f635d76 100644
|
||||
--- a/server/Makefile.in
|
||||
+++ b/server/Makefile.in
|
||||
@@ -60,9 +60,6 @@ export_files:
|
||||
ls $$dir/*.h ; \
|
||||
done; \
|
||||
echo "$(top_srcdir)/server/mpm_fdqueue.h"; \
|
||||
- for dir in $(EXPORT_DIRS_APR); do \
|
||||
- ls $$dir/ap[ru].h $$dir/ap[ru]_*.h 2>/dev/null; \
|
||||
- done; \
|
||||
) | sed -e s,//,/,g | sort -u > $@
|
||||
|
||||
exports.c: export_files
|
19
httpd-2.4.34-CVE-2019-9511-and-9516-and-9517.patch
Normal file
19
httpd-2.4.34-CVE-2019-9511-and-9516-and-9517.patch
Normal file
@ -0,0 +1,19 @@
|
||||
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c
|
||||
index 16e39be..2543693 100644
|
||||
--- a/server/mpm/event/event.c
|
||||
+++ b/server/mpm/event/event.c
|
||||
@@ -1111,10 +1111,11 @@ read_request:
|
||||
"network write failure in core output filter");
|
||||
cs->pub.state = CONN_STATE_LINGER;
|
||||
}
|
||||
- else if (c->data_in_output_filters) {
|
||||
+ else if (c->data_in_output_filters ||
|
||||
+ cs->pub.sense == CONN_SENSE_WANT_READ) {
|
||||
/* Still in WRITE_COMPLETION_STATE:
|
||||
- * Set a write timeout for this connection, and let the
|
||||
- * event thread poll for writeability.
|
||||
+ * Set a read/write timeout for this connection, and let the
|
||||
+ * event thread poll for read/writeability.
|
||||
*/
|
||||
cs->queue_timestamp = apr_time_now();
|
||||
notify_suspend(cs);
|
113
httpd-2.4.35-apachectl.patch
Normal file
113
httpd-2.4.35-apachectl.patch
Normal file
@ -0,0 +1,113 @@
|
||||
diff --git a/docs/man/apachectl.8 b/docs/man/apachectl.8
|
||||
index 870a048..32d3ee5 100644
|
||||
--- a/docs/man/apachectl.8
|
||||
+++ b/docs/man/apachectl.8
|
||||
@@ -74,7 +74,7 @@ Restarts the Apache httpd daemon\&. If the daemon is not running, it is started\
|
||||
Displays a full status report from mod_status\&. For this to work, you need to have mod_status enabled on your server and a text-based browser such as \fBlynx\fR available on your system\&. The URL used to access the status report can be set by editing the \fBSTATUSURL\fR variable in the script\&.
|
||||
.TP
|
||||
\fBstatus\fR
|
||||
-Displays a brief status report\&. Similar to the \fBfullstatus\fR option, except that the list of requests currently being served is omitted\&.
|
||||
+Displays a brief status report using systemd\&.
|
||||
.TP
|
||||
\fBgraceful\fR
|
||||
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 command automatically checks the configuration files as in \fBconfigtest\fR before initiating the restart to make sure Apache doesn't die\&. This is equivalent to \fBapachectl -k graceful\fR\&.
|
||||
diff --git a/support/apachectl.in b/support/apachectl.in
|
||||
index 3281c2e..8ce6f2b 100644
|
||||
--- a/support/apachectl.in
|
||||
+++ b/support/apachectl.in
|
||||
@@ -44,19 +44,20 @@ ARGV="$@"
|
||||
# the path to your httpd binary, including options if necessary
|
||||
HTTPD='@exp_sbindir@/@progname@'
|
||||
#
|
||||
-# pick up any necessary environment variables
|
||||
-if test -f @exp_sbindir@/envvars; then
|
||||
- . @exp_sbindir@/envvars
|
||||
-fi
|
||||
#
|
||||
# a command that outputs a formatted text version of the HTML at the
|
||||
# url given on the command line. Designed for lynx, however other
|
||||
# programs may work.
|
||||
-LYNX="@LYNX_PATH@ -dump"
|
||||
+if [ -x "@LYNX_PATH@" ]; then
|
||||
+ LYNX="@LYNX_PATH@ -dump"
|
||||
+else
|
||||
+ LYNX=none
|
||||
+fi
|
||||
#
|
||||
# the URL to your server's mod_status status page. If you do not
|
||||
# have one, then status and fullstatus will not work.
|
||||
STATUSURL="http://localhost:@PORT@/server-status"
|
||||
+
|
||||
#
|
||||
# Set this variable to a command that increases the maximum
|
||||
# number of file descriptors allowed per child process. This is
|
||||
@@ -76,9 +77,46 @@ if [ "x$ARGV" = "x" ] ; then
|
||||
ARGV="-h"
|
||||
fi
|
||||
|
||||
+function checklynx() {
|
||||
+if [ "$LYNX" = "none" ]; then
|
||||
+ echo "The 'links' package is required for this functionality."
|
||||
+ exit 8
|
||||
+fi
|
||||
+}
|
||||
+
|
||||
+function testconfig() {
|
||||
+# httpd is denied terminal access in SELinux, so run in the
|
||||
+# current context to get stdout from $HTTPD -t.
|
||||
+if test -x /usr/sbin/selinuxenabled && /usr/sbin/selinuxenabled; then
|
||||
+ runcon -- `id -Z` /usr/sbin/httpd $OPTIONS -t
|
||||
+else
|
||||
+ /usr/sbin/httpd $OPTIONS -t
|
||||
+fi
|
||||
+ERROR=$?
|
||||
+}
|
||||
+
|
||||
+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 If you want to pass extra arguments to httpd, edit the
|
||||
+ echo /etc/sysconfig/httpd config file.
|
||||
+fi
|
||||
+
|
||||
case $ACMD in
|
||||
-start|stop|restart|graceful|graceful-stop)
|
||||
- $HTTPD -k $ARGV
|
||||
+start|stop|restart|status)
|
||||
+ /usr/bin/systemctl $ACMD httpd.service
|
||||
+ ERROR=$?
|
||||
+ ;;
|
||||
+graceful)
|
||||
+ if /usr/bin/systemctl -q is-active httpd.service; then
|
||||
+ /usr/bin/systemctl reload httpd.service
|
||||
+ else
|
||||
+ /usr/bin/systemctl start httpd.service
|
||||
+ fi
|
||||
+ ERROR=$?
|
||||
+ ;;
|
||||
+graceful-stop)
|
||||
+ /usr/bin/systemctl stop httpd.service
|
||||
ERROR=$?
|
||||
;;
|
||||
startssl|sslstart|start-SSL)
|
||||
@@ -88,17 +126,14 @@ startssl|sslstart|start-SSL)
|
||||
ERROR=2
|
||||
;;
|
||||
configtest)
|
||||
- $HTTPD -t
|
||||
- ERROR=$?
|
||||
- ;;
|
||||
-status)
|
||||
- $LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } '
|
||||
+ testconfig
|
||||
;;
|
||||
fullstatus)
|
||||
+ checklynx
|
||||
$LYNX $STATUSURL
|
||||
;;
|
||||
*)
|
||||
- $HTTPD "$@"
|
||||
+ /usr/sbin/httpd $OPTIONS "$@"
|
||||
ERROR=$?
|
||||
esac
|
||||
|
82
httpd-2.4.35-cachehardmax.patch
Normal file
82
httpd-2.4.35-cachehardmax.patch
Normal file
@ -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 56a09f5..41015b5 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"),
|
37
httpd-2.4.35-corelimit.patch
Normal file
37
httpd-2.4.35-corelimit.patch
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
Bump up the core size limit if CoreDumpDirectory is
|
||||
configured.
|
||||
|
||||
Upstream-Status: Was discussed but there are competing desires;
|
||||
there are portability oddities here too.
|
||||
|
||||
diff --git a/server/core.c b/server/core.c
|
||||
index aa62e15..ec74029 100644
|
||||
--- a/server/core.c
|
||||
+++ b/server/core.c
|
||||
@@ -4952,6 +4952,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;
|
||||
}
|
||||
|
21
httpd-2.4.35-deplibs.patch
Normal file
21
httpd-2.4.35-deplibs.patch
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
Link straight against .la files.
|
||||
|
||||
Upstream-Status: vendor specific
|
||||
|
||||
diff --git a/configure.in b/configure.in
|
||||
index 9feaceb..82bfeef 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -784,9 +784,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)
|
77
httpd-2.4.35-detect-systemd.patch
Normal file
77
httpd-2.4.35-detect-systemd.patch
Normal file
@ -0,0 +1,77 @@
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index ea8366e..06b8c5a 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -4,7 +4,7 @@ CLEAN_SUBDIRS = test
|
||||
|
||||
PROGRAM_NAME = $(progname)
|
||||
PROGRAM_SOURCES = modules.c
|
||||
-PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(PCRE_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
|
||||
+PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
|
||||
PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c
|
||||
PROGRAM_DEPENDENCIES = \
|
||||
server/libmain.la \
|
||||
diff --git a/acinclude.m4 b/acinclude.m4
|
||||
index ce1d637..0ad0c13 100644
|
||||
--- a/acinclude.m4
|
||||
+++ b/acinclude.m4
|
||||
@@ -606,6 +606,30 @@ AC_DEFUN([APACHE_CHECK_OPENSSL],[
|
||||
fi
|
||||
])
|
||||
|
||||
+AC_DEFUN(APACHE_CHECK_SYSTEMD, [
|
||||
+dnl Check for systemd support for listen.c's socket activation.
|
||||
+case $host in
|
||||
+*-linux-*)
|
||||
+ if test -n "$PKGCONFIG" && $PKGCONFIG --exists libsystemd; then
|
||||
+ SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd`
|
||||
+ elif test -n "$PKGCONFIG" && $PKGCONFIG --exists libsystemd-daemon; then
|
||||
+ SYSTEMD_LIBS=`$PKGCONFIG --libs libsystemd-daemon`
|
||||
+ else
|
||||
+ AC_CHECK_LIB(systemd-daemon, sd_notify, SYSTEMD_LIBS="-lsystemd-daemon")
|
||||
+ fi
|
||||
+ if test -n "$SYSTEMD_LIBS"; then
|
||||
+ AC_CHECK_HEADERS(systemd/sd-daemon.h)
|
||||
+ if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
|
||||
+ AC_MSG_WARN([Your system does not support systemd.])
|
||||
+ else
|
||||
+ APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS])
|
||||
+ AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported])
|
||||
+ fi
|
||||
+ fi
|
||||
+ ;;
|
||||
+esac
|
||||
+])
|
||||
+
|
||||
dnl
|
||||
dnl APACHE_EXPORT_ARGUMENTS
|
||||
dnl Export (via APACHE_SUBST) the various path-related variables that
|
||||
diff --git a/configure.in b/configure.in
|
||||
index 82bfeef..eedba50 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -234,6 +234,7 @@ if test "$PCRE_CONFIG" != "false"; then
|
||||
AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG])
|
||||
APR_ADDTO(PCRE_INCLUDES, [`$PCRE_CONFIG --cflags`])
|
||||
APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs`])
|
||||
+ APR_ADDTO(HTTPD_LIBS, [\$(PCRE_LIBS)])
|
||||
else
|
||||
AC_MSG_ERROR([pcre-config for libpcre not found. PCRE is required and available from http://pcre.org/])
|
||||
fi
|
||||
@@ -504,6 +505,8 @@ if test "$ac_cv_struct_tm_gmtoff" = "yes"; then
|
||||
AC_DEFINE(HAVE_GMTOFF, 1, [Define if struct tm has a tm_gmtoff field])
|
||||
fi
|
||||
|
||||
+APACHE_CHECK_SYSTEMD
|
||||
+
|
||||
dnl ## Set up any appropriate OS-specific environment variables for apachectl
|
||||
|
||||
case $host in
|
||||
@@ -677,6 +680,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 ""'
|
125
httpd-2.4.35-freebind.patch
Normal file
125
httpd-2.4.35-freebind.patch
Normal file
@ -0,0 +1,125 @@
|
||||
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 1a6c1d3..d375fee 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/docs/manual/mod/mpm_common.html.en b/docs/manual/mod/mpm_common.html.en
|
||||
index 5d688e4..eb66c19 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)</td></tr>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#enableexceptionhook">EnableExceptionHook</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#gracefulshutdowntimeout">GracefulShutdownTimeout</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#listen">Listen</a></li>
|
||||
+<li><img alt="" src="../images/down.gif" /> <a href="#listenfree">ListenFree</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#listenbacklog">ListenBackLog</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#listencoresbucketsratio">ListenCoresBucketsRatio</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#maxconnectionsperchild">MaxConnectionsPerChild</a></li>
|
||||
@@ -233,6 +234,31 @@ discussion of the <code>Address already in use</code> error message,
|
||||
including other causes.</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
+
|
||||
+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
+<div class="directive-section"><h2><a name="ListenFree" id="ListenFree">ListenFree</a> <a name="listenfree" id="listenfree">Directive</a></h2>
|
||||
+<table class="directive">
|
||||
+<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>IP addresses and ports that the server
|
||||
+listens to. Doesn't require IP address to be up</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>ListenFree [<var>IP-address</var>:]<var>portnumber</var> [<var>protocol</var>]</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>MPM</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td><code class="module"><a href="../mod/event.html">event</a></code>, <code class="module"><a href="../mod/worker.html">worker</a></code>, <code class="module"><a href="../mod/prefork.html">prefork</a></code>, <code class="module"><a href="../mod/mpm_winnt.html">mpm_winnt</a></code>, <code class="module"><a href="../mod/mpm_netware.html">mpm_netware</a></code>, <code class="module"><a href="../mod/mpmt_os2.html">mpmt_os2</a></code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>This directive is currently available only in Red Hat Enterprise Linux</td></tr>
|
||||
+</table>
|
||||
+ <p>The <code class="directive">ListenFree</code> directive is
|
||||
+ identical to the <code class="directive">Listen</code> directive.
|
||||
+ The only difference is in the usage of the IP_FREEBIND socket
|
||||
+ option, which is enabled by default with <code class="directive">ListenFree</code>.
|
||||
+ 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.
|
||||
+ </p>
|
||||
+</div>
|
||||
+
|
||||
+
|
||||
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
<div class="directive-section"><h2><a name="ListenBackLog" id="ListenBackLog">ListenBackLog</a> <a name="listenbacklog" id="listenbacklog">Directive</a></h2>
|
||||
<table class="directive">
|
||||
|
46
httpd-2.4.35-full-release.patch
Normal file
46
httpd-2.4.35-full-release.patch
Normal file
@ -0,0 +1,46 @@
|
||||
diff --git a/server/core.c b/server/core.c
|
||||
index cb8e463..daf76b3 100644
|
||||
--- a/server/core.c
|
||||
+++ b/server/core.c
|
||||
@@ -3430,6 +3430,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;
|
||||
@@ -3506,7 +3507,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 ")");
|
||||
}
|
||||
|
||||
@@ -3514,7 +3518,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 ")";
|
||||
@@ -3547,8 +3551,11 @@ static const char *set_serv_tokens(cmd_parms *cmd, void *dummy,
|
||||
else if (!strcasecmp(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;
|
15
httpd-2.4.35-ocsp-wrong-ctx.patch
Normal file
15
httpd-2.4.35-ocsp-wrong-ctx.patch
Normal file
@ -0,0 +1,15 @@
|
||||
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
|
||||
index a5e86e4..6611610 100644
|
||||
--- a/modules/ssl/ssl_engine_kernel.c
|
||||
+++ b/modules/ssl/ssl_engine_kernel.c
|
||||
@@ -1823,8 +1823,8 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
|
||||
/*
|
||||
* Perform OCSP-based revocation checks
|
||||
*/
|
||||
- if (ok && ((sc->server->ocsp_mask & SSL_OCSPCHECK_CHAIN) ||
|
||||
- (errdepth == 0 && (sc->server->ocsp_mask & SSL_OCSPCHECK_LEAF)))) {
|
||||
+ if (ok && ((mctx->ocsp_mask & SSL_OCSPCHECK_CHAIN) ||
|
||||
+ (errdepth == 0 && (mctx->ocsp_mask & SSL_OCSPCHECK_LEAF)))) {
|
||||
/* If there was an optional verification error, it's not
|
||||
* possible to perform OCSP validation since the issuer may be
|
||||
* missing/untrusted. Fail in that case. */
|
16
httpd-2.4.35-r1633085.patch
Normal file
16
httpd-2.4.35-r1633085.patch
Normal file
@ -0,0 +1,16 @@
|
||||
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
|
||||
index d52d5e3..8a57659 100644
|
||||
--- a/modules/ssl/ssl_engine_io.c
|
||||
+++ b/modules/ssl/ssl_engine_io.c
|
||||
@@ -1415,6 +1415,11 @@ static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx)
|
||||
"\"SSLVerifyClient optional_no_ca\" "
|
||||
"configuration");
|
||||
ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, server);
|
||||
+
|
||||
+ /* on session resumption ssl_callback_SSLVerify()
|
||||
+ * will not be called, therefore we have to set it here
|
||||
+ */
|
||||
+ sslconn->verify_info = "GENEROUS";
|
||||
}
|
||||
else {
|
||||
const char *error = sslconn->verify_error ?
|
140
httpd-2.4.35-r1738878.patch
Normal file
140
httpd-2.4.35-r1738878.patch
Normal file
@ -0,0 +1,140 @@
|
||||
diff --git a/modules/proxy/ajp.h b/modules/proxy/ajp.h
|
||||
index c119a7e..267150a 100644
|
||||
--- a/modules/proxy/ajp.h
|
||||
+++ b/modules/proxy/ajp.h
|
||||
@@ -413,12 +413,14 @@ apr_status_t ajp_ilink_receive(apr_socket_t *sock, ajp_msg_t *msg);
|
||||
* @param sock backend socket
|
||||
* @param r current request
|
||||
* @param buffsize max size of the AJP packet.
|
||||
+ * @param secret authentication secret
|
||||
* @param uri requested uri
|
||||
* @return APR_SUCCESS or error
|
||||
*/
|
||||
apr_status_t ajp_send_header(apr_socket_t *sock, request_rec *r,
|
||||
apr_size_t buffsize,
|
||||
- apr_uri_t *uri);
|
||||
+ apr_uri_t *uri,
|
||||
+ const char *secret);
|
||||
|
||||
/**
|
||||
* Read the ajp message and return the type of the message.
|
||||
diff --git a/modules/proxy/ajp_header.c b/modules/proxy/ajp_header.c
|
||||
index 67353a7..680a8f3 100644
|
||||
--- a/modules/proxy/ajp_header.c
|
||||
+++ b/modules/proxy/ajp_header.c
|
||||
@@ -213,7 +213,8 @@ AJPV13_REQUEST/AJPV14_REQUEST=
|
||||
|
||||
static apr_status_t ajp_marshal_into_msgb(ajp_msg_t *msg,
|
||||
request_rec *r,
|
||||
- apr_uri_t *uri)
|
||||
+ apr_uri_t *uri,
|
||||
+ const char *secret)
|
||||
{
|
||||
int method;
|
||||
apr_uint32_t i, num_headers = 0;
|
||||
@@ -293,17 +294,15 @@ static apr_status_t ajp_marshal_into_msgb(ajp_msg_t *msg,
|
||||
i, elts[i].key, elts[i].val);
|
||||
}
|
||||
|
||||
-/* XXXX need to figure out how to do this
|
||||
- if (s->secret) {
|
||||
+ if (secret) {
|
||||
if (ajp_msg_append_uint8(msg, SC_A_SECRET) ||
|
||||
- ajp_msg_append_string(msg, s->secret)) {
|
||||
+ ajp_msg_append_string(msg, secret)) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(03228)
|
||||
- "Error ajp_marshal_into_msgb - "
|
||||
+ "ajp_marshal_into_msgb: "
|
||||
"Error appending secret");
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
}
|
||||
- */
|
||||
|
||||
if (r->user) {
|
||||
if (ajp_msg_append_uint8(msg, SC_A_REMOTE_USER) ||
|
||||
@@ -671,7 +670,8 @@ static apr_status_t ajp_unmarshal_response(ajp_msg_t *msg,
|
||||
apr_status_t ajp_send_header(apr_socket_t *sock,
|
||||
request_rec *r,
|
||||
apr_size_t buffsize,
|
||||
- apr_uri_t *uri)
|
||||
+ apr_uri_t *uri,
|
||||
+ const char *secret)
|
||||
{
|
||||
ajp_msg_t *msg;
|
||||
apr_status_t rc;
|
||||
@@ -683,7 +683,7 @@ apr_status_t ajp_send_header(apr_socket_t *sock,
|
||||
return rc;
|
||||
}
|
||||
|
||||
- rc = ajp_marshal_into_msgb(msg, r, uri);
|
||||
+ rc = ajp_marshal_into_msgb(msg, r, uri, secret);
|
||||
if (rc != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00988)
|
||||
"ajp_send_header: ajp_marshal_into_msgb failed");
|
||||
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
|
||||
index 69a35ce..800ede1 100644
|
||||
--- a/modules/proxy/mod_proxy.c
|
||||
+++ b/modules/proxy/mod_proxy.c
|
||||
@@ -327,6 +327,12 @@ static const char *set_worker_param(apr_pool_t *p,
|
||||
worker->s->response_field_size = (s ? s : HUGE_STRING_LEN);
|
||||
worker->s->response_field_size_set = 1;
|
||||
}
|
||||
+ else if (!strcasecmp(key, "secret")) {
|
||||
+ if (PROXY_STRNCPY(worker->s->secret, val) != APR_SUCCESS) {
|
||||
+ return apr_psprintf(p, "Secret length must be < %d characters",
|
||||
+ (int)sizeof(worker->s->secret));
|
||||
+ }
|
||||
+ }
|
||||
else {
|
||||
if (set_worker_hc_param_f) {
|
||||
return set_worker_hc_param_f(p, s, worker, key, val, NULL);
|
||||
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
|
||||
index aabd09f..3419023 100644
|
||||
--- a/modules/proxy/mod_proxy.h
|
||||
+++ b/modules/proxy/mod_proxy.h
|
||||
@@ -357,6 +357,7 @@ PROXY_WORKER_HC_FAIL )
|
||||
#define PROXY_WORKER_MAX_HOSTNAME_SIZE 64
|
||||
#define PROXY_BALANCER_MAX_HOSTNAME_SIZE PROXY_WORKER_MAX_HOSTNAME_SIZE
|
||||
#define PROXY_BALANCER_MAX_STICKY_SIZE 64
|
||||
+#define PROXY_WORKER_MAX_SECRET_SIZE 64
|
||||
|
||||
#define PROXY_RFC1035_HOSTNAME_SIZE 256
|
||||
|
||||
@@ -450,6 +451,7 @@ typedef struct {
|
||||
hcmethod_t method; /* method to use for health check */
|
||||
apr_interval_time_t interval;
|
||||
char upgrade[PROXY_WORKER_MAX_SCHEME_SIZE];/* upgrade protocol used by mod_proxy_wstunnel */
|
||||
+ char secret[PROXY_WORKER_MAX_SECRET_SIZE]; /* authentication secret (e.g. AJP13) */
|
||||
char hostname_ex[PROXY_RFC1035_HOSTNAME_SIZE]; /* RFC1035 compliant version of the remote backend address */
|
||||
apr_size_t response_field_size; /* Size of proxy response buffer in bytes. */
|
||||
unsigned int response_field_size_set:1;
|
||||
diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
|
||||
index 73716af..6faabea 100644
|
||||
--- a/modules/proxy/mod_proxy_ajp.c
|
||||
+++ b/modules/proxy/mod_proxy_ajp.c
|
||||
@@ -193,6 +193,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
|
||||
apr_off_t content_length = 0;
|
||||
int original_status = r->status;
|
||||
const char *original_status_line = r->status_line;
|
||||
+ const char *secret = NULL;
|
||||
|
||||
if (psf->io_buffer_size_set)
|
||||
maxsize = psf->io_buffer_size;
|
||||
@@ -202,12 +203,15 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
|
||||
maxsize = AJP_MSG_BUFFER_SZ;
|
||||
maxsize = APR_ALIGN(maxsize, 1024);
|
||||
|
||||
+ if (*conn->worker->s->secret)
|
||||
+ secret = conn->worker->s->secret;
|
||||
+
|
||||
/*
|
||||
* Send the AJP request to the remote server
|
||||
*/
|
||||
|
||||
/* send request headers */
|
||||
- status = ajp_send_header(conn->sock, r, maxsize, uri);
|
||||
+ status = ajp_send_header(conn->sock, r, maxsize, uri, secret);
|
||||
if (status != APR_SUCCESS) {
|
||||
conn->close = 1;
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, status, r, APLOGNO(00868)
|
96
httpd-2.4.35-r1825120.patch
Normal file
96
httpd-2.4.35-r1825120.patch
Normal file
@ -0,0 +1,96 @@
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index 19cb611..79d5219 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -2070,70 +2070,18 @@ 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);
|
||||
-}
|
||||
-
|
||||
STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
|
||||
apr_pool_t *ptemp,
|
||||
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.
|
||||
@@ -2168,17 +2116,12 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
|
||||
continue; /* don't try to load directories */
|
||||
}
|
||||
file = apr_pstrcat(ptemp, ca_path, "/", direntry.name, NULL);
|
||||
- ssl_init_PushCAList(ca_list, s, ptemp, file);
|
||||
+ SSL_add_file_cert_subjects_to_stack(ca_list, file);
|
||||
}
|
||||
|
||||
apr_dir_close(dir);
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Cleanup
|
||||
- */
|
||||
- (void) sk_X509_NAME_set_cmp_func(ca_list, NULL);
|
||||
-
|
||||
return ca_list;
|
||||
}
|
||||
|
708
httpd-2.4.35-r1830819+.patch
Normal file
708
httpd-2.4.35-r1830819+.patch
Normal file
@ -0,0 +1,708 @@
|
||||
# ./pullrev.sh 1830819 1830836 1830912 1830913 1830927 1831168 1831173
|
||||
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1830819
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1830912
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1830913
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1830927
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1831168
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1831173
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1835240
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1835242
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1835615
|
||||
|
||||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
|
||||
index 43397f9..ff8f429 100644
|
||||
--- httpd-2.4.35/modules/ssl/ssl_engine_config.c.r1830819+
|
||||
+++ httpd-2.4.35/modules/ssl/ssl_engine_config.c
|
||||
@@ -899,7 +899,9 @@
|
||||
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
||||
const char *err;
|
||||
|
||||
- if ((err = ssl_cmd_check_file(cmd, &arg))) {
|
||||
+ /* Only check for non-ENGINE based certs. */
|
||||
+ if (!modssl_is_engine_id(arg)
|
||||
+ && (err = ssl_cmd_check_file(cmd, &arg))) {
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -915,7 +917,9 @@
|
||||
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
||||
const char *err;
|
||||
|
||||
- if ((err = ssl_cmd_check_file(cmd, &arg))) {
|
||||
+ /* Check keyfile exists for non-ENGINE keys. */
|
||||
+ if (!modssl_is_engine_id(arg)
|
||||
+ && (err = ssl_cmd_check_file(cmd, &arg))) {
|
||||
return err;
|
||||
}
|
||||
|
||||
--- httpd-2.4.35/modules/ssl/ssl_engine_init.c.r1830819+
|
||||
+++ httpd-2.4.35/modules/ssl/ssl_engine_init.c
|
||||
@@ -1186,12 +1186,18 @@
|
||||
(certfile = APR_ARRAY_IDX(mctx->pks->cert_files, i,
|
||||
const char *));
|
||||
i++) {
|
||||
+ EVP_PKEY *pkey;
|
||||
+ const char *engine_certfile = NULL;
|
||||
+
|
||||
key_id = apr_psprintf(ptemp, "%s:%d", vhost_id, i);
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
/* first the certificate (public key) */
|
||||
- if (mctx->cert_chain) {
|
||||
+ if (modssl_is_engine_id(certfile)) {
|
||||
+ engine_certfile = certfile;
|
||||
+ }
|
||||
+ else if (mctx->cert_chain) {
|
||||
if ((SSL_CTX_use_certificate_file(mctx->ssl_ctx, certfile,
|
||||
SSL_FILETYPE_PEM) < 1)) {
|
||||
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02561)
|
||||
@@ -1220,12 +1226,46 @@
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
- if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile,
|
||||
- SSL_FILETYPE_PEM) < 1) &&
|
||||
- (ERR_GET_FUNC(ERR_peek_last_error())
|
||||
- != X509_F_X509_CHECK_PRIVATE_KEY)) {
|
||||
+ if (modssl_is_engine_id(keyfile)) {
|
||||
+ apr_status_t rv;
|
||||
+
|
||||
+ cert = NULL;
|
||||
+
|
||||
+ if ((rv = modssl_load_engine_keypair(s, ptemp, vhost_id,
|
||||
+ engine_certfile, keyfile,
|
||||
+ &cert, &pkey))) {
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ if (cert) {
|
||||
+ if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) < 1) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10137)
|
||||
+ "Failed to configure engine certificate %s, check %s",
|
||||
+ key_id, certfile);
|
||||
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
||||
+ return APR_EGENERAL;
|
||||
+ }
|
||||
+
|
||||
+ /* SSL_CTX now owns the cert. */
|
||||
+ X509_free(cert);
|
||||
+ }
|
||||
+
|
||||
+ if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) < 1) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10130)
|
||||
+ "Failed to configure private key %s from engine",
|
||||
+ keyfile);
|
||||
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
||||
+ return APR_EGENERAL;
|
||||
+ }
|
||||
+
|
||||
+ /* SSL_CTX now owns the key */
|
||||
+ EVP_PKEY_free(pkey);
|
||||
+ }
|
||||
+ else if ((SSL_CTX_use_PrivateKey_file(mctx->ssl_ctx, keyfile,
|
||||
+ SSL_FILETYPE_PEM) < 1)
|
||||
+ && (ERR_GET_FUNC(ERR_peek_last_error())
|
||||
+ != X509_F_X509_CHECK_PRIVATE_KEY)) {
|
||||
ssl_asn1_t *asn1;
|
||||
- EVP_PKEY *pkey;
|
||||
const unsigned char *ptr;
|
||||
|
||||
ERR_clear_error();
|
||||
@@ -1312,8 +1352,9 @@
|
||||
/*
|
||||
* Try to read DH parameters from the (first) SSLCertificateFile
|
||||
*/
|
||||
- if ((certfile = APR_ARRAY_IDX(mctx->pks->cert_files, 0, const char *)) &&
|
||||
- (dhparams = ssl_dh_GetParamFromFile(certfile))) {
|
||||
+ certfile = APR_ARRAY_IDX(mctx->pks->cert_files, 0, const char *);
|
||||
+ if (certfile && !modssl_is_engine_id(certfile)
|
||||
+ && (dhparams = ssl_dh_GetParamFromFile(certfile))) {
|
||||
SSL_CTX_set_tmp_dh(mctx->ssl_ctx, dhparams);
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02540)
|
||||
"Custom DH parameters (%d bits) for %s loaded from %s",
|
||||
@@ -1325,10 +1366,10 @@
|
||||
/*
|
||||
* Similarly, try to read the ECDH curve name from SSLCertificateFile...
|
||||
*/
|
||||
- if ((certfile != NULL) &&
|
||||
- (ecparams = ssl_ec_GetParamFromFile(certfile)) &&
|
||||
- (nid = EC_GROUP_get_curve_name(ecparams)) &&
|
||||
- (eckey = EC_KEY_new_by_curve_name(nid))) {
|
||||
+ if (certfile && !modssl_is_engine_id(certfile)
|
||||
+ && (ecparams = ssl_ec_GetParamFromFile(certfile))
|
||||
+ && (nid = EC_GROUP_get_curve_name(ecparams))
|
||||
+ && (eckey = EC_KEY_new_by_curve_name(nid))) {
|
||||
SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey);
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02541)
|
||||
"ECDH curve %s for %s specified in %s",
|
||||
--- httpd-2.4.35/modules/ssl/ssl_engine_pphrase.c.r1830819+
|
||||
+++ httpd-2.4.35/modules/ssl/ssl_engine_pphrase.c
|
||||
@@ -143,9 +143,6 @@
|
||||
const char *key_id = asn1_table_vhost_key(mc, p, sc->vhost_id, idx);
|
||||
EVP_PKEY *pPrivateKey = NULL;
|
||||
ssl_asn1_t *asn1;
|
||||
- unsigned char *ucp;
|
||||
- long int length;
|
||||
- BOOL bReadable;
|
||||
int nPassPhrase = (*pphrases)->nelts;
|
||||
int nPassPhraseRetry = 0;
|
||||
apr_time_t pkey_mtime = 0;
|
||||
@@ -222,16 +219,12 @@
|
||||
* is not empty. */
|
||||
ERR_clear_error();
|
||||
|
||||
- bReadable = ((pPrivateKey = modssl_read_privatekey(ppcb_arg.pkey_file,
|
||||
- NULL, ssl_pphrase_Handle_CB, &ppcb_arg)) != NULL ?
|
||||
- TRUE : FALSE);
|
||||
-
|
||||
- /*
|
||||
- * when the private key file now was readable,
|
||||
- * it's fine and we go out of the loop
|
||||
- */
|
||||
- if (bReadable)
|
||||
- break;
|
||||
+ pPrivateKey = modssl_read_privatekey(ppcb_arg.pkey_file,
|
||||
+ ssl_pphrase_Handle_CB, &ppcb_arg);
|
||||
+ /* If the private key was successfully read, nothing more to
|
||||
+ do here. */
|
||||
+ if (pPrivateKey != NULL)
|
||||
+ break;
|
||||
|
||||
/*
|
||||
* when we have more remembered pass phrases
|
||||
@@ -356,19 +349,12 @@
|
||||
nPassPhrase++;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Insert private key into the global module configuration
|
||||
- * (we convert it to a stand-alone DER byte sequence
|
||||
- * because the SSL library uses static variables inside a
|
||||
- * RSA structure which do not survive DSO reloads!)
|
||||
- */
|
||||
- length = i2d_PrivateKey(pPrivateKey, NULL);
|
||||
- ucp = ssl_asn1_table_set(mc->tPrivateKey, key_id, length);
|
||||
- (void)i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */
|
||||
+ /* Cache the private key in the global module configuration so it
|
||||
+ * can be used after subsequent reloads. */
|
||||
+ asn1 = ssl_asn1_table_set(mc->tPrivateKey, key_id, pPrivateKey);
|
||||
|
||||
if (ppcb_arg.nPassPhraseDialogCur != 0) {
|
||||
/* remember mtime of encrypted keys */
|
||||
- asn1 = ssl_asn1_table_get(mc->tPrivateKey, key_id);
|
||||
asn1->source_mtime = pkey_mtime;
|
||||
}
|
||||
|
||||
@@ -619,3 +605,303 @@
|
||||
*/
|
||||
return (len);
|
||||
}
|
||||
+
|
||||
+
|
||||
+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
|
||||
+
|
||||
+/* OpenSSL UI implementation for passphrase entry; largely duplicated
|
||||
+ * from ssl_pphrase_Handle_CB but adjusted for UI API. TODO: Might be
|
||||
+ * worth trying to shift pphrase handling over to the UI API
|
||||
+ * completely. */
|
||||
+static int passphrase_ui_open(UI *ui)
|
||||
+{
|
||||
+ pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui);
|
||||
+ SSLSrvConfigRec *sc = mySrvConfig(ppcb->s);
|
||||
+
|
||||
+ ppcb->nPassPhraseDialog++;
|
||||
+ ppcb->nPassPhraseDialogCur++;
|
||||
+
|
||||
+ /*
|
||||
+ * Builtin or Pipe dialog
|
||||
+ */
|
||||
+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN
|
||||
+ || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
|
||||
+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
|
||||
+ if (!readtty) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s,
|
||||
+ APLOGNO(10143)
|
||||
+ "Init: Creating pass phrase dialog pipe child "
|
||||
+ "'%s'", sc->server->pphrase_dialog_path);
|
||||
+ if (ssl_pipe_child_create(ppcb->p,
|
||||
+ sc->server->pphrase_dialog_path)
|
||||
+ != APR_SUCCESS) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ppcb->s,
|
||||
+ APLOGNO(10144)
|
||||
+ "Init: Failed to create pass phrase pipe '%s'",
|
||||
+ sc->server->pphrase_dialog_path);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO(10145)
|
||||
+ "Init: Requesting pass phrase via piped dialog");
|
||||
+ }
|
||||
+ else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */
|
||||
+#ifdef WIN32
|
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, ppcb->s, APLOGNO(10146)
|
||||
+ "Init: Failed to create pass phrase pipe '%s'",
|
||||
+ sc->server->pphrase_dialog_path);
|
||||
+ return 0;
|
||||
+#else
|
||||
+ /*
|
||||
+ * stderr has already been redirected to the error_log.
|
||||
+ * rather than attempting to temporarily rehook it to the terminal,
|
||||
+ * we print the prompt to stdout before EVP_read_pw_string turns
|
||||
+ * off tty echo
|
||||
+ */
|
||||
+ apr_file_open_stdout(&writetty, ppcb->p);
|
||||
+
|
||||
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO(10147)
|
||||
+ "Init: Requesting pass phrase via builtin terminal "
|
||||
+ "dialog");
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * The first time display a header to inform the user about what
|
||||
+ * program he actually speaks to, which module is responsible for
|
||||
+ * this terminal dialog and why to the hell he has to enter
|
||||
+ * something...
|
||||
+ */
|
||||
+ if (ppcb->nPassPhraseDialog == 1) {
|
||||
+ apr_file_printf(writetty, "%s mod_ssl (Pass Phrase Dialog)\n",
|
||||
+ AP_SERVER_BASEVERSION);
|
||||
+ apr_file_printf(writetty,
|
||||
+ "A pass phrase is required to access the private key.\n");
|
||||
+ }
|
||||
+ if (ppcb->bPassPhraseDialogOnce) {
|
||||
+ ppcb->bPassPhraseDialogOnce = FALSE;
|
||||
+ apr_file_printf(writetty, "\n");
|
||||
+ apr_file_printf(writetty, "Private key %s (%s)\n",
|
||||
+ ppcb->key_id, ppcb->pkey_file);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int passphrase_ui_read(UI *ui, UI_STRING *uis)
|
||||
+{
|
||||
+ pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui);
|
||||
+ SSLSrvConfigRec *sc = mySrvConfig(ppcb->s);
|
||||
+ const char *prompt;
|
||||
+ int i;
|
||||
+ int bufsize;
|
||||
+ int len;
|
||||
+ char *buf;
|
||||
+
|
||||
+ prompt = UI_get0_output_string(uis);
|
||||
+ if (prompt == NULL) {
|
||||
+ prompt = "Enter pass phrase:";
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Get the maximum expected size and allocate the buffer
|
||||
+ */
|
||||
+ bufsize = UI_get_result_maxsize(uis);
|
||||
+ buf = apr_pcalloc(ppcb->p, bufsize);
|
||||
+
|
||||
+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN
|
||||
+ || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
|
||||
+ /*
|
||||
+ * Get the pass phrase through a callback.
|
||||
+ * Empty input is not accepted.
|
||||
+ */
|
||||
+ for (;;) {
|
||||
+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
|
||||
+ i = pipe_get_passwd_cb(buf, bufsize, "", FALSE);
|
||||
+ }
|
||||
+ else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */
|
||||
+ i = EVP_read_pw_string(buf, bufsize, "", FALSE);
|
||||
+ }
|
||||
+ if (i != 0) {
|
||||
+ OPENSSL_cleanse(buf, bufsize);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ len = strlen(buf);
|
||||
+ if (len < 1){
|
||||
+ apr_file_printf(writetty, "Apache:mod_ssl:Error: Pass phrase"
|
||||
+ "empty (needs to be at least 1 character).\n");
|
||||
+ apr_file_puts(prompt, writetty);
|
||||
+ }
|
||||
+ else {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ /*
|
||||
+ * Filter program
|
||||
+ */
|
||||
+ else if (sc->server->pphrase_dialog_type == SSL_PPTYPE_FILTER) {
|
||||
+ const char *cmd = sc->server->pphrase_dialog_path;
|
||||
+ const char **argv = apr_palloc(ppcb->p, sizeof(char *) * 3);
|
||||
+ char *result;
|
||||
+
|
||||
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, ppcb->s, APLOGNO(10148)
|
||||
+ "Init: Requesting pass phrase from dialog filter "
|
||||
+ "program (%s)", cmd);
|
||||
+
|
||||
+ argv[0] = cmd;
|
||||
+ argv[1] = ppcb->key_id;
|
||||
+ argv[2] = NULL;
|
||||
+
|
||||
+ result = ssl_util_readfilter(ppcb->s, ppcb->p, cmd, argv);
|
||||
+ apr_cpystrn(buf, result, bufsize);
|
||||
+ len = strlen(buf);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Ok, we now have the pass phrase, so give it back
|
||||
+ */
|
||||
+ ppcb->cpPassPhraseCur = apr_pstrdup(ppcb->p, buf);
|
||||
+ UI_set_result(ui, uis, buf);
|
||||
+
|
||||
+ /* Clear sensitive data. */
|
||||
+ OPENSSL_cleanse(buf, bufsize);
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int passphrase_ui_write(UI *ui, UI_STRING *uis)
|
||||
+{
|
||||
+ pphrase_cb_arg_t *ppcb = UI_get0_user_data(ui);
|
||||
+ SSLSrvConfigRec *sc;
|
||||
+ const char *prompt;
|
||||
+
|
||||
+ sc = mySrvConfig(ppcb->s);
|
||||
+
|
||||
+ if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN
|
||||
+ || sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
|
||||
+ prompt = UI_get0_output_string(uis);
|
||||
+ apr_file_puts(prompt, writetty);
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static int passphrase_ui_close(UI *ui)
|
||||
+{
|
||||
+ /*
|
||||
+ * Close the pipes if they were opened
|
||||
+ */
|
||||
+ if (readtty) {
|
||||
+ apr_file_close(readtty);
|
||||
+ apr_file_close(writetty);
|
||||
+ readtty = writetty = NULL;
|
||||
+ }
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static apr_status_t pp_ui_method_cleanup(void *uip)
|
||||
+{
|
||||
+ UI_METHOD *uim = uip;
|
||||
+
|
||||
+ UI_destroy_method(uim);
|
||||
+
|
||||
+ return APR_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+static UI_METHOD *get_passphrase_ui(apr_pool_t *p)
|
||||
+{
|
||||
+ UI_METHOD *ui_method = UI_create_method("Passphrase UI");
|
||||
+
|
||||
+ UI_method_set_opener(ui_method, passphrase_ui_open);
|
||||
+ UI_method_set_reader(ui_method, passphrase_ui_read);
|
||||
+ UI_method_set_writer(ui_method, passphrase_ui_write);
|
||||
+ UI_method_set_closer(ui_method, passphrase_ui_close);
|
||||
+
|
||||
+ apr_pool_cleanup_register(p, ui_method, pp_ui_method_cleanup,
|
||||
+ pp_ui_method_cleanup);
|
||||
+
|
||||
+ return ui_method;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p,
|
||||
+ const char *vhostid,
|
||||
+ const char *certid, const char *keyid,
|
||||
+ X509 **pubkey, EVP_PKEY **privkey)
|
||||
+{
|
||||
+ const char *c, *scheme;
|
||||
+ ENGINE *e;
|
||||
+ UI_METHOD *ui_method = get_passphrase_ui(p);
|
||||
+ pphrase_cb_arg_t ppcb;
|
||||
+
|
||||
+ memset(&ppcb, 0, sizeof ppcb);
|
||||
+ ppcb.s = s;
|
||||
+ ppcb.p = p;
|
||||
+ ppcb.bPassPhraseDialogOnce = TRUE;
|
||||
+ ppcb.key_id = vhostid;
|
||||
+ ppcb.pkey_file = keyid;
|
||||
+
|
||||
+ c = ap_strchr_c(keyid, ':');
|
||||
+ if (!c || c == keyid) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10131)
|
||||
+ "Init: Unrecognized private key identifier `%s'",
|
||||
+ keyid);
|
||||
+ return ssl_die(s);
|
||||
+ }
|
||||
+
|
||||
+ scheme = apr_pstrmemdup(p, keyid, c - keyid);
|
||||
+ if (!(e = ENGINE_by_id(scheme))) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10132)
|
||||
+ "Init: Failed to load engine for private key %s",
|
||||
+ keyid);
|
||||
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
||||
+ return ssl_die(s);
|
||||
+ }
|
||||
+
|
||||
+ if (!ENGINE_init(e)) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10149)
|
||||
+ "Init: Failed to initialize engine %s for private key %s",
|
||||
+ scheme, keyid);
|
||||
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
||||
+ return ssl_die(s);
|
||||
+ }
|
||||
+
|
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
|
||||
+ "Init: Initialized engine %s for private key %s",
|
||||
+ scheme, keyid);
|
||||
+
|
||||
+ if (APLOGdebug(s)) {
|
||||
+ ENGINE_ctrl_cmd_string(e, "VERBOSE", NULL, 0);
|
||||
+ }
|
||||
+
|
||||
+ if (certid) {
|
||||
+ struct {
|
||||
+ const char *cert_id;
|
||||
+ X509 *cert;
|
||||
+ } params = { certid, NULL };
|
||||
+
|
||||
+ if (!ENGINE_ctrl_cmd(e, "LOAD_CERT_CTRL", 0, ¶ms, NULL, 1)) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10136)
|
||||
+ "Init: Unable to get the certificate");
|
||||
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
||||
+ return ssl_die(s);
|
||||
+ }
|
||||
+
|
||||
+ *pubkey = params.cert;
|
||||
+ }
|
||||
+
|
||||
+ *privkey = ENGINE_load_private_key(e, keyid, ui_method, &ppcb);
|
||||
+ if (*privkey == NULL) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(10133)
|
||||
+ "Init: Unable to get the private key");
|
||||
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
||||
+ return ssl_die(s);
|
||||
+ }
|
||||
+
|
||||
+ ENGINE_finish(e);
|
||||
+ ENGINE_free(e);
|
||||
+
|
||||
+ return APR_SUCCESS;
|
||||
+}
|
||||
+#endif
|
||||
--- httpd-2.4.35/modules/ssl/ssl_private.h.r1830819+
|
||||
+++ httpd-2.4.35/modules/ssl/ssl_private.h
|
||||
@@ -986,21 +986,28 @@
|
||||
apr_status_t ssl_load_encrypted_pkey(server_rec *, apr_pool_t *, int,
|
||||
const char *, apr_array_header_t **);
|
||||
|
||||
+/* Load public and/or private key from the configured ENGINE. Private
|
||||
+ * key returned as *pkey. certid can be NULL, in which case *pubkey
|
||||
+ * is not altered. Errors logged on failure. */
|
||||
+apr_status_t modssl_load_engine_keypair(server_rec *s, apr_pool_t *p,
|
||||
+ const char *vhostid,
|
||||
+ const char *certid, const char *keyid,
|
||||
+ X509 **pubkey, EVP_PKEY **privkey);
|
||||
+
|
||||
/** Diffie-Hellman Parameter Support */
|
||||
DH *ssl_dh_GetParamFromFile(const char *);
|
||||
#ifdef HAVE_ECC
|
||||
EC_GROUP *ssl_ec_GetParamFromFile(const char *);
|
||||
#endif
|
||||
|
||||
-unsigned char *ssl_asn1_table_set(apr_hash_t *table,
|
||||
- const char *key,
|
||||
- long int length);
|
||||
-
|
||||
-ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,
|
||||
- const char *key);
|
||||
-
|
||||
-void ssl_asn1_table_unset(apr_hash_t *table,
|
||||
- const char *key);
|
||||
+/* Store the EVP_PKEY key (serialized into DER) in the hash table with
|
||||
+ * key, returning the ssl_asn1_t structure pointer. */
|
||||
+ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key,
|
||||
+ EVP_PKEY *pkey);
|
||||
+/* Retrieve the ssl_asn1_t structure with given key from the hash. */
|
||||
+ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table, const char *key);
|
||||
+/* Remove and free the ssl_asn1_t structure with given key. */
|
||||
+void ssl_asn1_table_unset(apr_hash_t *table, const char *key);
|
||||
|
||||
/** Mutex Support */
|
||||
int ssl_mutex_init(server_rec *, apr_pool_t *);
|
||||
@@ -1088,6 +1095,10 @@
|
||||
int ssl_is_challenge(conn_rec *c, const char *servername,
|
||||
X509 **pcert, EVP_PKEY **pkey);
|
||||
|
||||
+/* Returns non-zero if the cert/key filename should be handled through
|
||||
+ * the configured ENGINE. */
|
||||
+int modssl_is_engine_id(const char *name);
|
||||
+
|
||||
#endif /* SSL_PRIVATE_H */
|
||||
/** @} */
|
||||
|
||||
--- httpd-2.4.35/modules/ssl/ssl_util.c.r1830819+
|
||||
+++ httpd-2.4.35/modules/ssl/ssl_util.c
|
||||
@@ -175,45 +175,37 @@
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * certain key data needs to survive restarts,
|
||||
- * which are stored in the user data table of s->process->pool.
|
||||
- * to prevent "leaking" of this data, we use malloc/free
|
||||
- * rather than apr_palloc and these wrappers to help make sure
|
||||
- * we do not leak the malloc-ed data.
|
||||
- */
|
||||
-unsigned char *ssl_asn1_table_set(apr_hash_t *table,
|
||||
- const char *key,
|
||||
- long int length)
|
||||
+/* Decrypted private keys are cached to survive restarts. The cached
|
||||
+ * data must have lifetime of the process (hence malloc/free rather
|
||||
+ * than pools), and uses raw DER since the EVP_PKEY structure
|
||||
+ * internals may not survive across a module reload. */
|
||||
+ssl_asn1_t *ssl_asn1_table_set(apr_hash_t *table, const char *key,
|
||||
+ EVP_PKEY *pkey)
|
||||
{
|
||||
apr_ssize_t klen = strlen(key);
|
||||
ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
|
||||
+ apr_size_t length = i2d_PrivateKey(pkey, NULL);
|
||||
+ unsigned char *p;
|
||||
|
||||
- /*
|
||||
- * if a value for this key already exists,
|
||||
- * reuse as much of the already malloc-ed data
|
||||
- * as possible.
|
||||
- */
|
||||
+ /* Re-use structure if cached previously. */
|
||||
if (asn1) {
|
||||
if (asn1->nData != length) {
|
||||
- free(asn1->cpData); /* XXX: realloc? */
|
||||
- asn1->cpData = NULL;
|
||||
+ asn1->cpData = ap_realloc(asn1->cpData, length);
|
||||
}
|
||||
}
|
||||
else {
|
||||
asn1 = ap_malloc(sizeof(*asn1));
|
||||
asn1->source_mtime = 0; /* used as a note for encrypted private keys */
|
||||
- asn1->cpData = NULL;
|
||||
- }
|
||||
-
|
||||
- asn1->nData = length;
|
||||
- if (!asn1->cpData) {
|
||||
asn1->cpData = ap_malloc(length);
|
||||
+
|
||||
+ apr_hash_set(table, key, klen, asn1);
|
||||
}
|
||||
|
||||
- apr_hash_set(table, key, klen, asn1);
|
||||
+ asn1->nData = length;
|
||||
+ p = asn1->cpData;
|
||||
+ i2d_PrivateKey(pkey, &p); /* increases p by length */
|
||||
|
||||
- return asn1->cpData; /* caller will assign a value to this */
|
||||
+ return asn1;
|
||||
}
|
||||
|
||||
ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,
|
||||
@@ -463,3 +455,13 @@
|
||||
}
|
||||
|
||||
#endif /* #if APR_HAS_THREADS && MODSSL_USE_OPENSSL_PRE_1_1_API */
|
||||
+
|
||||
+int modssl_is_engine_id(const char *name)
|
||||
+{
|
||||
+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
|
||||
+ /* ### Can handle any other special ENGINE key names here? */
|
||||
+ return strncmp(name, "pkcs11:", 7) == 0;
|
||||
+#else
|
||||
+ return 0;
|
||||
+#endif
|
||||
+}
|
||||
--- httpd-2.4.35/modules/ssl/ssl_util_ssl.c.r1830819+
|
||||
+++ httpd-2.4.35/modules/ssl/ssl_util_ssl.c
|
||||
@@ -74,7 +74,7 @@
|
||||
** _________________________________________________________________
|
||||
*/
|
||||
|
||||
-EVP_PKEY *modssl_read_privatekey(const char* filename, EVP_PKEY **key, pem_password_cb *cb, void *s)
|
||||
+EVP_PKEY *modssl_read_privatekey(const char *filename, pem_password_cb *cb, void *s)
|
||||
{
|
||||
EVP_PKEY *rc;
|
||||
BIO *bioS;
|
||||
@@ -83,7 +83,7 @@
|
||||
/* 1. try PEM (= DER+Base64+headers) */
|
||||
if ((bioS=BIO_new_file(filename, "r")) == NULL)
|
||||
return NULL;
|
||||
- rc = PEM_read_bio_PrivateKey(bioS, key, cb, s);
|
||||
+ rc = PEM_read_bio_PrivateKey(bioS, NULL, cb, s);
|
||||
BIO_free(bioS);
|
||||
|
||||
if (rc == NULL) {
|
||||
@@ -107,41 +107,9 @@
|
||||
BIO_free(bioS);
|
||||
}
|
||||
}
|
||||
- if (rc != NULL && key != NULL) {
|
||||
- if (*key != NULL)
|
||||
- EVP_PKEY_free(*key);
|
||||
- *key = rc;
|
||||
- }
|
||||
return rc;
|
||||
}
|
||||
|
||||
-typedef struct {
|
||||
- const char *pass;
|
||||
- int pass_len;
|
||||
-} pass_ctx;
|
||||
-
|
||||
-static int provide_pass(char *buf, int size, int rwflag, void *baton)
|
||||
-{
|
||||
- pass_ctx *ctx = baton;
|
||||
- if (ctx->pass_len > 0) {
|
||||
- if (ctx->pass_len < size) {
|
||||
- size = (int)ctx->pass_len;
|
||||
- }
|
||||
- memcpy(buf, ctx->pass, size);
|
||||
- }
|
||||
- return ctx->pass_len;
|
||||
-}
|
||||
-
|
||||
-EVP_PKEY *modssl_read_encrypted_pkey(const char *filename, EVP_PKEY **key,
|
||||
- const char *pass, apr_size_t pass_len)
|
||||
-{
|
||||
- pass_ctx ctx;
|
||||
-
|
||||
- ctx.pass = pass;
|
||||
- ctx.pass_len = pass_len;
|
||||
- return modssl_read_privatekey(filename, key, provide_pass, &ctx);
|
||||
-}
|
||||
-
|
||||
/* _________________________________________________________________
|
||||
**
|
||||
** Smart shutdown
|
||||
--- httpd-2.4.35/modules/ssl/ssl_util_ssl.h.r1830819+
|
||||
+++ httpd-2.4.35/modules/ssl/ssl_util_ssl.h
|
||||
@@ -64,8 +64,11 @@
|
||||
void modssl_init_app_data2_idx(void);
|
||||
void *modssl_get_app_data2(SSL *);
|
||||
void modssl_set_app_data2(SSL *, void *);
|
||||
-EVP_PKEY *modssl_read_privatekey(const char *, EVP_PKEY **, pem_password_cb *, void *);
|
||||
-EVP_PKEY *modssl_read_encrypted_pkey(const char *, EVP_PKEY **, const char *, apr_size_t);
|
||||
+
|
||||
+/* Read private key from filename in either PEM or raw base64(DER)
|
||||
+ * format, using password entry callback cb and userdata. */
|
||||
+EVP_PKEY *modssl_read_privatekey(const char *filename, pem_password_cb *cb, void *ud);
|
||||
+
|
||||
int modssl_smart_shutdown(SSL *ssl);
|
||||
BOOL modssl_X509_getBC(X509 *, int *, int *);
|
||||
char *modssl_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne,
|
22
httpd-2.4.35-r1842888.patch
Normal file
22
httpd-2.4.35-r1842888.patch
Normal file
@ -0,0 +1,22 @@
|
||||
diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c
|
||||
index d218bab..9f86b09 100644
|
||||
--- a/modules/filters/mod_deflate.c
|
||||
+++ b/modules/filters/mod_deflate.c
|
||||
@@ -864,7 +864,7 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
|
||||
|
||||
if (c->note_output_name) {
|
||||
apr_table_setn(r->notes, c->note_output_name,
|
||||
- (ctx->stream.total_in > 0)
|
||||
+ (ctx->stream.total_out > 0)
|
||||
? apr_off_t_toa(r->pool,
|
||||
ctx->stream.total_out)
|
||||
: "-");
|
||||
@@ -1336,8 +1336,6 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
|
||||
ctx->stream.next_in = (unsigned char *)data;
|
||||
ctx->stream.avail_in = (int)len;
|
||||
|
||||
- zRC = Z_OK;
|
||||
-
|
||||
if (!ctx->validation_buffer) {
|
||||
while (ctx->stream.avail_in != 0) {
|
||||
if (ctx->stream.avail_out == 0) {
|
65
httpd-2.4.35-selinux.patch
Normal file
65
httpd-2.4.35-selinux.patch
Normal file
@ -0,0 +1,65 @@
|
||||
|
||||
Log the SELinux context at startup.
|
||||
|
||||
Upstream-Status: unlikely to be any interest in this upstream
|
||||
|
||||
diff --git a/configure.in b/configure.in
|
||||
index eedba50..a208b53 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -484,6 +484,11 @@ getloadavg
|
||||
dnl confirm that a void pointer is large enough to store a long integer
|
||||
APACHE_CHECK_VOID_PTR_LEN
|
||||
|
||||
+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 <unistd.h>
|
||||
diff --git a/server/core.c b/server/core.c
|
||||
index ec74029..cb8e463 100644
|
||||
--- a/server/core.c
|
||||
+++ b/server/core.c
|
||||
@@ -59,6 +59,10 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_SELINUX
|
||||
+#include <selinux/selinux.h>
|
||||
+#endif
|
||||
+
|
||||
/* LimitRequestBody handling */
|
||||
#define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1)
|
||||
#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0)
|
||||
@@ -4971,6 +4975,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;
|
||||
}
|
||||
|
31
httpd-2.4.35-sslciphdefault.patch
Normal file
31
httpd-2.4.35-sslciphdefault.patch
Normal file
@ -0,0 +1,31 @@
|
||||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
|
||||
index 4cfd2d0..6ac55bd 100644
|
||||
--- a/modules/ssl/ssl_engine_config.c
|
||||
+++ b/modules/ssl/ssl_engine_config.c
|
||||
@@ -776,9 +776,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 {
|
||||
@@ -1542,8 +1544,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;
|
||||
}
|
245
httpd-2.4.35-systemd.patch
Normal file
245
httpd-2.4.35-systemd.patch
Normal file
@ -0,0 +1,245 @@
|
||||
--- httpd-2.4.33/modules/arch/unix/config5.m4.systemd
|
||||
+++ httpd-2.4.33/modules/arch/unix/config5.m4
|
||||
@@ -18,6 +18,16 @@
|
||||
fi
|
||||
])
|
||||
|
||||
+APACHE_MODULE(systemd, Systemd support, , , all, [
|
||||
+ if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
|
||||
+ AC_MSG_WARN([Your system does not support systemd.])
|
||||
+ enable_systemd="no"
|
||||
+ else
|
||||
+ APR_ADDTO(MOD_SYSTEMD_LDADD, [$SYSTEMD_LIBS])
|
||||
+ enable_systemd="yes"
|
||||
+ fi
|
||||
+])
|
||||
+
|
||||
APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
|
||||
|
||||
APACHE_MODPATH_FINISH
|
||||
--- httpd-2.4.33/modules/arch/unix/mod_systemd.c.systemd
|
||||
+++ httpd-2.4.33/modules/arch/unix/mod_systemd.c
|
||||
@@ -0,0 +1,223 @@
|
||||
+/* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
+ * contributor license agreements. See the NOTICE file distributed with
|
||||
+ * this work for additional information regarding copyright ownership.
|
||||
+ * The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
+ * (the "License"); you may not use this file except in compliance with
|
||||
+ * the License. You may obtain a copy of the License at
|
||||
+ *
|
||||
+ * http://www.apache.org/licenses/LICENSE-2.0
|
||||
+ *
|
||||
+ * Unless required by applicable law or agreed to in writing, software
|
||||
+ * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
+ * See the License for the specific language governing permissions and
|
||||
+ * limitations under the License.
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <stdint.h>
|
||||
+#include <ap_config.h>
|
||||
+#include "ap_mpm.h"
|
||||
+#include <http_core.h>
|
||||
+#include <httpd.h>
|
||||
+#include <http_log.h>
|
||||
+#include <apr_version.h>
|
||||
+#include <apr_pools.h>
|
||||
+#include <apr_strings.h>
|
||||
+#include "unixd.h"
|
||||
+#include "scoreboard.h"
|
||||
+#include "mpm_common.h"
|
||||
+
|
||||
+#include "systemd/sd-daemon.h"
|
||||
+#include "systemd/sd-journal.h"
|
||||
+
|
||||
+#if APR_HAVE_UNISTD_H
|
||||
+#include <unistd.h>
|
||||
+#endif
|
||||
+
|
||||
+static int shutdown_timer = 0;
|
||||
+static int shutdown_counter = 0;
|
||||
+static unsigned long bytes_served;
|
||||
+static pid_t mainpid;
|
||||
+static char describe_listeners[50];
|
||||
+
|
||||
+static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
|
||||
+ apr_pool_t *ptemp)
|
||||
+{
|
||||
+ sd_notify(0,
|
||||
+ "RELOADING=1\n"
|
||||
+ "STATUS=Reading configuration...\n");
|
||||
+ ap_extended_status = 1;
|
||||
+ return OK;
|
||||
+}
|
||||
+
|
||||
+static char *dump_listener(ap_listen_rec *lr, apr_pool_t *p)
|
||||
+{
|
||||
+ apr_sockaddr_t *sa = lr->bind_addr;
|
||||
+ char addr[128];
|
||||
+
|
||||
+ if (apr_sockaddr_is_wildcard(sa)) {
|
||||
+ return apr_pstrcat(p, "port ", apr_itoa(p, sa->port), NULL);
|
||||
+ }
|
||||
+
|
||||
+ apr_sockaddr_ip_getbuf(addr, sizeof addr, sa);
|
||||
+
|
||||
+ return apr_psprintf(p, "%s port %u", addr, sa->port);
|
||||
+}
|
||||
+
|
||||
+static int systemd_post_config(apr_pool_t *pconf, apr_pool_t *plog,
|
||||
+ apr_pool_t *ptemp, server_rec *s)
|
||||
+{
|
||||
+ ap_listen_rec *lr;
|
||||
+ apr_size_t plen = sizeof describe_listeners;
|
||||
+ char *p = describe_listeners;
|
||||
+
|
||||
+ if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
|
||||
+ return OK;
|
||||
+
|
||||
+ for (lr = ap_listeners; lr; lr = lr->next) {
|
||||
+ char *s = dump_listener(lr, ptemp);
|
||||
+
|
||||
+ if (strlen(s) + 3 < plen) {
|
||||
+ char *newp = apr_cpystrn(p, s, plen);
|
||||
+ if (lr->next)
|
||||
+ newp = apr_cpystrn(newp, ", ", 3);
|
||||
+ plen -= newp - p;
|
||||
+ p = newp;
|
||||
+ }
|
||||
+ else {
|
||||
+ if (plen < 4) {
|
||||
+ p = describe_listeners + sizeof describe_listeners - 4;
|
||||
+ plen = 4;
|
||||
+ }
|
||||
+ apr_cpystrn(p, "...", plen);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ sd_journal_print(LOG_INFO, "Server configured, listening on: %s", describe_listeners);
|
||||
+
|
||||
+ return OK;
|
||||
+}
|
||||
+
|
||||
+static int systemd_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type)
|
||||
+{
|
||||
+ int rv;
|
||||
+
|
||||
+ mainpid = getpid();
|
||||
+
|
||||
+ rv = sd_notifyf(0, "READY=1\n"
|
||||
+ "STATUS=Started, listening on: %s\n"
|
||||
+ "MAINPID=%" APR_PID_T_FMT,
|
||||
+ describe_listeners, mainpid);
|
||||
+ if (rv < 0) {
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_ERR, 0, p, APLOGNO(02395)
|
||||
+ "sd_notifyf returned an error %d", rv);
|
||||
+ }
|
||||
+
|
||||
+ return OK;
|
||||
+}
|
||||
+
|
||||
+static int systemd_monitor(apr_pool_t *p, server_rec *s)
|
||||
+{
|
||||
+ ap_sload_t sload;
|
||||
+ apr_interval_time_t up_time;
|
||||
+ char bps[5];
|
||||
+ int rv;
|
||||
+
|
||||
+ if (!ap_extended_status) {
|
||||
+ /* Nothing useful to report if ExtendedStatus disabled. */
|
||||
+ return DECLINED;
|
||||
+ }
|
||||
+
|
||||
+ ap_get_sload(&sload);
|
||||
+
|
||||
+ if (sload.access_count == 0) {
|
||||
+ rv = sd_notifyf(0, "READY=1\n"
|
||||
+ "STATUS=Running, listening on: %s\n",
|
||||
+ describe_listeners);
|
||||
+ }
|
||||
+ else {
|
||||
+ /* up_time in seconds */
|
||||
+ up_time = (apr_uint32_t) apr_time_sec(apr_time_now() -
|
||||
+ ap_scoreboard_image->global->restart_time);
|
||||
+
|
||||
+ apr_strfsize((unsigned long)((float) (sload.bytes_served)
|
||||
+ / (float) up_time), bps);
|
||||
+
|
||||
+ rv = sd_notifyf(0, "READY=1\n"
|
||||
+ "STATUS=Total requests: %lu; Idle/Busy workers %d/%d;"
|
||||
+ "Requests/sec: %.3g; Bytes served/sec: %sB/sec\n",
|
||||
+ sload.access_count, sload.idle, sload.busy,
|
||||
+ ((float) sload.access_count) / (float) up_time, bps);
|
||||
+ }
|
||||
+
|
||||
+ if (rv < 0) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02396)
|
||||
+ "sd_notifyf returned an error %d", rv);
|
||||
+ }
|
||||
+
|
||||
+ /* Shutdown httpd when nothing is sent for shutdown_timer seconds. */
|
||||
+ if (sload.bytes_served == bytes_served) {
|
||||
+ /* mpm_common.c: INTERVAL_OF_WRITABLE_PROBES is 10 */
|
||||
+ shutdown_counter += 10;
|
||||
+ if (shutdown_timer > 0 && shutdown_counter >= shutdown_timer) {
|
||||
+ rv = sd_notifyf(0, "READY=1\n"
|
||||
+ "STATUS=Stopped as result of IdleShutdown "
|
||||
+ "timeout.");
|
||||
+ if (rv < 0) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02804)
|
||||
+ "sd_notifyf returned an error %d", rv);
|
||||
+ }
|
||||
+ kill(mainpid, AP_SIG_GRACEFUL);
|
||||
+ }
|
||||
+ }
|
||||
+ else {
|
||||
+ shutdown_counter = 0;
|
||||
+ }
|
||||
+
|
||||
+ bytes_served = sload.bytes_served;
|
||||
+
|
||||
+ return DECLINED;
|
||||
+}
|
||||
+
|
||||
+static void systemd_register_hooks(apr_pool_t *p)
|
||||
+{
|
||||
+ /* Enable ap_extended_status. */
|
||||
+ ap_hook_pre_config(systemd_pre_config, NULL, NULL, APR_HOOK_LAST);
|
||||
+ /* Grab the listener config. */
|
||||
+ ap_hook_post_config(systemd_post_config, NULL, NULL, APR_HOOK_LAST);
|
||||
+ /* We know the PID in this hook ... */
|
||||
+ ap_hook_pre_mpm(systemd_pre_mpm, NULL, NULL, APR_HOOK_LAST);
|
||||
+ /* Used to update httpd's status line using sd_notifyf */
|
||||
+ ap_hook_monitor(systemd_monitor, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
+}
|
||||
+
|
||||
+static const char *set_shutdown_timer(cmd_parms *cmd, void *dummy,
|
||||
+ const char *arg)
|
||||
+{
|
||||
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
|
||||
+ if (err != NULL) {
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ shutdown_timer = atoi(arg);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static const command_rec systemd_cmds[] =
|
||||
+{
|
||||
+AP_INIT_TAKE1("IdleShutdown", set_shutdown_timer, NULL, RSRC_CONF,
|
||||
+ "Number of seconds in idle-state after which httpd is shutdown"),
|
||||
+ {NULL}
|
||||
+};
|
||||
+
|
||||
+AP_DECLARE_MODULE(systemd) = {
|
||||
+ STANDARD20_MODULE_STUFF,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ NULL,
|
||||
+ systemd_cmds,
|
||||
+ systemd_register_hooks,
|
||||
+};
|
39
httpd-2.4.37-CVE-2018-17199.patch
Normal file
39
httpd-2.4.37-CVE-2018-17199.patch
Normal file
@ -0,0 +1,39 @@
|
||||
diff --git a/modules/session/mod_session.c b/modules/session/mod_session.c
|
||||
index 10e6396..7ee477c 100644
|
||||
--- a/modules/session/mod_session.c
|
||||
+++ b/modules/session/mod_session.c
|
||||
@@ -126,20 +126,23 @@ static apr_status_t ap_session_load(request_rec * r, session_rec ** z)
|
||||
|
||||
/* found a session that hasn't expired? */
|
||||
now = apr_time_now();
|
||||
+
|
||||
if (zz) {
|
||||
- if (zz->expiry && zz->expiry < now) {
|
||||
+ /* load the session attibutes */
|
||||
+ rv = ap_run_session_decode(r, zz);
|
||||
+
|
||||
+ /* having a session we cannot decode is just as good as having
|
||||
+ none at all */
|
||||
+ if (OK != rv) {
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01817)
|
||||
+ "error while decoding the session, "
|
||||
+ "session not loaded: %s", r->uri);
|
||||
zz = NULL;
|
||||
}
|
||||
- else {
|
||||
- /* having a session we cannot decode is just as good as having
|
||||
- none at all */
|
||||
- rv = ap_run_session_decode(r, zz);
|
||||
- if (OK != rv) {
|
||||
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01817)
|
||||
- "error while decoding the session, "
|
||||
- "session not loaded: %s", r->uri);
|
||||
- zz = NULL;
|
||||
- }
|
||||
+
|
||||
+ /* invalidate session if session is expired */
|
||||
+ if (zz && zz->expiry && zz->expiry < now) {
|
||||
+ zz = NULL;
|
||||
}
|
||||
}
|
||||
|
207
httpd-2.4.37-CVE-2019-0211.patch
Normal file
207
httpd-2.4.37-CVE-2019-0211.patch
Normal file
@ -0,0 +1,207 @@
|
||||
diff --git a/include/scoreboard.h b/include/scoreboard.h
|
||||
index 9376da2..92d198d 100644
|
||||
--- a/include/scoreboard.h
|
||||
+++ b/include/scoreboard.h
|
||||
@@ -148,7 +148,9 @@ struct process_score {
|
||||
apr_uint32_t lingering_close; /* async connections in lingering close */
|
||||
apr_uint32_t keep_alive; /* async connections in keep alive */
|
||||
apr_uint32_t suspended; /* connections suspended by some module */
|
||||
- int bucket; /* Listener bucket used by this child */
|
||||
+ int bucket; /* Listener bucket used by this child; this field is DEPRECATED
|
||||
+ * and no longer updated by the MPMs (i.e. always zero).
|
||||
+ */
|
||||
};
|
||||
|
||||
/* Scoreboard is now in 'local' memory, since it isn't updated once created,
|
||||
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c
|
||||
index ffe8a23..048ae61 100644
|
||||
--- a/server/mpm/event/event.c
|
||||
+++ b/server/mpm/event/event.c
|
||||
@@ -2695,7 +2695,6 @@ static int make_child(server_rec * s, int slot, int bucket)
|
||||
|
||||
ap_scoreboard_image->parent[slot].quiescing = 0;
|
||||
ap_scoreboard_image->parent[slot].not_accepting = 0;
|
||||
- ap_scoreboard_image->parent[slot].bucket = bucket;
|
||||
event_note_child_started(slot, pid);
|
||||
active_daemons++;
|
||||
retained->total_daemons++;
|
||||
@@ -2734,6 +2733,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
|
||||
* that threads_per_child is always > 0 */
|
||||
int status = SERVER_DEAD;
|
||||
int child_threads_active = 0;
|
||||
+ int bucket = i % num_buckets;
|
||||
|
||||
if (i >= retained->max_daemons_limit &&
|
||||
free_length == retained->idle_spawn_rate[child_bucket]) {
|
||||
@@ -2757,7 +2757,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
|
||||
*/
|
||||
if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
|
||||
&& ps->generation == retained->mpm->my_generation
|
||||
- && ps->bucket == child_bucket)
|
||||
+ && bucket == child_bucket)
|
||||
{
|
||||
++idle_thread_count;
|
||||
}
|
||||
@@ -2768,7 +2768,9 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
|
||||
last_non_dead = i;
|
||||
}
|
||||
active_thread_count += child_threads_active;
|
||||
- if (!ps->pid && free_length < retained->idle_spawn_rate[child_bucket])
|
||||
+ if (!ps->pid
|
||||
+ && bucket == child_bucket
|
||||
+ && free_length < retained->idle_spawn_rate[child_bucket])
|
||||
free_slots[free_length++] = i;
|
||||
else if (child_threads_active == threads_per_child)
|
||||
had_healthy_child = 1;
|
||||
@@ -2951,13 +2953,14 @@ static void server_main_loop(int remaining_children_to_start, int num_buckets)
|
||||
retained->total_daemons--;
|
||||
if (processed_status == APEXIT_CHILDSICK) {
|
||||
/* resource shortage, minimize the fork rate */
|
||||
- retained->idle_spawn_rate[ps->bucket] = 1;
|
||||
+ retained->idle_spawn_rate[child_slot % num_buckets] = 1;
|
||||
}
|
||||
else if (remaining_children_to_start) {
|
||||
/* we're still doing a 1-for-1 replacement of dead
|
||||
* children with new children
|
||||
*/
|
||||
- make_child(ap_server_conf, child_slot, ps->bucket);
|
||||
+ make_child(ap_server_conf, child_slot,
|
||||
+ child_slot % num_buckets);
|
||||
--remaining_children_to_start;
|
||||
}
|
||||
}
|
||||
diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c
|
||||
index 8efda72..7c00625 100644
|
||||
--- a/server/mpm/prefork/prefork.c
|
||||
+++ b/server/mpm/prefork/prefork.c
|
||||
@@ -637,8 +637,9 @@ static void child_main(int child_num_arg, int child_bucket)
|
||||
}
|
||||
|
||||
|
||||
-static int make_child(server_rec *s, int slot, int bucket)
|
||||
+static int make_child(server_rec *s, int slot)
|
||||
{
|
||||
+ int bucket = slot % retained->mpm->num_buckets;
|
||||
int pid;
|
||||
|
||||
if (slot + 1 > retained->max_daemons_limit) {
|
||||
@@ -716,7 +717,6 @@ static int make_child(server_rec *s, int slot, int bucket)
|
||||
child_main(slot, bucket);
|
||||
}
|
||||
|
||||
- ap_scoreboard_image->parent[slot].bucket = bucket;
|
||||
prefork_note_child_started(slot, pid);
|
||||
|
||||
return 0;
|
||||
@@ -732,7 +732,7 @@ static void startup_children(int number_to_start)
|
||||
if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
|
||||
continue;
|
||||
}
|
||||
- if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) {
|
||||
+ if (make_child(ap_server_conf, i) < 0) {
|
||||
break;
|
||||
}
|
||||
--number_to_start;
|
||||
@@ -741,8 +741,6 @@ static void startup_children(int number_to_start)
|
||||
|
||||
static void perform_idle_server_maintenance(apr_pool_t *p)
|
||||
{
|
||||
- static int bucket_make_child_record = -1;
|
||||
- static int bucket_kill_child_record = -1;
|
||||
int i;
|
||||
int idle_count;
|
||||
worker_score *ws;
|
||||
@@ -789,6 +787,7 @@ static void perform_idle_server_maintenance(apr_pool_t *p)
|
||||
}
|
||||
retained->max_daemons_limit = last_non_dead + 1;
|
||||
if (idle_count > ap_daemons_max_free) {
|
||||
+ static int bucket_kill_child_record = -1;
|
||||
/* kill off one child... we use the pod because that'll cause it to
|
||||
* shut down gracefully, in case it happened to pick up a request
|
||||
* while we were counting
|
||||
@@ -819,10 +818,7 @@ static void perform_idle_server_maintenance(apr_pool_t *p)
|
||||
idle_count, total_non_dead);
|
||||
}
|
||||
for (i = 0; i < free_length; ++i) {
|
||||
- bucket_make_child_record++;
|
||||
- bucket_make_child_record %= retained->mpm->num_buckets;
|
||||
- make_child(ap_server_conf, free_slots[i],
|
||||
- bucket_make_child_record);
|
||||
+ make_child(ap_server_conf, free_slots[i]);
|
||||
}
|
||||
/* the next time around we want to spawn twice as many if this
|
||||
* wasn't good enough, but not if we've just done a graceful
|
||||
@@ -867,7 +863,7 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
|
||||
|
||||
if (one_process) {
|
||||
AP_MONCONTROL(1);
|
||||
- make_child(ap_server_conf, 0, 0);
|
||||
+ make_child(ap_server_conf, 0);
|
||||
/* NOTREACHED */
|
||||
ap_assert(0);
|
||||
return !OK;
|
||||
@@ -976,8 +972,7 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
|
||||
/* we're still doing a 1-for-1 replacement of dead
|
||||
* children with new children
|
||||
*/
|
||||
- make_child(ap_server_conf, child_slot,
|
||||
- ap_get_scoreboard_process(child_slot)->bucket);
|
||||
+ make_child(ap_server_conf, child_slot);
|
||||
--remaining_children_to_start;
|
||||
}
|
||||
#if APR_HAS_OTHER_CHILD
|
||||
diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c
|
||||
index 8012fe2..a927942 100644
|
||||
--- a/server/mpm/worker/worker.c
|
||||
+++ b/server/mpm/worker/worker.c
|
||||
@@ -1339,7 +1339,6 @@ static int make_child(server_rec *s, int slot, int bucket)
|
||||
worker_note_child_lost_slot(slot, pid);
|
||||
}
|
||||
ap_scoreboard_image->parent[slot].quiescing = 0;
|
||||
- ap_scoreboard_image->parent[slot].bucket = bucket;
|
||||
worker_note_child_started(slot, pid);
|
||||
return 0;
|
||||
}
|
||||
@@ -1388,6 +1387,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
|
||||
int any_dead_threads = 0;
|
||||
int all_dead_threads = 1;
|
||||
int child_threads_active = 0;
|
||||
+ int bucket = i % num_buckets;
|
||||
|
||||
if (i >= retained->max_daemons_limit &&
|
||||
totally_free_length == retained->idle_spawn_rate[child_bucket]) {
|
||||
@@ -1420,7 +1420,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
|
||||
if (status <= SERVER_READY &&
|
||||
!ps->quiescing &&
|
||||
ps->generation == retained->mpm->my_generation &&
|
||||
- ps->bucket == child_bucket) {
|
||||
+ bucket == child_bucket) {
|
||||
++idle_thread_count;
|
||||
}
|
||||
if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
|
||||
@@ -1430,6 +1430,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
|
||||
}
|
||||
active_thread_count += child_threads_active;
|
||||
if (any_dead_threads
|
||||
+ && bucket == child_bucket
|
||||
&& totally_free_length < retained->idle_spawn_rate[child_bucket]
|
||||
&& free_length < MAX_SPAWN_RATE / num_buckets
|
||||
&& (!ps->pid /* no process in the slot */
|
||||
@@ -1615,14 +1616,15 @@ static void server_main_loop(int remaining_children_to_start, int num_buckets)
|
||||
ps->quiescing = 0;
|
||||
if (processed_status == APEXIT_CHILDSICK) {
|
||||
/* resource shortage, minimize the fork rate */
|
||||
- retained->idle_spawn_rate[ps->bucket] = 1;
|
||||
+ retained->idle_spawn_rate[child_slot % num_buckets] = 1;
|
||||
}
|
||||
else if (remaining_children_to_start
|
||||
&& child_slot < ap_daemons_limit) {
|
||||
/* we're still doing a 1-for-1 replacement of dead
|
||||
* children with new children
|
||||
*/
|
||||
- make_child(ap_server_conf, child_slot, ps->bucket);
|
||||
+ make_child(ap_server_conf, child_slot,
|
||||
+ child_slot % num_buckets);
|
||||
--remaining_children_to_start;
|
||||
}
|
||||
}
|
20
httpd-2.4.37-CVE-2019-0215.patch
Normal file
20
httpd-2.4.37-CVE-2019-0215.patch
Normal file
@ -0,0 +1,20 @@
|
||||
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
|
||||
index de0ffb0..e6a9f67 100644
|
||||
--- a/modules/ssl/ssl_engine_kernel.c
|
||||
+++ b/modules/ssl/ssl_engine_kernel.c
|
||||
@@ -1154,6 +1154,7 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
|
||||
ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
|
||||
apr_table_setn(r->notes, "error-notes",
|
||||
"Reason: Cannot perform Post-Handshake Authentication.<br />");
|
||||
+ SSL_set_verify(ssl, vmode_inplace, NULL);
|
||||
return HTTP_FORBIDDEN;
|
||||
}
|
||||
|
||||
@@ -1175,6 +1176,7 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
|
||||
* Finally check for acceptable renegotiation results
|
||||
*/
|
||||
if (OK != (rc = ssl_check_post_client_verify(r, sc, dc, sslconn, ssl))) {
|
||||
+ SSL_set_verify(ssl, vmode_inplace, NULL);
|
||||
return rc;
|
||||
}
|
||||
}
|
111
httpd-2.4.37-CVE-2019-0217.patch
Normal file
111
httpd-2.4.37-CVE-2019-0217.patch
Normal file
@ -0,0 +1,111 @@
|
||||
--- a/modules/aaa/mod_auth_digest.c 2019/03/12 09:24:19 1855297
|
||||
+++ b/modules/aaa/mod_auth_digest.c 2019/03/12 09:24:26 1855298
|
||||
@@ -92,7 +92,6 @@
|
||||
int check_nc;
|
||||
const char *algorithm;
|
||||
char *uri_list;
|
||||
- const char *ha1;
|
||||
} digest_config_rec;
|
||||
|
||||
|
||||
@@ -153,6 +152,7 @@
|
||||
apr_time_t nonce_time;
|
||||
enum hdr_sts auth_hdr_sts;
|
||||
int needed_auth;
|
||||
+ const char *ha1;
|
||||
client_entry *client;
|
||||
} digest_header_rec;
|
||||
|
||||
@@ -1304,7 +1304,7 @@
|
||||
*/
|
||||
|
||||
static authn_status get_hash(request_rec *r, const char *user,
|
||||
- digest_config_rec *conf)
|
||||
+ digest_config_rec *conf, const char **rethash)
|
||||
{
|
||||
authn_status auth_result;
|
||||
char *password;
|
||||
@@ -1356,7 +1356,7 @@
|
||||
} while (current_provider);
|
||||
|
||||
if (auth_result == AUTH_USER_FOUND) {
|
||||
- conf->ha1 = password;
|
||||
+ *rethash = password;
|
||||
}
|
||||
|
||||
return auth_result;
|
||||
@@ -1483,25 +1483,24 @@
|
||||
|
||||
/* RFC-2069 */
|
||||
static const char *old_digest(const request_rec *r,
|
||||
- const digest_header_rec *resp, const char *ha1)
|
||||
+ const digest_header_rec *resp)
|
||||
{
|
||||
const char *ha2;
|
||||
|
||||
ha2 = ap_md5(r->pool, (unsigned char *)apr_pstrcat(r->pool, resp->method, ":",
|
||||
resp->uri, NULL));
|
||||
return ap_md5(r->pool,
|
||||
- (unsigned char *)apr_pstrcat(r->pool, ha1, ":", resp->nonce,
|
||||
- ":", ha2, NULL));
|
||||
+ (unsigned char *)apr_pstrcat(r->pool, resp->ha1, ":",
|
||||
+ resp->nonce, ":", ha2, NULL));
|
||||
}
|
||||
|
||||
/* RFC-2617 */
|
||||
static const char *new_digest(const request_rec *r,
|
||||
- digest_header_rec *resp,
|
||||
- const digest_config_rec *conf)
|
||||
+ digest_header_rec *resp)
|
||||
{
|
||||
const char *ha1, *ha2, *a2;
|
||||
|
||||
- ha1 = conf->ha1;
|
||||
+ ha1 = resp->ha1;
|
||||
|
||||
a2 = apr_pstrcat(r->pool, resp->method, ":", resp->uri, NULL);
|
||||
ha2 = ap_md5(r->pool, (const unsigned char *)a2);
|
||||
@@ -1514,7 +1513,6 @@
|
||||
NULL));
|
||||
}
|
||||
|
||||
-
|
||||
static void copy_uri_components(apr_uri_t *dst,
|
||||
apr_uri_t *src, request_rec *r) {
|
||||
if (src->scheme && src->scheme[0] != '\0') {
|
||||
@@ -1759,7 +1757,7 @@
|
||||
return HTTP_UNAUTHORIZED;
|
||||
}
|
||||
|
||||
- return_code = get_hash(r, r->user, conf);
|
||||
+ return_code = get_hash(r, r->user, conf, &resp->ha1);
|
||||
|
||||
if (return_code == AUTH_USER_NOT_FOUND) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01790)
|
||||
@@ -1789,7 +1787,7 @@
|
||||
|
||||
if (resp->message_qop == NULL) {
|
||||
/* old (rfc-2069) style digest */
|
||||
- if (strcmp(resp->digest, old_digest(r, resp, conf->ha1))) {
|
||||
+ if (strcmp(resp->digest, old_digest(r, resp))) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01792)
|
||||
"user %s: password mismatch: %s", r->user,
|
||||
r->uri);
|
||||
@@ -1819,7 +1817,7 @@
|
||||
return HTTP_UNAUTHORIZED;
|
||||
}
|
||||
|
||||
- exp_digest = new_digest(r, resp, conf);
|
||||
+ exp_digest = new_digest(r, resp);
|
||||
if (!exp_digest) {
|
||||
/* we failed to allocate a client struct */
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
@@ -1903,7 +1901,7 @@
|
||||
|
||||
/* calculate rspauth attribute
|
||||
*/
|
||||
- ha1 = conf->ha1;
|
||||
+ ha1 = resp->ha1;
|
||||
|
||||
a2 = apr_pstrcat(r->pool, ":", resp->uri, NULL);
|
||||
ha2 = ap_md5(r->pool, (const unsigned char *)a2);
|
235
httpd-2.4.37-CVE-2019-0220.patch
Normal file
235
httpd-2.4.37-CVE-2019-0220.patch
Normal file
@ -0,0 +1,235 @@
|
||||
diff --git a/docs/manual/mod/core.html.en b/docs/manual/mod/core.html.en
|
||||
index 0a24bc8..20d1e5a 100644
|
||||
--- a/docs/manual/mod/core.html.en
|
||||
+++ b/docs/manual/mod/core.html.en
|
||||
@@ -97,6 +97,7 @@ available</td></tr>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#maxrangeoverlaps">MaxRangeOverlaps</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#maxrangereversals">MaxRangeReversals</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#maxranges">MaxRanges</a></li>
|
||||
+<li><img alt="" src="../images/down.gif" /> <a href="#mergeslashes">MergeSlashes</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#mergetrailers">MergeTrailers</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#mutex">Mutex</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#namevirtualhost">NameVirtualHost</a></li>
|
||||
@@ -3465,6 +3466,30 @@ resource </td></tr>
|
||||
|
||||
</div>
|
||||
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
+<div class="directive-section"><h2><a name="MergeSlashes" id="MergeSlashes">MergeSlashes</a> <a name="mergeslashes" id="mergeslashes">Directive</a></h2>
|
||||
+<table class="directive">
|
||||
+<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Controls whether the server merges consecutive slashes in URLs. </td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>MergeSlashes ON | OFF</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>MergeSlashes ON</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Core</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>core</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>Available in Apache HTTP Server 2.4.6 in Red Hat Enterprise Linux 7</td></tr>
|
||||
+</table>
|
||||
+ <p>By default, the server merges (or collapses) multiple consecutive slash
|
||||
+ ('/') characters in the path component of the request URL.</p>
|
||||
+
|
||||
+ <p>When mapping URL's to the filesystem, these multiple slashes are not
|
||||
+ significant. However, URL's handled other ways, such as by CGI or proxy,
|
||||
+ might prefer to retain the significance of multiple consecutive slashes.
|
||||
+ In these cases <code class="directive">MergeSlashes</code> can be set to
|
||||
+ <em>OFF</em> to retain the multiple consecutive slashes. In these
|
||||
+ configurations, regular expressions used in the configuration file that match
|
||||
+ the path component of the URL (<code class="directive">LocationMatch</code>,
|
||||
+ <code class="directive">RewriteRule</code>, ...) need to take into account multiple
|
||||
+ consecutive slashes.</p>
|
||||
+</div>
|
||||
+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
<div class="directive-section"><h2><a name="MergeTrailers" id="MergeTrailers">MergeTrailers</a> <a name="mergetrailers" id="mergetrailers">Directive</a></h2>
|
||||
<table class="directive">
|
||||
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Determines whether trailers are merged into headers</td></tr>
|
||||
--- a/include/http_core.h 2019/03/18 08:49:19 1855736
|
||||
+++ b/include/http_core.h 2019/03/18 08:49:59 1855737
|
||||
@@ -740,7 +740,7 @@
|
||||
#define AP_HTTP_METHODS_LENIENT 1
|
||||
#define AP_HTTP_METHODS_REGISTERED 2
|
||||
char http_methods;
|
||||
-
|
||||
+ unsigned int merge_slashes;
|
||||
} core_server_config;
|
||||
|
||||
/* for AddOutputFiltersByType in core.c */
|
||||
diff --git a/include/httpd.h b/include/httpd.h
|
||||
index 65392f8..99f7f04 100644
|
||||
--- a/include/httpd.h
|
||||
+++ b/include/httpd.h
|
||||
@@ -1697,11 +1697,21 @@ AP_DECLARE(int) ap_unescape_url_keep2f(char *url, int decode_slashes);
|
||||
AP_DECLARE(int) ap_unescape_urlencoded(char *query);
|
||||
|
||||
/**
|
||||
- * Convert all double slashes to single slashes
|
||||
- * @param name The string to convert
|
||||
+ * Convert all double slashes to single slashes, except where significant
|
||||
+ * to the filesystem on the current platform.
|
||||
+ * @param name The string to convert, assumed to be a filesystem path
|
||||
*/
|
||||
AP_DECLARE(void) ap_no2slash(char *name);
|
||||
|
||||
+/**
|
||||
+ * Convert all double slashes to single slashes, except where significant
|
||||
+ * to the filesystem on the current platform.
|
||||
+ * @param name The string to convert
|
||||
+ * @param is_fs_path if set to 0, the significance of any double-slashes is
|
||||
+ * ignored.
|
||||
+ */
|
||||
+AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path);
|
||||
+
|
||||
/**
|
||||
* Remove all ./ and xx/../ substrings from a file name. Also remove
|
||||
* any leading ../ or /../ substrings.
|
||||
diff --git a/server/request.c b/server/request.c
|
||||
index dbe3e07..d5c558a 100644
|
||||
--- a/server/request.c
|
||||
+++ b/server/request.c
|
||||
@@ -167,6 +167,8 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r)
|
||||
int file_req = (r->main && r->filename);
|
||||
int access_status;
|
||||
core_dir_config *d;
|
||||
+ core_server_config *sconf =
|
||||
+ ap_get_core_module_config(r->server->module_config);
|
||||
|
||||
/* Ignore embedded %2F's in path for proxy requests */
|
||||
if (!r->proxyreq && r->parsed_uri.path) {
|
||||
@@ -191,6 +193,12 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r)
|
||||
}
|
||||
|
||||
ap_getparents(r->uri); /* OK --- shrinking transformations... */
|
||||
+ if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) {
|
||||
+ ap_no2slash(r->uri);
|
||||
+ if (r->parsed_uri.path) {
|
||||
+ ap_no2slash(r->parsed_uri.path);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/* All file subrequests are a huge pain... they cannot bubble through the
|
||||
* next several steps. Only file subrequests are allowed an empty uri,
|
||||
@@ -1411,20 +1419,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
|
||||
|
||||
cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r);
|
||||
cached = (cache->cached != NULL);
|
||||
-
|
||||
- /* Location and LocationMatch differ on their behaviour w.r.t. multiple
|
||||
- * slashes. Location matches multiple slashes with a single slash,
|
||||
- * LocationMatch doesn't. An exception, for backwards brokenness is
|
||||
- * absoluteURIs... in which case neither match multiple slashes.
|
||||
- */
|
||||
- if (r->uri[0] != '/') {
|
||||
- entry_uri = r->uri;
|
||||
- }
|
||||
- else {
|
||||
- char *uri = apr_pstrdup(r->pool, r->uri);
|
||||
- ap_no2slash(uri);
|
||||
- entry_uri = uri;
|
||||
- }
|
||||
+ entry_uri = r->uri;
|
||||
|
||||
/* If we have an cache->cached location that matches r->uri,
|
||||
* and the vhost's list of locations hasn't changed, we can skip
|
||||
@@ -1491,7 +1486,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
|
||||
pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
|
||||
}
|
||||
|
||||
- if (ap_regexec(entry_core->r, r->uri, nmatch, pmatch, 0)) {
|
||||
+ if (ap_regexec(entry_core->r, entry_uri, nmatch, pmatch, 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1501,7 +1496,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
|
||||
apr_table_setn(r->subprocess_env,
|
||||
((const char **)entry_core->refs->elts)[i],
|
||||
apr_pstrndup(r->pool,
|
||||
- r->uri + pmatch[i].rm_so,
|
||||
+ entry_uri + pmatch[i].rm_so,
|
||||
pmatch[i].rm_eo - pmatch[i].rm_so));
|
||||
}
|
||||
}
|
||||
diff --git a/server/util.c b/server/util.c
|
||||
index fd7a0a1..e0c558c 100644
|
||||
--- a/server/util.c
|
||||
+++ b/server/util.c
|
||||
@@ -561,16 +561,20 @@ AP_DECLARE(void) ap_getparents(char *name)
|
||||
name[l] = '\0';
|
||||
}
|
||||
}
|
||||
-
|
||||
-AP_DECLARE(void) ap_no2slash(char *name)
|
||||
+AP_DECLARE(void) ap_no2slash_ex(char *name, int is_fs_path)
|
||||
{
|
||||
+
|
||||
char *d, *s;
|
||||
|
||||
+ if (!*name) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
s = d = name;
|
||||
|
||||
#ifdef HAVE_UNC_PATHS
|
||||
/* Check for UNC names. Leave leading two slashes. */
|
||||
- if (s[0] == '/' && s[1] == '/')
|
||||
+ if (is_fs_path && s[0] == '/' && s[1] == '/')
|
||||
*d++ = *s++;
|
||||
#endif
|
||||
|
||||
@@ -587,6 +591,10 @@ AP_DECLARE(void) ap_no2slash(char *name)
|
||||
*d = '\0';
|
||||
}
|
||||
|
||||
+AP_DECLARE(void) ap_no2slash(char *name)
|
||||
+{
|
||||
+ ap_no2slash_ex(name, 1);
|
||||
+}
|
||||
|
||||
/*
|
||||
* copy at most n leading directories of s into d
|
||||
diff --git a/server/core.c b/server/core.c
|
||||
index b5ab429..a31f1e4 100644
|
||||
--- a/server/core.c
|
||||
+++ b/server/core.c
|
||||
@@ -493,6 +493,7 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s)
|
||||
*/
|
||||
|
||||
conf->trace_enable = AP_TRACE_UNSET;
|
||||
+ conf->merge_slashes = AP_CORE_CONFIG_UNSET;
|
||||
|
||||
conf->protocols = apr_array_make(a, 5, sizeof(const char *));
|
||||
conf->protocols_honor_order = -1;
|
||||
@@ -561,7 +562,9 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv)
|
||||
conf->protocols_honor_order = ((virt->protocols_honor_order < 0)?
|
||||
base->protocols_honor_order :
|
||||
virt->protocols_honor_order);
|
||||
-
|
||||
+
|
||||
+ AP_CORE_MERGE_FLAG(merge_slashes, conf, base, virt);
|
||||
+
|
||||
return conf;
|
||||
}
|
||||
|
||||
@@ -1872,6 +1875,13 @@ static const char *set_qualify_redirect_url(cmd_parms *cmd, void *d_, int flag)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static const char *set_core_server_flag(cmd_parms *cmd, void *s_, int flag)
|
||||
+{
|
||||
+ core_server_config *conf =
|
||||
+ ap_get_core_module_config(cmd->server->module_config);
|
||||
+ return ap_set_flag_slot(cmd, conf, flag);
|
||||
+}
|
||||
+
|
||||
static const char *set_override_list(cmd_parms *cmd, void *d_, int argc, char *const argv[])
|
||||
{
|
||||
core_dir_config *d = d_;
|
||||
@@ -4598,6 +4608,10 @@ AP_INIT_ITERATE("HttpProtocolOptions", set_http_protocol_options, NULL, RSRC_CON
|
||||
"'Unsafe' or 'Strict' (default). Sets HTTP acceptance rules"),
|
||||
AP_INIT_ITERATE("RegisterHttpMethod", set_http_method, NULL, RSRC_CONF,
|
||||
"Registers non-standard HTTP methods"),
|
||||
+AP_INIT_FLAG("MergeSlashes", set_core_server_flag,
|
||||
+ (void *)APR_OFFSETOF(core_server_config, merge_slashes),
|
||||
+ RSRC_CONF,
|
||||
+ "Controls whether consecutive slashes in the URI path are merged"),
|
||||
{ NULL }
|
||||
};
|
||||
|
192
httpd-2.4.37-CVE-2019-10092.patch
Normal file
192
httpd-2.4.37-CVE-2019-10092.patch
Normal file
@ -0,0 +1,192 @@
|
||||
diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c
|
||||
index e419eb6..dcafa9c 100644
|
||||
--- a/modules/http/http_protocol.c
|
||||
+++ b/modules/http/http_protocol.c
|
||||
@@ -1132,13 +1132,10 @@ static const char *get_canned_error_string(int status,
|
||||
"\">here</a>.</p>\n",
|
||||
NULL));
|
||||
case HTTP_USE_PROXY:
|
||||
- return(apr_pstrcat(p,
|
||||
- "<p>This resource is only accessible "
|
||||
- "through the proxy\n",
|
||||
- ap_escape_html(r->pool, location),
|
||||
- "<br />\nYou will need to configure "
|
||||
- "your client to use that proxy.</p>\n",
|
||||
- NULL));
|
||||
+ return("<p>This resource is only accessible "
|
||||
+ "through the proxy\n"
|
||||
+ "<br />\nYou will need to configure "
|
||||
+ "your client to use that proxy.</p>\n");
|
||||
case HTTP_PROXY_AUTHENTICATION_REQUIRED:
|
||||
case HTTP_UNAUTHORIZED:
|
||||
return("<p>This server could not verify that you\n"
|
||||
@@ -1154,34 +1151,20 @@ static const char *get_canned_error_string(int status,
|
||||
"error-notes",
|
||||
"</p>\n"));
|
||||
case HTTP_FORBIDDEN:
|
||||
- s1 = apr_pstrcat(p,
|
||||
- "<p>You don't have permission to access ",
|
||||
- ap_escape_html(r->pool, r->uri),
|
||||
- "\non this server.<br />\n",
|
||||
- NULL);
|
||||
- return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
|
||||
+ return(add_optional_notes(r, "<p>You don't have permission to access this resource.", "error-notes", "</p>\n"));
|
||||
case HTTP_NOT_FOUND:
|
||||
- return(apr_pstrcat(p,
|
||||
- "<p>The requested URL ",
|
||||
- ap_escape_html(r->pool, r->uri),
|
||||
- " was not found on this server.</p>\n",
|
||||
- NULL));
|
||||
+ return("<p>The requested URL was not found on this server.</p>\n");
|
||||
case HTTP_METHOD_NOT_ALLOWED:
|
||||
return(apr_pstrcat(p,
|
||||
"<p>The requested method ",
|
||||
ap_escape_html(r->pool, r->method),
|
||||
- " is not allowed for the URL ",
|
||||
- ap_escape_html(r->pool, r->uri),
|
||||
- ".</p>\n",
|
||||
+ " is not allowed for this URL.</p>\n",
|
||||
NULL));
|
||||
case HTTP_NOT_ACCEPTABLE:
|
||||
- s1 = apr_pstrcat(p,
|
||||
- "<p>An appropriate representation of the "
|
||||
- "requested resource ",
|
||||
- ap_escape_html(r->pool, r->uri),
|
||||
- " could not be found on this server.</p>\n",
|
||||
- NULL);
|
||||
- return(add_optional_notes(r, s1, "variant-list", ""));
|
||||
+ return(add_optional_notes(r,
|
||||
+ "<p>An appropriate representation of the requested resource "
|
||||
+ "could not be found on this server.</p>\n",
|
||||
+ "variant-list", ""));
|
||||
case HTTP_MULTIPLE_CHOICES:
|
||||
return(add_optional_notes(r, "", "variant-list", ""));
|
||||
case HTTP_LENGTH_REQUIRED:
|
||||
@@ -1192,18 +1175,13 @@ static const char *get_canned_error_string(int status,
|
||||
NULL);
|
||||
return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
|
||||
case HTTP_PRECONDITION_FAILED:
|
||||
- return(apr_pstrcat(p,
|
||||
- "<p>The precondition on the request "
|
||||
- "for the URL ",
|
||||
- ap_escape_html(r->pool, r->uri),
|
||||
- " evaluated to false.</p>\n",
|
||||
- NULL));
|
||||
+ return("<p>The precondition on the request "
|
||||
+ "for this URL evaluated to false.</p>\n");
|
||||
case HTTP_NOT_IMPLEMENTED:
|
||||
s1 = apr_pstrcat(p,
|
||||
"<p>",
|
||||
- ap_escape_html(r->pool, r->method), " to ",
|
||||
- ap_escape_html(r->pool, r->uri),
|
||||
- " not supported.<br />\n",
|
||||
+ ap_escape_html(r->pool, r->method), " ",
|
||||
+ " not supported for current URL.<br />\n",
|
||||
NULL);
|
||||
return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
|
||||
case HTTP_BAD_GATEWAY:
|
||||
@@ -1211,29 +1189,19 @@ static const char *get_canned_error_string(int status,
|
||||
"response from an upstream server.<br />" CRLF;
|
||||
return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
|
||||
case HTTP_VARIANT_ALSO_VARIES:
|
||||
- return(apr_pstrcat(p,
|
||||
- "<p>A variant for the requested "
|
||||
- "resource\n<pre>\n",
|
||||
- ap_escape_html(r->pool, r->uri),
|
||||
- "\n</pre>\nis itself a negotiable resource. "
|
||||
- "This indicates a configuration error.</p>\n",
|
||||
- NULL));
|
||||
+ return("<p>A variant for the requested "
|
||||
+ "resource\n<pre>\n"
|
||||
+ "\n</pre>\nis itself a negotiable resource. "
|
||||
+ "This indicates a configuration error.</p>\n");
|
||||
case HTTP_REQUEST_TIME_OUT:
|
||||
return("<p>Server timeout waiting for the HTTP request from the client.</p>\n");
|
||||
case HTTP_GONE:
|
||||
- return(apr_pstrcat(p,
|
||||
- "<p>The requested resource<br />",
|
||||
- ap_escape_html(r->pool, r->uri),
|
||||
- "<br />\nis no longer available on this server "
|
||||
- "and there is no forwarding address.\n"
|
||||
- "Please remove all references to this "
|
||||
- "resource.</p>\n",
|
||||
- NULL));
|
||||
+ return("<p>The requested resource is no longer available on this server"
|
||||
+ " and there is no forwarding address.\n"
|
||||
+ "Please remove all references to this resource.</p>\n");
|
||||
case HTTP_REQUEST_ENTITY_TOO_LARGE:
|
||||
return(apr_pstrcat(p,
|
||||
- "The requested resource<br />",
|
||||
- ap_escape_html(r->pool, r->uri), "<br />\n",
|
||||
- "does not allow request data with ",
|
||||
+ "The requested resource does not allow request data with ",
|
||||
ap_escape_html(r->pool, r->method),
|
||||
" requests, or the amount of data provided in\n"
|
||||
"the request exceeds the capacity limit.\n",
|
||||
@@ -1317,11 +1285,9 @@ static const char *get_canned_error_string(int status,
|
||||
"the Server Name Indication (SNI) in use for this\n"
|
||||
"connection.</p>\n");
|
||||
case HTTP_UNAVAILABLE_FOR_LEGAL_REASONS:
|
||||
- s1 = apr_pstrcat(p,
|
||||
- "<p>Access to ", ap_escape_html(r->pool, r->uri),
|
||||
- "\nhas been denied for legal reasons.<br />\n",
|
||||
- NULL);
|
||||
- return(add_optional_notes(r, s1, "error-notes", "</p>\n"));
|
||||
+ return(add_optional_notes(r,
|
||||
+ "<p>Access to this URL has been denied for legal reasons.<br />\n",
|
||||
+ "error-notes", "</p>\n"));
|
||||
default: /* HTTP_INTERNAL_SERVER_ERROR */
|
||||
/*
|
||||
* This comparison to expose error-notes could be modified to
|
||||
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
|
||||
index 800ede1..de48735 100644
|
||||
--- a/modules/proxy/mod_proxy.c
|
||||
+++ b/modules/proxy/mod_proxy.c
|
||||
@@ -1055,9 +1055,10 @@ static int proxy_handler(request_rec *r)
|
||||
char *end;
|
||||
maxfwd = apr_strtoi64(str, &end, 10);
|
||||
if (maxfwd < 0 || maxfwd == APR_INT64_MAX || *end) {
|
||||
- return ap_proxyerror(r, HTTP_BAD_REQUEST,
|
||||
- apr_psprintf(r->pool,
|
||||
- "Max-Forwards value '%s' could not be parsed", str));
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO()
|
||||
+ "Max-Forwards value '%s' could not be parsed", str);
|
||||
+ return ap_proxyerror(r, HTTP_BAD_REQUEST,
|
||||
+ "Max-Forwards request header could not be parsed");
|
||||
}
|
||||
else if (maxfwd == 0) {
|
||||
switch (r->method_number) {
|
||||
diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c
|
||||
index 4a10987..8f6f853 100644
|
||||
--- a/modules/proxy/mod_proxy_ftp.c
|
||||
+++ b/modules/proxy/mod_proxy_ftp.c
|
||||
@@ -1024,8 +1024,9 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
|
||||
/* We break the URL into host, port, path-search */
|
||||
if (r->parsed_uri.hostname == NULL) {
|
||||
if (APR_SUCCESS != apr_uri_parse(p, url, &uri)) {
|
||||
- return ap_proxyerror(r, HTTP_BAD_REQUEST,
|
||||
- apr_psprintf(p, "URI cannot be parsed: %s", url));
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO()
|
||||
+ "URI cannot be parsed: %s", url);
|
||||
+ return ap_proxyerror(r, HTTP_BAD_REQUEST, "URI cannot be parsed");
|
||||
}
|
||||
connectname = uri.hostname;
|
||||
connectport = uri.port;
|
||||
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
|
||||
index 6501c68..0bbfa59 100644
|
||||
--- a/modules/proxy/proxy_util.c
|
||||
+++ b/modules/proxy/proxy_util.c
|
||||
@@ -368,12 +368,9 @@ PROXY_DECLARE(char *)
|
||||
|
||||
PROXY_DECLARE(int) ap_proxyerror(request_rec *r, int statuscode, const char *message)
|
||||
{
|
||||
- const char *uri = ap_escape_html(r->pool, r->uri);
|
||||
apr_table_setn(r->notes, "error-notes",
|
||||
apr_pstrcat(r->pool,
|
||||
- "The proxy server could not handle the request <em><a href=\"",
|
||||
- uri, "\">", ap_escape_html(r->pool, r->method), " ", uri,
|
||||
- "</a></em>.<p>\n"
|
||||
+ "The proxy server could not handle the request<p>"
|
||||
"Reason: <strong>", ap_escape_html(r->pool, message),
|
||||
"</strong></p>",
|
||||
NULL));
|
66
httpd-2.4.37-CVE-2019-10097.patch
Normal file
66
httpd-2.4.37-CVE-2019-10097.patch
Normal file
@ -0,0 +1,66 @@
|
||||
diff --git a/modules/metadata/mod_remoteip.c b/modules/metadata/mod_remoteip.c
|
||||
index 4572ce1..a0cbc0f 100644
|
||||
--- a/modules/metadata/mod_remoteip.c
|
||||
+++ b/modules/metadata/mod_remoteip.c
|
||||
@@ -987,15 +987,13 @@ static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c,
|
||||
return HDR_ERROR;
|
||||
#endif
|
||||
default:
|
||||
- /* unsupported protocol, keep local connection address */
|
||||
- return HDR_DONE;
|
||||
+ /* unsupported protocol */
|
||||
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10183)
|
||||
+ "RemoteIPProxyProtocol: unsupported protocol %.2hx",
|
||||
+ (unsigned short)hdr->v2.fam);
|
||||
+ return HDR_ERROR;
|
||||
}
|
||||
break; /* we got a sockaddr now */
|
||||
-
|
||||
- case 0x00: /* LOCAL command */
|
||||
- /* keep local connection address for LOCAL */
|
||||
- return HDR_DONE;
|
||||
-
|
||||
default:
|
||||
/* not a supported command */
|
||||
ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03507)
|
||||
@@ -1087,11 +1085,24 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
|
||||
/* try to read a header's worth of data */
|
||||
while (!ctx->done) {
|
||||
if (APR_BRIGADE_EMPTY(ctx->bb)) {
|
||||
- ret = ap_get_brigade(f->next, ctx->bb, ctx->mode, block,
|
||||
- ctx->need - ctx->rcvd);
|
||||
+ apr_off_t got, want = ctx->need - ctx->rcvd;
|
||||
+
|
||||
+ ret = ap_get_brigade(f->next, ctx->bb, ctx->mode, block, want);
|
||||
if (ret != APR_SUCCESS) {
|
||||
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, f->c, APLOGNO(10184)
|
||||
+ "failed reading input");
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+ ret = apr_brigade_length(ctx->bb, 1, &got);
|
||||
+ if (ret || got > want) {
|
||||
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, f->c, APLOGNO(10185)
|
||||
+ "RemoteIPProxyProtocol header too long, "
|
||||
+ "got %" APR_OFF_T_FMT " expected %" APR_OFF_T_FMT,
|
||||
+ got, want);
|
||||
+ f->c->aborted = 1;
|
||||
+ return APR_ECONNABORTED;
|
||||
+ }
|
||||
}
|
||||
if (APR_BRIGADE_EMPTY(ctx->bb)) {
|
||||
return block == APR_NONBLOCK_READ ? APR_SUCCESS : APR_EOF;
|
||||
@@ -1139,6 +1150,13 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f,
|
||||
if (ctx->rcvd >= MIN_V2_HDR_LEN) {
|
||||
ctx->need = MIN_V2_HDR_LEN +
|
||||
remoteip_get_v2_len((proxy_header *) ctx->header);
|
||||
+ if (ctx->need > sizeof(proxy_v2)) {
|
||||
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(10186)
|
||||
+ "RemoteIPProxyProtocol protocol header length too long");
|
||||
+ f->c->aborted = 1;
|
||||
+ apr_brigade_destroy(ctx->bb);
|
||||
+ return APR_ECONNABORTED;
|
||||
+ }
|
||||
}
|
||||
if (ctx->rcvd >= ctx->need) {
|
||||
psts = remoteip_process_v2_header(f->c, conn_conf,
|
91
httpd-2.4.37-CVE-2019-10098.patch
Normal file
91
httpd-2.4.37-CVE-2019-10098.patch
Normal file
@ -0,0 +1,91 @@
|
||||
diff --git a/include/ap_regex.h b/include/ap_regex.h
|
||||
index 7d8df79..7af2f99 100644
|
||||
--- a/include/ap_regex.h
|
||||
+++ b/include/ap_regex.h
|
||||
@@ -84,7 +84,11 @@ extern "C" {
|
||||
|
||||
#define AP_REG_DOLLAR_ENDONLY 0x200 /* '$' matches at end of subject string only */
|
||||
|
||||
-#define AP_REG_MATCH "MATCH_" /** suggested prefix for ap_regname */
|
||||
+#define AP_REG_NO_DEFAULT 0x400 /**< Don't implicitely add AP_REG_DEFAULT options */
|
||||
+
|
||||
+#define AP_REG_MATCH "MATCH_" /**< suggested prefix for ap_regname */
|
||||
+
|
||||
+#define AP_REG_DEFAULT (AP_REG_DOTALL|AP_REG_DOLLAR_ENDONLY)
|
||||
|
||||
/* Error values: */
|
||||
enum {
|
||||
diff --git a/modules/filters/mod_substitute.c b/modules/filters/mod_substitute.c
|
||||
index b7d5296..e976c51 100644
|
||||
--- a/modules/filters/mod_substitute.c
|
||||
+++ b/modules/filters/mod_substitute.c
|
||||
@@ -667,8 +667,10 @@ static const char *set_pattern(cmd_parms *cmd, void *cfg, const char *line)
|
||||
|
||||
/* first see if we can compile the regex */
|
||||
if (!is_pattern) {
|
||||
- r = ap_pregcomp(cmd->pool, from, AP_REG_EXTENDED |
|
||||
- (ignore_case ? AP_REG_ICASE : 0));
|
||||
+ int flags = AP_REG_NO_DEFAULT
|
||||
+ | (ap_regcomp_get_default_cflags() & AP_REG_DOLLAR_ENDONLY)
|
||||
+ | (ignore_case ? AP_REG_ICASE : 0);
|
||||
+ r = ap_pregcomp(cmd->pool, from, flags);
|
||||
if (!r)
|
||||
return "Substitute could not compile regex";
|
||||
}
|
||||
diff --git a/server/core.c b/server/core.c
|
||||
index 76432ce..6d00777 100644
|
||||
--- a/server/core.c
|
||||
+++ b/server/core.c
|
||||
@@ -4973,7 +4973,7 @@ static int core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptem
|
||||
init_config_defines(pconf);
|
||||
apr_pool_cleanup_register(pconf, NULL, reset_config, apr_pool_cleanup_null);
|
||||
|
||||
- ap_regcomp_set_default_cflags(AP_REG_DOLLAR_ENDONLY);
|
||||
+ ap_regcomp_set_default_cflags(AP_REG_DEFAULT);
|
||||
|
||||
mpm_common_pre_config(pconf);
|
||||
|
||||
diff --git a/server/util_pcre.c b/server/util_pcre.c
|
||||
index f2cb1bb..2a665c8 100644
|
||||
--- a/server/util_pcre.c
|
||||
+++ b/server/util_pcre.c
|
||||
@@ -120,7 +120,7 @@ AP_DECLARE(void) ap_regfree(ap_regex_t *preg)
|
||||
* Compile a regular expression *
|
||||
*************************************************/
|
||||
|
||||
-static int default_cflags = AP_REG_DOLLAR_ENDONLY;
|
||||
+static int default_cflags = AP_REG_DEFAULT;
|
||||
|
||||
AP_DECLARE(int) ap_regcomp_get_default_cflags(void)
|
||||
{
|
||||
@@ -168,7 +168,8 @@ AP_DECLARE(int) ap_regcomp(ap_regex_t * preg, const char *pattern, int cflags)
|
||||
int errcode = 0;
|
||||
int options = PCRE_DUPNAMES;
|
||||
|
||||
- cflags |= default_cflags;
|
||||
+ if ((cflags & AP_REG_NO_DEFAULT) == 0)
|
||||
+ cflags |= default_cflags;
|
||||
if ((cflags & AP_REG_ICASE) != 0)
|
||||
options |= PCRE_CASELESS;
|
||||
if ((cflags & AP_REG_NEWLINE) != 0)
|
||||
diff --git a/server/util_regex.c b/server/util_regex.c
|
||||
index 2a30d68..5405f8d 100644
|
||||
--- a/server/util_regex.c
|
||||
+++ b/server/util_regex.c
|
||||
@@ -94,6 +94,7 @@ AP_DECLARE(ap_rxplus_t*) ap_rxplus_compile(apr_pool_t *pool,
|
||||
}
|
||||
|
||||
/* anything after the current delimiter is flags */
|
||||
+ ret->flags = ap_regcomp_get_default_cflags() & AP_REG_DOLLAR_ENDONLY;
|
||||
while (*++endp) {
|
||||
switch (*endp) {
|
||||
case 'i': ret->flags |= AP_REG_ICASE; break;
|
||||
@@ -106,7 +107,7 @@ AP_DECLARE(ap_rxplus_t*) ap_rxplus_compile(apr_pool_t *pool,
|
||||
default: break; /* we should probably be stricter here */
|
||||
}
|
||||
}
|
||||
- if (ap_regcomp(&ret->rx, rxstr, ret->flags) == 0) {
|
||||
+ if (ap_regcomp(&ret->rx, rxstr, AP_REG_NO_DEFAULT | ret->flags) == 0) {
|
||||
apr_pool_cleanup_register(pool, &ret->rx, rxplus_cleanup,
|
||||
apr_pool_cleanup_null);
|
||||
}
|
36
httpd-2.4.37-CVE-2020-11984.patch
Normal file
36
httpd-2.4.37-CVE-2020-11984.patch
Normal file
@ -0,0 +1,36 @@
|
||||
--- a/modules/proxy/mod_proxy_uwsgi.c 2020/07/24 09:31:46 1880250
|
||||
+++ b/modules/proxy/mod_proxy_uwsgi.c 2020/07/24 09:35:25 1880251
|
||||
@@ -136,7 +136,7 @@
|
||||
int j;
|
||||
|
||||
apr_size_t headerlen = 4;
|
||||
- apr_uint16_t pktsize, keylen, vallen;
|
||||
+ apr_size_t pktsize, keylen, vallen;
|
||||
const char *script_name;
|
||||
const char *path_info;
|
||||
const char *auth;
|
||||
@@ -178,6 +178,15 @@
|
||||
headerlen += 2 + strlen(env[j].key) + 2 + strlen(env[j].val);
|
||||
}
|
||||
|
||||
+ pktsize = headerlen - 4;
|
||||
+ if (pktsize > APR_UINT16_MAX) {
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10259)
|
||||
+ "can't send headers to %s:%u: packet size too "
|
||||
+ "large (%" APR_SIZE_T_FMT ")",
|
||||
+ conn->hostname, conn->port, pktsize);
|
||||
+ return HTTP_INTERNAL_SERVER_ERROR;
|
||||
+ }
|
||||
+
|
||||
ptr = buf = apr_palloc(r->pool, headerlen);
|
||||
|
||||
ptr += 4;
|
||||
@@ -196,8 +205,6 @@
|
||||
ptr += vallen;
|
||||
}
|
||||
|
||||
- pktsize = headerlen - 4;
|
||||
-
|
||||
buf[0] = 0;
|
||||
buf[1] = (apr_byte_t) (pktsize & 0xff);
|
||||
buf[2] = (apr_byte_t) ((pktsize >> 8) & 0xff);
|
68
httpd-2.4.37-CVE-2020-1934.patch
Normal file
68
httpd-2.4.37-CVE-2020-1934.patch
Normal file
@ -0,0 +1,68 @@
|
||||
--- a/modules/proxy/mod_proxy_ftp.c 2020/02/07 17:01:07 1873744
|
||||
+++ b/modules/proxy/mod_proxy_ftp.c 2020/02/07 17:04:45 1873745
|
||||
@@ -218,7 +218,7 @@
|
||||
* (EBCDIC) machines either.
|
||||
*/
|
||||
static apr_status_t ftp_string_read(conn_rec *c, apr_bucket_brigade *bb,
|
||||
- char *buff, apr_size_t bufflen, int *eos)
|
||||
+ char *buff, apr_size_t bufflen, int *eos, apr_size_t *outlen)
|
||||
{
|
||||
apr_bucket *e;
|
||||
apr_status_t rv;
|
||||
@@ -230,6 +230,7 @@
|
||||
/* start with an empty string */
|
||||
buff[0] = 0;
|
||||
*eos = 0;
|
||||
+ *outlen = 0;
|
||||
|
||||
/* loop through each brigade */
|
||||
while (!found) {
|
||||
@@ -273,6 +274,7 @@
|
||||
if (len > 0) {
|
||||
memcpy(pos, response, len);
|
||||
pos += len;
|
||||
+ *outlen += len;
|
||||
}
|
||||
}
|
||||
apr_bucket_delete(e);
|
||||
@@ -385,28 +387,36 @@
|
||||
char buff[5];
|
||||
char *mb = msgbuf, *me = &msgbuf[msglen];
|
||||
apr_status_t rv;
|
||||
+ apr_size_t nread;
|
||||
+
|
||||
int eos;
|
||||
|
||||
- if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos))) {
|
||||
+ if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos, &nread))) {
|
||||
return -1;
|
||||
}
|
||||
/*
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, APLOGNO(03233)
|
||||
"<%s", response);
|
||||
*/
|
||||
+ if (nread < 4) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, NULL, APLOGNO(10229) "Malformed FTP response '%s'", response);
|
||||
+ *mb = '\0';
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
if (!apr_isdigit(response[0]) || !apr_isdigit(response[1]) ||
|
||||
- !apr_isdigit(response[2]) || (response[3] != ' ' && response[3] != '-'))
|
||||
+ !apr_isdigit(response[2]) || (response[3] != ' ' && response[3] != '-'))
|
||||
status = 0;
|
||||
else
|
||||
status = 100 * response[0] + 10 * response[1] + response[2] - 111 * '0';
|
||||
|
||||
mb = apr_cpystrn(mb, response + 4, me - mb);
|
||||
|
||||
- if (response[3] == '-') {
|
||||
+ if (response[3] == '-') { /* multi-line reply "123-foo\nbar\n123 baz" */
|
||||
memcpy(buff, response, 3);
|
||||
buff[3] = ' ';
|
||||
do {
|
||||
- if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos))) {
|
||||
+ if (APR_SUCCESS != (rv = ftp_string_read(ftp_ctrl, bb, response, sizeof(response), &eos, &nread))) {
|
||||
return -1;
|
||||
}
|
||||
mb = apr_cpystrn(mb, response + (' ' == response[0] ? 1 : 4), me - mb);
|
14
httpd-2.4.37-CVE-2021-26690.patch
Normal file
14
httpd-2.4.37-CVE-2021-26690.patch
Normal file
@ -0,0 +1,14 @@
|
||||
diff --git a/modules/session/mod_session.c b/modules/session/mod_session.c
|
||||
index 7ee477c..049255d 100644
|
||||
--- a/modules/session/mod_session.c
|
||||
+++ b/modules/session/mod_session.c
|
||||
@@ -404,8 +404,8 @@ static apr_status_t session_identity_decode(request_rec * r, session_rec * z)
|
||||
char *plast = NULL;
|
||||
const char *psep = "=";
|
||||
char *key = apr_strtok(pair, psep, &plast);
|
||||
- char *val = apr_strtok(NULL, psep, &plast);
|
||||
if (key && *key) {
|
||||
+ char *val = apr_strtok(NULL, sep, &plast);
|
||||
if (!val || !*val) {
|
||||
apr_table_unset(z->entries, key);
|
||||
}
|
13
httpd-2.4.37-CVE-2021-26691.patch
Normal file
13
httpd-2.4.37-CVE-2021-26691.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/modules/session/mod_session.c b/modules/session/mod_session.c
|
||||
index 049255d..af70f6b 100644
|
||||
--- a/modules/session/mod_session.c
|
||||
+++ b/modules/session/mod_session.c
|
||||
@@ -317,7 +317,7 @@ static apr_status_t ap_session_set(request_rec * r, session_rec * z,
|
||||
static int identity_count(void *v, const char *key, const char *val)
|
||||
{
|
||||
int *count = v;
|
||||
- *count += strlen(key) * 3 + strlen(val) * 3 + 1;
|
||||
+ *count += strlen(key) * 3 + strlen(val) * 3 + 2;
|
||||
return 1;
|
||||
}
|
||||
|
44
httpd-2.4.37-CVE-2021-30641.patch
Normal file
44
httpd-2.4.37-CVE-2021-30641.patch
Normal file
@ -0,0 +1,44 @@
|
||||
diff --git a/server/request.c b/server/request.c
|
||||
index d5c558a..18625af 100644
|
||||
--- a/server/request.c
|
||||
+++ b/server/request.c
|
||||
@@ -1419,7 +1419,20 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
|
||||
|
||||
cache = prep_walk_cache(AP_NOTE_LOCATION_WALK, r);
|
||||
cached = (cache->cached != NULL);
|
||||
- entry_uri = r->uri;
|
||||
+
|
||||
+ /*
|
||||
+ * When merge_slashes is set to AP_CORE_CONFIG_OFF the slashes in r->uri
|
||||
+ * have not been merged. But for Location walks we always go with merged
|
||||
+ * slashes no matter what merge_slashes is set to.
|
||||
+ */
|
||||
+ if (sconf->merge_slashes != AP_CORE_CONFIG_OFF) {
|
||||
+ entry_uri = r->uri;
|
||||
+ }
|
||||
+ else {
|
||||
+ char *uri = apr_pstrdup(r->pool, r->uri);
|
||||
+ ap_no2slash(uri);
|
||||
+ entry_uri = uri;
|
||||
+ }
|
||||
|
||||
/* If we have an cache->cached location that matches r->uri,
|
||||
* and the vhost's list of locations hasn't changed, we can skip
|
||||
@@ -1486,7 +1499,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
|
||||
pmatch = apr_palloc(rxpool, nmatch*sizeof(ap_regmatch_t));
|
||||
}
|
||||
|
||||
- if (ap_regexec(entry_core->r, entry_uri, nmatch, pmatch, 0)) {
|
||||
+ if (ap_regexec(entry_core->r, r->uri, nmatch, pmatch, 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1496,7 +1509,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r)
|
||||
apr_table_setn(r->subprocess_env,
|
||||
((const char **)entry_core->refs->elts)[i],
|
||||
apr_pstrndup(r->pool,
|
||||
- entry_uri + pmatch[i].rm_so,
|
||||
+ r->uri + pmatch[i].rm_so,
|
||||
pmatch[i].rm_eo - pmatch[i].rm_so));
|
||||
}
|
||||
}
|
13
httpd-2.4.37-CVE-2021-34798.patch
Normal file
13
httpd-2.4.37-CVE-2021-34798.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/server/scoreboard.c b/server/scoreboard.c
|
||||
index 23e3d70..7b01bdf 100644
|
||||
--- a/server/scoreboard.c
|
||||
+++ b/server/scoreboard.c
|
||||
@@ -376,7 +376,7 @@ AP_DECLARE(void) ap_increment_counts(ap_sb_handle_t *sb, request_rec *r)
|
||||
if (pfn_ap_logio_get_last_bytes != NULL) {
|
||||
bytes = pfn_ap_logio_get_last_bytes(r->connection);
|
||||
}
|
||||
- else if (r->method_number == M_GET && r->method[0] == 'H') {
|
||||
+ else if (r->method_number == M_GET && r->method && r->method[0] == 'H') {
|
||||
bytes = 0;
|
||||
}
|
||||
else {
|
21
httpd-2.4.37-CVE-2021-39275.patch
Normal file
21
httpd-2.4.37-CVE-2021-39275.patch
Normal file
@ -0,0 +1,21 @@
|
||||
diff --git a/server/util.c b/server/util.c
|
||||
index e0c558c..2a5dd04 100644
|
||||
--- a/server/util.c
|
||||
+++ b/server/util.c
|
||||
@@ -2460,13 +2460,12 @@ AP_DECLARE(char *) ap_escape_quotes(apr_pool_t *p, const char *instring)
|
||||
* in front of every " that doesn't already have one.
|
||||
*/
|
||||
while (*inchr != '\0') {
|
||||
- if ((*inchr == '\\') && (inchr[1] != '\0')) {
|
||||
- *outchr++ = *inchr++;
|
||||
- *outchr++ = *inchr++;
|
||||
- }
|
||||
if (*inchr == '"') {
|
||||
*outchr++ = '\\';
|
||||
}
|
||||
+ if ((*inchr == '\\') && (inchr[1] != '\0')) {
|
||||
+ *outchr++ = *inchr++;
|
||||
+ }
|
||||
if (*inchr != '\0') {
|
||||
*outchr++ = *inchr++;
|
||||
}
|
126
httpd-2.4.37-CVE-2021-40438.patch
Normal file
126
httpd-2.4.37-CVE-2021-40438.patch
Normal file
@ -0,0 +1,126 @@
|
||||
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
|
||||
index fb897a9..38dbb24 100644
|
||||
--- a/modules/mappers/mod_rewrite.c
|
||||
+++ b/modules/mappers/mod_rewrite.c
|
||||
@@ -619,6 +619,13 @@ static unsigned is_absolute_uri(char *uri, int *supportsqs)
|
||||
return 6;
|
||||
}
|
||||
break;
|
||||
+
|
||||
+ case 'u':
|
||||
+ case 'U':
|
||||
+ if (!ap_cstr_casecmpn(uri, "nix:", 4)) { /* unix: */
|
||||
+ *sqs = 1;
|
||||
+ return (uri[4] == '/' && uri[5] == '/') ? 7 : 5;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
|
||||
index f383996..6a9ef55 100644
|
||||
--- a/modules/proxy/mod_proxy.c
|
||||
+++ b/modules/proxy/mod_proxy.c
|
||||
@@ -1717,7 +1717,8 @@ PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url)
|
||||
* the UDS path... ignore it
|
||||
*/
|
||||
if (!strncasecmp(url, "unix:", 5) &&
|
||||
- ((ptr = ap_strchr_c(url, '|')) != NULL)) {
|
||||
+ ((ptr = ap_strchr_c(url + 5, '|')) != NULL)) {
|
||||
+
|
||||
/* move past the 'unix:...|' UDS path info */
|
||||
const char *ret, *c;
|
||||
|
||||
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
|
||||
index 7714b6c..3dd570c 100644
|
||||
--- a/modules/proxy/proxy_util.c
|
||||
+++ b/modules/proxy/proxy_util.c
|
||||
@@ -2084,33 +2084,45 @@ static int ap_proxy_retry_worker(const char *proxy_function, proxy_worker *worke
|
||||
* were passed a UDS url (eg: from mod_proxy) and adjust uds_path
|
||||
* as required.
|
||||
*/
|
||||
-static void fix_uds_filename(request_rec *r, char **url)
|
||||
+static int fix_uds_filename(request_rec *r, char **url)
|
||||
{
|
||||
- char *ptr, *ptr2;
|
||||
- if (!r || !r->filename) return;
|
||||
+ char *uds_url = r->filename + 6, *origin_url;
|
||||
|
||||
if (!strncmp(r->filename, "proxy:", 6) &&
|
||||
- (ptr2 = ap_strcasestr(r->filename, "unix:")) &&
|
||||
- (ptr = ap_strchr(ptr2, '|'))) {
|
||||
+ !ap_cstr_casecmpn(uds_url, "unix:", 5) &&
|
||||
+ (origin_url = ap_strchr(uds_url + 5, '|'))) {
|
||||
+ char *uds_path = NULL;
|
||||
+ apr_size_t url_len;
|
||||
apr_uri_t urisock;
|
||||
apr_status_t rv;
|
||||
- *ptr = '\0';
|
||||
- rv = apr_uri_parse(r->pool, ptr2, &urisock);
|
||||
- if (rv == APR_SUCCESS) {
|
||||
- char *rurl = ptr+1;
|
||||
- char *sockpath = ap_runtime_dir_relative(r->pool, urisock.path);
|
||||
- apr_table_setn(r->notes, "uds_path", sockpath);
|
||||
- *url = apr_pstrdup(r->pool, rurl); /* so we get the scheme for the uds */
|
||||
- /* r->filename starts w/ "proxy:", so add after that */
|
||||
- memmove(r->filename+6, rurl, strlen(rurl)+1);
|
||||
- ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
|
||||
- "*: rewrite of url due to UDS(%s): %s (%s)",
|
||||
- sockpath, *url, r->filename);
|
||||
- }
|
||||
- else {
|
||||
- *ptr = '|';
|
||||
- }
|
||||
- }
|
||||
+
|
||||
+ *origin_url = '\0';
|
||||
+ rv = apr_uri_parse(r->pool, uds_url, &urisock);
|
||||
+ *origin_url++ = '|';
|
||||
+
|
||||
+ if (rv == APR_SUCCESS && urisock.path && (!urisock.hostname
|
||||
+ || !urisock.hostname[0])) {
|
||||
+ uds_path = ap_runtime_dir_relative(r->pool, urisock.path);
|
||||
+ }
|
||||
+
|
||||
+ if (!uds_path) {
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10292)
|
||||
+ "Invalid proxy UDS filename (%s)", r->filename);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ apr_table_setn(r->notes, "uds_path", uds_path);
|
||||
+
|
||||
+ /* Remove the UDS path from *url and r->filename */
|
||||
+ url_len = strlen(origin_url);
|
||||
+ *url = apr_pstrmemdup(r->pool, origin_url, url_len);
|
||||
+ memcpy(uds_url, *url, url_len + 1);
|
||||
+
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
|
||||
+ "*: rewrite of url due to UDS(%s): %s (%s)",
|
||||
+ uds_path, *url, r->filename);
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
|
||||
@@ -2128,7 +2140,9 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
|
||||
"%s: found worker %s for %s",
|
||||
(*worker)->s->scheme, (*worker)->s->name, *url);
|
||||
*balancer = NULL;
|
||||
- fix_uds_filename(r, url);
|
||||
+ if (!fix_uds_filename(r, url)) {
|
||||
+ return HTTP_INTERNAL_SERVER_ERROR;
|
||||
+ }
|
||||
access_status = OK;
|
||||
}
|
||||
else if (r->proxyreq == PROXYREQ_PROXY) {
|
||||
@@ -2159,7 +2173,9 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
|
||||
* regarding the Connection header in the request.
|
||||
*/
|
||||
apr_table_setn(r->subprocess_env, "proxy-nokeepalive", "1");
|
||||
- fix_uds_filename(r, url);
|
||||
+ if (!fix_uds_filename(r, url)) {
|
||||
+ return HTTP_INTERNAL_SERVER_ERROR;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
10
httpd-2.4.37-CVE-2021-44790.patch
Normal file
10
httpd-2.4.37-CVE-2021-44790.patch
Normal file
@ -0,0 +1,10 @@
|
||||
--- a/modules/lua/lua_request.c 2021/12/16 11:09:40 1896038
|
||||
+++ b/modules/lua/lua_request.c 2021/12/16 11:15:47 1896039
|
||||
@@ -410,6 +410,7 @@
|
||||
if (end == NULL) break;
|
||||
key = (char *) apr_pcalloc(r->pool, 256);
|
||||
filename = (char *) apr_pcalloc(r->pool, 256);
|
||||
+ if (end - crlf <= 8) break;
|
||||
vlen = end - crlf - 8;
|
||||
buffer = (char *) apr_pcalloc(r->pool, vlen+1);
|
||||
memcpy(buffer, crlf + 4, vlen);
|
225
httpd-2.4.37-balancer-failover.patch
Normal file
225
httpd-2.4.37-balancer-failover.patch
Normal file
@ -0,0 +1,225 @@
|
||||
diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
|
||||
index ec1e042..2c0500f 100644
|
||||
--- a/modules/proxy/mod_proxy_http.c
|
||||
+++ b/modules/proxy/mod_proxy_http.c
|
||||
@@ -310,16 +310,18 @@ static int stream_reqbody_read(proxy_http_req_t *req, apr_bucket_brigade *bb,
|
||||
return OK;
|
||||
}
|
||||
|
||||
-static int stream_reqbody(proxy_http_req_t *req, rb_methods rb_method)
|
||||
+static int stream_reqbody(proxy_http_req_t *req)
|
||||
{
|
||||
request_rec *r = req->r;
|
||||
int seen_eos = 0, rv = OK;
|
||||
apr_size_t hdr_len;
|
||||
char chunk_hdr[20]; /* must be here due to transient bucket. */
|
||||
+ conn_rec *origin = req->origin;
|
||||
proxy_conn_rec *p_conn = req->backend;
|
||||
apr_bucket_alloc_t *bucket_alloc = req->bucket_alloc;
|
||||
apr_bucket_brigade *header_brigade = req->header_brigade;
|
||||
apr_bucket_brigade *input_brigade = req->input_brigade;
|
||||
+ rb_methods rb_method = req->rb_method;
|
||||
apr_off_t bytes, bytes_streamed = 0;
|
||||
apr_bucket *e;
|
||||
|
||||
@@ -333,7 +335,7 @@ static int stream_reqbody(proxy_http_req_t *req, rb_methods rb_method)
|
||||
}
|
||||
|
||||
if (!APR_BRIGADE_EMPTY(input_brigade)) {
|
||||
- /* If this brigade contains EOS, either stop or remove it. */
|
||||
+ /* If this brigade contains EOS, remove it and be done. */
|
||||
if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
|
||||
seen_eos = 1;
|
||||
|
||||
@@ -375,7 +377,8 @@ static int stream_reqbody(proxy_http_req_t *req, rb_methods rb_method)
|
||||
APR_BRIGADE_INSERT_TAIL(input_brigade, e);
|
||||
}
|
||||
}
|
||||
- else if (bytes_streamed > req->cl_val) {
|
||||
+ else if (rb_method == RB_STREAM_CL
|
||||
+ && bytes_streamed > req->cl_val) {
|
||||
/* C-L < bytes streamed?!?
|
||||
* We will error out after the body is completely
|
||||
* consumed, but we can't stream more bytes at the
|
||||
@@ -407,7 +410,7 @@ static int stream_reqbody(proxy_http_req_t *req, rb_methods rb_method)
|
||||
APR_BRIGADE_PREPEND(input_brigade, header_brigade);
|
||||
|
||||
/* Flush here on EOS because we won't stream_reqbody_read() again */
|
||||
- rv = ap_proxy_pass_brigade(bucket_alloc, r, p_conn, req->origin,
|
||||
+ rv = ap_proxy_pass_brigade(bucket_alloc, r, p_conn, origin,
|
||||
input_brigade, seen_eos);
|
||||
if (rv != OK) {
|
||||
return rv;
|
||||
@@ -454,10 +457,6 @@ static int spool_reqbody_cl(proxy_http_req_t *req, apr_off_t *bytes_spooled)
|
||||
/* If this brigade contains EOS, either stop or remove it. */
|
||||
if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) {
|
||||
seen_eos = 1;
|
||||
-
|
||||
- /* We can't pass this EOS to the output_filters. */
|
||||
- e = APR_BRIGADE_LAST(input_brigade);
|
||||
- apr_bucket_delete(e);
|
||||
}
|
||||
|
||||
apr_brigade_length(input_brigade, 1, &bytes);
|
||||
@@ -644,7 +643,18 @@ static int ap_proxy_http_prefetch(proxy_http_req_t *req,
|
||||
*/
|
||||
temp_brigade = apr_brigade_create(p, bucket_alloc);
|
||||
block = req->prefetch_nonblocking ? APR_NONBLOCK_READ : APR_BLOCK_READ;
|
||||
- do {
|
||||
+
|
||||
+ /* Account for saved input, if any. */
|
||||
+ apr_brigade_length(input_brigade, 0, &bytes_read);
|
||||
+
|
||||
+ /* Ensure we don't hit a wall where we have a buffer too small
|
||||
+ * for ap_get_brigade's filters to fetch us another bucket,
|
||||
+ * surrender once we hit 80 bytes less than MAX_MEM_SPOOL
|
||||
+ * (an arbitrary value).
|
||||
+ */
|
||||
+ while (bytes_read < MAX_MEM_SPOOL - 80
|
||||
+ && (APR_BRIGADE_EMPTY(input_brigade)
|
||||
+ || !APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade)))) {
|
||||
status = ap_get_brigade(r->input_filters, temp_brigade,
|
||||
AP_MODE_READBYTES, block,
|
||||
MAX_MEM_SPOOL - bytes_read);
|
||||
@@ -686,15 +696,7 @@ static int ap_proxy_http_prefetch(proxy_http_req_t *req,
|
||||
c->client_ip, c->remote_host ? c->remote_host: "");
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
-
|
||||
- /* Ensure we don't hit a wall where we have a buffer too small
|
||||
- * for ap_get_brigade's filters to fetch us another bucket,
|
||||
- * surrender once we hit 80 bytes less than MAX_MEM_SPOOL
|
||||
- * (an arbitrary value.)
|
||||
- */
|
||||
- } while ((bytes_read < MAX_MEM_SPOOL - 80)
|
||||
- && !APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))
|
||||
- && !req->prefetch_nonblocking);
|
||||
+ }
|
||||
|
||||
/* Use chunked request body encoding or send a content-length body?
|
||||
*
|
||||
@@ -838,35 +840,21 @@ static int ap_proxy_http_request(proxy_http_req_t *req)
|
||||
{
|
||||
int rv;
|
||||
request_rec *r = req->r;
|
||||
- apr_bucket_alloc_t *bucket_alloc = req->bucket_alloc;
|
||||
- apr_bucket_brigade *header_brigade = req->header_brigade;
|
||||
- apr_bucket_brigade *input_brigade = req->input_brigade;
|
||||
|
||||
/* send the request header/body, if any. */
|
||||
switch (req->rb_method) {
|
||||
+ case RB_SPOOL_CL:
|
||||
case RB_STREAM_CL:
|
||||
case RB_STREAM_CHUNKED:
|
||||
if (req->do_100_continue) {
|
||||
- rv = ap_proxy_pass_brigade(bucket_alloc, r, req->backend,
|
||||
- req->origin, header_brigade, 1);
|
||||
+ rv = ap_proxy_pass_brigade(req->bucket_alloc, r, req->backend,
|
||||
+ req->origin, req->header_brigade, 1);
|
||||
}
|
||||
else {
|
||||
- rv = stream_reqbody(req, req->rb_method);
|
||||
+ rv = stream_reqbody(req);
|
||||
}
|
||||
break;
|
||||
|
||||
- case RB_SPOOL_CL:
|
||||
- /* Prefetch has built the header and spooled the whole body;
|
||||
- * if we don't expect 100-continue we can flush both all at once,
|
||||
- * otherwise flush the header only.
|
||||
- */
|
||||
- if (!req->do_100_continue) {
|
||||
- APR_BRIGADE_CONCAT(header_brigade, input_brigade);
|
||||
- }
|
||||
- rv = ap_proxy_pass_brigade(bucket_alloc, r, req->backend,
|
||||
- req->origin, header_brigade, 1);
|
||||
- break;
|
||||
-
|
||||
default:
|
||||
/* shouldn't be possible */
|
||||
rv = HTTP_INTERNAL_SERVER_ERROR;
|
||||
@@ -1577,15 +1565,10 @@ int ap_proxy_http_process_response(proxy_http_req_t *req)
|
||||
|
||||
/* Send the request body (fully). */
|
||||
switch(req->rb_method) {
|
||||
+ case RB_SPOOL_CL:
|
||||
case RB_STREAM_CL:
|
||||
case RB_STREAM_CHUNKED:
|
||||
- status = stream_reqbody(req, req->rb_method);
|
||||
- break;
|
||||
- case RB_SPOOL_CL:
|
||||
- /* Prefetch has spooled the whole body, flush it. */
|
||||
- status = ap_proxy_pass_brigade(req->bucket_alloc, r,
|
||||
- backend, origin,
|
||||
- req->input_brigade, 1);
|
||||
+ status = stream_reqbody(req);
|
||||
break;
|
||||
default:
|
||||
/* Shouldn't happen */
|
||||
@@ -1940,6 +1923,7 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker,
|
||||
const char *u;
|
||||
proxy_http_req_t *req = NULL;
|
||||
proxy_conn_rec *backend = NULL;
|
||||
+ apr_bucket_brigade *input_brigade = NULL;
|
||||
int is_ssl = 0;
|
||||
conn_rec *c = r->connection;
|
||||
proxy_dir_conf *dconf;
|
||||
@@ -2005,8 +1989,20 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker,
|
||||
|
||||
dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
|
||||
|
||||
+ /* We possibly reuse input data prefetched in previous call(s), e.g. for a
|
||||
+ * balancer fallback scenario, and in this case the 100 continue settings
|
||||
+ * should be consistent between balancer members. If not, we need to ignore
|
||||
+ * Proxy100Continue on=>off once we tried to prefetch already, otherwise
|
||||
+ * the HTTP_IN filter won't send 100 Continue for us anymore, and we might
|
||||
+ * deadlock with the client waiting for each other. Note that off=>on is
|
||||
+ * not an issue because in this case r->expecting_100 is false (the 100
|
||||
+ * Continue is out already), but we make sure that prefetch will be
|
||||
+ * nonblocking to avoid passing more time there.
|
||||
+ */
|
||||
+ apr_pool_userdata_get((void **)&input_brigade, "proxy-req-input", p);
|
||||
+
|
||||
/* Should we handle end-to-end or ping 100-continue? */
|
||||
- if ((r->expecting_100 && dconf->forward_100_continue)
|
||||
+ if ((r->expecting_100 && (dconf->forward_100_continue || input_brigade))
|
||||
|| PROXY_DO_100_CONTINUE(worker, r)) {
|
||||
/* We need to reset r->expecting_100 or prefetching will cause
|
||||
* ap_http_filter() to send "100 Continue" response by itself. So
|
||||
@@ -2023,7 +2019,8 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker,
|
||||
/* Should we block while prefetching the body or try nonblocking and flush
|
||||
* data to the backend ASAP?
|
||||
*/
|
||||
- else if (apr_table_get(r->subprocess_env, "proxy-prefetch-nonblocking")) {
|
||||
+ else if (input_brigade || apr_table_get(r->subprocess_env,
|
||||
+ "proxy-prefetch-nonblocking")) {
|
||||
req->prefetch_nonblocking = 1;
|
||||
}
|
||||
|
||||
@@ -2048,6 +2045,17 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker,
|
||||
sizeof(req->server_portstr))))
|
||||
goto cleanup;
|
||||
|
||||
+ /* The header is always (re-)built since it depends on worker settings,
|
||||
+ * but the body can be fetched only once (even partially), so it's saved
|
||||
+ * in between proxy_http_handler() calls should we come back here.
|
||||
+ */
|
||||
+ req->header_brigade = apr_brigade_create(p, req->bucket_alloc);
|
||||
+ if (input_brigade == NULL) {
|
||||
+ input_brigade = apr_brigade_create(p, req->bucket_alloc);
|
||||
+ apr_pool_userdata_setn(input_brigade, "proxy-req-input", NULL, p);
|
||||
+ }
|
||||
+ req->input_brigade = input_brigade;
|
||||
+
|
||||
/* Prefetch (nonlocking) the request body so to increase the chance to get
|
||||
* the whole (or enough) body and determine Content-Length vs chunked or
|
||||
* spooled. By doing this before connecting or reusing the backend, we want
|
||||
@@ -2058,8 +2066,6 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker,
|
||||
* to reduce to the minimum the unavoidable local is_socket_connected() vs
|
||||
* remote keepalive race condition.
|
||||
*/
|
||||
- req->input_brigade = apr_brigade_create(p, req->bucket_alloc);
|
||||
- req->header_brigade = apr_brigade_create(p, req->bucket_alloc);
|
||||
if ((status = ap_proxy_http_prefetch(req, uri, locurl)) != OK)
|
||||
goto cleanup;
|
||||
|
42
httpd-2.4.37-fips-segfault.patch
Normal file
42
httpd-2.4.37-fips-segfault.patch
Normal file
@ -0,0 +1,42 @@
|
||||
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
|
||||
index 37947e7..b50c259 100644
|
||||
--- a/modules/ssl/mod_ssl.c
|
||||
+++ b/modules/ssl/mod_ssl.c
|
||||
@@ -331,9 +331,6 @@ static apr_status_t ssl_cleanup_pre_config(void *data)
|
||||
/*
|
||||
* Try to kill the internals of the SSL library.
|
||||
*/
|
||||
-#ifdef HAVE_FIPS
|
||||
- FIPS_mode_set(0);
|
||||
-#endif
|
||||
/* Corresponds to OBJ_create()s */
|
||||
OBJ_cleanup();
|
||||
/* Corresponds to OPENSSL_load_builtin_modules() */
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index 5063a72..21e41e2 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -183,6 +183,14 @@ int ssl_is_challenge(conn_rec *c, const char *servername,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef HAVE_FIPS
|
||||
+static apr_status_t ssl_fips_cleanup(void *data)
|
||||
+{
|
||||
+ FIPS_mode_set(0);
|
||||
+ return APR_SUCCESS;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
/*
|
||||
* Per-module initialization
|
||||
*/
|
||||
@@ -316,6 +324,8 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
|
||||
if (FIPS_mode_set(1)) {
|
||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(01884)
|
||||
"Operating in SSL FIPS mode");
|
||||
+ apr_pool_cleanup_register(p, NULL, ssl_fips_cleanup,
|
||||
+ apr_pool_cleanup_null);
|
||||
}
|
||||
else {
|
||||
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01885) "FIPS mode failed");
|
13
httpd-2.4.37-htcacheclean-dont-break.patch
Normal file
13
httpd-2.4.37-htcacheclean-dont-break.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/support/htcacheclean.c b/support/htcacheclean.c
|
||||
index 8692377..fde34c9 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;
|
||||
}
|
||||
}
|
||||
}
|
87
httpd-2.4.37-logjournal.patch
Normal file
87
httpd-2.4.37-logjournal.patch
Normal file
@ -0,0 +1,87 @@
|
||||
diff --git a/modules/loggers/config.m4 b/modules/loggers/config.m4
|
||||
index 762e773e94..0848d2e377 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 996c09cf49..50a056a2f8 100644
|
||||
--- a/modules/loggers/mod_log_config.c
|
||||
+++ b/modules/loggers/mod_log_config.c
|
||||
@@ -172,6 +172,10 @@
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+#include <systemd/sd-journal.h>
|
||||
+#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;
|
544
httpd-2.4.37-mod-md-mod-ssl-hooks.patch
Normal file
544
httpd-2.4.37-mod-md-mod-ssl-hooks.patch
Normal file
@ -0,0 +1,544 @@
|
||||
diff --git a/modules/ssl/mod_ssl.h b/modules/ssl/mod_ssl.h
|
||||
index 24a65a0..a360911 100644
|
||||
--- a/modules/ssl/mod_ssl.h
|
||||
+++ b/modules/ssl/mod_ssl.h
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "httpd.h"
|
||||
#include "http_config.h"
|
||||
#include "apr_optional.h"
|
||||
+#include "apr_tables.h" /* for apr_array_header_t */
|
||||
|
||||
/* Create a set of SSL_DECLARE(type), SSL_DECLARE_NONSTD(type) and
|
||||
* SSL_DECLARE_DATA with appropriate export and import tags for the platform
|
||||
@@ -86,6 +87,34 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));
|
||||
APR_DECLARE_OPTIONAL_FN(int, ssl_engine_set, (conn_rec *,
|
||||
ap_conf_vector_t *,
|
||||
int proxy, int enable));
|
||||
+
|
||||
+/* Check for availability of new hooks */
|
||||
+#define SSL_CERT_HOOKS
|
||||
+#ifdef SSL_CERT_HOOKS
|
||||
+
|
||||
+/** Lets others add certificate and key files to the given server.
|
||||
+ * For each cert a key must also be added.
|
||||
+ * @param cert_file and array of const char* with the path to the certificate chain
|
||||
+ * @param key_file and array of const char* with the path to the private key file
|
||||
+ */
|
||||
+APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, add_cert_files,
|
||||
+ (server_rec *s, apr_pool_t *p,
|
||||
+ apr_array_header_t *cert_files,
|
||||
+ apr_array_header_t *key_files))
|
||||
+
|
||||
+/** In case no certificates are available for a server, this
|
||||
+ * lets other modules add a fallback certificate for the time
|
||||
+ * being. Regular requests against this server will be answered
|
||||
+ * with a 503.
|
||||
+ * @param cert_file and array of const char* with the path to the certificate chain
|
||||
+ * @param key_file and array of const char* with the path to the private key file
|
||||
+ */
|
||||
+APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, add_fallback_cert_files,
|
||||
+ (server_rec *s, apr_pool_t *p,
|
||||
+ apr_array_header_t *cert_files,
|
||||
+ apr_array_header_t *key_files))
|
||||
+
|
||||
+#endif /* SSL_CERT_HOOKS */
|
||||
|
||||
#endif /* __MOD_SSL_H__ */
|
||||
/** @} */
|
||||
diff --git a/modules/ssl/mod_ssl_openssl.h b/modules/ssl/mod_ssl_openssl.h
|
||||
index 0fa654a..d4f684f 100644
|
||||
--- a/modules/ssl/mod_ssl_openssl.h
|
||||
+++ b/modules/ssl/mod_ssl_openssl.h
|
||||
@@ -69,5 +69,45 @@ APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, pre_handshake,
|
||||
APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, proxy_post_handshake,
|
||||
(conn_rec *c, SSL *ssl))
|
||||
|
||||
+/** On TLS connections that do not relate to a configured virtual host,
|
||||
+ * allow other modules to provide a X509 certificate and EVP_PKEY to
|
||||
+ * be used on the connection. This first hook which does not
|
||||
+ * return DECLINED will determine the outcome. */
|
||||
+APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, answer_challenge,
|
||||
+ (conn_rec *c, const char *server_name,
|
||||
+ X509 **pcert, EVP_PKEY **pkey))
|
||||
+
|
||||
+/** During post_config phase, ask around if someone wants to provide
|
||||
+ * OCSP stapling status information for the given cert (with the also
|
||||
+ * provided issuer certificate). The first hook which does not
|
||||
+ * return DECLINED promises to take responsibility (and respond
|
||||
+ * in later calls via hook ssl_get_stapling_status).
|
||||
+ * If no hook takes over, mod_ssl's own stapling implementation will
|
||||
+ * be applied (if configured).
|
||||
+ */
|
||||
+APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, init_stapling_status,
|
||||
+ (server_rec *s, apr_pool_t *p,
|
||||
+ X509 *cert, X509 *issuer))
|
||||
+
|
||||
+/** Anyone answering positive to ssl_init_stapling_status for a
|
||||
+ * certificate, needs to register here and supply the actual OCSP stapling
|
||||
+ * status data (OCSP_RESP) for a new connection.
|
||||
+ * A hook supplying the response data must return APR_SUCCESS.
|
||||
+ * The data is returned in DER encoded bytes via pder and pderlen. The
|
||||
+ * returned pointer may be NULL, which indicates that data is (currently)
|
||||
+ * unavailable.
|
||||
+ * If DER data is returned, it MUST come from a response with
|
||||
+ * status OCSP_RESPONSE_STATUS_SUCCESSFUL and V_OCSP_CERTSTATUS_GOOD
|
||||
+ * or V_OCSP_CERTSTATUS_REVOKED, not V_OCSP_CERTSTATUS_UNKNOWN. This means
|
||||
+ * errors in OCSP retrieval are to be handled/logged by the hook and
|
||||
+ * are not done by mod_ssl.
|
||||
+ * Any DER bytes returned MUST be allocated via malloc() and ownership
|
||||
+ * passes to mod_ssl. Meaning, the hook must return a malloced copy of
|
||||
+ * the data it has. mod_ssl (or OpenSSL) will free it.
|
||||
+ */
|
||||
+APR_DECLARE_EXTERNAL_HOOK(ssl, SSL, int, get_stapling_status,
|
||||
+ (unsigned char **pder, int *pderlen,
|
||||
+ conn_rec *c, server_rec *s, X509 *cert))
|
||||
+
|
||||
#endif /* __MOD_SSL_OPENSSL_H__ */
|
||||
/** @} */
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index 21e41e2..ef631c1 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -36,6 +36,25 @@ APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_server,
|
||||
(server_rec *s,apr_pool_t *p,int is_proxy,SSL_CTX *ctx),
|
||||
(s,p,is_proxy,ctx), OK, DECLINED)
|
||||
|
||||
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, add_cert_files,
|
||||
+ (server_rec *s, apr_pool_t *p,
|
||||
+ apr_array_header_t *cert_files, apr_array_header_t *key_files),
|
||||
+ (s, p, cert_files, key_files),
|
||||
+ OK, DECLINED)
|
||||
+
|
||||
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, add_fallback_cert_files,
|
||||
+ (server_rec *s, apr_pool_t *p,
|
||||
+ apr_array_header_t *cert_files, apr_array_header_t *key_files),
|
||||
+ (s, p, cert_files, key_files),
|
||||
+ OK, DECLINED)
|
||||
+
|
||||
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, answer_challenge,
|
||||
+ (conn_rec *c, const char *server_name,
|
||||
+ X509 **pcert, EVP_PKEY **pkey),
|
||||
+ (c, server_name, pcert, pkey),
|
||||
+ DECLINED, DECLINED)
|
||||
+
|
||||
+
|
||||
/* _________________________________________________________________
|
||||
**
|
||||
** Module Initialization
|
||||
@@ -165,18 +184,18 @@ static void ssl_add_version_components(apr_pool_t *p,
|
||||
modver, AP_SERVER_BASEVERSION, incver);
|
||||
}
|
||||
|
||||
-/**************************************************************************************************/
|
||||
-/* Managed Domains Interface */
|
||||
-
|
||||
-static APR_OPTIONAL_FN_TYPE(md_is_managed) *md_is_managed;
|
||||
-static APR_OPTIONAL_FN_TYPE(md_get_certificate) *md_get_certificate;
|
||||
-static APR_OPTIONAL_FN_TYPE(md_is_challenge) *md_is_challenge;
|
||||
+/* _________________________________________________________________
|
||||
+**
|
||||
+** Let other answer special connection attempts.
|
||||
+** Used in ACME challenge handling by mod_md.
|
||||
+** _________________________________________________________________
|
||||
+*/
|
||||
|
||||
int ssl_is_challenge(conn_rec *c, const char *servername,
|
||||
X509 **pcert, EVP_PKEY **pkey)
|
||||
{
|
||||
- if (md_is_challenge) {
|
||||
- return md_is_challenge(c, servername, pcert, pkey);
|
||||
+ if (APR_SUCCESS == ssl_run_answer_challenge(c, servername, pcert, pkey)) {
|
||||
+ return 1;
|
||||
}
|
||||
*pcert = NULL;
|
||||
*pkey = NULL;
|
||||
@@ -231,16 +250,6 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
|
||||
ssl_config_global_create(base_server); /* just to avoid problems */
|
||||
ssl_config_global_fix(mc);
|
||||
|
||||
- /* Initialize our interface to mod_md, if it is loaded
|
||||
- */
|
||||
- md_is_managed = APR_RETRIEVE_OPTIONAL_FN(md_is_managed);
|
||||
- md_get_certificate = APR_RETRIEVE_OPTIONAL_FN(md_get_certificate);
|
||||
- md_is_challenge = APR_RETRIEVE_OPTIONAL_FN(md_is_challenge);
|
||||
- if (!md_is_managed || !md_get_certificate) {
|
||||
- md_is_managed = NULL;
|
||||
- md_get_certificate = NULL;
|
||||
- }
|
||||
-
|
||||
/*
|
||||
* try to fix the configuration and open the dedicated SSL
|
||||
* logfile as early as possible
|
||||
@@ -1392,8 +1401,7 @@ static apr_status_t ssl_init_server_certs(server_rec *s,
|
||||
* loaded via SSLOpenSSLConfCmd Certificate), so for 1.0.2 and
|
||||
* later, we defer to the code in ssl_init_server_ctx.
|
||||
*/
|
||||
- if ((mctx->stapling_enabled == TRUE) &&
|
||||
- !ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) {
|
||||
+ if (!ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02567)
|
||||
"Unable to configure certificate %s for stapling",
|
||||
key_id);
|
||||
@@ -1788,11 +1796,13 @@ static apr_status_t ssl_init_server_ctx(server_rec *s,
|
||||
apr_array_header_t *pphrases)
|
||||
{
|
||||
apr_status_t rv;
|
||||
+ modssl_pk_server_t *pks;
|
||||
#ifdef HAVE_SSL_CONF_CMD
|
||||
ssl_ctx_param_t *param = (ssl_ctx_param_t *)sc->server->ssl_ctx_param->elts;
|
||||
SSL_CONF_CTX *cctx = sc->server->ssl_ctx_config;
|
||||
int i;
|
||||
#endif
|
||||
+ int n;
|
||||
|
||||
/*
|
||||
* Check for problematic re-initializations
|
||||
@@ -1804,50 +1814,24 @@ static apr_status_t ssl_init_server_ctx(server_rec *s,
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
|
||||
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10083)
|
||||
- "Init: (%s) mod_md support is %s.", ssl_util_vhostid(p, s),
|
||||
- md_is_managed? "available" : "unavailable");
|
||||
- if (md_is_managed && md_is_managed(s)) {
|
||||
- modssl_pk_server_t *const pks = sc->server->pks;
|
||||
- if (pks->cert_files->nelts > 0 || pks->key_files->nelts > 0) {
|
||||
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10084)
|
||||
- "Init: (%s) You configured certificate/key files on this host, but "
|
||||
- "is is covered by a Managed Domain. You need to remove these directives "
|
||||
- "for the Managed Domain to take over.", ssl_util_vhostid(p, s));
|
||||
- }
|
||||
- else {
|
||||
- const char *key_file, *cert_file, *chain_file;
|
||||
-
|
||||
- key_file = cert_file = chain_file = NULL;
|
||||
-
|
||||
- if (md_get_certificate) {
|
||||
- rv = md_get_certificate(s, p, &key_file, &cert_file);
|
||||
- }
|
||||
- else {
|
||||
- rv = APR_ENOTIMPL;
|
||||
- }
|
||||
-
|
||||
- if (key_file && cert_file) {
|
||||
- ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
|
||||
- "%s: installing key=%s, cert=%s, chain=%s",
|
||||
- ssl_util_vhostid(p, s), key_file, cert_file, chain_file);
|
||||
- APR_ARRAY_PUSH(pks->key_files, const char *) = key_file;
|
||||
- APR_ARRAY_PUSH(pks->cert_files, const char *) = cert_file;
|
||||
- sc->server->cert_chain = chain_file;
|
||||
- }
|
||||
-
|
||||
- if (APR_STATUS_IS_EAGAIN(rv)) {
|
||||
- /* Managed Domain not ready yet. This is not a reason to fail the config */
|
||||
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10085)
|
||||
- "Init: %s will respond with '503 Service Unavailable' for now. This "
|
||||
- "host is part of a Managed Domain, but no SSL certificate is "
|
||||
- "available (yet).", ssl_util_vhostid(p, s));
|
||||
- pks->service_unavailable = 1;
|
||||
- }
|
||||
- else if (rv != APR_SUCCESS) {
|
||||
- return rv;
|
||||
- }
|
||||
- }
|
||||
+ /* Allow others to provide certificate files */
|
||||
+ pks = sc->server->pks;
|
||||
+ n = pks->cert_files->nelts;
|
||||
+ ssl_run_add_cert_files(s, p, pks->cert_files, pks->key_files);
|
||||
+
|
||||
+ if (n < pks->cert_files->nelts) {
|
||||
+ /* this overrides any old chain configuration */
|
||||
+ sc->server->cert_chain = NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (apr_is_empty_array(pks->cert_files) && !sc->server->cert_chain) {
|
||||
+ ssl_run_add_fallback_cert_files(s, p, pks->cert_files, pks->key_files);
|
||||
+
|
||||
+ pks->service_unavailable = 1;
|
||||
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(10085)
|
||||
+ "Init: %s will respond with '503 Service Unavailable' for now. There "
|
||||
+ "are no SSL certificates configured and no other module contributed any.",
|
||||
+ ssl_util_vhostid(p, s));
|
||||
}
|
||||
|
||||
if ((rv = ssl_init_ctx(s, p, ptemp, sc->server)) != APR_SUCCESS) {
|
||||
@@ -1900,7 +1884,7 @@ static apr_status_t ssl_init_server_ctx(server_rec *s,
|
||||
* (late) point makes sure that we catch both certificates loaded
|
||||
* via SSLCertificateFile and SSLOpenSSLConfCmd Certificate.
|
||||
*/
|
||||
- if (sc->server->stapling_enabled == TRUE) {
|
||||
+ do {
|
||||
X509 *cert;
|
||||
int i = 0;
|
||||
int ret = SSL_CTX_set_current_cert(sc->server->ssl_ctx,
|
||||
@@ -1917,7 +1901,7 @@ static apr_status_t ssl_init_server_ctx(server_rec *s,
|
||||
SSL_CERT_SET_NEXT);
|
||||
i++;
|
||||
}
|
||||
- }
|
||||
+ } while(0);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TLS_SESSION_TICKETS
|
||||
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
|
||||
index e6a9f67..a5e86e4 100644
|
||||
--- a/modules/ssl/ssl_engine_kernel.c
|
||||
+++ b/modules/ssl/ssl_engine_kernel.c
|
||||
@@ -2303,6 +2303,37 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
|
||||
}
|
||||
|
||||
#ifdef HAVE_TLSEXT
|
||||
+
|
||||
+static apr_status_t set_challenge_creds(conn_rec *c, const char *servername,
|
||||
+ SSL *ssl, X509 *cert, EVP_PKEY *key)
|
||||
+{
|
||||
+ SSLConnRec *sslcon = myConnConfig(c);
|
||||
+
|
||||
+ sslcon->service_unavailable = 1;
|
||||
+ if ((SSL_use_certificate(ssl, cert) < 1)) {
|
||||
+ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10086)
|
||||
+ "Failed to configure challenge certificate %s",
|
||||
+ servername);
|
||||
+ return APR_EGENERAL;
|
||||
+ }
|
||||
+
|
||||
+ if (!SSL_use_PrivateKey(ssl, key)) {
|
||||
+ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10087)
|
||||
+ "error '%s' using Challenge key: %s",
|
||||
+ ERR_error_string(ERR_peek_last_error(), NULL),
|
||||
+ servername);
|
||||
+ return APR_EGENERAL;
|
||||
+ }
|
||||
+
|
||||
+ if (SSL_check_private_key(ssl) < 1) {
|
||||
+ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10088)
|
||||
+ "Challenge certificate and private key %s "
|
||||
+ "do not match", servername);
|
||||
+ return APR_EGENERAL;
|
||||
+ }
|
||||
+ return APR_SUCCESS;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* This function sets the virtual host from an extended
|
||||
* client hello with a server name indication extension ("SNI", cf. RFC 6066).
|
||||
@@ -2332,30 +2363,12 @@ static apr_status_t init_vhost(conn_rec *c, SSL *ssl)
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
else if (ssl_is_challenge(c, servername, &cert, &key)) {
|
||||
-
|
||||
- sslcon->service_unavailable = 1;
|
||||
- if ((SSL_use_certificate(ssl, cert) < 1)) {
|
||||
- ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10086)
|
||||
- "Failed to configure challenge certificate %s",
|
||||
- servername);
|
||||
+ /* With ACMEv1 we can have challenge connections to a unknown domains
|
||||
+ * that need to be answered with a special certificate and will
|
||||
+ * otherwise not answer any requests. */
|
||||
+ if (set_challenge_creds(c, servername, ssl, cert, key) != APR_SUCCESS) {
|
||||
return APR_EGENERAL;
|
||||
}
|
||||
-
|
||||
- if (!SSL_use_PrivateKey(ssl, key)) {
|
||||
- ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10087)
|
||||
- "error '%s' using Challenge key: %s",
|
||||
- ERR_error_string(ERR_peek_last_error(), NULL),
|
||||
- servername);
|
||||
- return APR_EGENERAL;
|
||||
- }
|
||||
-
|
||||
- if (SSL_check_private_key(ssl) < 1) {
|
||||
- ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(10088)
|
||||
- "Challenge certificate and private key %s "
|
||||
- "do not match", servername);
|
||||
- return APR_EGENERAL;
|
||||
- }
|
||||
-
|
||||
}
|
||||
else {
|
||||
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02044)
|
||||
@@ -2648,6 +2661,23 @@ int ssl_callback_alpn_select(SSL *ssl,
|
||||
proposed);
|
||||
return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
}
|
||||
+
|
||||
+ /* protocol was switched, this could be a challenge protocol such as "acme-tls/1".
|
||||
+ * For that to work, we need to allow overrides to our ssl certificate.
|
||||
+ * However, exclude challenge checks on our best known traffic protocol.
|
||||
+ * (http/1.1 is the default, we never switch to it anyway.)
|
||||
+ */
|
||||
+ if (strcmp("h2", proposed)) {
|
||||
+ const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
|
||||
+ X509 *cert;
|
||||
+ EVP_PKEY *key;
|
||||
+
|
||||
+ if (ssl_is_challenge(c, servername, &cert, &key)) {
|
||||
+ if (set_challenge_creds(c, servername, ssl, cert, key) != APR_SUCCESS) {
|
||||
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
return SSL_TLSEXT_ERR_OK;
|
||||
diff --git a/modules/ssl/ssl_util_stapling.c b/modules/ssl/ssl_util_stapling.c
|
||||
index c3e2cfa..4df0a9a 100644
|
||||
--- a/modules/ssl/ssl_util_stapling.c
|
||||
+++ b/modules/ssl/ssl_util_stapling.c
|
||||
@@ -31,12 +31,28 @@
|
||||
#include "ssl_private.h"
|
||||
#include "ap_mpm.h"
|
||||
#include "apr_thread_mutex.h"
|
||||
+#include "mod_ssl_openssl.h"
|
||||
+
|
||||
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, init_stapling_status,
|
||||
+ (server_rec *s, apr_pool_t *p,
|
||||
+ X509 *cert, X509 *issuer),
|
||||
+ (s, p, cert, issuer),
|
||||
+ DECLINED, DECLINED)
|
||||
+
|
||||
+APR_IMPLEMENT_OPTIONAL_HOOK_RUN_ALL(ssl, SSL, int, get_stapling_status,
|
||||
+ (unsigned char **pder, int *pderlen,
|
||||
+ conn_rec *c, server_rec *s, X509 *cert),
|
||||
+ (pder, pderlen, c, s, cert),
|
||||
+ DECLINED, DECLINED)
|
||||
+
|
||||
|
||||
#ifdef HAVE_OCSP_STAPLING
|
||||
|
||||
static int stapling_cache_mutex_on(server_rec *s);
|
||||
static int stapling_cache_mutex_off(server_rec *s);
|
||||
|
||||
+static int stapling_cb(SSL *ssl, void *arg);
|
||||
+
|
||||
/**
|
||||
* Maxiumum OCSP stapling response size. This should be the response for a
|
||||
* single certificate and will typically include the responder certificate chain
|
||||
@@ -119,7 +135,38 @@ int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
|
||||
OCSP_CERTID *cid = NULL;
|
||||
STACK_OF(OPENSSL_STRING) *aia = NULL;
|
||||
|
||||
- if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1))
|
||||
+ if (x == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (!(issuer = stapling_get_issuer(mctx, x))) {
|
||||
+ /* In Apache pre 2.4.40, we use to come here only when mod_ssl stapling
|
||||
+ * was enabled. With the new hooks, we give other modules the chance
|
||||
+ * to provide stapling status. However, we do not want to log ssl errors
|
||||
+ * where we did not do so in the past. */
|
||||
+ if (mctx->stapling_enabled == TRUE) {
|
||||
+ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02217)
|
||||
+ "ssl_stapling_init_cert: can't retrieve issuer "
|
||||
+ "certificate!");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (ssl_run_init_stapling_status(s, p, x, issuer) == APR_SUCCESS) {
|
||||
+ /* Someone's taken over or mod_ssl's own implementation is not enabled */
|
||||
+ if (mctx->stapling_enabled != TRUE) {
|
||||
+ SSL_CTX_set_tlsext_status_cb(mctx->ssl_ctx, stapling_cb);
|
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO() "OCSP stapling added via hook");
|
||||
+ }
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (mctx->stapling_enabled != TRUE) {
|
||||
+ /* mod_ssl's own implementation is not enabled */
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (X509_digest(x, EVP_sha1(), idx, NULL) != 1)
|
||||
return 0;
|
||||
|
||||
cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx));
|
||||
@@ -139,13 +186,6 @@ int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
|
||||
return 1;
|
||||
}
|
||||
|
||||
- if (!(issuer = stapling_get_issuer(mctx, x))) {
|
||||
- ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02217)
|
||||
- "ssl_stapling_init_cert: can't retrieve issuer "
|
||||
- "certificate!");
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
cid = OCSP_cert_to_id(NULL, x, issuer);
|
||||
X509_free(issuer);
|
||||
if (!cid) {
|
||||
@@ -182,18 +222,16 @@ int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
|
||||
mctx->sc->vhost_id);
|
||||
|
||||
apr_hash_set(stapling_certinfo, cinf->idx, sizeof(cinf->idx), cinf);
|
||||
-
|
||||
+
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static certinfo *stapling_get_certinfo(server_rec *s, modssl_ctx_t *mctx,
|
||||
+static certinfo *stapling_get_certinfo(server_rec *s, X509 *x, modssl_ctx_t *mctx,
|
||||
SSL *ssl)
|
||||
{
|
||||
certinfo *cinf;
|
||||
- X509 *x;
|
||||
UCHAR idx[SHA_DIGEST_LENGTH];
|
||||
- x = SSL_get_certificate(ssl);
|
||||
- if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1))
|
||||
+ if (X509_digest(x, EVP_sha1(), idx, NULL) != 1)
|
||||
return NULL;
|
||||
cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx));
|
||||
if (cinf && cinf->cid)
|
||||
@@ -750,18 +788,34 @@ static int stapling_cb(SSL *ssl, void *arg)
|
||||
OCSP_RESPONSE *rsp = NULL;
|
||||
int rv;
|
||||
BOOL ok = TRUE;
|
||||
+ X509 *x;
|
||||
+ unsigned char *rspder = NULL;
|
||||
+ int rspderlen;
|
||||
|
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951)
|
||||
+ "stapling_cb: OCSP Stapling callback called");
|
||||
+
|
||||
+ x = SSL_get_certificate(ssl);
|
||||
+ if (x == NULL) {
|
||||
+ return SSL_TLSEXT_ERR_NOACK;
|
||||
+ }
|
||||
+
|
||||
+ if (ssl_run_get_stapling_status(&rspder, &rspderlen, conn, s, x) == APR_SUCCESS) {
|
||||
+ /* a hook handles stapling for this certicate and determines the response */
|
||||
+ if (rspder == NULL || rspderlen <= 0) {
|
||||
+ return SSL_TLSEXT_ERR_NOACK;
|
||||
+ }
|
||||
+ SSL_set_tlsext_status_ocsp_resp(ssl, rspder, rspderlen);
|
||||
+ return SSL_TLSEXT_ERR_OK;
|
||||
+ }
|
||||
+
|
||||
if (sc->server->stapling_enabled != TRUE) {
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01950)
|
||||
"stapling_cb: OCSP Stapling disabled");
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
|
||||
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951)
|
||||
- "stapling_cb: OCSP Stapling callback called");
|
||||
-
|
||||
- cinf = stapling_get_certinfo(s, mctx, ssl);
|
||||
- if (cinf == NULL) {
|
||||
+ if ((cinf = stapling_get_certinfo(s, x, mctx, ssl)) == NULL) {
|
||||
return SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
|
||||
@@ -864,9 +918,10 @@ apr_status_t modssl_init_stapling(server_rec *s, apr_pool_t *p,
|
||||
if (mctx->stapling_responder_timeout == UNSET) {
|
||||
mctx->stapling_responder_timeout = 10 * APR_USEC_PER_SEC;
|
||||
}
|
||||
+
|
||||
SSL_CTX_set_tlsext_status_cb(ctx, stapling_cb);
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01960) "OCSP stapling initialized");
|
||||
-
|
||||
+
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
44
httpd-2.4.37-mod-md-perms.patch
Normal file
44
httpd-2.4.37-mod-md-perms.patch
Normal file
@ -0,0 +1,44 @@
|
||||
diff --git a/modules/md/mod_md_os.c b/modules/md/mod_md_os.c
|
||||
index f96d566..8df0248 100644
|
||||
--- a/modules/md/mod_md_os.c
|
||||
+++ b/modules/md/mod_md_os.c
|
||||
@@ -41,14 +41,20 @@
|
||||
|
||||
apr_status_t md_try_chown(const char *fname, unsigned int uid, int gid, apr_pool_t *p)
|
||||
{
|
||||
-#if AP_NEED_SET_MUTEX_PERMS
|
||||
- if (-1 == chown(fname, (uid_t)uid, (gid_t)gid)) {
|
||||
- apr_status_t rv = APR_FROM_OS_ERROR(errno);
|
||||
- if (!APR_STATUS_IS_ENOENT(rv)) {
|
||||
- ap_log_perror(APLOG_MARK, APLOG_ERR, rv, p, APLOGNO(10082)
|
||||
- "Can't change owner of %s", fname);
|
||||
+#if AP_NEED_SET_MUTEX_PERMS && HAVE_UNISTD_H
|
||||
+ /* Since we only switch user when running as root, we only need to chown directories
|
||||
+ * in that case. Otherwise, the server will ignore any "user/group" directives and
|
||||
+ * child processes have the same privileges as the parent.
|
||||
+ */
|
||||
+ if (!geteuid()) {
|
||||
+ if (-1 == chown(fname, (uid_t)uid, (gid_t)gid)) {
|
||||
+ apr_status_t rv = APR_FROM_OS_ERROR(errno);
|
||||
+ if (!APR_STATUS_IS_ENOENT(rv)) {
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_ERR, rv, p, APLOGNO(10082)
|
||||
+ "Can't change owner of %s", fname);
|
||||
+ }
|
||||
+ return rv;
|
||||
}
|
||||
- return rv;
|
||||
}
|
||||
return APR_SUCCESS;
|
||||
#else
|
||||
@@ -58,11 +64,7 @@ apr_status_t md_try_chown(const char *fname, unsigned int uid, int gid, apr_pool
|
||||
|
||||
apr_status_t md_make_worker_accessible(const char *fname, apr_pool_t *p)
|
||||
{
|
||||
-#if AP_NEED_SET_MUTEX_PERMS
|
||||
return md_try_chown(fname, ap_unixd_config.user_id, -1, p);
|
||||
-#else
|
||||
- return APR_ENOTIMPL;
|
||||
-#endif
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
24
httpd-2.4.37-mod-mime-magic-strdup.patch
Normal file
24
httpd-2.4.37-mod-mime-magic-strdup.patch
Normal file
@ -0,0 +1,24 @@
|
||||
diff --git a/docs/conf/magic b/docs/conf/magic
|
||||
index 7c56119..bc891d9 100644
|
||||
--- a/docs/conf/magic
|
||||
+++ b/docs/conf/magic
|
||||
@@ -87,7 +87,7 @@
|
||||
# Microsoft WAVE format (*.wav)
|
||||
# [GRR 950115: probably all of the shorts and longs should be leshort/lelong]
|
||||
# Microsoft RIFF
|
||||
-0 string RIFF audio/unknown
|
||||
+0 string RIFF
|
||||
# - WAVE format
|
||||
>8 string WAVE audio/x-wav
|
||||
# MPEG audio.
|
||||
--- a/modules/metadata/mod_mime_magic.c 2013/06/11 07:36:13 1491699
|
||||
+++ b/modules/metadata/mod_mime_magic.c 2013/06/11 07:41:40 1491700
|
||||
@@ -606,7 +606,7 @@
|
||||
/* high overhead for 1 char - just hope they don't do this much */
|
||||
str[0] = c;
|
||||
str[1] = '\0';
|
||||
- return magic_rsl_add(r, str);
|
||||
+ return magic_rsl_add(r, apr_pstrdup(r->pool, str));
|
||||
}
|
||||
|
||||
/* allocate and copy a contiguous string from a result string list */
|
143
httpd-2.4.37-pr37355.patch
Normal file
143
httpd-2.4.37-pr37355.patch
Normal file
@ -0,0 +1,143 @@
|
||||
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
|
||||
index d13c249..f383996 100644
|
||||
--- a/modules/proxy/mod_proxy.c
|
||||
+++ b/modules/proxy/mod_proxy.c
|
||||
@@ -1200,11 +1200,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;
|
||||
@@ -1621,8 +1630,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 =
|
||||
@@ -1680,19 +1689,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)
|
||||
@@ -2638,9 +2652,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 288c5d4..57cc92f 100644
|
||||
--- a/modules/proxy/mod_proxy.h
|
||||
+++ b/modules/proxy/mod_proxy.h
|
||||
@@ -116,6 +116,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 0759dac..2bfc8f0 100644
|
||||
--- a/modules/proxy/proxy_util.c
|
||||
+++ b/modules/proxy/proxy_util.c
|
||||
@@ -2446,11 +2446,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);
|
||||
}
|
||||
}
|
||||
@@ -2672,7 +2675,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,
|
||||
@@ -3567,6 +3571,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
apr_bucket *e;
|
||||
int do_100_continue;
|
||||
conn_rec *origin = p_conn->connection;
|
||||
+ const char *creds;
|
||||
proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
|
||||
|
||||
/*
|
||||
@@ -3743,6 +3748,11 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
return HTTP_BAD_REQUEST;
|
||||
}
|
||||
|
||||
+ creds = apr_table_get(r->notes, "proxy-basic-creds");
|
||||
+ if (creds) {
|
||||
+ apr_table_mergen(r->headers_in, "Proxy-Authorization", creds);
|
||||
+ }
|
||||
+
|
||||
/* send request headers */
|
||||
headers_in_array = apr_table_elts(r->headers_in);
|
||||
headers_in = (const apr_table_entry_t *) headers_in_array->elts;
|
1713
httpd-2.4.37-proxy-continue.patch
Normal file
1713
httpd-2.4.37-proxy-continue.patch
Normal file
File diff suppressed because it is too large
Load Diff
132
httpd-2.4.37-proxy-ws-idle-timeout.patch
Normal file
132
httpd-2.4.37-proxy-ws-idle-timeout.patch
Normal file
@ -0,0 +1,132 @@
|
||||
diff --git a/docs/manual/mod/mod_proxy_wstunnel.html.en b/docs/manual/mod/mod_proxy_wstunnel.html.en
|
||||
index 21ffbe2..16e1628 100644
|
||||
--- a/docs/manual/mod/mod_proxy_wstunnel.html.en
|
||||
+++ b/docs/manual/mod/mod_proxy_wstunnel.html.en
|
||||
@@ -60,14 +60,33 @@ NONE means you bypass the check for the header but still upgrade to WebSocket.
|
||||
ANY means that <code>Upgrade</code> will read in the request headers and use
|
||||
in the response <code>Upgrade</code></p>
|
||||
</div>
|
||||
-<div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><h3 class="directives">Directives</h3>
|
||||
-<p>This module provides no
|
||||
- directives.</p>
|
||||
+<div id="quickview"><h3 class="directives">Directives</h3>
|
||||
+<ul id="toc">
|
||||
+<li><img alt="" src="../images/down.gif" /> <a href="#proxywebsocketidletimeout">ProxyWebsocketIdleTimeout</a></li>
|
||||
+</ul>
|
||||
+
|
||||
<h3>Bugfix checklist</h3><ul class="seealso"><li><a href="https://www.apache.org/dist/httpd/CHANGES_2.4">httpd changelog</a></li><li><a href="https://bz.apache.org/bugzilla/buglist.cgi?bug_status=__open__&list_id=144532&product=Apache%20httpd-2&query_format=specific&order=changeddate%20DESC%2Cpriority%2Cbug_severity&component=mod_proxy_wstunnel">Known issues</a></li><li><a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2&component=mod_proxy_wstunnel">Report a bug</a></li></ul><h3>See also</h3>
|
||||
<ul class="seealso">
|
||||
<li><code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code></li>
|
||||
<li><a href="#comments_section">Comments</a></li></ul></div>
|
||||
|
||||
+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
+<div class="directive-section"><h2><a name="ProxyWebsocketIdleTimeout" id="ProxyWebsocketIdleTimeout">ProxyWebsocketIdleTimeout</a> <a name="proxywebsocketidletimeout" id="proxywebsocketidletimeout">Directive</a> <a title="Permanent link" href="#proxywebsocketidletimeout" class="permalink">¶</a></h2>
|
||||
+<table class="directive">
|
||||
+<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Sets the maximum amount of time to wait for data on the websockets tunnel</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>ProxyWebsocketIdleTimeout <var>num</var>[ms]</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>ProxyWebsocketIdleTimeout 0</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_proxy_wstunnel</td></tr>
|
||||
+</table>
|
||||
+ <p>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 <em>ms</em> suffix.</p>
|
||||
+
|
||||
+</div>
|
||||
+
|
||||
</div>
|
||||
<div class="bottomlang">
|
||||
<p><span>Available Languages: </span><a href="../en/mod/mod_proxy_wstunnel.html" title="English"> en </a> |
|
||||
diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c
|
||||
index 4aadbab..ca3ed3a 100644
|
||||
--- a/modules/proxy/mod_proxy_wstunnel.c
|
||||
+++ b/modules/proxy/mod_proxy_wstunnel.c
|
||||
@@ -18,6 +18,10 @@
|
||||
|
||||
module AP_MODULE_DECLARE_DATA proxy_wstunnel_module;
|
||||
|
||||
+typedef struct {
|
||||
+ apr_time_t idle_timeout;
|
||||
+} proxyws_dir_conf;
|
||||
+
|
||||
/*
|
||||
* Canonicalise http-like URLs.
|
||||
* scheme is the scheme for the URL
|
||||
@@ -108,6 +112,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;
|
||||
@@ -185,10 +191,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;
|
||||
@@ -366,6 +375,38 @@ 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 */
|
||||
+
|
||||
+ return (void *) new;
|
||||
+}
|
||||
+
|
||||
+static const command_rec ws_proxy_cmds[] =
|
||||
+{
|
||||
+ AP_INIT_TAKE1("ProxyWebsocketIdleTimeout", proxyws_set_idle, NULL, RSRC_CONF|ACCESS_CONF,
|
||||
+ "timeout for activity in either direction, unlimited by default."),
|
||||
+
|
||||
+ {NULL}
|
||||
+};
|
||||
+
|
||||
static void ap_proxy_http_register_hook(apr_pool_t *p)
|
||||
{
|
||||
proxy_hook_scheme_handler(proxy_wstunnel_handler, NULL, NULL, APR_HOOK_FIRST);
|
||||
@@ -374,10 +415,10 @@ static void ap_proxy_http_register_hook(apr_pool_t *p)
|
||||
|
||||
AP_DECLARE_MODULE(proxy_wstunnel) = {
|
||||
STANDARD20_MODULE_STUFF,
|
||||
- NULL, /* create per-directory config structure */
|
||||
+ create_proxyws_dir_config, /* create per-directory config structure */
|
||||
NULL, /* merge per-directory config structures */
|
||||
NULL, /* create per-server config structure */
|
||||
NULL, /* merge per-server config structures */
|
||||
- NULL, /* command apr_table_t */
|
||||
+ ws_proxy_cmds, /* command apr_table_t */
|
||||
ap_proxy_http_register_hook /* register hooks */
|
||||
};
|
1420
httpd-2.4.37-r1828172+.patch
Normal file
1420
httpd-2.4.37-r1828172+.patch
Normal file
File diff suppressed because it is too large
Load Diff
35
httpd-2.4.37-r1840554.patch
Normal file
35
httpd-2.4.37-r1840554.patch
Normal file
@ -0,0 +1,35 @@
|
||||
diff --git a/modules/arch/unix/mod_systemd.c b/modules/arch/unix/mod_systemd.c
|
||||
index 7a82a90..6c244b6 100644
|
||||
--- a/modules/arch/unix/mod_systemd.c
|
||||
+++ b/modules/arch/unix/mod_systemd.c
|
||||
@@ -100,6 +100,21 @@ static int systemd_post_config(apr_pool_t *pconf, apr_pool_t *plog,
|
||||
return OK;
|
||||
}
|
||||
|
||||
+/* Report the service is ready in post_config, which could be during
|
||||
+ * startup or after a reload. The server could still hit a fatal
|
||||
+ * startup error after this point during ap_run_mpm(), so this is
|
||||
+ * perhaps too early, but by post_config listen() has been called on
|
||||
+ * the TCP ports so new connections will not be rejected. There will
|
||||
+ * always be a possible async failure event simultaneous to the
|
||||
+ * service reporting "ready", so this should be good enough. */
|
||||
+static int systemd_post_config_last(apr_pool_t *p, apr_pool_t *plog,
|
||||
+ apr_pool_t *ptemp, server_rec *main_server)
|
||||
+{
|
||||
+ sd_notify(0, "READY=1\n"
|
||||
+ "STATUS=Configuration loaded.\n");
|
||||
+ return OK;
|
||||
+}
|
||||
+
|
||||
static int systemd_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type)
|
||||
{
|
||||
int rv;
|
||||
@@ -187,6 +202,8 @@ static void systemd_register_hooks(apr_pool_t *p)
|
||||
ap_hook_pre_config(systemd_pre_config, NULL, NULL, APR_HOOK_LAST);
|
||||
/* Grab the listener config. */
|
||||
ap_hook_post_config(systemd_post_config, NULL, NULL, APR_HOOK_LAST);
|
||||
+ /* Signal service is ready. */
|
||||
+ ap_hook_post_config(systemd_post_config_last, NULL, NULL, APR_HOOK_REALLY_LAST);
|
||||
/* We know the PID in this hook ... */
|
||||
ap_hook_pre_mpm(systemd_pre_mpm, NULL, NULL, APR_HOOK_LAST);
|
||||
/* Used to update httpd's status line using sd_notifyf */
|
272
httpd-2.4.37-r1842929+.patch
Normal file
272
httpd-2.4.37-r1842929+.patch
Normal file
@ -0,0 +1,272 @@
|
||||
# ./pullrev.sh 1842929 1842931 1852982 1853631 1857731
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1842929
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1842931
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1852982
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1857731
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1853631
|
||||
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index 06b8c5a..9eeb5c7 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -213,6 +213,7 @@ install-cgi:
|
||||
install-other:
|
||||
@test -d $(DESTDIR)$(logfiledir) || $(MKINSTALLDIRS) $(DESTDIR)$(logfiledir)
|
||||
@test -d $(DESTDIR)$(runtimedir) || $(MKINSTALLDIRS) $(DESTDIR)$(runtimedir)
|
||||
+ @test -d $(DESTDIR)$(statedir) || $(MKINSTALLDIRS) $(DESTDIR)$(statedir)
|
||||
@for ext in dll x; do \
|
||||
file=apachecore.$$ext; \
|
||||
if test -f $$file; then \
|
||||
diff --git a/acinclude.m4 b/acinclude.m4
|
||||
index 0ad0c13..a8c2804 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)
|
||||
@@ -663,6 +664,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 a208b53..de6a8ad 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 adc5825..effccc1 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/modules/md/mod_md_config.c b/modules/md/mod_md_config.c
|
||||
index 336a21b..4d50e26 100644
|
||||
--- a/modules/md/mod_md_config.c
|
||||
+++ b/modules/md/mod_md_config.c
|
||||
@@ -54,10 +54,18 @@
|
||||
|
||||
#define DEF_VAL (-1)
|
||||
|
||||
+#ifndef MD_DEFAULT_BASE_DIR
|
||||
+#define MD_DEFAULT_BASE_DIR "md"
|
||||
+#endif
|
||||
+
|
||||
/* Default settings for the global conf */
|
||||
static md_mod_conf_t defmc = {
|
||||
NULL,
|
||||
- "md",
|
||||
+#if 1
|
||||
+ NULL, /* apply default state-dir-relative */
|
||||
+#else
|
||||
+ MD_DEFAULT_BASE_DIR,
|
||||
+#endif
|
||||
NULL,
|
||||
NULL,
|
||||
80,
|
||||
@@ -864,6 +872,12 @@ apr_status_t md_config_post_config(server_rec *s, apr_pool_t *p)
|
||||
if (mc->hsts_max_age > 0) {
|
||||
mc->hsts_header = apr_psprintf(p, "max-age=%d", mc->hsts_max_age);
|
||||
}
|
||||
+
|
||||
+#if 1
|
||||
+ if (mc->base_dir == NULL) {
|
||||
+ mc->base_dir = ap_state_dir_relative(p, MD_DEFAULT_BASE_DIR);
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
diff --git a/server/core.c b/server/core.c
|
||||
index bbe52e0..b5ab429 100644
|
||||
--- a/server/core.c
|
||||
+++ b/server/core.c
|
||||
@@ -133,6 +133,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;
|
||||
@@ -1411,12 +1413,15 @@ 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;
|
||||
- return OK;
|
||||
+ core_state_dir = NULL;
|
||||
+
|
||||
+ return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3108,6 +3113,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);
|
||||
@@ -4409,6 +4432,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"),
|
||||
@@ -4932,8 +4957,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_DOLLAR_ENDONLY);
|
||||
|
||||
@@ -5202,6 +5226,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;
|
48
httpd-2.4.37-r1845768+.patch
Normal file
48
httpd-2.4.37-r1845768+.patch
Normal file
@ -0,0 +1,48 @@
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index 70d151e..e4f5fc8 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -1095,7 +1095,9 @@ static apr_status_t ssl_init_ctx_crl(server_rec *s,
|
||||
/*
|
||||
* Read a file that optionally contains the server certificate in PEM
|
||||
* format, possibly followed by a sequence of CA certificates that
|
||||
- * should be sent to the peer in the SSL Certificate message.
|
||||
+ * should be sent to the peer in the SSL Certificate message. Returns
|
||||
+ * 0 on success, otherwise the OpenSSL error stack contents should be
|
||||
+ * reported.
|
||||
*/
|
||||
static int use_certificate_chain(
|
||||
SSL_CTX *ctx, char *file, int skipfirst, pem_password_cb *cb)
|
||||
@@ -1128,8 +1130,10 @@ static int use_certificate_chain(
|
||||
ctx->extra_certs = NULL;
|
||||
}
|
||||
#endif
|
||||
+
|
||||
/* create new extra chain by loading the certs */
|
||||
n = 0;
|
||||
+ ERR_clear_error();
|
||||
while ((x509 = PEM_read_bio_X509(bio, NULL, cb, NULL)) != NULL) {
|
||||
if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) {
|
||||
X509_free(x509);
|
||||
@@ -1190,6 +1194,7 @@ static apr_status_t ssl_init_ctx_cert_chain(server_rec *s,
|
||||
if (n < 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01903)
|
||||
"Failed to configure CA certificate chain!");
|
||||
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
|
||||
return ssl_die(s);
|
||||
}
|
||||
|
||||
diff --git a/modules/ssl/ssl_util_ocsp.c b/modules/ssl/ssl_util_ocsp.c
|
||||
index b11a6e9..b66e151 100644
|
||||
--- a/modules/ssl/ssl_util_ocsp.c
|
||||
+++ b/modules/ssl/ssl_util_ocsp.c
|
||||
@@ -363,7 +363,9 @@ static STACK_OF(X509) *modssl_read_ocsp_certificates(const char *file)
|
||||
BIO_free(bio);
|
||||
return NULL;
|
||||
}
|
||||
+
|
||||
/* create new extra chain by loading the certs */
|
||||
+ ERR_clear_error();
|
||||
while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
|
||||
if (!other_certs) {
|
||||
other_certs = sk_X509_new_null();
|
44
httpd-2.4.37-r1851471.patch
Normal file
44
httpd-2.4.37-r1851471.patch
Normal file
@ -0,0 +1,44 @@
|
||||
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
|
||||
index 0958135..018b667 100644
|
||||
--- a/modules/ssl/ssl_engine_io.c
|
||||
+++ b/modules/ssl/ssl_engine_io.c
|
||||
@@ -200,6 +200,8 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl)
|
||||
apr_bucket *e;
|
||||
int need_flush;
|
||||
|
||||
+ 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) {
|
||||
@@ -208,12 +210,6 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl)
|
||||
}
|
||||
#endif
|
||||
|
||||
- /* when handshaking we'll have a small number of bytes.
|
||||
- * max size SSL will pass us here is about 16k.
|
||||
- * (16413 bytes to be exact)
|
||||
- */
|
||||
- BIO_clear_retry_flags(bio);
|
||||
-
|
||||
/* Use a transient bucket for the output data - any downstream
|
||||
* filter must setaside if necessary. */
|
||||
e = apr_bucket_transient_create(in, inl, outctx->bb->bucket_alloc);
|
||||
@@ -460,6 +456,8 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen)
|
||||
if (!in)
|
||||
return 0;
|
||||
|
||||
+ 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) {
|
||||
@@ -468,8 +466,6 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen)
|
||||
}
|
||||
#endif
|
||||
|
||||
- BIO_clear_retry_flags(bio);
|
||||
-
|
||||
if (!inctx->bb) {
|
||||
inctx->rc = APR_EOF;
|
||||
return -1;
|
209
httpd-2.4.37-r1861793+.patch
Normal file
209
httpd-2.4.37-r1861793+.patch
Normal file
@ -0,0 +1,209 @@
|
||||
diff --git a/configure.in b/configure.in
|
||||
index de6a8ad..4ca489d 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -465,6 +465,28 @@ LIBS=""
|
||||
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 <crypt.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#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
|
||||
diff --git a/support/htpasswd.c b/support/htpasswd.c
|
||||
index 660a27c..136f62a 100644
|
||||
--- a/support/htpasswd.c
|
||||
+++ b/support/htpasswd.c
|
||||
@@ -98,28 +98,32 @@ static int mkrecord(struct passwd_ctx *ctx, char *user)
|
||||
static void usage(void)
|
||||
{
|
||||
apr_file_printf(errfile, "Usage:" NL
|
||||
- "\thtpasswd [-cimBdpsDv] [-C cost] passwordfile username" NL
|
||||
- "\thtpasswd -b[cmBdpsDv] [-C cost] passwordfile username password" NL
|
||||
+ "\thtpasswd [-cimB25dpsDv] [-C cost] [-r rounds] passwordfile username" NL
|
||||
+ "\thtpasswd -b[cmB25dpsDv] [-C cost] [-r rounds] passwordfile username password" NL
|
||||
NL
|
||||
- "\thtpasswd -n[imBdps] [-C cost] username" NL
|
||||
- "\thtpasswd -nb[mBdps] [-C cost] username password" NL
|
||||
+ "\thtpasswd -n[imB25dps] [-C cost] [-r rounds] username" NL
|
||||
+ "\thtpasswd -nb[mB25dps] [-C cost] [-r rounds] username password" NL
|
||||
" -c Create a new file." NL
|
||||
" -n Don't update file; display results on stdout." NL
|
||||
" -b Use the password from the command line rather than prompting "
|
||||
"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 (secure)." NL
|
||||
+ " -5 Force SHA-512 crypt() hash of the password (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 31)." 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 @@ static void check_args(int argc, const char *const argv[],
|
||||
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;
|
||||
diff --git a/support/passwd_common.c b/support/passwd_common.c
|
||||
index 664e509..d45657c 100644
|
||||
--- a/support/passwd_common.c
|
||||
+++ b/support/passwd_common.c
|
||||
@@ -185,10 +185,15 @@ int mkhash(struct passwd_ctx *ctx)
|
||||
#if CRYPT_ALGO_SUPPORTED
|
||||
char *cbuf;
|
||||
#endif
|
||||
+#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 @@ int mkhash(struct passwd_ctx *ctx)
|
||||
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 @@ int parse_common_options(struct passwd_ctx *ctx, char opt,
|
||||
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 @@ int parse_common_options(struct passwd_ctx *ctx, char opt,
|
||||
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;
|
||||
diff --git a/support/passwd_common.h b/support/passwd_common.h
|
||||
index 660081e..f1b3cd7 100644
|
||||
--- a/support/passwd_common.h
|
||||
+++ b/support/passwd_common.h
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "apu_version.h"
|
||||
#endif
|
||||
|
||||
+#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 @@ struct passwd_ctx {
|
||||
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,
|
40
httpd-2.4.37-r1864000.patch
Normal file
40
httpd-2.4.37-r1864000.patch
Normal file
@ -0,0 +1,40 @@
|
||||
--- a/modules/proxy/mod_proxy_hcheck.c 2019/07/30 13:01:08 1863999
|
||||
+++ b/modules/proxy/mod_proxy_hcheck.c 2019/07/30 13:01:21 1864000
|
||||
@@ -110,6 +110,10 @@
|
||||
if (!worker && !v) {
|
||||
return "Bad call to set_worker_hc_param()";
|
||||
}
|
||||
+ if (!ctx) {
|
||||
+ ctx = hc_create_config(p, s);
|
||||
+ ap_set_module_config(s->module_config, &proxy_hcheck_module, ctx);
|
||||
+ }
|
||||
temp = (hc_template_t *)v;
|
||||
if (!strcasecmp(key, "hctemplate")) {
|
||||
hc_template_t *template;
|
||||
@@ -1059,6 +1063,8 @@
|
||||
int i;
|
||||
sctx_t *ctx = (sctx_t *) ap_get_module_config(r->server->module_config,
|
||||
&proxy_hcheck_module);
|
||||
+ if (!ctx)
|
||||
+ return;
|
||||
if (apr_is_empty_table(ctx->conditions))
|
||||
return;
|
||||
|
||||
@@ -1088,6 +1094,8 @@
|
||||
int i;
|
||||
sctx_t *ctx = (sctx_t *) ap_get_module_config(r->server->module_config,
|
||||
&proxy_hcheck_module);
|
||||
+ if (!ctx)
|
||||
+ return;
|
||||
if (apr_is_empty_table(ctx->conditions))
|
||||
return;
|
||||
|
||||
@@ -1111,6 +1119,8 @@
|
||||
int i;
|
||||
sctx_t *ctx = (sctx_t *) ap_get_module_config(r->server->module_config,
|
||||
&proxy_hcheck_module);
|
||||
+ if (!ctx)
|
||||
+ return 0;
|
||||
if (apr_is_empty_table(ctx->conditions))
|
||||
return 0;
|
||||
|
117
httpd-2.4.37-r1870095+.patch
Normal file
117
httpd-2.4.37-r1870095+.patch
Normal file
@ -0,0 +1,117 @@
|
||||
# ./pullrev.sh 1870095 1870097
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1870095
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1870097
|
||||
|
||||
--- httpd-2.4.37/modules/ssl/ssl_engine_kernel.c
|
||||
+++ httpd-2.4.37/modules/ssl/ssl_engine_kernel.c
|
||||
@@ -114,6 +114,45 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
+/* If a renegotiation is required for the location, and the request
|
||||
+ * includes a message body (and the client has not requested a "100
|
||||
+ * Continue" response), then the client will be streaming the request
|
||||
+ * body over the wire already. In that case, it is not possible to
|
||||
+ * stop and perform a new SSL handshake immediately; once the SSL
|
||||
+ * library moves to the "accept" state, it will reject the SSL packets
|
||||
+ * which the client is sending for the request body.
|
||||
+ *
|
||||
+ * To allow authentication to complete in the hook, the solution used
|
||||
+ * here is to fill a (bounded) buffer with the request body, and then
|
||||
+ * to reinject that request body later.
|
||||
+ *
|
||||
+ * This function is called to fill the renegotiation buffer for the
|
||||
+ * location as required, or fail. Returns zero on success or HTTP_
|
||||
+ * error code on failure.
|
||||
+ */
|
||||
+static int fill_reneg_buffer(request_rec *r, SSLDirConfigRec *dc)
|
||||
+{
|
||||
+ int rv;
|
||||
+ apr_size_t rsize;
|
||||
+
|
||||
+ /* ### this is HTTP/1.1 specific, special case for protocol? */
|
||||
+ if (r->expecting_100 || !ap_request_has_body(r)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ rsize = dc->nRenegBufferSize == UNSET ? DEFAULT_RENEG_BUFFER_SIZE : dc->nRenegBufferSize;
|
||||
+ if (rsize > 0) {
|
||||
+ /* Fill the I/O buffer with the request body if possible. */
|
||||
+ rv = ssl_io_buffer_fill(r, rsize);
|
||||
+ }
|
||||
+ else {
|
||||
+ /* If the reneg buffer size is set to zero, just fail. */
|
||||
+ rv = HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||
+ }
|
||||
+
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
#ifdef HAVE_TLSEXT
|
||||
static int ap_array_same_str_set(apr_array_header_t *s1, apr_array_header_t *s2)
|
||||
{
|
||||
@@ -814,41 +853,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
- /* If a renegotiation is now required for this location, and the
|
||||
- * request includes a message body (and the client has not
|
||||
- * requested a "100 Continue" response), then the client will be
|
||||
- * streaming the request body over the wire already. In that
|
||||
- * case, it is not possible to stop and perform a new SSL
|
||||
- * handshake immediately; once the SSL library moves to the
|
||||
- * "accept" state, it will reject the SSL packets which the client
|
||||
- * is sending for the request body.
|
||||
- *
|
||||
- * To allow authentication to complete in this auth hook, the
|
||||
- * solution used here is to fill a (bounded) buffer with the
|
||||
- * request body, and then to reinject that request body later.
|
||||
- */
|
||||
- if (renegotiate && !renegotiate_quick
|
||||
- && !r->expecting_100
|
||||
- && ap_request_has_body(r)) {
|
||||
- int rv;
|
||||
- apr_size_t rsize;
|
||||
-
|
||||
- rsize = dc->nRenegBufferSize == UNSET ? DEFAULT_RENEG_BUFFER_SIZE :
|
||||
- dc->nRenegBufferSize;
|
||||
- if (rsize > 0) {
|
||||
- /* Fill the I/O buffer with the request body if possible. */
|
||||
- rv = ssl_io_buffer_fill(r, rsize);
|
||||
- }
|
||||
- else {
|
||||
- /* If the reneg buffer size is set to zero, just fail. */
|
||||
- rv = HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||
- }
|
||||
-
|
||||
- if (rv) {
|
||||
+ /* Fill reneg buffer if required. */
|
||||
+ if (renegotiate && !renegotiate_quick) {
|
||||
+ rc = fill_reneg_buffer(r, dc);
|
||||
+ if (rc) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02257)
|
||||
"could not buffer message body to allow "
|
||||
"SSL renegotiation to proceed");
|
||||
- return rv;
|
||||
+ return rc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1132,6 +1144,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Fill reneg buffer if required. */
|
||||
+ if (change_vmode) {
|
||||
+ rc = fill_reneg_buffer(r, dc);
|
||||
+ if (rc) {
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10228)
|
||||
+ "could not buffer message body to allow "
|
||||
+ "TLS Post-Handshake Authentication to proceed");
|
||||
+ return rc;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (change_vmode) {
|
||||
char peekbuf[1];
|
||||
|
636
httpd-2.4.37-r1872790.patch
Normal file
636
httpd-2.4.37-r1872790.patch
Normal file
@ -0,0 +1,636 @@
|
||||
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
|
||||
index 57cc92f..fbbd508 100644
|
||||
--- a/modules/proxy/mod_proxy.h
|
||||
+++ b/modules/proxy/mod_proxy.h
|
||||
@@ -288,12 +288,15 @@ typedef struct {
|
||||
|
||||
/* Connection pool */
|
||||
struct proxy_conn_pool {
|
||||
- apr_pool_t *pool; /* The pool used in constructor and destructor calls */
|
||||
- apr_sockaddr_t *addr; /* Preparsed remote address info */
|
||||
- apr_reslist_t *res; /* Connection resource list */
|
||||
- proxy_conn_rec *conn; /* Single connection for prefork mpm */
|
||||
+ apr_pool_t *pool; /* The pool used in constructor and destructor calls */
|
||||
+ apr_sockaddr_t *addr; /* Preparsed remote address info */
|
||||
+ apr_reslist_t *res; /* Connection resource list */
|
||||
+ proxy_conn_rec *conn; /* Single connection for prefork mpm */
|
||||
+ apr_pool_t *dns_pool; /* The pool used for worker scoped DNS resolutions */
|
||||
};
|
||||
|
||||
+#define AP_VOLATILIZE_T(T, x) (*(T volatile *)&(x))
|
||||
+
|
||||
/* worker status bits */
|
||||
/*
|
||||
* NOTE: Keep up-to-date w/ proxy_wstat_tbl[]
|
||||
@@ -475,7 +478,9 @@ struct proxy_worker {
|
||||
proxy_conn_pool *cp; /* Connection pool to use */
|
||||
proxy_worker_shared *s; /* Shared data */
|
||||
proxy_balancer *balancer; /* which balancer am I in? */
|
||||
+#if APR_HAS_THREADS
|
||||
apr_thread_mutex_t *tmutex; /* Thread lock for updating address cache */
|
||||
+#endif
|
||||
void *context; /* general purpose storage */
|
||||
ap_conf_vector_t *section_config; /* <Proxy>-section wherein defined */
|
||||
};
|
||||
@@ -534,7 +539,9 @@ struct proxy_balancer {
|
||||
apr_time_t wupdated; /* timestamp of last change to workers list */
|
||||
proxy_balancer_method *lbmethod;
|
||||
apr_global_mutex_t *gmutex; /* global lock for updating list of workers */
|
||||
+#if APR_HAS_THREADS
|
||||
apr_thread_mutex_t *tmutex; /* Thread lock for updating shm */
|
||||
+#endif
|
||||
proxy_server_conf *sconf;
|
||||
void *context; /* general purpose storage */
|
||||
proxy_balancer_shared *s; /* Shared data */
|
||||
diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c
|
||||
index c59f5e9..3a28038 100644
|
||||
--- a/modules/proxy/mod_proxy_balancer.c
|
||||
+++ b/modules/proxy/mod_proxy_balancer.c
|
||||
@@ -346,23 +346,27 @@ static proxy_worker *find_best_worker(proxy_balancer *balancer,
|
||||
proxy_worker *candidate = NULL;
|
||||
apr_status_t rv;
|
||||
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01163)
|
||||
"%s: Lock failed for find_best_worker()",
|
||||
balancer->s->name);
|
||||
return NULL;
|
||||
}
|
||||
+#endif
|
||||
|
||||
candidate = (*balancer->lbmethod->finder)(balancer, r);
|
||||
|
||||
if (candidate)
|
||||
candidate->s->elected++;
|
||||
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01164)
|
||||
"%s: Unlock failed for find_best_worker()",
|
||||
balancer->s->name);
|
||||
}
|
||||
+#endif
|
||||
|
||||
if (candidate == NULL) {
|
||||
/* All the workers are in error state or disabled.
|
||||
@@ -492,11 +496,13 @@ static int proxy_balancer_pre_request(proxy_worker **worker,
|
||||
/* Step 2: Lock the LoadBalancer
|
||||
* XXX: perhaps we need the process lock here
|
||||
*/
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_THREAD_LOCK(*balancer)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01166)
|
||||
"%s: Lock failed for pre_request", (*balancer)->s->name);
|
||||
return DECLINED;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/* Step 3: force recovery */
|
||||
force_recovery(*balancer, r->server);
|
||||
@@ -557,20 +563,24 @@ static int proxy_balancer_pre_request(proxy_worker **worker,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01167)
|
||||
"%s: All workers are in error state for route (%s)",
|
||||
(*balancer)->s->name, route);
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_THREAD_UNLOCK(*balancer)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01168)
|
||||
"%s: Unlock failed for pre_request",
|
||||
(*balancer)->s->name);
|
||||
}
|
||||
+#endif
|
||||
return HTTP_SERVICE_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_THREAD_UNLOCK(*balancer)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01169)
|
||||
"%s: Unlock failed for pre_request",
|
||||
(*balancer)->s->name);
|
||||
}
|
||||
+#endif
|
||||
if (!*worker) {
|
||||
runtime = find_best_worker(*balancer, r);
|
||||
if (!runtime) {
|
||||
@@ -644,12 +654,14 @@ static int proxy_balancer_post_request(proxy_worker *worker,
|
||||
|
||||
apr_status_t rv;
|
||||
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01173)
|
||||
"%s: Lock failed for post_request",
|
||||
balancer->s->name);
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
+#endif
|
||||
|
||||
if (!apr_is_empty_array(balancer->errstatuses)
|
||||
&& !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
|
||||
@@ -681,11 +693,12 @@ static int proxy_balancer_post_request(proxy_worker *worker,
|
||||
worker->s->error_time = apr_time_now();
|
||||
|
||||
}
|
||||
-
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01175)
|
||||
"%s: Unlock failed for post_request", balancer->s->name);
|
||||
}
|
||||
+#endif
|
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01176)
|
||||
"proxy_balancer_post_request for (%s)", balancer->s->name);
|
||||
|
||||
@@ -945,7 +958,6 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog,
|
||||
PROXY_STRNCPY(balancer->s->sname, sname); /* We know this will succeed */
|
||||
|
||||
balancer->max_workers = balancer->workers->nelts + balancer->growth;
|
||||
-
|
||||
/* Create global mutex */
|
||||
rv = ap_global_mutex_create(&(balancer->gmutex), NULL, balancer_mutex_type,
|
||||
balancer->s->sname, s, pconf, 0);
|
||||
@@ -955,7 +967,6 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog,
|
||||
balancer->s->sname);
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
-
|
||||
apr_pool_cleanup_register(pconf, (void *)s, lock_remove,
|
||||
apr_pool_cleanup_null);
|
||||
|
||||
@@ -1135,17 +1146,21 @@ static int balancer_handler(request_rec *r)
|
||||
|
||||
balancer = (proxy_balancer *)conf->balancers->elts;
|
||||
for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01189)
|
||||
"%s: Lock failed for balancer_handler",
|
||||
balancer->s->name);
|
||||
}
|
||||
+#endif
|
||||
ap_proxy_sync_balancer(balancer, r->server, conf);
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01190)
|
||||
"%s: Unlock failed for balancer_handler",
|
||||
balancer->s->name);
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
|
||||
if (r->args && (r->method_number == M_GET)) {
|
||||
@@ -1359,11 +1374,13 @@ static int balancer_handler(request_rec *r)
|
||||
proxy_worker *nworker;
|
||||
nworker = ap_proxy_get_worker(r->pool, bsel, conf, val);
|
||||
if (!nworker && storage->num_free_slots(bsel->wslot)) {
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_GLOBAL_LOCK(bsel)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01194)
|
||||
"%s: Lock failed for adding worker",
|
||||
bsel->s->name);
|
||||
}
|
||||
+#endif
|
||||
ret = ap_proxy_define_worker(conf->pool, &nworker, bsel, conf, val, 0);
|
||||
if (!ret) {
|
||||
unsigned int index;
|
||||
@@ -1372,53 +1389,76 @@ static int balancer_handler(request_rec *r)
|
||||
if ((rv = storage->grab(bsel->wslot, &index)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01195)
|
||||
"worker slotmem_grab failed");
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01196)
|
||||
"%s: Unlock failed for adding worker",
|
||||
bsel->s->name);
|
||||
}
|
||||
+#endif
|
||||
return HTTP_BAD_REQUEST;
|
||||
}
|
||||
if ((rv = storage->dptr(bsel->wslot, index, (void *)&shm)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01197)
|
||||
"worker slotmem_dptr failed");
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01198)
|
||||
"%s: Unlock failed for adding worker",
|
||||
bsel->s->name);
|
||||
}
|
||||
+#endif
|
||||
return HTTP_BAD_REQUEST;
|
||||
}
|
||||
if ((rv = ap_proxy_share_worker(nworker, shm, index)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01199)
|
||||
"Cannot share worker");
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01200)
|
||||
"%s: Unlock failed for adding worker",
|
||||
bsel->s->name);
|
||||
}
|
||||
+#endif
|
||||
return HTTP_BAD_REQUEST;
|
||||
}
|
||||
if ((rv = ap_proxy_initialize_worker(nworker, r->server, conf->pool)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01201)
|
||||
"Cannot init worker");
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01202)
|
||||
"%s: Unlock failed for adding worker",
|
||||
bsel->s->name);
|
||||
}
|
||||
+#endif
|
||||
return HTTP_BAD_REQUEST;
|
||||
}
|
||||
/* sync all timestamps */
|
||||
bsel->wupdated = bsel->s->wupdated = nworker->s->updated = apr_time_now();
|
||||
/* by default, all new workers are disabled */
|
||||
ap_proxy_set_wstatus(PROXY_WORKER_DISABLED_FLAG, 1, nworker);
|
||||
+ } else {
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10163)
|
||||
+ "%s: failed to add worker %s",
|
||||
+ bsel->s->name, val);
|
||||
+#if APR_HAS_THREADS
|
||||
+ PROXY_GLOBAL_UNLOCK(bsel);
|
||||
+#endif
|
||||
+ return HTTP_BAD_REQUEST;
|
||||
}
|
||||
+#if APR_HAS_THREADS
|
||||
if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01203)
|
||||
"%s: Unlock failed for adding worker",
|
||||
bsel->s->name);
|
||||
}
|
||||
+#endif
|
||||
+ } else {
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10164)
|
||||
+ "%s: failed to add worker %s",
|
||||
+ bsel->s->name, val);
|
||||
+ return HTTP_BAD_REQUEST;
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c
|
||||
index 5d9175e..5c4d641 100644
|
||||
--- a/modules/proxy/mod_proxy_ftp.c
|
||||
+++ b/modules/proxy/mod_proxy_ftp.c
|
||||
@@ -979,8 +979,10 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
|
||||
apr_status_t rv;
|
||||
conn_rec *origin, *data = NULL;
|
||||
apr_status_t err = APR_SUCCESS;
|
||||
+#if APR_HAS_THREADS
|
||||
apr_status_t uerr = APR_SUCCESS;
|
||||
- apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
|
||||
+#endif
|
||||
+ apr_bucket_brigade *bb;
|
||||
char *buf, *connectname;
|
||||
apr_port_t connectport;
|
||||
char *ftpmessage = NULL;
|
||||
@@ -1120,13 +1122,15 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
|
||||
|
||||
if (worker->s->is_address_reusable) {
|
||||
if (!worker->cp->addr) {
|
||||
+#if APR_HAS_THREADS
|
||||
if ((err = PROXY_THREAD_LOCK(worker->balancer)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, err, r, APLOGNO(01037) "lock");
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
- connect_addr = worker->cp->addr;
|
||||
- address_pool = worker->cp->pool;
|
||||
+ connect_addr = AP_VOLATILIZE_T(apr_sockaddr_t *, worker->cp->addr);
|
||||
+ address_pool = worker->cp->dns_pool;
|
||||
}
|
||||
else
|
||||
address_pool = r->pool;
|
||||
@@ -1139,9 +1143,11 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
|
||||
address_pool);
|
||||
if (worker->s->is_address_reusable && !worker->cp->addr) {
|
||||
worker->cp->addr = connect_addr;
|
||||
+#if APR_HAS_THREADS
|
||||
if ((uerr = PROXY_THREAD_UNLOCK(worker->balancer)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, uerr, r, APLOGNO(01038) "unlock");
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
/*
|
||||
* get all the possible IP addresses for the destname and loop through
|
||||
@@ -1212,6 +1218,7 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
|
||||
* correct directory...
|
||||
*/
|
||||
|
||||
+ bb = apr_brigade_create(p, c->bucket_alloc);
|
||||
|
||||
/* possible results: */
|
||||
/* 120 Service ready in nnn minutes. */
|
||||
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
|
||||
index 2bfc8f0..7714b6c 100644
|
||||
--- a/modules/proxy/proxy_util.c
|
||||
+++ b/modules/proxy/proxy_util.c
|
||||
@@ -1167,8 +1167,10 @@ PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p,
|
||||
lbmethod = ap_lookup_provider(PROXY_LBMETHOD, "byrequests", "0");
|
||||
|
||||
(*balancer)->workers = apr_array_make(p, 5, sizeof(proxy_worker *));
|
||||
+#if APR_HAS_THREADS
|
||||
(*balancer)->gmutex = NULL;
|
||||
(*balancer)->tmutex = NULL;
|
||||
+#endif
|
||||
(*balancer)->lbmethod = lbmethod;
|
||||
|
||||
if (do_malloc)
|
||||
@@ -1257,7 +1259,9 @@ PROXY_DECLARE(apr_status_t) ap_proxy_share_balancer(proxy_balancer *balancer,
|
||||
|
||||
PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balancer, server_rec *s, apr_pool_t *p)
|
||||
{
|
||||
+#if APR_HAS_THREADS
|
||||
apr_status_t rv = APR_SUCCESS;
|
||||
+#endif
|
||||
ap_slotmem_provider_t *storage = balancer->storage;
|
||||
apr_size_t size;
|
||||
unsigned int num;
|
||||
@@ -1297,6 +1301,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balance
|
||||
if (balancer->lbmethod && balancer->lbmethod->reset)
|
||||
balancer->lbmethod->reset(balancer, s);
|
||||
|
||||
+#if APR_HAS_THREADS
|
||||
if (balancer->tmutex == NULL) {
|
||||
rv = apr_thread_mutex_create(&(balancer->tmutex), APR_THREAD_MUTEX_DEFAULT, p);
|
||||
if (rv != APR_SUCCESS) {
|
||||
@@ -1305,6 +1310,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balance
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1446,16 +1452,14 @@ static void socket_cleanup(proxy_conn_rec *conn)
|
||||
|
||||
static apr_status_t conn_pool_cleanup(void *theworker)
|
||||
{
|
||||
- proxy_worker *worker = (proxy_worker *)theworker;
|
||||
- if (worker->cp->res) {
|
||||
- worker->cp->pool = NULL;
|
||||
- }
|
||||
+ ((proxy_worker *)theworker)->cp = NULL;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
||||
static void init_conn_pool(apr_pool_t *p, proxy_worker *worker)
|
||||
{
|
||||
apr_pool_t *pool;
|
||||
+ apr_pool_t *dns_pool;
|
||||
proxy_conn_pool *cp;
|
||||
|
||||
/*
|
||||
@@ -1466,12 +1470,21 @@ static void init_conn_pool(apr_pool_t *p, proxy_worker *worker)
|
||||
*/
|
||||
apr_pool_create(&pool, p);
|
||||
apr_pool_tag(pool, "proxy_worker_cp");
|
||||
+ /*
|
||||
+ * Create a subpool of the connection pool for worker
|
||||
+ * scoped DNS resolutions. This is needed to avoid race
|
||||
+ * conditions in using the connection pool by multiple
|
||||
+ * threads during ramp up.
|
||||
+ */
|
||||
+ apr_pool_create(&dns_pool, pool);
|
||||
+ apr_pool_tag(dns_pool, "proxy_worker_dns");
|
||||
/*
|
||||
* Alloc from the same pool as worker.
|
||||
* proxy_conn_pool is permanently attached to the worker.
|
||||
*/
|
||||
cp = (proxy_conn_pool *)apr_pcalloc(p, sizeof(proxy_conn_pool));
|
||||
cp->pool = pool;
|
||||
+ cp->dns_pool = dns_pool;
|
||||
worker->cp = cp;
|
||||
}
|
||||
|
||||
@@ -1487,14 +1500,6 @@ static apr_status_t connection_cleanup(void *theconn)
|
||||
proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
|
||||
proxy_worker *worker = conn->worker;
|
||||
|
||||
- /*
|
||||
- * If the connection pool is NULL the worker
|
||||
- * cleanup has been run. Just return.
|
||||
- */
|
||||
- if (!worker->cp->pool) {
|
||||
- return APR_SUCCESS;
|
||||
- }
|
||||
-
|
||||
if (conn->r) {
|
||||
apr_pool_destroy(conn->r->pool);
|
||||
conn->r = NULL;
|
||||
@@ -1616,7 +1621,7 @@ static apr_status_t connection_destructor(void *resource, void *params,
|
||||
proxy_worker *worker = params;
|
||||
|
||||
/* Destroy the pool only if not called from reslist_destroy */
|
||||
- if (worker->cp->pool) {
|
||||
+ if (worker->cp) {
|
||||
proxy_conn_rec *conn = resource;
|
||||
apr_pool_destroy(conn->pool);
|
||||
}
|
||||
@@ -1972,67 +1977,73 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, ser
|
||||
ap_proxy_worker_name(p, worker));
|
||||
}
|
||||
else {
|
||||
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00927)
|
||||
- "initializing worker %s local",
|
||||
- ap_proxy_worker_name(p, worker));
|
||||
apr_global_mutex_lock(proxy_mutex);
|
||||
- /* Now init local worker data */
|
||||
- if (worker->tmutex == NULL) {
|
||||
- rv = apr_thread_mutex_create(&(worker->tmutex), APR_THREAD_MUTEX_DEFAULT, p);
|
||||
- if (rv != APR_SUCCESS) {
|
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00928)
|
||||
- "can not create worker thread mutex");
|
||||
+ /* Check again after we got the lock if we are still uninitialized */
|
||||
+ if (!(AP_VOLATILIZE_T(unsigned int, worker->local_status) & PROXY_WORKER_INITIALIZED)) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00927)
|
||||
+ "initializing worker %s local",
|
||||
+ ap_proxy_worker_name(p, worker));
|
||||
+ /* Now init local worker data */
|
||||
+#if APR_HAS_THREADS
|
||||
+ if (worker->tmutex == NULL) {
|
||||
+ rv = apr_thread_mutex_create(&(worker->tmutex), APR_THREAD_MUTEX_DEFAULT, p);
|
||||
+ if (rv != APR_SUCCESS) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00928)
|
||||
+ "can not create worker thread mutex");
|
||||
+ apr_global_mutex_unlock(proxy_mutex);
|
||||
+ return rv;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+ if (worker->cp == NULL)
|
||||
+ init_conn_pool(p, worker);
|
||||
+ if (worker->cp == NULL) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00929)
|
||||
+ "can not create connection pool");
|
||||
apr_global_mutex_unlock(proxy_mutex);
|
||||
- return rv;
|
||||
+ return APR_EGENERAL;
|
||||
}
|
||||
- }
|
||||
- if (worker->cp == NULL)
|
||||
- init_conn_pool(p, worker);
|
||||
- if (worker->cp == NULL) {
|
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00929)
|
||||
- "can not create connection pool");
|
||||
- apr_global_mutex_unlock(proxy_mutex);
|
||||
- return APR_EGENERAL;
|
||||
- }
|
||||
|
||||
- if (worker->s->hmax) {
|
||||
- rv = apr_reslist_create(&(worker->cp->res),
|
||||
- worker->s->min, worker->s->smax,
|
||||
- worker->s->hmax, worker->s->ttl,
|
||||
- connection_constructor, connection_destructor,
|
||||
- worker, worker->cp->pool);
|
||||
+ if (worker->s->hmax) {
|
||||
+ rv = apr_reslist_create(&(worker->cp->res),
|
||||
+ worker->s->min, worker->s->smax,
|
||||
+ worker->s->hmax, worker->s->ttl,
|
||||
+ connection_constructor, connection_destructor,
|
||||
+ worker, worker->cp->pool);
|
||||
|
||||
- apr_pool_cleanup_register(worker->cp->pool, (void *)worker,
|
||||
- conn_pool_cleanup,
|
||||
- apr_pool_cleanup_null);
|
||||
+ apr_pool_pre_cleanup_register(worker->cp->pool, worker,
|
||||
+ conn_pool_cleanup);
|
||||
|
||||
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00930)
|
||||
- "initialized pool in child %" APR_PID_T_FMT " for (%s) min=%d max=%d smax=%d",
|
||||
- getpid(), worker->s->hostname_ex, worker->s->min,
|
||||
- worker->s->hmax, worker->s->smax);
|
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00930)
|
||||
+ "initialized pool in child %" APR_PID_T_FMT " for (%s) min=%d max=%d smax=%d",
|
||||
+ getpid(), worker->s->hostname_ex, worker->s->min,
|
||||
+ worker->s->hmax, worker->s->smax);
|
||||
|
||||
- /* Set the acquire timeout */
|
||||
- if (rv == APR_SUCCESS && worker->s->acquire_set) {
|
||||
- apr_reslist_timeout_set(worker->cp->res, worker->s->acquire);
|
||||
- }
|
||||
+ /* Set the acquire timeout */
|
||||
+ if (rv == APR_SUCCESS && worker->s->acquire_set) {
|
||||
+ apr_reslist_timeout_set(worker->cp->res, worker->s->acquire);
|
||||
+ }
|
||||
|
||||
- }
|
||||
- else {
|
||||
- void *conn;
|
||||
+ }
|
||||
+ else {
|
||||
+ void *conn;
|
||||
|
||||
- rv = connection_constructor(&conn, worker, worker->cp->pool);
|
||||
- worker->cp->conn = conn;
|
||||
+ rv = connection_constructor(&conn, worker, worker->cp->pool);
|
||||
+ worker->cp->conn = conn;
|
||||
|
||||
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00931)
|
||||
- "initialized single connection worker in child %" APR_PID_T_FMT " for (%s)",
|
||||
- getpid(), worker->s->hostname_ex);
|
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(00931)
|
||||
+ "initialized single connection worker in child %" APR_PID_T_FMT " for (%s)",
|
||||
+ getpid(), worker->s->hostname_ex);
|
||||
+ }
|
||||
+ if (rv == APR_SUCCESS) {
|
||||
+ worker->local_status |= (PROXY_WORKER_INITIALIZED);
|
||||
+ }
|
||||
}
|
||||
apr_global_mutex_unlock(proxy_mutex);
|
||||
|
||||
}
|
||||
if (rv == APR_SUCCESS) {
|
||||
worker->s->status |= (PROXY_WORKER_INITIALIZED);
|
||||
- worker->local_status |= (PROXY_WORKER_INITIALIZED);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@@ -2292,13 +2303,13 @@ PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
|
||||
else {
|
||||
/* create the new connection if the previous was destroyed */
|
||||
if (!worker->cp->conn) {
|
||||
- connection_constructor((void **)conn, worker, worker->cp->pool);
|
||||
+ rv = connection_constructor((void **)conn, worker, worker->cp->pool);
|
||||
}
|
||||
else {
|
||||
*conn = worker->cp->conn;
|
||||
worker->cp->conn = NULL;
|
||||
+ rv = APR_SUCCESS;
|
||||
}
|
||||
- rv = APR_SUCCESS;
|
||||
}
|
||||
|
||||
if (rv != APR_SUCCESS) {
|
||||
@@ -2344,7 +2355,9 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
|
||||
{
|
||||
int server_port;
|
||||
apr_status_t err = APR_SUCCESS;
|
||||
+#if APR_HAS_THREADS
|
||||
apr_status_t uerr = APR_SUCCESS;
|
||||
+#endif
|
||||
const char *uds_path;
|
||||
|
||||
/*
|
||||
@@ -2481,25 +2494,39 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
|
||||
* we can reuse the address.
|
||||
*/
|
||||
if (!worker->cp->addr) {
|
||||
+#if APR_HAS_THREADS
|
||||
if ((err = PROXY_THREAD_LOCK(worker)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, err, r, APLOGNO(00945) "lock");
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/*
|
||||
- * Worker can have the single constant backend address.
|
||||
- * The single DNS lookup is used once per worker.
|
||||
- * If dynamic change is needed then set the addr to NULL
|
||||
- * inside dynamic config to force the lookup.
|
||||
+ * Recheck addr after we got the lock. This may have changed
|
||||
+ * while waiting for the lock.
|
||||
*/
|
||||
- err = apr_sockaddr_info_get(&(worker->cp->addr),
|
||||
- conn->hostname, APR_UNSPEC,
|
||||
- conn->port, 0,
|
||||
- worker->cp->pool);
|
||||
+ if (!AP_VOLATILIZE_T(apr_sockaddr_t *, worker->cp->addr)) {
|
||||
+
|
||||
+ apr_sockaddr_t *addr;
|
||||
+
|
||||
+ /*
|
||||
+ * Worker can have the single constant backend address.
|
||||
+ * The single DNS lookup is used once per worker.
|
||||
+ * If dynamic change is needed then set the addr to NULL
|
||||
+ * inside dynamic config to force the lookup.
|
||||
+ */
|
||||
+ err = apr_sockaddr_info_get(&addr,
|
||||
+ conn->hostname, APR_UNSPEC,
|
||||
+ conn->port, 0,
|
||||
+ worker->cp->dns_pool);
|
||||
+ worker->cp->addr = addr;
|
||||
+ }
|
||||
conn->addr = worker->cp->addr;
|
||||
+#if APR_HAS_THREADS
|
||||
if ((uerr = PROXY_THREAD_UNLOCK(worker)) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, uerr, r, APLOGNO(00946) "unlock");
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
else {
|
||||
conn->addr = worker->cp->addr;
|
||||
@@ -3422,7 +3449,9 @@ PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b, server_rec
|
||||
(*runtime)->cp = NULL;
|
||||
(*runtime)->balancer = b;
|
||||
(*runtime)->s = shm;
|
||||
+#if APR_HAS_THREADS
|
||||
(*runtime)->tmutex = NULL;
|
||||
+#endif
|
||||
rv = ap_proxy_initialize_worker(*runtime, s, conf->pool);
|
||||
if (rv != APR_SUCCESS) {
|
||||
ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(00966) "Cannot init worker");
|
265
httpd-2.4.37-r1873907.patch
Normal file
265
httpd-2.4.37-r1873907.patch
Normal file
@ -0,0 +1,265 @@
|
||||
diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en
|
||||
index b543150..ab72d4f 100644
|
||||
--- a/docs/manual/mod/mod_ssl.html.en
|
||||
+++ b/docs/manual/mod/mod_ssl.html.en
|
||||
@@ -1524,6 +1524,32 @@ The available (case-insensitive) <em>protocol</em>s are:</p>
|
||||
<div class="example"><h3>Example</h3><pre class="prettyprint lang-config">SSLProtocol TLSv1</pre>
|
||||
</div>
|
||||
|
||||
+<div class="note">
|
||||
+<h3><code class="directive">SSLProtocol</code> for name-based virtual hosts</h3>
|
||||
+<p>
|
||||
+Before OpenSSL 1.1.1, even though the Server Name Indication (SNI) allowed to
|
||||
+determine the targeted virtual host early in the TLS handshake, it was not
|
||||
+possible to switch the TLS protocol version of the connection at this point,
|
||||
+and thus the <code class="directive">SSLProtocol</code> negotiated was always based off
|
||||
+the one of the <em>base virtual host</em> (first virtual host declared on the
|
||||
+listening <code>IP:port</code> of the connection).
|
||||
+</p>
|
||||
+<p>
|
||||
+Beginning with Apache HTTP server version 2.4.42, when built/linked against
|
||||
+OpenSSL 1.1.1 or later, and when the SNI is provided by the client in the TLS
|
||||
+handshake, the <code class="directive">SSLProtocol</code> of each (name-based) virtual
|
||||
+host can and will be honored.
|
||||
+</p>
|
||||
+<p>
|
||||
+For compatibility with previous versions, if no
|
||||
+<code class="directive">SSLProtocol</code> is configured in a name-based virtual host,
|
||||
+the one from the base virtual host still applies, <strong>unless</strong>
|
||||
+<code class="directive">SSLProtocol</code> is configured globally in which case the
|
||||
+global value applies (this latter exception is more sensible than compatible,
|
||||
+though).
|
||||
+</p>
|
||||
+</div>
|
||||
+
|
||||
</div>
|
||||
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
<div class="directive-section"><h2><a name="SSLProxyCACertificateFile" id="SSLProxyCACertificateFile">SSLProxyCACertificateFile</a> <a name="sslproxycacertificatefile" id="sslproxycacertificatefile">Directive</a></h2>
|
||||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
|
||||
index 0c4bf1f..ca5f702 100644
|
||||
--- a/modules/ssl/ssl_engine_config.c
|
||||
+++ b/modules/ssl/ssl_engine_config.c
|
||||
@@ -269,6 +269,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p,
|
||||
mrg->protocol_set = 1;
|
||||
}
|
||||
else {
|
||||
+ mrg->protocol_set = base->protocol_set;
|
||||
mrg->protocol = base->protocol;
|
||||
}
|
||||
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index 31062bc..70d151e 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -520,7 +520,9 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s,
|
||||
"Configuring TLS extension handling");
|
||||
|
||||
/*
|
||||
- * Server name indication (SNI)
|
||||
+ * The Server Name Indication (SNI) provided by the ClientHello can be
|
||||
+ * used to select the right (name-based-)vhost and its SSL configuration
|
||||
+ * before the handshake takes place.
|
||||
*/
|
||||
if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
|
||||
ssl_callback_ServerNameIndication) ||
|
||||
@@ -532,6 +534,16 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s,
|
||||
return ssl_die(s);
|
||||
}
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
+ /*
|
||||
+ * The ClientHello callback also allows to retrieve the SNI, but since it
|
||||
+ * runs at the earliest possible connection stage we can even set the TLS
|
||||
+ * protocol version(s) according to the selected (name-based-)vhost, which
|
||||
+ * is not possible at the SNI callback stage (due to OpenSSL internals).
|
||||
+ */
|
||||
+ SSL_CTX_set_client_hello_cb(mctx->ssl_ctx, ssl_callback_ClientHello, NULL);
|
||||
+#endif
|
||||
+
|
||||
#ifdef HAVE_OCSP_STAPLING
|
||||
/*
|
||||
* OCSP Stapling support, status_request extension
|
||||
@@ -708,7 +720,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
#else /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
|
||||
/* We first determine the maximum protocol version we should provide */
|
||||
#if SSL_HAVE_PROTOCOL_TLSV1_3
|
||||
- if (SSL_HAVE_PROTOCOL_TLSV1_3 && (protocol & SSL_PROTOCOL_TLSV1_3)) {
|
||||
+ if (protocol & SSL_PROTOCOL_TLSV1_3) {
|
||||
prot = TLS1_3_VERSION;
|
||||
} else
|
||||
#endif
|
||||
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
|
||||
index 8b44674..7313a55 100644
|
||||
--- a/modules/ssl/ssl_engine_kernel.c
|
||||
+++ b/modules/ssl/ssl_engine_kernel.c
|
||||
@@ -2357,28 +2357,31 @@ static apr_status_t set_challenge_creds(conn_rec *c, const char *servername,
|
||||
* This function sets the virtual host from an extended
|
||||
* client hello with a server name indication extension ("SNI", cf. RFC 6066).
|
||||
*/
|
||||
-static apr_status_t init_vhost(conn_rec *c, SSL *ssl)
|
||||
+static apr_status_t init_vhost(conn_rec *c, SSL *ssl, const char *servername)
|
||||
{
|
||||
- const char *servername;
|
||||
X509 *cert;
|
||||
EVP_PKEY *key;
|
||||
|
||||
if (c) {
|
||||
SSLConnRec *sslcon = myConnConfig(c);
|
||||
-
|
||||
- if (sslcon->server != c->base_server) {
|
||||
- /* already found the vhost */
|
||||
- return APR_SUCCESS;
|
||||
+
|
||||
+ if (sslcon->vhost_found) {
|
||||
+ /* already found the vhost? */
|
||||
+ return sslcon->vhost_found > 0 ? APR_SUCCESS : APR_NOTFOUND;
|
||||
}
|
||||
+ sslcon->vhost_found = -1;
|
||||
|
||||
- servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
|
||||
+ if (!servername) {
|
||||
+ servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
|
||||
+ }
|
||||
if (servername) {
|
||||
if (ap_vhost_iterate_given_conn(c, ssl_find_vhost,
|
||||
(void *)servername)) {
|
||||
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02043)
|
||||
"SSL virtual host for servername %s found",
|
||||
servername);
|
||||
-
|
||||
+
|
||||
+ sslcon->vhost_found = +1;
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
else if (ssl_is_challenge(c, servername, &cert, &key)) {
|
||||
@@ -2428,11 +2431,72 @@ static apr_status_t init_vhost(conn_rec *c, SSL *ssl)
|
||||
int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx)
|
||||
{
|
||||
conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
|
||||
- apr_status_t status = init_vhost(c, ssl);
|
||||
+ apr_status_t status = init_vhost(c, ssl, NULL);
|
||||
|
||||
return (status == APR_SUCCESS)? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
+/*
|
||||
+ * This callback function is called when the ClientHello is received.
|
||||
+ */
|
||||
+int ssl_callback_ClientHello(SSL *ssl, int *al, void *arg)
|
||||
+{
|
||||
+ char *servername = NULL;
|
||||
+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
|
||||
+ const unsigned char *pos;
|
||||
+ size_t len, remaining;
|
||||
+ (void)arg;
|
||||
+
|
||||
+ /* We can't use SSL_get_servername() at this earliest OpenSSL connection
|
||||
+ * stage, and there is no SSL_client_hello_get0_servername() provided as
|
||||
+ * of OpenSSL 1.1.1. So the code below, that extracts the SNI from the
|
||||
+ * ClientHello's TLS extensions, is taken from some test code in OpenSSL,
|
||||
+ * i.e. client_hello_select_server_ctx() in "test/handshake_helper.c".
|
||||
+ */
|
||||
+
|
||||
+ /*
|
||||
+ * The server_name extension was given too much extensibility when it
|
||||
+ * was written, so parsing the normal case is a bit complex.
|
||||
+ */
|
||||
+ if (!SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &pos,
|
||||
+ &remaining)
|
||||
+ || remaining <= 2)
|
||||
+ goto give_up;
|
||||
+
|
||||
+ /* Extract the length of the supplied list of names. */
|
||||
+ len = (*(pos++) << 8);
|
||||
+ len += *(pos++);
|
||||
+ if (len + 2 != remaining)
|
||||
+ goto give_up;
|
||||
+ remaining = len;
|
||||
+
|
||||
+ /*
|
||||
+ * The list in practice only has a single element, so we only consider
|
||||
+ * the first one.
|
||||
+ */
|
||||
+ if (remaining <= 3 || *pos++ != TLSEXT_NAMETYPE_host_name)
|
||||
+ goto give_up;
|
||||
+ remaining--;
|
||||
+
|
||||
+ /* Now we can finally pull out the byte array with the actual hostname. */
|
||||
+ len = (*(pos++) << 8);
|
||||
+ len += *(pos++);
|
||||
+ if (len + 2 != remaining)
|
||||
+ goto give_up;
|
||||
+
|
||||
+ /* Use the SNI to switch to the relevant vhost, should it differ from
|
||||
+ * c->base_server.
|
||||
+ */
|
||||
+ servername = apr_pstrmemdup(c->pool, (const char *)pos, len);
|
||||
+
|
||||
+give_up:
|
||||
+ init_vhost(c, ssl, servername);
|
||||
+ return SSL_CLIENT_HELLO_SUCCESS;
|
||||
+}
|
||||
+#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
|
||||
+
|
||||
+
|
||||
/*
|
||||
* Find a (name-based) SSL virtual host where either the ServerName
|
||||
* or one of the ServerAliases matches the supplied name (to be used
|
||||
@@ -2452,12 +2516,25 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
|
||||
if (found && (ssl = sslcon->ssl) &&
|
||||
(sc = mySrvConfig(s))) {
|
||||
SSL_CTX *ctx = SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx);
|
||||
+
|
||||
/*
|
||||
* SSL_set_SSL_CTX() only deals with the server cert,
|
||||
* so we need to duplicate a few additional settings
|
||||
* from the ctx by hand
|
||||
*/
|
||||
SSL_set_options(ssl, SSL_CTX_get_options(ctx));
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L \
|
||||
+ && (!defined(LIBRESSL_VERSION_NUMBER) \
|
||||
+ || LIBRESSL_VERSION_NUMBER >= 0x20800000L)
|
||||
+ /*
|
||||
+ * Don't switch the protocol if none is configured for this vhost,
|
||||
+ * the default in this case is still the base server's SSLProtocol.
|
||||
+ */
|
||||
+ if (myCtxConfig(sslcon, sc)->protocol_set) {
|
||||
+ SSL_set_min_proto_version(ssl, SSL_CTX_get_min_proto_version(ctx));
|
||||
+ SSL_set_max_proto_version(ssl, SSL_CTX_get_max_proto_version(ctx));
|
||||
+ }
|
||||
+#endif
|
||||
if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) ||
|
||||
(SSL_num_renegotiations(ssl) == 0)) {
|
||||
/*
|
||||
@@ -2654,7 +2731,7 @@ int ssl_callback_alpn_select(SSL *ssl,
|
||||
* they callback the SNI. We need to make sure that we know which vhost
|
||||
* we are dealing with so we respect the correct protocols.
|
||||
*/
|
||||
- init_vhost(c, ssl);
|
||||
+ init_vhost(c, ssl, NULL);
|
||||
|
||||
proposed = ap_select_protocol(c, NULL, sslconn->server, client_protos);
|
||||
if (!proposed) {
|
||||
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
|
||||
index 8055200..f8a1db7 100644
|
||||
--- a/modules/ssl/ssl_private.h
|
||||
+++ b/modules/ssl/ssl_private.h
|
||||
@@ -563,6 +563,7 @@ typedef struct {
|
||||
|
||||
const char *cipher_suite; /* cipher suite used in last reneg */
|
||||
int service_unavailable; /* thouugh we negotiate SSL, no requests will be served */
|
||||
+ int vhost_found; /* whether we found vhost from SNI already */
|
||||
} SSLConnRec;
|
||||
|
||||
/* BIG FAT WARNING: SSLModConfigRec has unusual memory lifetime: it is
|
||||
@@ -946,6 +947,9 @@ void ssl_callback_Info(const SSL *, int, int);
|
||||
#ifdef HAVE_TLSEXT
|
||||
int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
|
||||
#endif
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
+int ssl_callback_ClientHello(SSL *, int *, void *);
|
||||
+#endif
|
||||
#ifdef HAVE_TLS_SESSION_TICKETS
|
||||
int ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *,
|
||||
EVP_CIPHER_CTX *, HMAC_CTX *, int);
|
249
httpd-2.4.37-r1877397.patch
Normal file
249
httpd-2.4.37-r1877397.patch
Normal file
@ -0,0 +1,249 @@
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index b286053..8b6c34f 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -824,6 +824,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;
|
||||
}
|
||||
@@ -845,6 +852,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,
|
||||
@@ -854,7 +869,13 @@ static void ssl_init_ctx_callbacks(server_rec *s,
|
||||
|
||||
SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
|
||||
|
||||
- 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 836bfdb..0958135 100644
|
||||
--- a/modules/ssl/ssl_engine_io.c
|
||||
+++ b/modules/ssl/ssl_engine_io.c
|
||||
@@ -200,11 +200,13 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl)
|
||||
apr_bucket *e;
|
||||
int need_flush;
|
||||
|
||||
+#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
|
||||
|
||||
/* when handshaking we'll have a small number of bytes.
|
||||
* max size SSL will pass us here is about 16k.
|
||||
@@ -458,11 +460,13 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen)
|
||||
if (!in)
|
||||
return 0;
|
||||
|
||||
+#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
|
||||
|
||||
BIO_clear_retry_flags(bio);
|
||||
|
||||
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
|
||||
index e217b9d..21f701f 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);
|
||||
|
||||
/*
|
||||
@@ -2271,8 +2268,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)
|
||||
{
|
||||
@@ -2284,14 +2281,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;
|
||||
|
||||
@@ -2316,6 +2311,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 2514407..f4e5ac9 100644
|
||||
--- a/modules/ssl/ssl_private.h
|
||||
+++ b/modules/ssl/ssl_private.h
|
||||
@@ -508,6 +508,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)
|
||||
@@ -540,18 +550,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;
|
||||
@@ -1130,6 +1135,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 4fa089b..3413d83 100644
|
||||
--- a/modules/ssl/ssl_util_ssl.c
|
||||
+++ b/modules/ssl/ssl_util_ssl.c
|
||||
@@ -504,3 +504,19 @@ char *modssl_SSL_SESSION_id2sz(IDCONST unsigned char *id, int idlen,
|
||||
|
||||
return str;
|
||||
}
|
||||
+
|
||||
+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
|
||||
+}
|
47
httpd-2.4.37-r1878280.patch
Normal file
47
httpd-2.4.37-r1878280.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From ced24e032ebe185a2d885fa309d6de47668ba31e Mon Sep 17 00:00:00 2001
|
||||
From: Yann Ylavic <ylavic@apache.org>
|
||||
Date: Fri, 26 Jun 2020 10:21:19 +0000
|
||||
Subject: [PATCH] Merge r1878280 from trunk:
|
||||
|
||||
mod_proxy_http: don't strip EOS when spooling request body to file.
|
||||
|
||||
To prevent stream_reqbody() from sending the FILE and FLUSH bucket in separate
|
||||
brigades, and thus apr_file_setaside() to trigger if network congestion occurs
|
||||
with the backend, restore the EOS in spool_reqbody_cl() which was stripped
|
||||
when spooling the request body to a file.
|
||||
|
||||
Until APR r1878279 is released (and installed by users), apr_file_setaside()
|
||||
on a temporary file (mktemp) will simply drop the file cleanup, leaking the
|
||||
fd and inode..
|
||||
|
||||
This fixes BZ 64452.
|
||||
|
||||
|
||||
Submitted by: ylavic
|
||||
Reviewed by: ylavic, jorton, rpluem
|
||||
|
||||
|
||||
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1879226 13f79535-47bb-0310-9956-ffa450edef68
|
||||
---
|
||||
modules/proxy/mod_proxy_http.c | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
|
||||
index e94bf26d412..7a0f063f705 100644
|
||||
--- a/modules/proxy/mod_proxy_http.c
|
||||
+++ b/modules/proxy/mod_proxy_http.c
|
||||
@@ -548,6 +548,14 @@ static int spool_reqbody_cl(proxy_http_req_t *req, apr_off_t *bytes_spooled)
|
||||
e = apr_bucket_immortal_create(CRLF_ASCII, 2, bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(input_brigade, e);
|
||||
}
|
||||
+ if (tmpfile) {
|
||||
+ /* We dropped metadata buckets when spooling to tmpfile,
|
||||
+ * terminate with EOS for stream_reqbody() to flush the
|
||||
+ * whole in one go.
|
||||
+ */
|
||||
+ e = apr_bucket_eos_create(bucket_alloc);
|
||||
+ APR_BRIGADE_INSERT_TAIL(input_brigade, e);
|
||||
+ }
|
||||
return OK;
|
||||
}
|
||||
|
116
httpd-2.4.37-r1878890.patch
Normal file
116
httpd-2.4.37-r1878890.patch
Normal file
@ -0,0 +1,116 @@
|
||||
diff --git a/include/util_ldap.h b/include/util_ldap.h
|
||||
index f7cd736..f401e79 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 08f986c..eecb3f7 100644
|
||||
--- a/modules/ldap/util_ldap.c
|
||||
+++ b/modules/ldap/util_ldap.c
|
||||
@@ -140,6 +140,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 <apr_ldap_rebind.h>
|
||||
+
|
||||
+#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
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
@@ -181,6 +213,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);
|
||||
@@ -189,12 +228,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;
|
||||
@@ -330,7 +363,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?");
|
||||
@@ -855,6 +888,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)
|
||||
@@ -865,6 +899,7 @@ static util_ldap_connection_t *
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
if (p) {
|
||||
p->next = l;
|
||||
@@ -3051,7 +3086,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) {
|
13
httpd-2.4.37-r1879224.patch
Normal file
13
httpd-2.4.37-r1879224.patch
Normal file
@ -0,0 +1,13 @@
|
||||
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
|
||||
index c217a0d..d07d0ba 100644
|
||||
--- a/modules/ssl/ssl_engine_kernel.c
|
||||
+++ b/modules/ssl/ssl_engine_kernel.c
|
||||
@@ -1947,7 +1947,7 @@ static void modssl_proxy_info_log(conn_rec *c,
|
||||
*cert = info->x509; \
|
||||
CRYPTO_add(&(*cert)->references, +1, CRYPTO_LOCK_X509); \
|
||||
*pkey = info->x_pkey->dec_pkey; \
|
||||
- CRYPTO_add(&(*pkey)->references, +1, CRYPTO_LOCK_X509_PKEY)
|
||||
+ CRYPTO_add(&(*pkey)->references, +1, CRYPTO_LOCK_EVP_PKEY)
|
||||
#else
|
||||
#define modssl_set_cert_info(info, cert, pkey) \
|
||||
*cert = info->x509; \
|
16
httpd-2.4.37-r1881459.patch
Normal file
16
httpd-2.4.37-r1881459.patch
Normal file
@ -0,0 +1,16 @@
|
||||
--- a/modules/generators/cgi_common.h 2020/09/04 13:16:53 1881458
|
||||
+++ b/modules/generators/cgi_common.h 2020/09/04 13:56:25 1881459
|
||||
@@ -259,6 +259,13 @@
|
||||
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);
|
||||
|
||||
/*
|
188
httpd-2.4.37-reply-two-tls-rec.patch
Normal file
188
httpd-2.4.37-reply-two-tls-rec.patch
Normal file
@ -0,0 +1,188 @@
|
||||
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
|
||||
index 018b667..4e3875a 100644
|
||||
--- a/modules/ssl/ssl_engine_io.c
|
||||
+++ b/modules/ssl/ssl_engine_io.c
|
||||
@@ -1598,18 +1598,32 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
|
||||
}
|
||||
|
||||
|
||||
-/* ssl_io_filter_output() produces one SSL/TLS message per bucket
|
||||
+/* ssl_io_filter_output() produces one SSL/TLS record per bucket
|
||||
* passed down the output filter stack. This results in a high
|
||||
- * overhead (network packets) for any output comprising many small
|
||||
- * buckets. SSI page applied through the HTTP chunk filter, for
|
||||
- * example, may produce many brigades containing small buckets -
|
||||
- * [chunk-size CRLF] [chunk-data] [CRLF].
|
||||
+ * overhead (more network packets & TLS processing) for any output
|
||||
+ * comprising many small buckets. SSI output passed through the HTTP
|
||||
+ * chunk filter, for example, may produce many brigades containing
|
||||
+ * small buckets - [chunk-size CRLF] [chunk-data] [CRLF].
|
||||
*
|
||||
- * The coalescing filter merges many small buckets into larger buckets
|
||||
- * where possible, allowing the SSL I/O output filter to handle them
|
||||
- * more efficiently. */
|
||||
+ * Sending HTTP response headers as a separate TLS record to the
|
||||
+ * response body also reveals information to a network observer (the
|
||||
+ * size of headers) which can be significant.
|
||||
+ *
|
||||
+ * The coalescing filter merges data buckets with the aim of producing
|
||||
+ * fewer, larger TLS records - without copying/buffering all content
|
||||
+ * and introducing unnecessary overhead.
|
||||
+ *
|
||||
+ * ### This buffering could be probably be done more comprehensively
|
||||
+ * ### in ssl_io_filter_output itself.
|
||||
+ *
|
||||
+ * ### Another possible performance optimisation in particular for the
|
||||
+ * ### [HEAP] [FILE] HTTP response case is using a brigade rather than
|
||||
+ * ### a char array to buffer; using apr_brigade_write() to append
|
||||
+ * ### will use already-allocated memory from the HEAP, reducing # of
|
||||
+ * ### copies.
|
||||
+ */
|
||||
|
||||
-#define COALESCE_BYTES (2048)
|
||||
+#define COALESCE_BYTES (AP_IOBUFSIZE)
|
||||
|
||||
struct coalesce_ctx {
|
||||
char buffer[COALESCE_BYTES];
|
||||
@@ -1622,11 +1636,12 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f,
|
||||
apr_bucket *e, *upto;
|
||||
apr_size_t bytes = 0;
|
||||
struct coalesce_ctx *ctx = f->ctx;
|
||||
+ apr_size_t buffered = ctx ? ctx->bytes : 0; /* space used on entry */
|
||||
unsigned count = 0;
|
||||
|
||||
/* The brigade consists of zero-or-more small data buckets which
|
||||
- * can be coalesced (the prefix), followed by the remainder of the
|
||||
- * brigade.
|
||||
+ * can be coalesced (referred to as the "prefix"), followed by the
|
||||
+ * remainder of the brigade.
|
||||
*
|
||||
* Find the last bucket - if any - of that prefix. count gives
|
||||
* the number of buckets in the prefix. The "prefix" must contain
|
||||
@@ -1641,24 +1656,97 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f,
|
||||
e != APR_BRIGADE_SENTINEL(bb)
|
||||
&& !APR_BUCKET_IS_METADATA(e)
|
||||
&& e->length != (apr_size_t)-1
|
||||
- && e->length < COALESCE_BYTES
|
||||
- && (bytes + e->length) < COALESCE_BYTES
|
||||
- && (ctx == NULL
|
||||
- || bytes + ctx->bytes + e->length < COALESCE_BYTES);
|
||||
+ && e->length <= COALESCE_BYTES
|
||||
+ && (buffered + bytes + e->length) <= COALESCE_BYTES;
|
||||
e = APR_BUCKET_NEXT(e)) {
|
||||
if (e->length) count++; /* don't count zero-length buckets */
|
||||
bytes += e->length;
|
||||
}
|
||||
+
|
||||
+ /* If there is room remaining and the next bucket is a data
|
||||
+ * bucket, try to include it in the prefix to coalesce. For a
|
||||
+ * typical [HEAP] [FILE] HTTP response brigade, this handles
|
||||
+ * merging the headers and the start of the body into a single TLS
|
||||
+ * record. */
|
||||
+ if (bytes + buffered > 0
|
||||
+ && bytes + buffered < COALESCE_BYTES
|
||||
+ && e != APR_BRIGADE_SENTINEL(bb)
|
||||
+ && !APR_BUCKET_IS_METADATA(e)) {
|
||||
+ apr_status_t rv = APR_SUCCESS;
|
||||
+
|
||||
+ /* For an indeterminate length bucket (PIPE/CGI/...), try a
|
||||
+ * non-blocking read to have it morph into a HEAP. If the
|
||||
+ * read fails with EAGAIN, it is harmless to try a split
|
||||
+ * anyway, split is ENOTIMPL for most PIPE-like buckets. */
|
||||
+ if (e->length == (apr_size_t)-1) {
|
||||
+ const char *discard;
|
||||
+ apr_size_t ignore;
|
||||
+
|
||||
+ rv = apr_bucket_read(e, &discard, &ignore, APR_NONBLOCK_READ);
|
||||
+ if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
|
||||
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(10232)
|
||||
+ "coalesce failed to read from %s bucket",
|
||||
+ e->type->name);
|
||||
+ return AP_FILTER_ERROR;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (rv == APR_SUCCESS) {
|
||||
+ /* If the read above made the bucket morph, it may now fit
|
||||
+ * entirely within the buffer. Otherwise, split it so it does
|
||||
+ * fit. */
|
||||
+ if (e->length > COALESCE_BYTES
|
||||
+ || e->length + buffered + bytes > COALESCE_BYTES) {
|
||||
+ rv = apr_bucket_split(e, COALESCE_BYTES - (buffered + bytes));
|
||||
+ }
|
||||
+
|
||||
+ if (rv == APR_SUCCESS && e->length == 0) {
|
||||
+ /* As above, don't count in the prefix if the bucket is
|
||||
+ * now zero-length. */
|
||||
+ }
|
||||
+ else if (rv == APR_SUCCESS) {
|
||||
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
|
||||
+ "coalesce: adding %" APR_SIZE_T_FMT " bytes "
|
||||
+ "from split %s bucket, total %" APR_SIZE_T_FMT,
|
||||
+ e->length, e->type->name, bytes + buffered);
|
||||
+
|
||||
+ count++;
|
||||
+ bytes += e->length;
|
||||
+ e = APR_BUCKET_NEXT(e);
|
||||
+ }
|
||||
+ else if (rv != APR_ENOTIMPL) {
|
||||
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(10233)
|
||||
+ "coalesce: failed to split data bucket");
|
||||
+ return AP_FILTER_ERROR;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* The prefix is zero or more buckets. upto now points to the
|
||||
+ * bucket AFTER the end of the prefix, which may be the brigade
|
||||
+ * sentinel. */
|
||||
upto = e;
|
||||
|
||||
- /* Coalesce the prefix, if:
|
||||
- * a) more than one bucket is found to coalesce, or
|
||||
- * b) the brigade contains only a single data bucket, or
|
||||
- * c) the data bucket is not last but we have buffered data already.
|
||||
+ /* Coalesce the prefix, if any of the following are true:
|
||||
+ *
|
||||
+ * a) the prefix is more than one bucket
|
||||
+ * OR
|
||||
+ * b) the prefix is the entire brigade, which is a single bucket
|
||||
+ * AND the prefix length is smaller than the buffer size,
|
||||
+ * OR
|
||||
+ * c) the prefix is a single bucket
|
||||
+ * AND there is buffered data from a previous pass.
|
||||
+ *
|
||||
+ * The aim with (b) is to buffer a small bucket so it can be
|
||||
+ * coalesced with future invocations of this filter. e.g. three
|
||||
+ * calls each with a single 100 byte HEAP bucket should get
|
||||
+ * coalesced together. But an invocation with a 8192 byte HEAP
|
||||
+ * should pass through untouched.
|
||||
*/
|
||||
if (bytes > 0
|
||||
&& (count > 1
|
||||
- || (upto == APR_BRIGADE_SENTINEL(bb))
|
||||
+ || (upto == APR_BRIGADE_SENTINEL(bb)
|
||||
+ && bytes < COALESCE_BYTES)
|
||||
|| (ctx && ctx->bytes > 0))) {
|
||||
/* If coalescing some bytes, ensure a context has been
|
||||
* created. */
|
||||
@@ -1669,7 +1757,8 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f,
|
||||
|
||||
ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
|
||||
"coalesce: have %" APR_SIZE_T_FMT " bytes, "
|
||||
- "adding %" APR_SIZE_T_FMT " more", ctx->bytes, bytes);
|
||||
+ "adding %" APR_SIZE_T_FMT " more (buckets=%u)",
|
||||
+ ctx->bytes, bytes, count);
|
||||
|
||||
/* Iterate through the prefix segment. For non-fatal errors
|
||||
* in this loop it is safe to break out and fall back to the
|
||||
@@ -1684,7 +1773,8 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f,
|
||||
if (APR_BUCKET_IS_METADATA(e)
|
||||
|| e->length == (apr_size_t)-1) {
|
||||
ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(02012)
|
||||
- "unexpected bucket type during coalesce");
|
||||
+ "unexpected %s bucket during coalesce",
|
||||
+ e->type->name);
|
||||
break; /* non-fatal error; break out */
|
||||
}
|
||||
|
194
httpd-2.4.37-session-expiry-updt-int.patch
Normal file
194
httpd-2.4.37-session-expiry-updt-int.patch
Normal file
@ -0,0 +1,194 @@
|
||||
diff --git a/docs/manual/mod/mod_session.html.en b/docs/manual/mod/mod_session.html.en
|
||||
index 6834f8e..9f8301f 100644
|
||||
--- a/docs/manual/mod/mod_session.html.en
|
||||
+++ b/docs/manual/mod/mod_session.html.en
|
||||
@@ -82,6 +82,7 @@
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#sessionheader">SessionHeader</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#sessioninclude">SessionInclude</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#sessionmaxage">SessionMaxAge</a></li>
|
||||
+<li><img alt="" src="../images/down.gif" /> <a href="#sessionexpiryupdateinterval">SessionExpiryUpdateInterval</a></li>
|
||||
</ul>
|
||||
<h3>Bugfix checklist</h3><ul class="seealso"><li><a href="https://www.apache.org/dist/httpd/CHANGES_2.4">httpd changelog</a></li><li><a href="https://bz.apache.org/bugzilla/buglist.cgi?bug_status=__open__&list_id=144532&product=Apache%20httpd-2&query_format=specific&order=changeddate%20DESC%2Cpriority%2Cbug_severity&component=mod_session">Known issues</a></li><li><a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2&component=mod_session">Report a bug</a></li></ul><h3>See also</h3>
|
||||
<ul class="seealso">
|
||||
@@ -482,6 +483,37 @@ AuthName realm
|
||||
|
||||
<p>Setting the maxage to zero disables session expiry.</p>
|
||||
|
||||
+</div>
|
||||
+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
+<div class="directive-section"><h2><a name="SessionExpiryUpdateInterval" id="sessionexpiryupdateinterval">SessionExpiryUpdateInterval</a> <a name="sessionexpiryupdateinterval" id="sessionexpiryupdateinterval">Directive</a></h2>
|
||||
+<table class="directive">
|
||||
+<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Define the number of seconds a session's expiry may change without the session being updated</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>SessionExpiryUpdateInterval <var>interval</var></code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>SessionExpiryUpdateInterval 0 (always update)</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_session</td></tr>
|
||||
+</table>
|
||||
+ <p>The <code class="directive">SessionExpiryUpdateInterval</code> directive allows
|
||||
+ sessions to avoid the cost associated with writing the session each request
|
||||
+ when only the expiry time has changed. This can be used to make a website
|
||||
+ more efficient or reduce load on a database when using
|
||||
+ <module>mod_session_dbd</module>. The session is always written if the data
|
||||
+ stored in the session has changed or the expiry has changed by more than the
|
||||
+ configured interval.</p>
|
||||
+
|
||||
+ <p>Setting the interval to zero disables this directive, and the session
|
||||
+ expiry is refreshed for each request.</p>
|
||||
+
|
||||
+ <p>This directive only has an effect when combined with <code class="directive"><a href="../mod/mod_session.html#sessionmaxage">SessionMaxAge</a></code> to enable session
|
||||
+ expiry. Sessions without an expiry are only written when the data stored in
|
||||
+ the session has changed.</p>
|
||||
+
|
||||
+ <div class="warning"><h3>Warning</h3>
|
||||
+ <p>Because the session expiry may not be refreshed with each request, it's
|
||||
+ possible for sessions to expire up to <var>interval</var> seconds early.
|
||||
+ Using a small interval usually provides sufficient savings while having a
|
||||
+ minimal effect on expiry resolution.</p></div>
|
||||
+
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottomlang">
|
||||
diff --git a/modules/session/mod_session.c b/modules/session/mod_session.c
|
||||
index d517020..10e6396 100644
|
||||
--- a/modules/session/mod_session.c
|
||||
+++ b/modules/session/mod_session.c
|
||||
@@ -177,6 +177,7 @@ static apr_status_t ap_session_save(request_rec * r, session_rec * z)
|
||||
{
|
||||
if (z) {
|
||||
apr_time_t now = apr_time_now();
|
||||
+ apr_time_t initialExpiry = z->expiry;
|
||||
int rv = 0;
|
||||
|
||||
session_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
|
||||
@@ -207,6 +208,17 @@ static apr_status_t ap_session_save(request_rec * r, session_rec * z)
|
||||
z->expiry = now + z->maxage * APR_USEC_PER_SEC;
|
||||
}
|
||||
|
||||
+ /* don't save if the only change is the expiry by a small amount */
|
||||
+ if (!z->dirty && dconf->expiry_update_time
|
||||
+ && (z->expiry - initialExpiry < dconf->expiry_update_time)) {
|
||||
+ return APR_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ /* also don't save sessions that didn't change at all */
|
||||
+ if (!z->dirty && !z->maxage) {
|
||||
+ return APR_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
/* encode the session */
|
||||
rv = ap_run_session_encode(r, z);
|
||||
if (OK != rv) {
|
||||
@@ -553,6 +565,10 @@ static void *merge_session_dir_config(apr_pool_t * p, void *basev, void *addv)
|
||||
new->env_set = add->env_set || base->env_set;
|
||||
new->includes = apr_array_append(p, base->includes, add->includes);
|
||||
new->excludes = apr_array_append(p, base->excludes, add->excludes);
|
||||
+ new->expiry_update_time = (add->expiry_update_set == 0)
|
||||
+ ? base->expiry_update_time
|
||||
+ : add->expiry_update_time;
|
||||
+ new->expiry_update_set = add->expiry_update_set || base->expiry_update_set;
|
||||
|
||||
return new;
|
||||
}
|
||||
@@ -622,6 +638,21 @@ static const char *add_session_exclude(cmd_parms * cmd, void *dconf, const char
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static const char *
|
||||
+ set_session_expiry_update(cmd_parms * parms, void *dconf, const char *arg)
|
||||
+{
|
||||
+ session_dir_conf *conf = dconf;
|
||||
+
|
||||
+ conf->expiry_update_time = atoi(arg);
|
||||
+ if (conf->expiry_update_time < 0) {
|
||||
+ return "SessionExpiryUpdateInterval must be positive or nul";
|
||||
+ }
|
||||
+ conf->expiry_update_time = apr_time_from_sec(conf->expiry_update_time);
|
||||
+ conf->expiry_update_set = 1;
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
|
||||
static const command_rec session_cmds[] =
|
||||
{
|
||||
@@ -637,6 +668,9 @@ static const command_rec session_cmds[] =
|
||||
"URL prefixes to include in the session. Defaults to all URLs"),
|
||||
AP_INIT_TAKE1("SessionExclude", add_session_exclude, NULL, RSRC_CONF|OR_AUTHCFG,
|
||||
"URL prefixes to exclude from the session. Defaults to no URLs"),
|
||||
+ AP_INIT_TAKE1("SessionExpiryUpdateInterval", set_session_expiry_update, NULL, RSRC_CONF|OR_AUTHCFG,
|
||||
+ "time interval for which a session's expiry time may change "
|
||||
+ "without having to be rewritten. Zero to disable"),
|
||||
{NULL}
|
||||
};
|
||||
|
||||
diff --git a/modules/session/mod_session.h b/modules/session/mod_session.h
|
||||
index a6dd5e9..bdeb532 100644
|
||||
--- a/modules/session/mod_session.h
|
||||
+++ b/modules/session/mod_session.h
|
||||
@@ -115,6 +115,9 @@ typedef struct {
|
||||
* URLs included if empty */
|
||||
apr_array_header_t *excludes; /* URL prefixes to be excluded. No
|
||||
* URLs excluded if empty */
|
||||
+ apr_time_t expiry_update_time; /* seconds the session expiry may change and
|
||||
+ * not have to be rewritten */
|
||||
+ int expiry_update_set;
|
||||
} session_dir_conf;
|
||||
|
||||
/**
|
||||
diff --git a/modules/session/mod_session_cookie.c b/modules/session/mod_session_cookie.c
|
||||
index 6a02322..4aa75e4 100644
|
||||
--- a/modules/session/mod_session_cookie.c
|
||||
+++ b/modules/session/mod_session_cookie.c
|
||||
@@ -60,9 +60,6 @@ static apr_status_t session_cookie_save(request_rec * r, session_rec * z)
|
||||
session_cookie_dir_conf *conf = ap_get_module_config(r->per_dir_config,
|
||||
&session_cookie_module);
|
||||
|
||||
- /* don't cache auth protected pages */
|
||||
- apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
|
||||
-
|
||||
/* create RFC2109 compliant cookie */
|
||||
if (conf->name_set) {
|
||||
if (z->encoded && z->encoded[0]) {
|
||||
@@ -162,6 +159,9 @@ static apr_status_t session_cookie_load(request_rec * r, session_rec ** z)
|
||||
/* put the session in the notes so we don't have to parse it again */
|
||||
apr_table_setn(m->notes, note, (char *)zz);
|
||||
|
||||
+ /* don't cache auth protected pages */
|
||||
+ apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");
|
||||
+
|
||||
return OK;
|
||||
|
||||
}
|
||||
diff --git a/modules/session/mod_session_dbd.c b/modules/session/mod_session_dbd.c
|
||||
index 0be7306..f683da2 100644
|
||||
--- a/modules/session/mod_session_dbd.c
|
||||
+++ b/modules/session/mod_session_dbd.c
|
||||
@@ -245,6 +245,9 @@ static apr_status_t session_dbd_load(request_rec * r, session_rec ** z)
|
||||
/* put the session in the notes so we don't have to parse it again */
|
||||
apr_table_setn(m->notes, note, (char *)zz);
|
||||
|
||||
+ /* don't cache pages with a session */
|
||||
+ apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");
|
||||
+
|
||||
return OK;
|
||||
|
||||
}
|
||||
@@ -409,9 +412,6 @@ static apr_status_t session_dbd_save(request_rec * r, session_rec * z)
|
||||
if (conf->name_set || conf->name2_set) {
|
||||
char *oldkey = NULL, *newkey = NULL;
|
||||
|
||||
- /* don't cache pages with a session */
|
||||
- apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
|
||||
-
|
||||
/* if the session is new or changed, make a new session ID */
|
||||
if (z->uuid) {
|
||||
oldkey = apr_pcalloc(r->pool, APR_UUID_FORMATTED_LENGTH + 1);
|
||||
@@ -458,7 +458,7 @@ static apr_status_t session_dbd_save(request_rec * r, session_rec * z)
|
||||
else if (conf->peruser) {
|
||||
|
||||
/* don't cache pages with a session */
|
||||
- apr_table_addn(r->headers_out, "Cache-Control", "no-cache");
|
||||
+ apr_table_addn(r->headers_out, "Cache-Control", "no-cache, private");
|
||||
|
||||
if (r->user) {
|
||||
ret = dbd_save(r, r->user, r->user, z->encoded, z->expiry);
|
101
httpd-2.4.37-ssl-proxy-chains.patch
Normal file
101
httpd-2.4.37-ssl-proxy-chains.patch
Normal file
@ -0,0 +1,101 @@
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index 8b6c34f..3587fb5 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -1609,6 +1609,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
|
||||
@@ -1653,20 +1657,28 @@ 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;
|
||||
- }
|
||||
-
|
||||
/* 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;
|
||||
+
|
||||
+ /* 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 (!inf->x509 || !inf->x_pkey || !inf->x_pkey->dec_pkey ||
|
||||
- inf->enc_data) {
|
||||
+ 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 "
|
||||
@@ -1683,13 +1695,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/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
|
||||
index 2a08d1c..8055200 100644
|
||||
--- a/modules/ssl/ssl_private.h
|
||||
+++ b/modules/ssl/ssl_private.h
|
||||
@@ -655,10 +655,13 @@ typedef struct {
|
||||
const char *cert_file;
|
||||
const char *cert_path;
|
||||
const char *ca_cert_file;
|
||||
- STACK_OF(X509_INFO) *certs; /* Contains End Entity certs */
|
||||
- STACK_OF(X509) **ca_certs; /* Contains ONLY chain certs for
|
||||
- * each item in certs.
|
||||
- * (ptr to array of ptrs) */
|
||||
+ /* certs is a stack of configured cert, key pairs. */
|
||||
+ STACK_OF(X509_INFO) *certs;
|
||||
+ /* ca_certs contains ONLY chain certs for each item in certs.
|
||||
+ * ca_certs[n] is a pointer to the (STACK_OF(X509) *) stack which
|
||||
+ * holds the cert chain for the 'n'th cert in the certs stack, or
|
||||
+ * NULL if no chain is configured. */
|
||||
+ STACK_OF(X509) **ca_certs;
|
||||
} modssl_pk_proxy_t;
|
||||
|
||||
/** stuff related to authentication that can also be per-dir */
|
123
httpd-2.4.37-sslkeylogfile-support.patch
Normal file
123
httpd-2.4.37-sslkeylogfile-support.patch
Normal file
@ -0,0 +1,123 @@
|
||||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
|
||||
index 1d201d9..0c4bf1f 100644
|
||||
--- a/modules/ssl/ssl_engine_config.c
|
||||
+++ b/modules/ssl/ssl_engine_config.c
|
||||
@@ -75,6 +75,10 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s)
|
||||
mc->stapling_refresh_mutex = NULL;
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_OPENSSL_KEYLOG
|
||||
+ mc->keylog_file = NULL;
|
||||
+#endif
|
||||
+
|
||||
apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY,
|
||||
apr_pool_cleanup_null,
|
||||
pool);
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index ef631c1..b286053 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -437,6 +437,28 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
|
||||
init_bio_methods();
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_OPENSSL_KEYLOG
|
||||
+ {
|
||||
+ const char *logfn = getenv("SSLKEYLOGFILE");
|
||||
+
|
||||
+ if (logfn) {
|
||||
+ rv = apr_file_open(&mc->keylog_file, logfn,
|
||||
+ APR_FOPEN_CREATE|APR_FOPEN_WRITE|APR_FOPEN_APPEND|APR_FOPEN_LARGEFILE,
|
||||
+ APR_FPROT_UREAD|APR_FPROT_UWRITE,
|
||||
+ mc->pPool);
|
||||
+ if (rv) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, s, APLOGNO(10226)
|
||||
+ "Could not open log file '%s' configured via SSLKEYLOGFILE",
|
||||
+ logfn);
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(10227)
|
||||
+ "Init: Logging SSL private key material to %s", logfn);
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -796,6 +818,12 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
* https://github.com/openssl/openssl/issues/7178 */
|
||||
SSL_CTX_clear_mode(ctx, SSL_MODE_AUTO_RETRY);
|
||||
#endif
|
||||
+
|
||||
+#ifdef HAVE_OPENSSL_KEYLOG
|
||||
+ if (mctx->sc->mc->keylog_file) {
|
||||
+ SSL_CTX_set_keylog_callback(ctx, modssl_callback_keylog);
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
|
||||
index 6611610..7058865 100644
|
||||
--- a/modules/ssl/ssl_engine_kernel.c
|
||||
+++ b/modules/ssl/ssl_engine_kernel.c
|
||||
@@ -2719,3 +2719,17 @@ int ssl_callback_SRPServerParams(SSL *ssl, int *ad, void *arg)
|
||||
}
|
||||
|
||||
#endif /* HAVE_SRP */
|
||||
+
|
||||
+
|
||||
+#ifdef HAVE_OPENSSL_KEYLOG
|
||||
+/* Callback used with SSL_CTX_set_keylog_callback. */
|
||||
+void modssl_callback_keylog(const SSL *ssl, const char *line)
|
||||
+{
|
||||
+ conn_rec *conn = SSL_get_app_data(ssl);
|
||||
+ SSLSrvConfigRec *sc = mySrvConfig(conn->base_server);
|
||||
+
|
||||
+ if (sc && sc->mc->keylog_file) {
|
||||
+ apr_file_printf(sc->mc->keylog_file, "%s\n", line);
|
||||
+ }
|
||||
+}
|
||||
+#endif
|
||||
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
|
||||
index 0fac5d1..2514407 100644
|
||||
--- a/modules/ssl/ssl_private.h
|
||||
+++ b/modules/ssl/ssl_private.h
|
||||
@@ -250,6 +250,10 @@ void free_bio_methods(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
|
||||
+#define HAVE_OPENSSL_KEYLOG
|
||||
+#endif
|
||||
+
|
||||
/* mod_ssl headers */
|
||||
#include "ssl_util_ssl.h"
|
||||
|
||||
@@ -617,6 +621,12 @@ typedef struct {
|
||||
apr_global_mutex_t *stapling_cache_mutex;
|
||||
apr_global_mutex_t *stapling_refresh_mutex;
|
||||
#endif
|
||||
+
|
||||
+#ifdef HAVE_OPENSSL_KEYLOG
|
||||
+ /* Used for logging if SSLKEYLOGFILE is set at startup. */
|
||||
+ apr_file_t *keylog_file;
|
||||
+#endif
|
||||
+
|
||||
} SSLModConfigRec;
|
||||
|
||||
/** Structure representing configured filenames for certs and keys for
|
||||
@@ -970,6 +980,11 @@ int ssl_stapling_init_cert(server_rec *, apr_pool_t *, apr_pool_t *,
|
||||
int ssl_callback_SRPServerParams(SSL *, int *, void *);
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_OPENSSL_KEYLOG
|
||||
+/* Callback used with SSL_CTX_set_keylog_callback. */
|
||||
+void modssl_callback_keylog(const SSL *ssl, const char *line);
|
||||
+#endif
|
||||
+
|
||||
/** I/O */
|
||||
void ssl_io_filter_init(conn_rec *, request_rec *r, SSL *);
|
||||
void ssl_io_filter_register(apr_pool_t *);
|
98
httpd-2.4.37-sslprotdefault.patch
Normal file
98
httpd-2.4.37-sslprotdefault.patch
Normal file
@ -0,0 +1,98 @@
|
||||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
|
||||
index 55c237e..5467d23 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;
|
||||
@@ -262,6 +262,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p,
|
||||
{
|
||||
if (add->protocol_set) {
|
||||
mrg->protocol = add->protocol;
|
||||
+ mrg->protocol_set = 1;
|
||||
}
|
||||
else {
|
||||
mrg->protocol = base->protocol;
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index e3f62fe..31fc0e6 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -568,6 +568,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
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;
|
||||
@@ -577,12 +578,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
|
||||
@@ -595,7 +602,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);
|
||||
@@ -696,13 +704,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 */
|
||||
@@ -726,7 +736,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
|
178
httpd-2.4.37-usertrack-samesite.patch
Normal file
178
httpd-2.4.37-usertrack-samesite.patch
Normal file
@ -0,0 +1,178 @@
|
||||
diff --git a/docs/manual/mod/mod_usertrack.html.en b/docs/manual/mod/mod_usertrack.html.en
|
||||
index b212747..d2da9b9 100644
|
||||
--- a/docs/manual/mod/mod_usertrack.html.en
|
||||
+++ b/docs/manual/mod/mod_usertrack.html.en
|
||||
@@ -47,7 +47,10 @@
|
||||
<ul id="toc">
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#cookiedomain">CookieDomain</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#cookieexpires">CookieExpires</a></li>
|
||||
+<li><img alt="" src="../images/down.gif" /> <a href="#cookiehttponly">CookieHTTPOnly</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#cookiename">CookieName</a></li>
|
||||
+<li><img alt="" src="../images/down.gif" /> <a href="#cookiesamesite">CookieSameSite</a></li>
|
||||
+<li><img alt="" src="../images/down.gif" /> <a href="#cookiesecure">CookieSecure</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#cookiestyle">CookieStyle</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#cookietracking">CookieTracking</a></li>
|
||||
</ul>
|
||||
@@ -127,6 +130,22 @@ CustomLog "logs/clickstream.log" usertrack</pre>
|
||||
<pre class="prettyprint lang-config">CookieExpires "3 weeks"</pre>
|
||||
|
||||
|
||||
+</div>
|
||||
+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
+<div class="directive-section"><h2><a name="CookieHTTPOnly" id="CookieHTTPOnly">CookieHTTPOnly</a> <a name="cookiehttponly" id="cookiehttponly">Directive</a></h2>
|
||||
+<table class="directive">
|
||||
+<tbody><tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Adds the 'HTTPOnly' attribute to the cookie</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>CookieHTTPOnly on|off</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>CookieHTTPOnly off</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Override">Override:</a></th><td>FileInfo</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_usertrack</td></tr>
|
||||
+</tbody></table>
|
||||
+ <p>When set to 'ON', the 'HTTPOnly' cookie attribute is added to this
|
||||
+ modules tracking cookie. This attribute instructs browsers to block javascript
|
||||
+ from reading the value of the cookie.</p>
|
||||
+
|
||||
</div>
|
||||
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
<div class="directive-section"><h2><a name="CookieName" id="CookieName">CookieName</a> <a name="cookiename" id="cookiename">Directive</a></h2>
|
||||
@@ -150,6 +169,45 @@ CustomLog "logs/clickstream.log" usertrack</pre>
|
||||
<pre class="prettyprint lang-config">CookieName clicktrack</pre>
|
||||
|
||||
|
||||
+</div>
|
||||
+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
+<div class="directive-section"><h2><a name="CookieSameSite" id="CookieSameSite">CookieSameSite</a> <a name="cookiesamesite" id="cookiesamesite">Directive</a></h2>
|
||||
+<table class="directive">
|
||||
+<tbody><tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Adds the 'SameSite' attribute to the cookie</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>CookieSameSite None|Lax|Strict</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>unset</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Override">Override:</a></th><td>FileInfo</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_usertrack</td></tr>
|
||||
+</tbody></table>
|
||||
+ <p>When set to 'None', 'Lax', or 'Strict', the 'SameSite' cookie attribute
|
||||
+ is added to this modules tracking cookie with the corresponding value.
|
||||
+ This attribute instructs browser on how to treat the cookie when it is
|
||||
+ requested in a cross-site context.</p>
|
||||
+
|
||||
+ <div class="note">
|
||||
+ <p>A value of 'None' sets 'SameSite=None', which is the most liberal setting. To
|
||||
+ omit this attribute, omit the directive entirely.</p>
|
||||
+ </div>
|
||||
+
|
||||
+
|
||||
+</div>
|
||||
+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
+<div class="directive-section"><h2><a name="CookieSecure" id="CookieSecure">CookieSecure</a> <a name="cookiesecure" id="cookiesecure">Directive</a></h2>
|
||||
+<table class="directive">
|
||||
+<tbody><tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Adds the 'Secure' attribute to the cookie</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>CookieSecure on|off</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>CookieSecure off</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Override">Override:</a></th><td>FileInfo</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_usertrack</td></tr>
|
||||
+</tbody></table>
|
||||
+ <p>When set to 'ON', the 'Secure' cookie attribute is added to this
|
||||
+ modules tracking cookie. This attribute instructs browsers to only
|
||||
+ transmit the cookie over HTTPS.</p>
|
||||
+
|
||||
</div>
|
||||
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
<div class="directive-section"><h2><a name="CookieStyle" id="CookieStyle">CookieStyle</a> <a name="cookiestyle" id="cookiestyle">Directive</a></h2>
|
||||
diff --git a/modules/metadata/mod_usertrack.c b/modules/metadata/mod_usertrack.c
|
||||
index 73a9f45..65759c2 100644
|
||||
--- a/modules/metadata/mod_usertrack.c
|
||||
+++ b/modules/metadata/mod_usertrack.c
|
||||
@@ -86,6 +86,9 @@ typedef struct {
|
||||
const char *cookie_domain;
|
||||
char *regexp_string; /* used to compile regexp; save for debugging */
|
||||
ap_regex_t *regexp; /* used to find usertrack cookie in cookie header */
|
||||
+ int is_secure;
|
||||
+ int is_httponly;
|
||||
+ const char *samesite;
|
||||
} cookie_dir_rec;
|
||||
|
||||
/* Make Cookie: Now we have to generate something that is going to be
|
||||
@@ -143,6 +146,21 @@ static void make_cookie(request_rec *r)
|
||||
: ""),
|
||||
NULL);
|
||||
}
|
||||
+ if (dcfg->samesite != NULL) {
|
||||
+ new_cookie = apr_pstrcat(r->pool, new_cookie, "; ",
|
||||
+ dcfg->samesite,
|
||||
+ NULL);
|
||||
+ }
|
||||
+ if (dcfg->is_secure) {
|
||||
+ new_cookie = apr_pstrcat(r->pool, new_cookie, "; Secure",
|
||||
+ NULL);
|
||||
+ }
|
||||
+ if (dcfg->is_httponly) {
|
||||
+ new_cookie = apr_pstrcat(r->pool, new_cookie, "; HttpOnly",
|
||||
+ NULL);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
|
||||
apr_table_addn(r->err_headers_out,
|
||||
(dcfg->style == CT_COOKIE2 ? "Set-Cookie2" : "Set-Cookie"),
|
||||
@@ -269,6 +287,7 @@ static void *make_cookie_dir(apr_pool_t *p, char *d)
|
||||
dcfg->cookie_domain = NULL;
|
||||
dcfg->style = CT_UNSET;
|
||||
dcfg->enabled = 0;
|
||||
+ /* calloc'ed to disabled: samesite, is_secure, is_httponly */
|
||||
|
||||
/* In case the user does not use the CookieName directive,
|
||||
* we need to compile the regexp for the default cookie name. */
|
||||
@@ -429,6 +448,31 @@ static const char *set_cookie_style(cmd_parms *cmd, void *mconfig,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * SameSite enabled disabled
|
||||
+ */
|
||||
+
|
||||
+static const char *set_samesite_value(cmd_parms *cmd, void *mconfig,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ cookie_dir_rec *dcfg;
|
||||
+
|
||||
+ dcfg = (cookie_dir_rec *) mconfig;
|
||||
+
|
||||
+ if (strcasecmp(name, "strict") == 0) {
|
||||
+ dcfg->samesite = "SameSite=Strict";
|
||||
+ } else if (strcasecmp(name, "lax") == 0) {
|
||||
+ dcfg->samesite = "SameSite=Lax";
|
||||
+ } else if (strcasecmp(name, "none") == 0) {
|
||||
+ dcfg->samesite = "SameSite=None";
|
||||
+ } else {
|
||||
+ return "CookieSameSite accepts 'Strict', 'Lax', or 'None'";
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static const command_rec cookie_log_cmds[] = {
|
||||
AP_INIT_TAKE1("CookieExpires", set_cookie_exp, NULL, OR_FILEINFO,
|
||||
"an expiry date code"),
|
||||
@@ -440,6 +484,17 @@ static const command_rec cookie_log_cmds[] = {
|
||||
"whether or not to enable cookies"),
|
||||
AP_INIT_TAKE1("CookieName", set_cookie_name, NULL, OR_FILEINFO,
|
||||
"name of the tracking cookie"),
|
||||
+ AP_INIT_FLAG("CookieTracking", set_cookie_enable, NULL, OR_FILEINFO,
|
||||
+ "whether or not to enable cookies"),
|
||||
+ AP_INIT_TAKE1("CookieSameSite", set_samesite_value, NULL, OR_FILEINFO,
|
||||
+ "SameSite setting"),
|
||||
+ AP_INIT_FLAG("CookieSecure", ap_set_flag_slot,
|
||||
+ (void *)APR_OFFSETOF(cookie_dir_rec, is_secure), OR_FILEINFO,
|
||||
+ "is cookie secure"),
|
||||
+ AP_INIT_FLAG("CookieHttpOnly", ap_set_flag_slot,
|
||||
+ (void *)APR_OFFSETOF(cookie_dir_rec, is_httponly),OR_FILEINFO,
|
||||
+ "is cookie http only"),
|
||||
+
|
||||
{NULL}
|
||||
};
|
||||
|
BIN
httpd-2.4.37.tar.bz2
Normal file
BIN
httpd-2.4.37.tar.bz2
Normal file
Binary file not shown.
12
httpd-init.service
Normal file
12
httpd-init.service
Normal file
@ -0,0 +1,12 @@
|
||||
[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
|
||||
|
||||
ExecStart=/usr/libexec/httpd-ssl-gencerts
|
39
httpd-ssl-gencerts
Executable file
39
httpd-ssl-gencerts
Executable file
@ -0,0 +1,39 @@
|
||||
#!/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 \
|
||||
--lifetime 365 \
|
||||
--hostname $FQDN \
|
||||
--email root@$FQDN
|
||||
|
3
httpd-ssl-pass-dialog
Executable file
3
httpd-ssl-pass-dialog
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
exec /bin/systemd-ask-password "Enter TLS private key passphrase for $1 ($2) : "
|
356
httpd.conf
Normal file
356
httpd.conf
Normal file
@ -0,0 +1,356 @@
|
||||
#
|
||||
# This is the main Apache HTTP server configuration file. It contains the
|
||||
# configuration directives that give the server its instructions.
|
||||
# See <URL:http://httpd.apache.org/docs/2.4/> for detailed information.
|
||||
# In particular, see
|
||||
# <URL:http://httpd.apache.org/docs/2.4/mod/directives.html>
|
||||
# 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 <VirtualHost>
|
||||
# directive.
|
||||
#
|
||||
# Change this to Listen on specific IP addresses as shown below to
|
||||
# prevent Apache from glomming onto all bound IP addresses.
|
||||
#
|
||||
#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
|
||||
# <VirtualHost> definition. These values also provide defaults for
|
||||
# any <VirtualHost> containers you may define later in the file.
|
||||
#
|
||||
# All of these directives may appear inside <VirtualHost> 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
|
||||
# <Directory> blocks below.
|
||||
#
|
||||
<Directory />
|
||||
AllowOverride none
|
||||
Require all denied
|
||||
</Directory>
|
||||
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
<Directory "/var/www">
|
||||
AllowOverride None
|
||||
# Allow open access:
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
# Further relax access to the default document root:
|
||||
<Directory "/var/www/html">
|
||||
#
|
||||
# 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
|
||||
</Directory>
|
||||
|
||||
#
|
||||
# DirectoryIndex: sets the file that Apache will serve if a directory
|
||||
# is requested.
|
||||
#
|
||||
<IfModule dir_module>
|
||||
DirectoryIndex index.html
|
||||
</IfModule>
|
||||
|
||||
#
|
||||
# The following lines prevent .htaccess and .htpasswd files from being
|
||||
# viewed by Web clients.
|
||||
#
|
||||
<Files ".ht*">
|
||||
Require all denied
|
||||
</Files>
|
||||
|
||||
#
|
||||
# ErrorLog: The location of the error log file.
|
||||
# If you do not specify an ErrorLog directive within a <VirtualHost>
|
||||
# container, error messages relating to that virtual host will be
|
||||
# logged here. If you *do* define an error logfile for a <VirtualHost>
|
||||
# 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
|
||||
|
||||
<IfModule log_config_module>
|
||||
#
|
||||
# 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
|
||||
|
||||
<IfModule logio_module>
|
||||
# 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
|
||||
</IfModule>
|
||||
|
||||
#
|
||||
# The location and format of the access logfile (Common Logfile Format).
|
||||
# If you do not define any access logfiles within a <VirtualHost>
|
||||
# container, they will be logged here. Contrariwise, if you *do*
|
||||
# define per-<VirtualHost> 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
|
||||
</IfModule>
|
||||
|
||||
<IfModule alias_module>
|
||||
#
|
||||
# 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 <Directory> 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/"
|
||||
|
||||
</IfModule>
|
||||
|
||||
#
|
||||
# "/var/www/cgi-bin" should be changed to whatever your ScriptAliased
|
||||
# CGI directory exists, if you have that configured.
|
||||
#
|
||||
<Directory "/var/www/cgi-bin">
|
||||
AllowOverride None
|
||||
Options None
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
<IfModule mime_module>
|
||||
#
|
||||
# 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
|
||||
</IfModule>
|
||||
|
||||
#
|
||||
# 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
|
||||
|
||||
<IfModule mime_magic_module>
|
||||
#
|
||||
# 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
|
||||
</IfModule>
|
||||
|
||||
#
|
||||
# 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
|
259
httpd.conf.xml
Normal file
259
httpd.conf.xml
Normal file
@ -0,0 +1,259 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
|
||||
]>
|
||||
<!--
|
||||
Copyright 2018 Red Hat, Inc.
|
||||
|
||||
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.
|
||||
-->
|
||||
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<title>httpd.conf</title>
|
||||
<productname>httpd</productname>
|
||||
<author><contrib>Author</contrib><surname>Orton</surname><firstname>Joe</firstname><email>jorton@redhat.com</email></author>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>httpd.conf</refentrytitle>
|
||||
<manvolnum>5</manvolnum>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>httpd.conf</refname>
|
||||
<refpurpose>Configuration files for httpd</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<para>
|
||||
<filename>/etc/httpd/conf/httpd.conf</filename>,
|
||||
<filename>/etc/httpd/conf.modules.d</filename>,
|
||||
<filename>/etc/httpd/conf.d</filename>
|
||||
</para>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para>The main configuration file for the <command>httpd</command> daemon is
|
||||
<filename>/etc/httpd/conf/httpd.conf</filename>. The syntax of
|
||||
this file is described at <ulink
|
||||
url="https://httpd.apache.org/docs/2.4/configuring.html"/>, and
|
||||
the full set of available directives is listed at <ulink
|
||||
url="https://httpd.apache.org/docs/2.4/mod/directives.html"/>.
|
||||
</para>
|
||||
|
||||
<refsect2>
|
||||
<title>Configuration structure</title>
|
||||
|
||||
<para>The main configuration file
|
||||
(<filename>httpd.conf</filename>) sets up various defaults and
|
||||
includes configuration files from two directories -
|
||||
<filename>/etc/httpd/conf.modules.d</filename> and
|
||||
<filename>/etc/httpd/conf.d</filename>. Packages containing
|
||||
loadable modules (like <option>mod_ssl.so</option>) place files
|
||||
in the <filename>conf.modules.d</filename> directory with the
|
||||
appropriate <option>LoadModule</option> directive so that module
|
||||
is loaded by default.</para>
|
||||
|
||||
<para>Some notable configured defaults are:.</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>DocumentRoot @DOCROOT@/html</option></term>
|
||||
<listitem><para>The default document root from which content
|
||||
is served.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>Listen 80</option></term>
|
||||
<listitem><para>The daemon lists on TCP port 80.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>ErrorLog "logs/error_log"</option></term>
|
||||
<listitem><para>Error messages are logged to
|
||||
<filename>@LOGDIR@/error_log</filename>.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>ScriptAlias /cgi-bin/ "@DOCROOT@/cgi-bin/"</option></term>
|
||||
<listitem><para>CGI scripts are served via the URL-path <option>/cgi-bin/</option>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>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.</para>
|
||||
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>MPM configuration</title>
|
||||
|
||||
<para>The configuration file at
|
||||
<filename>/etc/httpd/conf.modules.d/00-mpm.conf</filename> is
|
||||
used to select the multi-processing module (MPM), which governs
|
||||
how <command>httpd</command> divides work between processes
|
||||
and/or threads at run-time. Exactly one
|
||||
<option>LoadModule</option> directive must be uncommented in
|
||||
this file; by default the <option>@MPM@</option> MPM is enabled.
|
||||
For more information on MPMs, see <ulink
|
||||
url="https://httpd.apache.org/docs/2.4/mpm.html"/>.</para>
|
||||
|
||||
<para>If using the <emphasis>prefork</emphasis> 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: <command>semanage boolean -m --on
|
||||
httpd_graceful_shutdown</command></para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Module configuration files</title>
|
||||
|
||||
<para>Module configuration files are provided in the
|
||||
<filename>/etc/httpd/conf.modules.d/</filename> 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 provide with the <command>httpd</command> package are
|
||||
loaded by files with a <option>0x-</option> prefix to ensure
|
||||
these are loaded first. Only filenames with a
|
||||
<option>.conf</option> suffix in this directory will be
|
||||
processed.</para>
|
||||
|
||||
<para>Other provided configuration files are listed below.
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><filename>/etc/httpd/conf.modules.d/00-base.conf</filename></term>
|
||||
<listitem><para>The set of core modules included with
|
||||
<command>httpd</command> which are all loaded by
|
||||
default.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><filename>/etc/httpd/conf.modules.d/00-optional.conf</filename></term>
|
||||
<listitem><para>The set of non-core modules included with
|
||||
<command>httpd</command> which are <emphasis>not</emphasis>
|
||||
loaded by default.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry>
|
||||
<term><filename>/etc/httpd/conf.modules.d/00-systemd.conf</filename></term>
|
||||
<listitem><para>This file loads <option>mod_systemd</option>
|
||||
which is necessary for the correct operation of the
|
||||
<command>httpd.service</command> service, and should not be
|
||||
removed or disabled.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Other configuration files</title>
|
||||
|
||||
<para>Default module configuration files and site-specific
|
||||
configuration files are loaded from the
|
||||
<filename>/etc/httpd/conf.d/</filename> directory. Only files
|
||||
with a <option>.conf</option> suffix will be loaded. The
|
||||
following files are provided:
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><filename>/etc/httpd/conf.d/userdir.conf</filename></term>
|
||||
<listitem><para>This file gives an example configuration for
|
||||
<option>mod_userdir</option> to map URLs such as
|
||||
<option>http://localhost/~jim/</option> to
|
||||
<filename>/home/jim/public_html/</filename>. Userdir mapping
|
||||
is disabled by default.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><filename>/etc/httpd/conf.d/autoindex.conf</filename></term>
|
||||
<listitem><para>This file provides the default configuration
|
||||
for <option>mod_autoindex</option> which generates HTML
|
||||
directory listings when enabled. It also makes file icon
|
||||
image files available at the <option>/icons/</option>
|
||||
URL-path.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><filename>/etc/httpd/conf.d/welcome.conf</filename></term>
|
||||
<listitem><para>This file enables a "welcome page" at
|
||||
<option>http://localhost/</option> if no content is present
|
||||
in the default documentation root
|
||||
<filename>/var/www/html</filename>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><filename>/etc/httpd/conf.d/ssl.conf</filename> (present only if <option>mod_ssl</option> is installed)</term>
|
||||
<listitem><para>This file configures a TLS
|
||||
<option>VirtualHost</option> listening on port
|
||||
<option>443</option>. If the default configuration is used,
|
||||
the referenced test certificate and private key are
|
||||
generated the first time <command>httpd.service</command> is
|
||||
started; see
|
||||
<citerefentry><refentrytitle>httpd-init.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
for more information.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist></para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Instantiated services</title>
|
||||
|
||||
<para>As an alternative to (or in addition to) the
|
||||
<command>httpd.service</command> unit, the instantiated template
|
||||
service <command>httpd@.service</command> unit file can be used,
|
||||
which starts <command>httpd</command> using a different
|
||||
configuration file to the default. For example,
|
||||
<command>systemctl start httpd@foobar.service</command> will
|
||||
start httpd using the configuration file
|
||||
<filename>/etc/httpd/conf/foobar.conf</filename>. See <citerefentry><refentrytitle>httpd@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> for more information.</para>
|
||||
</refsect2>
|
||||
|
||||
</refsect1>
|
||||
<refsect1>
|
||||
<title>Files</title>
|
||||
|
||||
<para>
|
||||
<filename>/etc/httpd/conf/httpd.conf</filename>,
|
||||
<filename>/etc/httpd/conf.d</filename>,
|
||||
<filename>/etc/httpd/conf.modules.d</filename>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See also</title>
|
||||
|
||||
<para>
|
||||
<citerefentry><refentrytitle>httpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>httpd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<ulink url="https://httpd.apache.org/docs/2.4/configuring.html"/>,
|
||||
<ulink url="https://httpd.apache.org/docs/2.4/mod/directives.html"/>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
|
||||
<!-- LocalWords: systemd PidFile
|
||||
-->
|
9
httpd.logrotate
Normal file
9
httpd.logrotate
Normal file
@ -0,0 +1,9 @@
|
||||
/var/log/httpd/*log {
|
||||
missingok
|
||||
notifempty
|
||||
sharedscripts
|
||||
delaycompress
|
||||
postrotate
|
||||
/bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true
|
||||
endscript
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user