webbuilder_pel7x64builder0
6 years ago
144 changed files with 16545 additions and 0 deletions
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
# |
||||
# This file loads most of the modules included with the Apache HTTP |
||||
# Server itself. |
||||
# |
||||
|
||||
LoadModule access_compat_module modules/mod_access_compat.so |
||||
LoadModule actions_module modules/mod_actions.so |
||||
LoadModule alias_module modules/mod_alias.so |
||||
LoadModule allowmethods_module modules/mod_allowmethods.so |
||||
LoadModule auth_basic_module modules/mod_auth_basic.so |
||||
LoadModule auth_digest_module modules/mod_auth_digest.so |
||||
LoadModule authn_anon_module modules/mod_authn_anon.so |
||||
LoadModule authn_core_module modules/mod_authn_core.so |
||||
LoadModule authn_dbd_module modules/mod_authn_dbd.so |
||||
LoadModule authn_dbm_module modules/mod_authn_dbm.so |
||||
LoadModule authn_file_module modules/mod_authn_file.so |
||||
LoadModule authn_socache_module modules/mod_authn_socache.so |
||||
LoadModule authz_core_module modules/mod_authz_core.so |
||||
LoadModule authz_dbd_module modules/mod_authz_dbd.so |
||||
LoadModule authz_dbm_module modules/mod_authz_dbm.so |
||||
LoadModule authz_groupfile_module modules/mod_authz_groupfile.so |
||||
LoadModule authz_host_module modules/mod_authz_host.so |
||||
LoadModule authz_owner_module modules/mod_authz_owner.so |
||||
LoadModule authz_user_module modules/mod_authz_user.so |
||||
LoadModule autoindex_module modules/mod_autoindex.so |
||||
LoadModule cache_module modules/mod_cache.so |
||||
LoadModule cache_disk_module modules/mod_cache_disk.so |
||||
LoadModule 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 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 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 buffer_module modules/mod_buffer.so |
||||
#LoadModule watchdog_module modules/mod_watchdog.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 ratelimit_module modules/mod_ratelimit.so |
||||
#LoadModule reflector_module modules/mod_reflector.so |
||||
#LoadModule request_module modules/mod_request.so |
||||
#LoadModule sed_module modules/mod_sed.so |
||||
#LoadModule speling_module modules/mod_speling.so |
||||
|
@ -0,0 +1,3 @@
@@ -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 |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
LoadModule lua_module modules/mod_lua.so |
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
# Select the MPM module which should be used by uncommenting exactly |
||||
# one of the following LoadModule lines: |
||||
|
||||
# prefork MPM: Implements a non-threaded, pre-forking web server |
||||
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html |
||||
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 |
||||
|
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
# 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_scgi_module modules/mod_proxy_scgi.so |
||||
LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so |
@ -0,0 +1,3 @@
@@ -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 |
@ -0,0 +1 @@
@@ -0,0 +1 @@
|
||||
LoadModule ssl_module modules/mod_ssl.so |
@ -0,0 +1,2 @@
@@ -0,0 +1,2 @@
|
||||
# This file configures systemd module: |
||||
LoadModule systemd_module modules/mod_systemd.so |
@ -0,0 +1,14 @@
@@ -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> |
||||
|
@ -0,0 +1,3 @@
@@ -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 |
@ -0,0 +1,6 @@
@@ -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 |
@ -0,0 +1,94 @@
@@ -0,0 +1,94 @@
|
||||
|
||||
- fail gracefully if links is not installed on target system |
||||
- source sysconfig/httpd for custom env. vars etc. |
||||
- make httpd -t work even in SELinux |
||||
- pass $OPTIONS to all $HTTPD invocation |
||||
|
||||
Upstream-HEAD: vendor |
||||
Upstream-2.0: vendor |
||||
Upstream-Status: Vendor-specific changes for better initscript integration |
||||
|
||||
--- httpd-2.4.1/support/apachectl.in.apctl |
||||
+++ httpd-2.4.1/support/apachectl.in |
||||
@@ -44,19 +44,25 @@ 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" |
||||
+ |
||||
+# Source /etc/sysconfig/httpd for $HTTPD setting, etc. |
||||
+if [ -r /etc/sysconfig/httpd ]; then |
||||
+ . /etc/sysconfig/httpd |
||||
+fi |
||||
+ |
||||
# |
||||
# Set this variable to a command that increases the maximum |
||||
# number of file descriptors allowed per child process. This is |
||||
@@ -76,9 +82,27 @@ 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` $HTTPD $OPTIONS -t |
||||
+else |
||||
+ $HTTPD $OPTIONS -t |
||||
+fi |
||||
+ERROR=$? |
||||
+} |
||||
+ |
||||
case $ACMD in |
||||
start|stop|restart|graceful|graceful-stop) |
||||
- $HTTPD -k $ARGV |
||||
+ $HTTPD $OPTIONS -k $ARGV |
||||
ERROR=$? |
||||
;; |
||||
startssl|sslstart|start-SSL) |
||||
@@ -88,17 +112,18 @@ startssl|sslstart|start-SSL) |
||||
ERROR=2 |
||||
;; |
||||
configtest) |
||||
- $HTTPD -t |
||||
- ERROR=$? |
||||
+ testconfig |
||||
;; |
||||
status) |
||||
+ checklynx |
||||
$LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } ' |
||||
;; |
||||
fullstatus) |
||||
+ checklynx |
||||
$LYNX $STATUSURL |
||||
;; |
||||
*) |
||||
- $HTTPD "$@" |
||||
+ $HTTPD $OPTIONS "$@" |
||||
ERROR=$? |
||||
esac |
||||
|
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
|
||||
Bump up the core size limit if CoreDumpDirectory is |
||||
configured. |
||||
|
||||
Upstream-Status: Was discussed but there are competing desires; |
||||
there are portability oddities here too. |
||||
|
||||
--- httpd-2.4.1/server/core.c.corelimit |
||||
+++ httpd-2.4.1/server/core.c |
||||
@@ -4433,6 +4433,25 @@ static int core_post_config(apr_pool_t * |
||||
} |
||||
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; |
||||
} |
||||
|
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
|
||||
Link straight against .la files. |
||||
|
||||
Upstream-Status: vendor specific |
||||
|
||||
--- httpd-2.4.1/configure.in.deplibs |
||||
+++ httpd-2.4.1/configure.in |
||||
@@ -707,9 +707,9 @@ APACHE_HELP_STRING(--with-suexec-umask,u |
||||
|
||||
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) |
@ -0,0 +1,61 @@
@@ -0,0 +1,61 @@
|
||||
|
||||
Log the SELinux context at startup. |
||||
|
||||
Upstream-Status: unlikely to be any interest in this upstream |
||||
|
||||
--- httpd-2.4.1/configure.in.selinux |
||||
+++ httpd-2.4.1/configure.in |
||||
@@ -458,6 +458,11 @@ fopen64 |
||||
dnl confirm that a void pointer is large enough to store a long integer |
||||
APACHE_CHECK_VOID_PTR_LEN |
||||
|
||||
+AC_CHECK_LIB(selinux, is_selinux_enabled, [ |
||||
+ AC_DEFINE(HAVE_SELINUX, 1, [Defined if SELinux is supported]) |
||||
+ APR_ADDTO(AP_LIBS, [-lselinux]) |
||||
+]) |
||||
+ |
||||
AC_CACHE_CHECK([for gettid()], ac_cv_gettid, |
||||
[AC_TRY_RUN(#define _GNU_SOURCE |
||||
#include <unistd.h> |
||||
--- httpd-2.4.1/server/core.c.selinux |
||||
+++ httpd-2.4.1/server/core.c |
||||
@@ -58,6 +58,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) |
||||
@@ -4452,6 +4456,28 @@ static int core_post_config(apr_pool_t * |
||||
} |
||||
#endif |
||||
|
||||
+#ifdef HAVE_SELINUX |
||||
+ { |
||||
+ static int already_warned = 0; |
||||
+ int is_enabled = is_selinux_enabled() > 0; |
||||
+ |
||||
+ if (is_enabled && !already_warned) { |
||||
+ security_context_t con; |
||||
+ |
||||
+ if (getcon(&con) == 0) { |
||||
+ |
||||
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, |
||||
+ "SELinux policy enabled; " |
||||
+ "httpd running as context %s", con); |
||||
+ |
||||
+ already_warned = 1; |
||||
+ |
||||
+ freecon(con); |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+#endif |
||||
+ |
||||
return OK; |
||||
} |
||||
|
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
|
||||
- Fix config for /icons/ dir to allow symlink to poweredby.png. |
||||
- Avoid using coredump GIF for a directory called "core" |
||||
|
||||
Upstream-Status: vendor specific patch |
||||
|
||||
--- httpd-2.4.2/docs/conf/extra/httpd-autoindex.conf.in.icons |
||||
+++ httpd-2.4.2/docs/conf/extra/httpd-autoindex.conf.in |
||||
@@ -21,7 +21,7 @@ IndexOptions FancyIndexing HTMLTable Ver |
||||
Alias /icons/ "@exp_iconsdir@/" |
||||
|
||||
<Directory "@exp_iconsdir@"> |
||||
- Options Indexes MultiViews |
||||
+ Options Indexes MultiViews FollowSymlinks |
||||
AllowOverride None |
||||
Require all granted |
||||
</Directory> |
||||
@@ -53,7 +53,7 @@ AddIcon /icons/dvi.gif .dvi |
||||
AddIcon /icons/uuencoded.gif .uu |
||||
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl |
||||
AddIcon /icons/tex.gif .tex |
||||
-AddIcon /icons/bomb.gif core |
||||
+AddIcon /icons/bomb.gif core. |
||||
|
||||
AddIcon /icons/back.gif .. |
||||
AddIcon /icons/hand.right.gif README |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
|
||||
Upstream-Status: vendor specific patch |
||||
|
||||
diff --git a/support/apachectl.in b/support/apachectl.in |
||||
index c6ac3ea..2599386 100644 |
||||
--- a/support/apachectl.in |
||||
+++ b/support/apachectl.in |
||||
@@ -100,9 +100,24 @@ 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 $OPTIONS -k $ARGV |
||||
+start|stop|restart|status) |
||||
+ /usr/bin/systemctl $ACMD httpd.service |
||||
+ ERROR=$? |
||||
+ ;; |
||||
+graceful) |
||||
+ /usr/bin/systemctl reload httpd.service |
||||
+ ERROR=$? |
||||
+ ;; |
||||
+graceful-stop) |
||||
+ /usr/bin/systemctl stop httpd.service |
||||
ERROR=$? |
||||
;; |
||||
startssl|sslstart|start-SSL) |
||||
@@ -114,10 +129,6 @@ startssl|sslstart|start-SSL) |
||||
configtest) |
||||
testconfig |
||||
;; |
||||
-status) |
||||
- checklynx |
||||
- $LYNX $STATUSURL | awk ' /process$/ { print; exit } { print } ' |
||||
- ;; |
||||
fullstatus) |
||||
checklynx |
||||
$LYNX $STATUSURL |
@ -0,0 +1,56 @@
@@ -0,0 +1,56 @@
|
||||
--- httpd-2.4.3/support/apxs.in.apxs |
||||
+++ httpd-2.4.3/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 |
||||
APXS=apxs |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
|
||||
Add layout for Fedora. |
||||
|
||||
--- httpd-2.4.3/config.layout.layout |
||||
+++ httpd-2.4.3/config.layout |
||||
@@ -370,3 +370,28 @@ |
||||
logfiledir: ${localstatedir}/log/httpd |
||||
proxycachedir: ${localstatedir}/cache/httpd |
||||
</Layout> |
||||
+ |
||||
+# Fedora/RHEL layout |
||||
+<Layout Fedora> |
||||
+ prefix: /usr |
||||
+ exec_prefix: ${prefix} |
||||
+ bindir: ${prefix}/bin |
||||
+ sbindir: ${prefix}/sbin |
||||
+ libdir: ${prefix}/lib |
||||
+ libexecdir: ${prefix}/libexec |
||||
+ mandir: ${prefix}/man |
||||
+ sysconfdir: /etc/httpd/conf |
||||
+ datadir: ${prefix}/share/httpd |
||||
+ installbuilddir: ${libdir}/httpd/build |
||||
+ errordir: ${datadir}/error |
||||
+ iconsdir: ${datadir}/icons |
||||
+ htdocsdir: /var/www/html |
||||
+ manualdir: ${datadir}/manual |
||||
+ cgidir: /var/www/cgi-bin |
||||
+ includedir: ${prefix}/include/httpd |
||||
+ localstatedir: /var |
||||
+ runtimedir: /run/httpd |
||||
+ logfiledir: ${localstatedir}/log/httpd |
||||
+ proxycachedir: ${localstatedir}/cache/httpd/proxy |
||||
+ davlockdb: ${localstatedir}/lib/dav/lockdb |
||||
+</Layout> |
@ -0,0 +1,163 @@
@@ -0,0 +1,163 @@
|
||||
--- httpd-2.4.3/modules/arch/unix/config5.m4.systemd |
||||
+++ httpd-2.4.3/modules/arch/unix/config5.m4 |
||||
@@ -18,6 +18,19 @@ APACHE_MODULE(privileges, Per-virtualhos |
||||
fi |
||||
]) |
||||
|
||||
+ |
||||
+APACHE_MODULE(systemd, Systemd support, , , $unixd_mods_enabled, [ |
||||
+ AC_CHECK_LIB(systemd-daemon, sd_notify, SYSTEMD_LIBS="-lsystemd-daemon") |
||||
+ AC_CHECK_HEADERS(systemd/sd-daemon.h, [ap_HAVE_SD_DAEMON_H="yes"], [ap_HAVE_SD_DAEMON_H="no"]) |
||||
+ if test $ap_HAVE_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.3/modules/arch/unix/mod_systemd.c.systemd |
||||
+++ httpd-2.4.3/modules/arch/unix/mod_systemd.c |
||||
@@ -0,0 +1,138 @@ |
||||
+/* 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 <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" |
||||
+ |
||||
+#if APR_HAVE_UNISTD_H |
||||
+#include <unistd.h> |
||||
+#endif |
||||
+ |
||||
+#define KBYTE 1024 |
||||
+ |
||||
+static pid_t pid; /* PID of the main httpd instance */ |
||||
+static int server_limit, thread_limit, threads_per_child, max_servers; |
||||
+static time_t last_update_time; |
||||
+static unsigned long last_update_access; |
||||
+static unsigned long last_update_kbytes; |
||||
+ |
||||
+static int systemd_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type) |
||||
+{ |
||||
+ int rv; |
||||
+ last_update_time = time(0); |
||||
+ |
||||
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); |
||||
+ ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit); |
||||
+ ap_mpm_query(AP_MPMQ_MAX_THREADS, &threads_per_child); |
||||
+ /* work around buggy MPMs */ |
||||
+ if (threads_per_child == 0) |
||||
+ threads_per_child = 1; |
||||
+ ap_mpm_query(AP_MPMQ_MAX_DAEMONS, &max_servers); |
||||
+ |
||||
+ pid = getpid(); |
||||
+ |
||||
+ rv = sd_notifyf(0, "READY=1\n" |
||||
+ "STATUS=Processing requests...\n" |
||||
+ "MAINPID=%lu", |
||||
+ (unsigned long) pid); |
||||
+ if (rv < 0) { |
||||
+ ap_log_perror(APLOG_MARK, APLOG_ERR, 0, p, |
||||
+ "sd_notifyf returned an error %d", rv); |
||||
+ } |
||||
+ |
||||
+ return OK; |
||||
+} |
||||
+ |
||||
+static int systemd_monitor(apr_pool_t *p, server_rec *s) |
||||
+{ |
||||
+ int i, j, res, rv; |
||||
+ process_score *ps_record; |
||||
+ worker_score *ws_record; |
||||
+ unsigned long access = 0; |
||||
+ unsigned long bytes = 0; |
||||
+ unsigned long kbytes = 0; |
||||
+ char bps[5]; |
||||
+ time_t now = time(0); |
||||
+ time_t elapsed = now - last_update_time; |
||||
+ |
||||
+ for (i = 0; i < server_limit; ++i) { |
||||
+ ps_record = ap_get_scoreboard_process(i); |
||||
+ for (j = 0; j < thread_limit; ++j) { |
||||
+ ws_record = ap_get_scoreboard_worker_from_indexes(i, j); |
||||
+ if (ap_extended_status && !ps_record->quiescing && ps_record->pid) { |
||||
+ res = ws_record->status; |
||||
+ if (ws_record->access_count != 0 || |
||||
+ (res != SERVER_READY && res != SERVER_DEAD)) { |
||||
+ access += ws_record->access_count; |
||||
+ bytes += ws_record->bytes_served; |
||||
+ if (bytes >= KBYTE) { |
||||
+ kbytes += (bytes >> 10); |
||||
+ bytes = bytes & 0x3ff; |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ apr_strfsize((unsigned long)(KBYTE *(float) (kbytes - last_update_kbytes) |
||||
+ / (float) elapsed), bps); |
||||
+ |
||||
+ rv = sd_notifyf(0, "READY=1\n" |
||||
+ "STATUS=Total requests: %lu; Current requests/sec: %.3g; " |
||||
+ "Current traffic: %sB/sec\n", access, |
||||
+ ((float)access - last_update_access) / (float) elapsed, bps); |
||||
+ if (rv < 0) { |
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00000) |
||||
+ "sd_notifyf returned an error %d", rv); |
||||
+ } |
||||
+ |
||||
+ last_update_access = access; |
||||
+ last_update_kbytes = kbytes; |
||||
+ last_update_time = now; |
||||
+ |
||||
+ return DECLINED; |
||||
+} |
||||
+ |
||||
+static void systemd_register_hooks(apr_pool_t *p) |
||||
+{ |
||||
+ /* 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); |
||||
+} |
||||
+ |
||||
+module AP_MODULE_DECLARE_DATA systemd_module = |
||||
+{ |
||||
+ STANDARD20_MODULE_STUFF, |
||||
+ NULL, |
||||
+ NULL, |
||||
+ NULL, |
||||
+ NULL, |
||||
+ NULL, |
||||
+ systemd_register_hooks, |
||||
+}; |
@ -0,0 +1,83 @@
@@ -0,0 +1,83 @@
|
||||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c |
||||
index 15993f1..53ed6f1 100644 |
||||
--- a/modules/ssl/ssl_engine_config.c |
||||
+++ b/modules/ssl/ssl_engine_config.c |
||||
@@ -55,6 +55,7 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s) |
||||
mc = (SSLModConfigRec *)apr_palloc(pool, sizeof(*mc)); |
||||
mc->pPool = pool; |
||||
mc->bFixed = FALSE; |
||||
+ mc->sni_required = FALSE; |
||||
|
||||
/* |
||||
* initialize per-module configuration |
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c |
||||
index bf1f0e4..a7523de 100644 |
||||
--- a/modules/ssl/ssl_engine_init.c |
||||
+++ b/modules/ssl/ssl_engine_init.c |
||||
@@ -409,7 +409,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, |
||||
/* |
||||
* Configuration consistency checks |
||||
*/ |
||||
- ssl_init_CheckServers(base_server, ptemp); |
||||
+ ssl_init_CheckServers(mc, base_server, ptemp); |
||||
|
||||
/* |
||||
* Announce mod_ssl and SSL library in HTTP Server field |
||||
@@ -1475,7 +1475,7 @@ void ssl_init_ConfigureServer(server_rec *s, |
||||
} |
||||
} |
||||
|
||||
-void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p) |
||||
+void ssl_init_CheckServers(SSLModConfigRec *mc, server_rec *base_server, apr_pool_t *p) |
||||
{ |
||||
server_rec *s, *ps; |
||||
SSLSrvConfigRec *sc; |
||||
@@ -1557,6 +1557,7 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p) |
||||
} |
||||
|
||||
if (conflict) { |
||||
+ mc->sni_required = TRUE; |
||||
#ifdef OPENSSL_NO_TLSEXT |
||||
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(01917) |
||||
"Init: You should not use name-based " |
||||
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c |
||||
index bc9e26b..2460f01 100644 |
||||
--- a/modules/ssl/ssl_engine_kernel.c |
||||
+++ b/modules/ssl/ssl_engine_kernel.c |
||||
@@ -164,6 +164,7 @@ int ssl_hook_ReadReq(request_rec *r) |
||||
return DECLINED; |
||||
} |
||||
#ifndef OPENSSL_NO_TLSEXT |
||||
+ if (myModConfig(r->server)->sni_required) { |
||||
if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { |
||||
char *host, *scope_id; |
||||
apr_port_t port; |
||||
@@ -206,6 +207,7 @@ int ssl_hook_ReadReq(request_rec *r) |
||||
" virtual host"); |
||||
return HTTP_FORBIDDEN; |
||||
} |
||||
+ } |
||||
#endif |
||||
SSL_set_app_data2(ssl, r); |
||||
|
||||
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h |
||||
index 75fc0e3..31dbfa9 100644 |
||||
--- a/modules/ssl/ssl_private.h |
||||
+++ b/modules/ssl/ssl_private.h |
||||
@@ -554,6 +554,7 @@ typedef struct { |
||||
struct { |
||||
void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9, *pV10; |
||||
} rCtx; |
||||
+ BOOL sni_required; |
||||
} SSLModConfigRec; |
||||
|
||||
/** Structure representing configured filenames for certs and keys for |
||||
@@ -786,7 +787,7 @@ const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag); |
||||
int ssl_init_Module(apr_pool_t *, apr_pool_t *, apr_pool_t *, server_rec *); |
||||
void ssl_init_Engine(server_rec *, apr_pool_t *); |
||||
void ssl_init_ConfigureServer(server_rec *, apr_pool_t *, apr_pool_t *, SSLSrvConfigRec *); |
||||
-void ssl_init_CheckServers(server_rec *, apr_pool_t *); |
||||
+void ssl_init_CheckServers(SSLModConfigRec *mc, server_rec *, apr_pool_t *); |
||||
STACK_OF(X509_NAME) |
||||
*ssl_init_FindCAList(server_rec *, apr_pool_t *, const char *, const char *); |
||||
void ssl_init_Child(apr_pool_t *, server_rec *); |
@ -0,0 +1,82 @@
@@ -0,0 +1,82 @@
|
||||
diff --git a/modules/cache/cache_util.h b/modules/cache/cache_util.h |
||||
index eec38f3..1a2d5ee 100644 |
||||
--- a/modules/cache/cache_util.h |
||||
+++ b/modules/cache/cache_util.h |
||||
@@ -194,6 +194,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 4f2d3e0..30c88f4 100644 |
||||
--- a/modules/cache/mod_cache.c |
||||
+++ b/modules/cache/mod_cache.c |
||||
@@ -1299,6 +1299,11 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in) |
||||
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. */ |
||||
@@ -1717,7 +1722,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; |
||||
} |
||||
|
||||
@@ -1767,7 +1774,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; |
||||
} |
||||
|
||||
@@ -2096,12 +2106,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; |
||||
} |
||||
|
||||
@@ -2309,7 +2325,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"), |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
|
||||
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 |
||||
|
||||
--- httpd-2.4.4/server/Makefile.in.export |
||||
+++ httpd-2.4.4/server/Makefile.in |
||||
@@ -57,9 +57,6 @@ export_files: |
||||
( for dir in $(EXPORT_DIRS); do \ |
||||
ls $$dir/*.h ; \ |
||||
done; \ |
||||
- 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 |
@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
|
||||
diff --git a/server/protocol.c b/server/protocol.c |
||||
index e1ef204..d6d9165 100644 |
||||
--- a/server/protocol.c |
||||
+++ b/server/protocol.c |
||||
@@ -1049,6 +1049,7 @@ request_rec *ap_read_request(conn_rec *conn) |
||||
* now read. may update status. |
||||
*/ |
||||
ap_update_vhost_from_headers(r); |
||||
+ access_status = r->status; |
||||
|
||||
/* Toggle to the Host:-based vhost's timeout mode to fetch the |
||||
* request body and send the response body, if needed. |
@ -0,0 +1,239 @@
@@ -0,0 +1,239 @@
|
||||
--- trunk/modules/metadata/mod_unique_id.c 2011/12/02 23:02:04 1209766 |
||||
+++ trunk/modules/metadata/mod_unique_id.c 2013/07/10 16:20:31 1501827 |
||||
@@ -31,14 +31,11 @@ |
||||
#include "http_log.h" |
||||
#include "http_protocol.h" /* for ap_hook_post_read_request */ |
||||
|
||||
-#if APR_HAVE_UNISTD_H |
||||
-#include <unistd.h> /* for getpid() */ |
||||
-#endif |
||||
+#define ROOT_SIZE 10 |
||||
|
||||
typedef struct { |
||||
unsigned int stamp; |
||||
- unsigned int in_addr; |
||||
- unsigned int pid; |
||||
+ char root[ROOT_SIZE]; |
||||
unsigned short counter; |
||||
unsigned int thread_index; |
||||
} unique_id_rec; |
||||
@@ -64,20 +61,15 @@ |
||||
* gethostbyname (gethostname()) is unique across all the machines at the |
||||
* "site". |
||||
* |
||||
- * We also further assume that pids fit in 32-bits. If something uses more |
||||
- * than 32-bits, the fix is trivial, but it requires the unrolled uuencoding |
||||
- * loop to be extended. * A similar fix is needed to support multithreaded |
||||
- * servers, using a pid/tid combo. |
||||
- * |
||||
- * Together, the in_addr and pid are assumed to absolutely uniquely identify |
||||
- * this one child from all other currently running children on all servers |
||||
- * (including this physical server if it is running multiple httpds) from each |
||||
+ * The root is assumed to absolutely uniquely identify this one child |
||||
+ * from all other currently running children on all servers (including |
||||
+ * this physical server if it is running multiple httpds) from each |
||||
* other. |
||||
* |
||||
- * The stamp and counter are used to distinguish all hits for a particular |
||||
- * (in_addr,pid) pair. The stamp is updated using r->request_time, |
||||
- * saving cpu cycles. The counter is never reset, and is used to permit up to |
||||
- * 64k requests in a single second by a single child. |
||||
+ * The stamp and counter are used to distinguish all hits for a |
||||
+ * particular root. The stamp is updated using r->request_time, |
||||
+ * saving cpu cycles. The counter is never reset, and is used to |
||||
+ * permit up to 64k requests in a single second by a single child. |
||||
* |
||||
* The 144-bits of unique_id_rec are encoded using the alphabet |
||||
* [A-Za-z0-9@-], resulting in 24 bytes of printable characters. That is then |
||||
@@ -92,7 +84,7 @@ |
||||
* module change. |
||||
* |
||||
* It is highly desirable that identifiers exist for "eternity". But future |
||||
- * needs (such as much faster webservers, moving to 64-bit pids, or moving to a |
||||
+ * needs (such as much faster webservers, or moving to a |
||||
* multithreaded server) may dictate a need to change the contents of |
||||
* unique_id_rec. Such a future implementation should ensure that the first |
||||
* field is still a time_t stamp. By doing that, it is possible for a site to |
||||
@@ -100,7 +92,15 @@ |
||||
* wait one entire second, and then start all of their new-servers. This |
||||
* procedure will ensure that the new space of identifiers is completely unique |
||||
* from the old space. (Since the first four unencoded bytes always differ.) |
||||
+ * |
||||
+ * Note: previous implementations used 32-bits of IP address plus pid |
||||
+ * in place of the PRNG output in the "root" field. This was |
||||
+ * insufficient for IPv6-only hosts, required working DNS to determine |
||||
+ * a unique IP address (fragile), and needed a [0, 1) second sleep |
||||
+ * call at startup to avoid pid reuse. Use of the PRNG avoids all |
||||
+ * these issues. |
||||
*/ |
||||
+ |
||||
/* |
||||
* Sun Jun 7 05:43:49 CEST 1998 -- Alvaro |
||||
* More comments: |
||||
@@ -116,8 +116,6 @@ |
||||
* htonl/ntohl. Well, this shouldn't be a problem till year 2106. |
||||
*/ |
||||
|
||||
-static unsigned global_in_addr; |
||||
- |
||||
/* |
||||
* XXX: We should have a per-thread counter and not use cur_unique_id.counter |
||||
* XXX: in all threads, because this is bad for performance on multi-processor |
||||
@@ -129,7 +127,7 @@ |
||||
/* |
||||
* Number of elements in the structure unique_id_rec. |
||||
*/ |
||||
-#define UNIQUE_ID_REC_MAX 5 |
||||
+#define UNIQUE_ID_REC_MAX 4 |
||||
|
||||
static unsigned short unique_id_rec_offset[UNIQUE_ID_REC_MAX], |
||||
unique_id_rec_size[UNIQUE_ID_REC_MAX], |
||||
@@ -138,113 +136,32 @@ |
||||
|
||||
static int unique_id_global_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server) |
||||
{ |
||||
- char str[APRMAXHOSTLEN + 1]; |
||||
- apr_status_t rv; |
||||
- char *ipaddrstr; |
||||
- apr_sockaddr_t *sockaddr; |
||||
- |
||||
/* |
||||
* Calculate the sizes and offsets in cur_unique_id. |
||||
*/ |
||||
unique_id_rec_offset[0] = APR_OFFSETOF(unique_id_rec, stamp); |
||||
unique_id_rec_size[0] = sizeof(cur_unique_id.stamp); |
||||
- unique_id_rec_offset[1] = APR_OFFSETOF(unique_id_rec, in_addr); |
||||
- unique_id_rec_size[1] = sizeof(cur_unique_id.in_addr); |
||||
- unique_id_rec_offset[2] = APR_OFFSETOF(unique_id_rec, pid); |
||||
- unique_id_rec_size[2] = sizeof(cur_unique_id.pid); |
||||
- unique_id_rec_offset[3] = APR_OFFSETOF(unique_id_rec, counter); |
||||
- unique_id_rec_size[3] = sizeof(cur_unique_id.counter); |
||||
- unique_id_rec_offset[4] = APR_OFFSETOF(unique_id_rec, thread_index); |
||||
- unique_id_rec_size[4] = sizeof(cur_unique_id.thread_index); |
||||
+ unique_id_rec_offset[1] = APR_OFFSETOF(unique_id_rec, root); |
||||
+ unique_id_rec_size[1] = sizeof(cur_unique_id.root); |
||||
+ unique_id_rec_offset[2] = APR_OFFSETOF(unique_id_rec, counter); |
||||
+ unique_id_rec_size[2] = sizeof(cur_unique_id.counter); |
||||
+ unique_id_rec_offset[3] = APR_OFFSETOF(unique_id_rec, thread_index); |
||||
+ unique_id_rec_size[3] = sizeof(cur_unique_id.thread_index); |
||||
unique_id_rec_total_size = unique_id_rec_size[0] + unique_id_rec_size[1] + |
||||
- unique_id_rec_size[2] + unique_id_rec_size[3] + |
||||
- unique_id_rec_size[4]; |
||||
+ unique_id_rec_size[2] + unique_id_rec_size[3]; |
||||
|
||||
/* |
||||
* Calculate the size of the structure when encoded. |
||||
*/ |
||||
unique_id_rec_size_uu = (unique_id_rec_total_size*8+5)/6; |
||||
|
||||
- /* |
||||
- * Now get the global in_addr. Note that it is not sufficient to use one |
||||
- * of the addresses from the main_server, since those aren't as likely to |
||||
- * be unique as the physical address of the machine |
||||
- */ |
||||
- if ((rv = apr_gethostname(str, sizeof(str) - 1, p)) != APR_SUCCESS) { |
||||
- ap_log_error(APLOG_MARK, APLOG_ALERT, rv, main_server, APLOGNO(01563) |
||||
- "unable to find hostname of the server"); |
||||
- return HTTP_INTERNAL_SERVER_ERROR; |
||||
- } |
||||
- |
||||
- if ((rv = apr_sockaddr_info_get(&sockaddr, str, AF_INET, 0, 0, p)) == APR_SUCCESS) { |
||||
- global_in_addr = sockaddr->sa.sin.sin_addr.s_addr; |
||||
- } |
||||
- else { |
||||
- ap_log_error(APLOG_MARK, APLOG_ALERT, rv, main_server, APLOGNO(01564) |
||||
- "unable to find IPv4 address of \"%s\"", str); |
||||
-#if APR_HAVE_IPV6 |
||||
- if ((rv = apr_sockaddr_info_get(&sockaddr, str, AF_INET6, 0, 0, p)) == APR_SUCCESS) { |
||||
- memcpy(&global_in_addr, |
||||
- (char *)sockaddr->ipaddr_ptr + sockaddr->ipaddr_len - sizeof(global_in_addr), |
||||
- sizeof(global_in_addr)); |
||||
- ap_log_error(APLOG_MARK, APLOG_ALERT, rv, main_server, APLOGNO(01565) |
||||
- "using low-order bits of IPv6 address " |
||||
- "as if they were unique"); |
||||
- } |
||||
- else |
||||
-#endif |
||||
- return HTTP_INTERNAL_SERVER_ERROR; |
||||
- } |
||||
- |
||||
- apr_sockaddr_ip_get(&ipaddrstr, sockaddr); |
||||
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, main_server, APLOGNO(01566) "using ip addr %s", |
||||
- ipaddrstr); |
||||
- |
||||
- /* |
||||
- * If the server is pummelled with restart requests we could possibly end |
||||
- * up in a situation where we're starting again during the same second |
||||
- * that has been used in previous identifiers. Avoid that situation. |
||||
- * |
||||
- * In truth, for this to actually happen not only would it have to restart |
||||
- * in the same second, but it would have to somehow get the same pids as |
||||
- * one of the other servers that was running in that second. Which would |
||||
- * mean a 64k wraparound on pids ... not very likely at all. |
||||
- * |
||||
- * But protecting against it is relatively cheap. We just sleep into the |
||||
- * next second. |
||||
- */ |
||||
- apr_sleep(apr_time_from_sec(1) - apr_time_usec(apr_time_now())); |
||||
return OK; |
||||
} |
||||
|
||||
static void unique_id_child_init(apr_pool_t *p, server_rec *s) |
||||
{ |
||||
- pid_t pid; |
||||
- |
||||
- /* |
||||
- * Note that we use the pid because it's possible that on the same |
||||
- * physical machine there are multiple servers (i.e. using Listen). But |
||||
- * it's guaranteed that none of them will share the same pids between |
||||
- * children. |
||||
- * |
||||
- * XXX: for multithread this needs to use a pid/tid combo and probably |
||||
- * needs to be expanded to 32 bits |
||||
- */ |
||||
- pid = getpid(); |
||||
- cur_unique_id.pid = pid; |
||||
- |
||||
- /* |
||||
- * Test our assumption that the pid is 32-bits. It's possible that |
||||
- * 64-bit machines will declare pid_t to be 64 bits but only use 32 |
||||
- * of them. It would have been really nice to test this during |
||||
- * global_init ... but oh well. |
||||
- */ |
||||
- if ((pid_t)cur_unique_id.pid != pid) { |
||||
- ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, APLOGNO(01567) |
||||
- "oh no! pids are greater than 32-bits! I'm broken!"); |
||||
- } |
||||
- |
||||
- cur_unique_id.in_addr = global_in_addr; |
||||
+ ap_random_insecure_bytes(&cur_unique_id.root, |
||||
+ sizeof(cur_unique_id.root)); |
||||
|
||||
/* |
||||
* If we use 0 as the initial counter we have a little less protection |
||||
@@ -253,13 +170,6 @@ |
||||
*/ |
||||
ap_random_insecure_bytes(&cur_unique_id.counter, |
||||
sizeof(cur_unique_id.counter)); |
||||
- |
||||
- /* |
||||
- * We must always use network ordering for these bytes, so that |
||||
- * identifiers are comparable between machines of different byte |
||||
- * orderings. Note in_addr is already in network order. |
||||
- */ |
||||
- cur_unique_id.pid = htonl(cur_unique_id.pid); |
||||
} |
||||
|
||||
/* NOTE: This is *NOT* the same encoding used by base64encode ... the last two |
||||
@@ -291,10 +201,8 @@ |
||||
unsigned short counter; |
||||
int i,j,k; |
||||
|
||||
- new_unique_id.in_addr = cur_unique_id.in_addr; |
||||
- new_unique_id.pid = cur_unique_id.pid; |
||||
+ memcpy(&new_unique_id.root, &cur_unique_id.root, ROOT_SIZE); |
||||
new_unique_id.counter = cur_unique_id.counter; |
||||
- |
||||
new_unique_id.stamp = htonl((unsigned int)apr_time_sec(r->request_time)); |
||||
new_unique_id.thread_index = htonl((unsigned int)r->connection->id); |
||||
|
@ -0,0 +1,250 @@
@@ -0,0 +1,250 @@
|
||||
# ./pullrev.sh 1337344 1341905 1342065 1341930 |
||||
|
||||
suexec enhancements: |
||||
|
||||
1) use syslog for logging |
||||
2) use capabilities not setuid/setgid root binary |
||||
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1337344 |
||||
http://svn.apache.org/viewvc?view=revision&revision=1341905 |
||||
http://svn.apache.org/viewvc?view=revision&revision=1342065 |
||||
http://svn.apache.org/viewvc?view=revision&revision=1341930 |
||||
|
||||
--- httpd-2.4.4/configure.in.r1337344+ |
||||
+++ httpd-2.4.4/configure.in |
||||
@@ -734,7 +734,24 @@ APACHE_HELP_STRING(--with-suexec-gidmin, |
||||
|
||||
AC_ARG_WITH(suexec-logfile, |
||||
APACHE_HELP_STRING(--with-suexec-logfile,Set the logfile),[ |
||||
- AC_DEFINE_UNQUOTED(AP_LOG_EXEC, "$withval", [SuExec log file] ) ] ) |
||||
+ if test "x$withval" = "xyes"; then |
||||
+ AC_DEFINE_UNQUOTED(AP_LOG_EXEC, "$withval", [SuExec log file]) |
||||
+ fi |
||||
+]) |
||||
+ |
||||
+AC_ARG_WITH(suexec-syslog, |
||||
+APACHE_HELP_STRING(--with-suexec-syslog,Set the logfile),[ |
||||
+ if test $withval = "yes"; then |
||||
+ if test "x${with_suexec_logfile}" != "xno"; then |
||||
+ AC_MSG_NOTICE([hint: use "--without-suexec-logfile --with-suexec-syslog"]) |
||||
+ AC_MSG_ERROR([suexec does not support both logging to file and syslog]) |
||||
+ fi |
||||
+ AC_CHECK_FUNCS([vsyslog], [], [ |
||||
+ AC_MSG_ERROR([cannot support syslog from suexec without vsyslog()])]) |
||||
+ AC_DEFINE(AP_LOG_SYSLOG, 1, [SuExec log to syslog]) |
||||
+ fi |
||||
+]) |
||||
+ |
||||
|
||||
AC_ARG_WITH(suexec-safepath, |
||||
APACHE_HELP_STRING(--with-suexec-safepath,Set the safepath),[ |
||||
@@ -744,6 +761,15 @@ AC_ARG_WITH(suexec-umask, |
||||
APACHE_HELP_STRING(--with-suexec-umask,umask for suexec'd process),[ |
||||
AC_DEFINE_UNQUOTED(AP_SUEXEC_UMASK, 0$withval, [umask for suexec'd process] ) ] ) |
||||
|
||||
+INSTALL_SUEXEC=setuid |
||||
+AC_ARG_ENABLE([suexec-capabilities], |
||||
+APACHE_HELP_STRING(--enable-suexec-capabilities,Use Linux capability bits not setuid root suexec), [ |
||||
+INSTALL_SUEXEC=caps |
||||
+AC_DEFINE(AP_SUEXEC_CAPABILITIES, 1, |
||||
+ [Enable if suexec is installed with Linux capabilities, not setuid]) |
||||
+]) |
||||
+APACHE_SUBST(INSTALL_SUEXEC) |
||||
+ |
||||
dnl APR should go after the other libs, so the right symbols can be picked up |
||||
if test x${apu_found} != xobsolete; then |
||||
AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool`" |
||||
--- httpd-2.4.4/docs/manual/suexec.html.en.r1337344+ |
||||
+++ httpd-2.4.4/docs/manual/suexec.html.en |
||||
@@ -372,6 +372,21 @@ |
||||
together with the <code>--enable-suexec</code> option to let |
||||
APACI accept your request for using the suEXEC feature.</dd> |
||||
|
||||
+ <dt><code>--enable-suexec-capabilities</code></dt> |
||||
+ |
||||
+ <dd><strong>Linux specific:</strong> Normally, |
||||
+ the <code>suexec</code> binary is installed "setuid/setgid |
||||
+ root", which allows it to run with the full privileges of the |
||||
+ root user. If this option is used, the <code>suexec</code> |
||||
+ binary will instead be installed with only the setuid/setgid |
||||
+ "capability" bits set, which is the subset of full root |
||||
+ priviliges required for suexec operation. Note that |
||||
+ the <code>suexec</code> binary may not be able to write to a log |
||||
+ file in this mode; it is recommended that the |
||||
+ <code>--with-suexec-syslog --without-suexec-logfile</code> |
||||
+ options are used in conjunction with this mode, so that syslog |
||||
+ logging is used instead.</dd> |
||||
+ |
||||
<dt><code>--with-suexec-bin=<em>PATH</em></code></dt> |
||||
|
||||
<dd>The path to the <code>suexec</code> binary must be hard-coded |
||||
@@ -433,6 +448,12 @@ |
||||
"<code>suexec_log</code>" and located in your standard logfile |
||||
directory (<code>--logfiledir</code>).</dd> |
||||
|
||||
+ <dt><code>--with-suexec-syslog</code></dt> |
||||
+ |
||||
+ <dd>If defined, suexec will log notices and errors to syslog |
||||
+ instead of a logfile. This option must be combined |
||||
+ with <code>--without-suexec-logfile</code>.</dd> |
||||
+ |
||||
<dt><code>--with-suexec-safepath=<em>PATH</em></code></dt> |
||||
|
||||
<dd>Define a safe PATH environment to pass to CGI |
||||
@@ -550,9 +571,12 @@ Group webgroup |
||||
|
||||
<p>The suEXEC wrapper will write log information |
||||
to the file defined with the <code>--with-suexec-logfile</code> |
||||
- option as indicated above. If you feel you have configured and |
||||
- installed the wrapper properly, have a look at this log and the |
||||
- error_log for the server to see where you may have gone astray.</p> |
||||
+ option as indicated above, or to syslog if <code>--with-suexec-syslog</code> |
||||
+ is used. If you feel you have configured and |
||||
+ installed the wrapper properly, have a look at the log and the |
||||
+ error_log for the server to see where you may have gone astray. |
||||
+ The output of <code>"suexec -V"</code> will show the options |
||||
+ used to compile suexec, if using a binary distribution.</p> |
||||
|
||||
</div><div class="top"><a href="#page-header"><img alt="top" src="./images/up.gif" /></a></div> |
||||
<div class="section"> |
||||
@@ -640,4 +664,4 @@ if (typeof(prettyPrint) !== 'undefined') |
||||
prettyPrint(); |
||||
} |
||||
//--><!]]></script> |
||||
-</body></html> |
||||
\ No newline at end of file |
||||
+</body></html> |
||||
--- httpd-2.4.4/Makefile.in.r1337344+ |
||||
+++ httpd-2.4.4/Makefile.in |
||||
@@ -238,11 +238,22 @@ install-man: |
||||
cd $(DESTDIR)$(manualdir) && find . -name ".svn" -type d -print | xargs rm -rf 2>/dev/null || true; \ |
||||
fi |
||||
|
||||
-install-suexec: |
||||
+install-suexec: install-suexec-binary install-suexec-$(INSTALL_SUEXEC) |
||||
+ |
||||
+install-suexec-binary: |
||||
@if test -f $(builddir)/support/suexec; then \ |
||||
test -d $(DESTDIR)$(sbindir) || $(MKINSTALLDIRS) $(DESTDIR)$(sbindir); \ |
||||
$(INSTALL_PROGRAM) $(top_builddir)/support/suexec $(DESTDIR)$(sbindir); \ |
||||
- chmod 4755 $(DESTDIR)$(sbindir)/suexec; \ |
||||
+ fi |
||||
+ |
||||
+install-suexec-setuid: |
||||
+ @if test -f $(builddir)/support/suexec; then \ |
||||
+ chmod 4755 $(DESTDIR)$(sbindir)/suexec; \ |
||||
+ fi |
||||
+ |
||||
+install-suexec-caps: |
||||
+ @if test -f $(builddir)/support/suexec; then \ |
||||
+ setcap 'cap_setuid,cap_setgid+pe' $(DESTDIR)$(sbindir)/suexec; \ |
||||
fi |
||||
|
||||
suexec: |
||||
--- httpd-2.4.4/modules/arch/unix/mod_unixd.c.r1337344+ |
||||
+++ httpd-2.4.4/modules/arch/unix/mod_unixd.c |
||||
@@ -284,6 +284,13 @@ unixd_set_suexec(cmd_parms *cmd, void *d |
||||
return NULL; |
||||
} |
||||
|
||||
+#ifdef AP_SUEXEC_CAPABILITIES |
||||
+/* If suexec is using capabilities, don't test for the setuid bit. */ |
||||
+#define SETUID_TEST(finfo) (1) |
||||
+#else |
||||
+#define SETUID_TEST(finfo) (finfo.protection & APR_USETID) |
||||
+#endif |
||||
+ |
||||
static int |
||||
unixd_pre_config(apr_pool_t *pconf, apr_pool_t *plog, |
||||
apr_pool_t *ptemp) |
||||
@@ -300,7 +307,7 @@ unixd_pre_config(apr_pool_t *pconf, apr_ |
||||
ap_unixd_config.suexec_enabled = 0; |
||||
if ((apr_stat(&wrapper, SUEXEC_BIN, APR_FINFO_NORM, ptemp)) |
||||
== APR_SUCCESS) { |
||||
- if ((wrapper.protection & APR_USETID) && wrapper.user == 0 |
||||
+ if (SETUID_TEST(wrapper) && wrapper.user == 0 |
||||
&& (access(SUEXEC_BIN, R_OK|X_OK) == 0)) { |
||||
ap_unixd_config.suexec_enabled = 1; |
||||
ap_unixd_config.suexec_disabled_reason = ""; |
||||
--- httpd-2.4.4/support/suexec.c.r1337344+ |
||||
+++ httpd-2.4.4/support/suexec.c |
||||
@@ -58,6 +58,10 @@ |
||||
#include <grp.h> |
||||
#endif |
||||
|
||||
+#ifdef AP_LOG_SYSLOG |
||||
+#include <syslog.h> |
||||
+#endif |
||||
+ |
||||
#if defined(PATH_MAX) |
||||
#define AP_MAXPATH PATH_MAX |
||||
#elif defined(MAXPATHLEN) |
||||
@@ -69,7 +73,20 @@ |
||||
#define AP_ENVBUF 256 |
||||
|
||||
extern char **environ; |
||||
+ |
||||
+#ifdef AP_LOG_SYSLOG |
||||
+/* Syslog support. */ |
||||
+#if !defined(AP_LOG_FACILITY) && defined(LOG_AUTHPRIV) |
||||
+#define AP_LOG_FACILITY LOG_AUTHPRIV |
||||
+#elif !defined(AP_LOG_FACILITY) |
||||
+#define AP_LOG_FACILITY LOG_AUTH |
||||
+#endif |
||||
+ |
||||
+static int log_open; |
||||
+#else |
||||
+/* Non-syslog support. */ |
||||
static FILE *log = NULL; |
||||
+#endif |
||||
|
||||
static const char *const safe_env_lst[] = |
||||
{ |
||||
@@ -137,7 +154,14 @@ static void err_output(int is_error, con |
||||
|
||||
static void err_output(int is_error, const char *fmt, va_list ap) |
||||
{ |
||||
-#ifdef AP_LOG_EXEC |
||||
+#if defined(AP_LOG_SYSLOG) |
||||
+ if (!log_open) { |
||||
+ openlog("suexec", LOG_PID, AP_LOG_FACILITY); |
||||
+ log_open = 1; |
||||
+ } |
||||
+ |
||||
+ vsyslog(is_error ? LOG_ERR : LOG_INFO, fmt, ap); |
||||
+#elif defined(AP_LOG_EXEC) |
||||
time_t timevar; |
||||
struct tm *lt; |
||||
|
||||
@@ -295,7 +319,9 @@ int main(int argc, char *argv[]) |
||||
#ifdef AP_HTTPD_USER |
||||
fprintf(stderr, " -D AP_HTTPD_USER=\"%s\"\n", AP_HTTPD_USER); |
||||
#endif |
||||
-#ifdef AP_LOG_EXEC |
||||
+#if defined(AP_LOG_SYSLOG) |
||||
+ fprintf(stderr, " -D AP_LOG_SYSLOG\n"); |
||||
+#elif defined(AP_LOG_EXEC) |
||||
fprintf(stderr, " -D AP_LOG_EXEC=\"%s\"\n", AP_LOG_EXEC); |
||||
#endif |
||||
#ifdef AP_SAFE_PATH |
||||
@@ -591,6 +617,12 @@ int main(int argc, char *argv[]) |
||||
#endif /* AP_SUEXEC_UMASK */ |
||||
|
||||
/* Be sure to close the log file so the CGI can't mess with it. */ |
||||
+#ifdef AP_LOG_SYSLOG |
||||
+ if (log_open) { |
||||
+ closelog(); |
||||
+ log_open = 0; |
||||
+ } |
||||
+#else |
||||
if (log != NULL) { |
||||
#if APR_HAVE_FCNTL_H |
||||
/* |
||||
@@ -612,6 +644,7 @@ int main(int argc, char *argv[]) |
||||
log = NULL; |
||||
#endif |
||||
} |
||||
+#endif |
||||
|
||||
/* |
||||
* Execute the command, replacing our image with its own. |
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
--- a/modules/cache/cache_storage.c 2013/09/14 13:30:39 1523234 |
||||
+++ b/modules/cache/cache_storage.c 2013/09/14 13:32:25 1523235 |
||||
@@ -713,7 +713,9 @@ |
||||
|| APR_SUCCESS |
||||
!= cache_canonicalise_key(r, r->pool, location, |
||||
&location_uri, &location_key) |
||||
- || strcmp(r->parsed_uri.hostname, location_uri.hostname)) { |
||||
+ || !(r->parsed_uri.hostname && location_uri.hostname |
||||
+ && !strcmp(r->parsed_uri.hostname, |
||||
+ location_uri.hostname))) { |
||||
location_key = NULL; |
||||
} |
||||
} |
||||
@@ -726,8 +728,9 @@ |
||||
|| APR_SUCCESS |
||||
!= cache_canonicalise_key(r, r->pool, content_location, |
||||
&content_location_uri, &content_location_key) |
||||
- || strcmp(r->parsed_uri.hostname, |
||||
- content_location_uri.hostname)) { |
||||
+ || !(r->parsed_uri.hostname && content_location_uri.hostname |
||||
+ && !strcmp(r->parsed_uri.hostname, |
||||
+ content_location_uri.hostname))) { |
||||
content_location_key = NULL; |
||||
} |
||||
} |
@ -0,0 +1,381 @@
@@ -0,0 +1,381 @@
|
||||
diff --git a/include/http_core.h b/include/http_core.h |
||||
index 3c47989..f6f4aa2 100644 |
||||
--- a/include/http_core.h |
||||
+++ b/include/http_core.h |
||||
@@ -663,6 +663,10 @@ typedef struct { |
||||
#define AP_TRACE_ENABLE 1 |
||||
#define AP_TRACE_EXTENDED 2 |
||||
int trace_enable; |
||||
+#define AP_MERGE_TRAILERS_UNSET 0 |
||||
+#define AP_MERGE_TRAILERS_ENABLE 1 |
||||
+#define AP_MERGE_TRAILERS_DISABLE 2 |
||||
+ int merge_trailers; |
||||
|
||||
} core_server_config; |
||||
|
||||
diff --git a/include/httpd.h b/include/httpd.h |
||||
index 36cd58d..2e415f9 100644 |
||||
--- a/include/httpd.h |
||||
+++ b/include/httpd.h |
||||
@@ -1032,6 +1032,11 @@ struct request_rec { |
||||
*/ |
||||
apr_sockaddr_t *useragent_addr; |
||||
char *useragent_ip; |
||||
+ |
||||
+ /** MIME trailer environment from the request */ |
||||
+ apr_table_t *trailers_in; |
||||
+ /** MIME trailer environment from the response */ |
||||
+ apr_table_t *trailers_out; |
||||
}; |
||||
|
||||
/** |
||||
diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c |
||||
index 24a939a..2ae8f46 100644 |
||||
--- a/modules/http/http_filters.c |
||||
+++ b/modules/http/http_filters.c |
||||
@@ -214,6 +214,49 @@ static apr_status_t get_chunk_line(http_ctx_t *ctx, apr_bucket_brigade *b, |
||||
} |
||||
|
||||
|
||||
+static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f, |
||||
+ apr_bucket_brigade *b, int merge) |
||||
+{ |
||||
+ int rv; |
||||
+ apr_bucket *e; |
||||
+ request_rec *r = f->r; |
||||
+ apr_table_t *saved_headers_in = r->headers_in; |
||||
+ int saved_status = r->status; |
||||
+ |
||||
+ r->status = HTTP_OK; |
||||
+ r->headers_in = r->trailers_in; |
||||
+ apr_table_clear(r->headers_in); |
||||
+ ctx->state = BODY_NONE; |
||||
+ ap_get_mime_headers(r); |
||||
+ |
||||
+ if(r->status == HTTP_OK) { |
||||
+ r->status = saved_status; |
||||
+ e = apr_bucket_eos_create(f->c->bucket_alloc); |
||||
+ APR_BRIGADE_INSERT_TAIL(b, e); |
||||
+ ctx->eos_sent = 1; |
||||
+ rv = APR_SUCCESS; |
||||
+ } |
||||
+ else { |
||||
+ const char *error_notes = apr_table_get(r->notes, |
||||
+ "error-notes"); |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
||||
+ "Error while reading HTTP trailer: %i%s%s", |
||||
+ r->status, error_notes ? ": " : "", |
||||
+ error_notes ? error_notes : ""); |
||||
+ rv = APR_EINVAL; |
||||
+ } |
||||
+ |
||||
+ if(!merge) { |
||||
+ r->headers_in = saved_headers_in; |
||||
+ } |
||||
+ else { |
||||
+ r->headers_in = apr_table_overlay(r->pool, saved_headers_in, |
||||
+ r->trailers_in); |
||||
+ } |
||||
+ |
||||
+ return rv; |
||||
+} |
||||
+ |
||||
/* This is the HTTP_INPUT filter for HTTP requests and responses from |
||||
* proxied servers (mod_proxy). It handles chunked and content-length |
||||
* bodies. This can only be inserted/used after the headers |
||||
@@ -223,6 +266,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, |
||||
ap_input_mode_t mode, apr_read_type_e block, |
||||
apr_off_t readbytes) |
||||
{ |
||||
+ core_server_config *conf; |
||||
apr_bucket *e; |
||||
http_ctx_t *ctx = f->ctx; |
||||
apr_status_t rv; |
||||
@@ -230,6 +274,9 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, |
||||
int http_error = HTTP_REQUEST_ENTITY_TOO_LARGE; |
||||
apr_bucket_brigade *bb; |
||||
|
||||
+ conf = (core_server_config *) |
||||
+ ap_get_module_config(f->r->server->module_config, &core_module); |
||||
+ |
||||
/* just get out of the way of things we don't want. */ |
||||
if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) { |
||||
return ap_get_brigade(f->next, b, mode, block, readbytes); |
||||
@@ -403,13 +450,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, |
||||
} |
||||
|
||||
if (!ctx->remaining) { |
||||
- /* Handle trailers by calling ap_get_mime_headers again! */ |
||||
- ctx->state = BODY_NONE; |
||||
- ap_get_mime_headers(f->r); |
||||
- e = apr_bucket_eos_create(f->c->bucket_alloc); |
||||
- APR_BRIGADE_INSERT_TAIL(b, e); |
||||
- ctx->eos_sent = 1; |
||||
- return APR_SUCCESS; |
||||
+ return read_chunked_trailers(ctx, f, b, |
||||
+ conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); |
||||
} |
||||
} |
||||
} |
||||
@@ -509,13 +551,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, |
||||
} |
||||
|
||||
if (!ctx->remaining) { |
||||
- /* Handle trailers by calling ap_get_mime_headers again! */ |
||||
- ctx->state = BODY_NONE; |
||||
- ap_get_mime_headers(f->r); |
||||
- e = apr_bucket_eos_create(f->c->bucket_alloc); |
||||
- APR_BRIGADE_INSERT_TAIL(b, e); |
||||
- ctx->eos_sent = 1; |
||||
- return APR_SUCCESS; |
||||
+ return read_chunked_trailers(ctx, f, b, |
||||
+ conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); |
||||
} |
||||
} |
||||
break; |
||||
diff --git a/modules/http/http_request.c b/modules/http/http_request.c |
||||
index 796d506..cdfec8b 100644 |
||||
--- a/modules/http/http_request.c |
||||
+++ b/modules/http/http_request.c |
||||
@@ -463,6 +463,7 @@ static request_rec *internal_internal_redirect(const char *new_uri, |
||||
new->main = r->main; |
||||
|
||||
new->headers_in = r->headers_in; |
||||
+ new->trailers_in = r->trailers_in; |
||||
new->headers_out = apr_table_make(r->pool, 12); |
||||
if (ap_is_HTTP_REDIRECT(new->status)) { |
||||
const char *location = apr_table_get(r->headers_out, "Location"); |
||||
@@ -470,6 +471,7 @@ static request_rec *internal_internal_redirect(const char *new_uri, |
||||
apr_table_setn(new->headers_out, "Location", location); |
||||
} |
||||
new->err_headers_out = r->err_headers_out; |
||||
+ new->trailers_out = apr_table_make(r->pool, 5); |
||||
new->subprocess_env = rename_original_env(r->pool, r->subprocess_env); |
||||
new->notes = apr_table_make(r->pool, 5); |
||||
|
||||
@@ -583,6 +585,8 @@ AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r) |
||||
r->headers_out); |
||||
r->err_headers_out = apr_table_overlay(r->pool, rr->err_headers_out, |
||||
r->err_headers_out); |
||||
+ r->trailers_out = apr_table_overlay(r->pool, rr->trailers_out, |
||||
+ r->trailers_out); |
||||
r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env, |
||||
r->subprocess_env); |
||||
|
||||
diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c |
||||
index 25f5030..b021dd3 100644 |
||||
--- a/modules/loggers/mod_log_config.c |
||||
+++ b/modules/loggers/mod_log_config.c |
||||
@@ -431,6 +431,12 @@ static const char *log_header_in(request_rec *r, char *a) |
||||
return ap_escape_logitem(r->pool, apr_table_get(r->headers_in, a)); |
||||
} |
||||
|
||||
+static const char *log_trailer_in(request_rec *r, char *a) |
||||
+{ |
||||
+ return ap_escape_logitem(r->pool, apr_table_get(r->trailers_in, a)); |
||||
+} |
||||
+ |
||||
+ |
||||
static APR_INLINE char *find_multiple_headers(apr_pool_t *pool, |
||||
const apr_table_t *table, |
||||
const char *key) |
||||
@@ -514,6 +520,11 @@ static const char *log_header_out(request_rec *r, char *a) |
||||
return ap_escape_logitem(r->pool, cp); |
||||
} |
||||
|
||||
+static const char *log_trailer_out(request_rec *r, char *a) |
||||
+{ |
||||
+ return ap_escape_logitem(r->pool, apr_table_get(r->trailers_out, a)); |
||||
+} |
||||
+ |
||||
static const char *log_note(request_rec *r, char *a) |
||||
{ |
||||
return ap_escape_logitem(r->pool, apr_table_get(r->notes, a)); |
||||
@@ -916,7 +927,7 @@ static char *parse_log_misc_string(apr_pool_t *p, log_format_item *it, |
||||
static char *parse_log_item(apr_pool_t *p, log_format_item *it, const char **sa) |
||||
{ |
||||
const char *s = *sa; |
||||
- ap_log_handler *handler; |
||||
+ ap_log_handler *handler = NULL; |
||||
|
||||
if (*s != '%') { |
||||
return parse_log_misc_string(p, it, sa); |
||||
@@ -986,7 +997,16 @@ static char *parse_log_item(apr_pool_t *p, log_format_item *it, const char **sa) |
||||
break; |
||||
|
||||
default: |
||||
- handler = (ap_log_handler *)apr_hash_get(log_hash, s++, 1); |
||||
+ /* check for '^' + two character format first */ |
||||
+ if (*s == '^' && *(s+1) && *(s+2)) { |
||||
+ handler = (ap_log_handler *)apr_hash_get(log_hash, s, 3); |
||||
+ if (handler) { |
||||
+ s += 3; |
||||
+ } |
||||
+ } |
||||
+ if (!handler) { |
||||
+ handler = (ap_log_handler *)apr_hash_get(log_hash, s++, 1); |
||||
+ } |
||||
if (!handler) { |
||||
char dummy[2]; |
||||
|
||||
@@ -1516,7 +1536,7 @@ static void ap_register_log_handler(apr_pool_t *p, char *tag, |
||||
log_struct->func = handler; |
||||
log_struct->want_orig_default = def; |
||||
|
||||
- apr_hash_set(log_hash, tag, 1, (const void *)log_struct); |
||||
+ apr_hash_set(log_hash, tag, strlen(tag), (const void *)log_struct); |
||||
} |
||||
static ap_log_writer_init* ap_log_set_writer_init(ap_log_writer_init *handle) |
||||
{ |
||||
@@ -1686,6 +1706,9 @@ static int log_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) |
||||
log_pfn_register(p, "U", log_request_uri, 1); |
||||
log_pfn_register(p, "s", log_status, 1); |
||||
log_pfn_register(p, "R", log_handler, 1); |
||||
+ |
||||
+ log_pfn_register(p, "^ti", log_trailer_in, 0); |
||||
+ log_pfn_register(p, "^to", log_trailer_out, 0); |
||||
} |
||||
|
||||
/* reset to default conditions */ |
||||
diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c |
||||
index 7ae0fa4..05f33b4 100644 |
||||
--- a/modules/proxy/mod_proxy_http.c |
||||
+++ b/modules/proxy/mod_proxy_http.c |
||||
@@ -994,8 +994,11 @@ static request_rec *make_fake_req(conn_rec *c, request_rec *r) |
||||
rp->status = HTTP_OK; |
||||
|
||||
rp->headers_in = apr_table_make(pool, 50); |
||||
+ rp->trailers_in = apr_table_make(pool, 5); |
||||
+ |
||||
rp->subprocess_env = apr_table_make(pool, 50); |
||||
rp->headers_out = apr_table_make(pool, 12); |
||||
+ rp->trailers_out = apr_table_make(pool, 5); |
||||
rp->err_headers_out = apr_table_make(pool, 5); |
||||
rp->notes = apr_table_make(pool, 5); |
||||
|
||||
@@ -1076,6 +1079,7 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr, |
||||
psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); |
||||
|
||||
r->headers_out = apr_table_make(r->pool, 20); |
||||
+ r->trailers_out = apr_table_make(r->pool, 5); |
||||
*pread_len = 0; |
||||
|
||||
/* |
||||
@@ -1206,6 +1210,14 @@ apr_status_t ap_proxygetline(apr_bucket_brigade *bb, char *s, int n, request_rec |
||||
#define AP_MAX_INTERIM_RESPONSES 10 |
||||
#endif |
||||
|
||||
+static int add_trailers(void *data, const char *key, const char *val) |
||||
+{ |
||||
+ if (val) { |
||||
+ apr_table_add((apr_table_t*)data, key, val); |
||||
+ } |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
static |
||||
apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, |
||||
proxy_conn_rec **backend_ptr, |
||||
@@ -1717,6 +1729,12 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, |
||||
/* next time try a non-blocking read */ |
||||
mode = APR_NONBLOCK_READ; |
||||
|
||||
+ if (!apr_is_empty_table(backend->r->trailers_in)) { |
||||
+ apr_table_do(add_trailers, r->trailers_out, |
||||
+ backend->r->trailers_in, NULL); |
||||
+ apr_table_clear(backend->r->trailers_in); |
||||
+ } |
||||
+ |
||||
apr_brigade_length(bb, 0, &readbytes); |
||||
backend->worker->s->read += readbytes; |
||||
#if DEBUGGING |
||||
diff --git a/server/core.c b/server/core.c |
||||
index 024bab6..7cfde63 100644 |
||||
--- a/server/core.c |
||||
+++ b/server/core.c |
||||
@@ -523,6 +523,10 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv) |
||||
if (virt->error_log_req) |
||||
conf->error_log_req = virt->error_log_req; |
||||
|
||||
+ conf->merge_trailers = (virt->merge_trailers != AP_MERGE_TRAILERS_UNSET) |
||||
+ ? virt->merge_trailers |
||||
+ : base->merge_trailers; |
||||
+ |
||||
return conf; |
||||
} |
||||
|
||||
@@ -3877,6 +3881,16 @@ AP_DECLARE(void) ap_register_errorlog_handler(apr_pool_t *p, char *tag, |
||||
} |
||||
|
||||
|
||||
+static const char *set_merge_trailers(cmd_parms *cmd, void *dummy, int arg) |
||||
+{ |
||||
+ core_server_config *conf = ap_get_module_config(cmd->server->module_config, |
||||
+ &core_module); |
||||
+ conf->merge_trailers = (arg ? AP_MERGE_TRAILERS_ENABLE : |
||||
+ AP_MERGE_TRAILERS_DISABLE); |
||||
+ |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
/* Note --- ErrorDocument will now work from .htaccess files. |
||||
* The AllowOverride of Fileinfo allows webmasters to turn it off |
||||
*/ |
||||
@@ -4124,6 +4138,8 @@ AP_INIT_TAKE1("EnableExceptionHook", ap_mpm_set_exception_hook, NULL, RSRC_CONF, |
||||
#endif |
||||
AP_INIT_TAKE1("TraceEnable", set_trace_enable, NULL, RSRC_CONF, |
||||
"'on' (default), 'off' or 'extended' to trace request body content"), |
||||
+AP_INIT_FLAG("MergeTrailers", set_merge_trailers, NULL, RSRC_CONF, |
||||
+ "merge request trailers into request headers or not"), |
||||
{ NULL } |
||||
}; |
||||
|
||||
@@ -4206,7 +4222,6 @@ static int core_map_to_storage(request_rec *r) |
||||
|
||||
static int do_nothing(request_rec *r) { return OK; } |
||||
|
||||
- |
||||
static int core_override_type(request_rec *r) |
||||
{ |
||||
core_dir_config *conf = |
||||
diff --git a/server/protocol.c b/server/protocol.c |
||||
index 14329eb..46fc034 100644 |
||||
--- a/server/protocol.c |
||||
+++ b/server/protocol.c |
||||
@@ -718,6 +718,8 @@ AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb |
||||
r->status = HTTP_REQUEST_TIME_OUT; |
||||
} |
||||
else { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, |
||||
+ "Failed to read request header line %s", field); |
||||
r->status = HTTP_BAD_REQUEST; |
||||
} |
||||
|
||||
@@ -917,9 +919,11 @@ request_rec *ap_read_request(conn_rec *conn) |
||||
r->allowed_methods = ap_make_method_list(p, 2); |
||||
|
||||
r->headers_in = apr_table_make(r->pool, 25); |
||||
+ r->trailers_in = apr_table_make(r->pool, 5); |
||||
r->subprocess_env = apr_table_make(r->pool, 25); |
||||
r->headers_out = apr_table_make(r->pool, 12); |
||||
r->err_headers_out = apr_table_make(r->pool, 5); |
||||
+ r->trailers_out = apr_table_make(r->pool, 5); |
||||
r->notes = apr_table_make(r->pool, 5); |
||||
|
||||
r->request_config = ap_create_request_config(r->pool); |
||||
@@ -1162,6 +1166,7 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, |
||||
rnew->status = HTTP_OK; |
||||
|
||||
rnew->headers_in = apr_table_copy(rnew->pool, r->headers_in); |
||||
+ rnew->trailers_in = apr_table_copy(rnew->pool, r->trailers_in); |
||||
|
||||
/* did the original request have a body? (e.g. POST w/SSI tags) |
||||
* if so, make sure the subrequest doesn't inherit body headers |
||||
@@ -1173,6 +1178,7 @@ AP_DECLARE(void) ap_set_sub_req_protocol(request_rec *rnew, |
||||
rnew->subprocess_env = apr_table_copy(rnew->pool, r->subprocess_env); |
||||
rnew->headers_out = apr_table_make(rnew->pool, 5); |
||||
rnew->err_headers_out = apr_table_make(rnew->pool, 5); |
||||
+ rnew->trailers_out = apr_table_make(rnew->pool, 5); |
||||
rnew->notes = apr_table_make(rnew->pool, 5); |
||||
|
||||
rnew->expecting_100 = r->expecting_100; |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
--- a/modules/dav/main/util.c 2014/01/09 14:28:39 1556815 |
||||
+++ b/modules/dav/main/util.c 2014/01/09 14:29:47 1556816 |
||||
@@ -396,8 +396,10 @@ |
||||
|
||||
if (strip_white) { |
||||
/* trim leading whitespace */ |
||||
- while (apr_isspace(*cdata)) /* assume: return false for '\0' */ |
||||
+ while (apr_isspace(*cdata)) { /* assume: return false for '\0' */ |
||||
++cdata; |
||||
+ --len; |
||||
+ } |
||||
|
||||
/* trim trailing whitespace */ |
||||
while (len-- > 0 && apr_isspace(cdata[len])) |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
--- a/modules/loggers/mod_log_config.c 2013/11/15 17:07:52 1542329 |
||||
+++ b/modules/loggers/mod_log_config.c 2014/03/10 11:23:47 1575904 |
||||
@@ -543,14 +543,24 @@ |
||||
|
||||
while ((cookie = apr_strtok(cookies, ";", &last1))) { |
||||
char *name = apr_strtok(cookie, "=", &last2); |
||||
- if (name) { |
||||
- char *value = name + strlen(name) + 1; |
||||
- apr_collapse_spaces(name, name); |
||||
+ /* last2 points to the next char following an '=' delim, |
||||
+ or the trailing NUL char of the string */ |
||||
+ char *value = last2; |
||||
+ if (name && *name && value && *value) { |
||||
+ char *last = value - 2; |
||||
+ /* Move past leading WS */ |
||||
+ name += strspn(name, " \t"); |
||||
+ while (last >= name && apr_isspace(*last)) { |
||||
+ *last = '\0'; |
||||
+ --last; |
||||
+ } |
||||
|
||||
if (!strcasecmp(name, a)) { |
||||
- char *last; |
||||
- value += strspn(value, " \t"); /* Move past leading WS */ |
||||
- last = value + strlen(value) - 1; |
||||
+ /* last1 points to the next char following the ';' delim, |
||||
+ or the trailing NUL char of the string */ |
||||
+ last = last1 - (*last1 ? 2 : 1); |
||||
+ /* Move past leading WS */ |
||||
+ value += strspn(value, " \t"); |
||||
while (last >= value && apr_isspace(*last)) { |
||||
*last = '\0'; |
||||
--last; |
||||
@@ -559,6 +569,7 @@ |
||||
return ap_escape_logitem(r->pool, value); |
||||
} |
||||
} |
||||
+ /* Iterate the remaining tokens using apr_strtok(NULL, ...) */ |
||||
cookies = NULL; |
||||
} |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
--- a/modules/proxy/proxy_util.c 2014/07/15 16:07:44 1610736 |
||||
+++ b/modules/proxy/proxy_util.c 2014/07/15 16:11:04 1610737 |
||||
@@ -3132,7 +3132,7 @@ |
||||
const char *name; |
||||
|
||||
do { |
||||
- while (*val == ',') { |
||||
+ while (*val == ',' || *val == ';') { |
||||
val++; |
||||
} |
||||
name = ap_get_token(x->pool, &val, 0); |
@ -0,0 +1,266 @@
@@ -0,0 +1,266 @@
|
||||
diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c |
||||
index 79f6f8d..6c415c8 100644 |
||||
--- a/modules/filters/mod_deflate.c |
||||
+++ b/modules/filters/mod_deflate.c |
||||
@@ -37,6 +37,7 @@ |
||||
#include "httpd.h" |
||||
#include "http_config.h" |
||||
#include "http_log.h" |
||||
+#include "http_core.h" |
||||
#include "apr_lib.h" |
||||
#include "apr_strings.h" |
||||
#include "apr_general.h" |
||||
@@ -52,6 +53,9 @@ |
||||
static const char deflateFilterName[] = "DEFLATE"; |
||||
module AP_MODULE_DECLARE_DATA deflate_module; |
||||
|
||||
+#define AP_INFLATE_RATIO_LIMIT 200 |
||||
+#define AP_INFLATE_RATIO_BURST 3 |
||||
+ |
||||
typedef struct deflate_filter_config_t |
||||
{ |
||||
int windowSize; |
||||
@@ -63,6 +67,12 @@ typedef struct deflate_filter_config_t |
||||
char *note_output_name; |
||||
} deflate_filter_config; |
||||
|
||||
+typedef struct deflate_dirconf_t { |
||||
+ apr_off_t inflate_limit; |
||||
+ int ratio_limit, |
||||
+ ratio_burst; |
||||
+} deflate_dirconf_t; |
||||
+ |
||||
/* RFC 1952 Section 2.3 defines the gzip header: |
||||
* |
||||
* +---+---+---+---+---+---+---+---+---+---+ |
||||
@@ -204,6 +214,14 @@ static void *create_deflate_server_config(apr_pool_t *p, server_rec *s) |
||||
return c; |
||||
} |
||||
|
||||
+static void *create_deflate_dirconf(apr_pool_t *p, char *dummy) |
||||
+{ |
||||
+ deflate_dirconf_t *dc = apr_pcalloc(p, sizeof(*dc)); |
||||
+ dc->ratio_limit = AP_INFLATE_RATIO_LIMIT; |
||||
+ dc->ratio_burst = AP_INFLATE_RATIO_BURST; |
||||
+ return dc; |
||||
+} |
||||
+ |
||||
static const char *deflate_set_window_size(cmd_parms *cmd, void *dummy, |
||||
const char *arg) |
||||
{ |
||||
@@ -295,6 +313,55 @@ static const char *deflate_set_compressionlevel(cmd_parms *cmd, void *dummy, |
||||
return NULL; |
||||
} |
||||
|
||||
+ |
||||
+static const char *deflate_set_inflate_limit(cmd_parms *cmd, void *dirconf, |
||||
+ const char *arg) |
||||
+{ |
||||
+ deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf; |
||||
+ char *errp; |
||||
+ |
||||
+ if (APR_SUCCESS != apr_strtoff(&dc->inflate_limit, arg, &errp, 10)) { |
||||
+ return "DeflateInflateLimitRequestBody is not parsable."; |
||||
+ } |
||||
+ if (*errp || dc->inflate_limit < 0) { |
||||
+ return "DeflateInflateLimitRequestBody requires a non-negative integer."; |
||||
+ } |
||||
+ |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+static const char *deflate_set_inflate_ratio_limit(cmd_parms *cmd, |
||||
+ void *dirconf, |
||||
+ const char *arg) |
||||
+{ |
||||
+ deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf; |
||||
+ int i; |
||||
+ |
||||
+ i = atoi(arg); |
||||
+ if (i <= 0) |
||||
+ return "DeflateInflateRatioLimit must be positive"; |
||||
+ |
||||
+ dc->ratio_limit = i; |
||||
+ |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
+static const char *deflate_set_inflate_ratio_burst(cmd_parms *cmd, |
||||
+ void *dirconf, |
||||
+ const char *arg) |
||||
+{ |
||||
+ deflate_dirconf_t *dc = (deflate_dirconf_t*) dirconf; |
||||
+ int i; |
||||
+ |
||||
+ i = atoi(arg); |
||||
+ if (i <= 0) |
||||
+ return "DeflateInflateRatioBurst must be positive"; |
||||
+ |
||||
+ dc->ratio_burst = i; |
||||
+ |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
typedef struct deflate_ctx_t |
||||
{ |
||||
z_stream stream; |
||||
@@ -304,6 +371,8 @@ typedef struct deflate_ctx_t |
||||
int (*libz_end_func)(z_streamp); |
||||
unsigned char *validation_buffer; |
||||
apr_size_t validation_buffer_length; |
||||
+ int ratio_hits; |
||||
+ apr_off_t inflate_total; |
||||
unsigned int inflate_init:1; |
||||
unsigned int filter_init:1; |
||||
unsigned int done:1; |
||||
@@ -422,6 +491,22 @@ static void deflate_check_etag(request_rec *r, const char *transform) |
||||
} |
||||
} |
||||
|
||||
+/* Check whether the (inflate) ratio exceeds the configured limit/burst. */ |
||||
+static int check_ratio(request_rec *r, deflate_ctx *ctx, |
||||
+ const deflate_dirconf_t *dc) |
||||
+{ |
||||
+ if (ctx->stream.total_in) { |
||||
+ int ratio = ctx->stream.total_out / ctx->stream.total_in; |
||||
+ if (ratio < dc->ratio_limit) { |
||||
+ ctx->ratio_hits = 0; |
||||
+ } |
||||
+ else if (++ctx->ratio_hits > dc->ratio_burst) { |
||||
+ return 0; |
||||
+ } |
||||
+ } |
||||
+ return 1; |
||||
+} |
||||
+ |
||||
static int have_ssl_compression(request_rec *r) |
||||
{ |
||||
const char *comp; |
||||
@@ -897,6 +982,8 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, |
||||
int zRC; |
||||
apr_status_t rv; |
||||
deflate_filter_config *c; |
||||
+ deflate_dirconf_t *dc; |
||||
+ apr_off_t inflate_limit; |
||||
|
||||
/* just get out of the way of things we don't want. */ |
||||
if (mode != AP_MODE_READBYTES) { |
||||
@@ -904,6 +991,7 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, |
||||
} |
||||
|
||||
c = ap_get_module_config(r->server->module_config, &deflate_module); |
||||
+ dc = ap_get_module_config(r->per_dir_config, &deflate_module); |
||||
|
||||
if (!ctx) { |
||||
char deflate_hdr[10]; |
||||
@@ -994,6 +1082,12 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, |
||||
apr_brigade_cleanup(ctx->bb); |
||||
} |
||||
|
||||
+ inflate_limit = dc->inflate_limit; |
||||
+ if (inflate_limit == 0) { |
||||
+ /* The core is checking the deflated body, we'll check the inflated */ |
||||
+ inflate_limit = ap_get_limit_req_body(f->r); |
||||
+ } |
||||
+ |
||||
if (APR_BRIGADE_EMPTY(ctx->proc_bb)) { |
||||
rv = ap_get_brigade(f->next, ctx->bb, mode, block, readbytes); |
||||
|
||||
@@ -1038,6 +1132,17 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, |
||||
|
||||
ctx->stream.next_out = ctx->buffer; |
||||
len = c->bufferSize - ctx->stream.avail_out; |
||||
+ |
||||
+ ctx->inflate_total += len; |
||||
+ if (inflate_limit && ctx->inflate_total > inflate_limit) { |
||||
+ inflateEnd(&ctx->stream); |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02647) |
||||
+ "Inflated content length of %" APR_OFF_T_FMT |
||||
+ " is larger than the configured limit" |
||||
+ " of %" APR_OFF_T_FMT, |
||||
+ ctx->inflate_total, inflate_limit); |
||||
+ return APR_ENOSPC; |
||||
+ } |
||||
|
||||
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); |
||||
tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, |
||||
@@ -1073,6 +1178,26 @@ static apr_status_t deflate_in_filter(ap_filter_t *f, |
||||
ctx->stream.next_out = ctx->buffer; |
||||
len = c->bufferSize - ctx->stream.avail_out; |
||||
|
||||
+ ctx->inflate_total += len; |
||||
+ if (inflate_limit && ctx->inflate_total > inflate_limit) { |
||||
+ inflateEnd(&ctx->stream); |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02648) |
||||
+ "Inflated content length of %" APR_OFF_T_FMT |
||||
+ " is larger than the configured limit" |
||||
+ " of %" APR_OFF_T_FMT, |
||||
+ ctx->inflate_total, inflate_limit); |
||||
+ return APR_ENOSPC; |
||||
+ } |
||||
+ |
||||
+ if (!check_ratio(r, ctx, dc)) { |
||||
+ inflateEnd(&ctx->stream); |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02649) |
||||
+ "Inflated content ratio is larger than the " |
||||
+ "configured limit %i by %i time(s)", |
||||
+ dc->ratio_limit, dc->ratio_burst); |
||||
+ return APR_EINVAL; |
||||
+ } |
||||
+ |
||||
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len); |
||||
tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len, |
||||
NULL, f->c->bucket_alloc); |
||||
@@ -1193,6 +1318,7 @@ static apr_status_t inflate_out_filter(ap_filter_t *f, |
||||
int zRC; |
||||
apr_status_t rv; |
||||
deflate_filter_config *c; |
||||
+ deflate_dirconf_t *dc; |
||||
|
||||
/* Do nothing if asked to filter nothing. */ |
||||
if (APR_BRIGADE_EMPTY(bb)) { |
||||
@@ -1200,6 +1326,7 @@ static apr_status_t inflate_out_filter(ap_filter_t *f, |
||||
} |
||||
|
||||
c = ap_get_module_config(r->server->module_config, &deflate_module); |
||||
+ dc = ap_get_module_config(r->per_dir_config, &deflate_module); |
||||
|
||||
if (!ctx) { |
||||
|
||||
@@ -1462,6 +1589,14 @@ static apr_status_t inflate_out_filter(ap_filter_t *f, |
||||
while (ctx->stream.avail_in != 0) { |
||||
if (ctx->stream.avail_out == 0) { |
||||
|
||||
+ if (!check_ratio(r, ctx, dc)) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02650) |
||||
+ "Inflated content ratio is larger than the " |
||||
+ "configured limit %i by %i time(s)", |
||||
+ dc->ratio_limit, dc->ratio_burst); |
||||
+ return APR_EINVAL; |
||||
+ } |
||||
+ |
||||
ctx->stream.next_out = ctx->buffer; |
||||
len = c->bufferSize - ctx->stream.avail_out; |
||||
|
||||
@@ -1548,12 +1683,20 @@ static const command_rec deflate_filter_cmds[] = { |
||||
"Set the Deflate Memory Level (1-9)"), |
||||
AP_INIT_TAKE1("DeflateCompressionLevel", deflate_set_compressionlevel, NULL, RSRC_CONF, |
||||
"Set the Deflate Compression Level (1-9)"), |
||||
+ AP_INIT_TAKE1("DeflateInflateLimitRequestBody", deflate_set_inflate_limit, NULL, OR_ALL, |
||||
+ "Set a limit on size of inflated input"), |
||||
+ AP_INIT_TAKE1("DeflateInflateRatioLimit", deflate_set_inflate_ratio_limit, NULL, OR_ALL, |
||||
+ "Set the inflate ratio limit above which inflation is " |
||||
+ "aborted (default: " APR_STRINGIFY(AP_INFLATE_RATIO_LIMIT) ")"), |
||||
+ AP_INIT_TAKE1("DeflateInflateRatioBurst", deflate_set_inflate_ratio_burst, NULL, OR_ALL, |
||||
+ "Set the maximum number of following inflate ratios above limit " |
||||
+ "(default: " APR_STRINGIFY(AP_INFLATE_RATIO_BURST) ")"), |
||||
{NULL} |
||||
}; |
||||
|
||||
AP_DECLARE_MODULE(deflate) = { |
||||
STANDARD20_MODULE_STUFF, |
||||
- NULL, /* dir config creater */ |
||||
+ create_deflate_dirconf, /* dir config creater */ |
||||
NULL, /* dir merger --- default is to override */ |
||||
create_deflate_server_config, /* server config */ |
||||
NULL, /* merge server config */ |
@ -0,0 +1,119 @@
@@ -0,0 +1,119 @@
|
||||
Index: server/scoreboard.c |
||||
=================================================================== |
||||
--- a/server/scoreboard.c (revision 1610498) |
||||
+++ b/server/scoreboard.c (revision 1610499) |
||||
@@ -579,6 +579,21 @@ |
||||
sbh->thread_num); |
||||
} |
||||
|
||||
+AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest, |
||||
+ int child_num, |
||||
+ int thread_num) |
||||
+{ |
||||
+ worker_score *ws = ap_get_scoreboard_worker_from_indexes(child_num, thread_num); |
||||
+ |
||||
+ memcpy(dest, ws, sizeof *ws); |
||||
+ |
||||
+ /* For extra safety, NUL-terminate the strings returned, though it |
||||
+ * should be true those last bytes are always zero anyway. */ |
||||
+ dest->client[sizeof(dest->client) - 1] = '\0'; |
||||
+ dest->request[sizeof(dest->request) - 1] = '\0'; |
||||
+ dest->vhost[sizeof(dest->vhost) - 1] = '\0'; |
||||
+} |
||||
+ |
||||
AP_DECLARE(process_score *) ap_get_scoreboard_process(int x) |
||||
{ |
||||
if ((x < 0) || (x >= server_limit)) { |
||||
Index: modules/generators/mod_status.c |
||||
=================================================================== |
||||
--- a/modules/generators/mod_status.c (revision 1610498) |
||||
+++ b/modules/generators/mod_status.c (revision 1610499) |
||||
@@ -194,7 +194,7 @@ |
||||
long req_time; |
||||
int short_report; |
||||
int no_table_report; |
||||
- worker_score *ws_record; |
||||
+ worker_score *ws_record = apr_palloc(r->pool, sizeof *ws_record); |
||||
process_score *ps_record; |
||||
char *stat_buffer; |
||||
pid_t *pid_buffer, worker_pid; |
||||
@@ -306,7 +306,7 @@ |
||||
for (j = 0; j < thread_limit; ++j) { |
||||
int indx = (i * thread_limit) + j; |
||||
|
||||
- ws_record = ap_get_scoreboard_worker_from_indexes(i, j); |
||||
+ ap_copy_scoreboard_worker(ws_record, i, j); |
||||
res = ws_record->status; |
||||
|
||||
if ((i >= max_servers || j >= threads_per_child) |
||||
@@ -637,7 +637,7 @@ |
||||
|
||||
for (i = 0; i < server_limit; ++i) { |
||||
for (j = 0; j < thread_limit; ++j) { |
||||
- ws_record = ap_get_scoreboard_worker_from_indexes(i, j); |
||||
+ ap_copy_scoreboard_worker(ws_record, i, j); |
||||
|
||||
if (ws_record->access_count == 0 && |
||||
(ws_record->status == SERVER_READY || |
||||
Index: modules/lua/lua_request.c |
||||
=================================================================== |
||||
--- a/modules/lua/lua_request.c (revision 1610498) |
||||
+++ b/modules/lua/lua_request.c (revision 1610499) |
||||
@@ -1245,16 +1245,22 @@ |
||||
*/ |
||||
static int lua_ap_scoreboard_worker(lua_State *L) |
||||
{ |
||||
- int i, |
||||
- j; |
||||
- worker_score *ws_record; |
||||
+ int i, j; |
||||
+ worker_score *ws_record = NULL; |
||||
+ request_rec *r = NULL; |
||||
|
||||
luaL_checktype(L, 1, LUA_TUSERDATA); |
||||
luaL_checktype(L, 2, LUA_TNUMBER); |
||||
luaL_checktype(L, 3, LUA_TNUMBER); |
||||
+ |
||||
+ r = ap_lua_check_request_rec(L, 1); |
||||
+ if (!r) return 0; |
||||
+ |
||||
i = lua_tointeger(L, 2); |
||||
j = lua_tointeger(L, 3); |
||||
- ws_record = ap_get_scoreboard_worker_from_indexes(i, j); |
||||
+ ws_record = apr_palloc(r->pool, sizeof *ws_record); |
||||
+ |
||||
+ ap_copy_scoreboard_worker(ws_record, i, j); |
||||
if (ws_record) { |
||||
lua_newtable(L); |
||||
|
||||
Index: include/scoreboard.h |
||||
=================================================================== |
||||
--- a/include/scoreboard.h (revision 1610498) |
||||
+++ b/include/scoreboard.h (revision 1610499) |
||||
@@ -183,8 +183,25 @@ |
||||
AP_DECLARE(void) ap_time_process_request(ap_sb_handle_t *sbh, int status); |
||||
|
||||
AP_DECLARE(worker_score *) ap_get_scoreboard_worker(ap_sb_handle_t *sbh); |
||||
+ |
||||
+/** Return a pointer to the worker_score for a given child, thread pair. |
||||
+ * @param child_num The child number. |
||||
+ * @param thread_num The thread number. |
||||
+ * @return A pointer to the worker_score structure. |
||||
+ * @deprecated This function is deprecated, use ap_copy_scoreboard_worker instead. */ |
||||
AP_DECLARE(worker_score *) ap_get_scoreboard_worker_from_indexes(int child_num, |
||||
int thread_num); |
||||
+ |
||||
+/** Copy the contents of a worker scoreboard entry. The contents of |
||||
+ * the worker_score structure are copied verbatim into the dest |
||||
+ * structure. |
||||
+ * @param dest Output parameter. |
||||
+ * @param child_num The child number. |
||||
+ * @param thread_num The thread number. |
||||
+ */ |
||||
+AP_DECLARE(void) ap_copy_scoreboard_worker(worker_score *dest, |
||||
+ int child_num, int thread_num); |
||||
+ |
||||
AP_DECLARE(process_score *) ap_get_scoreboard_process(int x); |
||||
AP_DECLARE(global_score *) ap_get_scoreboard_global(void); |
||||
|
||||
|
@ -0,0 +1,144 @@
@@ -0,0 +1,144 @@
|
||||
--- a/modules/generators/mod_cgid.c 2014/07/14 20:16:45 1610511 |
||||
+++ b/modules/generators/mod_cgid.c 2014/07/14 20:18:26 1610512 |
||||
@@ -97,6 +97,10 @@ |
||||
static pid_t parent_pid; |
||||
static ap_unix_identity_t empty_ugid = { (uid_t)-1, (gid_t)-1, -1 }; |
||||
|
||||
+typedef struct { |
||||
+ apr_interval_time_t timeout; |
||||
+} cgid_dirconf; |
||||
+ |
||||
/* The APR other-child API doesn't tell us how the daemon exited |
||||
* (SIGSEGV vs. exit(1)). The other-child maintenance function |
||||
* needs to decide whether to restart the daemon after a failure |
||||
@@ -968,7 +972,14 @@ |
||||
return overrides->logname ? overrides : base; |
||||
} |
||||
|
||||
+static void *create_cgid_dirconf(apr_pool_t *p, char *dummy) |
||||
+{ |
||||
+ cgid_dirconf *c = (cgid_dirconf *) apr_pcalloc(p, sizeof(cgid_dirconf)); |
||||
+ return c; |
||||
+} |
||||
+ |
||||
static const char *set_scriptlog(cmd_parms *cmd, void *dummy, const char *arg) |
||||
+ |
||||
{ |
||||
server_rec *s = cmd->server; |
||||
cgid_server_conf *conf = ap_get_module_config(s->module_config, |
||||
@@ -1021,7 +1032,16 @@ |
||||
|
||||
return NULL; |
||||
} |
||||
+static const char *set_script_timeout(cmd_parms *cmd, void *dummy, const char *arg) |
||||
+{ |
||||
+ cgid_dirconf *dc = dummy; |
||||
|
||||
+ if (ap_timeout_parameter_parse(arg, &dc->timeout, "s") != APR_SUCCESS) { |
||||
+ return "CGIDScriptTimeout has wrong format"; |
||||
+ } |
||||
+ |
||||
+ return NULL; |
||||
+} |
||||
static const command_rec cgid_cmds[] = |
||||
{ |
||||
AP_INIT_TAKE1("ScriptLog", set_scriptlog, NULL, RSRC_CONF, |
||||
@@ -1033,6 +1053,10 @@ |
||||
AP_INIT_TAKE1("ScriptSock", set_script_socket, NULL, RSRC_CONF, |
||||
"the name of the socket to use for communication with " |
||||
"the cgi daemon."), |
||||
+ AP_INIT_TAKE1("CGIDScriptTimeout", set_script_timeout, NULL, RSRC_CONF | ACCESS_CONF, |
||||
+ "The amount of time to wait between successful reads from " |
||||
+ "the CGI script, in seconds."), |
||||
+ |
||||
{NULL} |
||||
}; |
||||
|
||||
@@ -1356,12 +1380,16 @@ |
||||
apr_file_t *tempsock; |
||||
struct cleanup_script_info *info; |
||||
apr_status_t rv; |
||||
+ cgid_dirconf *dc; |
||||
|
||||
if (strcmp(r->handler, CGI_MAGIC_TYPE) && strcmp(r->handler, "cgi-script")) { |
||||
return DECLINED; |
||||
} |
||||
|
||||
conf = ap_get_module_config(r->server->module_config, &cgid_module); |
||||
+ dc = ap_get_module_config(r->per_dir_config, &cgid_module); |
||||
+ |
||||
+ |
||||
is_included = !strcmp(r->protocol, "INCLUDED"); |
||||
|
||||
if ((argv0 = strrchr(r->filename, '/')) != NULL) { |
||||
@@ -1441,6 +1469,12 @@ |
||||
*/ |
||||
|
||||
apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool); |
||||
+ if (dc->timeout > 0) { |
||||
+ apr_file_pipe_timeout_set(tempsock, dc->timeout); |
||||
+ } |
||||
+ else { |
||||
+ apr_file_pipe_timeout_set(tempsock, r->server->timeout); |
||||
+ } |
||||
apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket); |
||||
|
||||
/* Transfer any put/post args, CERN style... |
||||
@@ -1517,6 +1551,10 @@ |
||||
if (rv != APR_SUCCESS) { |
||||
/* silly script stopped reading, soak up remaining message */ |
||||
child_stopped_reading = 1; |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02651) |
||||
+ "Error writing request body to script %s", |
||||
+ r->filename); |
||||
+ |
||||
} |
||||
} |
||||
apr_brigade_cleanup(bb); |
||||
@@ -1610,7 +1648,13 @@ |
||||
return HTTP_MOVED_TEMPORARILY; |
||||
} |
||||
|
||||
- ap_pass_brigade(r->output_filters, bb); |
||||
+ rv = ap_pass_brigade(r->output_filters, bb); |
||||
+ if (rv != APR_SUCCESS) { |
||||
+ /* APLOG_ERR because the core output filter message is at error, |
||||
+ * but doesn't know it's passing CGI output |
||||
+ */ |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02550) "Failed to flush CGI output to client"); |
||||
+ } |
||||
} |
||||
|
||||
if (nph) { |
||||
@@ -1741,6 +1785,8 @@ |
||||
request_rec *r = f->r; |
||||
cgid_server_conf *conf = ap_get_module_config(r->server->module_config, |
||||
&cgid_module); |
||||
+ cgid_dirconf *dc = ap_get_module_config(r->per_dir_config, &cgid_module); |
||||
+ |
||||
struct cleanup_script_info *info; |
||||
|
||||
add_ssi_vars(r); |
||||
@@ -1770,6 +1816,13 @@ |
||||
* get rid of the cleanup we registered when we created the socket. |
||||
*/ |
||||
apr_os_pipe_put_ex(&tempsock, &sd, 1, r->pool); |
||||
+ if (dc->timeout > 0) { |
||||
+ apr_file_pipe_timeout_set(tempsock, dc->timeout); |
||||
+ } |
||||
+ else { |
||||
+ apr_file_pipe_timeout_set(tempsock, r->server->timeout); |
||||
+ } |
||||
+ |
||||
apr_pool_cleanup_kill(r->pool, (void *)((long)sd), close_unix_socket); |
||||
|
||||
APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_pipe_create(tempsock, |
||||
@@ -1875,7 +1928,7 @@ |
||||
|
||||
AP_DECLARE_MODULE(cgid) = { |
||||
STANDARD20_MODULE_STUFF, |
||||
- NULL, /* dir config creater */ |
||||
+ create_cgid_dirconf, /* dir config creater */ |
||||
NULL, /* dir merger --- default is to override */ |
||||
create_cgid_config, /* server config */ |
||||
merge_cgid_config, /* merge server config */ |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
diff --git a/modules/cache/cache_util.c b/modules/cache/cache_util.c |
||||
index 7b7fb45..fbebb1e 100644 |
||||
--- a/modules/cache/cache_util.c |
||||
+++ b/modules/cache/cache_util.c |
||||
@@ -1251,8 +1251,10 @@ CACHE_DECLARE(apr_table_t *)ap_cache_cacheable_headers_out(request_rec *r) |
||||
|
||||
if (!apr_table_get(headers_out, "Content-Type") |
||||
&& r->content_type) { |
||||
- apr_table_setn(headers_out, "Content-Type", |
||||
- ap_make_content_type(r, r->content_type)); |
||||
+ const char *ctype = ap_make_content_type(r, r->content_type); |
||||
+ if (ctype) { |
||||
+ apr_table_setn(headers_out, "Content-Type", ctype); |
||||
+ } |
||||
} |
||||
|
||||
if (!apr_table_get(headers_out, "Content-Encoding") |
@ -0,0 +1,982 @@
@@ -0,0 +1,982 @@
|
||||
diff --git a/include/http_protocol.h b/include/http_protocol.h |
||||
index 415270b..67fa02f 100644 |
||||
--- a/include/http_protocol.h |
||||
+++ b/include/http_protocol.h |
||||
@@ -502,6 +502,23 @@ AP_DECLARE(int) ap_should_client_block(request_rec *r); |
||||
*/ |
||||
AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, apr_size_t bufsiz); |
||||
|
||||
+/* |
||||
+ * Map specific APR codes returned by the filter stack to HTTP error |
||||
+ * codes, or the default status code provided. Use it as follows: |
||||
+ * |
||||
+ * return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); |
||||
+ * |
||||
+ * If the filter has already handled the error, AP_FILTER_ERROR will |
||||
+ * be returned, which is cleanly passed through. |
||||
+ * |
||||
+ * These mappings imply that the filter stack is reading from the |
||||
+ * downstream client, the proxy will map these codes differently. |
||||
+ * @param rv APR status code |
||||
+ * @param status Default HTTP code should the APR code not be recognised |
||||
+ * @return Mapped HTTP status code |
||||
+ */ |
||||
+AP_DECLARE(int) ap_map_http_request_error(apr_status_t rv, int status); |
||||
+ |
||||
/** |
||||
* In HTTP/1.1, any method can have a body. However, most GET handlers |
||||
* wouldn't know what to do with a request body if they received one. |
||||
diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c |
||||
index 1dde402..ed8749f 100644 |
||||
--- a/modules/http/http_filters.c |
||||
+++ b/modules/http/http_filters.c |
||||
@@ -57,24 +57,29 @@ |
||||
|
||||
APLOG_USE_MODULE(http); |
||||
|
||||
-#define INVALID_CHAR -2 |
||||
- |
||||
-static long get_chunk_size(char *); |
||||
- |
||||
-typedef struct http_filter_ctx { |
||||
+typedef struct http_filter_ctx |
||||
+{ |
||||
apr_off_t remaining; |
||||
apr_off_t limit; |
||||
apr_off_t limit_used; |
||||
- enum { |
||||
- BODY_NONE, |
||||
- BODY_LENGTH, |
||||
- BODY_CHUNK, |
||||
- BODY_CHUNK_PART |
||||
+ apr_int32_t chunk_used; |
||||
+ apr_int32_t chunk_bws; |
||||
+ apr_int32_t chunkbits; |
||||
+ enum |
||||
+ { |
||||
+ BODY_NONE, /* streamed data */ |
||||
+ BODY_LENGTH, /* data constrained by content length */ |
||||
+ BODY_CHUNK, /* chunk expected */ |
||||
+ BODY_CHUNK_PART, /* chunk digits */ |
||||
+ BODY_CHUNK_EXT, /* chunk extension */ |
||||
+ BODY_CHUNK_CR, /* got space(s) after digits, expect [CR]LF or ext */ |
||||
+ BODY_CHUNK_LF, /* got CR after digits or ext, expect LF */ |
||||
+ BODY_CHUNK_DATA, /* data constrained by chunked encoding */ |
||||
+ BODY_CHUNK_END, /* chunked data terminating CRLF */ |
||||
+ BODY_CHUNK_END_LF, /* got CR after data, expect LF */ |
||||
+ BODY_CHUNK_TRAILER /* trailers */ |
||||
} state; |
||||
- int eos_sent; |
||||
- char chunk_ln[32]; |
||||
- char *pos; |
||||
- apr_off_t linesize; |
||||
+ unsigned int eos_sent :1; |
||||
apr_bucket_brigade *bb; |
||||
} http_ctx_t; |
||||
|
||||
@@ -87,6 +92,23 @@ static apr_status_t bail_out_on_error(http_ctx_t *ctx, |
||||
apr_bucket_brigade *bb = ctx->bb; |
||||
|
||||
apr_brigade_cleanup(bb); |
||||
+ |
||||
+ if (f->r->proxyreq == PROXYREQ_RESPONSE) { |
||||
+ switch (http_error) { |
||||
+ case HTTP_REQUEST_ENTITY_TOO_LARGE: |
||||
+ return APR_ENOSPC; |
||||
+ |
||||
+ case HTTP_REQUEST_TIME_OUT: |
||||
+ return APR_INCOMPLETE; |
||||
+ |
||||
+ case HTTP_NOT_IMPLEMENTED: |
||||
+ return APR_ENOTIMPL; |
||||
+ |
||||
+ default: |
||||
+ return APR_EGENERAL; |
||||
+ } |
||||
+ } |
||||
+ |
||||
e = ap_bucket_error_create(http_error, |
||||
NULL, f->r->pool, |
||||
f->c->bucket_alloc); |
||||
@@ -102,117 +124,154 @@ static apr_status_t bail_out_on_error(http_ctx_t *ctx, |
||||
return ap_pass_brigade(f->r->output_filters, bb); |
||||
} |
||||
|
||||
-static apr_status_t get_remaining_chunk_line(http_ctx_t *ctx, |
||||
- apr_bucket_brigade *b, |
||||
- int linelimit) |
||||
+/** |
||||
+ * Parse a chunk line with optional extension, detect overflow. |
||||
+ * There are two error cases: |
||||
+ * 1) If the conversion would require too many bits, APR_EGENERAL is returned. |
||||
+ * 2) If the conversion used the correct number of bits, but an overflow |
||||
+ * caused only the sign bit to flip, then APR_ENOSPC is returned. |
||||
+ * In general, any negative number can be considered an overflow error. |
||||
+ */ |
||||
+static apr_status_t parse_chunk_size(http_ctx_t *ctx, const char *buffer, |
||||
+ apr_size_t len, int linelimit) |
||||
{ |
||||
- apr_status_t rv; |
||||
- apr_off_t brigade_length; |
||||
- apr_bucket *e; |
||||
- const char *lineend; |
||||
- apr_size_t len = 0; |
||||
+ apr_size_t i = 0; |
||||
|
||||
- /* |
||||
- * As the brigade b should have been requested in mode AP_MODE_GETLINE |
||||
- * all buckets in this brigade are already some type of memory |
||||
- * buckets (due to the needed scanning for LF in mode AP_MODE_GETLINE) |
||||
- * or META buckets. |
||||
- */ |
||||
- rv = apr_brigade_length(b, 0, &brigade_length); |
||||
- if (rv != APR_SUCCESS) { |
||||
- return rv; |
||||
- } |
||||
- /* Sanity check. Should never happen. See above. */ |
||||
- if (brigade_length == -1) { |
||||
- return APR_EGENERAL; |
||||
- } |
||||
- if (!brigade_length) { |
||||
- return APR_EAGAIN; |
||||
- } |
||||
- ctx->linesize += brigade_length; |
||||
- if (ctx->linesize > linelimit) { |
||||
- return APR_ENOSPC; |
||||
- } |
||||
- /* |
||||
- * As all buckets are already some type of memory buckets or META buckets |
||||
- * (see above), we only need to check the last byte in the last data bucket. |
||||
- */ |
||||
- for (e = APR_BRIGADE_LAST(b); |
||||
- e != APR_BRIGADE_SENTINEL(b); |
||||
- e = APR_BUCKET_PREV(e)) { |
||||
+ while (i < len) { |
||||
+ char c = buffer[i]; |
||||
+ |
||||
+ ap_xlate_proto_from_ascii(&c, 1); |
||||
|
||||
- if (APR_BUCKET_IS_METADATA(e)) { |
||||
+ /* handle CRLF after the chunk */ |
||||
+ if (ctx->state == BODY_CHUNK_END |
||||
+ || ctx->state == BODY_CHUNK_END_LF) { |
||||
+ if (c == LF) { |
||||
+ ctx->state = BODY_CHUNK; |
||||
+ } |
||||
+ else if (c == CR && ctx->state == BODY_CHUNK_END) { |
||||
+ ctx->state = BODY_CHUNK_END_LF; |
||||
+ } |
||||
+ else { |
||||
+ /* |
||||
+ * LF expected. |
||||
+ */ |
||||
+ return APR_EINVAL; |
||||
+ } |
||||
+ i++; |
||||
continue; |
||||
} |
||||
- rv = apr_bucket_read(e, &lineend, &len, APR_BLOCK_READ); |
||||
- if (rv != APR_SUCCESS) { |
||||
- return rv; |
||||
+ |
||||
+ /* handle start of the chunk */ |
||||
+ if (ctx->state == BODY_CHUNK) { |
||||
+ if (!apr_isxdigit(c)) { |
||||
+ /* |
||||
+ * Detect invalid character at beginning. This also works for |
||||
+ * empty chunk size lines. |
||||
+ */ |
||||
+ return APR_EINVAL; |
||||
+ } |
||||
+ else { |
||||
+ ctx->state = BODY_CHUNK_PART; |
||||
+ } |
||||
+ ctx->remaining = 0; |
||||
+ ctx->chunkbits = sizeof(apr_off_t) * 8; |
||||
+ ctx->chunk_used = 0; |
||||
+ ctx->chunk_bws = 0; |
||||
} |
||||
- if (len > 0) { |
||||
- break; /* we got the data we want */ |
||||
+ |
||||
+ if (c == LF) { |
||||
+ if (ctx->remaining) { |
||||
+ ctx->state = BODY_CHUNK_DATA; |
||||
+ } |
||||
+ else { |
||||
+ ctx->state = BODY_CHUNK_TRAILER; |
||||
+ } |
||||
} |
||||
- /* If we got a zero-length data bucket, we try the next one */ |
||||
- } |
||||
- /* We had no data in this brigade */ |
||||
- if (!len || e == APR_BRIGADE_SENTINEL(b)) { |
||||
- return APR_EAGAIN; |
||||
- } |
||||
- if (lineend[len - 1] != APR_ASCII_LF) { |
||||
- return APR_EAGAIN; |
||||
- } |
||||
- /* Line is complete. So reset ctx for next round. */ |
||||
- ctx->linesize = 0; |
||||
- ctx->pos = ctx->chunk_ln; |
||||
- return APR_SUCCESS; |
||||
-} |
||||
+ else if (ctx->state == BODY_CHUNK_LF) { |
||||
+ /* |
||||
+ * LF expected. |
||||
+ */ |
||||
+ return APR_EINVAL; |
||||
+ } |
||||
+ else if (c == CR) { |
||||
+ ctx->state = BODY_CHUNK_LF; |
||||
+ } |
||||
+ else if (c == ';') { |
||||
+ ctx->state = BODY_CHUNK_EXT; |
||||
+ } |
||||
+ else if (ctx->state == BODY_CHUNK_EXT) { |
||||
+ /* |
||||
+ * Control chars (but tabs) are invalid. |
||||
+ */ |
||||
+ if (c != '\t' && apr_iscntrl(c)) { |
||||
+ return APR_EINVAL; |
||||
+ } |
||||
+ } |
||||
+ else if (c == ' ' || c == '\t') { |
||||
+ /* Be lenient up to 10 BWS (term from rfc7230 - 3.2.3). |
||||
+ */ |
||||
+ ctx->state = BODY_CHUNK_CR; |
||||
+ if (++ctx->chunk_bws > 10) { |
||||
+ return APR_EINVAL; |
||||
+ } |
||||
+ } |
||||
+ else if (ctx->state == BODY_CHUNK_CR) { |
||||
+ /* |
||||
+ * ';', CR or LF expected. |
||||
+ */ |
||||
+ return APR_EINVAL; |
||||
+ } |
||||
+ else if (ctx->state == BODY_CHUNK_PART) { |
||||
+ int xvalue; |
||||
|
||||
-static apr_status_t get_chunk_line(http_ctx_t *ctx, apr_bucket_brigade *b, |
||||
- int linelimit) |
||||
-{ |
||||
- apr_size_t len; |
||||
- int tmp_len; |
||||
- apr_status_t rv; |
||||
+ /* ignore leading zeros */ |
||||
+ if (!ctx->remaining && c == '0') { |
||||
+ i++; |
||||
+ continue; |
||||
+ } |
||||
|
||||
- tmp_len = sizeof(ctx->chunk_ln) - (ctx->pos - ctx->chunk_ln) - 1; |
||||
- /* Saveguard ourselves against underflows */ |
||||
- if (tmp_len < 0) { |
||||
- len = 0; |
||||
- } |
||||
- else { |
||||
- len = (apr_size_t) tmp_len; |
||||
- } |
||||
- /* |
||||
- * Check if there is space left in ctx->chunk_ln. If not, then either |
||||
- * the chunk size is insane or we have chunk-extensions. Ignore both |
||||
- * by discarding the remaining part of the line via |
||||
- * get_remaining_chunk_line. Only bail out if the line is too long. |
||||
- */ |
||||
- if (len > 0) { |
||||
- rv = apr_brigade_flatten(b, ctx->pos, &len); |
||||
- if (rv != APR_SUCCESS) { |
||||
- return rv; |
||||
+ ctx->chunkbits -= 4; |
||||
+ if (ctx->chunkbits < 0) { |
||||
+ /* overflow */ |
||||
+ return APR_ENOSPC; |
||||
+ } |
||||
+ |
||||
+ if (c >= '0' && c <= '9') { |
||||
+ xvalue = c - '0'; |
||||
+ } |
||||
+ else if (c >= 'A' && c <= 'F') { |
||||
+ xvalue = c - 'A' + 0xa; |
||||
+ } |
||||
+ else if (c >= 'a' && c <= 'f') { |
||||
+ xvalue = c - 'a' + 0xa; |
||||
+ } |
||||
+ else { |
||||
+ /* bogus character */ |
||||
+ return APR_EINVAL; |
||||
+ } |
||||
+ |
||||
+ ctx->remaining = (ctx->remaining << 4) | xvalue; |
||||
+ if (ctx->remaining < 0) { |
||||
+ /* overflow */ |
||||
+ return APR_ENOSPC; |
||||
+ } |
||||
} |
||||
- ctx->pos += len; |
||||
- ctx->linesize += len; |
||||
- *(ctx->pos) = '\0'; |
||||
- /* |
||||
- * Check if we really got a full line. If yes the |
||||
- * last char in the just read buffer must be LF. |
||||
- * If not advance the buffer and return APR_EAGAIN. |
||||
- * We do not start processing until we have the |
||||
- * full line. |
||||
- */ |
||||
- if (ctx->pos[-1] != APR_ASCII_LF) { |
||||
- /* Check if the remaining data in the brigade has the LF */ |
||||
- return get_remaining_chunk_line(ctx, b, linelimit); |
||||
+ else { |
||||
+ /* Should not happen */ |
||||
+ return APR_EGENERAL; |
||||
} |
||||
- /* Line is complete. So reset ctx->pos for next round. */ |
||||
- ctx->pos = ctx->chunk_ln; |
||||
- return APR_SUCCESS; |
||||
+ |
||||
+ i++; |
||||
} |
||||
- return get_remaining_chunk_line(ctx, b, linelimit); |
||||
-} |
||||
|
||||
+ /* sanity check */ |
||||
+ ctx->chunk_used += len; |
||||
+ if (ctx->chunk_used < 0 || ctx->chunk_used > linelimit) { |
||||
+ return APR_ENOSPC; |
||||
+ } |
||||
+ |
||||
+ return APR_SUCCESS; |
||||
+} |
||||
|
||||
static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f, |
||||
apr_bucket_brigade *b, int merge) |
||||
@@ -226,7 +285,6 @@ static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f, |
||||
r->status = HTTP_OK; |
||||
r->headers_in = r->trailers_in; |
||||
apr_table_clear(r->headers_in); |
||||
- ctx->state = BODY_NONE; |
||||
ap_get_mime_headers(r); |
||||
|
||||
if(r->status == HTTP_OK) { |
||||
@@ -239,7 +297,7 @@ static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f, |
||||
else { |
||||
const char *error_notes = apr_table_get(r->notes, |
||||
"error-notes"); |
||||
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02656) |
||||
"Error while reading HTTP trailer: %i%s%s", |
||||
r->status, error_notes ? ": " : "", |
||||
error_notes ? error_notes : ""); |
||||
@@ -270,9 +328,9 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, |
||||
apr_bucket *e; |
||||
http_ctx_t *ctx = f->ctx; |
||||
apr_status_t rv; |
||||
- apr_off_t totalread; |
||||
int http_error = HTTP_REQUEST_ENTITY_TOO_LARGE; |
||||
apr_bucket_brigade *bb; |
||||
+ int again; |
||||
|
||||
conf = (core_server_config *) |
||||
ap_get_module_config(f->r->server->module_config, &core_module); |
||||
@@ -286,7 +344,6 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, |
||||
const char *tenc, *lenp; |
||||
f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx)); |
||||
ctx->state = BODY_NONE; |
||||
- ctx->pos = ctx->chunk_ln; |
||||
ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc); |
||||
bb = ctx->bb; |
||||
|
||||
@@ -306,25 +363,33 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, |
||||
lenp = apr_table_get(f->r->headers_in, "Content-Length"); |
||||
|
||||
if (tenc) { |
||||
- if (!strcasecmp(tenc, "chunked")) { |
||||
+ if (strcasecmp(tenc, "chunked") == 0 /* fast path */ |
||||
+ || ap_find_last_token(f->r->pool, tenc, "chunked")) { |
||||
ctx->state = BODY_CHUNK; |
||||
} |
||||
- /* test lenp, because it gives another case we can handle */ |
||||
- else if (!lenp) { |
||||
- /* Something that isn't in HTTP, unless some future |
||||
+ else if (f->r->proxyreq == PROXYREQ_RESPONSE) { |
||||
+ /* http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-23 |
||||
+ * Section 3.3.3.3: "If a Transfer-Encoding header field is |
||||
+ * present in a response and the chunked transfer coding is not |
||||
+ * the final encoding, the message body length is determined by |
||||
+ * reading the connection until it is closed by the server." |
||||
+ */ |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(02555) |
||||
+ "Unknown Transfer-Encoding: %s; " |
||||
+ "using read-until-close", tenc); |
||||
+ tenc = NULL; |
||||
+ } |
||||
+ else { |
||||
+ /* Something that isn't a HTTP request, unless some future |
||||
* edition defines new transfer encodings, is unsupported. |
||||
*/ |
||||
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01585) |
||||
"Unknown Transfer-Encoding: %s", tenc); |
||||
- return bail_out_on_error(ctx, f, HTTP_NOT_IMPLEMENTED); |
||||
- } |
||||
- else { |
||||
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, f->r, APLOGNO(01586) |
||||
- "Unknown Transfer-Encoding: %s; using Content-Length", tenc); |
||||
- tenc = NULL; |
||||
+ return bail_out_on_error(ctx, f, HTTP_BAD_REQUEST); |
||||
} |
||||
+ lenp = NULL; |
||||
} |
||||
- if (lenp && !tenc) { |
||||
+ if (lenp) { |
||||
char *endstr; |
||||
|
||||
ctx->state = BODY_LENGTH; |
||||
@@ -339,7 +404,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, |
||||
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01587) |
||||
"Invalid Content-Length"); |
||||
|
||||
- return bail_out_on_error(ctx, f, HTTP_REQUEST_ENTITY_TOO_LARGE); |
||||
+ return bail_out_on_error(ctx, f, HTTP_BAD_REQUEST); |
||||
} |
||||
|
||||
/* If we have a limit in effect and we know the C-L ahead of |
||||
@@ -381,7 +446,8 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, |
||||
if (!ap_is_HTTP_SUCCESS(f->r->status)) { |
||||
ctx->state = BODY_NONE; |
||||
ctx->eos_sent = 1; |
||||
- } else { |
||||
+ } |
||||
+ else { |
||||
char *tmp; |
||||
int len; |
||||
|
||||
@@ -389,7 +455,7 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, |
||||
* in a state of expecting one. |
||||
*/ |
||||
f->r->expecting_100 = 0; |
||||
- tmp = apr_pstrcat(f->r->pool, AP_SERVER_PROTOCOL, " ", |
||||
+ tmp = apr_pstrcat(f->r->pool, AP_SERVER_PROTOCOL " ", |
||||
ap_get_status_line(HTTP_CONTINUE), CRLF CRLF, |
||||
NULL); |
||||
len = strlen(tmp); |
||||
@@ -401,279 +467,205 @@ apr_status_t ap_http_filter(ap_filter_t *f, apr_bucket_brigade *b, |
||||
e = apr_bucket_flush_create(f->c->bucket_alloc); |
||||
APR_BRIGADE_INSERT_TAIL(bb, e); |
||||
|
||||
- ap_pass_brigade(f->c->output_filters, bb); |
||||
- } |
||||
- } |
||||
- |
||||
- /* We can't read the chunk until after sending 100 if required. */ |
||||
- if (ctx->state == BODY_CHUNK) { |
||||
- apr_brigade_cleanup(bb); |
||||
- |
||||
- rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, |
||||
- block, 0); |
||||
- |
||||
- /* for timeout */ |
||||
- if (block == APR_NONBLOCK_READ && |
||||
- ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) || |
||||
- (APR_STATUS_IS_EAGAIN(rv)) )) { |
||||
- ctx->state = BODY_CHUNK_PART; |
||||
- return APR_EAGAIN; |
||||
- } |
||||
- |
||||
- if (rv == APR_SUCCESS) { |
||||
- rv = get_chunk_line(ctx, bb, f->r->server->limit_req_line); |
||||
- if (APR_STATUS_IS_EAGAIN(rv)) { |
||||
- apr_brigade_cleanup(bb); |
||||
- ctx->state = BODY_CHUNK_PART; |
||||
- return rv; |
||||
- } |
||||
- if (rv == APR_SUCCESS) { |
||||
- ctx->remaining = get_chunk_size(ctx->chunk_ln); |
||||
- if (ctx->remaining == INVALID_CHAR) { |
||||
- rv = APR_EGENERAL; |
||||
- http_error = HTTP_BAD_REQUEST; |
||||
- } |
||||
+ rv = ap_pass_brigade(f->c->output_filters, bb); |
||||
+ if (rv != APR_SUCCESS) { |
||||
+ return AP_FILTER_ERROR; |
||||
} |
||||
} |
||||
- apr_brigade_cleanup(bb); |
||||
- |
||||
- /* Detect chunksize error (such as overflow) */ |
||||
- if (rv != APR_SUCCESS || ctx->remaining < 0) { |
||||
- ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r, APLOGNO(01589) "Error reading first chunk %s ", |
||||
- (ctx->remaining < 0) ? "(overflow)" : ""); |
||||
- ctx->remaining = 0; /* Reset it in case we have to |
||||
- * come back here later */ |
||||
- if (APR_STATUS_IS_TIMEUP(rv)) { |
||||
- http_error = HTTP_REQUEST_TIME_OUT; |
||||
- } |
||||
- return bail_out_on_error(ctx, f, http_error); |
||||
- } |
||||
- |
||||
- if (!ctx->remaining) { |
||||
- return read_chunked_trailers(ctx, f, b, |
||||
- conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); |
||||
- } |
||||
} |
||||
} |
||||
- else { |
||||
- bb = ctx->bb; |
||||
- } |
||||
|
||||
+ /* sanity check in case we're read twice */ |
||||
if (ctx->eos_sent) { |
||||
e = apr_bucket_eos_create(f->c->bucket_alloc); |
||||
APR_BRIGADE_INSERT_TAIL(b, e); |
||||
return APR_SUCCESS; |
||||
} |
||||
|
||||
- if (!ctx->remaining) { |
||||
+ do { |
||||
+ apr_brigade_cleanup(b); |
||||
+ again = 0; /* until further notice */ |
||||
+ |
||||
+ /* read and handle the brigade */ |
||||
switch (ctx->state) { |
||||
- case BODY_NONE: |
||||
- break; |
||||
- case BODY_LENGTH: |
||||
- e = apr_bucket_eos_create(f->c->bucket_alloc); |
||||
- APR_BRIGADE_INSERT_TAIL(b, e); |
||||
- ctx->eos_sent = 1; |
||||
- return APR_SUCCESS; |
||||
case BODY_CHUNK: |
||||
case BODY_CHUNK_PART: |
||||
- { |
||||
- apr_brigade_cleanup(bb); |
||||
+ case BODY_CHUNK_EXT: |
||||
+ case BODY_CHUNK_CR: |
||||
+ case BODY_CHUNK_LF: |
||||
+ case BODY_CHUNK_END: |
||||
+ case BODY_CHUNK_END_LF: { |
||||
|
||||
- /* We need to read the CRLF after the chunk. */ |
||||
- if (ctx->state == BODY_CHUNK) { |
||||
- rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, |
||||
- block, 0); |
||||
- if (block == APR_NONBLOCK_READ && |
||||
- ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) || |
||||
- (APR_STATUS_IS_EAGAIN(rv)) )) { |
||||
- return APR_EAGAIN; |
||||
- } |
||||
- /* If we get an error, then leave */ |
||||
- if (rv != APR_SUCCESS) { |
||||
- return rv; |
||||
- } |
||||
- /* |
||||
- * We really don't care whats on this line. If it is RFC |
||||
- * compliant it should be only \r\n. If there is more |
||||
- * before we just ignore it as long as we do not get over |
||||
- * the limit for request lines. |
||||
- */ |
||||
- rv = get_remaining_chunk_line(ctx, bb, |
||||
- f->r->server->limit_req_line); |
||||
- apr_brigade_cleanup(bb); |
||||
- if (APR_STATUS_IS_EAGAIN(rv)) { |
||||
- return rv; |
||||
- } |
||||
- } else { |
||||
- rv = APR_SUCCESS; |
||||
- } |
||||
+ rv = ap_get_brigade(f->next, b, AP_MODE_GETLINE, block, 0); |
||||
+ |
||||
+ /* for timeout */ |
||||
+ if (block == APR_NONBLOCK_READ |
||||
+ && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b)) |
||||
+ || (APR_STATUS_IS_EAGAIN(rv)))) { |
||||
+ return APR_EAGAIN; |
||||
+ } |
||||
+ |
||||
+ if (rv == APR_EOF) { |
||||
+ return APR_INCOMPLETE; |
||||
+ } |
||||
+ |
||||
+ if (rv != APR_SUCCESS) { |
||||
+ return rv; |
||||
+ } |
||||
+ |
||||
+ e = APR_BRIGADE_FIRST(b); |
||||
+ while (e != APR_BRIGADE_SENTINEL(b)) { |
||||
+ const char *buffer; |
||||
+ apr_size_t len; |
||||
+ |
||||
+ if (!APR_BUCKET_IS_METADATA(e)) { |
||||
+ int parsing = 0; |
||||
+ |
||||
+ rv = apr_bucket_read(e, &buffer, &len, APR_BLOCK_READ); |
||||
|
||||
- if (rv == APR_SUCCESS) { |
||||
- /* Read the real chunk line. */ |
||||
- rv = ap_get_brigade(f->next, bb, AP_MODE_GETLINE, |
||||
- block, 0); |
||||
- /* Test timeout */ |
||||
- if (block == APR_NONBLOCK_READ && |
||||
- ( (rv == APR_SUCCESS && APR_BRIGADE_EMPTY(bb)) || |
||||
- (APR_STATUS_IS_EAGAIN(rv)) )) { |
||||
- ctx->state = BODY_CHUNK_PART; |
||||
- return APR_EAGAIN; |
||||
- } |
||||
- ctx->state = BODY_CHUNK; |
||||
if (rv == APR_SUCCESS) { |
||||
- rv = get_chunk_line(ctx, bb, f->r->server->limit_req_line); |
||||
- if (APR_STATUS_IS_EAGAIN(rv)) { |
||||
- ctx->state = BODY_CHUNK_PART; |
||||
- apr_brigade_cleanup(bb); |
||||
- return rv; |
||||
- } |
||||
- if (rv == APR_SUCCESS) { |
||||
- ctx->remaining = get_chunk_size(ctx->chunk_ln); |
||||
- if (ctx->remaining == INVALID_CHAR) { |
||||
- rv = APR_EGENERAL; |
||||
+ parsing = 1; |
||||
+ rv = parse_chunk_size(ctx, buffer, len, |
||||
+ f->r->server->limit_req_fieldsize); |
||||
+ } |
||||
+ if (rv != APR_SUCCESS) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r, APLOGNO(01590) |
||||
+ "Error reading/parsing chunk %s ", |
||||
+ (APR_ENOSPC == rv) ? "(overflow)" : ""); |
||||
+ if (parsing) { |
||||
+ if (rv != APR_ENOSPC) { |
||||
http_error = HTTP_BAD_REQUEST; |
||||
} |
||||
+ return bail_out_on_error(ctx, f, http_error); |
||||
} |
||||
+ return rv; |
||||
} |
||||
- apr_brigade_cleanup(bb); |
||||
} |
||||
|
||||
- /* Detect chunksize error (such as overflow) */ |
||||
- if (rv != APR_SUCCESS || ctx->remaining < 0) { |
||||
- ap_log_rerror(APLOG_MARK, APLOG_INFO, rv, f->r, APLOGNO(01590) "Error reading chunk %s ", |
||||
- (ctx->remaining < 0) ? "(overflow)" : ""); |
||||
- ctx->remaining = 0; /* Reset it in case we have to |
||||
- * come back here later */ |
||||
- if (APR_STATUS_IS_TIMEUP(rv)) { |
||||
- http_error = HTTP_REQUEST_TIME_OUT; |
||||
- } |
||||
- return bail_out_on_error(ctx, f, http_error); |
||||
- } |
||||
+ apr_bucket_delete(e); |
||||
+ e = APR_BRIGADE_FIRST(b); |
||||
+ } |
||||
+ again = 1; /* come around again */ |
||||
|
||||
- if (!ctx->remaining) { |
||||
- return read_chunked_trailers(ctx, f, b, |
||||
+ if (ctx->state == BODY_CHUNK_TRAILER) { |
||||
+ /* Treat UNSET as DISABLE - trailers aren't merged by default */ |
||||
+ return read_chunked_trailers(ctx, f, b, |
||||
conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); |
||||
- } |
||||
} |
||||
+ |
||||
break; |
||||
} |
||||
- } |
||||
+ case BODY_NONE: |
||||
+ case BODY_LENGTH: |
||||
+ case BODY_CHUNK_DATA: { |
||||
|
||||
- /* Ensure that the caller can not go over our boundary point. */ |
||||
- if (ctx->state == BODY_LENGTH || ctx->state == BODY_CHUNK) { |
||||
- if (ctx->remaining < readbytes) { |
||||
- readbytes = ctx->remaining; |
||||
- } |
||||
- AP_DEBUG_ASSERT(readbytes > 0); |
||||
- } |
||||
+ /* Ensure that the caller can not go over our boundary point. */ |
||||
+ if (ctx->state != BODY_NONE && ctx->remaining < readbytes) { |
||||
+ readbytes = ctx->remaining; |
||||
+ } |
||||
+ if (readbytes > 0) { |
||||
+ apr_off_t totalread; |
||||
|
||||
- rv = ap_get_brigade(f->next, b, mode, block, readbytes); |
||||
+ rv = ap_get_brigade(f->next, b, mode, block, readbytes); |
||||
|
||||
- if (rv != APR_SUCCESS) { |
||||
- return rv; |
||||
- } |
||||
+ /* for timeout */ |
||||
+ if (block == APR_NONBLOCK_READ |
||||
+ && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b)) |
||||
+ || (APR_STATUS_IS_EAGAIN(rv)))) { |
||||
+ return APR_EAGAIN; |
||||
+ } |
||||
|
||||
- /* How many bytes did we just read? */ |
||||
- apr_brigade_length(b, 0, &totalread); |
||||
+ if (rv == APR_EOF && ctx->state != BODY_NONE |
||||
+ && ctx->remaining > 0) { |
||||
+ return APR_INCOMPLETE; |
||||
+ } |
||||
|
||||
- /* If this happens, we have a bucket of unknown length. Die because |
||||
- * it means our assumptions have changed. */ |
||||
- AP_DEBUG_ASSERT(totalread >= 0); |
||||
+ if (rv != APR_SUCCESS) { |
||||
+ return rv; |
||||
+ } |
||||
|
||||
- if (ctx->state != BODY_NONE) { |
||||
- ctx->remaining -= totalread; |
||||
- if (ctx->remaining > 0) { |
||||
- e = APR_BRIGADE_LAST(b); |
||||
- if (APR_BUCKET_IS_EOS(e)) |
||||
- return APR_EOF; |
||||
- } |
||||
- } |
||||
+ /* How many bytes did we just read? */ |
||||
+ apr_brigade_length(b, 0, &totalread); |
||||
|
||||
- /* If we have no more bytes remaining on a C-L request, |
||||
- * save the callter a roundtrip to discover EOS. |
||||
- */ |
||||
- if (ctx->state == BODY_LENGTH && ctx->remaining == 0) { |
||||
- e = apr_bucket_eos_create(f->c->bucket_alloc); |
||||
- APR_BRIGADE_INSERT_TAIL(b, e); |
||||
- } |
||||
+ /* If this happens, we have a bucket of unknown length. Die because |
||||
+ * it means our assumptions have changed. */ |
||||
+ AP_DEBUG_ASSERT(totalread >= 0); |
||||
|
||||
- /* We have a limit in effect. */ |
||||
- if (ctx->limit) { |
||||
- /* FIXME: Note that we might get slightly confused on chunked inputs |
||||
- * as we'd need to compensate for the chunk lengths which may not |
||||
- * really count. This seems to be up for interpretation. */ |
||||
- ctx->limit_used += totalread; |
||||
- if (ctx->limit < ctx->limit_used) { |
||||
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(01591) |
||||
- "Read content-length of %" APR_OFF_T_FMT |
||||
- " is larger than the configured limit" |
||||
- " of %" APR_OFF_T_FMT, ctx->limit_used, ctx->limit); |
||||
- apr_brigade_cleanup(bb); |
||||
- e = ap_bucket_error_create(HTTP_REQUEST_ENTITY_TOO_LARGE, NULL, |
||||
- f->r->pool, |
||||
- f->c->bucket_alloc); |
||||
- APR_BRIGADE_INSERT_TAIL(bb, e); |
||||
- e = apr_bucket_eos_create(f->c->bucket_alloc); |
||||
- APR_BRIGADE_INSERT_TAIL(bb, e); |
||||
- ctx->eos_sent = 1; |
||||
- return ap_pass_brigade(f->r->output_filters, bb); |
||||
- } |
||||
- } |
||||
+ if (ctx->state != BODY_NONE) { |
||||
+ ctx->remaining -= totalread; |
||||
+ if (ctx->remaining > 0) { |
||||
+ e = APR_BRIGADE_LAST(b); |
||||
+ if (APR_BUCKET_IS_EOS(e)) { |
||||
+ apr_bucket_delete(e); |
||||
+ return APR_INCOMPLETE; |
||||
+ } |
||||
+ } |
||||
+ else if (ctx->state == BODY_CHUNK_DATA) { |
||||
+ /* next chunk please */ |
||||
+ ctx->state = BODY_CHUNK_END; |
||||
+ ctx->chunk_used = 0; |
||||
+ } |
||||
+ } |
||||
|
||||
- return APR_SUCCESS; |
||||
-} |
||||
+ /* We have a limit in effect. */ |
||||
+ if (ctx->limit) { |
||||
+ /* FIXME: Note that we might get slightly confused on |
||||
+ * chunked inputs as we'd need to compensate for the chunk |
||||
+ * lengths which may not really count. This seems to be up |
||||
+ * for interpretation. |
||||
+ */ |
||||
+ ctx->limit_used += totalread; |
||||
+ if (ctx->limit < ctx->limit_used) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, |
||||
+ APLOGNO(01591) "Read content length of " |
||||
+ "%" APR_OFF_T_FMT " is larger than the " |
||||
+ "configured limit of %" APR_OFF_T_FMT, |
||||
+ ctx->limit_used, ctx->limit); |
||||
+ return bail_out_on_error(ctx, f, |
||||
+ HTTP_REQUEST_ENTITY_TOO_LARGE); |
||||
+ } |
||||
+ } |
||||
+ } |
||||
|
||||
-/** |
||||
- * Parse a chunk extension, detect overflow. |
||||
- * There are two error cases: |
||||
- * 1) If the conversion would require too many bits, a -1 is returned. |
||||
- * 2) If the conversion used the correct number of bits, but an overflow |
||||
- * caused only the sign bit to flip, then that negative number is |
||||
- * returned. |
||||
- * In general, any negative number can be considered an overflow error. |
||||
- */ |
||||
-static long get_chunk_size(char *b) |
||||
-{ |
||||
- long chunksize = 0; |
||||
- size_t chunkbits = sizeof(long) * 8; |
||||
+ /* If we have no more bytes remaining on a C-L request, |
||||
+ * save the caller a round trip to discover EOS. |
||||
+ */ |
||||
+ if (ctx->state == BODY_LENGTH && ctx->remaining == 0) { |
||||
+ e = apr_bucket_eos_create(f->c->bucket_alloc); |
||||
+ APR_BRIGADE_INSERT_TAIL(b, e); |
||||
+ ctx->eos_sent = 1; |
||||
+ } |
||||
|
||||
- ap_xlate_proto_from_ascii(b, strlen(b)); |
||||
+ break; |
||||
+ } |
||||
+ case BODY_CHUNK_TRAILER: { |
||||
|
||||
- if (!apr_isxdigit(*b)) { |
||||
- /* |
||||
- * Detect invalid character at beginning. This also works for empty |
||||
- * chunk size lines. |
||||
- */ |
||||
- return INVALID_CHAR; |
||||
- } |
||||
- /* Skip leading zeros */ |
||||
- while (*b == '0') { |
||||
- ++b; |
||||
- } |
||||
+ rv = ap_get_brigade(f->next, b, mode, block, readbytes); |
||||
|
||||
- while (apr_isxdigit(*b) && (chunkbits > 0)) { |
||||
- int xvalue = 0; |
||||
+ /* for timeout */ |
||||
+ if (block == APR_NONBLOCK_READ |
||||
+ && ((rv == APR_SUCCESS && APR_BRIGADE_EMPTY(b)) |
||||
+ || (APR_STATUS_IS_EAGAIN(rv)))) { |
||||
+ return APR_EAGAIN; |
||||
+ } |
||||
+ |
||||
+ if (rv != APR_SUCCESS) { |
||||
+ return rv; |
||||
+ } |
||||
|
||||
- if (*b >= '0' && *b <= '9') { |
||||
- xvalue = *b - '0'; |
||||
+ break; |
||||
} |
||||
- else if (*b >= 'A' && *b <= 'F') { |
||||
- xvalue = *b - 'A' + 0xa; |
||||
+ default: { |
||||
+ /* Should not happen */ |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, f->r, APLOGNO(02901) |
||||
+ "Unexpected body state (%i)", (int)ctx->state); |
||||
+ return APR_EGENERAL; |
||||
} |
||||
- else if (*b >= 'a' && *b <= 'f') { |
||||
- xvalue = *b - 'a' + 0xa; |
||||
} |
||||
|
||||
- chunksize = (chunksize << 4) | xvalue; |
||||
- chunkbits -= 4; |
||||
- ++b; |
||||
- } |
||||
- if (apr_isxdigit(*b)) { |
||||
- /* overflow */ |
||||
- return -1; |
||||
- } |
||||
+ } while (again); |
||||
|
||||
- return chunksize; |
||||
+ return APR_SUCCESS; |
||||
} |
||||
|
||||
typedef struct header_struct { |
||||
@@ -1385,6 +1377,39 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, |
||||
return ap_pass_brigade(f->next, b); |
||||
} |
||||
|
||||
+/* |
||||
+ * Map specific APR codes returned by the filter stack to HTTP error |
||||
+ * codes, or the default status code provided. Use it as follows: |
||||
+ * |
||||
+ * return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); |
||||
+ * |
||||
+ * If the filter has already handled the error, AP_FILTER_ERROR will |
||||
+ * be returned, which is cleanly passed through. |
||||
+ * |
||||
+ * These mappings imply that the filter stack is reading from the |
||||
+ * downstream client, the proxy will map these codes differently. |
||||
+ */ |
||||
+AP_DECLARE(int) ap_map_http_request_error(apr_status_t rv, int status) |
||||
+{ |
||||
+ switch (rv) { |
||||
+ case AP_FILTER_ERROR: { |
||||
+ return AP_FILTER_ERROR; |
||||
+ } |
||||
+ case APR_ENOSPC: { |
||||
+ return HTTP_REQUEST_ENTITY_TOO_LARGE; |
||||
+ } |
||||
+ case APR_ENOTIMPL: { |
||||
+ return HTTP_NOT_IMPLEMENTED; |
||||
+ } |
||||
+ case APR_ETIMEDOUT: { |
||||
+ return HTTP_REQUEST_TIME_OUT; |
||||
+ } |
||||
+ default: { |
||||
+ return status; |
||||
+ } |
||||
+ } |
||||
+} |
||||
+ |
||||
/* In HTTP/1.1, any method can have a body. However, most GET handlers |
||||
* wouldn't know what to do with a request body if they received one. |
||||
* This helper routine tests for and reads any message body in the request, |
||||
@@ -1402,7 +1427,8 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f, |
||||
AP_DECLARE(int) ap_discard_request_body(request_rec *r) |
||||
{ |
||||
apr_bucket_brigade *bb; |
||||
- int rv, seen_eos; |
||||
+ int seen_eos; |
||||
+ apr_status_t rv; |
||||
|
||||
/* Sometimes we'll get in a state where the input handling has |
||||
* detected an error where we want to drop the connection, so if |
||||
@@ -1425,21 +1451,8 @@ AP_DECLARE(int) ap_discard_request_body(request_rec *r) |
||||
APR_BLOCK_READ, HUGE_STRING_LEN); |
||||
|
||||
if (rv != APR_SUCCESS) { |
||||
- /* FIXME: If we ever have a mapping from filters (apr_status_t) |
||||
- * to HTTP error codes, this would be a good place for them. |
||||
- * |
||||
- * If we received the special case AP_FILTER_ERROR, it means |
||||
- * that the filters have already handled this error. |
||||
- * Otherwise, we should assume we have a bad request. |
||||
- */ |
||||
- if (rv == AP_FILTER_ERROR) { |
||||
- apr_brigade_destroy(bb); |
||||
- return rv; |
||||
- } |
||||
- else { |
||||
- apr_brigade_destroy(bb); |
||||
- return HTTP_BAD_REQUEST; |
||||
- } |
||||
+ apr_brigade_destroy(bb); |
||||
+ return ap_map_http_request_error(rv, HTTP_BAD_REQUEST); |
||||
} |
||||
|
||||
for (bucket = APR_BRIGADE_FIRST(bb); |
||||
@@ -1608,6 +1621,13 @@ AP_DECLARE(long) ap_get_client_block(request_rec *r, char *buffer, |
||||
/* We lose the failure code here. This is why ap_get_client_block should |
||||
* not be used. |
||||
*/ |
||||
+ if (rv == AP_FILTER_ERROR) { |
||||
+ /* AP_FILTER_ERROR means a filter has responded already, |
||||
+ * we are DONE. |
||||
+ */ |
||||
+ apr_brigade_destroy(bb); |
||||
+ return -1; |
||||
+ } |
||||
if (rv != APR_SUCCESS) { |
||||
/* if we actually fail here, we want to just return and |
||||
* stop trying to read data from the client. |
@ -0,0 +1,175 @@
@@ -0,0 +1,175 @@
|
||||
Index: server/request.c |
||||
=================================================================== |
||||
--- a/server/request.c (revision 1684524) |
||||
+++ b/server/request.c (revision 1684525) |
||||
@@ -71,6 +71,7 @@ |
||||
APR_HOOK_LINK(create_request) |
||||
APR_HOOK_LINK(post_perdir_config) |
||||
APR_HOOK_LINK(dirwalk_stat) |
||||
+ APR_HOOK_LINK(force_authn) |
||||
) |
||||
|
||||
AP_IMPLEMENT_HOOK_RUN_FIRST(int,translate_name, |
||||
@@ -97,6 +98,8 @@ |
||||
AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t,dirwalk_stat, |
||||
(apr_finfo_t *finfo, request_rec *r, apr_int32_t wanted), |
||||
(finfo, r, wanted), AP_DECLINED) |
||||
+AP_IMPLEMENT_HOOK_RUN_FIRST(int,force_authn, |
||||
+ (request_rec *r), (r), DECLINED) |
||||
|
||||
static int auth_internal_per_conf = 0; |
||||
static int auth_internal_per_conf_hooks = 0; |
||||
@@ -118,6 +121,39 @@ |
||||
} |
||||
} |
||||
|
||||
+AP_DECLARE(int) ap_some_authn_required(request_rec *r) |
||||
+{ |
||||
+ int access_status; |
||||
+ |
||||
+ switch (ap_satisfies(r)) { |
||||
+ case SATISFY_ALL: |
||||
+ case SATISFY_NOSPEC: |
||||
+ if ((access_status = ap_run_access_checker(r)) != OK) { |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ access_status = ap_run_access_checker_ex(r); |
||||
+ if (access_status == DECLINED) { |
||||
+ return TRUE; |
||||
+ } |
||||
+ |
||||
+ break; |
||||
+ case SATISFY_ANY: |
||||
+ if ((access_status = ap_run_access_checker(r)) == OK) { |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ access_status = ap_run_access_checker_ex(r); |
||||
+ if (access_status == DECLINED) { |
||||
+ return TRUE; |
||||
+ } |
||||
+ |
||||
+ break; |
||||
+ } |
||||
+ |
||||
+ return FALSE; |
||||
+} |
||||
+ |
||||
/* This is the master logic for processing requests. Do NOT duplicate |
||||
* this logic elsewhere, or the security model will be broken by future |
||||
* API changes. Each phase must be individually optimized to pick up |
||||
@@ -232,15 +268,8 @@ |
||||
} |
||||
|
||||
access_status = ap_run_access_checker_ex(r); |
||||
- if (access_status == OK) { |
||||
- ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, |
||||
- "request authorized without authentication by " |
||||
- "access_checker_ex hook: %s", r->uri); |
||||
- } |
||||
- else if (access_status != DECLINED) { |
||||
- return decl_die(access_status, "check access", r); |
||||
- } |
||||
- else { |
||||
+ if (access_status == DECLINED |
||||
+ || (access_status == OK && ap_run_force_authn(r) == OK)) { |
||||
if ((access_status = ap_run_check_user_id(r)) != OK) { |
||||
return decl_die(access_status, "check user", r); |
||||
} |
||||
@@ -258,6 +287,14 @@ |
||||
return decl_die(access_status, "check authorization", r); |
||||
} |
||||
} |
||||
+ else if (access_status == OK) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, |
||||
+ "request authorized without authentication by " |
||||
+ "access_checker_ex hook: %s", r->uri); |
||||
+ } |
||||
+ else { |
||||
+ return decl_die(access_status, "check access", r); |
||||
+ } |
||||
break; |
||||
case SATISFY_ANY: |
||||
if ((access_status = ap_run_access_checker(r)) == OK) { |
||||
@@ -269,15 +306,8 @@ |
||||
} |
||||
|
||||
access_status = ap_run_access_checker_ex(r); |
||||
- if (access_status == OK) { |
||||
- ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, |
||||
- "request authorized without authentication by " |
||||
- "access_checker_ex hook: %s", r->uri); |
||||
- } |
||||
- else if (access_status != DECLINED) { |
||||
- return decl_die(access_status, "check access", r); |
||||
- } |
||||
- else { |
||||
+ if (access_status == DECLINED |
||||
+ || (access_status == OK && ap_run_force_authn(r) == OK)) { |
||||
if ((access_status = ap_run_check_user_id(r)) != OK) { |
||||
return decl_die(access_status, "check user", r); |
||||
} |
||||
@@ -295,6 +325,14 @@ |
||||
return decl_die(access_status, "check authorization", r); |
||||
} |
||||
} |
||||
+ else if (access_status == OK) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r, |
||||
+ "request authorized without authentication by " |
||||
+ "access_checker_ex hook: %s", r->uri); |
||||
+ } |
||||
+ else { |
||||
+ return decl_die(access_status, "check access", r); |
||||
+ } |
||||
break; |
||||
} |
||||
} |
||||
Index: include/http_request.h |
||||
=================================================================== |
||||
--- a/include/http_request.h (revision 1684524) |
||||
+++ b/include/http_request.h (revision 1684525) |
||||
@@ -185,6 +185,8 @@ |
||||
* is required for the current request |
||||
* @param r The current request |
||||
* @return 1 if authentication is required, 0 otherwise |
||||
+ * @bug Behavior changed in 2.4.x refactoring, API no longer usable |
||||
+ * @deprecated @see ap_some_authn_required() |
||||
*/ |
||||
AP_DECLARE(int) ap_some_auth_required(request_rec *r); |
||||
|
||||
@@ -539,6 +541,16 @@ |
||||
AP_DECLARE_HOOK(int,post_perdir_config,(request_rec *r)) |
||||
|
||||
/** |
||||
+ * This hook allows a module to force authn to be required when |
||||
+ * processing a request. |
||||
+ * This hook should be registered with ap_hook_force_authn(). |
||||
+ * @param r The current request |
||||
+ * @return OK (force authn), DECLINED (let later modules decide) |
||||
+ * @ingroup hooks |
||||
+ */ |
||||
+AP_DECLARE_HOOK(int,force_authn,(request_rec *r)) |
||||
+ |
||||
+/** |
||||
* This hook allows modules to handle/emulate the apr_stat() calls |
||||
* needed for directory walk. |
||||
* @param r The current request |
||||
@@ -584,6 +596,17 @@ |
||||
AP_DECLARE(apr_bucket *) ap_bucket_eor_create(apr_bucket_alloc_t *list, |
||||
request_rec *r); |
||||
|
||||
+/** |
||||
+ * Can be used within any handler to determine if any authentication |
||||
+ * is required for the current request. Note that if used with an |
||||
+ * access_checker hook, an access_checker_ex hook or an authz provider; the |
||||
+ * caller should take steps to avoid a loop since this function is |
||||
+ * implemented by calling these hooks. |
||||
+ * @param r The current request |
||||
+ * @return TRUE if authentication is required, FALSE otherwise |
||||
+ */ |
||||
+AP_DECLARE(int) ap_some_authn_required(request_rec *r); |
||||
+ |
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
@ -0,0 +1,325 @@
@@ -0,0 +1,325 @@
|
||||
diff --git a/modules/session/mod_session_crypto.c b/modules/session/mod_session_crypto.c |
||||
index 4d65bb8..9231a5e 100644 |
||||
--- a/modules/session/mod_session_crypto.c |
||||
+++ b/modules/session/mod_session_crypto.c |
||||
@@ -18,6 +18,7 @@ |
||||
#include "apu_version.h" |
||||
#include "apr_base64.h" /* for apr_base64_decode et al */ |
||||
#include "apr_lib.h" |
||||
+#include "apr_md5.h" |
||||
#include "apr_strings.h" |
||||
#include "http_log.h" |
||||
#include "http_core.h" |
||||
@@ -57,6 +58,146 @@ typedef struct { |
||||
int library_set; |
||||
} session_crypto_conf; |
||||
|
||||
+/* Wrappers around apr_siphash24() and apr_crypto_equals(), |
||||
+ * available in APU-1.6/APR-2.0 only. |
||||
+ */ |
||||
+#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 6) |
||||
+ |
||||
+#include "apr_siphash.h" |
||||
+ |
||||
+#define AP_SIPHASH_DSIZE APR_SIPHASH_DSIZE |
||||
+#define AP_SIPHASH_KSIZE APR_SIPHASH_KSIZE |
||||
+#define ap_siphash24_auth apr_siphash24_auth |
||||
+ |
||||
+#define ap_crypto_equals apr_crypto_equals |
||||
+ |
||||
+#else |
||||
+ |
||||
+#define AP_SIPHASH_DSIZE 8 |
||||
+#define AP_SIPHASH_KSIZE 16 |
||||
+ |
||||
+#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n)))) |
||||
+ |
||||
+#define U8TO64_LE(p) \ |
||||
+ (((apr_uint64_t)((p)[0]) ) | \ |
||||
+ ((apr_uint64_t)((p)[1]) << 8) | \ |
||||
+ ((apr_uint64_t)((p)[2]) << 16) | \ |
||||
+ ((apr_uint64_t)((p)[3]) << 24) | \ |
||||
+ ((apr_uint64_t)((p)[4]) << 32) | \ |
||||
+ ((apr_uint64_t)((p)[5]) << 40) | \ |
||||
+ ((apr_uint64_t)((p)[6]) << 48) | \ |
||||
+ ((apr_uint64_t)((p)[7]) << 56)) |
||||
+ |
||||
+#define U64TO8_LE(p, v) \ |
||||
+do { \ |
||||
+ (p)[0] = (unsigned char)((v) ); \ |
||||
+ (p)[1] = (unsigned char)((v) >> 8); \ |
||||
+ (p)[2] = (unsigned char)((v) >> 16); \ |
||||
+ (p)[3] = (unsigned char)((v) >> 24); \ |
||||
+ (p)[4] = (unsigned char)((v) >> 32); \ |
||||
+ (p)[5] = (unsigned char)((v) >> 40); \ |
||||
+ (p)[6] = (unsigned char)((v) >> 48); \ |
||||
+ (p)[7] = (unsigned char)((v) >> 56); \ |
||||
+} while (0) |
||||
+ |
||||
+#define SIPROUND() \ |
||||
+do { \ |
||||
+ v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \ |
||||
+ v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \ |
||||
+ v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \ |
||||
+ v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \ |
||||
+} while(0) |
||||
+ |
||||
+static apr_uint64_t ap_siphash24(const void *src, apr_size_t len, |
||||
+ const unsigned char key[AP_SIPHASH_KSIZE]) |
||||
+{ |
||||
+ const unsigned char *ptr, *end; |
||||
+ apr_uint64_t v0, v1, v2, v3, m; |
||||
+ apr_uint64_t k0, k1; |
||||
+ unsigned int rem; |
||||
+ |
||||
+ k0 = U8TO64_LE(key + 0); |
||||
+ k1 = U8TO64_LE(key + 8); |
||||
+ v3 = k1 ^ (apr_uint64_t)0x7465646279746573ULL; |
||||
+ v2 = k0 ^ (apr_uint64_t)0x6c7967656e657261ULL; |
||||
+ v1 = k1 ^ (apr_uint64_t)0x646f72616e646f6dULL; |
||||
+ v0 = k0 ^ (apr_uint64_t)0x736f6d6570736575ULL; |
||||
+ |
||||
+ rem = (unsigned int)(len & 0x7); |
||||
+ for (ptr = src, end = ptr + len - rem; ptr < end; ptr += 8) { |
||||
+ m = U8TO64_LE(ptr); |
||||
+ v3 ^= m; |
||||
+ SIPROUND(); |
||||
+ SIPROUND(); |
||||
+ v0 ^= m; |
||||
+ } |
||||
+ m = (apr_uint64_t)(len & 0xff) << 56; |
||||
+ switch (rem) { |
||||
+ case 7: m |= (apr_uint64_t)ptr[6] << 48; |
||||
+ case 6: m |= (apr_uint64_t)ptr[5] << 40; |
||||
+ case 5: m |= (apr_uint64_t)ptr[4] << 32; |
||||
+ case 4: m |= (apr_uint64_t)ptr[3] << 24; |
||||
+ case 3: m |= (apr_uint64_t)ptr[2] << 16; |
||||
+ case 2: m |= (apr_uint64_t)ptr[1] << 8; |
||||
+ case 1: m |= (apr_uint64_t)ptr[0]; |
||||
+ case 0: break; |
||||
+ } |
||||
+ v3 ^= m; |
||||
+ SIPROUND(); |
||||
+ SIPROUND(); |
||||
+ v0 ^= m; |
||||
+ |
||||
+ v2 ^= 0xff; |
||||
+ SIPROUND(); |
||||
+ SIPROUND(); |
||||
+ SIPROUND(); |
||||
+ SIPROUND(); |
||||
+ |
||||
+ return v0 ^ v1 ^ v2 ^ v3; |
||||
+} |
||||
+ |
||||
+static void ap_siphash24_auth(unsigned char out[AP_SIPHASH_DSIZE], |
||||
+ const void *src, apr_size_t len, |
||||
+ const unsigned char key[AP_SIPHASH_KSIZE]) |
||||
+{ |
||||
+ apr_uint64_t h; |
||||
+ h = ap_siphash24(src, len, key); |
||||
+ U64TO8_LE(out, h); |
||||
+} |
||||
+ |
||||
+static int ap_crypto_equals(const void *buf1, const void *buf2, |
||||
+ apr_size_t size) |
||||
+{ |
||||
+ const unsigned char *p1 = buf1; |
||||
+ const unsigned char *p2 = buf2; |
||||
+ unsigned char diff = 0; |
||||
+ apr_size_t i; |
||||
+ |
||||
+ for (i = 0; i < size; ++i) { |
||||
+ diff |= p1[i] ^ p2[i]; |
||||
+ } |
||||
+ |
||||
+ return 1 & ((diff - 1) >> 8); |
||||
+} |
||||
+ |
||||
+#endif |
||||
+ |
||||
+static void compute_auth(const void *src, apr_size_t len, |
||||
+ const char *passphrase, apr_size_t passlen, |
||||
+ unsigned char auth[AP_SIPHASH_DSIZE]) |
||||
+{ |
||||
+ unsigned char key[APR_MD5_DIGESTSIZE]; |
||||
+ |
||||
+ /* XXX: if we had a way to get the raw bytes from an apr_crypto_key_t |
||||
+ * we could use them directly (not available in APR-1.5.x). |
||||
+ * MD5 is 128bit too, so use it to get a suitable siphash key |
||||
+ * from the passphrase. |
||||
+ */ |
||||
+ apr_md5(key, passphrase, passlen); |
||||
+ |
||||
+ ap_siphash24_auth(auth, src, len, key); |
||||
+} |
||||
+ |
||||
/** |
||||
* Initialise the encryption as per the current config. |
||||
* |
||||
@@ -128,21 +269,14 @@ static apr_status_t encrypt_string(request_rec * r, const apr_crypto_t *f, |
||||
apr_crypto_block_t *block = NULL; |
||||
unsigned char *encrypt = NULL; |
||||
unsigned char *combined = NULL; |
||||
- apr_size_t encryptlen, tlen; |
||||
+ apr_size_t encryptlen, tlen, combinedlen; |
||||
char *base64; |
||||
apr_size_t blockSize = 0; |
||||
const unsigned char *iv = NULL; |
||||
apr_uuid_t salt; |
||||
apr_crypto_block_key_type_e *cipher; |
||||
const char *passphrase; |
||||
- |
||||
- /* by default, return an empty string */ |
||||
- *out = ""; |
||||
- |
||||
- /* don't attempt to encrypt an empty string, trying to do so causes a segfault */ |
||||
- if (!in || !*in) { |
||||
- return APR_SUCCESS; |
||||
- } |
||||
+ apr_size_t passlen; |
||||
|
||||
/* use a uuid as a salt value, and prepend it to our result */ |
||||
apr_uuid_get(&salt); |
||||
@@ -152,9 +286,9 @@ static apr_status_t encrypt_string(request_rec * r, const apr_crypto_t *f, |
||||
} |
||||
|
||||
/* encrypt using the first passphrase in the list */ |
||||
- passphrase = APR_ARRAY_IDX(dconf->passphrases, 0, char *); |
||||
- res = apr_crypto_passphrase(&key, &ivSize, passphrase, |
||||
- strlen(passphrase), |
||||
+ passphrase = APR_ARRAY_IDX(dconf->passphrases, 0, const char *); |
||||
+ passlen = strlen(passphrase); |
||||
+ res = apr_crypto_passphrase(&key, &ivSize, passphrase, passlen, |
||||
(unsigned char *) (&salt), sizeof(apr_uuid_t), |
||||
*cipher, APR_MODE_CBC, 1, 4096, f, r->pool); |
||||
if (APR_STATUS_IS_ENOKEY(res)) { |
||||
@@ -183,8 +317,9 @@ static apr_status_t encrypt_string(request_rec * r, const apr_crypto_t *f, |
||||
} |
||||
|
||||
/* encrypt the given string */ |
||||
- res = apr_crypto_block_encrypt(&encrypt, &encryptlen, (unsigned char *)in, |
||||
- strlen(in), block); |
||||
+ res = apr_crypto_block_encrypt(&encrypt, &encryptlen, |
||||
+ (const unsigned char *)in, strlen(in), |
||||
+ block); |
||||
if (APR_SUCCESS != res) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, res, r, APLOGNO(01830) |
||||
"apr_crypto_block_encrypt failed"); |
||||
@@ -198,18 +333,20 @@ static apr_status_t encrypt_string(request_rec * r, const apr_crypto_t *f, |
||||
} |
||||
encryptlen += tlen; |
||||
|
||||
- /* prepend the salt and the iv to the result */ |
||||
- combined = apr_palloc(r->pool, ivSize + encryptlen + sizeof(apr_uuid_t)); |
||||
- memcpy(combined, &salt, sizeof(apr_uuid_t)); |
||||
- memcpy(combined + sizeof(apr_uuid_t), iv, ivSize); |
||||
- memcpy(combined + sizeof(apr_uuid_t) + ivSize, encrypt, encryptlen); |
||||
- |
||||
- /* base64 encode the result */ |
||||
- base64 = apr_palloc(r->pool, apr_base64_encode_len(ivSize + encryptlen + |
||||
- sizeof(apr_uuid_t) + 1) |
||||
- * sizeof(char)); |
||||
- apr_base64_encode(base64, (const char *) combined, |
||||
- ivSize + encryptlen + sizeof(apr_uuid_t)); |
||||
+ /* prepend the salt and the iv to the result (keep room for the MAC) */ |
||||
+ combinedlen = AP_SIPHASH_DSIZE + sizeof(apr_uuid_t) + ivSize + encryptlen; |
||||
+ combined = apr_palloc(r->pool, combinedlen); |
||||
+ memcpy(combined + AP_SIPHASH_DSIZE, &salt, sizeof(apr_uuid_t)); |
||||
+ memcpy(combined + AP_SIPHASH_DSIZE + sizeof(apr_uuid_t), iv, ivSize); |
||||
+ memcpy(combined + AP_SIPHASH_DSIZE + sizeof(apr_uuid_t) + ivSize, |
||||
+ encrypt, encryptlen); |
||||
+ /* authenticate the whole salt+IV+ciphertext with a leading MAC */ |
||||
+ compute_auth(combined + AP_SIPHASH_DSIZE, combinedlen - AP_SIPHASH_DSIZE, |
||||
+ passphrase, passlen, combined); |
||||
+ |
||||
+ /* base64 encode the result (APR handles the trailing '\0') */ |
||||
+ base64 = apr_palloc(r->pool, apr_base64_encode_len(combinedlen)); |
||||
+ apr_base64_encode(base64, (const char *) combined, combinedlen); |
||||
*out = base64; |
||||
|
||||
return res; |
||||
@@ -234,6 +371,7 @@ static apr_status_t decrypt_string(request_rec * r, const apr_crypto_t *f, |
||||
char *decoded; |
||||
apr_size_t blockSize = 0; |
||||
apr_crypto_block_key_type_e *cipher; |
||||
+ unsigned char auth[AP_SIPHASH_DSIZE]; |
||||
int i = 0; |
||||
|
||||
/* strip base64 from the string */ |
||||
@@ -241,6 +379,13 @@ static apr_status_t decrypt_string(request_rec * r, const apr_crypto_t *f, |
||||
decodedlen = apr_base64_decode(decoded, in); |
||||
decoded[decodedlen] = '\0'; |
||||
|
||||
+ /* sanity check - decoded too short? */ |
||||
+ if (decodedlen < (AP_SIPHASH_DSIZE + sizeof(apr_uuid_t))) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO() |
||||
+ "too short to decrypt, aborting"); |
||||
+ return APR_ECRYPT; |
||||
+ } |
||||
+ |
||||
res = crypt_init(r, f, &cipher, dconf); |
||||
if (res != APR_SUCCESS) { |
||||
return res; |
||||
@@ -249,14 +394,25 @@ static apr_status_t decrypt_string(request_rec * r, const apr_crypto_t *f, |
||||
/* try each passphrase in turn */ |
||||
for (; i < dconf->passphrases->nelts; i++) { |
||||
const char *passphrase = APR_ARRAY_IDX(dconf->passphrases, i, char *); |
||||
- apr_size_t len = decodedlen; |
||||
- char *slider = decoded; |
||||
+ apr_size_t passlen = strlen(passphrase); |
||||
+ apr_size_t len = decodedlen - AP_SIPHASH_DSIZE; |
||||
+ unsigned char *slider = (unsigned char *)decoded + AP_SIPHASH_DSIZE; |
||||
+ |
||||
+ /* Verify authentication of the whole salt+IV+ciphertext by computing |
||||
+ * the MAC and comparing it (timing safe) with the one in the payload. |
||||
+ */ |
||||
+ compute_auth(slider, len, passphrase, passlen, auth); |
||||
+ if (!ap_crypto_equals(auth, decoded, AP_SIPHASH_DSIZE)) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO() |
||||
+ "auth does not match, skipping"); |
||||
+ continue; |
||||
+ } |
||||
|
||||
/* encrypt using the first passphrase in the list */ |
||||
- res = apr_crypto_passphrase(&key, &ivSize, passphrase, |
||||
- strlen(passphrase), |
||||
- (unsigned char *)decoded, sizeof(apr_uuid_t), |
||||
- *cipher, APR_MODE_CBC, 1, 4096, f, r->pool); |
||||
+ res = apr_crypto_passphrase(&key, &ivSize, passphrase, passlen, |
||||
+ slider, sizeof(apr_uuid_t), |
||||
+ *cipher, APR_MODE_CBC, 1, 4096, |
||||
+ f, r->pool); |
||||
if (APR_STATUS_IS_ENOKEY(res)) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01832) |
||||
"the passphrase '%s' was empty", passphrase); |
||||
@@ -279,7 +435,7 @@ static apr_status_t decrypt_string(request_rec * r, const apr_crypto_t *f, |
||||
} |
||||
|
||||
/* sanity check - decoded too short? */ |
||||
- if (decodedlen < (sizeof(apr_uuid_t) + ivSize)) { |
||||
+ if (len < (sizeof(apr_uuid_t) + ivSize)) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(01836) |
||||
"too short to decrypt, skipping"); |
||||
res = APR_ECRYPT; |
||||
@@ -290,8 +446,8 @@ static apr_status_t decrypt_string(request_rec * r, const apr_crypto_t *f, |
||||
slider += sizeof(apr_uuid_t); |
||||
len -= sizeof(apr_uuid_t); |
||||
|
||||
- res = apr_crypto_block_decrypt_init(&block, &blockSize, (unsigned char *)slider, key, |
||||
- r->pool); |
||||
+ res = apr_crypto_block_decrypt_init(&block, &blockSize, slider, key, |
||||
+ r->pool); |
||||
if (APR_SUCCESS != res) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01837) |
||||
"apr_crypto_block_decrypt_init failed"); |
||||
@@ -304,7 +460,7 @@ static apr_status_t decrypt_string(request_rec * r, const apr_crypto_t *f, |
||||
|
||||
/* decrypt the given string */ |
||||
res = apr_crypto_block_decrypt(&decrypted, &decryptedlen, |
||||
- (unsigned char *)slider, len, block); |
||||
+ slider, len, block); |
||||
if (res) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, res, r, APLOGNO(01838) |
||||
"apr_crypto_block_decrypt failed"); |
||||
|
@ -0,0 +1,121 @@
@@ -0,0 +1,121 @@
|
||||
diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c |
||||
index 44b5fc8..6a50ba7 100644 |
||||
--- a/modules/aaa/mod_auth_digest.c |
||||
+++ b/modules/aaa/mod_auth_digest.c |
||||
@@ -261,6 +261,26 @@ static void log_error_and_cleanup(char *msg, apr_status_t sts, server_rec *s) |
||||
cleanup_tables(NULL); |
||||
} |
||||
|
||||
+/* RMM helper functions that behave like single-step malloc/free. */ |
||||
+ |
||||
+static void *rmm_malloc(apr_rmm_t *rmm, apr_size_t size) |
||||
+{ |
||||
+ apr_rmm_off_t offset = apr_rmm_malloc(rmm, size); |
||||
+ |
||||
+ if (!offset) { |
||||
+ return NULL; |
||||
+ } |
||||
+ |
||||
+ return apr_rmm_addr_get(rmm, offset); |
||||
+} |
||||
+ |
||||
+static apr_status_t rmm_free(apr_rmm_t *rmm, void *alloc) |
||||
+{ |
||||
+ apr_rmm_off_t offset = apr_rmm_offset_get(rmm, alloc); |
||||
+ |
||||
+ return apr_rmm_free(rmm, offset); |
||||
+} |
||||
+ |
||||
#if APR_HAS_SHARED_MEMORY |
||||
|
||||
static int initialize_tables(server_rec *s, apr_pool_t *ctx) |
||||
@@ -299,8 +319,8 @@ static int initialize_tables(server_rec *s, apr_pool_t *ctx) |
||||
return !OK; |
||||
} |
||||
|
||||
- client_list = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(*client_list) + |
||||
- sizeof(client_entry*)*num_buckets)); |
||||
+ client_list = rmm_malloc(client_rmm, sizeof(*client_list) + |
||||
+ sizeof(client_entry *) * num_buckets); |
||||
if (!client_list) { |
||||
log_error_and_cleanup("failed to allocate shared memory", -1, s); |
||||
return !OK; |
||||
@@ -322,7 +342,7 @@ static int initialize_tables(server_rec *s, apr_pool_t *ctx) |
||||
|
||||
/* setup opaque */ |
||||
|
||||
- opaque_cntr = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(*opaque_cntr))); |
||||
+ opaque_cntr = rmm_malloc(client_rmm, sizeof(*opaque_cntr)); |
||||
if (opaque_cntr == NULL) { |
||||
log_error_and_cleanup("failed to allocate shared memory", -1, s); |
||||
return !OK; |
||||
@@ -339,7 +359,7 @@ static int initialize_tables(server_rec *s, apr_pool_t *ctx) |
||||
|
||||
/* setup one-time-nonce counter */ |
||||
|
||||
- otn_counter = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(*otn_counter))); |
||||
+ otn_counter = rmm_malloc(client_rmm, sizeof(*otn_counter)); |
||||
if (otn_counter == NULL) { |
||||
log_error_and_cleanup("failed to allocate shared memory", -1, s); |
||||
return !OK; |
||||
@@ -779,7 +799,7 @@ static client_entry *get_client(unsigned long key, const request_rec *r) |
||||
* last entry in each bucket and updates the counters. Returns the |
||||
* number of removed entries. |
||||
*/ |
||||
-static long gc(void) |
||||
+static long gc(server_rec *s) |
||||
{ |
||||
client_entry *entry, *prev; |
||||
unsigned long num_removed = 0, idx; |
||||
@@ -789,6 +809,12 @@ static long gc(void) |
||||
for (idx = 0; idx < client_list->tbl_len; idx++) { |
||||
entry = client_list->table[idx]; |
||||
prev = NULL; |
||||
+ |
||||
+ if (!entry) { |
||||
+ /* This bucket is empty. */ |
||||
+ continue; |
||||
+ } |
||||
+ |
||||
while (entry->next) { /* find last entry */ |
||||
prev = entry; |
||||
entry = entry->next; |
||||
@@ -800,8 +826,16 @@ static long gc(void) |
||||
client_list->table[idx] = NULL; |
||||
} |
||||
if (entry) { /* remove entry */ |
||||
- apr_rmm_free(client_rmm, apr_rmm_offset_get(client_rmm, entry)); |
||||
+ apr_status_t err; |
||||
+ |
||||
+ err = rmm_free(client_rmm, entry); |
||||
num_removed++; |
||||
+ |
||||
+ if (err) { |
||||
+ /* Nothing we can really do but log... */ |
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, err, s, APLOGNO() |
||||
+ "Failed to free auth_digest client allocation"); |
||||
+ } |
||||
} |
||||
} |
||||
|
||||
@@ -835,16 +869,16 @@ static client_entry *add_client(unsigned long key, client_entry *info, |
||||
|
||||
/* try to allocate a new entry */ |
||||
|
||||
- entry = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(client_entry))); |
||||
+ entry = rmm_malloc(client_rmm, sizeof(client_entry)); |
||||
if (!entry) { |
||||
- long num_removed = gc(); |
||||
+ long num_removed = gc(s); |
||||
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01766) |
||||
"gc'd %ld client entries. Total new clients: " |
||||
"%ld; Total removed clients: %ld; Total renewed clients: " |
||||
"%ld", num_removed, |
||||
client_list->num_created - client_list->num_renewed, |
||||
client_list->num_removed, client_list->num_renewed); |
||||
- entry = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(client_entry))); |
||||
+ entry = rmm_malloc(client_rmm, sizeof(client_entry)); |
||||
if (!entry) { |
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01767) |
||||
"unable to allocate new auth_digest client"); |
||||
|
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-5387 |
||||
|
||||
--- httpd-2.4.6/server/util_script.c.cve5387 |
||||
+++ httpd-2.4.6/server/util_script.c |
||||
@@ -190,6 +190,10 @@ |
||||
continue; |
||||
} |
||||
#endif |
||||
+ else if (!strcasecmp(hdrs[i].key, "Proxy")) { |
||||
+ /* Don't pass through HTTP_PROXY */ |
||||
+ continue; |
||||
+ } |
||||
else |
||||
add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val); |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,343 @@
@@ -0,0 +1,343 @@
|
||||
diff --git a/include/http_protocol.h b/include/http_protocol.h |
||||
index 5ac0ce3..f3a5137 100644 |
||||
--- a/include/http_protocol.h |
||||
+++ b/include/http_protocol.h |
||||
@@ -558,7 +558,11 @@ AP_DECLARE(void) ap_note_digest_auth_failure(request_rec *r); |
||||
AP_DECLARE_HOOK(int, note_auth_failure, (request_rec *r, const char *auth_type)) |
||||
|
||||
/** |
||||
- * Get the password from the request headers |
||||
+ * Get the password from the request headers. This function has multiple side |
||||
+ * effects due to its prior use in the old authentication framework. |
||||
+ * ap_get_basic_auth_components() should be preferred. |
||||
+ * |
||||
+ * @deprecated @see ap_get_basic_auth_components |
||||
* @param r The current request |
||||
* @param pw The password as set in the headers |
||||
* @return 0 (OK) if it set the 'pw' argument (and assured |
||||
@@ -571,6 +575,25 @@ AP_DECLARE_HOOK(int, note_auth_failure, (request_rec *r, const char *auth_type)) |
||||
*/ |
||||
AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw); |
||||
|
||||
+#define AP_GET_BASIC_AUTH_PW_NOTE "AP_GET_BASIC_AUTH_PW_NOTE" |
||||
+ |
||||
+/** |
||||
+ * Get the username and/or password from the request's Basic authentication |
||||
+ * headers. Unlike ap_get_basic_auth_pw(), calling this function has no side |
||||
+ * effects on the passed request_rec. |
||||
+ * |
||||
+ * @param r The current request |
||||
+ * @param username If not NULL, set to the username sent by the client |
||||
+ * @param password If not NULL, set to the password sent by the client |
||||
+ * @return APR_SUCCESS if the credentials were successfully parsed and returned; |
||||
+ * APR_EINVAL if there was no authentication header sent or if the |
||||
+ * client was not using the Basic authentication scheme. username and |
||||
+ * password are unchanged on failure. |
||||
+ */ |
||||
+AP_DECLARE(apr_status_t) ap_get_basic_auth_components(const request_rec *r, |
||||
+ const char **username, |
||||
+ const char **password); |
||||
+ |
||||
/** |
||||
* parse_uri: break apart the uri |
||||
* @warning Side Effects: |
||||
diff --git a/include/httpd.h b/include/httpd.h |
||||
index 652a212..176ef5e 100644 |
||||
--- a/include/httpd.h |
||||
+++ b/include/httpd.h |
||||
@@ -2272,6 +2272,34 @@ AP_DECLARE(char *) ap_get_exec_line(apr_pool_t *p, |
||||
|
||||
#define AP_NORESTART APR_OS_START_USEERR + 1 |
||||
|
||||
+/** |
||||
+ * Perform a case-insensitive comparison of two strings @a atr1 and @a atr2, |
||||
+ * treating upper and lower case values of the 26 standard C/POSIX alphabetic |
||||
+ * characters as equivalent. Extended latin characters outside of this set |
||||
+ * are treated as unique octets, irrespective of the current locale. |
||||
+ * |
||||
+ * Returns in integer greater than, equal to, or less than 0, |
||||
+ * according to whether @a str1 is considered greater than, equal to, |
||||
+ * or less than @a str2. |
||||
+ * |
||||
+ * @note Same code as apr_cstr_casecmp, which arrives in APR 1.6 |
||||
+ */ |
||||
+AP_DECLARE(int) ap_cstr_casecmp(const char *s1, const char *s2); |
||||
+ |
||||
+/** |
||||
+ * Perform a case-insensitive comparison of two strings @a atr1 and @a atr2, |
||||
+ * treating upper and lower case values of the 26 standard C/POSIX alphabetic |
||||
+ * characters as equivalent. Extended latin characters outside of this set |
||||
+ * are treated as unique octets, irrespective of the current locale. |
||||
+ * |
||||
+ * Returns in integer greater than, equal to, or less than 0, |
||||
+ * according to whether @a str1 is considered greater than, equal to, |
||||
+ * or less than @a str2. |
||||
+ * |
||||
+ * @note Same code as apr_cstr_casecmpn, which arrives in APR 1.6 |
||||
+ */ |
||||
+AP_DECLARE(int) ap_cstr_casecmpn(const char *s1, const char *s2, apr_size_t n); |
||||
+ |
||||
#ifdef __cplusplus |
||||
} |
||||
#endif |
||||
diff --git a/server/protocol.c b/server/protocol.c |
||||
index 24355c7..868c3e3 100644 |
||||
--- a/server/protocol.c |
||||
+++ b/server/protocol.c |
||||
@@ -1567,6 +1567,7 @@ AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw) |
||||
|
||||
t = ap_pbase64decode(r->pool, auth_line); |
||||
r->user = ap_getword_nulls (r->pool, &t, ':'); |
||||
+ apr_table_setn(r->notes, AP_GET_BASIC_AUTH_PW_NOTE, "1"); |
||||
r->ap_auth_type = "Basic"; |
||||
|
||||
*pw = t; |
||||
@@ -1574,6 +1575,53 @@ AP_DECLARE(int) ap_get_basic_auth_pw(request_rec *r, const char **pw) |
||||
return OK; |
||||
} |
||||
|
||||
+AP_DECLARE(apr_status_t) ap_get_basic_auth_components(const request_rec *r, |
||||
+ const char **username, |
||||
+ const char **password) |
||||
+{ |
||||
+ const char *auth_header; |
||||
+ const char *credentials; |
||||
+ const char *decoded; |
||||
+ const char *user; |
||||
+ |
||||
+ auth_header = (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authorization" |
||||
+ : "Authorization"; |
||||
+ credentials = apr_table_get(r->headers_in, auth_header); |
||||
+ |
||||
+ if (!credentials) { |
||||
+ /* No auth header. */ |
||||
+ return APR_EINVAL; |
||||
+ } |
||||
+ |
||||
+ if (ap_cstr_casecmp(ap_getword(r->pool, &credentials, ' '), "Basic")) { |
||||
+ /* These aren't Basic credentials. */ |
||||
+ return APR_EINVAL; |
||||
+ } |
||||
+ |
||||
+ while (*credentials == ' ' || *credentials == '\t') { |
||||
+ credentials++; |
||||
+ } |
||||
+ |
||||
+ /* XXX Our base64 decoding functions don't actually error out if the string |
||||
+ * we give it isn't base64; they'll just silently stop and hand us whatever |
||||
+ * they've parsed up to that point. |
||||
+ * |
||||
+ * Since this function is supposed to be a drop-in replacement for the |
||||
+ * deprecated ap_get_basic_auth_pw(), don't fix this for 2.4.x. |
||||
+ */ |
||||
+ decoded = ap_pbase64decode(r->pool, credentials); |
||||
+ user = ap_getword_nulls(r->pool, &decoded, ':'); |
||||
+ |
||||
+ if (username) { |
||||
+ *username = user; |
||||
+ } |
||||
+ if (password) { |
||||
+ *password = decoded; |
||||
+ } |
||||
+ |
||||
+ return APR_SUCCESS; |
||||
+} |
||||
+ |
||||
struct content_length_ctx { |
||||
int data_sent; /* true if the C-L filter has already sent at |
||||
* least one bucket on to the next output filter |
||||
diff --git a/server/request.c b/server/request.c |
||||
index 2711bed..4eef097 100644 |
||||
--- a/server/request.c |
||||
+++ b/server/request.c |
||||
@@ -124,6 +124,8 @@ static int decl_die(int status, const char *phase, request_rec *r) |
||||
AP_DECLARE(int) ap_some_authn_required(request_rec *r) |
||||
{ |
||||
int access_status; |
||||
+ char *olduser = r->user; |
||||
+ int rv = FALSE; |
||||
|
||||
switch (ap_satisfies(r)) { |
||||
case SATISFY_ALL: |
||||
@@ -134,7 +136,7 @@ AP_DECLARE(int) ap_some_authn_required(request_rec *r) |
||||
|
||||
access_status = ap_run_access_checker_ex(r); |
||||
if (access_status == DECLINED) { |
||||
- return TRUE; |
||||
+ rv = TRUE; |
||||
} |
||||
|
||||
break; |
||||
@@ -145,13 +147,14 @@ AP_DECLARE(int) ap_some_authn_required(request_rec *r) |
||||
|
||||
access_status = ap_run_access_checker_ex(r); |
||||
if (access_status == DECLINED) { |
||||
- return TRUE; |
||||
+ rv = TRUE; |
||||
} |
||||
|
||||
break; |
||||
} |
||||
|
||||
- return FALSE; |
||||
+ r->user = olduser; |
||||
+ return rv; |
||||
} |
||||
|
||||
/* This is the master logic for processing requests. Do NOT duplicate |
||||
@@ -259,6 +262,14 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) |
||||
r->ap_auth_type = r->main->ap_auth_type; |
||||
} |
||||
else { |
||||
+ /* A module using a confusing API (ap_get_basic_auth_pw) caused |
||||
+ ** r->user to be filled out prior to check_authn hook. We treat |
||||
+ ** it is inadvertent. |
||||
+ */ |
||||
+ if (r->user && apr_table_get(r->notes, AP_GET_BASIC_AUTH_PW_NOTE)) { |
||||
+ r->user = NULL; |
||||
+ } |
||||
+ |
||||
switch (ap_satisfies(r)) { |
||||
case SATISFY_ALL: |
||||
case SATISFY_NOSPEC: |
||||
diff --git a/server/util.c b/server/util.c |
||||
index db22b50..70fd662 100644 |
||||
--- a/server/util.c |
||||
+++ b/server/util.c |
||||
@@ -96,7 +96,6 @@ |
||||
#undef APLOG_MODULE_INDEX |
||||
#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX |
||||
|
||||
- |
||||
/* |
||||
* Examine a field value (such as a media-/content-type) string and return |
||||
* it sans any parameters; e.g., strip off any ';charset=foo' and the like. |
||||
@@ -3036,3 +3035,128 @@ AP_DECLARE(char *) ap_get_exec_line(apr_pool_t *p, |
||||
|
||||
return apr_pstrndup(p, buf, k); |
||||
} |
||||
+ |
||||
+#if !APR_CHARSET_EBCDIC |
||||
+/* |
||||
+ * Our own known-fast translation table for casecmp by character. |
||||
+ * Only ASCII alpha characters 41-5A are folded to 61-7A, other |
||||
+ * octets (such as extended latin alphabetics) are never case-folded. |
||||
+ * NOTE: Other than Alpha A-Z/a-z, each code point is unique! |
||||
+*/ |
||||
+static const short ucharmap[] = { |
||||
+ 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, |
||||
+ 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, |
||||
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, |
||||
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, |
||||
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, |
||||
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, |
||||
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
||||
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, |
||||
+ 0x40, 'a', 'b', 'c', 'd', 'e', 'f', 'g', |
||||
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', |
||||
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', |
||||
+ 'x', 'y', 'z', 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, |
||||
+ 0x60, 'a', 'b', 'c', 'd', 'e', 'f', 'g', |
||||
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', |
||||
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', |
||||
+ 'x', 'y', 'z', 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, |
||||
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, |
||||
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, |
||||
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, |
||||
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, |
||||
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, |
||||
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, |
||||
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, |
||||
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, |
||||
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, |
||||
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, |
||||
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, |
||||
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, |
||||
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, |
||||
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, |
||||
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, |
||||
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff |
||||
+}; |
||||
+#else /* APR_CHARSET_EBCDIC */ |
||||
+/* |
||||
+ * Derived from apr-iconv/ccs/cp037.c for EBCDIC case comparison, |
||||
+ * provides unique identity of every char value (strict ISO-646 |
||||
+ * conformance, arbitrary election of an ISO-8859-1 ordering, and |
||||
+ * very arbitrary control code assignments into C1 to achieve |
||||
+ * identity and a reversible mapping of code points), |
||||
+ * then folding the equivalences of ASCII 41-5A into 61-7A, |
||||
+ * presenting comparison results in a somewhat ISO/IEC 10646 |
||||
+ * (ASCII-like) order, depending on the EBCDIC code page in use. |
||||
+ * |
||||
+ * NOTE: Other than Alpha A-Z/a-z, each code point is unique! |
||||
+ */ |
||||
+static const short ucharmap[] = { |
||||
+ 0x00, 0x01, 0x02, 0x03, 0x9C, 0x09, 0x86, 0x7F, |
||||
+ 0x97, 0x8D, 0x8E, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, |
||||
+ 0x10, 0x11, 0x12, 0x13, 0x9D, 0x85, 0x08, 0x87, |
||||
+ 0x18, 0x19, 0x92, 0x8F, 0x1C, 0x1D, 0x1E, 0x1F, |
||||
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x0A, 0x17, 0x1B, |
||||
+ 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x05, 0x06, 0x07, |
||||
+ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, |
||||
+ 0x98, 0x99, 0x9A, 0x9B, 0x14, 0x15, 0x9E, 0x1A, |
||||
+ 0x20, 0xA0, 0xE2, 0xE4, 0xE0, 0xE1, 0xE3, 0xE5, |
||||
+ 0xE7, 0xF1, 0xA2, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, |
||||
+ 0x26, 0xE9, 0xEA, 0xEB, 0xE8, 0xED, 0xEE, 0xEF, |
||||
+ 0xEC, 0xDF, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAC, |
||||
+ 0x2D, 0x2F, 0xC2, 0xC4, 0xC0, 0xC1, 0xC3, 0xC5, |
||||
+ 0xC7, 0xD1, 0xA6, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, |
||||
+ 0xF8, 0xC9, 0xCA, 0xCB, 0xC8, 0xCD, 0xCE, 0xCF, |
||||
+ 0xCC, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, |
||||
+ 0xD8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, |
||||
+ 0x68, 0x69, 0xAB, 0xBB, 0xF0, 0xFD, 0xFE, 0xB1, |
||||
+ 0xB0, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, |
||||
+ 0x71, 0x72, 0xAA, 0xBA, 0xE6, 0xB8, 0xC6, 0xA4, |
||||
+ 0xB5, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, |
||||
+ 0x79, 0x7A, 0xA1, 0xBF, 0xD0, 0xDD, 0xDE, 0xAE, |
||||
+ 0x5E, 0xA3, 0xA5, 0xB7, 0xA9, 0xA7, 0xB6, 0xBC, |
||||
+ 0xBD, 0xBE, 0x5B, 0x5D, 0xAF, 0xA8, 0xB4, 0xD7, |
||||
+ 0x7B, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, |
||||
+ 0x68, 0x69, 0xAD, 0xF4, 0xF6, 0xF2, 0xF3, 0xF5, |
||||
+ 0x7D, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, |
||||
+ 0x71, 0x72, 0xB9, 0xFB, 0xFC, 0xF9, 0xFA, 0xFF, |
||||
+ 0x5C, 0xF7, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, |
||||
+ 0x79, 0x7A, 0xB2, 0xD4, 0xD6, 0xD2, 0xD3, 0xD5, |
||||
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, |
||||
+ 0x38, 0x39, 0xB3, 0xDB, 0xDC, 0xD9, 0xDA, 0x9F |
||||
+}; |
||||
+#endif |
||||
+ |
||||
+AP_DECLARE(int) ap_cstr_casecmp(const char *s1, const char *s2) |
||||
+{ |
||||
+ const unsigned char *str1 = (const unsigned char *)s1; |
||||
+ const unsigned char *str2 = (const unsigned char *)s2; |
||||
+ for (;;) |
||||
+ { |
||||
+ const int c1 = (int)(*str1); |
||||
+ const int c2 = (int)(*str2); |
||||
+ const int cmp = ucharmap[c1] - ucharmap[c2]; |
||||
+ /* Not necessary to test for !c2, this is caught by cmp */ |
||||
+ if (cmp || !c1) |
||||
+ return cmp; |
||||
+ str1++; |
||||
+ str2++; |
||||
+ } |
||||
+} |
||||
+ |
||||
+AP_DECLARE(int) ap_cstr_casecmpn(const char *s1, const char *s2, apr_size_t n) |
||||
+{ |
||||
+ const unsigned char *str1 = (const unsigned char *)s1; |
||||
+ const unsigned char *str2 = (const unsigned char *)s2; |
||||
+ while (n--) |
||||
+ { |
||||
+ const int c1 = (int)(*str1); |
||||
+ const int c2 = (int)(*str2); |
||||
+ const int cmp = ucharmap[c1] - ucharmap[c2]; |
||||
+ /* Not necessary to test for !c2, this is caught by cmp */ |
||||
+ if (cmp || !c1) |
||||
+ return cmp; |
||||
+ str1++; |
||||
+ str2++; |
||||
+ } |
||||
+ return 0; |
||||
+} |
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c |
||||
index 85c6ce7..4a9fc9a 100644 |
||||
--- a/modules/ssl/ssl_engine_io.c |
||||
+++ b/modules/ssl/ssl_engine_io.c |
||||
@@ -834,19 +834,20 @@ static apr_status_t ssl_filter_write(ap_filter_t *f, |
||||
* establish an outgoing SSL connection. */ |
||||
#define MODSSL_ERROR_BAD_GATEWAY (APR_OS_START_USERERR + 1) |
||||
|
||||
-static void ssl_io_filter_disable(SSLConnRec *sslconn, ap_filter_t *f) |
||||
+static void ssl_io_filter_disable(SSLConnRec *sslconn, |
||||
+ bio_filter_in_ctx_t *inctx) |
||||
{ |
||||
- bio_filter_in_ctx_t *inctx = f->ctx; |
||||
SSL_free(inctx->ssl); |
||||
sslconn->ssl = NULL; |
||||
inctx->ssl = NULL; |
||||
inctx->filter_ctx->pssl = NULL; |
||||
} |
||||
|
||||
-static apr_status_t ssl_io_filter_error(ap_filter_t *f, |
||||
+static apr_status_t ssl_io_filter_error(bio_filter_in_ctx_t *inctx, |
||||
apr_bucket_brigade *bb, |
||||
apr_status_t status) |
||||
{ |
||||
+ ap_filter_t *f = inctx->f; |
||||
SSLConnRec *sslconn = myConnConfig(f->c); |
||||
apr_bucket *bucket; |
||||
int send_eos = 1; |
||||
@@ -860,7 +861,7 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f, |
||||
ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, sslconn->server); |
||||
|
||||
sslconn->non_ssl_request = NON_SSL_SEND_HDR_SEP; |
||||
- ssl_io_filter_disable(sslconn, f); |
||||
+ ssl_io_filter_disable(sslconn, inctx); |
||||
|
||||
/* fake the request line */ |
||||
bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc); |
||||
@@ -1342,7 +1343,7 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f, |
||||
* rather than have SSLEngine On configured. |
||||
*/ |
||||
if ((status = ssl_io_filter_handshake(inctx->filter_ctx)) != APR_SUCCESS) { |
||||
- return ssl_io_filter_error(f, bb, status); |
||||
+ return ssl_io_filter_error(inctx, bb, status); |
||||
} |
||||
|
||||
if (is_init) { |
||||
@@ -1396,7 +1397,7 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f, |
||||
|
||||
/* Handle custom errors. */ |
||||
if (status != APR_SUCCESS) { |
||||
- return ssl_io_filter_error(f, bb, status); |
||||
+ return ssl_io_filter_error(inctx, bb, status); |
||||
} |
||||
|
||||
/* Create a transient bucket out of the decrypted data. */ |
||||
@@ -1613,7 +1614,7 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f, |
||||
inctx->block = APR_BLOCK_READ; |
||||
|
||||
if ((status = ssl_io_filter_handshake(filter_ctx)) != APR_SUCCESS) { |
||||
- return ssl_io_filter_error(f, bb, status); |
||||
+ return ssl_io_filter_error(inctx, bb, status); |
||||
} |
||||
|
||||
while (!APR_BRIGADE_EMPTY(bb)) { |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
--- a/server/util.c 2017/05/30 12:27:41 1796855 |
||||
+++ b/server/util.c 2017/05/30 12:28:20 1796856 |
||||
@@ -1679,10 +1679,8 @@ |
||||
|
||||
s = (const unsigned char *)line; |
||||
for (;;) { |
||||
- /* find start of token, skip all stop characters, note NUL |
||||
- * isn't a token stop, so we don't need to test for it |
||||
- */ |
||||
- while (TEST_CHAR(*s, T_HTTP_TOKEN_STOP)) { |
||||
+ /* find start of token, skip all stop characters */ |
||||
+ while (*s && TEST_CHAR(*s, T_HTTP_TOKEN_STOP)) { |
||||
++s; |
||||
} |
||||
if (!*s) { |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
--- a/modules/http/mod_mime.c 2017/06/05 12:10:05 1797652 |
||||
+++ b/modules/http/mod_mime.c 2017/06/05 12:12:31 1797653 |
||||
@@ -528,9 +528,9 @@ |
||||
int res = -1; |
||||
int c; |
||||
|
||||
- if (((s + 1) != NULL) && (*s == '\\')) { |
||||
+ if (*s == '\\') { |
||||
c = (int) *(s + 1); |
||||
- if (apr_isascii(c)) { |
||||
+ if (c && apr_isascii(c)) { |
||||
res = 1; |
||||
} |
||||
} |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
diff --git a/modules/aaa/mod_auth_digest.c b/modules/aaa/mod_auth_digest.c |
||||
index 0ff47f7..cbb4434 100644 |
||||
--- a/modules/aaa/mod_auth_digest.c |
||||
+++ b/modules/aaa/mod_auth_digest.c |
||||
@@ -956,13 +956,13 @@ static int get_digest_rec(request_rec *r, digest_header_rec *resp) |
||||
|
||||
/* find value */ |
||||
|
||||
+ vv = 0; |
||||
if (auth_line[0] == '=') { |
||||
auth_line++; |
||||
while (apr_isspace(auth_line[0])) { |
||||
auth_line++; |
||||
} |
||||
|
||||
- vv = 0; |
||||
if (auth_line[0] == '\"') { /* quoted string */ |
||||
auth_line++; |
||||
while (auth_line[0] != '\"' && auth_line[0] != '\0') { |
||||
@@ -981,8 +981,8 @@ static int get_digest_rec(request_rec *r, digest_header_rec *resp) |
||||
value[vv++] = *auth_line++; |
||||
} |
||||
} |
||||
- value[vv] = '\0'; |
||||
} |
||||
+ value[vv] = '\0'; |
||||
|
||||
while (auth_line[0] != ',' && auth_line[0] != '\0') { |
||||
auth_line++; |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
diff --git a/server/core.c b/server/core.c |
||||
index f60e8fa..245fcb6 100644 |
||||
--- a/server/core.c |
||||
+++ b/server/core.c |
||||
@@ -2061,6 +2061,12 @@ AP_CORE_DECLARE_NONSTD(const char *) ap_limit_section(cmd_parms *cmd, |
||||
/* method has not been registered yet, but resorce restriction |
||||
* is always checked before method handling, so register it. |
||||
*/ |
||||
+ if (cmd->pool == cmd->temp_pool) { |
||||
+ /* In .htaccess, we can't globally register new methods. */ |
||||
+ return apr_psprintf(cmd->pool, "Could not register method '%s' " |
||||
+ "for %s from .htaccess configuration", |
||||
+ method, cmd->cmd->name); |
||||
+ } |
||||
methnum = ap_method_register(cmd->pool, |
||||
apr_pstrdup(cmd->pool, method)); |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
--- a/support/ab.c 2014/08/14 12:12:38 1617912 |
||||
+++ b/support/ab.c 2014/08/14 12:15:31 1617913 |
||||
@@ -1029,7 +1029,7 @@ |
||||
ap_round_ms(stats[done - 1].time)); |
||||
else |
||||
printf(" %d%% %5" APR_TIME_T_FMT "\n", percs[i], |
||||
- ap_round_ms(stats[(int) (done * percs[i] / 100)].time)); |
||||
+ ap_round_ms(stats[(unsigned long)done * percs[i] / 100].time)); |
||||
} |
||||
} |
||||
if (csvperc) { |
||||
@@ -1046,7 +1046,7 @@ |
||||
else if (i == 100) |
||||
t = ap_double_ms(stats[done - 1].time); |
||||
else |
||||
- t = ap_double_ms(stats[(int) (0.5 + done * i / 100.0)].time); |
||||
+ t = ap_double_ms(stats[(unsigned long) (0.5 + (double)done * i / 100.0)].time); |
||||
fprintf(out, "%d,%.3f\n", i, t); |
||||
} |
||||
fclose(out); |
@ -0,0 +1,27 @@
@@ -0,0 +1,27 @@
|
||||
diff --git a/support/ab.c b/support/ab.c |
||||
index bf76406..80c1b74 100644 |
||||
--- a/support/ab.c |
||||
+++ b/support/ab.c |
||||
@@ -1346,11 +1346,21 @@ static void read_connection(struct connection * c) |
||||
&& good == 0) { |
||||
return; |
||||
} |
||||
+ else if (scode == SSL_ERROR_SYSCALL |
||||
+ && status == 0 |
||||
+ && c->read != 0) { |
||||
+ /* connection closed, but in violation of the protocol, after |
||||
+ * some data has already been read; this commonly happens, so |
||||
+ * let the length check catch any response errors |
||||
+ */ |
||||
+ good++; |
||||
+ close_connection(c); |
||||
+ } |
||||
else if (scode != SSL_ERROR_WANT_WRITE |
||||
&& scode != SSL_ERROR_WANT_READ) { |
||||
/* some fatal error: */ |
||||
c->read = 0; |
||||
- BIO_printf(bio_err, "SSL read failed (%d) - closing connection\n", scode); |
||||
+ BIO_printf(bio_err, "SSL read failed (%d) - closing connection\n", scode); |
||||
ERR_print_errors(bio_err); |
||||
close_connection(c); |
||||
} |
@ -0,0 +1,139 @@
@@ -0,0 +1,139 @@
|
||||
diff --git a/support/ab.c b/support/ab.c |
||||
index f54c402..93c9066 100644 |
||||
--- a/support/ab.c |
||||
+++ b/support/ab.c |
||||
@@ -344,6 +344,7 @@ apr_time_t start, lasttime, stoptime; |
||||
char _request[2048]; |
||||
char *request = _request; |
||||
apr_size_t reqlen; |
||||
+int requests_initialized = 0; |
||||
|
||||
/* one global throw-away buffer to read stuff into */ |
||||
char buffer[8192]; |
||||
@@ -1253,12 +1254,18 @@ static void start_connect(struct connection * c) |
||||
else { |
||||
set_conn_state(c, STATE_UNCONNECTED); |
||||
apr_socket_close(c->aprsock); |
||||
- err_conn++; |
||||
- if (bad++ > 10) { |
||||
+ if (good == 0 && destsa->next) { |
||||
+ destsa = destsa->next; |
||||
+ err_conn = 0; |
||||
+ } |
||||
+ else if (bad++ > 10) { |
||||
fprintf(stderr, |
||||
"\nTest aborted after 10 failures\n\n"); |
||||
apr_err("apr_socket_connect()", rv); |
||||
} |
||||
+ else { |
||||
+ err_conn++; |
||||
+ } |
||||
|
||||
start_connect(c); |
||||
return; |
||||
@@ -1339,6 +1346,7 @@ static void read_connection(struct connection * c) |
||||
apr_status_t status; |
||||
char *part; |
||||
char respcode[4]; /* 3 digits and null */ |
||||
+ int i; |
||||
|
||||
r = sizeof(buffer); |
||||
#ifdef USE_SSL |
||||
@@ -1362,6 +1370,13 @@ static void read_connection(struct connection * c) |
||||
good++; |
||||
close_connection(c); |
||||
} |
||||
+ else if (scode == SSL_ERROR_SYSCALL |
||||
+ && c->read == 0 |
||||
+ && destsa->next |
||||
+ && c->state == STATE_CONNECTING |
||||
+ && good == 0) { |
||||
+ return; |
||||
+ } |
||||
else if (scode != SSL_ERROR_WANT_WRITE |
||||
&& scode != SSL_ERROR_WANT_READ) { |
||||
/* some fatal error: */ |
||||
@@ -1387,8 +1402,8 @@ static void read_connection(struct connection * c) |
||||
} |
||||
/* catch legitimate fatal apr_socket_recv errors */ |
||||
else if (status != APR_SUCCESS) { |
||||
- err_recv++; |
||||
if (recverrok) { |
||||
+ err_recv++; |
||||
bad++; |
||||
close_connection(c); |
||||
if (verbosity >= 1) { |
||||
@@ -1396,7 +1411,12 @@ static void read_connection(struct connection * c) |
||||
fprintf(stderr,"%s: %s (%d)\n", "apr_socket_recv", apr_strerror(status, buf, sizeof buf), status); |
||||
} |
||||
return; |
||||
- } else { |
||||
+ } else if (destsa->next && c->state == STATE_CONNECTING |
||||
+ && c->read == 0 && good == 0) { |
||||
+ return; |
||||
+ } |
||||
+ else { |
||||
+ err_recv++; |
||||
apr_err("apr_socket_recv", status); |
||||
} |
||||
} |
||||
@@ -1523,6 +1543,16 @@ static void read_connection(struct connection * c) |
||||
} |
||||
c->bread += c->cbx - (s + l - c->cbuff) + r - tocopy; |
||||
totalbread += c->bread; |
||||
+ |
||||
+ /* We have received the header, so we know this destination socket |
||||
+ * address is working, so initialize all remaining requests. */ |
||||
+ if (!requests_initialized) { |
||||
+ for (i = 1; i < concurrency; i++) { |
||||
+ con[i].socknum = i; |
||||
+ start_connect(&con[i]); |
||||
+ } |
||||
+ requests_initialized = 1; |
||||
+ } |
||||
} |
||||
} |
||||
else { |
||||
@@ -1734,11 +1764,10 @@ static void test(void) |
||||
apr_signal(SIGINT, output_results); |
||||
#endif |
||||
|
||||
- /* initialise lots of requests */ |
||||
- for (i = 0; i < concurrency; i++) { |
||||
- con[i].socknum = i; |
||||
- start_connect(&con[i]); |
||||
- } |
||||
+ /* initialise first connection to determine destination socket address |
||||
+ * which should be used for next connections. */ |
||||
+ con[0].socknum = 0; |
||||
+ start_connect(&con[0]); |
||||
|
||||
do { |
||||
apr_int32_t n; |
||||
@@ -1786,14 +1815,20 @@ static void test(void) |
||||
if ((rtnev & APR_POLLIN) || (rtnev & APR_POLLPRI) || (rtnev & APR_POLLHUP)) |
||||
read_connection(c); |
||||
if ((rtnev & APR_POLLERR) || (rtnev & APR_POLLNVAL)) { |
||||
- bad++; |
||||
- err_except++; |
||||
- /* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */ |
||||
- if (c->state == STATE_CONNECTING) { |
||||
- read_connection(c); |
||||
+ if (destsa->next && c->state == STATE_CONNECTING && good == 0) { |
||||
+ destsa = destsa->next; |
||||
+ start_connect(c); |
||||
} |
||||
else { |
||||
- start_connect(c); |
||||
+ bad++; |
||||
+ err_except++; |
||||
+ /* avoid apr_poll/EINPROGRESS loop on HP-UX, let recv discover ECONNREFUSED */ |
||||
+ if (c->state == STATE_CONNECTING) { |
||||
+ read_connection(c); |
||||
+ } |
||||
+ else { |
||||
+ start_connect(c); |
||||
+ } |
||||
} |
||||
continue; |
||||
} |
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
diff --git a/docs/man/apachectl.8 b/docs/man/apachectl.8 |
||||
index 054550f..4bfc7cb 100644 |
||||
--- a/docs/man/apachectl.8 |
||||
+++ b/docs/man/apachectl.8 |
||||
@@ -77,7 +77,7 @@ status |
||||
Displays a brief status report\&. Similar to the fullstatus option, except that the list of requests currently being served is omitted\&. |
||||
.TP |
||||
graceful |
||||
-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 configtest before initiating the restart to make sure Apache doesn't die\&. This is equivalent to apachectl -k graceful\&. |
||||
+Gracefully restarts the Apache httpd daemon\&. If the daemon is not running, it is not 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 configtest before initiating the restart to make sure Apache doesn't die\&. This is equivalent to apachectl -k graceful\&. |
||||
.TP |
||||
graceful-stop |
||||
Gracefully stops the Apache httpd daemon\&. This differs from a normal stop in that currently open connections are not aborted\&. A side effect is that old log files will not be closed immediately\&. This is equivalent to apachectl -k graceful-stop\&. |
||||
diff --git a/support/apachectl.in b/support/apachectl.in |
||||
index 2d59623..10fc280 100644 |
||||
--- a/support/apachectl.in |
||||
+++ b/support/apachectl.in |
||||
@@ -93,9 +93,9 @@ 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` $HTTPD $OPTIONS -t |
||||
+ runcon -- `id -Z` /usr/sbin/httpd $OPTIONS -t |
||||
else |
||||
- $HTTPD $OPTIONS -t |
||||
+ /usr/sbin/httpd $OPTIONS -t |
||||
fi |
||||
ERROR=$? |
||||
} |
||||
@@ -134,7 +134,7 @@ fullstatus) |
||||
$LYNX $STATUSURL |
||||
;; |
||||
*) |
||||
- $HTTPD $OPTIONS "$@" |
||||
+ /usr/sbin/httpd $OPTIONS "$@" |
||||
ERROR=$? |
||||
esac |
||||
|
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
diff --git a/docs/man/apachectl.8 b/docs/man/apachectl.8 |
||||
index 4bfc7cb..372c08e 100644 |
||||
--- a/docs/man/apachectl.8 |
||||
+++ b/docs/man/apachectl.8 |
||||
@@ -74,7 +74,7 @@ fullstatus |
||||
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 lynx available on your system\&. The URL used to access the status report can be set by editing the STATUSURL variable in the script\&. |
||||
.TP |
||||
status |
||||
-Displays a brief status report\&. Similar to the fullstatus option, except that the list of requests currently being served is omitted\&. |
||||
+Displays a brief status report using systemd\&. |
||||
.TP |
||||
graceful |
||||
Gracefully restarts the Apache httpd daemon\&. If the daemon is not running, it is not 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 configtest before initiating the restart to make sure Apache doesn't die\&. This is equivalent to apachectl -k graceful\&. |
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
diff --git a/docs/conf/extra/httpd-autoindex.conf.in b/docs/conf/extra/httpd-autoindex.conf.in |
||||
index 0e8b626..dd6f2c6 100644 |
||||
--- a/docs/conf/extra/httpd-autoindex.conf.in |
||||
+++ b/docs/conf/extra/httpd-autoindex.conf.in |
||||
@@ -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 |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c |
||||
index ee46db4..c560422 100644 |
||||
--- a/modules/ssl/ssl_engine_init.c |
||||
+++ b/modules/ssl/ssl_engine_init.c |
||||
@@ -915,7 +915,7 @@ static void ssl_init_server_certs(server_rec *s, |
||||
const char *rsa_id, *dsa_id; |
||||
#ifndef OPENSSL_NO_EC |
||||
const char *ecc_id; |
||||
- EC_GROUP *ecparams; |
||||
+ EC_GROUP *ecparams = NULL; |
||||
int nid; |
||||
EC_KEY *eckey = NULL; |
||||
#endif |
||||
@@ -988,6 +988,7 @@ static void ssl_init_server_certs(server_rec *s, |
||||
"Custom DH parameters (%d bits) for %s loaded from %s", |
||||
BN_num_bits(dhparams->p), vhost_id, |
||||
mctx->pks->cert_files[0]); |
||||
+ DH_free(dhparams); |
||||
} |
||||
|
||||
#ifndef OPENSSL_NO_EC |
||||
@@ -1012,6 +1013,9 @@ static void ssl_init_server_certs(server_rec *s, |
||||
SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, eckey); |
||||
#endif |
||||
} |
||||
+ if (ecparams) { |
||||
+ EC_GROUP_free(ecparams); |
||||
+ } |
||||
EC_KEY_free(eckey); |
||||
#endif |
||||
} |
@ -0,0 +1,48 @@
@@ -0,0 +1,48 @@
|
||||
diff --git a/server/core.c b/server/core.c |
||||
index fb5e34a..e71f716 100644 |
||||
--- a/server/core.c |
||||
+++ b/server/core.c |
||||
@@ -3115,7 +3115,8 @@ 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_PRODUCT_ONLY /* eg: Apache */ |
||||
+ 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; |
||||
|
||||
@@ -3191,7 +3192,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 ")"); |
||||
} |
||||
|
||||
@@ -3199,7 +3203,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 ")"; |
||||
@@ -3232,8 +3236,11 @@ static const char *set_serv_tokens(cmd_parms *cmd, void *dummy, |
||||
else if (!strcasecmp(arg1, "Full")) { |
||||
ap_server_tokens = SrvTk_FULL; |
||||
} |
||||
+ else if (!strcasecmp(arg1, "Full-Release")) { |
||||
+ ap_server_tokens = SrvTk_FULL_RELEASE; |
||||
+ } |
||||
else { |
||||
- return "ServerTokens takes 1 argument, 'Prod', 'Major', 'Minor', 'Min', 'OS', or 'Full'"; |
||||
+ return "ServerTokens takes 1 argument, 'Prod', 'Major', 'Minor', 'Min', 'OS', 'Full' or 'Full-Release'"; |
||||
} |
||||
|
||||
return NULL; |
@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
|
||||
diff --git a/server/main.c b/server/main.c |
||||
index 28d1872..544882d 100644 |
||||
--- a/server/main.c |
||||
+++ b/server/main.c |
||||
@@ -478,6 +478,12 @@ int main(int argc, const char * const argv[]) |
||||
ap_server_post_read_config = apr_array_make(pcommands, 1, sizeof(char *)); |
||||
ap_server_config_defines = apr_array_make(pcommands, 1, sizeof(char *)); |
||||
|
||||
+ { |
||||
+ char **new = (char **)apr_array_push(ap_server_config_defines); |
||||
+ |
||||
+ *new = "_RH_HAS_HTTPPROTOCOLOPTIONS"; |
||||
+ } |
||||
+ |
||||
error = ap_setup_prelinked_modules(process); |
||||
if (error) { |
||||
ap_log_error(APLOG_MARK, APLOG_STARTUP|APLOG_EMERG, 0, NULL, APLOGNO(00012) |
@ -0,0 +1,73 @@
@@ -0,0 +1,73 @@
|
||||
http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/ldap/util_ldap.c?r1=1517388&r2=1517387&pathrev=1517388&view=patch |
||||
|
||||
--- trunk/modules/ldap/util_ldap.c 2013/08/25 21:46:27 1517387 |
||||
+++ trunk/modules/ldap/util_ldap.c 2013/08/25 22:42:29 1517388 |
||||
@@ -60,6 +60,7 @@ |
||||
#endif |
||||
|
||||
#define AP_LDAP_HOPLIMIT_UNSET -1 |
||||
+#define AP_LDAP_CHASEREFERRALS_SDKDEFAULT -1 |
||||
#define AP_LDAP_CHASEREFERRALS_OFF 0 |
||||
#define AP_LDAP_CHASEREFERRALS_ON 1 |
||||
|
||||
@@ -371,7 +372,7 @@ |
||||
ldap_option = ldc->deref; |
||||
ldap_set_option(ldc->ldap, LDAP_OPT_DEREF, &ldap_option); |
||||
|
||||
- if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) { |
||||
+ if (ldc->ChaseReferrals != AP_LDAP_CHASEREFERRALS_SDKDEFAULT) { |
||||
/* Set options for rebind and referrals. */ |
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01278) |
||||
"LDAP: Setting referrals to %s.", |
||||
@@ -391,7 +392,9 @@ |
||||
uldap_connection_unbind(ldc); |
||||
return(result->rc); |
||||
} |
||||
+ } |
||||
|
||||
+ if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) { |
||||
if ((ldc->ReferralHopLimit != AP_LDAP_HOPLIMIT_UNSET) && ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) { |
||||
/* Referral hop limit - only if referrals are enabled and a hop limit is explicitly requested */ |
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, APLOGNO(01280) |
||||
@@ -2584,15 +2587,25 @@ |
||||
|
||||
static const char *util_ldap_set_chase_referrals(cmd_parms *cmd, |
||||
void *config, |
||||
- int mode) |
||||
+ const char *arg) |
||||
{ |
||||
util_ldap_config_t *dc = config; |
||||
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, cmd->server, APLOGNO(01311) |
||||
- "LDAP: Setting referral chasing %s", |
||||
- (mode == AP_LDAP_CHASEREFERRALS_ON) ? "ON" : "OFF"); |
||||
+ "LDAP: Setting referral chasing %s", arg); |
||||
|
||||
- dc->ChaseReferrals = mode; |
||||
+ if (0 == strcasecmp(arg, "on")) { |
||||
+ dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_ON; |
||||
+ } |
||||
+ else if (0 == strcasecmp(arg, "off")) { |
||||
+ dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_OFF; |
||||
+ } |
||||
+ else if (0 == strcasecmp(arg, "default")) { |
||||
+ dc->ChaseReferrals = AP_LDAP_CHASEREFERRALS_SDKDEFAULT; |
||||
+ } |
||||
+ else { |
||||
+ return "LDAPReferrals must be 'on', 'off', or 'default'"; |
||||
+ } |
||||
|
||||
return(NULL); |
||||
} |
||||
@@ -3116,9 +3129,9 @@ |
||||
"Specify the LDAP socket connection timeout in seconds " |
||||
"(default: 10)"), |
||||
|
||||
- AP_INIT_FLAG("LDAPReferrals", util_ldap_set_chase_referrals, |
||||
+ AP_INIT_TAKE1("LDAPReferrals", util_ldap_set_chase_referrals, |
||||
NULL, OR_AUTHCFG, |
||||
- "Choose whether referrals are chased ['ON'|'OFF']. Default 'ON'"), |
||||
+ "Choose whether referrals are chased ['ON'|'OFF'|'DEFAULT']. Default 'ON'"), |
||||
|
||||
AP_INIT_TAKE1("LDAPReferralHopLimit", util_ldap_set_referral_hop_limit, |
||||
NULL, OR_AUTHCFG, |
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
diff --git a/modules/aaa/mod_authz_dbd.c b/modules/aaa/mod_authz_dbd.c |
||||
index 1a456fe..6a0f705 100644 |
||||
--- a/modules/aaa/mod_authz_dbd.c |
||||
+++ b/modules/aaa/mod_authz_dbd.c |
||||
@@ -116,7 +116,7 @@ static int authz_dbd_login(request_rec *r, authz_dbd_cfg *cfg, |
||||
const char *newuri = NULL; |
||||
int nrows; |
||||
const char *message; |
||||
- ap_dbd_t *dbd = dbd_handle(r); |
||||
+ ap_dbd_t *dbd; |
||||
apr_dbd_prepared_t *query; |
||||
apr_dbd_results_t *res = NULL; |
||||
apr_dbd_row_t *row = NULL; |
||||
@@ -126,6 +126,16 @@ static int authz_dbd_login(request_rec *r, authz_dbd_cfg *cfg, |
||||
"No query configured for %s!", action); |
||||
return HTTP_INTERNAL_SERVER_ERROR; |
||||
} |
||||
+ |
||||
+ dbd = dbd_handle(r); |
||||
+ if (dbd == NULL) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02902) |
||||
+ "No db handle available for %s! " |
||||
+ "Check your database access", |
||||
+ action); |
||||
+ return HTTP_INTERNAL_SERVER_ERROR; |
||||
+ } |
||||
+ |
||||
query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING); |
||||
if (query == NULL) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01643) |
||||
@@ -202,7 +212,7 @@ static int authz_dbd_group_query(request_rec *r, authz_dbd_cfg *cfg, |
||||
/* SELECT group FROM authz WHERE user = %s */ |
||||
int rv; |
||||
const char *message; |
||||
- ap_dbd_t *dbd = dbd_handle(r); |
||||
+ ap_dbd_t *dbd; |
||||
apr_dbd_prepared_t *query; |
||||
apr_dbd_results_t *res = NULL; |
||||
apr_dbd_row_t *row = NULL; |
||||
@@ -212,6 +222,15 @@ static int authz_dbd_group_query(request_rec *r, authz_dbd_cfg *cfg, |
||||
"No query configured for dbd-group!"); |
||||
return HTTP_INTERNAL_SERVER_ERROR; |
||||
} |
||||
+ |
||||
+ dbd = dbd_handle(r); |
||||
+ if (dbd == NULL) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02903) |
||||
+ "No db handle available for dbd-query! " |
||||
+ "Check your database access"); |
||||
+ return HTTP_INTERNAL_SERVER_ERROR; |
||||
+ } |
||||
+ |
||||
query = apr_hash_get(dbd->prepared, cfg->query, APR_HASH_KEY_STRING); |
||||
if (query == NULL) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01650) |
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
--- a/server/mpm/event/event.c |
||||
+++ a/server/mpm/event/event.c |
||||
@@ -2735,6 +2735,7 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s) |
||||
|
||||
/* we've been told to restart */ |
||||
apr_signal(SIGHUP, SIG_IGN); |
||||
+ apr_signal(AP_SIG_GRACEFUL, SIG_IGN); |
||||
|
||||
if (one_process) { |
||||
/* not worth thinking about */ |
@ -0,0 +1,140 @@
@@ -0,0 +1,140 @@
|
||||
diff --git a/include/ap_mmn.h b/include/ap_mmn.h |
||||
index 89c4140..82a0acb 100644 |
||||
--- a/include/ap_mmn.h |
||||
+++ b/include/ap_mmn.h |
||||
@@ -418,6 +418,7 @@ |
||||
* ap_proxy_pass_brigade() |
||||
* 20120211.22 (2.4.5-dev) No longer prevent usage of strtoul() |
||||
* 20120211.23 (2.4.5-dev) Add ap_proxy_clear_connection() |
||||
+ * 20120211.24 (2.4.7-dev) add open_htaccess hook. |
||||
*/ |
||||
|
||||
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ |
||||
@@ -425,7 +426,7 @@ |
||||
#ifndef MODULE_MAGIC_NUMBER_MAJOR |
||||
#define MODULE_MAGIC_NUMBER_MAJOR 20120211 |
||||
#endif |
||||
-#define MODULE_MAGIC_NUMBER_MINOR 23 /* 0...n */ |
||||
+#define MODULE_MAGIC_NUMBER_MINOR 24 /* 0...n */ |
||||
|
||||
/** |
||||
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a |
||||
diff --git a/include/http_config.h b/include/http_config.h |
||||
index 7ee3760..c93c3b2 100644 |
||||
--- a/include/http_config.h |
||||
+++ b/include/http_config.h |
||||
@@ -1322,6 +1322,31 @@ AP_DECLARE_HOOK(int,quick_handler,(request_rec *r, int lookup_uri)) |
||||
AP_DECLARE_HOOK(void,optional_fn_retrieve,(void)) |
||||
|
||||
/** |
||||
+ * Allow modules to open htaccess files or perform operations before doing so |
||||
+ * @param r The current request |
||||
+ * @param dir_name The directory for which the htaccess file should be opened |
||||
+ * @param access_name The filename for which the htaccess file should be opened |
||||
+ * @param conffile Where the pointer to the opened ap_configfile_t must be |
||||
+ * stored |
||||
+ * @param full_name Where the full file name of the htaccess file must be |
||||
+ * stored. |
||||
+ * @return APR_SUCCESS on success, |
||||
+ * APR_ENOENT or APR_ENOTDIR if no htaccess file exists, |
||||
+ * AP_DECLINED to let later modules do the opening, |
||||
+ * any other error code on error. |
||||
+ */ |
||||
+AP_DECLARE_HOOK(apr_status_t,open_htaccess, |
||||
+ (request_rec *r, const char *dir_name, const char *access_name, |
||||
+ ap_configfile_t **conffile, const char **full_name)) |
||||
+ |
||||
+/** |
||||
+ * Core internal function, use ap_run_open_htaccess() instead. |
||||
+ */ |
||||
+apr_status_t ap_open_htaccess(request_rec *r, const char *dir_name, |
||||
+ const char *access_name, ap_configfile_t **conffile, |
||||
+ const char **full_name); |
||||
+ |
||||
+/** |
||||
* A generic pool cleanup that will reset a pointer to NULL. For use with |
||||
* apr_pool_cleanup_register. |
||||
* @param data The address of the pointer |
||||
diff --git a/server/config.c b/server/config.c |
||||
index c1aae17..265744e 100644 |
||||
--- a/server/config.c |
||||
+++ b/server/config.c |
||||
@@ -80,6 +80,7 @@ APR_HOOK_STRUCT( |
||||
APR_HOOK_LINK(quick_handler) |
||||
APR_HOOK_LINK(optional_fn_retrieve) |
||||
APR_HOOK_LINK(test_config) |
||||
+ APR_HOOK_LINK(open_htaccess) |
||||
) |
||||
|
||||
AP_IMPLEMENT_HOOK_RUN_ALL(int, header_parser, |
||||
@@ -171,6 +172,12 @@ AP_IMPLEMENT_HOOK_RUN_FIRST(int, handler, (request_rec *r), |
||||
AP_IMPLEMENT_HOOK_RUN_FIRST(int, quick_handler, (request_rec *r, int lookup), |
||||
(r, lookup), DECLINED) |
||||
|
||||
+AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, open_htaccess, |
||||
+ (request_rec *r, const char *dir_name, const char *access_name, |
||||
+ ap_configfile_t **conffile, const char **full_name), |
||||
+ (r, dir_name, access_name, conffile, full_name), |
||||
+ AP_DECLINED) |
||||
+ |
||||
/* hooks with no args are implemented last, after disabling APR hook probes */ |
||||
#if defined(APR_HOOK_PROBES_ENABLED) |
||||
#undef APR_HOOK_PROBES_ENABLED |
||||
@@ -2073,14 +2080,23 @@ AP_DECLARE(int) ap_process_config_tree(server_rec *s, |
||||
return OK; |
||||
} |
||||
|
||||
+apr_status_t ap_open_htaccess(request_rec *r, const char *dir_name, |
||||
+ const char *access_name, |
||||
+ ap_configfile_t **conffile, |
||||
+ const char **full_name) |
||||
+{ |
||||
+ *full_name = ap_make_full_path(r->pool, dir_name, access_name); |
||||
+ return ap_pcfg_openfile(conffile, r->pool, *full_name); |
||||
+} |
||||
+ |
||||
AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result, |
||||
request_rec *r, int override, |
||||
int override_opts, apr_table_t *override_list, |
||||
- const char *d, const char *access_name) |
||||
+ const char *d, const char *access_names) |
||||
{ |
||||
ap_configfile_t *f = NULL; |
||||
cmd_parms parms; |
||||
- char *filename = NULL; |
||||
+ const char *filename; |
||||
const struct htaccess_result *cache; |
||||
struct htaccess_result *new; |
||||
ap_conf_vector_t *dc = NULL; |
||||
@@ -2104,15 +2120,11 @@ AP_CORE_DECLARE(int) ap_parse_htaccess(ap_conf_vector_t **result, |
||||
parms.path = apr_pstrdup(r->pool, d); |
||||
|
||||
/* loop through the access names and find the first one */ |
||||
- while (access_name[0]) { |
||||
- /* AFAICT; there is no use of the actual 'filename' against |
||||
- * any canonicalization, so we will simply take the given |
||||
- * name, ignoring case sensitivity and aliases |
||||
- */ |
||||
- filename = ap_make_full_path(r->pool, d, |
||||
- ap_getword_conf(r->pool, &access_name)); |
||||
- status = ap_pcfg_openfile(&f, r->pool, filename); |
||||
+ while (access_names[0]) { |
||||
+ const char *access_name = ap_getword_conf(r->pool, &access_names); |
||||
|
||||
+ filename = NULL; |
||||
+ status = ap_run_open_htaccess(r, d, access_name, &f, &filename); |
||||
if (status == APR_SUCCESS) { |
||||
const char *errmsg; |
||||
ap_directive_t *temptree = NULL; |
||||
diff --git a/server/core.c b/server/core.c |
||||
index f3965ca..85f876b 100644 |
||||
--- a/server/core.c |
||||
+++ b/server/core.c |
||||
@@ -4930,6 +4930,7 @@ static void register_hooks(apr_pool_t *p) |
||||
ap_hook_insert_network_bucket(core_insert_network_bucket, NULL, NULL, |
||||
APR_HOOK_REALLY_LAST); |
||||
ap_hook_dirwalk_stat(core_dirwalk_stat, NULL, NULL, APR_HOOK_REALLY_LAST); |
||||
+ ap_hook_open_htaccess(ap_open_htaccess, NULL, NULL, APR_HOOK_REALLY_LAST); |
||||
|
||||
/* register the core's insert_filter hook and register core-provided |
||||
* filters |
@ -0,0 +1,313 @@
@@ -0,0 +1,313 @@
|
||||
# ./pullrev.sh 1332643 1345599 1487772 |
||||
|
||||
https://bugzilla.redhat.com//show_bug.cgi?id=809599 |
||||
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1332643 |
||||
http://svn.apache.org/viewvc?view=revision&revision=1345599 |
||||
http://svn.apache.org/viewvc?view=revision&revision=1487772 |
||||
|
||||
--- httpd-2.4.6/modules/ssl/mod_ssl.c.r1332643+ |
||||
+++ httpd-2.4.6/modules/ssl/mod_ssl.c |
||||
@@ -413,6 +413,37 @@ int ssl_engine_disable(conn_rec *c) |
||||
return 1; |
||||
} |
||||
|
||||
+static int modssl_register_npn(conn_rec *c, |
||||
+ ssl_npn_advertise_protos advertisefn, |
||||
+ ssl_npn_proto_negotiated negotiatedfn) |
||||
+{ |
||||
+#ifdef HAVE_TLS_NPN |
||||
+ SSLConnRec *sslconn = myConnConfig(c); |
||||
+ |
||||
+ if (!sslconn) { |
||||
+ return DECLINED; |
||||
+ } |
||||
+ |
||||
+ if (!sslconn->npn_advertfns) { |
||||
+ sslconn->npn_advertfns = |
||||
+ apr_array_make(c->pool, 5, sizeof(ssl_npn_advertise_protos)); |
||||
+ sslconn->npn_negofns = |
||||
+ apr_array_make(c->pool, 5, sizeof(ssl_npn_proto_negotiated)); |
||||
+ } |
||||
+ |
||||
+ if (advertisefn) |
||||
+ APR_ARRAY_PUSH(sslconn->npn_advertfns, ssl_npn_advertise_protos) = |
||||
+ advertisefn; |
||||
+ if (negotiatedfn) |
||||
+ APR_ARRAY_PUSH(sslconn->npn_negofns, ssl_npn_proto_negotiated) = |
||||
+ negotiatedfn; |
||||
+ |
||||
+ return OK; |
||||
+#else |
||||
+ return DECLINED; |
||||
+#endif |
||||
+} |
||||
+ |
||||
int ssl_init_ssl_connection(conn_rec *c, request_rec *r) |
||||
{ |
||||
SSLSrvConfigRec *sc; |
||||
@@ -584,6 +615,7 @@ static void ssl_register_hooks(apr_pool_ |
||||
|
||||
APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable); |
||||
APR_REGISTER_OPTIONAL_FN(ssl_engine_disable); |
||||
+ APR_REGISTER_OPTIONAL_FN(modssl_register_npn); |
||||
|
||||
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl", |
||||
AUTHZ_PROVIDER_VERSION, |
||||
--- httpd-2.4.6/modules/ssl/mod_ssl.h.r1332643+ |
||||
+++ httpd-2.4.6/modules/ssl/mod_ssl.h |
||||
@@ -63,5 +63,40 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_e |
||||
|
||||
APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *)); |
||||
|
||||
+/** The npn_advertise_protos callback allows another modules to add |
||||
+ * entries to the list of protocol names advertised by the server |
||||
+ * during the Next Protocol Negotiation (NPN) portion of the SSL |
||||
+ * handshake. The callback is given the connection and an APR array; |
||||
+ * it should push one or more char*'s pointing to NUL-terminated |
||||
+ * strings (such as "http/1.1" or "spdy/2") onto the array and return |
||||
+ * OK. To prevent further processing of (other modules') callbacks, |
||||
+ * return DONE. */ |
||||
+typedef int (*ssl_npn_advertise_protos)(conn_rec *connection, |
||||
+ apr_array_header_t *protos); |
||||
+ |
||||
+/** The npn_proto_negotiated callback allows other modules to discover |
||||
+ * the name of the protocol that was chosen during the Next Protocol |
||||
+ * Negotiation (NPN) portion of the SSL handshake. Note that this may |
||||
+ * be the empty string (in which case modules should probably assume |
||||
+ * HTTP), or it may be a protocol that was never even advertised by |
||||
+ * the server. The callback is given the connection, a |
||||
+ * non-NUL-terminated string containing the protocol name, and the |
||||
+ * length of the string; it should do something appropriate |
||||
+ * (i.e. insert or remove filters) and return OK. To prevent further |
||||
+ * processing of (other modules') callbacks, return DONE. */ |
||||
+typedef int (*ssl_npn_proto_negotiated)(conn_rec *connection, |
||||
+ const char *proto_name, |
||||
+ apr_size_t proto_name_len); |
||||
+ |
||||
+/* An optional function which can be used to register a pair of |
||||
+ * callbacks for NPN handling. This optional function should be |
||||
+ * invoked from a pre_connection hook which runs *after* mod_ssl.c's |
||||
+ * pre_connection hook. The function returns OK if the callbacks are |
||||
+ * register, or DECLINED otherwise (for example if mod_ssl does not |
||||
+l * support NPN). */ |
||||
+APR_DECLARE_OPTIONAL_FN(int, modssl_register_npn, (conn_rec *conn, |
||||
+ ssl_npn_advertise_protos advertisefn, |
||||
+ ssl_npn_proto_negotiated negotiatedfn)); |
||||
+ |
||||
#endif /* __MOD_SSL_H__ */ |
||||
/** @} */ |
||||
--- httpd-2.4.6/modules/ssl/ssl_engine_init.c.r1332643+ |
||||
+++ httpd-2.4.6/modules/ssl/ssl_engine_init.c |
||||
@@ -725,6 +725,11 @@ static void ssl_init_ctx_callbacks(serve |
||||
#endif |
||||
|
||||
SSL_CTX_set_info_callback(ctx, ssl_callback_Info); |
||||
+ |
||||
+#ifdef HAVE_TLS_NPN |
||||
+ SSL_CTX_set_next_protos_advertised_cb( |
||||
+ ctx, ssl_callback_AdvertiseNextProtos, NULL); |
||||
+#endif |
||||
} |
||||
|
||||
static void ssl_init_ctx_verify(server_rec *s, |
||||
--- httpd-2.4.6/modules/ssl/ssl_engine_io.c.r1332643+ |
||||
+++ httpd-2.4.6/modules/ssl/ssl_engine_io.c |
||||
@@ -297,6 +297,7 @@ typedef struct { |
||||
apr_pool_t *pool; |
||||
char buffer[AP_IOBUFSIZE]; |
||||
ssl_filter_ctx_t *filter_ctx; |
||||
+ int npn_finished; /* 1 if NPN has finished, 0 otherwise */ |
||||
} bio_filter_in_ctx_t; |
||||
|
||||
/* |
||||
@@ -1400,6 +1401,37 @@ static apr_status_t ssl_io_filter_input( |
||||
APR_BRIGADE_INSERT_TAIL(bb, bucket); |
||||
} |
||||
|
||||
+#ifdef HAVE_TLS_NPN |
||||
+ /* By this point, Next Protocol Negotiation (NPN) should be completed (if |
||||
+ * our version of OpenSSL supports it). If we haven't already, find out |
||||
+ * which protocol was decided upon and inform other modules by calling |
||||
+ * npn_proto_negotiated_hook. */ |
||||
+ if (!inctx->npn_finished) { |
||||
+ SSLConnRec *sslconn = myConnConfig(f->c); |
||||
+ const unsigned char *next_proto = NULL; |
||||
+ unsigned next_proto_len = 0; |
||||
+ int n; |
||||
+ |
||||
+ if (sslconn->npn_negofns) { |
||||
+ SSL_get0_next_proto_negotiated( |
||||
+ inctx->ssl, &next_proto, &next_proto_len); |
||||
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, f->c, |
||||
+ APLOGNO(02306) "SSL NPN negotiated protocol: '%*s'", |
||||
+ next_proto_len, (const char*)next_proto); |
||||
+ |
||||
+ for (n = 0; n < sslconn->npn_negofns->nelts; n++) { |
||||
+ ssl_npn_proto_negotiated fn = |
||||
+ APR_ARRAY_IDX(sslconn->npn_negofns, n, ssl_npn_proto_negotiated); |
||||
+ |
||||
+ if (fn(f->c, (const char *)next_proto, next_proto_len) == DONE) |
||||
+ break; |
||||
+ } |
||||
+ } |
||||
+ |
||||
+ inctx->npn_finished = 1; |
||||
+ } |
||||
+#endif |
||||
+ |
||||
return APR_SUCCESS; |
||||
} |
||||
|
||||
@@ -1881,6 +1913,7 @@ static void ssl_io_input_add_filter(ssl_ |
||||
inctx->block = APR_BLOCK_READ; |
||||
inctx->pool = c->pool; |
||||
inctx->filter_ctx = filter_ctx; |
||||
+ inctx->npn_finished = 0; |
||||
} |
||||
|
||||
/* The request_rec pointer is passed in here only to ensure that the |
||||
--- httpd-2.4.6/modules/ssl/ssl_engine_kernel.c.r1332643+ |
||||
+++ httpd-2.4.6/modules/ssl/ssl_engine_kernel.c |
||||
@@ -2161,6 +2161,97 @@ int ssl_callback_SessionTicket(SSL *ssl, |
||||
} |
||||
#endif /* HAVE_TLS_SESSION_TICKETS */ |
||||
|
||||
+#ifdef HAVE_TLS_NPN |
||||
+/* |
||||
+ * This callback function is executed when SSL needs to decide what protocols |
||||
+ * to advertise during Next Protocol Negotiation (NPN). It must produce a |
||||
+ * string in wire format -- a sequence of length-prefixed strings -- indicating |
||||
+ * the advertised protocols. Refer to SSL_CTX_set_next_protos_advertised_cb |
||||
+ * in OpenSSL for reference. |
||||
+ */ |
||||
+int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data_out, |
||||
+ unsigned int *size_out, void *arg) |
||||
+{ |
||||
+ conn_rec *c = (conn_rec*)SSL_get_app_data(ssl); |
||||
+ SSLConnRec *sslconn = myConnConfig(c); |
||||
+ apr_array_header_t *protos; |
||||
+ int num_protos; |
||||
+ unsigned int size; |
||||
+ int i; |
||||
+ unsigned char *data; |
||||
+ unsigned char *start; |
||||
+ |
||||
+ *data_out = NULL; |
||||
+ *size_out = 0; |
||||
+ |
||||
+ /* If the connection object is not available, or there are no NPN |
||||
+ * hooks registered, then there's nothing for us to do. */ |
||||
+ if (c == NULL || sslconn->npn_advertfns == NULL) { |
||||
+ return SSL_TLSEXT_ERR_NOACK; |
||||
+ } |
||||
+ |
||||
+ /* Invoke our npn_advertise_protos hook, giving other modules a chance to |
||||
+ * add alternate protocol names to advertise. */ |
||||
+ protos = apr_array_make(c->pool, 0, sizeof(char *)); |
||||
+ for (i = 0; i < sslconn->npn_advertfns->nelts; i++) { |
||||
+ ssl_npn_advertise_protos fn = |
||||
+ APR_ARRAY_IDX(sslconn->npn_advertfns, i, ssl_npn_advertise_protos); |
||||
+ |
||||
+ if (fn(c, protos) == DONE) |
||||
+ break; |
||||
+ } |
||||
+ num_protos = protos->nelts; |
||||
+ |
||||
+ /* We now have a list of null-terminated strings; we need to concatenate |
||||
+ * them together into a single string, where each protocol name is prefixed |
||||
+ * by its length. First, calculate how long that string will be. */ |
||||
+ size = 0; |
||||
+ for (i = 0; i < num_protos; ++i) { |
||||
+ const char *string = APR_ARRAY_IDX(protos, i, const char*); |
||||
+ unsigned int length = strlen(string); |
||||
+ /* If the protocol name is too long (the length must fit in one byte), |
||||
+ * then log an error and skip it. */ |
||||
+ if (length > 255) { |
||||
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02307) |
||||
+ "SSL NPN protocol name too long (length=%u): %s", |
||||
+ length, string); |
||||
+ continue; |
||||
+ } |
||||
+ /* Leave room for the length prefix (one byte) plus the protocol name |
||||
+ * itself. */ |
||||
+ size += 1 + length; |
||||
+ } |
||||
+ |
||||
+ /* If there is nothing to advertise (either because no modules added |
||||
+ * anything to the protos array, or because all strings added to the array |
||||
+ * were skipped), then we're done. */ |
||||
+ if (size == 0) { |
||||
+ return SSL_TLSEXT_ERR_NOACK; |
||||
+ } |
||||
+ |
||||
+ /* Now we can build the string. Copy each protocol name string into the |
||||
+ * larger string, prefixed by its length. */ |
||||
+ data = apr_palloc(c->pool, size * sizeof(unsigned char)); |
||||
+ start = data; |
||||
+ for (i = 0; i < num_protos; ++i) { |
||||
+ const char *string = APR_ARRAY_IDX(protos, i, const char*); |
||||
+ apr_size_t length = strlen(string); |
||||
+ if (length > 255) |
||||
+ continue; |
||||
+ *start = (unsigned char)length; |
||||
+ ++start; |
||||
+ memcpy(start, string, length * sizeof(unsigned char)); |
||||
+ start += length; |
||||
+ } |
||||
+ |
||||
+ /* Success. */ |
||||
+ *data_out = data; |
||||
+ *size_out = size; |
||||
+ return SSL_TLSEXT_ERR_OK; |
||||
+} |
||||
+ |
||||
+#endif /* HAVE_TLS_NPN */ |
||||
+ |
||||
#ifndef OPENSSL_NO_SRP |
||||
|
||||
int ssl_callback_SRPServerParams(SSL *ssl, int *ad, void *arg) |
||||
--- httpd-2.4.6/modules/ssl/ssl_private.h.r1332643+ |
||||
+++ httpd-2.4.6/modules/ssl/ssl_private.h |
||||
@@ -98,6 +98,8 @@ |
||||
#include <openssl/x509_vfy.h> |
||||
#include <openssl/ocsp.h> |
||||
|
||||
+#include "mod_ssl.h" |
||||
+ |
||||
/* Avoid tripping over an engine build installed globally and detected |
||||
* when the user points at an explicit non-engine flavor of OpenSSL |
||||
*/ |
||||
@@ -139,6 +141,11 @@ |
||||
#define HAVE_FIPS |
||||
#endif |
||||
|
||||
+#if OPENSSL_VERSION_NUMBER >= 0x10001000L && !defined(OPENSSL_NO_NEXTPROTONEG) \ |
||||
+ && !defined(OPENSSL_NO_TLSEXT) |
||||
+#define HAVE_TLS_NPN |
||||
+#endif |
||||
+ |
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10000000) |
||||
#define MODSSL_SSL_CIPHER_CONST const |
||||
#define MODSSL_SSL_METHOD_CONST const |
||||
@@ -487,6 +494,12 @@ typedef struct { |
||||
* connection */ |
||||
} reneg_state; |
||||
|
||||
+#ifdef HAVE_TLS_NPN |
||||
+ /* Poor man's inter-module optional hooks for NPN. */ |
||||
+ apr_array_header_t *npn_advertfns; /* list of ssl_npn_advertise_protos callbacks */ |
||||
+ apr_array_header_t *npn_negofns; /* list of ssl_npn_proto_negotiated callbacks. */ |
||||
+#endif |
||||
+ |
||||
server_rec *server; |
||||
} SSLConnRec; |
||||
|
||||
@@ -842,6 +855,7 @@ int ssl_callback_ServerNameIndi |
||||
int ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *, |
||||
EVP_CIPHER_CTX *, HMAC_CTX *, int); |
||||
#endif |
||||
+int ssl_callback_AdvertiseNextProtos(SSL *ssl, const unsigned char **data, unsigned int *len, void *arg); |
||||
|
||||
/** Session Cache Support */ |
||||
void ssl_scache_init(server_rec *, apr_pool_t *); |
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c |
||||
index 2121892..6f904b2 100644 |
||||
--- a/modules/proxy/proxy_util.c |
||||
+++ b/modules/proxy/proxy_util.c |
||||
@@ -2838,33 +2838,48 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, |
||||
|
||||
connected = 1; |
||||
} |
||||
- /* |
||||
- * Put the entire worker to error state if |
||||
- * the PROXY_WORKER_IGNORE_ERRORS flag is not set. |
||||
- * Altrough some connections may be alive |
||||
- * no further connections to the worker could be made |
||||
- */ |
||||
- if (!connected && PROXY_WORKER_IS_USABLE(worker) && |
||||
- !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) { |
||||
- worker->s->error_time = apr_time_now(); |
||||
- worker->s->status |= PROXY_WORKER_IN_ERROR; |
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00959) |
||||
- "ap_proxy_connect_backend disabling worker for (%s) for %" |
||||
- APR_TIME_T_FMT "s", |
||||
- worker->s->hostname, apr_time_sec(worker->s->retry)); |
||||
+ |
||||
+ if (PROXY_WORKER_IS_USABLE(worker)) { |
||||
+ /* |
||||
+ * Put the entire worker to error state if |
||||
+ * the PROXY_WORKER_IGNORE_ERRORS flag is not set. |
||||
+ * Although some connections may be alive |
||||
+ * no further connections to the worker could be made |
||||
+ */ |
||||
+ if (!connected) { |
||||
+ if (!(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) { |
||||
+ worker->s->error_time = apr_time_now(); |
||||
+ worker->s->status |= PROXY_WORKER_IN_ERROR; |
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00959) |
||||
+ "ap_proxy_connect_backend disabling worker for (%s) for %" |
||||
+ APR_TIME_T_FMT "s", |
||||
+ worker->s->hostname, apr_time_sec(worker->s->retry)); |
||||
+ } |
||||
+ } |
||||
+ else { |
||||
+ if (worker->s->retries) { |
||||
+ /* |
||||
+ * A worker came back. So here is where we need to |
||||
+ * either reset all params to initial conditions or |
||||
+ * apply some sort of aging |
||||
+ */ |
||||
+ } |
||||
+ worker->s->error_time = 0; |
||||
+ worker->s->retries = 0; |
||||
+ } |
||||
+ return connected ? OK : DECLINED; |
||||
} |
||||
else { |
||||
- if (worker->s->retries) { |
||||
- /* |
||||
- * A worker came back. So here is where we need to |
||||
- * either reset all params to initial conditions or |
||||
- * apply some sort of aging |
||||
- */ |
||||
- } |
||||
- worker->s->error_time = 0; |
||||
- worker->s->retries = 0; |
||||
+ /* |
||||
+ * The worker is in error likely done by a different thread / process |
||||
+ * e.g. for a timeout or bad status. We should respect this and should |
||||
+ * not continue with a connection via this worker even if we got one. |
||||
+ */ |
||||
+ if (connected) { |
||||
+ socket_cleanup(conn); |
||||
+ } |
||||
+ return DECLINED; |
||||
} |
||||
- return connected ? OK : DECLINED; |
||||
} |
||||
|
||||
PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, |
@ -0,0 +1,154 @@
@@ -0,0 +1,154 @@
|
||||
Index: modules/aaa/mod_authz_owner.c |
||||
=================================================================== |
||||
--- a/modules/aaa/mod_authz_owner.c (revision 1420183) |
||||
+++ b/modules/aaa/mod_authz_owner.c (revision 1420184) |
||||
@@ -28,9 +28,8 @@ |
||||
#include "http_request.h" |
||||
|
||||
#include "mod_auth.h" |
||||
+#include "mod_authz_owner.h" |
||||
|
||||
-APR_DECLARE_OPTIONAL_FN(char*, authz_owner_get_file_group, (request_rec *r)); |
||||
- |
||||
static const command_rec authz_owner_cmds[] = |
||||
{ |
||||
{NULL} |
||||
Index: modules/aaa/mod_authz_owner.h |
||||
=================================================================== |
||||
--- a/modules/aaa/mod_authz_owner.h (revision 0) |
||||
+++ b/modules/aaa/mod_authz_owner.h (revision 1420184) |
||||
@@ -0,0 +1,27 @@ |
||||
+/* 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. |
||||
+ */ |
||||
+ |
||||
+#ifndef MOD_AUTHZ_OWNER_H |
||||
+#define MOD_AUTHZ_OWNER_H |
||||
+ |
||||
+#include "http_request.h" |
||||
+ |
||||
+/* mod_authz_owner exports an optional function which retrieves the |
||||
+ * group name of the file identified by r->filename, if available, or |
||||
+ * else returns NULL. */ |
||||
+APR_DECLARE_OPTIONAL_FN(char*, authz_owner_get_file_group, (request_rec *r)); |
||||
+ |
||||
+#endif /* MOD_AUTHZ_OWNER_H */ |
||||
Index: modules/aaa/mod_authz_groupfile.c |
||||
=================================================================== |
||||
--- a/modules/aaa/mod_authz_groupfile.c (revision 1420183) |
||||
+++ b/modules/aaa/mod_authz_groupfile.c (revision 1420184) |
||||
@@ -55,13 +55,12 @@ |
||||
#include "util_varbuf.h" |
||||
|
||||
#include "mod_auth.h" |
||||
+#include "mod_authz_owner.h" |
||||
|
||||
typedef struct { |
||||
char *groupfile; |
||||
} authz_groupfile_config_rec; |
||||
|
||||
-APR_DECLARE_OPTIONAL_FN(char*, authz_owner_get_file_group, (request_rec *r)); |
||||
- |
||||
static void *create_authz_groupfile_dir_config(apr_pool_t *p, char *d) |
||||
{ |
||||
authz_groupfile_config_rec *conf = apr_palloc(p, sizeof(*conf)); |
||||
@@ -200,7 +199,7 @@ |
||||
return AUTHZ_DENIED; |
||||
} |
||||
|
||||
-APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group; |
||||
+static APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group; |
||||
|
||||
static authz_status filegroup_check_authorization(request_rec *r, |
||||
const char *require_args, |
||||
@@ -279,10 +278,14 @@ |
||||
NULL, |
||||
}; |
||||
|
||||
-static void register_hooks(apr_pool_t *p) |
||||
+ |
||||
+static void authz_groupfile_getfns(void) |
||||
{ |
||||
authz_owner_get_file_group = APR_RETRIEVE_OPTIONAL_FN(authz_owner_get_file_group); |
||||
+} |
||||
|
||||
+static void register_hooks(apr_pool_t *p) |
||||
+{ |
||||
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "group", |
||||
AUTHZ_PROVIDER_VERSION, |
||||
&authz_group_provider, |
||||
@@ -291,6 +294,7 @@ |
||||
AUTHZ_PROVIDER_VERSION, |
||||
&authz_filegroup_provider, |
||||
AP_AUTH_INTERNAL_PER_CONF); |
||||
+ ap_hook_optional_fn_retrieve(authz_groupfile_getfns, NULL, NULL, APR_HOOK_MIDDLE); |
||||
} |
||||
|
||||
AP_DECLARE_MODULE(authz_groupfile) = |
||||
Index: modules/aaa/mod_authz_dbm.c |
||||
=================================================================== |
||||
--- a/modules/aaa/mod_authz_dbm.c (revision 1420183) |
||||
+++ b/modules/aaa/mod_authz_dbm.c (revision 1420184) |
||||
@@ -29,6 +29,7 @@ |
||||
#include "http_request.h" /* for ap_hook_(check_user_id | auth_checker)*/ |
||||
|
||||
#include "mod_auth.h" |
||||
+#include "mod_authz_owner.h" |
||||
|
||||
typedef struct { |
||||
const char *grpfile; |
||||
@@ -35,9 +36,7 @@ |
||||
const char *dbmtype; |
||||
} authz_dbm_config_rec; |
||||
|
||||
-APR_DECLARE_OPTIONAL_FN(char*, authz_owner_get_file_group, (request_rec *r)); |
||||
|
||||
- |
||||
/* This should go into APR; perhaps with some nice |
||||
* caching/locking/flocking of the open dbm file. |
||||
*/ |
||||
@@ -199,7 +198,7 @@ |
||||
return AUTHZ_DENIED; |
||||
} |
||||
|
||||
-APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group; |
||||
+static APR_OPTIONAL_FN_TYPE(authz_owner_get_file_group) *authz_owner_get_file_group; |
||||
|
||||
static authz_status dbmfilegroup_check_authorization(request_rec *r, |
||||
const char *require_args, |
||||
@@ -279,11 +278,13 @@ |
||||
NULL, |
||||
}; |
||||
|
||||
+static void authz_dbm_getfns(void) |
||||
+{ |
||||
+ authz_owner_get_file_group = APR_RETRIEVE_OPTIONAL_FN(authz_owner_get_file_group); |
||||
+} |
||||
|
||||
static void register_hooks(apr_pool_t *p) |
||||
{ |
||||
- authz_owner_get_file_group = APR_RETRIEVE_OPTIONAL_FN(authz_owner_get_file_group); |
||||
- |
||||
ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "dbm-group", |
||||
AUTHZ_PROVIDER_VERSION, |
||||
&authz_dbmgroup_provider, |
||||
@@ -292,6 +293,7 @@ |
||||
AUTHZ_PROVIDER_VERSION, |
||||
&authz_dbmfilegroup_provider, |
||||
AP_AUTH_INTERNAL_PER_CONF); |
||||
+ ap_hook_optional_fn_retrieve(authz_dbm_getfns, NULL, NULL, APR_HOOK_MIDDLE); |
||||
} |
||||
|
||||
AP_DECLARE_MODULE(authz_dbm) = |
@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
|
||||
--- a/server/core.c 2013/07/24 09:49:38 1506473 |
||||
+++ b/server/core.c 2013/07/24 09:51:14 1506474 |
||||
@@ -1481,7 +1481,9 @@ |
||||
conf->ap_document_root = arg; |
||||
} |
||||
else { |
||||
- return "DocumentRoot must be a directory"; |
||||
+ return apr_psprintf(cmd->pool, |
||||
+ "DocumentRoot '%s' is not a directory, or is not readable", |
||||
+ arg); |
||||
} |
||||
} |
||||
return NULL; |
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
# ./pullrev.sh 1507681 1533447 |
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1004046 |
||||
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1507681 |
||||
http://svn.apache.org/viewvc?view=revision&revision=1533447 |
||||
|
||||
--- httpd-2.4.6/modules/dav/main/mod_dav.c |
||||
+++ httpd-2.4.6/modules/dav/main/mod_dav.c |
||||
@@ -2756,7 +2756,7 @@ |
||||
* The multistatus responses will contain the information about any |
||||
* resource that fails the validation. |
||||
* |
||||
- * We check the parent resource, too, since this is a MOVE. Moving the |
||||
+ * We check the parent resource, too, if this is a MOVE. Moving the |
||||
* resource effectively removes it from the parent collection, so we |
||||
* must ensure that we have met the appropriate conditions. |
||||
* |
||||
@@ -2765,7 +2765,9 @@ |
||||
*/ |
||||
if ((err = dav_validate_request(r, resource, depth, NULL, |
||||
&multi_response, |
||||
- DAV_VALIDATE_PARENT |
||||
+ (is_move ? DAV_VALIDATE_PARENT |
||||
+ : DAV_VALIDATE_RESOURCE |
||||
+ | DAV_VALIDATE_NO_MODIFY) |
||||
| DAV_VALIDATE_USE_424, |
||||
NULL)) != NULL) { |
||||
err = dav_push_error(r->pool, err->status, 0, |
||||
--- httpd-2.4.6/modules/dav/main/util.c |
||||
+++ httpd-2.4.6/modules/dav/main/util.c |
||||
@@ -954,13 +954,16 @@ |
||||
/* |
||||
** For methods other than LOCK: |
||||
** |
||||
- ** If we have no locks, then <seen_locktoken> can be set to true -- |
||||
+ ** If we have no locks or if the resource is not being modified |
||||
+ ** (per RFC 4918 the lock token is not required on resources |
||||
+ ** we are not changing), then <seen_locktoken> can be set to true -- |
||||
** pretending that we've already met the requirement of seeing one |
||||
** of the resource's locks in the If: header. |
||||
** |
||||
** Otherwise, it must be cleared and we'll look for one. |
||||
*/ |
||||
- seen_locktoken = (lock_list == NULL); |
||||
+ seen_locktoken = (lock_list == NULL |
||||
+ || flags & DAV_VALIDATE_NO_MODIFY); |
||||
} |
||||
|
||||
/* |
||||
--- httpd-2.4.6/modules/dav/main/mod_dav.h |
||||
+++ httpd-2.4.6/modules/dav/main/mod_dav.h |
||||
@@ -1297,6 +1297,9 @@ |
||||
the 424 DAV:response */ |
||||
#define DAV_VALIDATE_USE_424 0x0080 /* return 424 status, not 207 */ |
||||
#define DAV_VALIDATE_IS_PARENT 0x0100 /* for internal use */ |
||||
+#define DAV_VALIDATE_NO_MODIFY 0x0200 /* resource is not being modified |
||||
+ so allow even if lock token |
||||
+ is not provided */ |
||||
|
||||
/* Lock-null related public lock functions */ |
||||
DAV_DECLARE(int) dav_get_resource_state(request_rec *r, |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
--- a/modules/proxy/mod_proxy_fcgi.c 2013/09/18 11:17:28 1524367 |
||||
+++ b/modules/proxy/mod_proxy_fcgi.c 2013/09/18 11:18:02 1524368 |
||||
@@ -429,15 +429,13 @@ |
||||
ob = apr_brigade_create(r->pool, c->bucket_alloc); |
||||
|
||||
while (! done) { |
||||
- apr_interval_time_t timeout = conn->worker->s->timeout; |
||||
+ apr_interval_time_t timeout; |
||||
apr_size_t len; |
||||
int n; |
||||
|
||||
/* We need SOME kind of timeout here, or virtually anything will |
||||
* cause timeout errors. */ |
||||
- if (! conn->worker->s->timeout_set) { |
||||
- timeout = apr_time_from_sec(30); |
||||
- } |
||||
+ apr_socket_timeout_get(conn->sock, &timeout); |
||||
|
||||
rv = apr_poll(&pfd, 1, &n, timeout); |
||||
if (rv != APR_SUCCESS) { |
@ -0,0 +1,62 @@
@@ -0,0 +1,62 @@
|
||||
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h |
||||
index 81fd14c..cd1710f 100644 |
||||
--- a/modules/proxy/mod_proxy.h |
||||
+++ b/modules/proxy/mod_proxy.h |
||||
@@ -856,6 +856,17 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, |
||||
PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, |
||||
proxy_conn_rec *conn, |
||||
conn_rec *c, server_rec *s); |
||||
+ |
||||
+/** |
||||
+ * Determine if proxy connection can potentially be reused at the |
||||
+ * end of this request. |
||||
+ * @param conn proxy connection |
||||
+ * @return non-zero if reusable, 0 otherwise |
||||
+ * @note Even if this function returns non-zero, the connection may |
||||
+ * be subsequently marked for closure. |
||||
+ */ |
||||
+PROXY_DECLARE(int) ap_proxy_connection_reusable(proxy_conn_rec *conn); |
||||
+ |
||||
/** |
||||
* Signal the upstream chain that the connection to the backend broke in the |
||||
* middle of the response. This is done by sending an error bucket with |
||||
diff --git a/modules/proxy/mod_proxy_fcgi.c b/modules/proxy/mod_proxy_fcgi.c |
||||
index 0f84416..c57696a 100644 |
||||
--- a/modules/proxy/mod_proxy_fcgi.c |
||||
+++ b/modules/proxy/mod_proxy_fcgi.c |
||||
@@ -247,7 +247,7 @@ static apr_status_t send_begin_request(proxy_conn_rec *conn, int request_id) |
||||
|
||||
brb.roleB1 = ((FCGI_RESPONDER >> 8) & 0xff); |
||||
brb.roleB0 = ((FCGI_RESPONDER) & 0xff); |
||||
- brb.flags = FCGI_KEEP_CONN; |
||||
+ brb.flags = ap_proxy_connection_reusable(conn) ? FCGI_KEEP_CONN : 0; |
||||
brb.reserved[0] = 0; |
||||
brb.reserved[1] = 0; |
||||
brb.reserved[2] = 0; |
||||
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c |
||||
index 8bc9fab..ca70ae4 100644 |
||||
--- a/modules/proxy/proxy_util.c |
||||
+++ b/modules/proxy/proxy_util.c |
||||
@@ -1333,6 +1333,13 @@ static void init_conn_pool(apr_pool_t *p, proxy_worker *worker) |
||||
worker->cp = cp; |
||||
} |
||||
|
||||
+PROXY_DECLARE(int) ap_proxy_connection_reusable(proxy_conn_rec *conn) |
||||
+{ |
||||
+ proxy_worker *worker = conn->worker; |
||||
+ |
||||
+ return ! (conn->close || !worker->s->is_address_reusable || worker->s->disablereuse); |
||||
+} |
||||
+ |
||||
static apr_status_t connection_cleanup(void *theconn) |
||||
{ |
||||
proxy_conn_rec *conn = (proxy_conn_rec *)theconn; |
||||
@@ -1361,7 +1368,7 @@ static apr_status_t connection_cleanup(void *theconn) |
||||
} |
||||
|
||||
/* determine if the connection need to be closed */ |
||||
- if (conn->close || !worker->s->is_address_reusable || worker->s->disablereuse) { |
||||
+ if (!ap_proxy_connection_reusable(conn)) { |
||||
apr_pool_t *p = conn->pool; |
||||
apr_pool_clear(p); |
||||
conn = apr_pcalloc(p, sizeof(proxy_conn_rec)); |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
diff -Npru httpd-2.4.6.orig/modules/dav/main/mod_dav.c httpd-2.4.6/modules/dav/main/mod_dav.c |
||||
--- httpd-2.4.6.orig/modules/dav/main/mod_dav.c 2015-06-24 12:24:47.920000000 -0400 |
||||
+++ httpd-2.4.6/modules/dav/main/mod_dav.c 2015-06-24 12:27:19.706000000 -0400 |
||||
@@ -316,6 +316,8 @@ static int dav_error_response(request_re |
||||
{ |
||||
r->status = status; |
||||
|
||||
+ r->status_line = ap_get_status_line(status); |
||||
+ |
||||
ap_set_content_type(r, "text/html; charset=ISO-8859-1"); |
||||
|
||||
/* begin the response now... */ |
||||
@@ -347,6 +349,8 @@ static int dav_error_response_tag(reques |
||||
{ |
||||
r->status = err->status; |
||||
|
||||
+ r->status_line = ap_get_status_line(err->status); |
||||
+ |
||||
ap_set_content_type(r, DAV_XML_CONTENT_TYPE); |
||||
|
||||
ap_rputs(DAV_XML_HEADER DEBUG_CR |
@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
|
||||
Index: modules/mappers/mod_rewrite.c |
||||
=================================================================== |
||||
--- a/modules/mappers/mod_rewrite.c (revision 1499025) |
||||
+++ b/modules/mappers/mod_rewrite.c (revision 1528556) |
||||
@@ -589,6 +589,18 @@ |
||||
return 7; |
||||
} |
||||
break; |
||||
+ |
||||
+ case 'w': |
||||
+ case 'W': |
||||
+ if (!strncasecmp(uri, "s://", 4)) { /* ws:// */ |
||||
+ *sqs = 1; |
||||
+ return 5; |
||||
+ } |
||||
+ else if (!strncasecmp(uri, "ss://", 5)) { /* wss:// */ |
||||
+ *sqs = 1; |
||||
+ return 6; |
||||
+ } |
||||
+ break; |
||||
} |
||||
|
||||
return 0; |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
--- a/server/vhost.c 2013/07/15 11:50:50 1503188 |
||||
+++ b/server/vhost.c 2013/10/03 18:31:22 1528958 |
||||
@@ -577,14 +577,22 @@ |
||||
*/ |
||||
|
||||
for (s = main_s->next; s; s = s->next) { |
||||
+ server_addr_rec *sar_prev = NULL; |
||||
has_default_vhost_addr = 0; |
||||
for (sar = s->addrs; sar; sar = sar->next) { |
||||
ipaddr_chain *ic; |
||||
char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */ |
||||
- |
||||
+ /* XXX: this treats 0.0.0.0 as a "default" server which matches no-exact-match for IPv6 */ |
||||
if (!memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) { |
||||
ic = find_default_server(sar->host_port); |
||||
- if (!ic || sar->host_port != ic->sar->host_port) { |
||||
+ |
||||
+ if (ic && sar->host_port == ic->sar->host_port) { /* we're a match for an existing "default server" */ |
||||
+ if (!sar_prev || memcmp(sar_prev->host_addr->ipaddr_ptr, inaddr_any, sar_prev->host_addr->ipaddr_len) |
||||
+ || sar_prev->host_port != sar->host_port) { |
||||
+ add_name_vhost_config(p, main_s, s, sar, ic); |
||||
+ } |
||||
+ } |
||||
+ else { |
||||
/* No default server, or we found a default server but |
||||
** exactly one of us is a wildcard port, which means we want |
||||
** two ip-based vhosts not an NVH with two names |
||||
@@ -592,6 +600,7 @@ |
||||
ic = new_ipaddr_chain(p, s, sar); |
||||
ic->next = default_list; |
||||
default_list = ic; |
||||
+ add_name_vhost_config(p, main_s, s, sar, ic); |
||||
} |
||||
has_default_vhost_addr = 1; |
||||
} |
||||
@@ -609,8 +618,9 @@ |
||||
ic->next = *iphash_table_tail[bucket]; |
||||
*iphash_table_tail[bucket] = ic; |
||||
} |
||||
+ add_name_vhost_config(p, main_s, s, sar, ic); |
||||
} |
||||
- add_name_vhost_config(p, main_s, s, sar, ic); |
||||
+ sar_prev = sar; |
||||
} |
||||
|
||||
/* Ok now we want to set up a server_hostname if the user was |
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
--- a/modules/http/http_filters.c 2013/10/08 14:17:33 1530279 |
||||
+++ b/modules/http/http_filters.c 2013/10/08 14:18:44 1530280 |
||||
@@ -825,7 +825,7 @@ |
||||
* handler. |
||||
* Zap r->status_line if bad. |
||||
*/ |
||||
-static void validate_status_line(request_rec *r) |
||||
+static apr_status_t validate_status_line(request_rec *r) |
||||
{ |
||||
char *end; |
||||
|
||||
@@ -836,15 +836,19 @@ |
||||
|| (end - 3) != r->status_line |
||||
|| (len >= 4 && ! apr_isspace(r->status_line[3]))) { |
||||
r->status_line = NULL; |
||||
+ return APR_EGENERAL; |
||||
} |
||||
/* Since we passed the above check, we know that length three |
||||
* is equivalent to only a 3 digit numeric http status. |
||||
* RFC2616 mandates a trailing space, let's add it. |
||||
*/ |
||||
- else if (len == 3) { |
||||
+ if (len == 3) { |
||||
r->status_line = apr_pstrcat(r->pool, r->status_line, " ", NULL); |
||||
+ return APR_EGENERAL; |
||||
} |
||||
+ return APR_SUCCESS; |
||||
} |
||||
+ return APR_EGENERAL; |
||||
} |
||||
|
||||
/* |
||||
@@ -856,15 +860,25 @@ |
||||
static void basic_http_header_check(request_rec *r, |
||||
const char **protocol) |
||||
{ |
||||
+ apr_status_t rv; |
||||
+ |
||||
if (r->assbackwards) { |
||||
/* no such thing as a response protocol */ |
||||
return; |
||||
} |
||||
|
||||
- validate_status_line(r); |
||||
+ rv = validate_status_line(r); |
||||
|
||||
if (!r->status_line) { |
||||
r->status_line = ap_get_status_line(r->status); |
||||
+ } else if (rv != APR_SUCCESS) { |
||||
+ /* Status line is OK but our own reason phrase |
||||
+ * would be preferred if defined |
||||
+ */ |
||||
+ const char *tmp = ap_get_status_line(r->status); |
||||
+ if (!strncmp(tmp, r->status_line, 3)) { |
||||
+ r->status_line = tmp; |
||||
+ } |
||||
} |
||||
|
||||
/* Note that we must downgrade before checking for force responses. */ |
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
# ./pullrev.sh 1530999 |
||||
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1530999 |
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1557785 |
||||
|
||||
--- httpd-2.4.6/server/core_filters.c |
||||
+++ httpd-2.4.6/server/core_filters.c |
||||
@@ -745,7 +745,9 @@ |
||||
pollset.reqevents = APR_POLLOUT; |
||||
pollset.desc.s = s; |
||||
apr_socket_timeout_get(s, &timeout); |
||||
- rv = apr_poll(&pollset, 1, &nsds, timeout); |
||||
+ do { |
||||
+ rv = apr_poll(&pollset, 1, &nsds, timeout); |
||||
+ } while (APR_STATUS_IS_EINTR(rv)); |
||||
if (rv != APR_SUCCESS) { |
||||
break; |
||||
} |
@ -0,0 +1,155 @@
@@ -0,0 +1,155 @@
|
||||
Index: modules/dav/fs/repos.c |
||||
=================================================================== |
||||
--- a/modules/dav/fs/repos.c (revision 1533447) |
||||
+++ b/modules/dav/fs/repos.c (revision 1533448) |
||||
@@ -717,13 +717,13 @@ |
||||
resource->pool = r->pool; |
||||
|
||||
/* make sure the URI does not have a trailing "/" */ |
||||
- len = strlen(r->uri); |
||||
- if (len > 1 && r->uri[len - 1] == '/') { |
||||
- s = apr_pstrmemdup(r->pool, r->uri, len-1); |
||||
+ len = strlen(r->unparsed_uri); |
||||
+ if (len > 1 && r->unparsed_uri[len - 1] == '/') { |
||||
+ s = apr_pstrmemdup(r->pool, r->unparsed_uri, len-1); |
||||
resource->uri = s; |
||||
} |
||||
else { |
||||
- resource->uri = r->uri; |
||||
+ resource->uri = r->unparsed_uri; |
||||
} |
||||
|
||||
if (r->finfo.filetype != APR_NOFILE) { |
||||
@@ -1482,6 +1482,18 @@ |
||||
return dav_fs_deleteset(info->pool, resource); |
||||
} |
||||
|
||||
+/* Take an unescaped path component and escape it and append it onto a |
||||
+ * dav_buffer for a URI */ |
||||
+static apr_size_t dav_fs_append_uri(apr_pool_t *p, dav_buffer *pbuf, |
||||
+ const char *path, apr_size_t pad) |
||||
+{ |
||||
+ const char *epath = ap_escape_uri(p, path); |
||||
+ apr_size_t epath_len = strlen(epath); |
||||
+ |
||||
+ dav_buffer_place_mem(p, pbuf, epath, epath_len + 1, pad); |
||||
+ return epath_len; |
||||
+} |
||||
+ |
||||
/* ### move this to dav_util? */ |
||||
/* Walk recursively down through directories, * |
||||
* including lock-null resources as we go. */ |
||||
@@ -1537,6 +1549,7 @@ |
||||
} |
||||
while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) { |
||||
apr_size_t len; |
||||
+ apr_size_t escaped_len; |
||||
|
||||
len = strlen(dirent.name); |
||||
|
||||
@@ -1579,7 +1592,7 @@ |
||||
|
||||
/* copy the file to the URI, too. NOTE: we will pad an extra byte |
||||
for the trailing slash later. */ |
||||
- dav_buffer_place_mem(pool, &fsctx->uri_buf, dirent.name, len + 1, 1); |
||||
+ escaped_len = dav_fs_append_uri(pool, &fsctx->uri_buf, dirent.name, 1); |
||||
|
||||
/* if there is a secondary path, then do that, too */ |
||||
if (fsctx->path2.buf != NULL) { |
||||
@@ -1612,7 +1625,7 @@ |
||||
fsctx->path2.cur_len += len; |
||||
|
||||
/* adjust URI length to incorporate subdir and a slash */ |
||||
- fsctx->uri_buf.cur_len += len + 1; |
||||
+ fsctx->uri_buf.cur_len += escaped_len + 1; |
||||
fsctx->uri_buf.buf[fsctx->uri_buf.cur_len - 1] = '/'; |
||||
fsctx->uri_buf.buf[fsctx->uri_buf.cur_len] = '\0'; |
||||
|
||||
@@ -1678,8 +1691,8 @@ |
||||
*/ |
||||
dav_buffer_place_mem(pool, &fsctx->path1, |
||||
fsctx->locknull_buf.buf + offset, len + 1, 0); |
||||
- dav_buffer_place_mem(pool, &fsctx->uri_buf, |
||||
- fsctx->locknull_buf.buf + offset, len + 1, 0); |
||||
+ dav_fs_append_uri(pool, &fsctx->uri_buf, |
||||
+ fsctx->locknull_buf.buf + offset, 0); |
||||
if (fsctx->path2.buf != NULL) { |
||||
dav_buffer_place_mem(pool, &fsctx->path2, |
||||
fsctx->locknull_buf.buf + offset, |
||||
Index: modules/dav/main/mod_dav.c |
||||
=================================================================== |
||||
--- a/modules/dav/main/mod_dav.c (revision 1533447) |
||||
+++ b/modules/dav/main/mod_dav.c (revision 1533448) |
||||
@@ -396,11 +396,9 @@ |
||||
*/ |
||||
static const char *dav_xml_escape_uri(apr_pool_t *p, const char *uri) |
||||
{ |
||||
- const char *e_uri = ap_escape_uri(p, uri); |
||||
- |
||||
/* check the easy case... */ |
||||
- if (ap_strchr_c(e_uri, '&') == NULL) |
||||
- return e_uri; |
||||
+ if (ap_strchr_c(uri, '&') == NULL) |
||||
+ return uri; |
||||
|
||||
/* there was a '&', so more work is needed... sigh. */ |
||||
|
||||
@@ -408,7 +406,7 @@ |
||||
* Note: this is a teeny bit of overkill since we know there are no |
||||
* '<' or '>' characters, but who cares. |
||||
*/ |
||||
- return apr_xml_quote_string(p, e_uri, 0); |
||||
+ return apr_xml_quote_string(p, uri, 0); |
||||
} |
||||
|
||||
|
||||
@@ -604,7 +602,8 @@ |
||||
return DONE; |
||||
} |
||||
|
||||
-/* handy function for return values of methods that (may) create things */ |
||||
+/* handy function for return values of methods that (may) create things. |
||||
+ * locn if provided is assumed to be escaped. */ |
||||
static int dav_created(request_rec *r, const char *locn, const char *what, |
||||
int replaced) |
||||
{ |
||||
@@ -612,8 +611,6 @@ |
||||
|
||||
if (locn == NULL) { |
||||
locn = r->unparsed_uri; |
||||
- } else { |
||||
- locn = ap_escape_uri(r->pool, locn); |
||||
} |
||||
|
||||
/* did the target resource already exist? */ |
||||
@@ -3004,7 +3001,7 @@ |
||||
} |
||||
|
||||
/* return an appropriate response (HTTP_CREATED or HTTP_NO_CONTENT) */ |
||||
- return dav_created(r, lookup.rnew->uri, "Destination", |
||||
+ return dav_created(r, lookup.rnew->unparsed_uri, "Destination", |
||||
resnew_state == DAV_RESOURCE_EXISTS); |
||||
} |
||||
|
||||
@@ -4610,7 +4607,7 @@ |
||||
|
||||
/* return an appropriate response (HTTP_CREATED) */ |
||||
/* ### spec doesn't say what happens when destination was replaced */ |
||||
- return dav_created(r, lookup.rnew->uri, "Binding", 0); |
||||
+ return dav_created(r, lookup.rnew->unparsed_uri, "Binding", 0); |
||||
} |
||||
|
||||
|
||||
Index: modules/dav/main/mod_dav.h |
||||
=================================================================== |
||||
--- a/modules/dav/main/mod_dav.h (revision 1533447) |
||||
+++ b/modules/dav/main/mod_dav.h (revision 1533448) |
||||
@@ -386,7 +386,7 @@ |
||||
* REGULAR and WORKSPACE resources, |
||||
* and is always 1 for WORKING */ |
||||
|
||||
- const char *uri; /* the URI for this resource */ |
||||
+ const char *uri; /* the escaped URI for this resource */ |
||||
|
||||
dav_resource_private *info; /* the provider's private info */ |
||||
|
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
# ./pullrev.sh 1537535 |
||||
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1537535 |
||||
|
||||
--- httpd-2.4.6/modules/ssl/ssl_engine_config.c.r1537535 |
||||
+++ httpd-2.4.6/modules/ssl/ssl_engine_config.c |
||||
@@ -198,7 +198,7 @@ static SSLSrvConfigRec *ssl_config_serve |
||||
SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc)); |
||||
|
||||
sc->mc = NULL; |
||||
- sc->enabled = SSL_ENABLED_FALSE; |
||||
+ sc->enabled = SSL_ENABLED_UNSET; |
||||
sc->proxy_enabled = UNSET; |
||||
sc->vhost_id = NULL; /* set during module init */ |
||||
sc->vhost_id_len = 0; /* set during module init */ |
||||
--- httpd-2.4.6/modules/ssl/ssl_engine_init.c.r1537535 |
||||
+++ httpd-2.4.6/modules/ssl/ssl_engine_init.c |
||||
@@ -289,13 +289,16 @@ int ssl_init_Module(apr_pool_t *p, apr_p |
||||
sc->vhost_id = ssl_util_vhostid(p, s); |
||||
sc->vhost_id_len = strlen(sc->vhost_id); |
||||
|
||||
- if (ap_get_server_protocol(s) && |
||||
- strcmp("https", ap_get_server_protocol(s)) == 0) { |
||||
+ /* Default to enabled if SSLEngine is not set explicitly, and |
||||
+ * the protocol is https. */ |
||||
+ if (ap_get_server_protocol(s) |
||||
+ && strcmp("https", ap_get_server_protocol(s)) == 0 |
||||
+ && sc->enabled == SSL_ENABLED_UNSET) { |
||||
sc->enabled = SSL_ENABLED_TRUE; |
||||
} |
||||
|
||||
- /* If sc->enabled is UNSET, then SSL is optional on this vhost */ |
||||
- /* Fix up stuff that may not have been set */ |
||||
+ /* Fix up stuff that may not have been set. If sc->enabled is |
||||
+ * UNSET, then SSL is disabled on this vhost. */ |
||||
if (sc->enabled == SSL_ENABLED_UNSET) { |
||||
sc->enabled = SSL_ENABLED_FALSE; |
||||
} |
@ -0,0 +1,868 @@
@@ -0,0 +1,868 @@
|
||||
# ./pullrev.sh 1542327 |
||||
http://svn.apache.org/viewvc?view=revision&revision=1542327 |
||||
|
||||
--- httpd-2.4.6/LAYOUT.r1542327 |
||||
+++ httpd-2.4.6/LAYOUT |
||||
@@ -108,7 +108,6 @@ modules/ ................ Manditory and |
||||
mod_ssl.c ............... main source file containing API structures |
||||
mod_ssl.h ............... common header file of mod_ssl |
||||
ssl_engine_config.c ..... module configuration handling |
||||
- ssl_engine_dh.c ......... DSA/DH support |
||||
ssl_engine_init.c ....... module initialization |
||||
ssl_engine_io.c ......... I/O support |
||||
ssl_engine_kernel.c ..... SSL engine kernel |
||||
--- httpd-2.4.6/modules/ssl/config.m4.r1542327 |
||||
+++ httpd-2.4.6/modules/ssl/config.m4 |
||||
@@ -20,7 +20,6 @@ dnl # list of module object files |
||||
ssl_objs="dnl |
||||
mod_ssl.lo dnl |
||||
ssl_engine_config.lo dnl |
||||
-ssl_engine_dh.lo dnl |
||||
ssl_engine_init.lo dnl |
||||
ssl_engine_io.lo dnl |
||||
ssl_engine_kernel.lo dnl |
||||
--- httpd-2.4.6/modules/ssl/mod_ssl.c.r1542327 |
||||
+++ httpd-2.4.6/modules/ssl/mod_ssl.c |
||||
@@ -515,15 +515,6 @@ int ssl_init_ssl_connection(conn_rec *c, |
||||
|
||||
sslconn->ssl = ssl; |
||||
|
||||
- /* |
||||
- * Configure callbacks for SSL connection |
||||
- */ |
||||
- SSL_set_tmp_rsa_callback(ssl, ssl_callback_TmpRSA); |
||||
- SSL_set_tmp_dh_callback(ssl, ssl_callback_TmpDH); |
||||
-#ifndef OPENSSL_NO_EC |
||||
- SSL_set_tmp_ecdh_callback(ssl, ssl_callback_TmpECDH); |
||||
-#endif |
||||
- |
||||
SSL_set_verify_result(ssl, X509_V_OK); |
||||
|
||||
ssl_io_filter_init(c, r, ssl); |
||||
--- httpd-2.4.6/modules/ssl/mod_ssl.dsp.r1542327 |
||||
+++ httpd-2.4.6/modules/ssl/mod_ssl.dsp |
||||
@@ -112,10 +112,6 @@ SOURCE=.\ssl_engine_config.c |
||||
# End Source File |
||||
# Begin Source File |
||||
|
||||
-SOURCE=.\ssl_engine_dh.c |
||||
-# End Source File |
||||
-# Begin Source File |
||||
- |
||||
SOURCE=.\ssl_engine_init.c |
||||
# End Source File |
||||
# Begin Source File |
||||
--- httpd-2.4.6/modules/ssl/ssl_engine_config.c.r1542327 |
||||
+++ httpd-2.4.6/modules/ssl/ssl_engine_config.c |
||||
@@ -76,8 +76,6 @@ SSLModConfigRec *ssl_config_global_creat |
||||
mc->stapling_mutex = NULL; |
||||
#endif |
||||
|
||||
- memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys)); |
||||
- |
||||
apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY, |
||||
apr_pool_cleanup_null, |
||||
pool); |
||||
--- httpd-2.4.6/modules/ssl/ssl_engine_dh.c.r1542327 |
||||
+++ httpd-2.4.6/modules/ssl/ssl_engine_dh.c |
||||
@@ -1,244 +0,0 @@ |
||||
-#if 0 |
||||
-=pod |
||||
-#endif |
||||
- |
||||
-/* 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. |
||||
- */ |
||||
- |
||||
-/* _ _ |
||||
- * _ __ ___ ___ __| | ___ ___| | mod_ssl |
||||
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL |
||||
- * | | | | | | (_) | (_| | \__ \__ \ | |
||||
- * |_| |_| |_|\___/ \__,_|___|___/___/_| |
||||
- * |_____| |
||||
- * ssl_engine_dh.c |
||||
- * Diffie-Hellman Built-in Temporary Parameters |
||||
- */ |
||||
- |
||||
-#include "ssl_private.h" |
||||
- |
||||
-/* ----BEGIN GENERATED SECTION-------- */ |
||||
- |
||||
-/* |
||||
-** Diffie-Hellman-Parameters: (512 bit) |
||||
-** prime: |
||||
-** 00:9f:db:8b:8a:00:45:44:f0:04:5f:17:37:d0:ba: |
||||
-** 2e:0b:27:4c:df:1a:9f:58:82:18:fb:43:53:16:a1: |
||||
-** 6e:37:41:71:fd:19:d8:d8:f3:7c:39:bf:86:3f:d6: |
||||
-** 0e:3e:30:06:80:a3:03:0c:6e:4c:37:57:d0:8f:70: |
||||
-** e6:aa:87:10:33 |
||||
-** generator: 2 (0x2) |
||||
-** Diffie-Hellman-Parameters: (1024 bit) |
||||
-** prime: |
||||
-** 00:d6:7d:e4:40:cb:bb:dc:19:36:d6:93:d3:4a:fd: |
||||
-** 0a:d5:0c:84:d2:39:a4:5f:52:0b:b8:81:74:cb:98: |
||||
-** bc:e9:51:84:9f:91:2e:63:9c:72:fb:13:b4:b4:d7: |
||||
-** 17:7e:16:d5:5a:c1:79:ba:42:0b:2a:29:fe:32:4a: |
||||
-** 46:7a:63:5e:81:ff:59:01:37:7b:ed:dc:fd:33:16: |
||||
-** 8a:46:1a:ad:3b:72:da:e8:86:00:78:04:5b:07:a7: |
||||
-** db:ca:78:74:08:7d:15:10:ea:9f:cc:9d:dd:33:05: |
||||
-** 07:dd:62:db:88:ae:aa:74:7d:e0:f4:d6:e2:bd:68: |
||||
-** b0:e7:39:3e:0f:24:21:8e:b3 |
||||
-** generator: 2 (0x2) |
||||
-*/ |
||||
- |
||||
-static unsigned char dh512_p[] = { |
||||
- 0x9F, 0xDB, 0x8B, 0x8A, 0x00, 0x45, 0x44, 0xF0, 0x04, 0x5F, 0x17, 0x37, |
||||
- 0xD0, 0xBA, 0x2E, 0x0B, 0x27, 0x4C, 0xDF, 0x1A, 0x9F, 0x58, 0x82, 0x18, |
||||
- 0xFB, 0x43, 0x53, 0x16, 0xA1, 0x6E, 0x37, 0x41, 0x71, 0xFD, 0x19, 0xD8, |
||||
- 0xD8, 0xF3, 0x7C, 0x39, 0xBF, 0x86, 0x3F, 0xD6, 0x0E, 0x3E, 0x30, 0x06, |
||||
- 0x80, 0xA3, 0x03, 0x0C, 0x6E, 0x4C, 0x37, 0x57, 0xD0, 0x8F, 0x70, 0xE6, |
||||
- 0xAA, 0x87, 0x10, 0x33, |
||||
-}; |
||||
-static unsigned char dh512_g[] = { |
||||
- 0x02, |
||||
-}; |
||||
- |
||||
-static DH *get_dh512(void) |
||||
-{ |
||||
- DH *dh; |
||||
- |
||||
- if (!(dh = DH_new())) { |
||||
- return NULL; |
||||
- } |
||||
- |
||||
- dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL); |
||||
- dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL); |
||||
- if (!(dh->p && dh->g)) { |
||||
- DH_free(dh); |
||||
- return NULL; |
||||
- } |
||||
- |
||||
- return dh; |
||||
-} |
||||
- |
||||
-static unsigned char dh1024_p[] = { |
||||
- 0xD6, 0x7D, 0xE4, 0x40, 0xCB, 0xBB, 0xDC, 0x19, 0x36, 0xD6, 0x93, 0xD3, |
||||
- 0x4A, 0xFD, 0x0A, 0xD5, 0x0C, 0x84, 0xD2, 0x39, 0xA4, 0x5F, 0x52, 0x0B, |
||||
- 0xB8, 0x81, 0x74, 0xCB, 0x98, 0xBC, 0xE9, 0x51, 0x84, 0x9F, 0x91, 0x2E, |
||||
- 0x63, 0x9C, 0x72, 0xFB, 0x13, 0xB4, 0xB4, 0xD7, 0x17, 0x7E, 0x16, 0xD5, |
||||
- 0x5A, 0xC1, 0x79, 0xBA, 0x42, 0x0B, 0x2A, 0x29, 0xFE, 0x32, 0x4A, 0x46, |
||||
- 0x7A, 0x63, 0x5E, 0x81, 0xFF, 0x59, 0x01, 0x37, 0x7B, 0xED, 0xDC, 0xFD, |
||||
- 0x33, 0x16, 0x8A, 0x46, 0x1A, 0xAD, 0x3B, 0x72, 0xDA, 0xE8, 0x86, 0x00, |
||||
- 0x78, 0x04, 0x5B, 0x07, 0xA7, 0xDB, 0xCA, 0x78, 0x74, 0x08, 0x7D, 0x15, |
||||
- 0x10, 0xEA, 0x9F, 0xCC, 0x9D, 0xDD, 0x33, 0x05, 0x07, 0xDD, 0x62, 0xDB, |
||||
- 0x88, 0xAE, 0xAA, 0x74, 0x7D, 0xE0, 0xF4, 0xD6, 0xE2, 0xBD, 0x68, 0xB0, |
||||
- 0xE7, 0x39, 0x3E, 0x0F, 0x24, 0x21, 0x8E, 0xB3, |
||||
-}; |
||||
-static unsigned char dh1024_g[] = { |
||||
- 0x02, |
||||
-}; |
||||
- |
||||
-static DH *get_dh1024(void) |
||||
-{ |
||||
- DH *dh; |
||||
- |
||||
- if (!(dh = DH_new())) { |
||||
- return NULL; |
||||
- } |
||||
- |
||||
- dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); |
||||
- dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL); |
||||
- if (!(dh->p && dh->g)) { |
||||
- DH_free(dh); |
||||
- return NULL; |
||||
- } |
||||
- |
||||
- return dh; |
||||
-} |
||||
- |
||||
-/* ----END GENERATED SECTION---------- */ |
||||
- |
||||
-DH *ssl_dh_GetTmpParam(int nKeyLen) |
||||
-{ |
||||
- DH *dh; |
||||
- |
||||
- if (nKeyLen == 512) |
||||
- dh = get_dh512(); |
||||
- else if (nKeyLen == 1024) |
||||
- dh = get_dh1024(); |
||||
- else |
||||
- dh = get_dh1024(); |
||||
- return dh; |
||||
-} |
||||
- |
||||
-DH *ssl_dh_GetParamFromFile(char *file) |
||||
-{ |
||||
- DH *dh = NULL; |
||||
- BIO *bio; |
||||
- |
||||
- if ((bio = BIO_new_file(file, "r")) == NULL) |
||||
- return NULL; |
||||
- dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); |
||||
- BIO_free(bio); |
||||
- return (dh); |
||||
-} |
||||
- |
||||
-/* |
||||
-=cut |
||||
-## |
||||
-## Embedded Perl script for generating the temporary DH parameters |
||||
-## |
||||
- |
||||
-require 5.003; |
||||
-use strict; |
||||
- |
||||
-# configuration |
||||
-my $file = $0; |
||||
-my $begin = '----BEGIN GENERATED SECTION--------'; |
||||
-my $end = '----END GENERATED SECTION----------'; |
||||
- |
||||
-# read ourself and keep a backup |
||||
-open(FP, "<$file") || die; |
||||
-my $source = ''; |
||||
-$source .= $_ while (<FP>); |
||||
-close(FP); |
||||
-open(FP, ">$file.bak") || die; |
||||
-print FP $source; |
||||
-close(FP); |
||||
- |
||||
-# generate the DH parameters |
||||
-print "1. Generate 512 and 1024 bit Diffie-Hellman parameters (p, g)\n"; |
||||
-my $rand = ''; |
||||
-foreach $file (qw(/var/log/messages /var/adm/messages |
||||
- /kernel /vmunix /vmlinuz /etc/hosts /etc/resolv.conf)) { |
||||
- if (-f $file) { |
||||
- $rand = $file if ($rand eq ''); |
||||
- $rand .= ":$file" if ($rand ne ''); |
||||
- } |
||||
-} |
||||
-$rand = "-rand $rand" if ($rand ne ''); |
||||
-system("openssl gendh $rand -out dh512.pem 512"); |
||||
-system("openssl gendh $rand -out dh1024.pem 1024"); |
||||
- |
||||
-# generate DH param info |
||||
-my $dhinfo = ''; |
||||
-open(FP, "openssl dh -noout -text -in dh512.pem |") || die; |
||||
-$dhinfo .= $_ while (<FP>); |
||||
-close(FP); |
||||
-open(FP, "openssl dh -noout -text -in dh1024.pem |") || die; |
||||
-$dhinfo .= $_ while (<FP>); |
||||
-close(FP); |
||||
-$dhinfo =~ s|^|** |mg; |
||||
-$dhinfo = "\n\/\*\n$dhinfo\*\/\n\n"; |
||||
- |
||||
-my $indent_args = "-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1"; |
||||
- |
||||
-# generate C source from DH params |
||||
-my $dhsource = ''; |
||||
-open(FP, "openssl dh -noout -C -in dh512.pem | indent $indent_args | expand |") || die; |
||||
-$dhsource .= $_ while (<FP>); |
||||
-close(FP); |
||||
-open(FP, "openssl dh -noout -C -in dh1024.pem | indent $indent_args | expand |") || die; |
||||
-$dhsource .= $_ while (<FP>); |
||||
-close(FP); |
||||
-$dhsource =~ s|(DH\s+\*get_dh)(\d+)[^}]*\n}|static $1$2(void) |
||||
-{ |
||||
- DH *dh; |
||||
- |
||||
- if (!(dh = DH_new())) { |
||||
- return NULL; |
||||
- } |
||||
- |
||||
- dh->p = BN_bin2bn(dh$2_p, sizeof(dh$2_p), NULL); |
||||
- dh->g = BN_bin2bn(dh$2_g, sizeof(dh$2_g), NULL); |
||||
- if (!(dh->p && dh->g)) { |
||||
- DH_free(dh); |
||||
- return NULL; |
||||
- } |
||||
- |
||||
- return dh; |
||||
-} |
||||
-|sg; |
||||
- |
||||
-# generate output |
||||
-my $o = $dhinfo . $dhsource; |
||||
- |
||||
-# insert the generated code at the target location |
||||
-$source =~ s|(\/\* $begin.+?\n).*\n(.*?\/\* $end)|$1$o$2|s; |
||||
- |
||||
-# and update the source on disk |
||||
-print "Updating file `$file'\n"; |
||||
-open(FP, ">$file") || die; |
||||
-print FP $source; |
||||
-close(FP); |
||||
- |
||||
-# cleanup |
||||
-unlink("dh512.pem"); |
||||
-unlink("dh1024.pem"); |
||||
- |
||||
-=pod |
||||
-*/ |
||||
--- httpd-2.4.6/modules/ssl/ssl_engine_init.c.r1542327 |
||||
+++ httpd-2.4.6/modules/ssl/ssl_engine_init.c |
||||
@@ -56,180 +56,6 @@ static void ssl_add_version_components(a |
||||
modver, AP_SERVER_BASEVERSION, incver); |
||||
} |
||||
|
||||
- |
||||
-/* |
||||
- * Handle the Temporary RSA Keys and DH Params |
||||
- */ |
||||
- |
||||
-#define MODSSL_TMP_KEY_FREE(mc, type, idx) \ |
||||
- if (mc->pTmpKeys[idx]) { \ |
||||
- type##_free((type *)mc->pTmpKeys[idx]); \ |
||||
- mc->pTmpKeys[idx] = NULL; \ |
||||
- } |
||||
- |
||||
-#define MODSSL_TMP_KEYS_FREE(mc, type) \ |
||||
- MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_512); \ |
||||
- MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_1024) |
||||
- |
||||
-static void ssl_tmp_keys_free(server_rec *s) |
||||
-{ |
||||
- SSLModConfigRec *mc = myModConfig(s); |
||||
- |
||||
- MODSSL_TMP_KEYS_FREE(mc, RSA); |
||||
- MODSSL_TMP_KEYS_FREE(mc, DH); |
||||
-#ifndef OPENSSL_NO_EC |
||||
- MODSSL_TMP_KEY_FREE(mc, EC_KEY, SSL_TMP_KEY_EC_256); |
||||
-#endif |
||||
-} |
||||
- |
||||
-static int ssl_tmp_key_init_rsa(server_rec *s, |
||||
- int bits, int idx) |
||||
-{ |
||||
- SSLModConfigRec *mc = myModConfig(s); |
||||
- |
||||
-#ifdef HAVE_FIPS |
||||
- |
||||
- if (FIPS_mode() && bits < 1024) { |
||||
- mc->pTmpKeys[idx] = NULL; |
||||
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01877) |
||||
- "Init: Skipping generating temporary " |
||||
- "%d bit RSA private key in FIPS mode", bits); |
||||
- return OK; |
||||
- } |
||||
- |
||||
-#endif |
||||
-#ifdef HAVE_GENERATE_EX |
||||
- { |
||||
- RSA *tkey; |
||||
- BIGNUM *bn_f4; |
||||
- if (!(tkey = RSA_new()) |
||||
- || !(bn_f4 = BN_new()) |
||||
- || !BN_set_word(bn_f4, RSA_F4) |
||||
- || !RSA_generate_key_ex(tkey, bits, bn_f4, NULL)) |
||||
- { |
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01878) |
||||
- "Init: Failed to generate temporary " |
||||
- "%d bit RSA private key", bits); |
||||
- ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); |
||||
- return !OK; |
||||
- } |
||||
- BN_free(bn_f4); |
||||
- mc->pTmpKeys[idx] = tkey; |
||||
- } |
||||
-#else |
||||
- if (!(mc->pTmpKeys[idx] = |
||||
- RSA_generate_key(bits, RSA_F4, NULL, NULL))) |
||||
- { |
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01879) |
||||
- "Init: Failed to generate temporary " |
||||
- "%d bit RSA private key", bits); |
||||
- ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s); |
||||
- return !OK; |
||||
- } |
||||
-#endif |
||||
- |
||||
- return OK; |
||||
-} |
||||
- |
||||
-static int ssl_tmp_key_init_dh(server_rec *s, |
||||
- int bits, int idx) |
||||
-{ |
||||
- SSLModConfigRec *mc = myModConfig(s); |
||||
- |
||||
-#ifdef HAVE_FIPS |
||||
- |
||||
- if (FIPS_mode() && bits < 1024) { |
||||
- mc->pTmpKeys[idx] = NULL; |
||||
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01880) |
||||
- "Init: Skipping generating temporary " |
||||
- "%d bit DH parameters in FIPS mode", bits); |
||||
- return OK; |
||||
- } |
||||
- |
||||
-#endif |
||||
- |
||||
- if (!(mc->pTmpKeys[idx] = |
||||
- ssl_dh_GetTmpParam(bits))) |
||||
- { |
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01881) |
||||
- "Init: Failed to generate temporary " |
||||
- "%d bit DH parameters", bits); |
||||
- return !OK; |
||||
- } |
||||
- |
||||
- return OK; |
||||
-} |
||||
- |
||||
-#ifndef OPENSSL_NO_EC |
||||
-static int ssl_tmp_key_init_ec(server_rec *s, |
||||
- int bits, int idx) |
||||
-{ |
||||
- SSLModConfigRec *mc = myModConfig(s); |
||||
- EC_KEY *ecdh = NULL; |
||||
- |
||||
- /* XXX: Are there any FIPS constraints we should enforce? */ |
||||
- |
||||
- if (bits != 256) { |
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02298) |
||||
- "Init: Failed to generate temporary " |
||||
- "%d bit EC parameters, only 256 bits supported", bits); |
||||
- return !OK; |
||||
- } |
||||
- |
||||
- if ((ecdh = EC_KEY_new()) == NULL || |
||||
- EC_KEY_set_group(ecdh, EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)) != 1) |
||||
- { |
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02299) |
||||
- "Init: Failed to generate temporary " |
||||
- "%d bit EC parameters", bits); |
||||
- return !OK; |
||||
- } |
||||
- |
||||
- mc->pTmpKeys[idx] = ecdh; |
||||
- return OK; |
||||
-} |
||||
- |
||||
-#define MODSSL_TMP_KEY_INIT_EC(s, bits) \ |
||||
- ssl_tmp_key_init_ec(s, bits, SSL_TMP_KEY_EC_##bits) |
||||
- |
||||
-#endif |
||||
- |
||||
-#define MODSSL_TMP_KEY_INIT_RSA(s, bits) \ |
||||
- ssl_tmp_key_init_rsa(s, bits, SSL_TMP_KEY_RSA_##bits) |
||||
- |
||||
-#define MODSSL_TMP_KEY_INIT_DH(s, bits) \ |
||||
- ssl_tmp_key_init_dh(s, bits, SSL_TMP_KEY_DH_##bits) |
||||
- |
||||
-static int ssl_tmp_keys_init(server_rec *s) |
||||
-{ |
||||
- ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, |
||||
- "Init: Generating temporary RSA private keys (512/1024 bits)"); |
||||
- |
||||
- if (MODSSL_TMP_KEY_INIT_RSA(s, 512) || |
||||
- MODSSL_TMP_KEY_INIT_RSA(s, 1024)) { |
||||
- return !OK; |
||||
- } |
||||
- |
||||
- ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, |
||||
- "Init: Generating temporary DH parameters (512/1024 bits)"); |
||||
- |
||||
- if (MODSSL_TMP_KEY_INIT_DH(s, 512) || |
||||
- MODSSL_TMP_KEY_INIT_DH(s, 1024)) { |
||||
- return !OK; |
||||
- } |
||||
- |
||||
-#ifndef OPENSSL_NO_EC |
||||
- ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s, |
||||
- "Init: Generating temporary EC parameters (256 bits)"); |
||||
- |
||||
- if (MODSSL_TMP_KEY_INIT_EC(s, 256)) { |
||||
- return !OK; |
||||
- } |
||||
-#endif |
||||
- |
||||
- return OK; |
||||
-} |
||||
- |
||||
/* |
||||
* Per-module initialization |
||||
*/ |
||||
@@ -370,10 +196,6 @@ int ssl_init_Module(apr_pool_t *p, apr_p |
||||
*/ |
||||
ssl_pphrase_Handle(base_server, ptemp); |
||||
|
||||
- if (ssl_tmp_keys_init(base_server)) { |
||||
- return !OK; |
||||
- } |
||||
- |
||||
/* |
||||
* initialize the mutex handling |
||||
*/ |
||||
@@ -681,6 +503,9 @@ static void ssl_init_ctx_protocol(server |
||||
* Configure additional context ingredients |
||||
*/ |
||||
SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); |
||||
+#ifndef OPENSSL_NO_EC |
||||
+ SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE); |
||||
+#endif |
||||
|
||||
#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
||||
/* |
||||
@@ -721,11 +546,7 @@ static void ssl_init_ctx_callbacks(serve |
||||
{ |
||||
SSL_CTX *ctx = mctx->ssl_ctx; |
||||
|
||||
- SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA); |
||||
SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH); |
||||
-#ifndef OPENSSL_NO_EC |
||||
- SSL_CTX_set_tmp_ecdh_callback(ctx,ssl_callback_TmpECDH); |
||||
-#endif |
||||
|
||||
SSL_CTX_set_info_callback(ctx, ssl_callback_Info); |
||||
|
||||
@@ -1165,12 +986,16 @@ static void ssl_init_server_certs(server |
||||
modssl_ctx_t *mctx) |
||||
{ |
||||
const char *rsa_id, *dsa_id; |
||||
-#ifndef OPENSSL_NO_EC |
||||
+#ifndef OPENSSL_NO_EC |
||||
const char *ecc_id; |
||||
+ EC_GROUP *ecparams; |
||||
+ int nid; |
||||
+ EC_KEY *eckey; |
||||
#endif |
||||
const char *vhost_id = mctx->sc->vhost_id; |
||||
int i; |
||||
int have_rsa, have_dsa; |
||||
+ DH *dhparams; |
||||
#ifndef OPENSSL_NO_EC |
||||
int have_ecc; |
||||
#endif |
||||
@@ -1217,6 +1042,40 @@ static void ssl_init_server_certs(server |
||||
"Oops, no " KEYTYPES " server private key found?!"); |
||||
ssl_die(s); |
||||
} |
||||
+ |
||||
+ /* |
||||
+ * Try to read DH parameters from the (first) SSLCertificateFile |
||||
+ */ |
||||
+ if ((mctx->pks->cert_files[0] != NULL) && |
||||
+ (dhparams = ssl_dh_GetParamFromFile(mctx->pks->cert_files[0]))) { |
||||
+ 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", |
||||
+ BN_num_bits(dhparams->p), vhost_id, |
||||
+ mctx->pks->cert_files[0]); |
||||
+ } |
||||
+ |
||||
+#ifndef OPENSSL_NO_EC |
||||
+ /* |
||||
+ * Similarly, try to read the ECDH curve name from SSLCertificateFile... |
||||
+ */ |
||||
+ if ((mctx->pks->cert_files[0] != NULL) && |
||||
+ (ecparams = ssl_ec_GetParamFromFile(mctx->pks->cert_files[0])) && |
||||
+ (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", |
||||
+ OBJ_nid2sn(nid), vhost_id, mctx->pks->cert_files[0]); |
||||
+ } |
||||
+ /* |
||||
+ * ...otherwise, configure NIST P-256 (required to enable ECDHE) |
||||
+ */ |
||||
+ else { |
||||
+ SSL_CTX_set_tmp_ecdh(mctx->ssl_ctx, |
||||
+ EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); |
||||
+ } |
||||
+#endif |
||||
} |
||||
|
||||
#ifdef HAVE_TLS_SESSION_TICKETS |
||||
@@ -1754,11 +1613,6 @@ apr_status_t ssl_init_ModuleKill(void *d |
||||
ssl_scache_kill(base_server); |
||||
|
||||
/* |
||||
- * Destroy the temporary keys and params |
||||
- */ |
||||
- ssl_tmp_keys_free(base_server); |
||||
- |
||||
- /* |
||||
* Free the non-pool allocated structures |
||||
* in the per-server configurations |
||||
*/ |
||||
--- httpd-2.4.6/modules/ssl/ssl_engine_kernel.c.r1542327 |
||||
+++ httpd-2.4.6/modules/ssl/ssl_engine_kernel.c |
||||
@@ -1289,117 +1289,70 @@ const authz_provider ssl_authz_provider_ |
||||
*/ |
||||
|
||||
/* |
||||
- * Handle out temporary RSA private keys on demand |
||||
- * |
||||
- * The background of this as the TLSv1 standard explains it: |
||||
- * |
||||
- * | D.1. Temporary RSA keys |
||||
- * | |
||||
- * | US Export restrictions limit RSA keys used for encryption to 512 |
||||
- * | bits, but do not place any limit on lengths of RSA keys used for |
||||
- * | signing operations. Certificates often need to be larger than 512 |
||||
- * | bits, since 512-bit RSA keys are not secure enough for high-value |
||||
- * | transactions or for applications requiring long-term security. Some |
||||
- * | certificates are also designated signing-only, in which case they |
||||
- * | cannot be used for key exchange. |
||||
- * | |
||||
- * | When the public key in the certificate cannot be used for encryption, |
||||
- * | the server signs a temporary RSA key, which is then exchanged. In |
||||
- * | exportable applications, the temporary RSA key should be the maximum |
||||
- * | allowable length (i.e., 512 bits). Because 512-bit RSA keys are |
||||
- * | relatively insecure, they should be changed often. For typical |
||||
- * | electronic commerce applications, it is suggested that keys be |
||||
- * | changed daily or every 500 transactions, and more often if possible. |
||||
- * | Note that while it is acceptable to use the same temporary key for |
||||
- * | multiple transactions, it must be signed each time it is used. |
||||
- * | |
||||
- * | RSA key generation is a time-consuming process. In many cases, a |
||||
- * | low-priority process can be assigned the task of key generation. |
||||
- * | Whenever a new key is completed, the existing temporary key can be |
||||
- * | replaced with the new one. |
||||
- * |
||||
- * XXX: base on comment above, if thread support is enabled, |
||||
- * we should spawn a low-priority thread to generate new keys |
||||
- * on the fly. |
||||
- * |
||||
- * So we generated 512 and 1024 bit temporary keys on startup |
||||
- * which we now just hand out on demand.... |
||||
+ * Grab well-defined DH parameters from OpenSSL, see <openssl/bn.h> |
||||
+ * (get_rfc*) for all available primes. |
||||
*/ |
||||
- |
||||
-RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int keylen) |
||||
-{ |
||||
- conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
||||
- SSLModConfigRec *mc = myModConfigFromConn(c); |
||||
- int idx; |
||||
- |
||||
- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, |
||||
- "handing out temporary %d bit RSA key", keylen); |
||||
- |
||||
- /* doesn't matter if export flag is on, |
||||
- * we won't be asked for keylen > 512 in that case. |
||||
- * if we are asked for a keylen > 1024, it is too expensive |
||||
- * to generate on the fly. |
||||
- * XXX: any reason not to generate 2048 bit keys at startup? |
||||
- */ |
||||
- |
||||
- switch (keylen) { |
||||
- case 512: |
||||
- idx = SSL_TMP_KEY_RSA_512; |
||||
- break; |
||||
- |
||||
- case 1024: |
||||
- default: |
||||
- idx = SSL_TMP_KEY_RSA_1024; |
||||
- } |
||||
- |
||||
- return (RSA *)mc->pTmpKeys[idx]; |
||||
+#define make_get_dh(rfc,size,gen) \ |
||||
+static DH *get_dh##size(void) \ |
||||
+{ \ |
||||
+ DH *dh; \ |
||||
+ if (!(dh = DH_new())) { \ |
||||
+ return NULL; \ |
||||
+ } \ |
||||
+ dh->p = get_##rfc##_prime_##size(NULL); \ |
||||
+ BN_dec2bn(&dh->g, #gen); \ |
||||
+ if (!dh->p || !dh->g) { \ |
||||
+ DH_free(dh); \ |
||||
+ return NULL; \ |
||||
+ } \ |
||||
+ return dh; \ |
||||
} |
||||
|
||||
/* |
||||
- * Hand out the already generated DH parameters... |
||||
+ * Prepare DH parameters from 1024 to 4096 bits, in 1024-bit increments |
||||
+ */ |
||||
+make_get_dh(rfc2409, 1024, 2) |
||||
+make_get_dh(rfc3526, 2048, 2) |
||||
+make_get_dh(rfc3526, 3072, 2) |
||||
+make_get_dh(rfc3526, 4096, 2) |
||||
+ |
||||
+/* |
||||
+ * Hand out standard DH parameters, based on the authentication strength |
||||
*/ |
||||
DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen) |
||||
{ |
||||
conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
||||
- SSLModConfigRec *mc = myModConfigFromConn(c); |
||||
- int idx; |
||||
- |
||||
- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, |
||||
- "handing out temporary %d bit DH key", keylen); |
||||
+ EVP_PKEY *pkey = SSL_get_privatekey(ssl); |
||||
+ int type = pkey ? EVP_PKEY_type(pkey->type) : EVP_PKEY_NONE; |
||||
|
||||
- switch (keylen) { |
||||
- case 512: |
||||
- idx = SSL_TMP_KEY_DH_512; |
||||
- break; |
||||
- |
||||
- case 1024: |
||||
- default: |
||||
- idx = SSL_TMP_KEY_DH_1024; |
||||
+ /* |
||||
+ * OpenSSL will call us with either keylen == 512 or keylen == 1024 |
||||
+ * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h). |
||||
+ * Adjust the DH parameter length according to the size of the |
||||
+ * RSA/DSA private key used for the current connection, and always |
||||
+ * use at least 1024-bit parameters. |
||||
+ * Note: This may cause interoperability issues with implementations |
||||
+ * which limit their DH support to 1024 bit - e.g. Java 7 and earlier. |
||||
+ * In this case, SSLCertificateFile can be used to specify fixed |
||||
+ * 1024-bit DH parameters (with the effect that OpenSSL skips this |
||||
+ * callback). |
||||
+ */ |
||||
+ if ((type == EVP_PKEY_RSA) || (type == EVP_PKEY_DSA)) { |
||||
+ keylen = EVP_PKEY_bits(pkey); |
||||
} |
||||
|
||||
- return (DH *)mc->pTmpKeys[idx]; |
||||
-} |
||||
- |
||||
-#ifndef OPENSSL_NO_EC |
||||
-EC_KEY *ssl_callback_TmpECDH(SSL *ssl, int export, int keylen) |
||||
-{ |
||||
- conn_rec *c = (conn_rec *)SSL_get_app_data(ssl); |
||||
- SSLModConfigRec *mc = myModConfigFromConn(c); |
||||
- int idx; |
||||
- |
||||
- /* XXX Uses 256-bit key for now. TODO: support other sizes. */ |
||||
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c, |
||||
- "handing out temporary 256 bit ECC key"); |
||||
- |
||||
- switch (keylen) { |
||||
- case 256: |
||||
- default: |
||||
- idx = SSL_TMP_KEY_EC_256; |
||||
- } |
||||
+ "handing out built-in DH parameters for %d-bit authenticated connection", keylen); |
||||
|
||||
- return (EC_KEY *)mc->pTmpKeys[idx]; |
||||
+ if (keylen >= 4096) |
||||
+ return get_dh4096(); |
||||
+ else if (keylen >= 3072) |
||||
+ return get_dh3072(); |
||||
+ else if (keylen >= 2048) |
||||
+ return get_dh2048(); |
||||
+ else |
||||
+ return get_dh1024(); |
||||
} |
||||
-#endif |
||||
|
||||
/* |
||||
* This OpenSSL callback function is called when OpenSSL |
||||
--- httpd-2.4.6/modules/ssl/ssl_private.h.r1542327 |
||||
+++ httpd-2.4.6/modules/ssl/ssl_private.h |
||||
@@ -310,22 +310,6 @@ typedef int ssl_algo_t; |
||||
#define SSL_AIDX_MAX (2) |
||||
#endif |
||||
|
||||
- |
||||
-/** |
||||
- * Define IDs for the temporary RSA keys and DH params |
||||
- */ |
||||
- |
||||
-#define SSL_TMP_KEY_RSA_512 (0) |
||||
-#define SSL_TMP_KEY_RSA_1024 (1) |
||||
-#define SSL_TMP_KEY_DH_512 (2) |
||||
-#define SSL_TMP_KEY_DH_1024 (3) |
||||
-#ifndef OPENSSL_NO_EC |
||||
-#define SSL_TMP_KEY_EC_256 (4) |
||||
-#define SSL_TMP_KEY_MAX (5) |
||||
-#else |
||||
-#define SSL_TMP_KEY_MAX (4) |
||||
-#endif |
||||
- |
||||
/** |
||||
* Define the SSL options |
||||
*/ |
||||
@@ -547,7 +531,6 @@ typedef struct { |
||||
apr_global_mutex_t *pMutex; |
||||
apr_array_header_t *aRandSeed; |
||||
apr_hash_t *tVHostKeys; |
||||
- void *pTmpKeys[SSL_TMP_KEY_MAX]; |
||||
|
||||
/* Two hash tables of pointers to ssl_asn1_t structures. The |
||||
* structures are used to store certificates and private keys |
||||
@@ -837,11 +820,7 @@ extern const authz_provider ssl_authz_pr |
||||
extern const authz_provider ssl_authz_provider_verify_client; |
||||
|
||||
/** OpenSSL callbacks */ |
||||
-RSA *ssl_callback_TmpRSA(SSL *, int, int); |
||||
DH *ssl_callback_TmpDH(SSL *, int, int); |
||||
-#ifndef OPENSSL_NO_EC |
||||
-EC_KEY *ssl_callback_TmpECDH(SSL *, int, int); |
||||
-#endif |
||||
int ssl_callback_SSLVerify(int, X509_STORE_CTX *); |
||||
int ssl_callback_SSLVerify_CRL(int, X509_STORE_CTX *, conn_rec *); |
||||
int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey); |
||||
@@ -921,8 +900,10 @@ int ssl_init_ssl_connection(con |
||||
void ssl_pphrase_Handle(server_rec *, apr_pool_t *); |
||||
|
||||
/** Diffie-Hellman Parameter Support */ |
||||
-DH *ssl_dh_GetTmpParam(int); |
||||
-DH *ssl_dh_GetParamFromFile(char *); |
||||
+DH *ssl_dh_GetParamFromFile(const char *); |
||||
+#ifndef OPNESSL_NO_EC |
||||
+EC_GROUP *ssl_ec_GetParamFromFile(const char *); |
||||
+#endif |
||||
|
||||
unsigned char *ssl_asn1_table_set(apr_hash_t *table, |
||||
const char *key, |
||||
--- httpd-2.4.6/modules/ssl/ssl_util_ssl.c.r1542327 |
||||
+++ httpd-2.4.6/modules/ssl/ssl_util_ssl.c |
||||
@@ -483,6 +483,38 @@ BOOL SSL_X509_INFO_load_path(apr_pool_t |
||||
|
||||
/* _________________________________________________________________ |
||||
** |
||||
+** Custom (EC)DH parameter support |
||||
+** _________________________________________________________________ |
||||
+*/ |
||||
+ |
||||
+DH *ssl_dh_GetParamFromFile(const char *file) |
||||
+{ |
||||
+ DH *dh = NULL; |
||||
+ BIO *bio; |
||||
+ |
||||
+ if ((bio = BIO_new_file(file, "r")) == NULL) |
||||
+ return NULL; |
||||
+ dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); |
||||
+ BIO_free(bio); |
||||
+ return (dh); |
||||
+} |
||||
+ |
||||
+#ifndef OPENSSL_NO_EC |
||||
+EC_GROUP *ssl_ec_GetParamFromFile(const char *file) |
||||
+{ |
||||
+ EC_GROUP *group = NULL; |
||||
+ BIO *bio; |
||||
+ |
||||
+ if ((bio = BIO_new_file(file, "r")) == NULL) |
||||
+ return NULL; |
||||
+ group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL); |
||||
+ BIO_free(bio); |
||||
+ return (group); |
||||
+} |
||||
+#endif |
||||
+ |
||||
+/* _________________________________________________________________ |
||||
+** |
||||
** Extra Server Certificate Chain Support |
||||
** _________________________________________________________________ |
||||
*/ |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
# ./pullrev.sh 1553540 |
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1040447 |
||||
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1553540 |
||||
|
||||
--- httpd-2.4.6/modules/proxy/mod_proxy_http.c |
||||
+++ httpd-2.4.6/modules/proxy/mod_proxy_http.c |
||||
@@ -710,7 +710,7 @@ |
||||
force10 = 0; |
||||
} |
||||
|
||||
- header_brigade = apr_brigade_create(p, origin->bucket_alloc); |
||||
+ header_brigade = apr_brigade_create(p, bucket_alloc); |
||||
rv = ap_proxy_create_hdrbrgd(p, header_brigade, r, p_conn, |
||||
worker, conf, uri, url, server_portstr, |
||||
&old_cl_val, &old_te_val); |
||||
@@ -1813,6 +1813,10 @@ |
||||
} |
||||
} while (interim_response && (interim_response < AP_MAX_INTERIM_RESPONSES)); |
||||
|
||||
+ /* We have to cleanup bb brigade, because buckets inserted to it could be |
||||
+ * created from scpool and this pool can be freed before this brigade. */ |
||||
+ apr_brigade_cleanup(bb); |
||||
+ |
||||
/* See define of AP_MAX_INTERIM_RESPONSES for why */ |
||||
if (interim_response >= AP_MAX_INTERIM_RESPONSES) { |
||||
return ap_proxyerror(r, HTTP_BAD_GATEWAY, |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
# ./pullrev.sh 1556473 |
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1036666 |
||||
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1556473 |
||||
|
||||
--- httpd-2.4.6/modules/ssl/ssl_engine_config.c |
||||
+++ httpd-2.4.6/modules/ssl/ssl_engine_config.c |
||||
@@ -699,9 +699,20 @@ |
||||
#ifndef SSL_OP_NO_COMPRESSION |
||||
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); |
||||
if (err) |
||||
- return "This version of openssl does not support configuring " |
||||
- "compression within <VirtualHost> sections."; |
||||
+ return "This version of OpenSSL does not support enabling " |
||||
+ "SSLCompression within <VirtualHost> sections."; |
||||
#endif |
||||
+ if (flag) { |
||||
+ /* Some (packaged) versions of OpenSSL do not support |
||||
+ * compression by default. Enabling this directive would not |
||||
+ * have the desired effect, so fail with an error. */ |
||||
+ STACK_OF(SSL_COMP) *meths = SSL_COMP_get_compression_methods(); |
||||
+ |
||||
+ if (sk_SSL_COMP_num(meths) == 0) { |
||||
+ return "This version of OpenSSL does not have any compression methods " |
||||
+ "available, cannot enable SSLCompression."; |
||||
+ } |
||||
+ } |
||||
sc->compression = flag ? TRUE : FALSE; |
||||
return NULL; |
||||
#else |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
# ./pullrev.sh r1556818 |
||||
http://svn.apache.org/viewvc?view=revision&revision=r1556818 |
||||
--- httpd-2.4.6/modules/aaa/mod_authn_core.c 2014/01/09 14:30:23 1556817 |
||||
+++ httpd-2.4.6/modules/aaa/mod_authn_core.c 2014/01/09 14:32:47 1556818 |
||||
@@ -179,6 +179,12 @@ |
||||
return (void *) authcfg; |
||||
} |
||||
|
||||
+/* Only per-server directive we have is GLOBAL_ONLY */ |
||||
+static void *merge_authn_alias_svr_config(apr_pool_t *p, void *basev, void *overridesv) |
||||
+{ |
||||
+ return basev; |
||||
+} |
||||
+ |
||||
static const authn_provider authn_alias_provider = |
||||
{ |
||||
&authn_alias_check_password, |
||||
@@ -373,7 +379,7 @@ |
||||
create_authn_core_dir_config, /* dir config creater */ |
||||
merge_authn_core_dir_config, /* dir merger --- default is to override */ |
||||
create_authn_alias_svr_config, /* server config */ |
||||
- NULL, /* merge server config */ |
||||
+ merge_authn_alias_svr_config, /* merge server config */ |
||||
authn_cmds, |
||||
register_hooks /* register hooks */ |
||||
}; |
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
# ./pullrev.sh 1560093 |
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1331341 |
||||
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1560093 |
||||
|
||||
--- httpd-2.4.6/modules/cache/mod_cache.c |
||||
+++ httpd-2.4.6/modules/cache/mod_cache.c |
||||
@@ -1130,7 +1130,6 @@ |
||||
"Content-Range"))) |
||||
|| ((reason = cache_header_cmp(r->pool, left, right, |
||||
"Content-Type"))) |
||||
- || ((reason = cache_header_cmp(r->pool, left, right, "Expires"))) |
||||
|| ((reason = cache_header_cmp(r->pool, left, right, "ETag"))) |
||||
|| ((reason = cache_header_cmp(r->pool, left, right, |
||||
"Last-Modified")))) { |
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
--- a/modules/metadata/mod_remoteip.c 2014/02/17 14:11:38 1569005 |
||||
+++ b/modules/metadata/mod_remoteip.c 2014/02/17 14:12:30 1569006 |
||||
@@ -246,14 +246,14 @@ |
||||
|
||||
while (remote) { |
||||
|
||||
- /* verify c->client_addr is trusted if there is a trusted proxy list |
||||
+ /* verify user agent IP against the trusted proxy list |
||||
*/ |
||||
if (config->proxymatch_ip) { |
||||
int i; |
||||
remoteip_proxymatch_t *match; |
||||
match = (remoteip_proxymatch_t *)config->proxymatch_ip->elts; |
||||
for (i = 0; i < config->proxymatch_ip->nelts; ++i) { |
||||
- if (apr_ipsubnet_test(match[i].ip, c->client_addr)) { |
||||
+ if (apr_ipsubnet_test(match[i].ip, temp_sa)) { |
||||
internal = match[i].internal; |
||||
break; |
||||
} |
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
# ./pullrev.sh 1570327 |
||||
http://svn.apache.org/viewvc?view=revision&revision=1570327 |
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1327624 |
||||
|
||||
--- httpd-2.4.6/server/mpm_unix.c |
||||
+++ httpd-2.4.6/server/mpm_unix.c |
||||
@@ -742,7 +742,12 @@ |
||||
* readers stranded (a number of them could be tied up for |
||||
* a while serving time-consuming requests) |
||||
*/ |
||||
+ /* Recall: we only worry about IDLE child processes here */ |
||||
for (i = 0; i < num && rv == APR_SUCCESS; i++) { |
||||
+ if (ap_scoreboard_image->servers[i][0].status != SERVER_READY || |
||||
+ ap_scoreboard_image->servers[i][0].pid == 0) { |
||||
+ continue; |
||||
+ } |
||||
rv = dummy_connection(pod); |
||||
} |
||||
} |
@ -0,0 +1,29 @@
@@ -0,0 +1,29 @@
|
||||
--- a/modules/proxy/mod_proxy.c 2014/03/03 17:28:10 1573625 |
||||
+++ b/modules/proxy/mod_proxy.c 2014/03/03 17:28:17 1573626 |
||||
@@ -927,8 +927,25 @@ |
||||
struct dirconn_entry *list = (struct dirconn_entry *)conf->dirconn->elts; |
||||
|
||||
/* is this for us? */ |
||||
- if (!r->proxyreq || !r->filename || strncmp(r->filename, "proxy:", 6) != 0) |
||||
+ if (!r->filename) { |
||||
return DECLINED; |
||||
+ } |
||||
+ |
||||
+ if (!r->proxyreq) { |
||||
+ /* We may have forced the proxy handler via config or .htaccess */ |
||||
+ if (r->handler && |
||||
+ strncmp(r->handler, "proxy:", 6) == 0 && |
||||
+ strncmp(r->filename, "proxy:", 6) != 0) { |
||||
+ r->proxyreq = PROXYREQ_REVERSE; |
||||
+ r->filename = apr_pstrcat(r->pool, r->handler, r->filename, NULL); |
||||
+ apr_table_setn(r->notes, "rewrite-proxy", "1"); |
||||
+ } |
||||
+ else { |
||||
+ return DECLINED; |
||||
+ } |
||||
+ } else if (strncmp(r->filename, "proxy:", 6) != 0) { |
||||
+ return DECLINED; |
||||
+ } |
||||
|
||||
/* handle max-forwards / OPTIONS / TRACE */ |
||||
if ((str = apr_table_get(r->headers_in, "Max-Forwards"))) { |
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c |
||||
index 525109a..eb34eee 100644 |
||||
--- a/modules/proxy/mod_proxy_wstunnel.c |
||||
+++ b/modules/proxy/mod_proxy_wstunnel.c |
||||
@@ -103,10 +103,12 @@ static int proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o, |
||||
rv = ap_get_brigade(c_i->input_filters, bb, AP_MODE_READBYTES, |
||||
APR_NONBLOCK_READ, AP_IOBUFSIZE); |
||||
if (rv == APR_SUCCESS) { |
||||
- if (c_o->aborted) |
||||
+ if (c_o->aborted) { |
||||
return APR_EPIPE; |
||||
- if (APR_BRIGADE_EMPTY(bb)) |
||||
+ } |
||||
+ if (APR_BRIGADE_EMPTY(bb)){ |
||||
break; |
||||
+ } |
||||
#ifdef DEBUGGING |
||||
len = -1; |
||||
apr_brigade_length(bb, 0, &len); |
||||
@@ -178,7 +180,6 @@ static int ap_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; |
||||
- int client_error = 0; |
||||
char *buf; |
||||
apr_bucket_brigade *header_brigade; |
||||
apr_bucket *e; |
||||
@@ -224,7 +225,7 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r, |
||||
|
||||
pollfd.p = p; |
||||
pollfd.desc_type = APR_POLL_SOCKET; |
||||
- pollfd.reqevents = APR_POLLIN; |
||||
+ pollfd.reqevents = APR_POLLIN | APR_POLLHUP; |
||||
pollfd.desc.s = sock; |
||||
pollfd.client_data = NULL; |
||||
apr_pollset_add(pollset, &pollfd); |
||||
@@ -237,6 +238,9 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r, |
||||
r->proto_output_filters = c->output_filters; |
||||
r->input_filters = c->input_filters; |
||||
r->proto_input_filters = c->input_filters; |
||||
+ /* This handler should take care of the entire connection; make it so that |
||||
+ * nothing else is attempted on the connection after returning. */ |
||||
+ c->keepalive = AP_CONN_CLOSE; |
||||
|
||||
remove_reqtimeout(r->input_filters); |
||||
|
||||
@@ -257,26 +261,28 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r, |
||||
|
||||
if (cur->desc.s == sock) { |
||||
pollevent = cur->rtnevents; |
||||
- if (pollevent & APR_POLLIN) { |
||||
+ if (pollevent & (APR_POLLIN | APR_POLLHUP)) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02446) |
||||
"sock was readable"); |
||||
rv = proxy_wstunnel_transfer(r, backconn, c, bb, "sock"); |
||||
} |
||||
- else if ((pollevent & APR_POLLERR) |
||||
- || (pollevent & APR_POLLHUP)) { |
||||
+ else if (pollevent & APR_POLLERR) { |
||||
rv = APR_EPIPE; |
||||
ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO(02447) |
||||
- "err/hup on backconn"); |
||||
+ "err on backconn"); |
||||
} |
||||
- if (rv != APR_SUCCESS) |
||||
- client_error = 1; |
||||
} |
||||
else if (cur->desc.s == client_socket) { |
||||
pollevent = cur->rtnevents; |
||||
- if (pollevent & APR_POLLIN) { |
||||
+ if (pollevent & (APR_POLLIN | APR_POLLHUP)) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02448) |
||||
"client was readable"); |
||||
rv = proxy_wstunnel_transfer(r, c, backconn, bb, "client"); |
||||
+ } else if (pollevent & APR_POLLERR) { |
||||
+ rv = APR_EPIPE; |
||||
+ c->aborted = 1; |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, APLOGNO(02607) |
||||
+ "error on client conn"); |
||||
} |
||||
} |
||||
else { |
||||
@@ -294,9 +300,6 @@ static int ap_proxy_wstunnel_request(apr_pool_t *p, request_rec *r, |
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r, |
||||
"finished with poll() - cleaning up"); |
||||
|
||||
- if (client_error) { |
||||
- return HTTP_INTERNAL_SERVER_ERROR; |
||||
- } |
||||
return OK; |
||||
} |
||||
|
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
--- a/modules/ssl/ssl_util_stapling.c 2014/05/07 12:51:38 1593001 |
||||
+++ b/modules/ssl/ssl_util_stapling.c 2014/05/07 12:52:13 1593002 |
||||
@@ -145,14 +145,15 @@ |
||||
X509_digest(x, EVP_sha1(), cinf->idx, NULL); |
||||
|
||||
aia = X509_get1_ocsp(x); |
||||
- if (aia) |
||||
+ if (aia) { |
||||
cinf->uri = sk_OPENSSL_STRING_pop(aia); |
||||
+ X509_email_free(aia); |
||||
+ } |
||||
if (!cinf->uri && !mctx->stapling_force_url) { |
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02218) |
||||
"ssl_stapling_init_cert: no responder URL"); |
||||
+ return 0; |
||||
} |
||||
- if (aia) |
||||
- X509_email_free(aia); |
||||
return 1; |
||||
} |
||||
|
||||
@@ -403,6 +404,13 @@ |
||||
else |
||||
ocspuri = cinf->uri; |
||||
|
||||
+ if (!ocspuri) { |
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02621) |
||||
+ "stapling_renew_response: no uri for responder"); |
||||
+ rv = FALSE; |
||||
+ goto done; |
||||
+ } |
||||
+ |
||||
/* Create a temporary pool to constrain memory use */ |
||||
apr_pool_create(&vpool, conn->pool); |
||||
|
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
Index: modules/proxy/mod_proxy_wstunnel.c |
||||
=================================================================== |
||||
--- a/modules/proxy/mod_proxy_wstunnel.c (revision 1593857) |
||||
+++ b/modules/proxy/mod_proxy_wstunnel.c (revision 1594625) |
||||
@@ -477,9 +477,11 @@ |
||||
conn_rec *c = r->connection; |
||||
apr_pool_t *p = r->pool; |
||||
apr_uri_t *uri; |
||||
+ int is_ssl = 0; |
||||
|
||||
if (strncasecmp(url, "wss:", 4) == 0) { |
||||
scheme = "WSS"; |
||||
+ is_ssl = 1; |
||||
} |
||||
else if (strncasecmp(url, "ws:", 3) == 0) { |
||||
scheme = "WS"; |
||||
@@ -503,7 +505,7 @@ |
||||
return status; |
||||
} |
||||
|
||||
- backend->is_ssl = 0; |
||||
+ backend->is_ssl = is_ssl; |
||||
backend->close = 0; |
||||
|
||||
retry = 0; |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
--- a/modules/filters/mod_deflate.c 2014/02/26 15:24:07 1572091 |
||||
+++ b/modules/filters/mod_deflate.c 2014/02/26 15:30:25 1572092 |
||||
@@ -1125,7 +1125,8 @@ |
||||
} |
||||
ctx->stream.next_in += 4; |
||||
compLen = getLong(ctx->stream.next_in); |
||||
- if (ctx->stream.total_out != compLen) { |
||||
+ /* gzip stores original size only as 4 byte value */ |
||||
+ if ((ctx->stream.total_out & 0xFFFFFFFF) != compLen) { |
||||
inflateEnd(&ctx->stream); |
||||
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01395) |
||||
"Zlib: Length %ld of inflated data does " |
||||
@@ -1322,7 +1323,8 @@ |
||||
} |
||||
ctx->validation_buffer += VALIDATION_SIZE / 2; |
||||
compLen = getLong(ctx->validation_buffer); |
||||
- if (ctx->stream.total_out != compLen) { |
||||
+ /* gzip stores original size only as 4 byte value */ |
||||
+ if ((ctx->stream.total_out & 0xFFFFFFFF) != compLen) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01400) |
||||
"Zlib: Length of inflated stream invalid"); |
||||
return APR_EGENERAL; |
@ -0,0 +1,141 @@
@@ -0,0 +1,141 @@
|
||||
Index: modules/dav/main/mod_dav.c |
||||
=================================================================== |
||||
--- a/modules/dav/main/mod_dav.c (revision 1610012) |
||||
+++ b/modules/dav/main/mod_dav.c (revision 1610013) |
||||
@@ -396,9 +396,11 @@ |
||||
*/ |
||||
static const char *dav_xml_escape_uri(apr_pool_t *p, const char *uri) |
||||
{ |
||||
+ const char *e_uri = ap_escape_uri(p, uri); |
||||
+ |
||||
/* check the easy case... */ |
||||
- if (ap_strchr_c(uri, '&') == NULL) |
||||
- return uri; |
||||
+ if (ap_strchr_c(e_uri, '&') == NULL) |
||||
+ return e_uri; |
||||
|
||||
/* there was a '&', so more work is needed... sigh. */ |
||||
|
||||
@@ -406,7 +408,7 @@ |
||||
* Note: this is a teeny bit of overkill since we know there are no |
||||
* '<' or '>' characters, but who cares. |
||||
*/ |
||||
- return apr_xml_quote_string(p, uri, 0); |
||||
+ return apr_xml_quote_string(p, e_uri, 0); |
||||
} |
||||
|
||||
|
||||
Index: modules/dav/main/mod_dav.h |
||||
=================================================================== |
||||
--- a/modules/dav/main/mod_dav.h (revision 1610012) |
||||
+++ b/modules/dav/main/mod_dav.h (revision 1610013) |
||||
@@ -386,7 +386,9 @@ |
||||
* REGULAR and WORKSPACE resources, |
||||
* and is always 1 for WORKING */ |
||||
|
||||
- const char *uri; /* the escaped URI for this resource */ |
||||
+ const char *uri; /* the URI for this resource; |
||||
+ * currently has an ABI flaw where sometimes it is |
||||
+ * assumed to be encoded and sometimes not */ |
||||
|
||||
dav_resource_private *info; /* the provider's private info */ |
||||
|
||||
Index: modules/dav/main/props.c |
||||
=================================================================== |
||||
--- a/modules/dav/main/props.c (revision 1610012) |
||||
+++ b/modules/dav/main/props.c (revision 1610013) |
||||
@@ -321,10 +321,14 @@ |
||||
/* do a sub-request to fetch properties for the target resource's URI. */ |
||||
static void dav_do_prop_subreq(dav_propdb *propdb) |
||||
{ |
||||
+ /* need to escape the uri that's in the resource struct because during |
||||
+ * the property walker it's not encoded. */ |
||||
+ const char *e_uri = ap_escape_uri(propdb->resource->pool, |
||||
+ propdb->resource->uri); |
||||
+ |
||||
/* perform a "GET" on the resource's URI (note that the resource |
||||
may not correspond to the current request!). */ |
||||
- propdb->subreq = ap_sub_req_lookup_uri(propdb->resource->uri, propdb->r, |
||||
- NULL); |
||||
+ propdb->subreq = ap_sub_req_lookup_uri(e_uri, propdb->r, NULL); |
||||
} |
||||
|
||||
static dav_error * dav_insert_coreprop(dav_propdb *propdb, |
||||
Index: modules/dav/fs/repos.c |
||||
=================================================================== |
||||
--- a/modules/dav/fs/repos.c (revision 1610012) |
||||
+++ b/modules/dav/fs/repos.c (revision 1610013) |
||||
@@ -717,13 +717,13 @@ |
||||
resource->pool = r->pool; |
||||
|
||||
/* make sure the URI does not have a trailing "/" */ |
||||
- len = strlen(r->unparsed_uri); |
||||
- if (len > 1 && r->unparsed_uri[len - 1] == '/') { |
||||
- s = apr_pstrmemdup(r->pool, r->unparsed_uri, len-1); |
||||
+ len = strlen(r->uri); |
||||
+ if (len > 1 && r->uri[len - 1] == '/') { |
||||
+ s = apr_pstrmemdup(r->pool, r->uri, len-1); |
||||
resource->uri = s; |
||||
} |
||||
else { |
||||
- resource->uri = r->unparsed_uri; |
||||
+ resource->uri = r->uri; |
||||
} |
||||
|
||||
if (r->finfo.filetype != APR_NOFILE) { |
||||
@@ -1482,18 +1482,6 @@ |
||||
return dav_fs_deleteset(info->pool, resource); |
||||
} |
||||
|
||||
-/* Take an unescaped path component and escape it and append it onto a |
||||
- * dav_buffer for a URI */ |
||||
-static apr_size_t dav_fs_append_uri(apr_pool_t *p, dav_buffer *pbuf, |
||||
- const char *path, apr_size_t pad) |
||||
-{ |
||||
- const char *epath = ap_escape_uri(p, path); |
||||
- apr_size_t epath_len = strlen(epath); |
||||
- |
||||
- dav_buffer_place_mem(p, pbuf, epath, epath_len + 1, pad); |
||||
- return epath_len; |
||||
-} |
||||
- |
||||
/* ### move this to dav_util? */ |
||||
/* Walk recursively down through directories, * |
||||
* including lock-null resources as we go. */ |
||||
@@ -1549,7 +1537,6 @@ |
||||
} |
||||
while ((apr_dir_read(&dirent, APR_FINFO_DIRENT, dirp)) == APR_SUCCESS) { |
||||
apr_size_t len; |
||||
- apr_size_t escaped_len; |
||||
|
||||
len = strlen(dirent.name); |
||||
|
||||
@@ -1592,7 +1579,7 @@ |
||||
|
||||
/* copy the file to the URI, too. NOTE: we will pad an extra byte |
||||
for the trailing slash later. */ |
||||
- escaped_len = dav_fs_append_uri(pool, &fsctx->uri_buf, dirent.name, 1); |
||||
+ dav_buffer_place_mem(pool, &fsctx->uri_buf, dirent.name, len + 1, 1); |
||||
|
||||
/* if there is a secondary path, then do that, too */ |
||||
if (fsctx->path2.buf != NULL) { |
||||
@@ -1625,7 +1612,7 @@ |
||||
fsctx->path2.cur_len += len; |
||||
|
||||
/* adjust URI length to incorporate subdir and a slash */ |
||||
- fsctx->uri_buf.cur_len += escaped_len + 1; |
||||
+ fsctx->uri_buf.cur_len += len + 1; |
||||
fsctx->uri_buf.buf[fsctx->uri_buf.cur_len - 1] = '/'; |
||||
fsctx->uri_buf.buf[fsctx->uri_buf.cur_len] = '\0'; |
||||
|
||||
@@ -1691,8 +1678,8 @@ |
||||
*/ |
||||
dav_buffer_place_mem(pool, &fsctx->path1, |
||||
fsctx->locknull_buf.buf + offset, len + 1, 0); |
||||
- dav_fs_append_uri(pool, &fsctx->uri_buf, |
||||
- fsctx->locknull_buf.buf + offset, 0); |
||||
+ dav_buffer_place_mem(pool, &fsctx->uri_buf, |
||||
+ fsctx->locknull_buf.buf + offset, len + 1, 0); |
||||
if (fsctx->path2.buf != NULL) { |
||||
dav_buffer_place_mem(pool, &fsctx->path2, |
||||
fsctx->locknull_buf.buf + offset, |
@ -0,0 +1,189 @@
@@ -0,0 +1,189 @@
|
||||
Index: modules/ldap/util_ldap.c |
||||
=================================================================== |
||||
--- a/modules/ldap/util_ldap.c (revision 1610395) |
||||
+++ b/modules/ldap/util_ldap.c (revision 1610396) |
||||
@@ -157,10 +157,12 @@ |
||||
*/ |
||||
if (!ldc->keep) { |
||||
uldap_connection_unbind(ldc); |
||||
+ ldc->r = NULL; |
||||
} |
||||
else { |
||||
/* mark our connection as available for reuse */ |
||||
ldc->freed = apr_time_now(); |
||||
+ ldc->r = NULL; |
||||
#if APR_HAS_THREADS |
||||
apr_thread_mutex_unlock(ldc->lock); |
||||
#endif |
||||
@@ -179,6 +181,9 @@ |
||||
|
||||
if (ldc) { |
||||
if (ldc->ldap) { |
||||
+ if (ldc->r) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp unbind", ldc); |
||||
+ } |
||||
ldap_unbind_s(ldc->ldap); |
||||
ldc->ldap = NULL; |
||||
} |
||||
@@ -319,6 +324,8 @@ |
||||
return(result->rc); |
||||
} |
||||
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "LDC %pp init", ldc); |
||||
+ |
||||
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); |
||||
@@ -516,6 +523,10 @@ |
||||
ldc->reason = "LDAP: ldap_simple_bind() parse result failed"; |
||||
return uldap_ld_errno(ldc); |
||||
} |
||||
+ else { |
||||
+ ldc->last_backend_conn = ldc->r->request_time; |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp bind", ldc); |
||||
+ } |
||||
return rc; |
||||
} |
||||
|
||||
@@ -540,7 +551,7 @@ |
||||
|
||||
/* If the connection is already bound, return |
||||
*/ |
||||
- if (ldc->bound) |
||||
+ if (ldc->bound && !ldc->must_rebind) |
||||
{ |
||||
ldc->reason = "LDAP: connection open successful (already bound)"; |
||||
return LDAP_SUCCESS; |
||||
@@ -621,6 +632,7 @@ |
||||
} |
||||
else { |
||||
ldc->bound = 1; |
||||
+ ldc->must_rebind = 0; |
||||
ldc->reason = "LDAP: connection open successful"; |
||||
} |
||||
|
||||
@@ -718,13 +730,17 @@ |
||||
&& !compare_client_certs(dc->client_certs, l->client_certs)) |
||||
{ |
||||
if (st->connection_pool_ttl > 0) { |
||||
- if (l->bound && (now - l->freed) > st->connection_pool_ttl) { |
||||
+ if (l->bound && (now - l->last_backend_conn) > st->connection_pool_ttl) { |
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, |
||||
"Removing LDAP connection last used %" APR_TIME_T_FMT " seconds ago", |
||||
- (now - l->freed) / APR_USEC_PER_SEC); |
||||
+ (now - l->last_backend_conn) / APR_USEC_PER_SEC); |
||||
+ l->r = r; |
||||
uldap_connection_unbind(l); |
||||
/* Go ahead (by falling through) and use it, so we don't create more just to unbind some other old ones */ |
||||
} |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, |
||||
+ "Reuse %s LDC %pp", |
||||
+ l->bound ? "bound" : "unbound", l); |
||||
} |
||||
break; |
||||
} |
||||
@@ -751,12 +767,25 @@ |
||||
(l->deref == deref) && (l->secure == secureflag) && |
||||
!compare_client_certs(dc->client_certs, l->client_certs)) |
||||
{ |
||||
+ if (st->connection_pool_ttl > 0) { |
||||
+ if (l->bound && (now - l->last_backend_conn) > st->connection_pool_ttl) { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r, |
||||
+ "Removing LDAP connection last used %" APR_TIME_T_FMT " seconds ago", |
||||
+ (now - l->last_backend_conn) / APR_USEC_PER_SEC); |
||||
+ l->r = r; |
||||
+ uldap_connection_unbind(l); |
||||
+ /* Go ahead (by falling through) and use it, so we don't create more just to unbind some other old ones */ |
||||
+ } |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, |
||||
+ "Reuse %s LDC %pp (will rebind)", |
||||
+ l->bound ? "bound" : "unbound", l); |
||||
+ } |
||||
+ |
||||
/* the bind credentials have changed */ |
||||
- /* no check for connection_pool_ttl, since we are unbinding any way */ |
||||
- uldap_connection_unbind(l); |
||||
- |
||||
+ l->must_rebind = 1; |
||||
util_ldap_strdup((char**)&(l->binddn), binddn); |
||||
util_ldap_strdup((char**)&(l->bindpw), bindpw); |
||||
+ |
||||
break; |
||||
} |
||||
#if APR_HAS_THREADS |
||||
@@ -846,6 +875,7 @@ |
||||
#if APR_HAS_THREADS |
||||
apr_thread_mutex_unlock(st->mutex); |
||||
#endif |
||||
+ l->r = r; |
||||
return l; |
||||
} |
||||
|
||||
@@ -965,6 +995,7 @@ |
||||
return result; |
||||
} |
||||
|
||||
+ ldc->last_backend_conn = r->request_time; |
||||
entry = ldap_first_entry(ldc->ldap, res); |
||||
searchdn = ldap_get_dn(ldc->ldap, entry); |
||||
|
||||
@@ -1116,6 +1147,7 @@ |
||||
goto start_over; |
||||
} |
||||
|
||||
+ ldc->last_backend_conn = r->request_time; |
||||
ldc->reason = "Comparison complete"; |
||||
if ((LDAP_COMPARE_TRUE == result) || |
||||
(LDAP_COMPARE_FALSE == result) || |
||||
@@ -1241,6 +1273,7 @@ |
||||
return res; |
||||
} |
||||
|
||||
+ ldc->last_backend_conn = r->request_time; |
||||
entry = ldap_first_entry(ldc->ldap, sga_res); |
||||
|
||||
/* |
||||
@@ -1723,6 +1756,7 @@ |
||||
* We should have found exactly one entry; to find a different |
||||
* number is an error. |
||||
*/ |
||||
+ ldc->last_backend_conn = r->request_time; |
||||
count = ldap_count_entries(ldc->ldap, res); |
||||
if (count != 1) |
||||
{ |
||||
@@ -1788,10 +1822,10 @@ |
||||
/* |
||||
* We have just bound the connection to a different user and password |
||||
* combination, which might be reused unintentionally next time this |
||||
- * connection is used from the connection pool. To ensure no confusion, |
||||
- * we mark the connection as unbound. |
||||
+ * connection is used from the connection pool. |
||||
*/ |
||||
- ldc->bound = 0; |
||||
+ ldc->must_rebind = 0; |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "LDC %pp used for authn, must be rebound", ldc); |
||||
} |
||||
|
||||
/* |
||||
@@ -1983,6 +2017,7 @@ |
||||
* We should have found exactly one entry; to find a different |
||||
* number is an error. |
||||
*/ |
||||
+ ldc->last_backend_conn = r->request_time; |
||||
count = ldap_count_entries(ldc->ldap, res); |
||||
if (count != 1) |
||||
{ |
||||
Index: include/util_ldap.h |
||||
=================================================================== |
||||
--- a/include/util_ldap.h (revision 1610395) |
||||
+++ b/include/util_ldap.h (revision 1610396) |
||||
@@ -133,6 +133,9 @@ |
||||
int ReferralHopLimit; /* # of referral hops to follow (default = AP_LDAP_DEFAULT_HOPLIMIT) */ |
||||
apr_time_t freed; /* the time this conn was placed back in the pool */ |
||||
apr_pool_t *rebind_pool; /* frequently cleared pool for rebind data */ |
||||
+ int must_rebind; /* The connection was last bound with other then binddn/bindpw */ |
||||
+ request_rec *r; /* request_rec used to find this util_ldap_connection_t */ |
||||
+ apr_time_t last_backend_conn; /* the approximate time of the last backend LDAP requst */ |
||||
} util_ldap_connection_t; |
||||
|
||||
typedef struct util_ldap_config_t { |
@ -0,0 +1,28 @@
@@ -0,0 +1,28 @@
|
||||
# ./pullrev.sh r1618851 |
||||
http://svn.apache.org/viewvc?view=revision&revision=r1618851 |
||||
|
||||
--- httpd-2.4.6/modules/aaa/mod_authz_core.c |
||||
+++ httpd-2.4.6/modules/aaa/mod_authz_core.c |
||||
@@ -168,6 +168,13 @@ |
||||
return (void*)conf; |
||||
} |
||||
|
||||
+/* Only per-server directive we have is GLOBAL_ONLY */ |
||||
+static void *merge_authz_core_svr_config(apr_pool_t *p, |
||||
+ void *basev, void *newv) |
||||
+{ |
||||
+ return basev; |
||||
+} |
||||
+ |
||||
static void *create_authz_core_svr_config(apr_pool_t *p, server_rec *s) |
||||
{ |
||||
authz_core_srv_conf *authcfg; |
||||
@@ -1140,7 +1148,7 @@ AP_DECLARE_MODULE(authz_core) = |
||||
create_authz_core_dir_config, /* dir config creater */ |
||||
merge_authz_core_dir_config, /* dir merger */ |
||||
create_authz_core_svr_config, /* server config */ |
||||
- NULL, /* merge server config */ |
||||
+ merge_authz_core_svr_config , /* merge server config */ |
||||
authz_cmds, |
||||
register_hooks /* register hooks */ |
||||
}; |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
--- a/modules/proxy/mod_proxy_http.c 2014/08/31 16:06:36 1621600 |
||||
+++ b/modules/proxy/mod_proxy_http.c 2014/08/31 16:07:45 1621601 |
||||
@@ -1652,6 +1652,18 @@ |
||||
if (!r->header_only && /* not HEAD request */ |
||||
(proxy_status != HTTP_NO_CONTENT) && /* not 204 */ |
||||
(proxy_status != HTTP_NOT_MODIFIED)) { /* not 304 */ |
||||
+ const char *tmp; |
||||
+ /* Add minimal headers needed to allow http_in filter |
||||
+ * detecting end of body without waiting for a timeout. */ |
||||
+ if ((tmp = apr_table_get(r->headers_out, "Transfer-Encoding"))) { |
||||
+ apr_table_set(backend->r->headers_in, "Transfer-Encoding", tmp); |
||||
+ } |
||||
+ else if ((tmp = apr_table_get(r->headers_out, "Content-Length"))) { |
||||
+ apr_table_set(backend->r->headers_in, "Content-Length", tmp); |
||||
+ } |
||||
+ else if (te) { |
||||
+ apr_table_set(backend->r->headers_in, "Transfer-Encoding", te); |
||||
+ } |
||||
ap_discard_request_body(backend->r); |
||||
} |
||||
return proxy_status; |
@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
|
||||
diff --git a/server/scoreboard.c b/server/scoreboard.c |
||||
index bef2b90..c8ef6a3 100644 |
||||
--- a/server/scoreboard.c |
||||
+++ b/server/scoreboard.c |
||||
@@ -484,8 +484,14 @@ static int update_child_status_internal(int child_num, |
||||
ws->conn_bytes = 0; |
||||
} |
||||
if (r) { |
||||
- apr_cpystrn(ws->client, ap_get_remote_host(c, r->per_dir_config, |
||||
- REMOTE_NOLOOKUP, NULL), sizeof(ws->client)); |
||||
+ const char *client = ap_get_remote_host(c, r->per_dir_config, |
||||
+ REMOTE_NOLOOKUP, NULL); |
||||
+ if (!client || !strcmp(client, c->client_ip)) { |
||||
+ apr_cpystrn(ws->client, r->useragent_ip, sizeof(ws->client)); |
||||
+ } |
||||
+ else { |
||||
+ apr_cpystrn(ws->client, client, sizeof(ws->client)); |
||||
+ } |
||||
copy_request(ws->request, sizeof(ws->request), r); |
||||
if (r->server) { |
||||
apr_snprintf(ws->vhost, sizeof(ws->vhost), "%s:%d", |
@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
|
||||
# ./pullrev.sh 1631119 |
||||
http://svn.apache.org/viewvc?view=revision&revision=1631119 |
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1415257 |
||||
|
||||
--- httpd-2.4.6/modules/ldap/util_ldap.c |
||||
+++ httpd-2.4.6/modules/ldap/util_ldap.c |
||||
@@ -1824,7 +1824,7 @@ |
||||
* combination, which might be reused unintentionally next time this |
||||
* connection is used from the connection pool. |
||||
*/ |
||||
- ldc->must_rebind = 0; |
||||
+ ldc->must_rebind = 1; |
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "LDC %pp used for authn, must be rebound", ldc); |
||||
} |
||||
|
@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
|
||||
--- a/modules/ssl/ssl_engine_io.c 2014/10/20 09:11:19 1633084 |
||||
+++ b/modules/ssl/ssl_engine_io.c 2014/10/20 09:18:22 1633085 |
||||
@@ -1322,6 +1322,11 @@ |
||||
"\"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 ? |
@ -0,0 +1,275 @@
@@ -0,0 +1,275 @@
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c |
||||
index 9811af8..568627f 100644 |
||||
--- a/modules/ssl/ssl_engine_init.c |
||||
+++ b/modules/ssl/ssl_engine_init.c |
||||
@@ -276,7 +276,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, |
||||
return HTTP_INTERNAL_SERVER_ERROR; |
||||
} |
||||
#ifdef HAVE_OCSP_STAPLING |
||||
- ssl_stapling_ex_init(); |
||||
+ ssl_stapling_certinfo_hash_init(p); |
||||
#endif |
||||
|
||||
/* |
||||
@@ -899,6 +899,8 @@ static void ssl_init_ctx(server_rec *s, |
||||
} |
||||
|
||||
static int ssl_server_import_cert(server_rec *s, |
||||
+ apr_pool_t *p, |
||||
+ apr_pool_t *ptemp, |
||||
modssl_ctx_t *mctx, |
||||
const char *id, |
||||
int idx) |
||||
@@ -933,7 +935,7 @@ static int ssl_server_import_cert(server_rec *s, |
||||
|
||||
#ifdef HAVE_OCSP_STAPLING |
||||
if ((mctx->pkp == FALSE) && (mctx->stapling_enabled == TRUE)) { |
||||
- if (!ssl_stapling_init_cert(s, mctx, cert)) { |
||||
+ if (!ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) { |
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02235) |
||||
"Unable to configure server certificate for stapling"); |
||||
} |
||||
@@ -1081,10 +1083,10 @@ static void ssl_init_server_certs(server_rec *s, |
||||
ecc_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_ECC); |
||||
#endif |
||||
|
||||
- have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA); |
||||
- have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA); |
||||
+ have_rsa = ssl_server_import_cert(s, p, ptemp, mctx, rsa_id, SSL_AIDX_RSA); |
||||
+ have_dsa = ssl_server_import_cert(s, p, ptemp, mctx, dsa_id, SSL_AIDX_DSA); |
||||
#ifndef OPENSSL_NO_EC |
||||
- have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC); |
||||
+ have_ecc = ssl_server_import_cert(s, p, ptemp, mctx, ecc_id, SSL_AIDX_ECC); |
||||
#endif |
||||
|
||||
if (!(have_rsa || have_dsa |
||||
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h |
||||
index 80e1e8e..0cc6d3f 100644 |
||||
--- a/modules/ssl/ssl_private.h |
||||
+++ b/modules/ssl/ssl_private.h |
||||
@@ -132,6 +132,13 @@ |
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908080 && !defined(OPENSSL_NO_OCSP) \ |
||||
&& !defined(OPENSSL_NO_TLSEXT) |
||||
#define HAVE_OCSP_STAPLING |
||||
+/* backward compatibility with OpenSSL < 1.0 */ |
||||
+#ifndef sk_OPENSSL_STRING_num |
||||
+#define sk_OPENSSL_STRING_num sk_num |
||||
+#endif |
||||
+#ifndef sk_OPENSSL_STRING_value |
||||
+#define sk_OPENSSL_STRING_value sk_value |
||||
+#endif |
||||
#if (OPENSSL_VERSION_NUMBER < 0x10000000) |
||||
#define sk_OPENSSL_STRING_pop sk_pop |
||||
#endif |
||||
@@ -862,10 +869,10 @@ const char *ssl_cmd_SSLStaplingErrorCacheTimeout(cmd_parms *, void *, const char |
||||
const char *ssl_cmd_SSLStaplingReturnResponderErrors(cmd_parms *, void *, int); |
||||
const char *ssl_cmd_SSLStaplingFakeTryLater(cmd_parms *, void *, int); |
||||
const char *ssl_cmd_SSLStaplingResponderTimeout(cmd_parms *, void *, const char *); |
||||
-const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *, void *, const char *); |
||||
+const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *, void *, const char *); |
||||
void modssl_init_stapling(server_rec *, apr_pool_t *, apr_pool_t *, modssl_ctx_t *); |
||||
-void ssl_stapling_ex_init(void); |
||||
-int ssl_stapling_init_cert(server_rec *s, modssl_ctx_t *mctx, X509 *x); |
||||
+void ssl_stapling_certinfo_hash_init(apr_pool_t *); |
||||
+int ssl_stapling_init_cert(server_rec *, apr_pool_t *, apr_pool_t *, modssl_ctx_t *, X509 *); |
||||
#endif |
||||
#ifndef OPENSSL_NO_SRP |
||||
int ssl_callback_SRPServerParams(SSL *, int *, void *); |
||||
diff --git a/modules/ssl/ssl_util_stapling.c b/modules/ssl/ssl_util_stapling.c |
||||
index 2be2c36..2387ae1 100644 |
||||
--- a/modules/ssl/ssl_util_stapling.c |
||||
+++ b/modules/ssl/ssl_util_stapling.c |
||||
@@ -43,36 +43,32 @@ |
||||
|
||||
#define MAX_STAPLING_DER 10240 |
||||
|
||||
-/* Cached info stored in certificate ex_info. */ |
||||
+/* Cached info stored in the global stapling_certinfo hash. */ |
||||
typedef struct { |
||||
- /* Index in session cache SHA1 hash of certificate */ |
||||
- UCHAR idx[20]; |
||||
- /* Certificate ID for OCSP requests or NULL if ID cannot be determined */ |
||||
+ /* Index in session cache (SHA-1 digest of DER encoded certificate) */ |
||||
+ UCHAR idx[SHA_DIGEST_LENGTH]; |
||||
+ /* Certificate ID for OCSP request */ |
||||
OCSP_CERTID *cid; |
||||
- /* Responder details */ |
||||
+ /* URI of the OCSP responder */ |
||||
char *uri; |
||||
} certinfo; |
||||
|
||||
-static void certinfo_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, |
||||
- int idx, long argl, void *argp) |
||||
+static apr_status_t ssl_stapling_certid_free(void *data) |
||||
{ |
||||
- certinfo *cinf = ptr; |
||||
+ OCSP_CERTID *cid = data; |
||||
|
||||
- if (!cinf) |
||||
- return; |
||||
- if (cinf->uri) |
||||
- OPENSSL_free(cinf->uri); |
||||
- OPENSSL_free(cinf); |
||||
+ if (cid) { |
||||
+ OCSP_CERTID_free(cid); |
||||
+ } |
||||
+ |
||||
+ return APR_SUCCESS; |
||||
} |
||||
|
||||
-static int stapling_ex_idx = -1; |
||||
+static apr_hash_t *stapling_certinfo; |
||||
|
||||
-void ssl_stapling_ex_init(void) |
||||
+void ssl_stapling_certinfo_hash_init(apr_pool_t *p) |
||||
{ |
||||
- if (stapling_ex_idx != -1) |
||||
- return; |
||||
- stapling_ex_idx = X509_get_ex_new_index(0, "X509 cached OCSP info", 0, 0, |
||||
- certinfo_free); |
||||
+ stapling_certinfo = apr_hash_make(p); |
||||
} |
||||
|
||||
static X509 *stapling_get_issuer(modssl_ctx_t *mctx, X509 *x) |
||||
@@ -106,70 +102,97 @@ static X509 *stapling_get_issuer(modssl_ctx_t *mctx, X509 *x) |
||||
|
||||
} |
||||
|
||||
-int ssl_stapling_init_cert(server_rec *s, modssl_ctx_t *mctx, X509 *x) |
||||
+int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, |
||||
+ modssl_ctx_t *mctx, X509 *x) |
||||
{ |
||||
- certinfo *cinf; |
||||
+ UCHAR idx[SHA_DIGEST_LENGTH]; |
||||
+ certinfo *cinf = NULL; |
||||
X509 *issuer = NULL; |
||||
+ OCSP_CERTID *cid = NULL; |
||||
STACK_OF(OPENSSL_STRING) *aia = NULL; |
||||
|
||||
- if (x == NULL) |
||||
+ if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1)) |
||||
return 0; |
||||
- cinf = X509_get_ex_data(x, stapling_ex_idx); |
||||
+ |
||||
+ cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx)); |
||||
if (cinf) { |
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02215) |
||||
- "ssl_stapling_init_cert: certificate already initialized!"); |
||||
- return 0; |
||||
- } |
||||
- cinf = OPENSSL_malloc(sizeof(certinfo)); |
||||
- if (!cinf) { |
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02216) |
||||
- "ssl_stapling_init_cert: error allocating memory!"); |
||||
- return 0; |
||||
+ /* |
||||
+ * We already parsed the certificate, and no OCSP URI was found. |
||||
+ * The certificate might be used for multiple vhosts, though, |
||||
+ * so we check for a ForceURL for this vhost. |
||||
+ */ |
||||
+ if (!cinf->uri && !mctx->stapling_force_url) { |
||||
+ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, |
||||
+ APLOGNO(02814) "ssl_stapling_init_cert: no OCSP URI " |
||||
+ "in certificate and no SSLStaplingForceURL " |
||||
+ "configured for server %s", mctx->sc->vhost_id); |
||||
+ return 0; |
||||
+ } |
||||
+ return 1; |
||||
} |
||||
- cinf->cid = NULL; |
||||
- cinf->uri = NULL; |
||||
- X509_set_ex_data(x, stapling_ex_idx, cinf); |
||||
- |
||||
- issuer = stapling_get_issuer(mctx, x); |
||||
|
||||
- if (issuer == NULL) { |
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02217) |
||||
- "ssl_stapling_init_cert: Can't retrieve issuer certificate!"); |
||||
+ 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; |
||||
} |
||||
|
||||
- cinf->cid = OCSP_cert_to_id(NULL, x, issuer); |
||||
+ cid = OCSP_cert_to_id(NULL, x, issuer); |
||||
X509_free(issuer); |
||||
- if (!cinf->cid) |
||||
+ if (!cid) { |
||||
+ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02815) |
||||
+ "ssl_stapling_init_cert: can't create CertID " |
||||
+ "for OCSP request"); |
||||
return 0; |
||||
- X509_digest(x, EVP_sha1(), cinf->idx, NULL); |
||||
+ } |
||||
|
||||
aia = X509_get1_ocsp(x); |
||||
- if (aia) { |
||||
- cinf->uri = sk_OPENSSL_STRING_pop(aia); |
||||
- X509_email_free(aia); |
||||
- } |
||||
- if (!cinf->uri && !mctx->stapling_force_url) { |
||||
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02218) |
||||
- "ssl_stapling_init_cert: no responder URL"); |
||||
+ |
||||
+ if (!aia && !mctx->stapling_force_url) { |
||||
+ OCSP_CERTID_free(cid); |
||||
+ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, |
||||
+ APLOGNO(02218) "ssl_stapling_init_cert: no OCSP URI " |
||||
+ "in certificate and no SSLStaplingForceURL set"); |
||||
return 0; |
||||
} |
||||
+ |
||||
+ /* At this point, we have determined that there's something to store */ |
||||
+ cinf = apr_pcalloc(p, sizeof(certinfo)); |
||||
+ memcpy (cinf->idx, idx, sizeof(idx)); |
||||
+ cinf->cid = cid; |
||||
+ /* make sure cid is also freed at pool cleanup */ |
||||
+ apr_pool_cleanup_register(p, cid, ssl_stapling_certid_free, |
||||
+ apr_pool_cleanup_null); |
||||
+ if (aia) { |
||||
+ /* allocate uri from the pconf pool */ |
||||
+ cinf->uri = apr_pstrdup(p, sk_OPENSSL_STRING_value(aia, 0)); |
||||
+ X509_email_free(aia); |
||||
+ } |
||||
+ |
||||
+ ssl_log_xerror(SSLLOG_MARK, APLOG_TRACE1, 0, ptemp, s, x, |
||||
+ "ssl_stapling_init_cert: storing certinfo for server %s", |
||||
+ mctx->sc->vhost_id); |
||||
+ |
||||
+ apr_hash_set(stapling_certinfo, cinf->idx, sizeof(cinf->idx), cinf); |
||||
+ |
||||
return 1; |
||||
} |
||||
|
||||
-static certinfo *stapling_get_cert_info(server_rec *s, modssl_ctx_t *mctx, |
||||
+static certinfo *stapling_get_certinfo(server_rec *s, modssl_ctx_t *mctx, |
||||
SSL *ssl) |
||||
{ |
||||
certinfo *cinf; |
||||
X509 *x; |
||||
+ UCHAR idx[SHA_DIGEST_LENGTH]; |
||||
x = SSL_get_certificate(ssl); |
||||
- if (x == NULL) |
||||
+ if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1)) |
||||
return NULL; |
||||
- cinf = X509_get_ex_data(x, stapling_ex_idx); |
||||
+ cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx)); |
||||
if (cinf && cinf->cid) |
||||
return cinf; |
||||
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01926) |
||||
- "stapling_get_cert_info: stapling not supported for certificate"); |
||||
+ "stapling_get_certinfo: stapling not supported for certificate"); |
||||
return NULL; |
||||
} |
||||
|
||||
@@ -585,7 +608,7 @@ static int stapling_cb(SSL *ssl, void *arg) |
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951) |
||||
"stapling_cb: OCSP Stapling callback called"); |
||||
|
||||
- cinf = stapling_get_cert_info(s, mctx, ssl); |
||||
+ cinf = stapling_get_certinfo(s, mctx, ssl); |
||||
if (cinf == NULL) { |
||||
return SSL_TLSEXT_ERR_NOACK; |
||||
} |
@ -0,0 +1,132 @@
@@ -0,0 +1,132 @@
|
||||
diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en |
||||
index ca178ab..4580f1c 100644 |
||||
--- a/docs/manual/mod/mod_ssl.html.en |
||||
+++ b/docs/manual/mod/mod_ssl.html.en |
||||
@@ -57,6 +57,7 @@ to provide the cryptography engine.</p> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#sslcertificatekeyfile">SSLCertificateKeyFile</a></li> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#sslciphersuite">SSLCipherSuite</a></li> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#sslcompression">SSLCompression</a></li> |
||||
+<li><img alt="" src="../images/down.gif" /> <a href="#sslsessiontickets">SSLSessionTickets</a></li> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#sslcryptodevice">SSLCryptoDevice</a></li> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#sslengine">SSLEngine</a></li> |
||||
<li><img alt="" src="../images/down.gif" /> <a href="#sslfips">SSLFIPS</a></li> |
||||
@@ -797,6 +798,26 @@ CRIME attack).</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="SSLSessionTickets" id="SSLSessionTickets">SSLSessionTickets</a> <a name="sslsessiontickets" id="sslsessiontickets">Directive</a></h2> |
||||
+<table class="directive"> |
||||
+<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Enable or disable use of TLS session tickets</td></tr> |
||||
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>SSLSessionTickets on|off</code></td></tr> |
||||
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>SSLCompression 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>Extension</td></tr> |
||||
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_ssl</td></tr> |
||||
+<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>Available.</td></tr> |
||||
+</table> |
||||
+<p>This directive allows to enable or disable the use of TLS session tickets(RFC 5077).</p> |
||||
+<div class="warning"> |
||||
+<p>TLS session tickets are enabled by default. Using them without restarting |
||||
+the web server with an appropriate frequency (e.g. daily) compromises perfect |
||||
+forward secrecy.</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="SSLCryptoDevice" id="SSLCryptoDevice">SSLCryptoDevice</a> <a name="sslcryptodevice" id="sslcryptodevice">Directive</a></h2> |
||||
<table class="directive"> |
||||
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c |
||||
index bbe1d20..4a8b661 100644 |
||||
--- a/modules/ssl/mod_ssl.c |
||||
+++ b/modules/ssl/mod_ssl.c |
||||
@@ -141,6 +141,9 @@ static const command_rec ssl_config_cmds[] = { |
||||
SSL_CMD_SRV(Compression, FLAG, |
||||
"Enable SSL level compression" |
||||
"(`on', `off')") |
||||
+ SSL_CMD_SRV(SessionTickets, FLAG, |
||||
+ "Enable or disable TLS session tickets" |
||||
+ "(`on', `off')") |
||||
SSL_CMD_SRV(InsecureRenegotiation, FLAG, |
||||
"Enable support for insecure renegotiation") |
||||
SSL_CMD_ALL(UserName, TAKE1, |
||||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c |
||||
index 9530fcc..86a7f0f 100644 |
||||
--- a/modules/ssl/ssl_engine_config.c |
||||
+++ b/modules/ssl/ssl_engine_config.c |
||||
@@ -216,6 +216,7 @@ static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p) |
||||
#ifndef OPENSSL_NO_COMP |
||||
sc->compression = UNSET; |
||||
#endif |
||||
+ sc->session_tickets = UNSET; |
||||
|
||||
modssl_ctx_init_proxy(sc, p); |
||||
|
||||
@@ -346,6 +347,7 @@ void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv) |
||||
#ifndef OPENSSL_NO_COMP |
||||
cfgMergeBool(compression); |
||||
#endif |
||||
+ cfgMergeBool(session_tickets); |
||||
|
||||
modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy); |
||||
|
||||
@@ -720,6 +722,17 @@ const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag) |
||||
#endif |
||||
} |
||||
|
||||
+const char *ssl_cmd_SSLSessionTickets(cmd_parms *cmd, void *dcfg, int flag) |
||||
+{ |
||||
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server); |
||||
+#ifndef SSL_OP_NO_TICKET |
||||
+ return "This version of OpenSSL does not support using " |
||||
+ "SSLSessionTickets."; |
||||
+#endif |
||||
+ sc->session_tickets = flag ? TRUE : FALSE; |
||||
+ return NULL; |
||||
+} |
||||
+ |
||||
const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag) |
||||
{ |
||||
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION |
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c |
||||
index 568627f..672760c 100644 |
||||
--- a/modules/ssl/ssl_engine_init.c |
||||
+++ b/modules/ssl/ssl_engine_init.c |
||||
@@ -566,6 +566,16 @@ static void ssl_init_ctx_protocol(server_rec *s, |
||||
} |
||||
#endif |
||||
|
||||
+#ifdef SSL_OP_NO_TICKET |
||||
+ /* |
||||
+ * Configure using RFC 5077 TLS session tickets |
||||
+ * for session resumption. |
||||
+ */ |
||||
+ if (sc->session_tickets == FALSE) { |
||||
+ SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET); |
||||
+ } |
||||
+#endif |
||||
+ |
||||
#ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION |
||||
if (sc->insecure_reneg == TRUE) { |
||||
SSL_CTX_set_options(ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION); |
||||
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h |
||||
index 0cc6d3f..b601316 100644 |
||||
--- a/modules/ssl/ssl_private.h |
||||
+++ b/modules/ssl/ssl_private.h |
||||
@@ -701,6 +701,7 @@ struct SSLSrvConfigRec { |
||||
#ifndef OPENSSL_NO_COMP |
||||
BOOL compression; |
||||
#endif |
||||
+ BOOL session_tickets; |
||||
}; |
||||
|
||||
/** |
||||
@@ -756,6 +757,7 @@ const char *ssl_cmd_SSLCARevocationFile(cmd_parms *, void *, const char *); |
||||
const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *, void *, const char *); |
||||
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag); |
||||
const char *ssl_cmd_SSLCompression(cmd_parms *, void *, int flag); |
||||
+const char *ssl_cmd_SSLSessionTickets(cmd_parms *, void *, int flag); |
||||
const char *ssl_cmd_SSLVerifyClient(cmd_parms *, void *, const char *); |
||||
const char *ssl_cmd_SSLVerifyDepth(cmd_parms *, void *, const char *); |
||||
const char *ssl_cmd_SSLSessionCache(cmd_parms *, void *, const char *); |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c |
||||
index c37a09b..2121892 100644 |
||||
--- a/modules/proxy/proxy_util.c |
||||
+++ b/modules/proxy/proxy_util.c |
||||
@@ -1733,6 +1733,9 @@ PROXY_DECLARE(char *) ap_proxy_define_worker(apr_pool_t *p, |
||||
|
||||
memset(wshared, 0, sizeof(proxy_worker_shared)); |
||||
|
||||
+ if (uri.port && uri.port == ap_proxy_port_of_scheme(uri.scheme)) { |
||||
+ uri.port = 0; |
||||
+ } |
||||
ptr = apr_uri_unparse(p, &uri, APR_URI_UNP_REVEALPASSWORD); |
||||
if (PROXY_STRNCPY(wshared->name, ptr) != APR_SUCCESS) { |
||||
return apr_psprintf(p, "worker name (%s) too long", ptr); |
||||
@@ -2688,6 +2691,13 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, |
||||
worker->s->hostname); |
||||
break; |
||||
} |
||||
+ |
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02823) |
||||
+ "%s: connection established with Unix domain socket " |
||||
+ "%s (%s)", |
||||
+ proxy_function, |
||||
+ conn->uds_path, |
||||
+ worker->s->hostname); |
||||
} |
||||
else |
||||
#endif |
||||
@@ -2780,6 +2790,12 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, |
||||
backend_addr = backend_addr->next; |
||||
continue; |
||||
} |
||||
+ |
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02824) |
||||
+ "%s: connection established with %pI (%s)", |
||||
+ proxy_function, |
||||
+ backend_addr, |
||||
+ worker->s->hostname); |
||||
} |
||||
|
||||
/* Set a timeout on the socket */ |
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
--- a/modules/proxy/mod_proxy_fcgi.c 2015/01/09 21:25:26 1650676 |
||||
+++ b/modules/proxy/mod_proxy_fcgi.c 2015/01/09 21:33:12 1650677 |
||||
@@ -367,7 +367,7 @@ |
||||
request_rec *r, int request_id) |
||||
{ |
||||
apr_bucket_brigade *ib, *ob; |
||||
- int seen_end_of_headers = 0, done = 0; |
||||
+ int seen_end_of_headers = 0, done = 0, ignore_body = 0; |
||||
apr_status_t rv = APR_SUCCESS; |
||||
int script_error_status = HTTP_OK; |
||||
conn_rec *c = r->connection; |
||||
@@ -577,9 +577,16 @@ |
||||
APR_BRIGADE_INSERT_TAIL(ob, tmp_b); |
||||
r->status = status; |
||||
ap_pass_brigade(r->output_filters, ob); |
||||
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01070) |
||||
- "Error parsing script headers"); |
||||
- rv = APR_EINVAL; |
||||
+ if (status == HTTP_NOT_MODIFIED) { |
||||
+ /* The 304 response MUST NOT contain |
||||
+ * a message-body, ignore it. */ |
||||
+ ignore_body = 1; |
||||
+ } |
||||
+ else { |
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01070) |
||||
+ "Error parsing script headers"); |
||||
+ rv = APR_EINVAL; |
||||
+ } |
||||
break; |
||||
} |
||||
|
||||
@@ -598,7 +605,7 @@ |
||||
r->status = HTTP_OK; |
||||
} |
||||
|
||||
- if (script_error_status == HTTP_OK) { |
||||
+ if (script_error_status == HTTP_OK && !ignore_body) { |
||||
rv = ap_pass_brigade(r->output_filters, ob); |
||||
if (rv != APR_SUCCESS) { |
||||
break; |
||||
@@ -626,7 +633,7 @@ |
||||
* but that could be a huge amount of data; so we pass |
||||
* along smaller chunks |
||||
*/ |
||||
- if (script_error_status == HTTP_OK) { |
||||
+ if (script_error_status == HTTP_OK && !ignore_body) { |
||||
rv = ap_pass_brigade(r->output_filters, ob); |
||||
if (rv != APR_SUCCESS) { |
||||
break; |
@ -0,0 +1,10 @@
@@ -0,0 +1,10 @@
|
||||
--- a/server/core.c 2015/01/12 13:37:20 1651082 |
||||
+++ b/server/core.c 2015/01/12 13:38:02 1651083 |
||||
@@ -1271,6 +1271,7 @@ |
||||
static int reset_config_defines(void *dummy) |
||||
{ |
||||
ap_server_config_defines = saved_server_config_defines; |
||||
+ saved_server_config_defines = NULL; |
||||
server_config_defined_vars = NULL; |
||||
return OK; |
||||
} |
@ -0,0 +1,100 @@
@@ -0,0 +1,100 @@
|
||||
diff --git a/server/util.c b/server/util.c |
||||
index e0ba5c2..a6516d4 100644 |
||||
--- a/server/util.c |
||||
+++ b/server/util.c |
||||
@@ -968,20 +968,20 @@ AP_DECLARE(const char *) ap_pcfg_strerror(apr_pool_t *p, ap_configfile_t *cfp, |
||||
/* Read one line from open ap_configfile_t, strip LF, increase line number */ |
||||
/* If custom handler does not define a getstr() function, read char by char */ |
||||
static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, |
||||
- ap_configfile_t *cfp) |
||||
+ apr_size_t offset, ap_configfile_t *cfp) |
||||
{ |
||||
apr_status_t rc; |
||||
/* If a "get string" function is defined, use it */ |
||||
if (cfp->getstr != NULL) { |
||||
char *cp; |
||||
- char *cbuf = buf; |
||||
- apr_size_t cbufsize = bufsize; |
||||
+ char *cbuf = buf + offset; |
||||
+ apr_size_t cbufsize = bufsize - offset; |
||||
|
||||
while (1) { |
||||
++cfp->line_number; |
||||
rc = cfp->getstr(cbuf, cbufsize, cfp->param); |
||||
if (rc == APR_EOF) { |
||||
- if (cbuf != buf) { |
||||
+ if (cbuf != buf + offset) { |
||||
*cbuf = '\0'; |
||||
break; |
||||
} |
||||
@@ -999,11 +999,11 @@ static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, |
||||
*/ |
||||
cp = cbuf; |
||||
cp += strlen(cp); |
||||
- if (cp > cbuf && cp[-1] == LF) { |
||||
+ if (cp > buf && cp[-1] == LF) { |
||||
cp--; |
||||
- if (cp > cbuf && cp[-1] == CR) |
||||
+ if (cp > buf && cp[-1] == CR) |
||||
cp--; |
||||
- if (cp > cbuf && cp[-1] == '\\') { |
||||
+ if (cp > buf && cp[-1] == '\\') { |
||||
cp--; |
||||
/* |
||||
* line continuation requested - |
||||
@@ -1021,19 +1021,19 @@ static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, |
||||
} |
||||
} else { |
||||
/* No "get string" function defined; read character by character */ |
||||
- apr_size_t i = 0; |
||||
+ apr_size_t i = offset; |
||||
|
||||
if (bufsize < 2) { |
||||
/* too small, assume caller is crazy */ |
||||
return APR_EINVAL; |
||||
} |
||||
- buf[0] = '\0'; |
||||
+ buf[offset] = '\0'; |
||||
|
||||
while (1) { |
||||
char c; |
||||
rc = cfp->getch(&c, cfp->param); |
||||
if (rc == APR_EOF) { |
||||
- if (i > 0) |
||||
+ if (i > offset) |
||||
break; |
||||
else |
||||
return APR_EOF; |
||||
@@ -1051,11 +1051,11 @@ static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, |
||||
break; |
||||
} |
||||
} |
||||
- else if (i >= bufsize - 2) { |
||||
- return APR_ENOSPC; |
||||
- } |
||||
buf[i] = c; |
||||
++i; |
||||
+ if (i >= bufsize - 1) { |
||||
+ return APR_ENOSPC; |
||||
+ } |
||||
} |
||||
buf[i] = '\0'; |
||||
} |
||||
@@ -1089,7 +1089,7 @@ static int cfg_trim_line(char *buf) |
||||
AP_DECLARE(apr_status_t) ap_cfg_getline(char *buf, apr_size_t bufsize, |
||||
ap_configfile_t *cfp) |
||||
{ |
||||
- apr_status_t rc = ap_cfg_getline_core(buf, bufsize, cfp); |
||||
+ apr_status_t rc = ap_cfg_getline_core(buf, bufsize, 0, cfp); |
||||
if (rc == APR_SUCCESS) |
||||
cfg_trim_line(buf); |
||||
return rc; |
||||
@@ -1116,7 +1116,7 @@ AP_DECLARE(apr_status_t) ap_varbuf_cfg_getline(struct ap_varbuf *vb, |
||||
} |
||||
|
||||
for (;;) { |
||||
- rc = ap_cfg_getline_core(vb->buf + vb->strlen, vb->avail - vb->strlen, cfp); |
||||
+ rc = ap_cfg_getline_core(vb->buf, vb->avail, vb->strlen, cfp); |
||||
if (rc == APR_ENOSPC || rc == APR_SUCCESS) |
||||
vb->strlen += strlen(vb->buf + vb->strlen); |
||||
if (rc != APR_ENOSPC) |
@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
|
||||
--- a/modules/proxy/mod_proxy_fcgi.c 2015/01/14 13:22:50 1651657 |
||||
+++ b/modules/proxy/mod_proxy_fcgi.c 2015/01/14 13:24:10 1651658 |
||||
@@ -204,9 +204,19 @@ |
||||
apr_status_t rv; |
||||
apr_size_t len; |
||||
int i, numenv; |
||||
+ char *proxyfilename = r->filename; |
||||
+ |
||||
+ /* Strip balancer prefix */ |
||||
+ if (r->filename && !strncmp(r->filename, "proxy:balancer://", 17)) { |
||||
+ char *newfname = apr_pstrdup(r->pool, r->filename+17); |
||||
+ newfname = ap_strchr(newfname, '/'); |
||||
+ r->filename = newfname; |
||||
+ } |
||||
|
||||
ap_add_common_vars(r); |
||||
ap_add_cgi_vars(r); |
||||
+ |
||||
+ r->filename = proxyfilename; |
||||
|
||||
/* XXX are there any FastCGI specific env vars we need to send? */ |
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue