resync
Signed-off-by: Brian Stinson <bstinson@redhat.com>
This commit is contained in:
parent
189e1bf564
commit
a22322be54
|
@ -0,0 +1,3 @@
|
|||
Owner: luhliari
|
||||
Rationale: RHEL branding is used in this package, will be merged manually
|
||||
with Fedora as required.
|
|
@ -1,4 +1,5 @@
|
|||
SOURCES/apache-poweredby.png
|
||||
SOURCES/httpd-2.4.37.tar.bz2
|
||||
/apache-poweredby.png
|
||||
/httpd-2.4.28.tar.bz2
|
||||
/httpd-2.4.33.tar.bz2
|
||||
/httpd-2.4.35.tar.bz2
|
||||
/httpd-2.4.37.tar.bz2
|
||||
/httpd.conf.5
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
LoadModule brotli_module modules/mod_brotli.so
|
|
@ -0,0 +1 @@
|
|||
LoadModule md_module modules/mod_md.so
|
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
74
apachectl.sh
74
apachectl.sh
|
@ -1,74 +0,0 @@
|
|||
#!/usr/bin/sh
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
###
|
||||
### NOTE: This is a replacement version of the "apachectl" script with
|
||||
### some differences in behaviour to the version distributed with
|
||||
### Apache httpd. Please read the apachectl(8) man page for more
|
||||
### information.
|
||||
###
|
||||
|
||||
if [ "x$1" = "x-k" ]; then
|
||||
shift
|
||||
fi
|
||||
|
||||
ACMD="$1"
|
||||
ARGV="$@"
|
||||
SVC='httpd.service'
|
||||
HTTPD='@HTTPDBIN@'
|
||||
|
||||
if [ "x$2" != "x" ] ; then
|
||||
echo Passing arguments to httpd using apachectl is no longer supported.
|
||||
echo You can only start/stop/restart httpd using this script.
|
||||
echo To pass extra arguments to httpd, see the $SVC'(8)'
|
||||
echo man page.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case $ACMD in
|
||||
start|stop|restart|status)
|
||||
/usr/bin/systemctl --no-pager $ACMD $SVC
|
||||
ERROR=$?
|
||||
;;
|
||||
graceful)
|
||||
if /usr/bin/systemctl -q is-active $SVC; then
|
||||
/usr/bin/systemctl kill --signal=SIGUSR1 --kill-who=main $SVC
|
||||
else
|
||||
/usr/bin/systemctl start $SVC
|
||||
fi
|
||||
ERROR=$?
|
||||
;;
|
||||
graceful-stop)
|
||||
/usr/bin/systemctl kill --signal=SIGWINCH --kill-who=main $SVC
|
||||
ERROR=$?
|
||||
;;
|
||||
configtest|-t)
|
||||
$HTTPD -t
|
||||
ERROR=$?
|
||||
;;
|
||||
-v|-V)
|
||||
$HTTPD $ACMD
|
||||
ERROR=$?
|
||||
;;
|
||||
*)
|
||||
echo apachectl: The \"$ACMD\" option is not supported. 1>&2
|
||||
ERROR=2
|
||||
;;
|
||||
esac
|
||||
|
||||
exit $ERROR
|
||||
|
191
apachectl.xml
191
apachectl.xml
|
@ -1,191 +0,0 @@
|
|||
<?xml version='1.0' encoding='UTF-8' ?>
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">[
|
||||
|
||||
]>
|
||||
<!--
|
||||
Copyright 2020 Red Hat, Inc.
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<refentry>
|
||||
<refentryinfo>
|
||||
<title>apachectl</title>
|
||||
<productname>httpd</productname>
|
||||
<author><contrib>Apache man page</contrib><othername>Apache Software Foundation contributors</othername></author>
|
||||
<author><contrib>Fedora man page</contrib><surname>Dana</surname><firstname>Frank</firstname></author>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>apachectl</refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>apachectl</refname>
|
||||
<refpurpose>Server control interface for httpd</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv id='synopsis'>
|
||||
<cmdsynopsis>
|
||||
<command>apachectl</command>
|
||||
<arg choice='opt'><replaceable>command</replaceable> </arg>
|
||||
<sbr/>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<!-- body begins here -->
|
||||
<refsect1 id='description'>
|
||||
<title>Description</title>
|
||||
|
||||
<para><command>apachectl</command> is a front end to the Apache HyperText
|
||||
Transfer Protocol (HTTP) server. It is designed to help the
|
||||
administrator control the functioning of the Apache
|
||||
<command>httpd</command> daemon.</para>
|
||||
|
||||
<para>The <command>apachectl</command> script takes one-word arguments like
|
||||
<option>start</option>,
|
||||
<option>restart</option>, and
|
||||
<option>stop</option>, and translates them
|
||||
into appropriate signals to <command>httpd</command>.</para>
|
||||
|
||||
<para>The <command>apachectl</command> script returns a 0 exit value on
|
||||
success, and >0 if an error occurs.</para>
|
||||
|
||||
<refsect2 id="compatibility">
|
||||
<title>Compatibility</title>
|
||||
|
||||
<para>The version of <command>apachectl</command> used on this
|
||||
system is a replacement script intended to be mostly (but not
|
||||
completely) compatible with version provided with
|
||||
<emphasis>Apache httpd</emphasis>. This
|
||||
<command>apachectl</command> mostly acts as a wrapper around
|
||||
<command>systemctl</command> and manipulates the
|
||||
<command>systemd</command> service for <command>httpd</command>.
|
||||
The interface to the <emphasis>Apache</emphasis> version of
|
||||
<command>apachectl</command> is described at <ulink
|
||||
url="https://httpd.apache.org/docs/2.4/programs/apachectl.html"/>.</para>
|
||||
|
||||
<para>The following differences are present in the version of
|
||||
<command>apachectl</command> present on this system:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>Option arguments passed when starting
|
||||
<command>httpd</command> are not allowed. These should be
|
||||
configured in the systemd service directly (see <citerefentry><refentrytitle>httpd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>).</para></listitem>
|
||||
|
||||
<listitem><para>The <command>"fullstatus"</command> option is
|
||||
not available.</para></listitem>
|
||||
|
||||
<listitem><para>The <command>"status"</command> option does
|
||||
not use or rely on the running server's
|
||||
<emphasis>server-status</emphasis> output.</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</para>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id='options'>
|
||||
<title>Options</title>
|
||||
<variablelist remap='TP'>
|
||||
<varlistentry>
|
||||
<term><option>start</option></term>
|
||||
<listitem>
|
||||
<para>Start the Apache <command>httpd</command> daemon. Gives an error if it
|
||||
is already running. This is equivalent to <command>systemctl start httpd.service</command>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>stop</option></term>
|
||||
<listitem>
|
||||
<para>Stops the Apache <command>httpd</command> daemon. This is equivalent to
|
||||
<command>systemctl stop httpd.service</command>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>restart</option></term>
|
||||
<listitem>
|
||||
<para>Restarts the Apache <command>httpd</command> daemon. If the daemon is
|
||||
not running, it is started. This is equivalent
|
||||
to <command>systemctl restart httpd.service</command>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>status</option></term>
|
||||
<listitem>
|
||||
<para>Displays a brief status report. This is equivalent to <command>systemctl status httpd.service.</command></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>graceful</option></term>
|
||||
<listitem>
|
||||
<para>Gracefully restarts the Apache <command>httpd</command> daemon. If the
|
||||
daemon is not running, it is started. This differs from a normal
|
||||
restart in that currently open connections are not aborted. A side
|
||||
effect is that old log files will not be closed immediately. This
|
||||
means that if used in a log rotation script, a substantial delay may
|
||||
be necessary to ensure that the old log files are closed before
|
||||
processing them. This is equivalent to
|
||||
<command>systemctl kill --signal=SIGUSR1 --kill-who=main httpd.service</command>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>graceful-stop</option></term>
|
||||
<listitem>
|
||||
<para>Gracefully stops the Apache <command>httpd</command> 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
|
||||
<command>systemctl kill --signal=SIGWINCH --kill-who=main httpd.service</command>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>configtest</option></term>
|
||||
<listitem>
|
||||
<para>Run a configuration file syntax test. It parses the configuration
|
||||
files and either reports <literal>Syntax OK</literal>
|
||||
or detailed information about the particular syntax error. This is
|
||||
equivalent to <command>httpd -t</command>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id='bugs'>
|
||||
<title>Bugs</title>
|
||||
<para>Please report bugs by filing an issue in Bugzilla via <ulink url='https://bugzilla.redhat.com/'/>.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See also</title>
|
||||
|
||||
<para>
|
||||
<citerefentry><refentrytitle>httpd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>httpd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>httpd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
11
gating.yaml
11
gating.yaml
|
@ -1,11 +0,0 @@
|
|||
--- !Policy
|
||||
product_versions:
|
||||
- rhel-9
|
||||
decision_context: osci_compose_gate
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}
|
||||
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier2.functional}
|
||||
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier3.functional}
|
||||
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.acceptance-tier.functional}
|
||||
- !PassingTestCaseRule {test_case_name: osci.brew-build./plans/tier1-internal.functional}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
diff --git a/modules/dav/main/util.c b/modules/dav/main/util.c
|
||||
index 1ae5914027c..3f7822fc931 100644
|
||||
--- a/modules/dav/main/util.c
|
||||
+++ b/modules/dav/main/util.c
|
||||
@@ -801,8 +801,14 @@ static dav_error * dav_process_if_header(request_rec *r, dav_if_header **p_ih)
|
||||
"for the same state.");
|
||||
}
|
||||
condition = DAV_IF_COND_NOT;
|
||||
+ list += 2;
|
||||
+ }
|
||||
+ else {
|
||||
+ return dav_new_error(r->pool, HTTP_BAD_REQUEST,
|
||||
+ DAV_ERR_IF_UNK_CHAR, 0,
|
||||
+ "Invalid \"If:\" header: "
|
||||
+ "Unexpected character in List");
|
||||
}
|
||||
- list += 2;
|
||||
break;
|
||||
|
||||
case ' ':
|
|
@ -0,0 +1,23 @@
|
|||
From 5efc9507c487c37dfe2a279a4a0335cad701cd5f Mon Sep 17 00:00:00 2001
|
||||
From: Eric Covener <covener@apache.org>
|
||||
Date: Tue, 10 Jan 2023 13:19:07 +0000
|
||||
Subject: [PATCH] cleanup on error
|
||||
|
||||
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1906540 13f79535-47bb-0310-9956-ffa450edef68
|
||||
---
|
||||
modules/proxy/mod_proxy_ajp.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
|
||||
index 9cd7adbcbbf..07f37392d88 100644
|
||||
--- a/modules/proxy/mod_proxy_ajp.c
|
||||
+++ b/modules/proxy/mod_proxy_ajp.c
|
||||
@@ -255,6 +255,8 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10396)
|
||||
"%s Transfer-Encoding is not supported",
|
||||
tenc);
|
||||
+ /* We had a failure: Close connection to backend */
|
||||
+ conn->close = 1;
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
} else {
|
|
@ -0,0 +1,129 @@
|
|||
From 8b6d55f6a047acf62675e32606b037f5eea8ccc7 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Covener <covener@apache.org>
|
||||
Date: Tue, 10 Jan 2023 13:20:09 +0000
|
||||
Subject: [PATCH] Merge r1906539 from trunk:
|
||||
|
||||
fail on bad header
|
||||
|
||||
Submitted By: covener
|
||||
Reviewed By: covener, rpluem, gbechis
|
||||
|
||||
|
||||
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1906541 13f79535-47bb-0310-9956-ffa450edef68
|
||||
---
|
||||
modules/proxy/mod_proxy_http.c | 46 ++++++++++++++++++++--------------
|
||||
server/protocol.c | 2 ++
|
||||
2 files changed, 29 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
|
||||
index d74ae054ac9..ec4e7fb06b5 100644
|
||||
--- a/modules/proxy/mod_proxy_http.c
|
||||
+++ b/modules/proxy/mod_proxy_http.c
|
||||
@@ -788,7 +788,7 @@ static void process_proxy_header(request_rec *r, proxy_dir_conf *c,
|
||||
* any sense at all, since we depend on buffer still containing
|
||||
* what was read by ap_getline() upon return.
|
||||
*/
|
||||
-static void ap_proxy_read_headers(request_rec *r, request_rec *rr,
|
||||
+static apr_status_t ap_proxy_read_headers(request_rec *r, request_rec *rr,
|
||||
char *buffer, int size,
|
||||
conn_rec *c, int *pread_len)
|
||||
{
|
||||
@@ -820,19 +820,26 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr,
|
||||
rc = ap_proxygetline(tmp_bb, buffer, size, rr,
|
||||
AP_GETLINE_FOLD | AP_GETLINE_NOSPC_EOL, &len);
|
||||
|
||||
- if (len <= 0)
|
||||
- break;
|
||||
|
||||
- if (APR_STATUS_IS_ENOSPC(rc)) {
|
||||
- /* The header could not fit in the provided buffer, warn.
|
||||
- * XXX: falls through with the truncated header, 5xx instead?
|
||||
- */
|
||||
- int trunc = (len > 128 ? 128 : len) / 2;
|
||||
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10124)
|
||||
- "header size is over the limit allowed by "
|
||||
- "ResponseFieldSize (%d bytes). "
|
||||
- "Bad response header: '%.*s[...]%s'",
|
||||
- size, trunc, buffer, buffer + len - trunc);
|
||||
+ if (rc != APR_SUCCESS) {
|
||||
+ if (APR_STATUS_IS_ENOSPC(rc)) {
|
||||
+ int trunc = (len > 128 ? 128 : len) / 2;
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10124)
|
||||
+ "header size is over the limit allowed by "
|
||||
+ "ResponseFieldSize (%d bytes). "
|
||||
+ "Bad response header: '%.*s[...]%s'",
|
||||
+ size, trunc, buffer, buffer + len - trunc);
|
||||
+ }
|
||||
+ else {
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, rc, r, APLOGNO(10404)
|
||||
+ "Error reading headers from backend");
|
||||
+ }
|
||||
+ r->headers_out = NULL;
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ if (len <= 0) {
|
||||
+ break;
|
||||
}
|
||||
else {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "%s", buffer);
|
||||
@@ -855,7 +862,7 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr,
|
||||
if (psc->badopt == bad_error) {
|
||||
/* Nope, it wasn't even an extra HTTP header. Give up. */
|
||||
r->headers_out = NULL;
|
||||
- return;
|
||||
+ return APR_EINVAL;
|
||||
}
|
||||
else if (psc->badopt == bad_body) {
|
||||
/* if we've already started loading headers_out, then
|
||||
@@ -869,13 +876,13 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr,
|
||||
"in headers returned by %s (%s)",
|
||||
r->uri, r->method);
|
||||
*pread_len = len;
|
||||
- return;
|
||||
+ return APR_SUCCESS;
|
||||
}
|
||||
else {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01099)
|
||||
"No HTTP headers returned by %s (%s)",
|
||||
r->uri, r->method);
|
||||
- return;
|
||||
+ return APR_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -905,6 +912,7 @@ static void ap_proxy_read_headers(request_rec *r, request_rec *rr,
|
||||
process_proxy_header(r, dconf, buffer, value);
|
||||
saw_headers = 1;
|
||||
}
|
||||
+ return APR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1218,10 +1226,10 @@ int ap_proxy_http_process_response(proxy_http_req_t *req)
|
||||
"Set-Cookie", NULL);
|
||||
|
||||
/* shove the headers direct into r->headers_out */
|
||||
- ap_proxy_read_headers(r, backend->r, buffer, response_field_size,
|
||||
- origin, &pread_len);
|
||||
+ rc = ap_proxy_read_headers(r, backend->r, buffer, response_field_size,
|
||||
+ origin, &pread_len);
|
||||
|
||||
- if (r->headers_out == NULL) {
|
||||
+ if (rc != APR_SUCCESS || r->headers_out == NULL) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01106)
|
||||
"bad HTTP/%d.%d header returned by %s (%s)",
|
||||
major, minor, r->uri, r->method);
|
||||
diff --git a/server/protocol.c b/server/protocol.c
|
||||
index 7adc7f75c10..6f9540ad1de 100644
|
||||
--- a/server/protocol.c
|
||||
+++ b/server/protocol.c
|
||||
@@ -508,6 +508,8 @@ AP_DECLARE(apr_status_t) ap_rgetline_core(char **s, apr_size_t n,
|
||||
/* PR#43039: We shouldn't accept NULL bytes within the line */
|
||||
bytes_handled = strlen(*s);
|
||||
if (bytes_handled < *read) {
|
||||
+ ap_log_data(APLOG_MARK, APLOG_DEBUG, ap_server_conf,
|
||||
+ "NULL bytes in header", *s, *read, 0);
|
||||
*read = bytes_handled;
|
||||
if (rv == APR_SUCCESS) {
|
||||
rv = APR_EINVAL;
|
|
@ -0,0 +1,586 @@
|
|||
diff --git a/docs/manual/mod/mod_rewrite.html.en b/docs/manual/mod/mod_rewrite.html.en
|
||||
index 815ec72..2b8ed35 100644
|
||||
--- a/docs/manual/mod/mod_rewrite.html.en
|
||||
+++ b/docs/manual/mod/mod_rewrite.html.en
|
||||
@@ -1265,7 +1265,17 @@ cannot use <code>$N</code> in the substitution string!
|
||||
<td>B</td>
|
||||
<td>Escape non-alphanumeric characters in backreferences <em>before</em>
|
||||
applying the transformation. <em><a href="../rewrite/flags.html#flag_b">details ...</a></em></td>
|
||||
- </tr>
|
||||
+ </tr>
|
||||
+<tr class="odd">
|
||||
+ <td>BCTLS</td>
|
||||
+ <td>Like [B], but only escape control characters and spaces.
|
||||
+ <em><a href="../rewrite/flags.html#flag_bctls">details ...</a></em></td>
|
||||
+</tr>
|
||||
+ <tr>
|
||||
+ <td>BNE</td>
|
||||
+ <td>Characters of [B] or [BCTLS] which should <strong>not</strong> be escaped.
|
||||
+ <em><a href="../rewrite/flags.html#flag_bne">details ...</a></em></td>
|
||||
+ </tr>
|
||||
<tr class="odd">
|
||||
<td>backrefnoplus|BNP</td>
|
||||
<td>If backreferences are being escaped, spaces should be escaped to
|
||||
diff --git a/docs/manual/rewrite/flags.html.en b/docs/manual/rewrite/flags.html.en
|
||||
index 80d0759..734809a 100644
|
||||
--- a/docs/manual/rewrite/flags.html.en
|
||||
+++ b/docs/manual/rewrite/flags.html.en
|
||||
@@ -85,10 +85,6 @@ of how you might use them.</p>
|
||||
<h2><a name="flag_b" id="flag_b">B (escape backreferences)</a></h2>
|
||||
<p>The [B] flag instructs <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code> to escape non-alphanumeric
|
||||
characters before applying the transformation.</p>
|
||||
-<p>In 2.4.26 and later, you can limit the escaping to specific characters
|
||||
-in backreferences by listing them: <code>[B=#?;]</code>. Note: The space
|
||||
-character can be used in the list of characters to escape, but it cannot be
|
||||
-the last character in the list.</p>
|
||||
|
||||
<p><code>mod_rewrite</code> has to unescape URLs before mapping them,
|
||||
so backreferences are unescaped at the time they are applied.
|
||||
@@ -120,6 +116,20 @@ when the backend may break if presented with an unescaped URL.</p>
|
||||
|
||||
<p>An alternative to this flag is using a <code class="directive"><a href="../mod/mod_rewrite.html#rewritecond">RewriteCond</a></code> to capture against %{THE_REQUEST} which will capture
|
||||
strings in the encoded form.</p>
|
||||
+
|
||||
+<p>In 2.4.26 and later, you can limit the escaping to specific characters
|
||||
+in backreferences by listing them: <code>[B=#?;]</code>. Note: The space
|
||||
+character can be used in the list of characters to escape, but you must quote
|
||||
+the entire third argument of <code class="directive"><a href="../mod/mod_rewrite.html#rewriterule">RewriteRule</a></code>
|
||||
+and the space must not be the last character in the list.</p>
|
||||
+
|
||||
+<pre class="prettyprint lang-config"># Escape spaces and question marks. The quotes around the final argument
|
||||
+# are required when a space is included.
|
||||
+RewriteRule "^search/(.*)$" "/search.php?term=$1" "[B= ?]"</pre>
|
||||
+
|
||||
+<p>To limit the characters escaped this way, see <a href="#flag_bne">#flag_bne</a>
|
||||
+and <a href="#flag_bctls">#flag_bctls</a></p>
|
||||
+
|
||||
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
<div class="section">
|
||||
<h2><a name="flag_bnp" id="flag_bnp">BNP|backrefnoplus (don't escape space to +)</a></h2>
|
||||
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
|
||||
index 38dbb24..b71c67c 100644
|
||||
--- a/modules/mappers/mod_rewrite.c
|
||||
+++ b/modules/mappers/mod_rewrite.c
|
||||
@@ -101,6 +101,8 @@
|
||||
#include "mod_rewrite.h"
|
||||
#include "ap_expr.h"
|
||||
|
||||
+#include "test_char.h"
|
||||
+
|
||||
static ap_dbd_t *(*dbd_acquire)(request_rec*) = NULL;
|
||||
static void (*dbd_prepare)(server_rec*, const char*, const char*) = NULL;
|
||||
static const char* really_last_key = "rewrite_really_last";
|
||||
@@ -168,6 +170,8 @@ static const char* really_last_key = "rewrite_really_last";
|
||||
#define RULEFLAG_END (1<<17)
|
||||
#define RULEFLAG_ESCAPENOPLUS (1<<18)
|
||||
#define RULEFLAG_QSLAST (1<<19)
|
||||
+#define RULEFLAG_QSNONE (1<<20) /* programattic only */
|
||||
+#define RULEFLAG_ESCAPECTLS (1<<21)
|
||||
|
||||
/* return code of the rewrite rule
|
||||
* the result may be escaped - or not
|
||||
@@ -321,7 +325,8 @@ typedef struct {
|
||||
data_item *cookie; /* added cookies */
|
||||
int skip; /* number of next rules to skip */
|
||||
int maxrounds; /* limit on number of loops with N flag */
|
||||
- char *escapes; /* specific backref escapes */
|
||||
+ const char *escapes; /* specific backref escapes */
|
||||
+ const char *noescapes; /* specific backref chars not to escape */
|
||||
} rewriterule_entry;
|
||||
|
||||
typedef struct {
|
||||
@@ -422,7 +427,9 @@ static const char *rewritemap_mutex_type = "rewrite-map";
|
||||
/* Optional functions imported from mod_ssl when loaded: */
|
||||
static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *rewrite_ssl_lookup = NULL;
|
||||
static APR_OPTIONAL_FN_TYPE(ssl_is_https) *rewrite_is_https = NULL;
|
||||
-static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int noplus);
|
||||
+static char *escape_backref(apr_pool_t *p, const char *path,
|
||||
+ const char *escapeme, const char *noescapeme,
|
||||
+ int flags);
|
||||
|
||||
/*
|
||||
* +-------------------------------------------------------+
|
||||
@@ -645,18 +652,26 @@ static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix,
|
||||
return where;
|
||||
}
|
||||
|
||||
+
|
||||
/*
|
||||
* Escapes a backreference in a similar way as php's urlencode does.
|
||||
* Based on ap_os_escape_path in server/util.c
|
||||
*/
|
||||
-static char *escape_backref(apr_pool_t *p, const char *path, const char *escapeme, int noplus) {
|
||||
- char *copy = apr_palloc(p, 3 * strlen(path) + 3);
|
||||
+static char *escape_backref(apr_pool_t *p, const char *path,
|
||||
+ const char *escapeme, const char *noescapeme,
|
||||
+ int flags)
|
||||
+{
|
||||
+ char *copy = apr_palloc(p, 3 * strlen(path) + 1);
|
||||
const unsigned char *s = (const unsigned char *)path;
|
||||
unsigned char *d = (unsigned char *)copy;
|
||||
- unsigned c;
|
||||
+ int noplus = (flags & RULEFLAG_ESCAPENOPLUS) != 0;
|
||||
+ int ctls = (flags & RULEFLAG_ESCAPECTLS) != 0;
|
||||
+ unsigned char c;
|
||||
|
||||
while ((c = *s)) {
|
||||
- if (!escapeme) {
|
||||
+ if (((ctls ? !TEST_CHAR(c, T_VCHAR_OBSTEXT) : !escapeme)
|
||||
+ || (escapeme && ap_strchr_c(escapeme, c)))
|
||||
+ && (!noescapeme || !ap_strchr_c(noescapeme, c))) {
|
||||
if (apr_isalnum(c) || c == '_') {
|
||||
*d++ = c;
|
||||
}
|
||||
@@ -667,23 +682,8 @@ static char *escape_backref(apr_pool_t *p, const char *path, const char *escapem
|
||||
d = c2x(c, '%', d);
|
||||
}
|
||||
}
|
||||
- else {
|
||||
- const char *esc = escapeme;
|
||||
- while (*esc) {
|
||||
- if (c == *esc) {
|
||||
- if (c == ' ' && !noplus) {
|
||||
- *d++ = '+';
|
||||
- }
|
||||
- else {
|
||||
- d = c2x(c, '%', d);
|
||||
- }
|
||||
- break;
|
||||
- }
|
||||
- ++esc;
|
||||
- }
|
||||
- if (!*esc) {
|
||||
- *d++ = c;
|
||||
- }
|
||||
+ else {
|
||||
+ *d++ = c;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
@@ -761,15 +761,24 @@ static char *escape_absolute_uri(apr_pool_t *p, char *uri, unsigned scheme)
|
||||
ap_escape_uri(p, cp), NULL);
|
||||
}
|
||||
|
||||
+
|
||||
/*
|
||||
* split out a QUERY_STRING part from
|
||||
* the current URI string
|
||||
*/
|
||||
-static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard,
|
||||
- int qslast)
|
||||
+static void splitout_queryargs(request_rec *r, int flags)
|
||||
{
|
||||
char *q;
|
||||
int split;
|
||||
+ int qsappend = flags & RULEFLAG_QSAPPEND;
|
||||
+ int qsdiscard = flags & RULEFLAG_QSDISCARD;
|
||||
+ int qslast = flags & RULEFLAG_QSLAST;
|
||||
+
|
||||
+ if (flags & RULEFLAG_QSNONE) {
|
||||
+ rewritelog((r, 2, NULL, "discarding query string, no parse from substitution"));
|
||||
+ r->args = NULL;
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
/* don't touch, unless it's a scheme for which a query string makes sense.
|
||||
* See RFC 1738 and RFC 2368.
|
||||
@@ -794,7 +803,7 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard,
|
||||
olduri = apr_pstrdup(r->pool, r->filename);
|
||||
*q++ = '\0';
|
||||
if (qsappend) {
|
||||
- if (*q) {
|
||||
+ if (*q) {
|
||||
r->args = apr_pstrcat(r->pool, q, "&" , r->args, NULL);
|
||||
}
|
||||
}
|
||||
@@ -802,9 +811,9 @@ static void splitout_queryargs(request_rec *r, int qsappend, int qsdiscard,
|
||||
r->args = apr_pstrdup(r->pool, q);
|
||||
}
|
||||
|
||||
- if (r->args) {
|
||||
+ if (r->args) {
|
||||
len = strlen(r->args);
|
||||
-
|
||||
+
|
||||
if (!len) {
|
||||
r->args = NULL;
|
||||
}
|
||||
@@ -2436,7 +2445,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
|
||||
/* escape the backreference */
|
||||
char *tmp2, *tmp;
|
||||
tmp = apr_pstrmemdup(pool, bri->source + bri->regmatch[n].rm_so, span);
|
||||
- tmp2 = escape_backref(pool, tmp, entry->escapes, entry->flags & RULEFLAG_ESCAPENOPLUS);
|
||||
+ tmp2 = escape_backref(pool, tmp, entry->escapes, entry->noescapes,
|
||||
+ entry->flags);
|
||||
rewritelog((ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'",
|
||||
tmp, tmp2));
|
||||
|
||||
@@ -2733,7 +2743,7 @@ static apr_status_t rewritelock_remove(void *data)
|
||||
* XXX: what an inclined parser. Seems we have to leave it so
|
||||
* for backwards compat. *sigh*
|
||||
*/
|
||||
-static int parseargline(char *str, char **a1, char **a2, char **a3)
|
||||
+static int parseargline(char *str, char **a1, char **a2, char **a2_end, char **a3)
|
||||
{
|
||||
char quote;
|
||||
|
||||
@@ -2784,8 +2794,10 @@ static int parseargline(char *str, char **a1, char **a2, char **a3)
|
||||
|
||||
if (!*str) {
|
||||
*a3 = NULL; /* 3rd argument is optional */
|
||||
+ *a2_end = str;
|
||||
return 0;
|
||||
}
|
||||
+ *a2_end = str;
|
||||
*str++ = '\0';
|
||||
|
||||
while (apr_isspace(*str)) {
|
||||
@@ -3323,7 +3335,7 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf,
|
||||
rewrite_server_conf *sconf;
|
||||
rewritecond_entry *newcond;
|
||||
ap_regex_t *regexp;
|
||||
- char *a1 = NULL, *a2 = NULL, *a3 = NULL;
|
||||
+ char *a1 = NULL, *a2 = NULL, *a2_end, *a3 = NULL;
|
||||
const char *err;
|
||||
|
||||
sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
|
||||
@@ -3341,7 +3353,7 @@ static const char *cmd_rewritecond(cmd_parms *cmd, void *in_dconf,
|
||||
* of the argument line. So we can use a1 .. a3 without
|
||||
* copying them again.
|
||||
*/
|
||||
- if (parseargline(str, &a1, &a2, &a3)) {
|
||||
+ if (parseargline(str, &a1, &a2, &a2_end, &a3)) {
|
||||
return apr_pstrcat(cmd->pool, "RewriteCond: bad argument line '", str,
|
||||
"'", NULL);
|
||||
}
|
||||
@@ -3500,13 +3512,24 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg,
|
||||
case 'B':
|
||||
if (!*key || !strcasecmp(key, "ackrefescaping")) {
|
||||
cfg->flags |= RULEFLAG_ESCAPEBACKREF;
|
||||
- if (val && *val) {
|
||||
+ if (val && *val) {
|
||||
cfg->escapes = val;
|
||||
}
|
||||
}
|
||||
+ else if (!strcasecmp(key, "NE")) {
|
||||
+ if (val && *val) {
|
||||
+ cfg->noescapes = val;
|
||||
+ }
|
||||
+ else {
|
||||
+ return "flag 'BNE' wants a list of characters (i.e. [BNE=...])";
|
||||
+ }
|
||||
+ }
|
||||
else if (!strcasecmp(key, "NP") || !strcasecmp(key, "ackrefernoplus")) {
|
||||
cfg->flags |= RULEFLAG_ESCAPENOPLUS;
|
||||
}
|
||||
+ else if (!strcasecmp(key, "CTLS")) {
|
||||
+ cfg->flags |= RULEFLAG_ESCAPECTLS|RULEFLAG_ESCAPEBACKREF;
|
||||
+ }
|
||||
else {
|
||||
++error;
|
||||
}
|
||||
@@ -3749,7 +3772,7 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
|
||||
rewrite_server_conf *sconf;
|
||||
rewriterule_entry *newrule;
|
||||
ap_regex_t *regexp;
|
||||
- char *a1 = NULL, *a2 = NULL, *a3 = NULL;
|
||||
+ char *a1 = NULL, *a2 = NULL, *a2_end, *a3 = NULL;
|
||||
const char *err;
|
||||
|
||||
sconf = ap_get_module_config(cmd->server->module_config, &rewrite_module);
|
||||
@@ -3763,12 +3786,11 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
|
||||
}
|
||||
|
||||
/* parse the argument line ourself */
|
||||
- if (parseargline(str, &a1, &a2, &a3)) {
|
||||
+ if (parseargline(str, &a1, &a2, &a2_end, &a3)) {
|
||||
return apr_pstrcat(cmd->pool, "RewriteRule: bad argument line '", str,
|
||||
"'", NULL);
|
||||
}
|
||||
|
||||
- /* arg3: optional flags field */
|
||||
newrule->forced_mimetype = NULL;
|
||||
newrule->forced_handler = NULL;
|
||||
newrule->forced_responsecode = HTTP_MOVED_TEMPORARILY;
|
||||
@@ -3777,6 +3799,9 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
|
||||
newrule->cookie = NULL;
|
||||
newrule->skip = 0;
|
||||
newrule->maxrounds = REWRITE_MAX_ROUNDS;
|
||||
+ newrule->escapes = newrule->noescapes = NULL;
|
||||
+
|
||||
+ /* arg3: optional flags field */
|
||||
if (a3 != NULL) {
|
||||
if ((err = cmd_parseflagfield(cmd->pool, newrule, a3,
|
||||
cmd_rewriterule_setflag)) != NULL) {
|
||||
@@ -3810,6 +3835,17 @@ static const char *cmd_rewriterule(cmd_parms *cmd, void *in_dconf,
|
||||
newrule->flags |= RULEFLAG_NOSUB;
|
||||
}
|
||||
|
||||
+ if (*(a2_end-1) == '?') {
|
||||
+ /* a literal ? at the end of the unsubstituted rewrite rule */
|
||||
+ newrule->flags |= RULEFLAG_QSNONE;
|
||||
+ *(a2_end-1) = '\0'; /* trailing ? has done its job */
|
||||
+ }
|
||||
+ else if (newrule->flags & RULEFLAG_QSDISCARD) {
|
||||
+ if (NULL == ap_strchr(newrule->output, '?')) {
|
||||
+ newrule->flags |= RULEFLAG_QSNONE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* now, if the server or per-dir config holds an
|
||||
* array of RewriteCond entries, we take it for us
|
||||
* and clear the array
|
||||
@@ -4215,9 +4251,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
|
||||
r->path_info = NULL;
|
||||
}
|
||||
|
||||
- splitout_queryargs(r, p->flags & RULEFLAG_QSAPPEND,
|
||||
- p->flags & RULEFLAG_QSDISCARD,
|
||||
- p->flags & RULEFLAG_QSLAST);
|
||||
+ splitout_queryargs(r, p->flags);
|
||||
|
||||
/* Add the previously stripped per-directory location prefix, unless
|
||||
* (1) it's an absolute URL path and
|
||||
@@ -4696,8 +4730,25 @@ static int hook_uri2file(request_rec *r)
|
||||
}
|
||||
|
||||
if (rulestatus) {
|
||||
- unsigned skip;
|
||||
- apr_size_t flen;
|
||||
+ unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
|
||||
+ apr_size_t flen = r->filename ? strlen(r->filename) : 0;
|
||||
+ int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0);
|
||||
+ int will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);
|
||||
+
|
||||
+ if (r->args
|
||||
+ && !will_escape
|
||||
+ && *(ap_scan_vchar_obstext(r->args))) {
|
||||
+ /*
|
||||
+ * We have a raw control character or a ' ' in r->args.
|
||||
+ * Correct encoding was missed.
|
||||
+ * Correct encoding was missed and we're not going to escape
|
||||
+ * it before returning.
|
||||
+ */
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10410)
|
||||
+ "Rewritten query string contains control "
|
||||
+ "characters or spaces");
|
||||
+ return HTTP_FORBIDDEN;
|
||||
+ }
|
||||
|
||||
if (ACTION_STATUS == rulestatus) {
|
||||
int n = r->status;
|
||||
@@ -4706,8 +4757,7 @@ static int hook_uri2file(request_rec *r)
|
||||
return n;
|
||||
}
|
||||
|
||||
- flen = r->filename ? strlen(r->filename) : 0;
|
||||
- if (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0) {
|
||||
+ if (to_proxyreq) {
|
||||
/* it should be go on as an internal proxy request */
|
||||
|
||||
/* check if the proxy module is enabled, so
|
||||
@@ -4749,7 +4799,7 @@ static int hook_uri2file(request_rec *r)
|
||||
r->filename));
|
||||
return OK;
|
||||
}
|
||||
- else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) {
|
||||
+ else if (skip_absolute > 0) {
|
||||
int n;
|
||||
|
||||
/* it was finally rewritten to a remote URL */
|
||||
@@ -4757,7 +4807,7 @@ static int hook_uri2file(request_rec *r)
|
||||
if (rulestatus != ACTION_NOESCAPE) {
|
||||
rewritelog((r, 1, NULL, "escaping %s for redirect",
|
||||
r->filename));
|
||||
- r->filename = escape_absolute_uri(r->pool, r->filename, skip);
|
||||
+ r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute);
|
||||
}
|
||||
|
||||
/* append the QUERY_STRING part */
|
||||
@@ -4981,7 +5031,26 @@ static int hook_fixup(request_rec *r)
|
||||
*/
|
||||
rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory);
|
||||
if (rulestatus) {
|
||||
- unsigned skip;
|
||||
+ unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
|
||||
+ int to_proxyreq = 0;
|
||||
+ int will_escape = 0;
|
||||
+
|
||||
+ l = strlen(r->filename);
|
||||
+ to_proxyreq = l > 6 && strncmp(r->filename, "proxy:", 6) == 0;
|
||||
+ will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);
|
||||
+
|
||||
+ if (r->args
|
||||
+ && !will_escape
|
||||
+ && *(ap_scan_vchar_obstext(r->args))) {
|
||||
+ /*
|
||||
+ * We have a raw control character or a ' ' in r->args.
|
||||
+ * Correct encoding was missed.
|
||||
+ */
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10411)
|
||||
+ "Rewritten query string contains control "
|
||||
+ "characters or spaces");
|
||||
+ return HTTP_FORBIDDEN;
|
||||
+ }
|
||||
|
||||
if (ACTION_STATUS == rulestatus) {
|
||||
int n = r->status;
|
||||
@@ -4990,8 +5059,7 @@ static int hook_fixup(request_rec *r)
|
||||
return n;
|
||||
}
|
||||
|
||||
- l = strlen(r->filename);
|
||||
- if (l > 6 && strncmp(r->filename, "proxy:", 6) == 0) {
|
||||
+ if (to_proxyreq) {
|
||||
/* it should go on as an internal proxy request */
|
||||
|
||||
/* make sure the QUERY_STRING and
|
||||
@@ -5015,7 +5083,7 @@ static int hook_fixup(request_rec *r)
|
||||
"%s [OK]", r->filename));
|
||||
return OK;
|
||||
}
|
||||
- else if ((skip = is_absolute_uri(r->filename, NULL)) > 0) {
|
||||
+ else if (skip_absolute > 0) {
|
||||
/* it was finally rewritten to a remote URL */
|
||||
|
||||
/* because we are in a per-dir context
|
||||
@@ -5024,7 +5092,7 @@ static int hook_fixup(request_rec *r)
|
||||
*/
|
||||
if (dconf->baseurl != NULL) {
|
||||
/* skip 'scheme://' */
|
||||
- cp = r->filename + skip;
|
||||
+ cp = r->filename + skip_absolute;
|
||||
|
||||
if ((cp = ap_strchr(cp, '/')) != NULL && *(++cp)) {
|
||||
rewritelog((r, 2, dconf->directory,
|
||||
@@ -5069,7 +5137,7 @@ static int hook_fixup(request_rec *r)
|
||||
if (rulestatus != ACTION_NOESCAPE) {
|
||||
rewritelog((r, 1, dconf->directory, "escaping %s for redirect",
|
||||
r->filename));
|
||||
- r->filename = escape_absolute_uri(r->pool, r->filename, skip);
|
||||
+ r->filename = escape_absolute_uri(r->pool, r->filename, skip_absolute);
|
||||
}
|
||||
|
||||
/* append the QUERY_STRING part */
|
||||
diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
|
||||
index cbb0872..873ccf1 100644
|
||||
--- a/modules/proxy/mod_proxy_ajp.c
|
||||
+++ b/modules/proxy/mod_proxy_ajp.c
|
||||
@@ -69,6 +69,16 @@ static int proxy_ajp_canon(request_rec *r, char *url)
|
||||
path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
|
||||
r->proxyreq);
|
||||
search = r->args;
|
||||
+ if (search && *(ap_scan_vchar_obstext(search))) {
|
||||
+ /*
|
||||
+ * We have a raw control character or a ' ' in r->args.
|
||||
+ * Correct encoding was missed.
|
||||
+ */
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10406)
|
||||
+ "To be forwarded query string contains control "
|
||||
+ "characters or spaces");
|
||||
+ return HTTP_FORBIDDEN;
|
||||
+ }
|
||||
}
|
||||
if (path == NULL)
|
||||
return HTTP_BAD_REQUEST;
|
||||
diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c
|
||||
index 3a28038..c599e1a 100644
|
||||
--- a/modules/proxy/mod_proxy_balancer.c
|
||||
+++ b/modules/proxy/mod_proxy_balancer.c
|
||||
@@ -106,6 +106,16 @@ static int proxy_balancer_canon(request_rec *r, char *url)
|
||||
path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
|
||||
r->proxyreq);
|
||||
search = r->args;
|
||||
+ if (search && *(ap_scan_vchar_obstext(search))) {
|
||||
+ /*
|
||||
+ * We have a raw control character or a ' ' in r->args.
|
||||
+ * Correct encoding was missed.
|
||||
+ */
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10407)
|
||||
+ "To be forwarded query string contains control "
|
||||
+ "characters or spaces");
|
||||
+ return HTTP_FORBIDDEN;
|
||||
+ }
|
||||
}
|
||||
if (path == NULL)
|
||||
return HTTP_BAD_REQUEST;
|
||||
diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c
|
||||
index 7573638..fe7b322 100644
|
||||
--- a/modules/proxy/mod_proxy_http.c
|
||||
+++ b/modules/proxy/mod_proxy_http.c
|
||||
@@ -90,6 +90,16 @@ static int proxy_http_canon(request_rec *r, char *url)
|
||||
path = ap_proxy_canonenc(r->pool, url, strlen(url),
|
||||
enc_path, 0, r->proxyreq);
|
||||
search = r->args;
|
||||
+ if (search && *(ap_scan_vchar_obstext(search))) {
|
||||
+ /*
|
||||
+ * We have a raw control character or a ' ' in r->args.
|
||||
+ * Correct encoding was missed.
|
||||
+ */
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10408)
|
||||
+ "To be forwarded query string contains control "
|
||||
+ "characters or spaces");
|
||||
+ return HTTP_FORBIDDEN;
|
||||
+ }
|
||||
}
|
||||
break;
|
||||
case PROXYREQ_PROXY:
|
||||
diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c
|
||||
index e005a94..f5e27d9 100644
|
||||
--- a/modules/proxy/mod_proxy_wstunnel.c
|
||||
+++ b/modules/proxy/mod_proxy_wstunnel.c
|
||||
@@ -77,6 +77,16 @@ static int proxy_wstunnel_canon(request_rec *r, char *url)
|
||||
path = ap_proxy_canonenc(r->pool, url, strlen(url), enc_path, 0,
|
||||
r->proxyreq);
|
||||
search = r->args;
|
||||
+ if (search && *(ap_scan_vchar_obstext(search))) {
|
||||
+ /*
|
||||
+ * We have a raw control character or a ' ' in r->args.
|
||||
+ * Correct encoding was missed.
|
||||
+ */
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10409)
|
||||
+ "To be forwarded query string contains control "
|
||||
+ "characters or spaces");
|
||||
+ return HTTP_FORBIDDEN;
|
||||
+ }
|
||||
}
|
||||
if (path == NULL)
|
||||
return HTTP_BAD_REQUEST;
|
||||
diff --git a/server/gen_test_char.c b/server/gen_test_char.c
|
||||
index 48ae6f4..6a153a3 100644
|
||||
--- a/server/gen_test_char.c
|
||||
+++ b/server/gen_test_char.c
|
||||
@@ -169,5 +169,15 @@ int main(int argc, char *argv[])
|
||||
|
||||
printf("\n};\n");
|
||||
|
||||
+
|
||||
+ printf(
|
||||
+ "/* we assume the folks using this ensure 0 <= c < 256... which means\n"
|
||||
+ " * you need a cast to (unsigned char) first, you can't just plug a\n"
|
||||
+ " * char in here and get it to work, because if char is signed then it\n"
|
||||
+ " * will first be sign extended.\n"
|
||||
+ " */\n"
|
||||
+ "#define TEST_CHAR(c, f) (test_char_table[(unsigned char)(c)] & (f))\n"
|
||||
+ );
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
diff --git a/server/util.c b/server/util.c
|
||||
index 45051b7..9d897d4 100644
|
||||
--- a/server/util.c
|
||||
+++ b/server/util.c
|
||||
@@ -74,13 +74,6 @@
|
||||
*/
|
||||
#include "test_char.h"
|
||||
|
||||
-/* we assume the folks using this ensure 0 <= c < 256... which means
|
||||
- * you need a cast to (unsigned char) first, you can't just plug a
|
||||
- * char in here and get it to work, because if char is signed then it
|
||||
- * will first be sign extended.
|
||||
- */
|
||||
-#define TEST_CHAR(c, f) (test_char_table[(unsigned char)(c)] & (f))
|
||||
-
|
||||
/* Win32/NetWare/OS2 need to check for both forward and back slashes
|
||||
* in ap_getparents() and ap_escape_url.
|
||||
*/
|
|
@ -1,58 +0,0 @@
|
|||
diff --git a/support/apxs.in b/support/apxs.in
|
||||
index b2705fa..c331631 100644
|
||||
--- a/support/apxs.in
|
||||
+++ b/support/apxs.in
|
||||
@@ -35,7 +35,18 @@ if ($ddi >= 0) {
|
||||
|
||||
my %config_vars = ();
|
||||
|
||||
-my $installbuilddir = "@exp_installbuilddir@";
|
||||
+# Awful hack to make apxs libdir-agnostic:
|
||||
+my $pkg_config = "/usr/bin/pkg-config";
|
||||
+if (! -x "$pkg_config") {
|
||||
+ error("$pkg_config not found!");
|
||||
+ exit(1);
|
||||
+}
|
||||
+
|
||||
+my $libdir = `pkg-config --variable=libdir apr-1`;
|
||||
+chomp $libdir;
|
||||
+
|
||||
+my $installbuilddir = $libdir . "/httpd/build";
|
||||
+
|
||||
get_config_vars($destdir . "$installbuilddir/config_vars.mk",\%config_vars);
|
||||
|
||||
# read the configuration variables once
|
||||
@@ -285,7 +296,7 @@ if ($opt_g) {
|
||||
$data =~ s|%NAME%|$name|sg;
|
||||
$data =~ s|%TARGET%|$CFG_TARGET|sg;
|
||||
$data =~ s|%PREFIX%|$prefix|sg;
|
||||
- $data =~ s|%INSTALLBUILDDIR%|$installbuilddir|sg;
|
||||
+ $data =~ s|%LIBDIR%|$libdir|sg;
|
||||
|
||||
my ($mkf, $mods, $src) = ($data =~ m|^(.+)-=#=-\n(.+)-=#=-\n(.+)|s);
|
||||
|
||||
@@ -463,11 +474,11 @@ if ($opt_c) {
|
||||
my $ldflags = "$CFG_LDFLAGS";
|
||||
if ($opt_p == 1) {
|
||||
|
||||
- my $apr_libs=`$apr_config --cflags --ldflags --link-libtool --libs`;
|
||||
+ my $apr_libs=`$apr_config --cflags --ldflags --link-libtool`;
|
||||
chomp($apr_libs);
|
||||
my $apu_libs="";
|
||||
if ($apr_major_version < 2) {
|
||||
- $apu_libs=`$apu_config --ldflags --link-libtool --libs`;
|
||||
+ $apu_libs=`$apu_config --ldflags --link-libtool`;
|
||||
chomp($apu_libs);
|
||||
}
|
||||
|
||||
@@ -682,8 +693,8 @@ __DATA__
|
||||
|
||||
builddir=.
|
||||
top_srcdir=%PREFIX%
|
||||
-top_builddir=%PREFIX%
|
||||
-include %INSTALLBUILDDIR%/special.mk
|
||||
+top_builddir=%LIBDIR%/httpd
|
||||
+include %LIBDIR%/httpd/build/special.mk
|
||||
|
||||
# the used tools
|
||||
APACHECTL=apachectl
|
|
@ -1,82 +0,0 @@
|
|||
diff --git a/modules/cache/cache_util.h b/modules/cache/cache_util.h
|
||||
index 6b92151..4c42a8e 100644
|
||||
--- a/modules/cache/cache_util.h
|
||||
+++ b/modules/cache/cache_util.h
|
||||
@@ -195,6 +195,9 @@ typedef struct {
|
||||
unsigned int store_nostore_set:1;
|
||||
unsigned int enable_set:1;
|
||||
unsigned int disable_set:1;
|
||||
+ /* treat maxex as hard limit */
|
||||
+ unsigned int hardmaxex:1;
|
||||
+ unsigned int hardmaxex_set:1;
|
||||
} cache_dir_conf;
|
||||
|
||||
/* A linked-list of authn providers. */
|
||||
diff --git a/modules/cache/mod_cache.c b/modules/cache/mod_cache.c
|
||||
index 3b9aa4f..8268503 100644
|
||||
--- a/modules/cache/mod_cache.c
|
||||
+++ b/modules/cache/mod_cache.c
|
||||
@@ -1455,6 +1455,11 @@ static apr_status_t cache_save_filter(ap_filter_t *f, apr_bucket_brigade *in)
|
||||
exp = date + dconf->defex;
|
||||
}
|
||||
}
|
||||
+ /* else, forcibly cap the expiry date if required */
|
||||
+ else if (dconf->hardmaxex && (date + dconf->maxex) < exp) {
|
||||
+ exp = date + dconf->maxex;
|
||||
+ }
|
||||
+
|
||||
info->expire = exp;
|
||||
|
||||
/* We found a stale entry which wasn't really stale. */
|
||||
@@ -1954,7 +1959,9 @@ static void *create_dir_config(apr_pool_t *p, char *dummy)
|
||||
|
||||
/* array of providers for this URL space */
|
||||
dconf->cacheenable = apr_array_make(p, 10, sizeof(struct cache_enable));
|
||||
-
|
||||
+ /* flag; treat maxex as hard limit */
|
||||
+ dconf->hardmaxex = 0;
|
||||
+ dconf->hardmaxex_set = 0;
|
||||
return dconf;
|
||||
}
|
||||
|
||||
@@ -2004,7 +2011,10 @@ static void *merge_dir_config(apr_pool_t *p, void *basev, void *addv) {
|
||||
new->enable_set = add->enable_set || base->enable_set;
|
||||
new->disable = (add->disable_set == 0) ? base->disable : add->disable;
|
||||
new->disable_set = add->disable_set || base->disable_set;
|
||||
-
|
||||
+ new->hardmaxex =
|
||||
+ (add->hardmaxex_set == 0)
|
||||
+ ? base->hardmaxex
|
||||
+ : add->hardmaxex;
|
||||
return new;
|
||||
}
|
||||
|
||||
@@ -2332,12 +2342,18 @@ static const char *add_cache_disable(cmd_parms *parms, void *dummy,
|
||||
}
|
||||
|
||||
static const char *set_cache_maxex(cmd_parms *parms, void *dummy,
|
||||
- const char *arg)
|
||||
+ const char *arg, const char *hard)
|
||||
{
|
||||
cache_dir_conf *dconf = (cache_dir_conf *)dummy;
|
||||
|
||||
dconf->maxex = (apr_time_t) (atol(arg) * MSEC_ONE_SEC);
|
||||
dconf->maxex_set = 1;
|
||||
+
|
||||
+ if (hard && strcasecmp(hard, "hard") == 0) {
|
||||
+ dconf->hardmaxex = 1;
|
||||
+ dconf->hardmaxex_set = 1;
|
||||
+ }
|
||||
+
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2545,7 +2561,7 @@ static const command_rec cache_cmds[] =
|
||||
"caching is enabled"),
|
||||
AP_INIT_TAKE1("CacheDisable", add_cache_disable, NULL, RSRC_CONF|ACCESS_CONF,
|
||||
"A partial URL prefix below which caching is disabled"),
|
||||
- AP_INIT_TAKE1("CacheMaxExpire", set_cache_maxex, NULL, RSRC_CONF|ACCESS_CONF,
|
||||
+ AP_INIT_TAKE12("CacheMaxExpire", set_cache_maxex, NULL, RSRC_CONF|ACCESS_CONF,
|
||||
"The maximum time in seconds to cache a document"),
|
||||
AP_INIT_TAKE1("CacheMinExpire", set_cache_minex, NULL, RSRC_CONF|ACCESS_CONF,
|
||||
"The minimum time in seconds to cache a document"),
|
|
@ -1,30 +0,0 @@
|
|||
diff --git a/server/core.c b/server/core.c
|
||||
index 79b2a82..dc0f17a 100644
|
||||
--- a/server/core.c
|
||||
+++ b/server/core.c
|
||||
@@ -4996,6 +4996,25 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
|
||||
}
|
||||
apr_pool_cleanup_register(pconf, NULL, ap_mpm_end_gen_helper,
|
||||
apr_pool_cleanup_null);
|
||||
+
|
||||
+#ifdef RLIMIT_CORE
|
||||
+ if (ap_coredumpdir_configured) {
|
||||
+ struct rlimit lim;
|
||||
+
|
||||
+ if (getrlimit(RLIMIT_CORE, &lim) == 0 && lim.rlim_cur == 0) {
|
||||
+ lim.rlim_cur = lim.rlim_max;
|
||||
+ if (setrlimit(RLIMIT_CORE, &lim) == 0) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
|
||||
+ "core dump file size limit raised to %lu bytes",
|
||||
+ lim.rlim_cur);
|
||||
+ } else {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, errno, NULL,
|
||||
+ "core dump file size is zero, setrlimit failed");
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
diff --git a/configure.in b/configure.in
|
||||
index f8f9442..f276550 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -786,9 +786,9 @@ APACHE_SUBST(INSTALL_SUEXEC)
|
||||
|
||||
dnl APR should go after the other libs, so the right symbols can be picked up
|
||||
if test x${apu_found} != xobsolete; then
|
||||
- AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool --libs`"
|
||||
+ AP_LIBS="$AP_LIBS `$apu_config --avoid-ldap --link-libtool`"
|
||||
fi
|
||||
-AP_LIBS="$AP_LIBS `$apr_config --link-libtool --libs`"
|
||||
+AP_LIBS="$AP_LIBS `$apr_config --link-libtool`"
|
||||
APACHE_SUBST(AP_LIBS)
|
||||
APACHE_SUBST(AP_BUILD_SRCLIB_DIRS)
|
||||
APACHE_SUBST(AP_CLEAN_SRCLIB_DIRS)
|
|
@ -1,62 +0,0 @@
|
|||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
|
||||
index 979489c..3d6443b 100644
|
||||
--- a/modules/ssl/ssl_engine_config.c
|
||||
+++ b/modules/ssl/ssl_engine_config.c
|
||||
@@ -1485,6 +1485,10 @@ static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
|
||||
#endif
|
||||
else if (strcEQ(w, "all")) {
|
||||
thisopt = SSL_PROTOCOL_ALL;
|
||||
+#ifndef OPENSSL_NO_SSL3
|
||||
+ /* by default, ALL kw doesn't turn on SSLv3 */
|
||||
+ thisopt &= ~SSL_PROTOCOL_SSLV3;
|
||||
+#endif
|
||||
}
|
||||
else {
|
||||
return apr_pstrcat(parms->temp_pool,
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index b0fcf81..ab6f263 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -568,6 +568,28 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s,
|
||||
}
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * Enable/disable SSLProtocol. If the mod_ssl enables protocol
|
||||
+ * which is disabled by default by OpenSSL, show a warning.
|
||||
+ * "option" is for example SSL_OP_NO_SSLv3.
|
||||
+ */
|
||||
+static void ssl_set_ctx_protocol_option(server_rec *s,
|
||||
+ SSL_CTX *ctx,
|
||||
+ long option,
|
||||
+ int enabled,
|
||||
+ const char *name)
|
||||
+{
|
||||
+ if (!enabled) {
|
||||
+ SSL_CTX_set_options(ctx, option);
|
||||
+ }
|
||||
+ else if (SSL_CTX_get_options(ctx) & option) {
|
||||
+ SSL_CTX_clear_options(ctx, option);
|
||||
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02904)
|
||||
+ "Allowing SSLProtocol %s even though it is disabled "
|
||||
+ "by OpenSSL by default on this system", name);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
apr_pool_t *p,
|
||||
apr_pool_t *ptemp,
|
||||
@@ -735,9 +757,13 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
}
|
||||
if (prot == TLS1_1_VERSION && protocol & SSL_PROTOCOL_TLSV1) {
|
||||
prot = TLS1_VERSION;
|
||||
+ ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_TLSv1,
|
||||
+ protocol & SSL_PROTOCOL_TLSV1, "TLSv1");
|
||||
}
|
||||
#ifndef OPENSSL_NO_SSL3
|
||||
if (prot == TLS1_VERSION && protocol & SSL_PROTOCOL_SSLV3) {
|
||||
+ ssl_set_ctx_protocol_option(s, ctx, SSL_OP_NO_SSLv3,
|
||||
+ protocol & SSL_PROTOCOL_SSLV3, "SSLv3");
|
||||
prot = SSL3_VERSION;
|
||||
}
|
||||
#endif
|
|
@ -1,93 +0,0 @@
|
|||
From d4e5b6e1e5585d341d1e51f1ddc637c099111076 Mon Sep 17 00:00:00 2001
|
||||
From: Joe Orton <jorton@redhat.com>
|
||||
Date: Tue, 7 Jul 2020 09:48:01 +0100
|
||||
Subject: [PATCH] Check and use gettid() directly with glibc 2.30+.
|
||||
|
||||
* configure.in: Check for gettid() and define HAVE_SYS_GETTID if
|
||||
gettid() is only usable via syscall().
|
||||
|
||||
* server/log.c (log_tid): Use gettid() directly if available.
|
||||
---
|
||||
configure.in | 14 +++++++++-----
|
||||
server/log.c | 8 ++++++--
|
||||
2 files changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/configure.in b/configure.in
|
||||
index 423d58d4b9a..60cbf7b7f81 100644
|
||||
--- httpd-2.4.43/configure.in.gettid
|
||||
+++ httpd-2.4.43/configure.in
|
||||
@@ -478,7 +500,8 @@
|
||||
timegm \
|
||||
getpgid \
|
||||
fopen64 \
|
||||
-getloadavg
|
||||
+getloadavg \
|
||||
+gettid
|
||||
)
|
||||
|
||||
dnl confirm that a void pointer is large enough to store a long integer
|
||||
@@ -489,16 +512,19 @@
|
||||
APR_ADDTO(HTTPD_LIBS, [-lselinux])
|
||||
])
|
||||
|
||||
-AC_CACHE_CHECK([for gettid()], ac_cv_gettid,
|
||||
+if test $ac_cv_func_gettid = no; then
|
||||
+ # On Linux before glibc 2.30, gettid() is only usable via syscall()
|
||||
+ AC_CACHE_CHECK([for gettid() via syscall], ap_cv_gettid,
|
||||
[AC_TRY_RUN(#define _GNU_SOURCE
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
int main(int argc, char **argv) {
|
||||
pid_t t = syscall(SYS_gettid); return t == -1 ? 1 : 0; },
|
||||
-[ac_cv_gettid=yes], [ac_cv_gettid=no], [ac_cv_gettid=no])])
|
||||
-if test "$ac_cv_gettid" = "yes"; then
|
||||
- AC_DEFINE(HAVE_GETTID, 1, [Define if you have gettid()])
|
||||
+ [ap_cv_gettid=yes], [ap_cv_gettid=no], [ap_cv_gettid=no])])
|
||||
+ if test "$ap_cv_gettid" = "yes"; then
|
||||
+ AC_DEFINE(HAVE_SYS_GETTID, 1, [Define if you have gettid() via syscall()])
|
||||
+ fi
|
||||
fi
|
||||
|
||||
dnl ## Check for the tm_gmtoff field in struct tm to get the timezone diffs
|
||||
--- httpd-2.4.43/server/log.c.gettid
|
||||
+++ httpd-2.4.43/server/log.c
|
||||
@@ -55,7 +55,7 @@
|
||||
#include "ap_mpm.h"
|
||||
#include "ap_listen.h"
|
||||
|
||||
-#if HAVE_GETTID
|
||||
+#if HAVE_SYS_GETTID
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
@@ -625,14 +625,18 @@
|
||||
#if APR_HAS_THREADS
|
||||
int result;
|
||||
#endif
|
||||
-#if HAVE_GETTID
|
||||
+#if defined(HAVE_GETTID) || defined(HAVE_SYS_GETTID)
|
||||
if (arg && *arg == 'g') {
|
||||
+#ifdef HAVE_GETTID
|
||||
+ pid_t tid = gettid();
|
||||
+#else
|
||||
pid_t tid = syscall(SYS_gettid);
|
||||
+#endif
|
||||
if (tid == -1)
|
||||
return 0;
|
||||
return apr_snprintf(buf, buflen, "%"APR_PID_T_FMT, tid);
|
||||
}
|
||||
-#endif
|
||||
+#endif /* HAVE_GETTID || HAVE_SYS_GETTID */
|
||||
#if APR_HAS_THREADS
|
||||
if (ap_mpm_query(AP_MPMQ_IS_THREADED, &result) == APR_SUCCESS
|
||||
&& result != AP_MPMQ_NOT_SUPPORTED)
|
||||
@@ -966,7 +970,7 @@
|
||||
#if APR_HAS_THREADS
|
||||
field_start = len;
|
||||
len += cpystrn(buf + len, ":tid ", buflen - len);
|
||||
- item_len = log_tid(info, NULL, buf + len, buflen - len);
|
||||
+ item_len = log_tid(info, "g", buf + len, buflen - len);
|
||||
if (!item_len)
|
||||
len = field_start;
|
||||
else
|
|
@ -1,87 +0,0 @@
|
|||
diff --git a/modules/loggers/config.m4 b/modules/loggers/config.m4
|
||||
index 762e773..0848d2e 100644
|
||||
--- a/modules/loggers/config.m4
|
||||
+++ b/modules/loggers/config.m4
|
||||
@@ -5,6 +5,8 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
|
||||
APACHE_MODPATH_INIT(loggers)
|
||||
|
||||
APACHE_MODULE(log_config, logging configuration. You won't be able to log requests to the server without this module., , , yes)
|
||||
+APR_ADDTO(MOD_LOG_CONFIG_LDADD, [$SYSTEMD_LIBS])
|
||||
+
|
||||
APACHE_MODULE(log_debug, configurable debug logging, , , most)
|
||||
APACHE_MODULE(log_forensic, forensic logging)
|
||||
|
||||
diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c
|
||||
index 996c09c..50a056a 100644
|
||||
--- a/modules/loggers/mod_log_config.c
|
||||
+++ b/modules/loggers/mod_log_config.c
|
||||
@@ -172,6 +172,10 @@
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+#include <systemd/sd-journal.h>
|
||||
+#endif
|
||||
+
|
||||
#define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b"
|
||||
|
||||
module AP_MODULE_DECLARE_DATA log_config_module;
|
||||
@@ -1638,6 +1642,25 @@ static apr_status_t ap_default_log_writer( request_rec *r,
|
||||
|
||||
return rv;
|
||||
}
|
||||
+
|
||||
+static apr_status_t wrap_journal_stream(apr_pool_t *p, apr_file_t **outfd,
|
||||
+ int priority)
|
||||
+{
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+ int fd;
|
||||
+
|
||||
+ fd = sd_journal_stream_fd("httpd", priority, 0);
|
||||
+ if (fd < 0) return fd;
|
||||
+
|
||||
+ /* This is an AF_UNIX socket fd so is more pipe-like than
|
||||
+ * file-like (the fd is neither seekable or readable), and use of
|
||||
+ * apr_os_pipe_put_ex() allows cleanup registration. */
|
||||
+ return apr_os_pipe_put_ex(outfd, &fd, 1, p);
|
||||
+#else
|
||||
+ return APR_ENOTIMPL;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s,
|
||||
const char* name)
|
||||
{
|
||||
@@ -1650,6 +1673,32 @@ static void *ap_default_log_writer_init(apr_pool_t *p, server_rec *s,
|
||||
}
|
||||
return ap_piped_log_write_fd(pl);
|
||||
}
|
||||
+ else if (strncasecmp(name, "journald:", 9) == 0) {
|
||||
+ int priority;
|
||||
+ const char *err = ap_parse_log_level(name + 9, &priority);
|
||||
+ apr_status_t rv;
|
||||
+ apr_file_t *fd;
|
||||
+
|
||||
+ if (err == NULL && priority > LOG_DEBUG) {
|
||||
+ err = "TRACE level debugging not supported with journald";
|
||||
+ }
|
||||
+
|
||||
+ if (err) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s,
|
||||
+ "invalid journald log priority name %s: %s",
|
||||
+ name, err);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ rv = wrap_journal_stream(p, &fd, priority);
|
||||
+ if (rv) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
|
||||
+ "could not open journald log stream");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ return fd;
|
||||
+ }
|
||||
else {
|
||||
const char *fname = ap_server_root_relative(p, name);
|
||||
apr_file_t *fd;
|
|
@ -1,96 +0,0 @@
|
|||
|
||||
More verbose startup logging for mod_systemd.
|
||||
|
||||
--- httpd-2.4.43/modules/arch/unix/mod_systemd.c.mod_systemd
|
||||
+++ httpd-2.4.43/modules/arch/unix/mod_systemd.c
|
||||
@@ -29,11 +29,14 @@
|
||||
#include "mpm_common.h"
|
||||
|
||||
#include "systemd/sd-daemon.h"
|
||||
+#include "systemd/sd-journal.h"
|
||||
|
||||
#if APR_HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
+static char describe_listeners[30];
|
||||
+
|
||||
static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
|
||||
apr_pool_t *ptemp)
|
||||
{
|
||||
@@ -44,6 +47,20 @@
|
||||
return OK;
|
||||
}
|
||||
|
||||
+static char *dump_listener(ap_listen_rec *lr, apr_pool_t *p)
|
||||
+{
|
||||
+ apr_sockaddr_t *sa = lr->bind_addr;
|
||||
+ char addr[128];
|
||||
+
|
||||
+ if (apr_sockaddr_is_wildcard(sa)) {
|
||||
+ return apr_pstrcat(p, "port ", apr_itoa(p, sa->port), NULL);
|
||||
+ }
|
||||
+
|
||||
+ apr_sockaddr_ip_getbuf(addr, sizeof addr, sa);
|
||||
+
|
||||
+ return apr_psprintf(p, "%s port %u", addr, sa->port);
|
||||
+}
|
||||
+
|
||||
/* Report the service is ready in post_config, which could be during
|
||||
* startup or after a reload. The server could still hit a fatal
|
||||
* startup error after this point during ap_run_mpm(), so this is
|
||||
@@ -51,19 +68,51 @@
|
||||
* the TCP ports so new connections will not be rejected. There will
|
||||
* always be a possible async failure event simultaneous to the
|
||||
* service reporting "ready", so this should be good enough. */
|
||||
-static int systemd_post_config(apr_pool_t *p, apr_pool_t *plog,
|
||||
+static int systemd_post_config(apr_pool_t *pconf, apr_pool_t *plog,
|
||||
apr_pool_t *ptemp, server_rec *main_server)
|
||||
{
|
||||
+ ap_listen_rec *lr;
|
||||
+ apr_size_t plen = sizeof describe_listeners;
|
||||
+ char *p = describe_listeners;
|
||||
+
|
||||
+ if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
|
||||
+ return OK;
|
||||
+
|
||||
+ for (lr = ap_listeners; lr; lr = lr->next) {
|
||||
+ char *s = dump_listener(lr, ptemp);
|
||||
+
|
||||
+ if (strlen(s) + 3 < plen) {
|
||||
+ char *newp = apr_cpystrn(p, s, plen);
|
||||
+ if (lr->next)
|
||||
+ newp = apr_cpystrn(newp, ", ", 3);
|
||||
+ plen -= newp - p;
|
||||
+ p = newp;
|
||||
+ }
|
||||
+ else {
|
||||
+ if (plen < 4) {
|
||||
+ p = describe_listeners + sizeof describe_listeners - 4;
|
||||
+ plen = 4;
|
||||
+ }
|
||||
+ apr_cpystrn(p, "...", plen);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
sd_notify(0, "READY=1\n"
|
||||
"STATUS=Configuration loaded.\n");
|
||||
+
|
||||
+ sd_journal_print(LOG_INFO, "Server configured, listening on: %s",
|
||||
+ describe_listeners);
|
||||
+
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int systemd_pre_mpm(apr_pool_t *p, ap_scoreboard_e sb_type)
|
||||
{
|
||||
sd_notifyf(0, "READY=1\n"
|
||||
- "STATUS=Processing requests...\n"
|
||||
- "MAINPID=%" APR_PID_T_FMT, getpid());
|
||||
+ "STATUS=Started, listening on: %s\n"
|
||||
+ "MAINPID=%" APR_PID_T_FMT,
|
||||
+ describe_listeners, getpid());
|
||||
|
||||
return OK;
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
|
||||
index e599515..154ab21 100644
|
||||
--- a/modules/proxy/mod_proxy.c
|
||||
+++ b/modules/proxy/mod_proxy.c
|
||||
@@ -1200,11 +1200,20 @@ static int proxy_handler(request_rec *r)
|
||||
/* handle the scheme */
|
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01142)
|
||||
"Trying to run scheme_handler against proxy");
|
||||
+
|
||||
+ if (ents[i].creds) {
|
||||
+ apr_table_set(r->notes, "proxy-basic-creds", ents[i].creds);
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
|
||||
+ "Using proxy auth creds %s", ents[i].creds);
|
||||
+ }
|
||||
+
|
||||
access_status = proxy_run_scheme_handler(r, worker,
|
||||
conf, url,
|
||||
ents[i].hostname,
|
||||
ents[i].port);
|
||||
|
||||
+ if (ents[i].creds) apr_table_unset(r->notes, "proxy-basic-creds");
|
||||
+
|
||||
/* Did the scheme handler process the request? */
|
||||
if (access_status != DECLINED) {
|
||||
const char *cl_a;
|
||||
@@ -1620,8 +1629,8 @@ static void *merge_proxy_dir_config(apr_pool_t *p, void *basev, void *addv)
|
||||
return new;
|
||||
}
|
||||
|
||||
-static const char *
|
||||
- add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1, int regex)
|
||||
+static const char *add_proxy(cmd_parms *cmd, void *dummy, const char *f1,
|
||||
+ const char *r1, const char *creds, int regex)
|
||||
{
|
||||
server_rec *s = cmd->server;
|
||||
proxy_server_conf *conf =
|
||||
@@ -1679,19 +1688,24 @@ static const char *
|
||||
new->port = port;
|
||||
new->regexp = reg;
|
||||
new->use_regex = regex;
|
||||
+ if (creds) {
|
||||
+ new->creds = apr_pstrcat(cmd->pool, "Basic ",
|
||||
+ ap_pbase64encode(cmd->pool, (char *)creds),
|
||||
+ NULL);
|
||||
+ }
|
||||
return NULL;
|
||||
}
|
||||
|
||||
-static const char *
|
||||
- add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1)
|
||||
+static const char *add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1,
|
||||
+ const char *r1, const char *creds)
|
||||
{
|
||||
- return add_proxy(cmd, dummy, f1, r1, 0);
|
||||
+ return add_proxy(cmd, dummy, f1, r1, creds, 0);
|
||||
}
|
||||
|
||||
-static const char *
|
||||
- add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1)
|
||||
+static const char *add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1,
|
||||
+ const char *r1, const char *creds)
|
||||
{
|
||||
- return add_proxy(cmd, dummy, f1, r1, 1);
|
||||
+ return add_proxy(cmd, dummy, f1, r1, creds, 1);
|
||||
}
|
||||
|
||||
PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url)
|
||||
@@ -2637,9 +2651,9 @@ static const command_rec proxy_cmds[] =
|
||||
"location, in regular expression syntax"),
|
||||
AP_INIT_FLAG("ProxyRequests", set_proxy_req, NULL, RSRC_CONF,
|
||||
"on if the true proxy requests should be accepted"),
|
||||
- AP_INIT_TAKE2("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF,
|
||||
+ AP_INIT_TAKE23("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF,
|
||||
"a scheme, partial URL or '*' and a proxy server"),
|
||||
- AP_INIT_TAKE2("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF,
|
||||
+ AP_INIT_TAKE23("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF,
|
||||
"a regex pattern and a proxy server"),
|
||||
AP_INIT_FLAG("ProxyPassInterpolateEnv", ap_set_flag_slot_char,
|
||||
(void*)APR_OFFSETOF(proxy_dir_conf, interpolate_env),
|
||||
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
|
||||
index 895b937..538839f 100644
|
||||
--- a/modules/proxy/mod_proxy.h
|
||||
+++ b/modules/proxy/mod_proxy.h
|
||||
@@ -116,6 +116,7 @@ struct proxy_remote {
|
||||
const char *protocol; /* the scheme used to talk to this proxy */
|
||||
const char *hostname; /* the hostname of this proxy */
|
||||
ap_regex_t *regexp; /* compiled regex (if any) for the remote */
|
||||
+ const char *creds; /* auth credentials (if any) for the proxy */
|
||||
int use_regex; /* simple boolean. True if we have a regex pattern */
|
||||
apr_port_t port; /* the port for this proxy */
|
||||
};
|
||||
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
|
||||
index e7ffe33..50561a4 100644
|
||||
--- a/modules/proxy/proxy_util.c
|
||||
+++ b/modules/proxy/proxy_util.c
|
||||
@@ -2474,11 +2474,14 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
|
||||
* So let's make it configurable by env.
|
||||
* The logic here is the same used in mod_proxy_http.
|
||||
*/
|
||||
- proxy_auth = apr_table_get(r->headers_in, "Proxy-Authorization");
|
||||
+ proxy_auth = apr_table_get(r->notes, "proxy-basic-creds");
|
||||
+ if (proxy_auth == NULL)
|
||||
+ proxy_auth = apr_table_get(r->headers_in, "Proxy-Authorization");
|
||||
+
|
||||
if (proxy_auth != NULL &&
|
||||
proxy_auth[0] != '\0' &&
|
||||
- r->user == NULL && /* we haven't yet authenticated */
|
||||
- apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) {
|
||||
+ (r->user == NULL /* we haven't yet authenticated */
|
||||
+ || apr_table_get(r->subprocess_env, "Proxy-Chain-Auth"))) {
|
||||
forward->proxy_auth = apr_pstrdup(conn->pool, proxy_auth);
|
||||
}
|
||||
}
|
||||
@@ -2714,7 +2717,8 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
|
||||
nbytes = apr_snprintf(buffer, sizeof(buffer),
|
||||
"CONNECT %s:%d HTTP/1.0" CRLF,
|
||||
forward->target_host, forward->target_port);
|
||||
- /* Add proxy authorization from the initial request if necessary */
|
||||
+ /* Add proxy authorization from the configuration, or initial
|
||||
+ * request if necessary */
|
||||
if (forward->proxy_auth != NULL) {
|
||||
nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes,
|
||||
"Proxy-Authorization: %s" CRLF,
|
||||
@@ -3627,6 +3631,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
apr_bucket *e;
|
||||
int do_100_continue;
|
||||
conn_rec *origin = p_conn->connection;
|
||||
+ const char *creds;
|
||||
proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
|
||||
|
||||
/*
|
||||
@@ -3803,6 +3808,11 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
return HTTP_BAD_REQUEST;
|
||||
}
|
||||
|
||||
+ creds = apr_table_get(r->notes, "proxy-basic-creds");
|
||||
+ if (creds) {
|
||||
+ apr_table_mergen(r->headers_in, "Proxy-Authorization", creds);
|
||||
+ }
|
||||
+
|
||||
/* send request headers */
|
||||
headers_in_array = apr_table_elts(r->headers_in);
|
||||
headers_in = (const apr_table_entry_t *) headers_in_array->elts;
|
|
@ -1,20 +0,0 @@
|
|||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
|
||||
index b53f3f8..979489c 100644
|
||||
--- a/modules/ssl/ssl_engine_config.c
|
||||
+++ b/modules/ssl/ssl_engine_config.c
|
||||
@@ -812,8 +812,14 @@ const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
|
||||
static const char *ssl_cmd_check_file(cmd_parms *parms,
|
||||
const char **file)
|
||||
{
|
||||
- const char *filepath = ap_server_root_relative(parms->pool, *file);
|
||||
+ const char *filepath;
|
||||
|
||||
+ /* If only dumping the config, don't verify the paths */
|
||||
+ if (ap_state_query(AP_SQ_RUN_MODE) == AP_SQ_RM_CONFIG_DUMP) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ filepath = ap_server_root_relative(parms->pool, *file);
|
||||
if (!filepath) {
|
||||
return apr_pstrcat(parms->pool, parms->cmd->name,
|
||||
": Invalid file path ", *file, NULL);
|
|
@ -1,271 +0,0 @@
|
|||
diff --git a/configure.in b/configure.in
|
||||
index cb43246..0bb6b0d 100644
|
||||
--- httpd-2.4.43/configure.in.r1861793+
|
||||
+++ httpd-2.4.43/configure.in
|
||||
@@ -465,6 +465,28 @@
|
||||
AC_SEARCH_LIBS(crypt, crypt)
|
||||
CRYPT_LIBS="$LIBS"
|
||||
APACHE_SUBST(CRYPT_LIBS)
|
||||
+
|
||||
+if test "$ac_cv_search_crypt" != "no"; then
|
||||
+ # Test crypt() with the SHA-512 test vector from https://akkadia.org/drepper/SHA-crypt.txt
|
||||
+ AC_CACHE_CHECK([whether crypt() supports SHA-2], [ap_cv_crypt_sha2], [
|
||||
+ AC_RUN_IFELSE([AC_LANG_PROGRAM([[
|
||||
+#include <crypt.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+#define PASSWD_0 "Hello world!"
|
||||
+#define SALT_0 "\$6\$saltstring"
|
||||
+#define EXPECT_0 "\$6\$saltstring\$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJu" \
|
||||
+ "esI68u4OTLiBFdcbYEdFCoEOfaS35inz1"
|
||||
+]], [char *result = crypt(PASSWD_0, SALT_0);
|
||||
+ if (!result) return 1;
|
||||
+ if (strcmp(result, EXPECT_0)) return 2;
|
||||
+])], [ap_cv_crypt_sha2=yes], [ap_cv_crypt_sha2=no])])
|
||||
+ if test "$ap_cv_crypt_sha2" = yes; then
|
||||
+ AC_DEFINE([HAVE_CRYPT_SHA2], 1, [Define if crypt() supports SHA-2 hashes])
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
LIBS="$saved_LIBS"
|
||||
|
||||
dnl See Comment #Spoon
|
||||
--- httpd-2.4.43/docs/man/htpasswd.1.r1861793+
|
||||
+++ httpd-2.4.43/docs/man/htpasswd.1
|
||||
@@ -27,16 +27,16 @@
|
||||
.SH "SYNOPSIS"
|
||||
|
||||
.PP
|
||||
-\fB\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR\fR
|
||||
+\fB\fBhtpasswd\fR [ -\fBc\fR ] [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR\fR
|
||||
|
||||
.PP
|
||||
-\fB\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR\fR
|
||||
+\fB\fBhtpasswd\fR -\fBb\fR [ -\fBc\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] [ -\fBD\fR ] [ -\fBv\fR ] \fIpasswdfile\fR \fIusername\fR \fIpassword\fR\fR
|
||||
|
||||
.PP
|
||||
-\fB\fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR\fR
|
||||
+\fB\fBhtpasswd\fR -\fBn\fR [ -\fBi\fR ] [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR\fR
|
||||
|
||||
.PP
|
||||
-\fB\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR \fIpassword\fR\fR
|
||||
+\fB\fBhtpasswd\fR -\fBnb\fR [ -\fBm\fR | -\fBB\fR | -\fB2\fR | -\fB5\fR | -\fBd\fR | -\fBs\fR | -\fBp\fR ] [ -\fBr\fR \fIrounds\fR ] [ -\fBC\fR \fIcost\fR ] \fIusername\fR \fIpassword\fR\fR
|
||||
|
||||
|
||||
.SH "SUMMARY"
|
||||
@@ -48,7 +48,7 @@
|
||||
Resources available from the Apache HTTP server can be restricted to just the users listed in the files created by \fBhtpasswd\fR\&. This program can only manage usernames and passwords stored in a flat-file\&. It can encrypt and display password information for use in other types of data stores, though\&. To use a DBM database see dbmmanage or htdbm\&.
|
||||
|
||||
.PP
|
||||
-\fBhtpasswd\fR encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA1, or the system's \fBcrypt()\fR routine\&. Files managed by \fBhtpasswd\fR may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-encrypted passwords while others in the same file may have passwords encrypted with \fBcrypt()\fR\&.
|
||||
+\fBhtpasswd\fR encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA-1, or the system's \fBcrypt()\fR routine\&. SHA-2-based hashes (SHA-256 and SHA-512) are supported for \fBcrypt()\fR\&. Files managed by \fBhtpasswd\fR may contain a mixture of different encoding types of passwords; some user records may have bcrypt or MD5-encrypted passwords while others in the same file may have passwords encrypted with \fBcrypt()\fR\&.
|
||||
|
||||
.PP
|
||||
This manual page only lists the command line arguments\&. For details of the directives necessary to configure user authentication in httpd see the Apache manual, which is part of the Apache distribution or can be found at http://httpd\&.apache\&.org/\&.
|
||||
@@ -73,17 +73,26 @@
|
||||
\fB-m\fR
|
||||
Use MD5 encryption for passwords\&. This is the default (since version 2\&.2\&.18)\&.
|
||||
.TP
|
||||
+\fB-2\fR
|
||||
+Use SHA-256 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&.
|
||||
+.TP
|
||||
+\fB-5\fR
|
||||
+Use SHA-512 \fBcrypt()\fR based hashes for passwords\&. This is supported on most Unix platforms\&.
|
||||
+.TP
|
||||
\fB-B\fR
|
||||
Use bcrypt encryption for passwords\&. This is currently considered to be very secure\&.
|
||||
.TP
|
||||
\fB-C\fR
|
||||
This flag is only allowed in combination with \fB-B\fR (bcrypt encryption)\&. It sets the computing time used for the bcrypt algorithm (higher is more secure but slower, default: 5, valid: 4 to 17)\&.
|
||||
.TP
|
||||
+\fB-r\fR
|
||||
+This flag is only allowed in combination with \fB-2\fR or \fB-5\fR\&. It sets the number of hash rounds used for the SHA-2 algorithms (higher is more secure but slower; the default is 5,000)\&.
|
||||
+.TP
|
||||
\fB-d\fR
|
||||
Use \fBcrypt()\fR encryption for passwords\&. This is not supported by the httpd server on Windows and Netware\&. This algorithm limits the password length to 8 characters\&. This algorithm is \fBinsecure\fR by today's standards\&. It used to be the default algorithm until version 2\&.2\&.17\&.
|
||||
.TP
|
||||
\fB-s\fR
|
||||
-Use SHA encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&.
|
||||
+Use SHA-1 (160-bit) encryption for passwords\&. Facilitates migration from/to Netscape servers using the LDAP Directory Interchange Format (ldif)\&. This algorithm is \fBinsecure\fR by today's standards\&.
|
||||
.TP
|
||||
\fB-p\fR
|
||||
Use plaintext passwords\&. Though \fBhtpasswd\fR will support creation on all platforms, the httpd daemon will only accept plain text passwords on Windows and Netware\&.
|
||||
@@ -152,10 +161,13 @@
|
||||
When using the \fBcrypt()\fR algorithm, note that only the first 8 characters of the password are used to form the password\&. If the supplied password is longer, the extra characters will be silently discarded\&.
|
||||
|
||||
.PP
|
||||
-The SHA encryption format does not use salting: for a given password, there is only one encrypted representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&.
|
||||
+The SHA-1 encryption format does not use salting: for a given password, there is only one encrypted representation\&. The \fBcrypt()\fR and MD5 formats permute the representation by prepending a random salt string, to make dictionary attacks against the passwords more difficult\&.
|
||||
+
|
||||
+.PP
|
||||
+The SHA-1 and \fBcrypt()\fR formats are insecure by today's standards\&.
|
||||
|
||||
.PP
|
||||
-The SHA and \fBcrypt()\fR formats are insecure by today's standards\&.
|
||||
+The SHA-2-based \fBcrypt()\fR formats (SHA-256 and SHA-512) are supported on most modern Unix systems, and follow the specification at https://www\&.akkadia\&.org/drepper/SHA-crypt\&.txt\&.
|
||||
|
||||
.SH "RESTRICTIONS"
|
||||
|
||||
--- httpd-2.4.43/support/htpasswd.c.r1861793+
|
||||
+++ httpd-2.4.43/support/htpasswd.c
|
||||
@@ -109,17 +109,21 @@
|
||||
"for it." NL
|
||||
" -i Read password from stdin without verification (for script usage)." NL
|
||||
" -m Force MD5 encryption of the password (default)." NL
|
||||
- " -B Force bcrypt encryption of the password (very secure)." NL
|
||||
+ " -2 Force SHA-256 crypt() hash of the password (very secure)." NL
|
||||
+ " -5 Force SHA-512 crypt() hash of the password (very secure)." NL
|
||||
+ " -B Force bcrypt encryption of the password (very secure)." NL
|
||||
" -C Set the computing time used for the bcrypt algorithm" NL
|
||||
" (higher is more secure but slower, default: %d, valid: 4 to 17)." NL
|
||||
+ " -r Set the number of rounds used for the SHA-256, SHA-512 algorithms" NL
|
||||
+ " (higher is more secure but slower, default: 5000)." NL
|
||||
" -d Force CRYPT encryption of the password (8 chars max, insecure)." NL
|
||||
- " -s Force SHA encryption of the password (insecure)." NL
|
||||
+ " -s Force SHA-1 encryption of the password (insecure)." NL
|
||||
" -p Do not encrypt the password (plaintext, insecure)." NL
|
||||
" -D Delete the specified user." NL
|
||||
" -v Verify password for the specified user." NL
|
||||
"On other systems than Windows and NetWare the '-p' flag will "
|
||||
"probably not work." NL
|
||||
- "The SHA algorithm does not use a salt and is less secure than the "
|
||||
+ "The SHA-1 algorithm does not use a salt and is less secure than the "
|
||||
"MD5 algorithm." NL,
|
||||
BCRYPT_DEFAULT_COST
|
||||
);
|
||||
@@ -178,7 +182,7 @@
|
||||
if (rv != APR_SUCCESS)
|
||||
exit(ERR_SYNTAX);
|
||||
|
||||
- while ((rv = apr_getopt(state, "cnmspdBbDiC:v", &opt, &opt_arg)) == APR_SUCCESS) {
|
||||
+ while ((rv = apr_getopt(state, "cnmspdBbDi25C:r:v", &opt, &opt_arg)) == APR_SUCCESS) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
*mask |= APHTP_NEWFILE;
|
||||
--- httpd-2.4.43/support/passwd_common.c.r1861793+
|
||||
+++ httpd-2.4.43/support/passwd_common.c
|
||||
@@ -179,16 +179,21 @@
|
||||
int mkhash(struct passwd_ctx *ctx)
|
||||
{
|
||||
char *pw;
|
||||
- char salt[16];
|
||||
+ char salt[17];
|
||||
apr_status_t rv;
|
||||
int ret = 0;
|
||||
#if CRYPT_ALGO_SUPPORTED
|
||||
char *cbuf;
|
||||
#endif
|
||||
+#ifdef HAVE_CRYPT_SHA2
|
||||
+ const char *setting;
|
||||
+ char method;
|
||||
+#endif
|
||||
|
||||
- if (ctx->cost != 0 && ctx->alg != ALG_BCRYPT) {
|
||||
+ if (ctx->cost != 0 && ctx->alg != ALG_BCRYPT
|
||||
+ && ctx->alg != ALG_CRYPT_SHA256 && ctx->alg != ALG_CRYPT_SHA512 ) {
|
||||
apr_file_printf(errfile,
|
||||
- "Warning: Ignoring -C argument for this algorithm." NL);
|
||||
+ "Warning: Ignoring -C/-r argument for this algorithm." NL);
|
||||
}
|
||||
|
||||
if (ctx->passwd == NULL) {
|
||||
@@ -246,6 +251,34 @@
|
||||
break;
|
||||
#endif /* CRYPT_ALGO_SUPPORTED */
|
||||
|
||||
+#ifdef HAVE_CRYPT_SHA2
|
||||
+ case ALG_CRYPT_SHA256:
|
||||
+ case ALG_CRYPT_SHA512:
|
||||
+ ret = generate_salt(salt, 16, &ctx->errstr, ctx->pool);
|
||||
+ if (ret != 0)
|
||||
+ break;
|
||||
+
|
||||
+ method = ctx->alg == ALG_CRYPT_SHA256 ? '5': '6';
|
||||
+
|
||||
+ if (ctx->cost)
|
||||
+ setting = apr_psprintf(ctx->pool, "$%c$rounds=%d$%s",
|
||||
+ method, ctx->cost, salt);
|
||||
+ else
|
||||
+ setting = apr_psprintf(ctx->pool, "$%c$%s",
|
||||
+ method, salt);
|
||||
+
|
||||
+ cbuf = crypt(pw, setting);
|
||||
+ if (cbuf == NULL) {
|
||||
+ rv = APR_FROM_OS_ERROR(errno);
|
||||
+ ctx->errstr = apr_psprintf(ctx->pool, "crypt() failed: %pm", &rv);
|
||||
+ ret = ERR_PWMISMATCH;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ apr_cpystrn(ctx->out, cbuf, ctx->out_len - 1);
|
||||
+ break;
|
||||
+#endif /* HAVE_CRYPT_SHA2 */
|
||||
+
|
||||
#if BCRYPT_ALGO_SUPPORTED
|
||||
case ALG_BCRYPT:
|
||||
rv = apr_generate_random_bytes((unsigned char*)salt, 16);
|
||||
@@ -294,6 +327,19 @@
|
||||
case 's':
|
||||
ctx->alg = ALG_APSHA;
|
||||
break;
|
||||
+#ifdef HAVE_CRYPT_SHA2
|
||||
+ case '2':
|
||||
+ ctx->alg = ALG_CRYPT_SHA256;
|
||||
+ break;
|
||||
+ case '5':
|
||||
+ ctx->alg = ALG_CRYPT_SHA512;
|
||||
+ break;
|
||||
+#else
|
||||
+ case '2':
|
||||
+ case '5':
|
||||
+ ctx->errstr = "SHA-2 crypt() algorithms are not supported on this platform.";
|
||||
+ return ERR_ALG_NOT_SUPP;
|
||||
+#endif
|
||||
case 'p':
|
||||
ctx->alg = ALG_PLAIN;
|
||||
#if !PLAIN_ALGO_SUPPORTED
|
||||
@@ -324,11 +370,12 @@
|
||||
return ERR_ALG_NOT_SUPP;
|
||||
#endif
|
||||
break;
|
||||
- case 'C': {
|
||||
+ case 'C':
|
||||
+ case 'r': {
|
||||
char *endptr;
|
||||
long num = strtol(opt_arg, &endptr, 10);
|
||||
if (*endptr != '\0' || num <= 0) {
|
||||
- ctx->errstr = "argument to -C must be a positive integer";
|
||||
+ ctx->errstr = "argument to -C/-r must be a positive integer";
|
||||
return ERR_SYNTAX;
|
||||
}
|
||||
ctx->cost = num;
|
||||
--- httpd-2.4.43/support/passwd_common.h.r1861793+
|
||||
+++ httpd-2.4.43/support/passwd_common.h
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "apu_version.h"
|
||||
#endif
|
||||
|
||||
+#include "ap_config_auto.h"
|
||||
+
|
||||
#define MAX_STRING_LEN 256
|
||||
|
||||
#define ALG_PLAIN 0
|
||||
@@ -35,6 +37,8 @@
|
||||
#define ALG_APMD5 2
|
||||
#define ALG_APSHA 3
|
||||
#define ALG_BCRYPT 4
|
||||
+#define ALG_CRYPT_SHA256 5
|
||||
+#define ALG_CRYPT_SHA512 6
|
||||
|
||||
#define BCRYPT_DEFAULT_COST 5
|
||||
|
||||
@@ -84,7 +88,7 @@
|
||||
apr_size_t out_len;
|
||||
char *passwd;
|
||||
int alg;
|
||||
- int cost;
|
||||
+ int cost; /* cost for bcrypt, rounds for SHA-2 */
|
||||
enum {
|
||||
PW_PROMPT = 0,
|
||||
PW_ARG,
|
|
@ -1,60 +0,0 @@
|
|||
diff --git a/configure.in b/configure.in
|
||||
index c8f9aa2..cb43246 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -484,6 +484,11 @@ getloadavg
|
||||
dnl confirm that a void pointer is large enough to store a long integer
|
||||
APACHE_CHECK_VOID_PTR_LEN
|
||||
|
||||
+AC_CHECK_LIB(selinux, is_selinux_enabled, [
|
||||
+ AC_DEFINE(HAVE_SELINUX, 1, [Defined if SELinux is supported])
|
||||
+ APR_ADDTO(HTTPD_LIBS, [-lselinux])
|
||||
+])
|
||||
+
|
||||
AC_CACHE_CHECK([for gettid()], ac_cv_gettid,
|
||||
[AC_TRY_RUN(#define _GNU_SOURCE
|
||||
#include <unistd.h>
|
||||
diff --git a/server/core.c b/server/core.c
|
||||
index dc0f17a..7ed9527 100644
|
||||
--- a/server/core.c
|
||||
+++ b/server/core.c
|
||||
@@ -59,6 +59,10 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_SELINUX
|
||||
+#include <selinux/selinux.h>
|
||||
+#endif
|
||||
+
|
||||
/* LimitRequestBody handling */
|
||||
#define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1)
|
||||
#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0)
|
||||
@@ -5015,6 +5019,28 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
|
||||
}
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_SELINUX
|
||||
+ {
|
||||
+ static int already_warned = 0;
|
||||
+ int is_enabled = is_selinux_enabled() > 0;
|
||||
+
|
||||
+ if (is_enabled && !already_warned) {
|
||||
+ security_context_t con;
|
||||
+
|
||||
+ if (getcon(&con) == 0) {
|
||||
+
|
||||
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
|
||||
+ "SELinux policy enabled; "
|
||||
+ "httpd running as context %s", con);
|
||||
+
|
||||
+ already_warned = 1;
|
||||
+
|
||||
+ freecon(con);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -1,300 +0,0 @@
|
|||
diff --git a/server/listen.c b/server/listen.c
|
||||
index 5242c2a..e2e028a 100644
|
||||
--- a/server/listen.c
|
||||
+++ b/server/listen.c
|
||||
@@ -34,6 +34,10 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+#include <systemd/sd-daemon.h>
|
||||
+#endif
|
||||
+
|
||||
/* we know core's module_index is 0 */
|
||||
#undef APLOG_MODULE_INDEX
|
||||
#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
|
||||
@@ -59,9 +63,12 @@ static int ap_listenbacklog;
|
||||
static int ap_listencbratio;
|
||||
static int send_buffer_size;
|
||||
static int receive_buffer_size;
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+static int use_systemd = -1;
|
||||
+#endif
|
||||
|
||||
/* TODO: make_sock is just begging and screaming for APR abstraction */
|
||||
-static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
|
||||
+static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_listen)
|
||||
{
|
||||
apr_socket_t *s = server->sd;
|
||||
int one = 1;
|
||||
@@ -94,20 +101,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
|
||||
return stat;
|
||||
}
|
||||
|
||||
-#if APR_HAVE_IPV6
|
||||
- if (server->bind_addr->family == APR_INET6) {
|
||||
- stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting);
|
||||
- if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
|
||||
- ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069)
|
||||
- "make_sock: for address %pI, apr_socket_opt_set: "
|
||||
- "(IPV6_V6ONLY)",
|
||||
- server->bind_addr);
|
||||
- apr_socket_close(s);
|
||||
- return stat;
|
||||
- }
|
||||
- }
|
||||
-#endif
|
||||
-
|
||||
/*
|
||||
* To send data over high bandwidth-delay connections at full
|
||||
* speed we must force the TCP window to open wide enough to keep the
|
||||
@@ -169,21 +162,37 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
|
||||
}
|
||||
#endif
|
||||
|
||||
- if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
|
||||
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072)
|
||||
- "make_sock: could not bind to address %pI",
|
||||
- server->bind_addr);
|
||||
- apr_socket_close(s);
|
||||
- return stat;
|
||||
- }
|
||||
+ if (do_bind_listen) {
|
||||
+#if APR_HAVE_IPV6
|
||||
+ if (server->bind_addr->family == APR_INET6) {
|
||||
+ stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting);
|
||||
+ if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) {
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069)
|
||||
+ "make_sock: for address %pI, apr_socket_opt_set: "
|
||||
+ "(IPV6_V6ONLY)",
|
||||
+ server->bind_addr);
|
||||
+ apr_socket_close(s);
|
||||
+ return stat;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
- if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
|
||||
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073)
|
||||
- "make_sock: unable to listen for connections "
|
||||
- "on address %pI",
|
||||
- server->bind_addr);
|
||||
- apr_socket_close(s);
|
||||
- return stat;
|
||||
+ if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) {
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072)
|
||||
+ "make_sock: could not bind to address %pI",
|
||||
+ server->bind_addr);
|
||||
+ apr_socket_close(s);
|
||||
+ return stat;
|
||||
+ }
|
||||
+
|
||||
+ if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) {
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073)
|
||||
+ "make_sock: unable to listen for connections "
|
||||
+ "on address %pI",
|
||||
+ server->bind_addr);
|
||||
+ apr_socket_close(s);
|
||||
+ return stat;
|
||||
+ }
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
@@ -315,6 +324,123 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
|
||||
return found;
|
||||
}
|
||||
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+
|
||||
+static int find_systemd_socket(process_rec * process, apr_port_t port) {
|
||||
+ int fdcount, fd;
|
||||
+ int sdc = sd_listen_fds(0);
|
||||
+
|
||||
+ if (sdc < 0) {
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486)
|
||||
+ "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d",
|
||||
+ sdc);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (sdc == 0) {
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487)
|
||||
+ "find_systemd_socket: At least one socket must be set.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ fdcount = atoi(getenv("LISTEN_FDS"));
|
||||
+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) {
|
||||
+ if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) {
|
||||
+ return fd;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static apr_status_t alloc_systemd_listener(process_rec * process,
|
||||
+ int fd, const char *proto,
|
||||
+ ap_listen_rec **out_rec)
|
||||
+{
|
||||
+ apr_status_t rv;
|
||||
+ struct sockaddr sa;
|
||||
+ socklen_t len = sizeof(struct sockaddr);
|
||||
+ apr_os_sock_info_t si;
|
||||
+ ap_listen_rec *rec;
|
||||
+ *out_rec = NULL;
|
||||
+
|
||||
+ memset(&si, 0, sizeof(si));
|
||||
+
|
||||
+ rv = getsockname(fd, &sa, &len);
|
||||
+
|
||||
+ if (rv != 0) {
|
||||
+ rv = apr_get_netos_error();
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02489)
|
||||
+ "getsockname on %d failed.", fd);
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ si.os_sock = &fd;
|
||||
+ si.family = sa.sa_family;
|
||||
+ si.local = &sa;
|
||||
+ si.type = SOCK_STREAM;
|
||||
+ si.protocol = APR_PROTO_TCP;
|
||||
+
|
||||
+ rec = apr_palloc(process->pool, sizeof(ap_listen_rec));
|
||||
+ rec->active = 0;
|
||||
+ rec->next = 0;
|
||||
+
|
||||
+
|
||||
+ rv = apr_os_sock_make(&rec->sd, &si, process->pool);
|
||||
+ if (rv != APR_SUCCESS) {
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02490)
|
||||
+ "apr_os_sock_make on %d failed.", fd);
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ rv = apr_socket_addr_get(&rec->bind_addr, APR_LOCAL, rec->sd);
|
||||
+ if (rv != APR_SUCCESS) {
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02491)
|
||||
+ "apr_socket_addr_get on %d failed.", fd);
|
||||
+ return rv;
|
||||
+ }
|
||||
+
|
||||
+ rec->protocol = apr_pstrdup(process->pool, proto);
|
||||
+
|
||||
+ *out_rec = rec;
|
||||
+
|
||||
+ return make_sock(process->pool, rec, 0);
|
||||
+}
|
||||
+
|
||||
+static const char *set_systemd_listener(process_rec *process, apr_port_t port,
|
||||
+ const char *proto)
|
||||
+{
|
||||
+ ap_listen_rec *last, *new;
|
||||
+ apr_status_t rv;
|
||||
+ int fd = find_systemd_socket(process, port);
|
||||
+ if (fd < 0) {
|
||||
+ return "Systemd socket activation is used, but this port is not "
|
||||
+ "configured in systemd";
|
||||
+ }
|
||||
+
|
||||
+ last = ap_listeners;
|
||||
+ while (last && last->next) {
|
||||
+ last = last->next;
|
||||
+ }
|
||||
+
|
||||
+ rv = alloc_systemd_listener(process, fd, proto, &new);
|
||||
+ if (rv != APR_SUCCESS) {
|
||||
+ return "Failed to setup socket passed by systemd using socket activation";
|
||||
+ }
|
||||
+
|
||||
+ if (last == NULL) {
|
||||
+ ap_listeners = last = new;
|
||||
+ }
|
||||
+ else {
|
||||
+ last->next = new;
|
||||
+ last = new;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+#endif /* HAVE_SYSTEMD */
|
||||
+
|
||||
static const char *alloc_listener(process_rec *process, const char *addr,
|
||||
apr_port_t port, const char* proto,
|
||||
void *slave)
|
||||
@@ -495,7 +621,7 @@ static int open_listeners(apr_pool_t *pool)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
- if (make_sock(pool, lr) == APR_SUCCESS) {
|
||||
+ if (make_sock(pool, lr, 1) == APR_SUCCESS) {
|
||||
++num_open;
|
||||
}
|
||||
else {
|
||||
@@ -607,8 +733,28 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
|
||||
}
|
||||
}
|
||||
|
||||
- if (open_listeners(s->process->pool)) {
|
||||
- return 0;
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+ if (use_systemd) {
|
||||
+ const char *userdata_key = "ap_open_systemd_listeners";
|
||||
+ void *data;
|
||||
+ /* clear the enviroment on our second run
|
||||
+ * so that none of our future children get confused.
|
||||
+ */
|
||||
+ apr_pool_userdata_get(&data, userdata_key, s->process->pool);
|
||||
+ if (!data) {
|
||||
+ apr_pool_userdata_set((const void *)1, userdata_key,
|
||||
+ apr_pool_cleanup_null, s->process->pool);
|
||||
+ }
|
||||
+ else {
|
||||
+ sd_listen_fds(1);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ {
|
||||
+ if (open_listeners(s->process->pool)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
|
||||
for (lr = ap_listeners; lr; lr = lr->next) {
|
||||
@@ -698,7 +844,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
|
||||
duplr->bind_addr);
|
||||
return stat;
|
||||
}
|
||||
- make_sock(p, duplr);
|
||||
+ make_sock(p, duplr, 1);
|
||||
#if AP_NONBLOCK_WHEN_MULTI_LISTEN
|
||||
use_nonblock = (ap_listeners && ap_listeners->next);
|
||||
stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock);
|
||||
@@ -825,6 +971,11 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
|
||||
if (argc < 1 || argc > 2) {
|
||||
return "Listen requires 1 or 2 arguments.";
|
||||
}
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+ if (use_systemd == -1) {
|
||||
+ use_systemd = sd_listen_fds(0) > 0;
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool);
|
||||
if (rv != APR_SUCCESS) {
|
||||
@@ -856,6 +1007,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
|
||||
ap_str_tolower(proto);
|
||||
}
|
||||
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+ if (use_systemd) {
|
||||
+ return set_systemd_listener(cmd->server->process, port, proto);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
return alloc_listener(cmd->server->process, host, port, proto, NULL);
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
|
||||
index 97778a8..27e7a53 100644
|
||||
--- a/modules/ssl/ssl_engine_config.c
|
||||
+++ b/modules/ssl/ssl_engine_config.c
|
||||
@@ -778,9 +778,11 @@ const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
|
||||
}
|
||||
|
||||
if (!strcmp("SSL", arg1)) {
|
||||
- /* always disable null and export ciphers */
|
||||
- arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
|
||||
if (cmd->path) {
|
||||
+ /* Disable null and export ciphers by default, except for PROFILE=
|
||||
+ * configs where the parser doesn't cope. */
|
||||
+ if (strncmp(arg2, "PROFILE=", 8) != 0)
|
||||
+ arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
|
||||
dc->szCipherSuite = arg2;
|
||||
}
|
||||
else {
|
||||
@@ -1544,8 +1546,10 @@ const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
|
||||
}
|
||||
|
||||
if (!strcmp("SSL", arg1)) {
|
||||
- /* always disable null and export ciphers */
|
||||
- arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
|
||||
+ /* Disable null and export ciphers by default, except for PROFILE=
|
||||
+ * configs where the parser doesn't cope. */
|
||||
+ if (strncmp(arg2, "PROFILE=", 8) != 0)
|
||||
+ arg2 = apr_pstrcat(cmd->pool, arg2, ":!aNULL:!eNULL:!EXP", NULL);
|
||||
dc->proxy->auth.cipher_suite = arg2;
|
||||
return NULL;
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
|
||||
index 27e7a53..b53f3f8 100644
|
||||
--- a/modules/ssl/ssl_engine_config.c
|
||||
+++ b/modules/ssl/ssl_engine_config.c
|
||||
@@ -119,7 +119,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p)
|
||||
mctx->ticket_key = NULL;
|
||||
#endif
|
||||
|
||||
- mctx->protocol = SSL_PROTOCOL_DEFAULT;
|
||||
+ mctx->protocol = SSL_PROTOCOL_NONE;
|
||||
mctx->protocol_set = 0;
|
||||
|
||||
mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET;
|
||||
@@ -263,6 +263,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p,
|
||||
if (add->protocol_set) {
|
||||
mrg->protocol_set = 1;
|
||||
mrg->protocol = add->protocol;
|
||||
+ mrg->protocol_set = 1;
|
||||
}
|
||||
else {
|
||||
mrg->protocol_set = base->protocol_set;
|
||||
|
||||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index bfad47a..b0fcf81 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -577,6 +577,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
MODSSL_SSL_METHOD_CONST SSL_METHOD *method = NULL;
|
||||
char *cp;
|
||||
int protocol = mctx->protocol;
|
||||
+ int protocol_set = mctx->protocol_set;
|
||||
SSLSrvConfigRec *sc = mySrvConfig(s);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
int prot;
|
||||
@@ -586,12 +587,18 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
* Create the new per-server SSL context
|
||||
*/
|
||||
if (protocol == SSL_PROTOCOL_NONE) {
|
||||
- ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231)
|
||||
- "No SSL protocols available [hint: SSLProtocol]");
|
||||
- return ssl_die(s);
|
||||
- }
|
||||
+ if (protocol_set) {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231)
|
||||
+ "No SSL protocols available [hint: SSLProtocol]");
|
||||
+ return ssl_die(s);
|
||||
+ }
|
||||
|
||||
- cp = apr_pstrcat(p,
|
||||
+ ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
|
||||
+ "Using OpenSSL/system default SSL/TLS protocols");
|
||||
+ cp = "default";
|
||||
+ }
|
||||
+ else {
|
||||
+ cp = apr_pstrcat(p,
|
||||
#ifndef OPENSSL_NO_SSL3
|
||||
(protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
|
||||
#endif
|
||||
@@ -604,7 +611,8 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
#endif
|
||||
#endif
|
||||
NULL);
|
||||
- cp[strlen(cp)-2] = NUL;
|
||||
+ cp[strlen(cp)-2] = NUL;
|
||||
+ }
|
||||
|
||||
ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
|
||||
"Creating new SSL context (protocols: %s)", cp);
|
||||
@@ -705,13 +713,15 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
prot = SSL3_VERSION;
|
||||
#endif
|
||||
} else {
|
||||
- SSL_CTX_free(ctx);
|
||||
- mctx->ssl_ctx = NULL;
|
||||
- ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(03378)
|
||||
- "No SSL protocols available [hint: SSLProtocol]");
|
||||
- return ssl_die(s);
|
||||
+ if (protocol_set) {
|
||||
+ SSL_CTX_free(ctx);
|
||||
+ mctx->ssl_ctx = NULL;
|
||||
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(03378)
|
||||
+ "No SSL protocols available [hint: SSLProtocol]");
|
||||
+ return ssl_die(s);
|
||||
+ }
|
||||
}
|
||||
- SSL_CTX_set_max_proto_version(ctx, prot);
|
||||
+ if (protocol != SSL_PROTOCOL_NONE) SSL_CTX_set_max_proto_version(ctx, prot);
|
||||
|
||||
/* Next we scan for the minimal protocol version we should provide,
|
||||
* but we do not allow holes between max and min */
|
||||
@@ -731,7 +741,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
prot = SSL3_VERSION;
|
||||
}
|
||||
#endif
|
||||
- SSL_CTX_set_min_proto_version(ctx, prot);
|
||||
+ if (protocol != SSL_PROTOCOL_NONE) SSL_CTX_set_min_proto_version(ctx, prot);
|
||||
#endif /* if OPENSSL_VERSION_NUMBER < 0x10100000L */
|
||||
|
||||
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
|
|
@ -1,124 +0,0 @@
|
|||
diff --git a/docs/manual/mod/mpm_common.html.en b/docs/manual/mod/mpm_common.html.en
|
||||
index e7af21d..01d54b7 100644
|
||||
--- a/docs/manual/mod/mpm_common.html.en
|
||||
+++ b/docs/manual/mod/mpm_common.html.en
|
||||
@@ -42,6 +42,7 @@ more than one multi-processing module (MPM)</td></tr>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#enableexceptionhook">EnableExceptionHook</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#gracefulshutdowntimeout">GracefulShutdownTimeout</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#listen">Listen</a></li>
|
||||
+<li><img alt="" src="../images/down.gif" /> <a href="#listenfree">ListenFree</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#listenbacklog">ListenBackLog</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#listencoresbucketsratio">ListenCoresBucketsRatio</a></li>
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#maxconnectionsperchild">MaxConnectionsPerChild</a></li>
|
||||
@@ -244,6 +245,31 @@ discussion of the <code>Address already in use</code> error message,
|
||||
including other causes.</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
+
|
||||
+<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
+<div class="directive-section"><h2><a name="ListenFree" id="ListenFree">ListenFree</a> <a name="listenfree" id="listenfree">Directive</a></h2>
|
||||
+<table class="directive">
|
||||
+<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>IP addresses and ports that the server
|
||||
+listens to. Doesn't require IP address to be up</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>ListenFree [<var>IP-address</var>:]<var>portnumber</var> [<var>protocol</var>]</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>MPM</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td><code class="module"><a href="../mod/event.html">event</a></code>, <code class="module"><a href="../mod/worker.html">worker</a></code>, <code class="module"><a href="../mod/prefork.html">prefork</a></code>, <code class="module"><a href="../mod/mpm_winnt.html">mpm_winnt</a></code>, <code class="module"><a href="../mod/mpm_netware.html">mpm_netware</a></code>, <code class="module"><a href="../mod/mpmt_os2.html">mpmt_os2</a></code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>This directive is currently available only in Red Hat Enterprise Linux</td></tr>
|
||||
+</table>
|
||||
+ <p>The <code class="directive">ListenFree</code> directive is
|
||||
+ identical to the <code class="directive">Listen</code> directive.
|
||||
+ The only difference is in the usage of the IP_FREEBIND socket
|
||||
+ option, which is enabled by default with <code class="directive">ListenFree</code>.
|
||||
+ If IP_FREEBIND is enabled, it allows httpd to bind to an IP
|
||||
+ address that is nonlocal or does not (yet) exist. This allows httpd to
|
||||
+ listen on a socket without requiring the underlying network interface
|
||||
+ or the specified dynamic IP address to be up at the time when httpd
|
||||
+ is trying to bind to it.
|
||||
+ </p>
|
||||
+</div>
|
||||
+
|
||||
+
|
||||
<div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
<div class="directive-section"><h2><a name="ListenBackLog" id="ListenBackLog">ListenBackLog</a> <a name="listenbacklog" id="listenbacklog">Directive</a></h2>
|
||||
<table class="directive">
|
||||
diff --git a/include/ap_listen.h b/include/ap_listen.h
|
||||
index 58c2574..1a53292 100644
|
||||
--- a/include/ap_listen.h
|
||||
+++ b/include/ap_listen.h
|
||||
@@ -137,6 +137,9 @@ AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy
|
||||
AP_DECLARE_NONSTD(const char *) ap_set_listencbratio(cmd_parms *cmd, void *dummy, const char *arg);
|
||||
AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
|
||||
int argc, char *const argv[]);
|
||||
+AP_DECLARE_NONSTD(const char *) ap_set_freelistener(cmd_parms *cmd, void *dummy,
|
||||
+ int argc, char *const argv[]);
|
||||
+
|
||||
AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, void *dummy,
|
||||
const char *arg);
|
||||
AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd,
|
||||
@@ -150,6 +153,8 @@ AP_INIT_TAKE1("ListenCoresBucketsRatio", ap_set_listencbratio, NULL, RSRC_CONF,
|
||||
"Ratio between the number of CPU cores (online) and the number of listeners buckets"), \
|
||||
AP_INIT_TAKE_ARGV("Listen", ap_set_listener, NULL, RSRC_CONF, \
|
||||
"A port number or a numeric IP address and a port number, and an optional protocol"), \
|
||||
+AP_INIT_TAKE_ARGV("ListenFree", ap_set_freelistener, NULL, RSRC_CONF, \
|
||||
+ "A port number or a numeric IP address and a port number, and an optional protocol"), \
|
||||
AP_INIT_TAKE1("SendBufferSize", ap_set_send_buffer_size, NULL, RSRC_CONF, \
|
||||
"Send buffer size in bytes"), \
|
||||
AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \
|
||||
diff --git a/server/listen.c b/server/listen.c
|
||||
index e2e028a..6ef664b 100644
|
||||
--- a/server/listen.c
|
||||
+++ b/server/listen.c
|
||||
@@ -63,6 +63,7 @@ static int ap_listenbacklog;
|
||||
static int ap_listencbratio;
|
||||
static int send_buffer_size;
|
||||
static int receive_buffer_size;
|
||||
+static int ap_listenfreebind;
|
||||
#ifdef HAVE_SYSTEMD
|
||||
static int use_systemd = -1;
|
||||
#endif
|
||||
@@ -162,6 +163,21 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_
|
||||
}
|
||||
#endif
|
||||
|
||||
+
|
||||
+#if defined(APR_SO_FREEBIND)
|
||||
+ if (ap_listenfreebind) {
|
||||
+ if (apr_socket_opt_set(s, APR_SO_FREEBIND, one) < 0) {
|
||||
+ stat = apr_get_netos_error();
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(02182)
|
||||
+ "make_sock: apr_socket_opt_set: "
|
||||
+ "error setting APR_SO_FREEBIND");
|
||||
+ apr_socket_close(s);
|
||||
+ return stat;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
if (do_bind_listen) {
|
||||
#if APR_HAVE_IPV6
|
||||
if (server->bind_addr->family == APR_INET6) {
|
||||
@@ -956,6 +972,7 @@ AP_DECLARE(void) ap_listen_pre_config(void)
|
||||
}
|
||||
}
|
||||
|
||||
+
|
||||
AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
|
||||
int argc, char *const argv[])
|
||||
{
|
||||
@@ -1016,6 +1033,14 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
|
||||
return alloc_listener(cmd->server->process, host, port, proto, NULL);
|
||||
}
|
||||
|
||||
+AP_DECLARE_NONSTD(const char *) ap_set_freelistener(cmd_parms *cmd, void *dummy,
|
||||
+ int argc,
|
||||
+ char *const argv[])
|
||||
+{
|
||||
+ ap_listenfreebind = 1;
|
||||
+ return ap_set_listener(cmd, dummy, argc, argv);
|
||||
+}
|
||||
+
|
||||
AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd,
|
||||
void *dummy,
|
||||
const char *arg)
|
|
@ -1,13 +0,0 @@
|
|||
diff --git a/support/htcacheclean.c b/support/htcacheclean.c
|
||||
index 958ba6d..0a7fe3c 100644
|
||||
--- a/support/htcacheclean.c
|
||||
+++ b/support/htcacheclean.c
|
||||
@@ -557,8 +557,6 @@ static int list_urls(char *path, apr_pool_t *pool, apr_off_t round)
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
- break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
|
||||
Reduce size of httpd binary by telling linker to export all symbols
|
||||
from libmain.a, rather than bloating the symbol table with ap_hack_*
|
||||
to do so indirectly.
|
||||
|
||||
Upstream: https://svn.apache.org/r1861685 (as new default-off configure option)
|
||||
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index 40c7076..ac98e5f 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -4,8 +4,15 @@ CLEAN_SUBDIRS = test
|
||||
|
||||
PROGRAM_NAME = $(progname)
|
||||
PROGRAM_SOURCES = modules.c
|
||||
-PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
|
||||
+PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) \
|
||||
+ $(PROGRAM_LDDEPS) \
|
||||
+ $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
|
||||
PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c
|
||||
+PROGRAM_LDDEPS = \
|
||||
+ $(BUILTIN_LIBS) \
|
||||
+ $(MPM_LIB) \
|
||||
+ -Wl,--whole-archive,server/.libs/libmain.a,--no-whole-archive \
|
||||
+ os/$(OS_DIR)/libos.la
|
||||
PROGRAM_DEPENDENCIES = \
|
||||
server/libmain.la \
|
||||
$(BUILTIN_LIBS) \
|
||||
diff --git a/server/Makefile.in b/server/Makefile.in
|
||||
index 8111877..f00bb3f 100644
|
||||
--- a/server/Makefile.in
|
||||
+++ b/server/Makefile.in
|
||||
@@ -12,7 +12,7 @@ LTLIBRARY_SOURCES = \
|
||||
connection.c listen.c util_mutex.c \
|
||||
mpm_common.c mpm_unix.c mpm_fdqueue.c \
|
||||
util_charset.c util_cookies.c util_debug.c util_xml.c \
|
||||
- util_filter.c util_pcre.c util_regex.c exports.c \
|
||||
+ util_filter.c util_pcre.c util_regex.c \
|
||||
scoreboard.c error_bucket.c protocol.c core.c request.c ssl.c provider.c \
|
||||
eoc_bucket.c eor_bucket.c core_filters.c \
|
||||
util_expr_parse.c util_expr_scan.c util_expr_eval.c
|
||||
diff --git a/server/main.c b/server/main.c
|
||||
index 62e06df..17c09ee 100644
|
||||
--- a/server/main.c
|
||||
+++ b/server/main.c
|
||||
@@ -835,17 +835,3 @@ int main(int argc, const char * const argv[])
|
||||
return !OK;
|
||||
}
|
||||
|
||||
-#ifdef AP_USING_AUTOCONF
|
||||
-/* This ugly little hack pulls any function referenced in exports.c into
|
||||
- * the web server. exports.c is generated during the build, and it
|
||||
- * has all of the APR functions specified by the apr/apr.exports and
|
||||
- * apr-util/aprutil.exports files.
|
||||
- */
|
||||
-const void *ap_suck_in_APR(void);
|
||||
-const void *ap_suck_in_APR(void)
|
||||
-{
|
||||
- extern const void *ap_ugly_hack;
|
||||
-
|
||||
- return ap_ugly_hack;
|
||||
-}
|
||||
-#endif
|
|
@ -1,46 +0,0 @@
|
|||
diff --git a/server/core.c b/server/core.c
|
||||
index c36ff26..621c82a 100644
|
||||
--- a/server/core.c
|
||||
+++ b/server/core.c
|
||||
@@ -3569,6 +3569,7 @@ enum server_token_type {
|
||||
SrvTk_MINIMAL, /* eg: Apache/2.0.41 */
|
||||
SrvTk_OS, /* eg: Apache/2.0.41 (UNIX) */
|
||||
SrvTk_FULL, /* eg: Apache/2.0.41 (UNIX) PHP/4.2.2 FooBar/1.2b */
|
||||
+ SrvTk_FULL_RELEASE, /* eg: Apache/2.0.41 (UNIX) (Release 32.el7) PHP/4.2.2 FooBar/1.2b */
|
||||
SrvTk_PRODUCT_ONLY /* eg: Apache */
|
||||
};
|
||||
static enum server_token_type ap_server_tokens = SrvTk_FULL;
|
||||
@@ -3645,7 +3646,10 @@ static void set_banner(apr_pool_t *pconf)
|
||||
else if (ap_server_tokens == SrvTk_MAJOR) {
|
||||
ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT "/" AP_SERVER_MAJORVERSION);
|
||||
}
|
||||
- else {
|
||||
+ else if (ap_server_tokens == SrvTk_FULL_RELEASE) {
|
||||
+ ap_add_version_component(pconf, AP_SERVER_BASEVERSION " (" PLATFORM ") (Release @RELEASE@)");
|
||||
+ }
|
||||
+ else {
|
||||
ap_add_version_component(pconf, AP_SERVER_BASEVERSION " (" PLATFORM ")");
|
||||
}
|
||||
|
||||
@@ -3653,7 +3657,7 @@ static void set_banner(apr_pool_t *pconf)
|
||||
* Lock the server_banner string if we're not displaying
|
||||
* the full set of tokens
|
||||
*/
|
||||
- if (ap_server_tokens != SrvTk_FULL) {
|
||||
+ if (ap_server_tokens != SrvTk_FULL && ap_server_tokens != SrvTk_FULL_RELEASE) {
|
||||
banner_locked++;
|
||||
}
|
||||
server_description = AP_SERVER_BASEVERSION " (" PLATFORM ")";
|
||||
@@ -3686,8 +3690,11 @@ static const char *set_serv_tokens(cmd_parms *cmd, void *dummy,
|
||||
else if (!ap_cstr_casecmp(arg, "Full")) {
|
||||
ap_server_tokens = SrvTk_FULL;
|
||||
}
|
||||
+ else if (!strcasecmp(arg, "Full-Release")) {
|
||||
+ ap_server_tokens = SrvTk_FULL_RELEASE;
|
||||
+ }
|
||||
else {
|
||||
- return "ServerTokens takes 1 argument: 'Prod(uctOnly)', 'Major', 'Minor', 'Min(imal)', 'OS', or 'Full'";
|
||||
+ return "ServerTokens takes 1 argument: 'Prod(uctOnly)', 'Major', 'Minor', 'Min(imal)', 'OS', 'Full' or 'Full-Release'";
|
||||
}
|
||||
|
||||
return NULL;
|
|
@ -1,109 +0,0 @@
|
|||
diff --git a/docs/manual/mod/mod_proxy_wstunnel.html.en b/docs/manual/mod/mod_proxy_wstunnel.html.en
|
||||
index 9f2c120..61ff7de 100644
|
||||
--- a/docs/manual/mod/mod_proxy_wstunnel.html.en
|
||||
+++ b/docs/manual/mod/mod_proxy_wstunnel.html.en
|
||||
@@ -83,6 +83,7 @@ in the response <code>Upgrade</code></p>
|
||||
<div id="quickview"><a href="https://www.apache.org/foundation/contributing.html" class="badge"><img src="https://www.apache.org/images/SupportApache-small.png" alt="Support Apache!" /></a><h3 class="directives">Directives</h3>
|
||||
<ul id="toc">
|
||||
<li><img alt="" src="../images/down.gif" /> <a href="#proxywebsocketfallbacktoproxyhttp">ProxyWebsocketFallbackToProxyHttp</a></li>
|
||||
+<li><img alt="" src="../images/down.gif" /> <a href="#proxywebsocketidletimeout">ProxyWebsocketIdleTimeout</a></li>
|
||||
</ul>
|
||||
<h3>Bugfix checklist</h3><ul class="seealso"><li><a href="https://www.apache.org/dist/httpd/CHANGES_2.4">httpd changelog</a></li><li><a href="https://bz.apache.org/bugzilla/buglist.cgi?bug_status=__open__&list_id=144532&product=Apache%20httpd-2&query_format=specific&order=changeddate%20DESC%2Cpriority%2Cbug_severity&component=mod_proxy_wstunnel">Known issues</a></li><li><a href="https://bz.apache.org/bugzilla/enter_bug.cgi?product=Apache%20httpd-2&component=mod_proxy_wstunnel">Report a bug</a></li></ul><h3>See also</h3>
|
||||
<ul class="seealso">
|
||||
@@ -108,6 +109,23 @@ in the response <code>Upgrade</code></p>
|
||||
WebSocket requests as in httpd 2.4.46 and earlier.</p>
|
||||
|
||||
</div>
|
||||
+
|
||||
+<div class="directive-section"><h2><a name="ProxyWebsocketIdleTimeout" id="ProxyWebsocketIdleTimeout">ProxyWebsocketIdleTimeout</a> <a name="proxywebsocketidletimeout" id="proxywebsocketidletimeout">Directive</a> <a title="Permanent link" href="#proxywebsocketidletimeout" class="permalink">¶</a></h2>
|
||||
+<table class="directive">
|
||||
+<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Sets the maximum amount of time to wait for data on the websockets tunnel</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>ProxyWebsocketIdleTimeout <var>num</var>[ms]</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>ProxyWebsocketIdleTimeout 0</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Extension</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>mod_proxy_wstunnel</td></tr>
|
||||
+</table>
|
||||
+ <p>This directive imposes a maximum amount of time for the tunnel to be
|
||||
+ left open while idle. The timeout is considered in seconds by default, but
|
||||
+ it is possible to increase the time resolution to milliseconds
|
||||
+ adding the <em>ms</em> suffix.</p>
|
||||
+
|
||||
+</div>
|
||||
+
|
||||
</div>
|
||||
<div class="bottomlang">
|
||||
<p><span>Available Languages: </span><a href="../en/mod/mod_proxy_wstunnel.html" title="English"> en </a> |
|
||||
diff --git a/modules/proxy/mod_proxy_wstunnel.c b/modules/proxy/mod_proxy_wstunnel.c
|
||||
index bcbba42..c29ded1 100644
|
||||
--- a/modules/proxy/mod_proxy_wstunnel.c
|
||||
+++ b/modules/proxy/mod_proxy_wstunnel.c
|
||||
@@ -22,6 +22,7 @@ module AP_MODULE_DECLARE_DATA proxy_wstunnel_module;
|
||||
typedef struct {
|
||||
unsigned int fallback_to_proxy_http :1,
|
||||
fallback_to_proxy_http_set :1;
|
||||
+ apr_time_t idle_timeout;
|
||||
} proxyws_dir_conf;
|
||||
|
||||
static int can_fallback_to_proxy_http;
|
||||
@@ -152,6 +153,8 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
|
||||
conn_rec *c = r->connection;
|
||||
apr_socket_t *sock = conn->sock;
|
||||
conn_rec *backconn = conn->connection;
|
||||
+ proxyws_dir_conf *dconf = ap_get_module_config(r->per_dir_config,
|
||||
+ &proxy_wstunnel_module);
|
||||
char *buf;
|
||||
apr_bucket_brigade *header_brigade;
|
||||
apr_bucket *e;
|
||||
@@ -229,10 +232,13 @@ static int proxy_wstunnel_request(apr_pool_t *p, request_rec *r,
|
||||
c->keepalive = AP_CONN_CLOSE;
|
||||
|
||||
do { /* Loop until done (one side closes the connection, or an error) */
|
||||
- rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled);
|
||||
+ rv = apr_pollset_poll(pollset, dconf->idle_timeout, &pollcnt, &signalled);
|
||||
if (rv != APR_SUCCESS) {
|
||||
if (APR_STATUS_IS_EINTR(rv)) {
|
||||
continue;
|
||||
+ } else if(APR_STATUS_IS_TIMEUP(rv)){
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, "RH: the connection has timed out");
|
||||
+ return HTTP_REQUEST_TIME_OUT;
|
||||
}
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02444) "error apr_poll()");
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
@@ -418,11 +424,26 @@ cleanup:
|
||||
return status;
|
||||
}
|
||||
|
||||
+static const char * proxyws_set_idle(cmd_parms *cmd, void *conf, const char *val)
|
||||
+{
|
||||
+ proxyws_dir_conf *dconf = conf;
|
||||
+ if (ap_timeout_parameter_parse(val, &(dconf->idle_timeout), "s") != APR_SUCCESS)
|
||||
+ return "ProxyWebsocketIdleTimeout timeout has wrong format";
|
||||
+
|
||||
+ if (dconf->idle_timeout < 0)
|
||||
+ return "ProxyWebsocketIdleTimeout timeout has to be a non-negative number";
|
||||
+
|
||||
+ if (!dconf->idle_timeout) dconf->idle_timeout = -1; /* loop indefinitely */
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static void *create_proxyws_dir_config(apr_pool_t *p, char *dummy)
|
||||
{
|
||||
proxyws_dir_conf *new =
|
||||
(proxyws_dir_conf *) apr_pcalloc(p, sizeof(proxyws_dir_conf));
|
||||
|
||||
+ new->idle_timeout = -1; /* no timeout */
|
||||
new->fallback_to_proxy_http = 1;
|
||||
|
||||
return (void *) new;
|
||||
@@ -465,7 +486,8 @@ static const command_rec ws_proxy_cmds[] =
|
||||
proxyws_fallback_to_proxy_http, NULL, RSRC_CONF|ACCESS_CONF,
|
||||
"whether to let mod_proxy_http handle the upgrade and tunneling, "
|
||||
"On by default"),
|
||||
-
|
||||
+ AP_INIT_TAKE1("ProxyWebsocketIdleTimeout", proxyws_set_idle, NULL, RSRC_CONF|ACCESS_CONF,
|
||||
+ "timeout for activity in either direction, unlimited by default."),
|
||||
{NULL}
|
||||
};
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index 4e2e80d..10a2c86 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -2256,51 +2256,6 @@ int ssl_proxy_section_post_config(apr_pool_t *p, apr_pool_t *plog,
|
||||
return OK;
|
||||
}
|
||||
|
||||
-static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a,
|
||||
- const X509_NAME * const *b)
|
||||
-{
|
||||
- return(X509_NAME_cmp(*a, *b));
|
||||
-}
|
||||
-
|
||||
-static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list,
|
||||
- server_rec *s, apr_pool_t *ptemp,
|
||||
- const char *file)
|
||||
-{
|
||||
- int n;
|
||||
- STACK_OF(X509_NAME) *sk;
|
||||
-
|
||||
- sk = (STACK_OF(X509_NAME) *)
|
||||
- SSL_load_client_CA_file(file);
|
||||
-
|
||||
- if (!sk) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- for (n = 0; n < sk_X509_NAME_num(sk); n++) {
|
||||
- X509_NAME *name = sk_X509_NAME_value(sk, n);
|
||||
-
|
||||
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02209)
|
||||
- "CA certificate: %s",
|
||||
- modssl_X509_NAME_to_string(ptemp, name, 0));
|
||||
-
|
||||
- /*
|
||||
- * note that SSL_load_client_CA_file() checks for duplicates,
|
||||
- * but since we call it multiple times when reading a directory
|
||||
- * we must also check for duplicates ourselves.
|
||||
- */
|
||||
-
|
||||
- if (sk_X509_NAME_find(ca_list, name) < 0) {
|
||||
- /* this will be freed when ca_list is */
|
||||
- sk_X509_NAME_push(ca_list, name);
|
||||
- }
|
||||
- else {
|
||||
- /* need to free this ourselves, else it will leak */
|
||||
- X509_NAME_free(name);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- sk_X509_NAME_free(sk);
|
||||
-}
|
||||
|
||||
static apr_status_t ssl_init_ca_cert_path(server_rec *s,
|
||||
apr_pool_t *ptemp,
|
||||
@@ -2324,7 +2279,7 @@ static apr_status_t ssl_init_ca_cert_path(server_rec *s,
|
||||
}
|
||||
file = apr_pstrcat(ptemp, path, "/", direntry.name, NULL);
|
||||
if (ca_list) {
|
||||
- ssl_init_PushCAList(ca_list, s, ptemp, file);
|
||||
+ SSL_add_file_cert_subjects_to_stack(ca_list, file);
|
||||
}
|
||||
if (xi_list) {
|
||||
load_x509_info(ptemp, xi_list, file);
|
||||
@@ -2341,19 +2296,13 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
|
||||
const char *ca_file,
|
||||
const char *ca_path)
|
||||
{
|
||||
- STACK_OF(X509_NAME) *ca_list;
|
||||
-
|
||||
- /*
|
||||
- * Start with a empty stack/list where new
|
||||
- * entries get added in sorted order.
|
||||
- */
|
||||
- ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp);
|
||||
+ STACK_OF(X509_NAME) *ca_list = sk_X509_NAME_new_null();;
|
||||
|
||||
/*
|
||||
* Process CA certificate bundle file
|
||||
*/
|
||||
if (ca_file) {
|
||||
- ssl_init_PushCAList(ca_list, s, ptemp, ca_file);
|
||||
+ SSL_add_file_cert_subjects_to_stack(ca_list, ca_file);
|
||||
/*
|
||||
* If ca_list is still empty after trying to load ca_file
|
||||
* then the file failed to load, and users should hear about that.
|
||||
@@ -2377,11 +2326,6 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- /*
|
||||
- * Cleanup
|
||||
- */
|
||||
- (void) sk_X509_NAME_set_cmp_func(ca_list, NULL);
|
||||
-
|
||||
return ca_list;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,229 +0,0 @@
|
|||
diff --git a/Makefile.in b/Makefile.in
|
||||
index 6747aea..40c7076 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -233,6 +233,7 @@ install-cgi:
|
||||
install-other:
|
||||
@test -d $(DESTDIR)$(logfiledir) || $(MKINSTALLDIRS) $(DESTDIR)$(logfiledir)
|
||||
@test -d $(DESTDIR)$(runtimedir) || $(MKINSTALLDIRS) $(DESTDIR)$(runtimedir)
|
||||
+ @test -d $(DESTDIR)$(statedir) || $(MKINSTALLDIRS) $(DESTDIR)$(statedir)
|
||||
@for ext in dll x; do \
|
||||
file=apachecore.$$ext; \
|
||||
if test -f $$file; then \
|
||||
diff --git a/acinclude.m4 b/acinclude.m4
|
||||
index b6ef442..98f1441 100644
|
||||
--- a/acinclude.m4
|
||||
+++ b/acinclude.m4
|
||||
@@ -45,6 +45,7 @@ AC_DEFUN([APACHE_GEN_CONFIG_VARS],[
|
||||
APACHE_SUBST(installbuilddir)
|
||||
APACHE_SUBST(runtimedir)
|
||||
APACHE_SUBST(proxycachedir)
|
||||
+ APACHE_SUBST(statedir)
|
||||
APACHE_SUBST(other_targets)
|
||||
APACHE_SUBST(progname)
|
||||
APACHE_SUBST(prefix)
|
||||
@@ -665,6 +666,7 @@ AC_DEFUN([APACHE_EXPORT_ARGUMENTS],[
|
||||
APACHE_SUBST_EXPANDED_ARG(runtimedir)
|
||||
APACHE_SUBST_EXPANDED_ARG(logfiledir)
|
||||
APACHE_SUBST_EXPANDED_ARG(proxycachedir)
|
||||
+ APACHE_SUBST_EXPANDED_ARG(statedir)
|
||||
])
|
||||
|
||||
dnl
|
||||
diff --git a/configure.in b/configure.in
|
||||
index 37346b2..f303784 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -41,7 +41,7 @@ dnl Something seems broken here.
|
||||
AC_PREFIX_DEFAULT(/usr/local/apache2)
|
||||
|
||||
dnl Get the layout here, so we can pass the required variables to apr
|
||||
-APR_ENABLE_LAYOUT(Apache, [errordir iconsdir htdocsdir cgidir])
|
||||
+APR_ENABLE_LAYOUT(Apache, [errordir iconsdir htdocsdir cgidir statedir])
|
||||
|
||||
dnl reparse the configure arguments.
|
||||
APR_PARSE_ARGUMENTS
|
||||
diff --git a/include/ap_config_layout.h.in b/include/ap_config_layout.h.in
|
||||
index 2b4a70c..e076f41 100644
|
||||
--- a/include/ap_config_layout.h.in
|
||||
+++ b/include/ap_config_layout.h.in
|
||||
@@ -60,5 +60,7 @@
|
||||
#define DEFAULT_REL_LOGFILEDIR "@rel_logfiledir@"
|
||||
#define DEFAULT_EXP_PROXYCACHEDIR "@exp_proxycachedir@"
|
||||
#define DEFAULT_REL_PROXYCACHEDIR "@rel_proxycachedir@"
|
||||
+#define DEFAULT_EXP_STATEDIR "@exp_statedir@"
|
||||
+#define DEFAULT_REL_STATEDIR "@rel_statedir@"
|
||||
|
||||
#endif /* AP_CONFIG_LAYOUT_H */
|
||||
diff --git a/include/http_config.h b/include/http_config.h
|
||||
index 77657ae..384a90f 100644
|
||||
--- a/include/http_config.h
|
||||
+++ b/include/http_config.h
|
||||
@@ -757,6 +757,14 @@ AP_DECLARE(char *) ap_server_root_relative(apr_pool_t *p, const char *fname);
|
||||
*/
|
||||
AP_DECLARE(char *) ap_runtime_dir_relative(apr_pool_t *p, const char *fname);
|
||||
|
||||
+/**
|
||||
+ * Compute the name of a persistent state file (e.g. a database or
|
||||
+ * long-lived cache) relative to the appropriate state directory.
|
||||
+ * Absolute paths are returned as-is. The state directory is
|
||||
+ * configured via the DefaultStateDir directive or at build time.
|
||||
+ */
|
||||
+AP_DECLARE(char *) ap_state_dir_relative(apr_pool_t *p, const char *fname);
|
||||
+
|
||||
/* Finally, the hook for dynamically loading modules in... */
|
||||
|
||||
/**
|
||||
diff --git a/modules/dav/fs/mod_dav_fs.c b/modules/dav/fs/mod_dav_fs.c
|
||||
index addfd7e..2389f8f 100644
|
||||
--- a/modules/dav/fs/mod_dav_fs.c
|
||||
+++ b/modules/dav/fs/mod_dav_fs.c
|
||||
@@ -29,6 +29,10 @@ typedef struct {
|
||||
|
||||
extern module AP_MODULE_DECLARE_DATA dav_fs_module;
|
||||
|
||||
+#ifndef DEFAULT_DAV_LOCKDB
|
||||
+#define DEFAULT_DAV_LOCKDB "davlockdb"
|
||||
+#endif
|
||||
+
|
||||
const char *dav_get_lockdb_path(const request_rec *r)
|
||||
{
|
||||
dav_fs_server_conf *conf;
|
||||
@@ -57,6 +61,24 @@ static void *dav_fs_merge_server_config(apr_pool_t *p,
|
||||
return newconf;
|
||||
}
|
||||
|
||||
+static apr_status_t dav_fs_post_config(apr_pool_t *p, apr_pool_t *plog,
|
||||
+ apr_pool_t *ptemp, server_rec *base_server)
|
||||
+{
|
||||
+ server_rec *s;
|
||||
+
|
||||
+ for (s = base_server; s; s = s->next) {
|
||||
+ dav_fs_server_conf *conf;
|
||||
+
|
||||
+ conf = ap_get_module_config(s->module_config, &dav_fs_module);
|
||||
+
|
||||
+ if (!conf->lockdb_path) {
|
||||
+ conf->lockdb_path = ap_state_dir_relative(p, DEFAULT_DAV_LOCKDB);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return OK;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Command handler for the DAVLockDB directive, which is TAKE1
|
||||
*/
|
||||
@@ -87,6 +109,8 @@ static const command_rec dav_fs_cmds[] =
|
||||
|
||||
static void register_hooks(apr_pool_t *p)
|
||||
{
|
||||
+ ap_hook_post_config(dav_fs_post_config, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
+
|
||||
dav_hook_gather_propsets(dav_fs_gather_propsets, NULL, NULL,
|
||||
APR_HOOK_MIDDLE);
|
||||
dav_hook_find_liveprop(dav_fs_find_liveprop, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
diff --git a/server/core.c b/server/core.c
|
||||
index d135764..c2176b9 100644
|
||||
--- a/server/core.c
|
||||
+++ b/server/core.c
|
||||
@@ -142,6 +142,8 @@ AP_DECLARE_DATA int ap_main_state = AP_SQ_MS_INITIAL_STARTUP;
|
||||
AP_DECLARE_DATA int ap_run_mode = AP_SQ_RM_UNKNOWN;
|
||||
AP_DECLARE_DATA int ap_config_generation = 0;
|
||||
|
||||
+static const char *core_state_dir;
|
||||
+
|
||||
static void *create_core_dir_config(apr_pool_t *a, char *dir)
|
||||
{
|
||||
core_dir_config *conf;
|
||||
@@ -1444,13 +1446,16 @@ AP_DECLARE(const char *) ap_resolve_env(apr_pool_t *p, const char * word)
|
||||
return res_buf;
|
||||
}
|
||||
|
||||
-static int reset_config_defines(void *dummy)
|
||||
+/* pconf cleanup - clear global variables set from config here. */
|
||||
+static apr_status_t reset_config(void *dummy)
|
||||
{
|
||||
ap_server_config_defines = saved_server_config_defines;
|
||||
saved_server_config_defines = NULL;
|
||||
server_config_defined_vars = NULL;
|
||||
ap_runtime_dir = NULL;
|
||||
- return OK;
|
||||
+ core_state_dir = NULL;
|
||||
+
|
||||
+ return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3220,6 +3225,24 @@ static const char *set_runtime_dir(cmd_parms *cmd, void *dummy, const char *arg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static const char *set_state_dir(cmd_parms *cmd, void *dummy, const char *arg)
|
||||
+{
|
||||
+ const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
|
||||
+
|
||||
+ if (err != NULL) {
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ if ((apr_filepath_merge((char**)&core_state_dir, NULL,
|
||||
+ ap_server_root_relative(cmd->temp_pool, arg),
|
||||
+ APR_FILEPATH_TRUENAME, cmd->pool) != APR_SUCCESS)
|
||||
+ || !ap_is_directory(cmd->temp_pool, core_state_dir)) {
|
||||
+ return "DefaultStateDir must be a valid directory, absolute or relative to ServerRoot";
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static const char *set_timeout(cmd_parms *cmd, void *dummy, const char *arg)
|
||||
{
|
||||
const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_CONTEXT);
|
||||
@@ -4521,6 +4544,8 @@ AP_INIT_TAKE1("ServerRoot", set_server_root, NULL, RSRC_CONF | EXEC_ON_READ,
|
||||
"Common directory of server-related files (logs, confs, etc.)"),
|
||||
AP_INIT_TAKE1("DefaultRuntimeDir", set_runtime_dir, NULL, RSRC_CONF | EXEC_ON_READ,
|
||||
"Common directory for run-time files (shared memory, locks, etc.)"),
|
||||
+AP_INIT_TAKE1("DefaultStateDir", set_state_dir, NULL, RSRC_CONF | EXEC_ON_READ,
|
||||
+ "Common directory for persistent state (databases, long-lived caches, etc.)"),
|
||||
AP_INIT_TAKE1("ErrorLog", set_server_string_slot,
|
||||
(void *)APR_OFFSETOF(server_rec, error_fname), RSRC_CONF,
|
||||
"The filename of the error log"),
|
||||
@@ -5055,8 +5080,7 @@ static int core_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptem
|
||||
|
||||
if (!saved_server_config_defines)
|
||||
init_config_defines(pconf);
|
||||
- apr_pool_cleanup_register(pconf, NULL, reset_config_defines,
|
||||
- apr_pool_cleanup_null);
|
||||
+ apr_pool_cleanup_register(pconf, NULL, reset_config, apr_pool_cleanup_null);
|
||||
|
||||
ap_regcomp_set_default_cflags(AP_REG_DEFAULT);
|
||||
|
||||
@@ -5303,6 +5327,27 @@ AP_DECLARE(int) ap_state_query(int query)
|
||||
}
|
||||
}
|
||||
|
||||
+AP_DECLARE(char *) ap_state_dir_relative(apr_pool_t *p, const char *file)
|
||||
+{
|
||||
+ char *newpath = NULL;
|
||||
+ apr_status_t rv;
|
||||
+ const char *state_dir;
|
||||
+
|
||||
+ state_dir = core_state_dir
|
||||
+ ? core_state_dir
|
||||
+ : ap_server_root_relative(p, DEFAULT_REL_STATEDIR);
|
||||
+
|
||||
+ rv = apr_filepath_merge(&newpath, state_dir, file, APR_FILEPATH_TRUENAME, p);
|
||||
+ if (newpath && (rv == APR_SUCCESS || APR_STATUS_IS_EPATHWILD(rv)
|
||||
+ || APR_STATUS_IS_ENOENT(rv)
|
||||
+ || APR_STATUS_IS_ENOTDIR(rv))) {
|
||||
+ return newpath;
|
||||
+ }
|
||||
+ else {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static apr_random_t *rng = NULL;
|
||||
#if APR_HAS_THREADS
|
||||
static apr_thread_mutex_t *rng_mutex = NULL;
|
|
@ -1,79 +0,0 @@
|
|||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index 15f68f9..e67c81d 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -1682,6 +1682,10 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
|
||||
STACK_OF(X509) *chain;
|
||||
X509_STORE_CTX *sctx;
|
||||
X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
|
||||
+ int addl_chain = 0; /* non-zero if additional chain certs were
|
||||
+ * added to store */
|
||||
+
|
||||
+ ap_assert(store != NULL); /* safe to assume always non-NULL? */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL
|
||||
/* For OpenSSL >=1.1.1, turn on client cert support which is
|
||||
@@ -1707,20 +1711,28 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
|
||||
ssl_init_ca_cert_path(s, ptemp, pkp->cert_path, NULL, sk);
|
||||
}
|
||||
|
||||
- if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
|
||||
- sk_X509_INFO_free(sk);
|
||||
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
|
||||
- "no client certs found for SSL proxy");
|
||||
- return APR_SUCCESS;
|
||||
- }
|
||||
-
|
||||
/* Check that all client certs have got certificates and private
|
||||
- * keys. */
|
||||
- for (n = 0; n < ncerts; n++) {
|
||||
+ * keys. Note the number of certs in the stack may decrease
|
||||
+ * during the loop. */
|
||||
+ for (n = 0; n < sk_X509_INFO_num(sk); n++) {
|
||||
X509_INFO *inf = sk_X509_INFO_value(sk, n);
|
||||
+ int has_privkey = inf->x_pkey && inf->x_pkey->dec_pkey;
|
||||
|
||||
- if (!inf->x509 || !inf->x_pkey || !inf->x_pkey->dec_pkey ||
|
||||
- inf->enc_data) {
|
||||
+ /* For a lone certificate in the file, trust it as a
|
||||
+ * CA/intermediate certificate. */
|
||||
+ if (inf->x509 && !has_privkey && !inf->enc_data) {
|
||||
+ ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, inf->x509,
|
||||
+ APLOGNO(10261) "Trusting non-leaf certificate");
|
||||
+ X509_STORE_add_cert(store, inf->x509); /* increments inf->x509 */
|
||||
+ /* Delete from the stack and iterate again. */
|
||||
+ X509_INFO_free(inf);
|
||||
+ sk_X509_INFO_delete(sk, n);
|
||||
+ n--;
|
||||
+ addl_chain = 1;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!has_privkey || inf->enc_data) {
|
||||
sk_X509_INFO_free(sk);
|
||||
ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252)
|
||||
"incomplete client cert configured for SSL proxy "
|
||||
@@ -1737,13 +1749,21 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
|
||||
}
|
||||
}
|
||||
|
||||
+ if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
|
||||
+ sk_X509_INFO_free(sk);
|
||||
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
|
||||
+ "no client certs found for SSL proxy");
|
||||
+ return APR_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02207)
|
||||
"loaded %d client certs for SSL proxy",
|
||||
ncerts);
|
||||
pkp->certs = sk;
|
||||
|
||||
-
|
||||
- if (!pkp->ca_cert_file || !store) {
|
||||
+ /* If any chain certs are configured, build the ->ca_certs chains
|
||||
+ * corresponding to the loaded keypairs. */
|
||||
+ if (!pkp->ca_cert_file && !addl_chain) {
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
diff --git a/server/util_script.c b/server/util_script.c
|
||||
index 4121ae0..b7f8674 100644
|
||||
--- a/server/util_script.c
|
||||
+++ b/server/util_script.c
|
||||
@@ -92,9 +92,21 @@ static void add_unless_null(apr_table_t *table, const char *name, const char *va
|
||||
}
|
||||
}
|
||||
|
||||
-static void env2env(apr_table_t *table, const char *name)
|
||||
+/* Sets variable @name in table @dest from r->subprocess_env if
|
||||
+ * available, else from the environment, else from @fallback if
|
||||
+ * non-NULL. */
|
||||
+static void env2env(apr_table_t *dest, request_rec *r,
|
||||
+ const char *name, const char *fallback)
|
||||
{
|
||||
- add_unless_null(table, name, getenv(name));
|
||||
+ const char *val;
|
||||
+
|
||||
+ val = apr_table_get(r->subprocess_env, name);
|
||||
+ if (!val)
|
||||
+ val = apr_pstrdup(r->pool, getenv(name));
|
||||
+ if (!val)
|
||||
+ val = apr_pstrdup(r->pool, fallback);
|
||||
+ if (val)
|
||||
+ apr_table_addn(dest, name, val);
|
||||
}
|
||||
|
||||
AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
|
||||
@@ -211,37 +223,29 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r)
|
||||
add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
|
||||
}
|
||||
|
||||
- env_temp = apr_table_get(r->subprocess_env, "PATH");
|
||||
- if (env_temp == NULL) {
|
||||
- env_temp = getenv("PATH");
|
||||
- }
|
||||
- if (env_temp == NULL) {
|
||||
- env_temp = DEFAULT_PATH;
|
||||
- }
|
||||
- apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_temp));
|
||||
-
|
||||
+ env2env(e, r, "PATH", DEFAULT_PATH);
|
||||
#if defined(WIN32)
|
||||
- env2env(e, "SystemRoot");
|
||||
- env2env(e, "COMSPEC");
|
||||
- env2env(e, "PATHEXT");
|
||||
- env2env(e, "WINDIR");
|
||||
+ env2env(e, r, "SystemRoot", NULL);
|
||||
+ env2env(e, r, "COMSPEC", NULL);
|
||||
+ env2env(e, r, "PATHEXT", NULL);
|
||||
+ env2env(e, r, "WINDIR", NULL);
|
||||
#elif defined(OS2)
|
||||
- env2env(e, "COMSPEC");
|
||||
- env2env(e, "ETC");
|
||||
- env2env(e, "DPATH");
|
||||
- env2env(e, "PERLLIB_PREFIX");
|
||||
+ env2env(e, r, "COMSPEC", NULL);
|
||||
+ env2env(e, r, "ETC", NULL);
|
||||
+ env2env(e, r, "DPATH", NULL);
|
||||
+ env2env(e, r, "PERLLIB_PREFIX", NULL);
|
||||
#elif defined(BEOS)
|
||||
- env2env(e, "LIBRARY_PATH");
|
||||
+ env2env(e, r, "LIBRARY_PATH", NULL);
|
||||
#elif defined(DARWIN)
|
||||
- env2env(e, "DYLD_LIBRARY_PATH");
|
||||
+ env2env(e, r, "DYLD_LIBRARY_PATH", NULL);
|
||||
#elif defined(_AIX)
|
||||
- env2env(e, "LIBPATH");
|
||||
+ env2env(e, r, "LIBPATH", NULL);
|
||||
#elif defined(__HPUX__)
|
||||
/* HPUX PARISC 2.0W knows both, otherwise redundancy is harmless */
|
||||
- env2env(e, "SHLIB_PATH");
|
||||
- env2env(e, "LD_LIBRARY_PATH");
|
||||
+ env2env(e, r, "SHLIB_PATH", NULL);
|
||||
+ env2env(e, r, "LD_LIBRARY_PATH", NULL);
|
||||
#else /* Some Unix */
|
||||
- env2env(e, "LD_LIBRARY_PATH");
|
||||
+ env2env(e, r, "LD_LIBRARY_PATH", NULL);
|
||||
#endif
|
||||
|
||||
apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
|
|
@ -1,249 +0,0 @@
|
|||
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
|
||||
index 211ebff..c8cb1af 100644
|
||||
--- a/modules/ssl/ssl_engine_init.c
|
||||
+++ b/modules/ssl/ssl_engine_init.c
|
||||
@@ -871,6 +871,13 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
|
||||
SSL_CTX_set_keylog_callback(ctx, modssl_callback_keylog);
|
||||
}
|
||||
#endif
|
||||
+
|
||||
+#ifdef SSL_OP_NO_RENEGOTIATION
|
||||
+ /* For server-side SSL_CTX, disable renegotiation by default.. */
|
||||
+ if (!mctx->pkp) {
|
||||
+ SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION);
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
return APR_SUCCESS;
|
||||
}
|
||||
@@ -892,6 +899,14 @@ static void ssl_init_ctx_session_cache(server_rec *s,
|
||||
}
|
||||
}
|
||||
|
||||
+#ifdef SSL_OP_NO_RENEGOTIATION
|
||||
+/* OpenSSL-level renegotiation protection. */
|
||||
+#define MODSSL_BLOCKS_RENEG (0)
|
||||
+#else
|
||||
+/* mod_ssl-level renegotiation protection. */
|
||||
+#define MODSSL_BLOCKS_RENEG (1)
|
||||
+#endif
|
||||
+
|
||||
static void ssl_init_ctx_callbacks(server_rec *s,
|
||||
apr_pool_t *p,
|
||||
apr_pool_t *ptemp,
|
||||
@@ -905,7 +920,13 @@ static void ssl_init_ctx_callbacks(server_rec *s,
|
||||
SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
|
||||
#endif
|
||||
|
||||
- SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
|
||||
+ /* The info callback is used for debug-level tracing. For OpenSSL
|
||||
+ * versions where SSL_OP_NO_RENEGOTIATION is not available, the
|
||||
+ * callback is also used to prevent use of client-initiated
|
||||
+ * renegotiation. Enable it in either case. */
|
||||
+ if (APLOGdebug(s) || MODSSL_BLOCKS_RENEG) {
|
||||
+ SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
|
||||
+ }
|
||||
|
||||
#ifdef HAVE_TLS_ALPN
|
||||
SSL_CTX_set_alpn_select_cb(ctx, ssl_callback_alpn_select, NULL);
|
||||
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
|
||||
index 79b9a70..3a0c22a 100644
|
||||
--- a/modules/ssl/ssl_engine_io.c
|
||||
+++ b/modules/ssl/ssl_engine_io.c
|
||||
@@ -209,11 +209,13 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl)
|
||||
|
||||
BIO_clear_retry_flags(bio);
|
||||
|
||||
+#ifndef SSL_OP_NO_RENEGOTIATION
|
||||
/* Abort early if the client has initiated a renegotiation. */
|
||||
if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) {
|
||||
outctx->rc = APR_ECONNABORTED;
|
||||
return -1;
|
||||
}
|
||||
+#endif
|
||||
|
||||
ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c,
|
||||
"bio_filter_out_write: %i bytes", inl);
|
||||
@@ -474,11 +476,13 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen)
|
||||
|
||||
BIO_clear_retry_flags(bio);
|
||||
|
||||
+#ifndef SSL_OP_NO_RENEGOTIATION
|
||||
/* Abort early if the client has initiated a renegotiation. */
|
||||
if (inctx->filter_ctx->config->reneg_state == RENEG_ABORT) {
|
||||
inctx->rc = APR_ECONNABORTED;
|
||||
return -1;
|
||||
}
|
||||
+#endif
|
||||
|
||||
if (!inctx->bb) {
|
||||
inctx->rc = APR_EOF;
|
||||
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
|
||||
index 591f6ae..8416864 100644
|
||||
--- a/modules/ssl/ssl_engine_kernel.c
|
||||
+++ b/modules/ssl/ssl_engine_kernel.c
|
||||
@@ -992,7 +992,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo
|
||||
|
||||
/* Toggle the renegotiation state to allow the new
|
||||
* handshake to proceed. */
|
||||
- sslconn->reneg_state = RENEG_ALLOW;
|
||||
+ modssl_set_reneg_state(sslconn, RENEG_ALLOW);
|
||||
|
||||
SSL_renegotiate(ssl);
|
||||
SSL_do_handshake(ssl);
|
||||
@@ -1019,7 +1019,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo
|
||||
*/
|
||||
SSL_peek(ssl, peekbuf, 0);
|
||||
|
||||
- sslconn->reneg_state = RENEG_REJECT;
|
||||
+ modssl_set_reneg_state(sslconn, RENEG_REJECT);
|
||||
|
||||
if (!SSL_is_init_finished(ssl)) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02261)
|
||||
@@ -1078,7 +1078,7 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
|
||||
(sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) {
|
||||
int vmode_inplace, vmode_needed;
|
||||
int change_vmode = FALSE;
|
||||
- int old_state, n, rc;
|
||||
+ int n, rc;
|
||||
|
||||
vmode_inplace = SSL_get_verify_mode(ssl);
|
||||
vmode_needed = SSL_VERIFY_NONE;
|
||||
@@ -1180,8 +1180,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
|
||||
return HTTP_FORBIDDEN;
|
||||
}
|
||||
|
||||
- old_state = sslconn->reneg_state;
|
||||
- sslconn->reneg_state = RENEG_ALLOW;
|
||||
modssl_set_app_data2(ssl, r);
|
||||
|
||||
SSL_do_handshake(ssl);
|
||||
@@ -1191,7 +1189,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
|
||||
*/
|
||||
SSL_peek(ssl, peekbuf, 0);
|
||||
|
||||
- sslconn->reneg_state = old_state;
|
||||
modssl_set_app_data2(ssl, NULL);
|
||||
|
||||
/*
|
||||
@@ -2263,8 +2260,8 @@ static void log_tracing_state(const SSL *ssl, conn_rec *c,
|
||||
/*
|
||||
* This callback function is executed while OpenSSL processes the SSL
|
||||
* handshake and does SSL record layer stuff. It's used to trap
|
||||
- * client-initiated renegotiations, and for dumping everything to the
|
||||
- * log.
|
||||
+ * client-initiated renegotiations (where SSL_OP_NO_RENEGOTIATION is
|
||||
+ * not available), and for dumping everything to the log.
|
||||
*/
|
||||
void ssl_callback_Info(const SSL *ssl, int where, int rc)
|
||||
{
|
||||
@@ -2276,14 +2273,12 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
|
||||
return;
|
||||
}
|
||||
|
||||
- /* With TLS 1.3 this callback may be called multiple times on the first
|
||||
- * negotiation, so the below logic to detect renegotiations can't work.
|
||||
- * Fortunately renegotiations are forbidden starting with TLS 1.3, and
|
||||
- * this is enforced by OpenSSL so there's nothing to be done here.
|
||||
- */
|
||||
-#if SSL_HAVE_PROTOCOL_TLSV1_3
|
||||
- if (SSL_version(ssl) < TLS1_3_VERSION)
|
||||
-#endif
|
||||
+#ifndef SSL_OP_NO_RENEGOTIATION
|
||||
+ /* With OpenSSL < 1.1.1 (implying TLS v1.2 or earlier), this
|
||||
+ * callback is used to block client-initiated renegotiation. With
|
||||
+ * TLSv1.3 it is unnecessary since renegotiation is forbidden at
|
||||
+ * protocol level. Otherwise (TLSv1.2 with OpenSSL >=1.1.1),
|
||||
+ * SSL_OP_NO_RENEGOTIATION is used to block renegotiation. */
|
||||
{
|
||||
SSLConnRec *sslconn;
|
||||
|
||||
@@ -2308,6 +2303,7 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
|
||||
sslconn->reneg_state = RENEG_REJECT;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
s = mySrvFromConn(c);
|
||||
if (s && APLOGdebug(s)) {
|
||||
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
|
||||
index a329d99..7666c31 100644
|
||||
--- a/modules/ssl/ssl_private.h
|
||||
+++ b/modules/ssl/ssl_private.h
|
||||
@@ -512,6 +512,16 @@ typedef struct {
|
||||
apr_time_t source_mtime;
|
||||
} ssl_asn1_t;
|
||||
|
||||
+typedef enum {
|
||||
+ RENEG_INIT = 0, /* Before initial handshake */
|
||||
+ RENEG_REJECT, /* After initial handshake; any client-initiated
|
||||
+ * renegotiation should be rejected */
|
||||
+ RENEG_ALLOW, /* A server-initiated renegotiation is taking
|
||||
+ * place (as dictated by configuration) */
|
||||
+ RENEG_ABORT /* Renegotiation initiated by client, abort the
|
||||
+ * connection */
|
||||
+} modssl_reneg_state;
|
||||
+
|
||||
/**
|
||||
* Define the mod_ssl per-module configuration structure
|
||||
* (i.e. the global configuration for each httpd process)
|
||||
@@ -543,18 +553,13 @@ typedef struct {
|
||||
NON_SSL_SET_ERROR_MSG /* Need to set the error message */
|
||||
} non_ssl_request;
|
||||
|
||||
- /* Track the handshake/renegotiation state for the connection so
|
||||
- * that all client-initiated renegotiations can be rejected, as a
|
||||
- * partial fix for CVE-2009-3555. */
|
||||
- enum {
|
||||
- RENEG_INIT = 0, /* Before initial handshake */
|
||||
- RENEG_REJECT, /* After initial handshake; any client-initiated
|
||||
- * renegotiation should be rejected */
|
||||
- RENEG_ALLOW, /* A server-initiated renegotiation is taking
|
||||
- * place (as dictated by configuration) */
|
||||
- RENEG_ABORT /* Renegotiation initiated by client, abort the
|
||||
- * connection */
|
||||
- } reneg_state;
|
||||
+#ifndef SSL_OP_NO_RENEGOTIATION
|
||||
+ /* For OpenSSL < 1.1.1, track the handshake/renegotiation state
|
||||
+ * for the connection to block client-initiated renegotiations.
|
||||
+ * For OpenSSL >=1.1.1, the SSL_OP_NO_RENEGOTIATION flag is used in
|
||||
+ * the SSL * options state with equivalent effect. */
|
||||
+ modssl_reneg_state reneg_state;
|
||||
+#endif
|
||||
|
||||
server_rec *server;
|
||||
SSLDirConfigRec *dc;
|
||||
@@ -1158,6 +1163,9 @@ int ssl_is_challenge(conn_rec *c, const char *servername,
|
||||
* the configured ENGINE. */
|
||||
int modssl_is_engine_id(const char *name);
|
||||
|
||||
+/* Set the renegotation state for connection. */
|
||||
+void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state);
|
||||
+
|
||||
#endif /* SSL_PRIVATE_H */
|
||||
/** @} */
|
||||
|
||||
diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c
|
||||
index 38079a9..dafb833 100644
|
||||
--- a/modules/ssl/ssl_util_ssl.c
|
||||
+++ b/modules/ssl/ssl_util_ssl.c
|
||||
@@ -589,3 +589,19 @@ cleanup:
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
+
|
||||
+void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state)
|
||||
+{
|
||||
+#ifdef SSL_OP_NO_RENEGOTIATION
|
||||
+ switch (state) {
|
||||
+ case RENEG_ALLOW:
|
||||
+ SSL_clear_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION);
|
||||
+ break;
|
||||
+ default:
|
||||
+ SSL_set_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION);
|
||||
+ break;
|
||||
+ }
|
||||
+#else
|
||||
+ sslconn->reneg_state = state;
|
||||
+#endif
|
||||
+}
|
|
@ -1,156 +0,0 @@
|
|||
# ./pullrev.sh 1892413 1895552
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1938740
|
||||
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1892413
|
||||
http://svn.apache.org/viewvc?view=revision&revision=1895552
|
||||
|
||||
- also mod_cgi/mod_cgid log_flags fix from r1881559
|
||||
|
||||
--- httpd-2.4.51/modules/filters/mod_deflate.c.r1892413+
|
||||
+++ httpd-2.4.51/modules/filters/mod_deflate.c
|
||||
@@ -1275,44 +1275,46 @@
|
||||
if (APR_BUCKET_IS_FLUSH(bkt)) {
|
||||
apr_bucket *tmp_b;
|
||||
|
||||
- ctx->inflate_total += ctx->stream.avail_out;
|
||||
- zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH);
|
||||
- ctx->inflate_total -= ctx->stream.avail_out;
|
||||
- if (zRC != Z_OK) {
|
||||
- inflateEnd(&ctx->stream);
|
||||
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01391)
|
||||
- "Zlib error %d inflating data (%s)", zRC,
|
||||
- ctx->stream.msg);
|
||||
- return APR_EGENERAL;
|
||||
- }
|
||||
+ if (!ctx->done) {
|
||||
+ ctx->inflate_total += ctx->stream.avail_out;
|
||||
+ zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH);
|
||||
+ ctx->inflate_total -= ctx->stream.avail_out;
|
||||
+ if (zRC != Z_OK) {
|
||||
+ inflateEnd(&ctx->stream);
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01391)
|
||||
+ "Zlib error %d inflating data (%s)", zRC,
|
||||
+ ctx->stream.msg);
|
||||
+ return APR_EGENERAL;
|
||||
+ }
|
||||
|
||||
- if (inflate_limit && ctx->inflate_total > inflate_limit) {
|
||||
- inflateEnd(&ctx->stream);
|
||||
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02647)
|
||||
- "Inflated content length of %" APR_OFF_T_FMT
|
||||
- " is larger than the configured limit"
|
||||
- " of %" APR_OFF_T_FMT,
|
||||
- ctx->inflate_total, inflate_limit);
|
||||
- return APR_ENOSPC;
|
||||
- }
|
||||
+ if (inflate_limit && ctx->inflate_total > inflate_limit) {
|
||||
+ inflateEnd(&ctx->stream);
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02647)
|
||||
+ "Inflated content length of %" APR_OFF_T_FMT
|
||||
+ " is larger than the configured limit"
|
||||
+ " of %" APR_OFF_T_FMT,
|
||||
+ ctx->inflate_total, inflate_limit);
|
||||
+ return APR_ENOSPC;
|
||||
+ }
|
||||
|
||||
- if (!check_ratio(r, ctx, dc)) {
|
||||
- inflateEnd(&ctx->stream);
|
||||
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02805)
|
||||
- "Inflated content ratio is larger than the "
|
||||
- "configured limit %i by %i time(s)",
|
||||
- dc->ratio_limit, dc->ratio_burst);
|
||||
- return APR_EINVAL;
|
||||
- }
|
||||
+ if (!check_ratio(r, ctx, dc)) {
|
||||
+ inflateEnd(&ctx->stream);
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02805)
|
||||
+ "Inflated content ratio is larger than the "
|
||||
+ "configured limit %i by %i time(s)",
|
||||
+ dc->ratio_limit, dc->ratio_burst);
|
||||
+ return APR_EINVAL;
|
||||
+ }
|
||||
|
||||
- len = c->bufferSize - ctx->stream.avail_out;
|
||||
- ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
|
||||
- tmp_b = apr_bucket_heap_create((char *)ctx->buffer, len,
|
||||
- NULL, f->c->bucket_alloc);
|
||||
- APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_b);
|
||||
+ len = c->bufferSize - ctx->stream.avail_out;
|
||||
+ ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
|
||||
+ tmp_b = apr_bucket_heap_create((char *)ctx->buffer, len,
|
||||
+ NULL, f->c->bucket_alloc);
|
||||
+ APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_b);
|
||||
|
||||
- ctx->stream.next_out = ctx->buffer;
|
||||
- ctx->stream.avail_out = c->bufferSize;
|
||||
+ ctx->stream.next_out = ctx->buffer;
|
||||
+ ctx->stream.avail_out = c->bufferSize;
|
||||
+ }
|
||||
|
||||
/* Flush everything so far in the returning brigade, but continue
|
||||
* reading should EOS/more follow (don't lose them).
|
||||
--- httpd-2.4.51/modules/generators/mod_cgi.c.r1892413+
|
||||
+++ httpd-2.4.51/modules/generators/mod_cgi.c
|
||||
@@ -191,11 +191,10 @@
|
||||
apr_file_t *f = NULL;
|
||||
apr_finfo_t finfo;
|
||||
char time_str[APR_CTIME_LEN];
|
||||
- int log_flags = rv ? APLOG_ERR : APLOG_ERR;
|
||||
|
||||
/* Intentional no APLOGNO */
|
||||
/* Callee provides APLOGNO in error text */
|
||||
- ap_log_rerror(APLOG_MARK, log_flags, rv, r,
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
|
||||
"%s%s: %s", logno ? logno : "", error, r->filename);
|
||||
|
||||
/* XXX Very expensive mainline case! Open, then getfileinfo! */
|
||||
--- httpd-2.4.51/modules/generators/mod_cgid.c.r1892413+
|
||||
+++ httpd-2.4.51/modules/generators/mod_cgid.c
|
||||
@@ -1190,11 +1190,10 @@
|
||||
apr_file_t *f = NULL;
|
||||
struct stat finfo;
|
||||
char time_str[APR_CTIME_LEN];
|
||||
- int log_flags = rv ? APLOG_ERR : APLOG_ERR;
|
||||
|
||||
/* Intentional no APLOGNO */
|
||||
/* Callee provides APLOGNO in error text */
|
||||
- ap_log_rerror(APLOG_MARK, log_flags, rv, r,
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
|
||||
"%s: %s", error, r->filename);
|
||||
|
||||
/* XXX Very expensive mainline case! Open, then getfileinfo! */
|
||||
--- httpd-2.4.51/server/mpm_unix.c.r1892413+
|
||||
+++ httpd-2.4.51/server/mpm_unix.c
|
||||
@@ -259,10 +259,12 @@
|
||||
while (cur_extra) {
|
||||
ap_generation_t old_gen;
|
||||
extra_process_t *next = cur_extra->next;
|
||||
+ pid_t pid = cur_extra->pid;
|
||||
|
||||
- if (reclaim_one_pid(cur_extra->pid, action_table[cur_action].action)) {
|
||||
- if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
|
||||
- mpm_callback(-1, cur_extra->pid, old_gen);
|
||||
+ if (reclaim_one_pid(pid, action_table[cur_action].action)) {
|
||||
+ if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) {
|
||||
+ /* cur_extra dangling pointer from here. */
|
||||
+ mpm_callback(-1, pid, old_gen);
|
||||
}
|
||||
else {
|
||||
AP_DEBUG_ASSERT(1 == 0);
|
||||
@@ -307,10 +309,12 @@
|
||||
while (cur_extra) {
|
||||
ap_generation_t old_gen;
|
||||
extra_process_t *next = cur_extra->next;
|
||||
+ pid_t pid = cur_extra->pid;
|
||||
|
||||
- if (reclaim_one_pid(cur_extra->pid, DO_NOTHING)) {
|
||||
- if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
|
||||
- mpm_callback(-1, cur_extra->pid, old_gen);
|
||||
+ if (reclaim_one_pid(pid, DO_NOTHING)) {
|
||||
+ if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) {
|
||||
+ /* cur_extra dangling pointer from here. */
|
||||
+ mpm_callback(-1, pid, old_gen);
|
||||
}
|
||||
else {
|
||||
AP_DEBUG_ASSERT(1 == 0);
|
|
@ -1,26 +0,0 @@
|
|||
diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c
|
||||
index e2992fc..46d42bc 100644
|
||||
--- a/modules/proxy/mod_proxy_ajp.c
|
||||
+++ b/modules/proxy/mod_proxy_ajp.c
|
||||
@@ -246,9 +246,18 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r,
|
||||
/* read the first block of data */
|
||||
input_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
|
||||
tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
|
||||
- if (tenc && (ap_cstr_casecmp(tenc, "chunked") == 0)) {
|
||||
- /* The AJP protocol does not want body data yet */
|
||||
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00870) "request is chunked");
|
||||
+ if (tenc) {
|
||||
+ if (ap_cstr_casecmp(tenc, "chunked") == 0) {
|
||||
+ /* The AJP protocol does not want body data yet */
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00870)
|
||||
+ "request is chunked");
|
||||
+ }
|
||||
+ else {
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10396)
|
||||
+ "%s Transfer-Encoding is not supported",
|
||||
+ tenc);
|
||||
+ return HTTP_INTERNAL_SERVER_ERROR;
|
||||
+ }
|
||||
} else {
|
||||
/* Get client provided Content-Length header */
|
||||
content_length = get_content_length(r);
|
|
@ -1,61 +0,0 @@
|
|||
From 8c14927162cf3b4f810683e1c5505e9ef9e1f123 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Covener <covener@apache.org>
|
||||
Date: Wed, 1 Jun 2022 12:34:16 +0000
|
||||
Subject: [PATCH] Merge r1901500 from trunk:
|
||||
|
||||
handle large writes in ap_rputs
|
||||
|
||||
|
||||
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901501 13f79535-47bb-0310-9956-ffa450edef68
|
||||
---
|
||||
include/http_protocol.h | 22 +++++++++++++++++++++-
|
||||
server/protocol.c | 3 +++
|
||||
2 files changed, 24 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/http_protocol.h b/include/http_protocol.h
|
||||
index 20bd2022266..94c481e5f43 100644
|
||||
--- a/include/http_protocol.h
|
||||
+++ b/include/http_protocol.h
|
||||
@@ -475,7 +475,27 @@ AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r);
|
||||
*/
|
||||
static APR_INLINE int ap_rputs(const char *str, request_rec *r)
|
||||
{
|
||||
- return ap_rwrite(str, (int)strlen(str), r);
|
||||
+ apr_size_t len;
|
||||
+
|
||||
+ len = strlen(str);
|
||||
+
|
||||
+ for (;;) {
|
||||
+ if (len <= INT_MAX) {
|
||||
+ return ap_rwrite(str, (int)len, r);
|
||||
+ }
|
||||
+ else {
|
||||
+ int rc;
|
||||
+
|
||||
+ rc = ap_rwrite(str, INT_MAX, r);
|
||||
+ if (rc < 0) {
|
||||
+ return rc;
|
||||
+ }
|
||||
+ else {
|
||||
+ str += INT_MAX;
|
||||
+ len -= INT_MAX;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/**
|
||||
diff --git a/server/protocol.c b/server/protocol.c
|
||||
index 298f61e1fb8..7adc7f75c10 100644
|
||||
--- a/server/protocol.c
|
||||
+++ b/server/protocol.c
|
||||
@@ -2128,6 +2128,9 @@ AP_DECLARE(int) ap_rputc(int c, request_rec *r)
|
||||
|
||||
AP_DECLARE(int) ap_rwrite(const void *buf, int nbyte, request_rec *r)
|
||||
{
|
||||
+ if (nbyte < 0)
|
||||
+ return -1;
|
||||
+
|
||||
if (r->connection->aborted)
|
||||
return -1;
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
diff --git a/server/util.c b/server/util.c
|
||||
index 604be1a..6808164 100644
|
||||
--- a/server/util.c
|
||||
+++ b/server/util.c
|
||||
@@ -185,7 +185,7 @@ AP_DECLARE(char *) ap_ht_time(apr_pool_t *p, apr_time_t t, const char *fmt,
|
||||
*/
|
||||
AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected)
|
||||
{
|
||||
- int x, y;
|
||||
+ apr_size_t x, y;
|
||||
|
||||
for (x = 0, y = 0; expected[y]; ++y, ++x) {
|
||||
if (expected[y] == '*') {
|
||||
@@ -209,7 +209,7 @@ AP_DECLARE(int) ap_strcmp_match(const char *str, const char *expected)
|
||||
|
||||
AP_DECLARE(int) ap_strcasecmp_match(const char *str, const char *expected)
|
||||
{
|
||||
- int x, y;
|
||||
+ apr_size_t x, y;
|
||||
|
||||
for (x = 0, y = 0; expected[y]; ++y, ++x) {
|
||||
if (!str[x] && expected[y] != '*')
|
|
@ -1,126 +0,0 @@
|
|||
diff --git a/docs/manual/mod/core.html.en b/docs/manual/mod/core.html.en
|
||||
index bb6b90a..d14aed4 100644
|
||||
--- a/docs/manual/mod/core.html.en
|
||||
+++ b/docs/manual/mod/core.html.en
|
||||
@@ -2796,16 +2796,16 @@ subrequests</td></tr>
|
||||
<tr><th><a href="directive-dict.html#Description">Description:</a></th><td>Restricts the total size of the HTTP request body sent
|
||||
from the client</td></tr>
|
||||
<tr><th><a href="directive-dict.html#Syntax">Syntax:</a></th><td><code>LimitRequestBody <var>bytes</var></code></td></tr>
|
||||
-<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>LimitRequestBody 0</code></td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>LimitRequestBody 1073741824</code></td></tr>
|
||||
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config, virtual host, directory, .htaccess</td></tr>
|
||||
<tr><th><a href="directive-dict.html#Override">Override:</a></th><td>All</td></tr>
|
||||
<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>Core</td></tr>
|
||||
<tr><th><a href="directive-dict.html#Module">Module:</a></th><td>core</td></tr>
|
||||
+<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>In Apache HTTP Server 2.4.53 and earlier, the default value
|
||||
+ was 0 (unlimited)</td></tr>
|
||||
</table>
|
||||
- <p>This directive specifies the number of <var>bytes</var> from 0
|
||||
- (meaning unlimited) to 2147483647 (2GB) that are allowed in a
|
||||
- request body. See the note below for the limited applicability
|
||||
- to proxy requests.</p>
|
||||
+ <p>This directive specifies the number of <var>bytes</var>
|
||||
+ that are allowed in a request body. A value of <var>0</var> means unlimited.</p>
|
||||
|
||||
<p>The <code class="directive">LimitRequestBody</code> directive allows
|
||||
the user to set a limit on the allowed size of an HTTP request
|
||||
@@ -2831,12 +2831,6 @@ from the client</td></tr>
|
||||
|
||||
<pre class="prettyprint lang-config">LimitRequestBody 102400</pre>
|
||||
|
||||
-
|
||||
- <div class="note"><p>For a full description of how this directive is interpreted by
|
||||
- proxy requests, see the <code class="module"><a href="../mod/mod_proxy.html">mod_proxy</a></code> documentation.</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="LimitRequestFields" id="LimitRequestFields">LimitRequestFields</a> <a name="limitrequestfields" id="limitrequestfields">Directive</a></h2>
|
||||
diff --git a/docs/manual/mod/mod_proxy.html.en b/docs/manual/mod/mod_proxy.html.en
|
||||
index ee7b1e3..233d234 100644
|
||||
--- a/docs/manual/mod/mod_proxy.html.en
|
||||
+++ b/docs/manual/mod/mod_proxy.html.en
|
||||
@@ -463,9 +463,6 @@ ProxyPass "/examples" "http://backend.example.com/examples" timeout=10</pre>
|
||||
Content-Length header, but the server is configured to filter incoming
|
||||
request bodies.</p>
|
||||
|
||||
- <p><code class="directive"><a href="../mod/core.html#limitrequestbody">LimitRequestBody</a></code> only applies to
|
||||
- request bodies that the server will spool to disk</p>
|
||||
-
|
||||
</div><div class="top"><a href="#page-header"><img alt="top" src="../images/up.gif" /></a></div>
|
||||
<div class="section">
|
||||
<h2><a name="x-headers" id="x-headers">Reverse Proxy Request Headers</a></h2>
|
||||
diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c
|
||||
index 43e8c6d..33c78f3 100644
|
||||
--- a/modules/http/http_filters.c
|
||||
+++ b/modules/http/http_filters.c
|
||||
@@ -1703,6 +1703,7 @@ AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy)
|
||||
{
|
||||
const char *tenc = apr_table_get(r->headers_in, "Transfer-Encoding");
|
||||
const char *lenp = apr_table_get(r->headers_in, "Content-Length");
|
||||
+ apr_off_t limit_req_body = ap_get_limit_req_body(r);
|
||||
|
||||
r->read_body = read_policy;
|
||||
r->read_chunked = 0;
|
||||
@@ -1738,6 +1739,11 @@ AP_DECLARE(int) ap_setup_client_block(request_rec *r, int read_policy)
|
||||
return HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||
}
|
||||
|
||||
+ if (limit_req_body > 0 && (r->remaining > limit_req_body)) {
|
||||
+ /* will be logged when the body is discarded */
|
||||
+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||
+ }
|
||||
+
|
||||
#ifdef AP_DEBUG
|
||||
{
|
||||
/* Make sure ap_getline() didn't leave any droppings. */
|
||||
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
|
||||
index bc86253..85f2f9c 100644
|
||||
--- a/modules/proxy/proxy_util.c
|
||||
+++ b/modules/proxy/proxy_util.c
|
||||
@@ -4260,13 +4260,10 @@ PROXY_DECLARE(int) ap_proxy_spool_input(request_rec *r,
|
||||
apr_bucket *e;
|
||||
apr_off_t bytes, fsize = 0;
|
||||
apr_file_t *tmpfile = NULL;
|
||||
- apr_off_t limit;
|
||||
|
||||
*bytes_spooled = 0;
|
||||
body_brigade = apr_brigade_create(p, bucket_alloc);
|
||||
|
||||
- limit = ap_get_limit_req_body(r);
|
||||
-
|
||||
do {
|
||||
if (APR_BRIGADE_EMPTY(input_brigade)) {
|
||||
rv = ap_proxy_read_input(r, backend, input_brigade,
|
||||
@@ -4284,17 +4281,6 @@ PROXY_DECLARE(int) ap_proxy_spool_input(request_rec *r,
|
||||
apr_brigade_length(input_brigade, 1, &bytes);
|
||||
|
||||
if (*bytes_spooled + bytes > max_mem_spool) {
|
||||
- /*
|
||||
- * LimitRequestBody does not affect Proxy requests (Should it?).
|
||||
- * Let it take effect if we decide to store the body in a
|
||||
- * temporary file on disk.
|
||||
- */
|
||||
- if (limit && (*bytes_spooled + bytes > limit)) {
|
||||
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01088)
|
||||
- "Request body is larger than the configured "
|
||||
- "limit of %" APR_OFF_T_FMT, limit);
|
||||
- return HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||
- }
|
||||
/* can't spool any more in memory; write latest brigade to disk */
|
||||
if (tmpfile == NULL) {
|
||||
const char *temp_dir;
|
||||
diff --git a/server/core.c b/server/core.c
|
||||
index 3d44e0e..682259f 100644
|
||||
--- a/server/core.c
|
||||
+++ b/server/core.c
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
/* LimitRequestBody handling */
|
||||
#define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1)
|
||||
-#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 0)
|
||||
+#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 1<<30) /* 1GB */
|
||||
|
||||
/* LimitXMLRequestBody handling */
|
||||
#define AP_LIMIT_UNSET ((long) -1)
|
|
@ -1,557 +0,0 @@
|
|||
From db47781128e42bd49f55076665b3f6ca4e2bc5e2 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Covener <covener@apache.org>
|
||||
Date: Wed, 1 Jun 2022 12:50:40 +0000
|
||||
Subject: [PATCH] Merge r1901506 from trunk:
|
||||
|
||||
limit mod_sed memory use
|
||||
|
||||
Resync mod_sed.c with trunk due to merge conflicts.
|
||||
|
||||
|
||||
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901509 13f79535-47bb-0310-9956-ffa450edef68
|
||||
---
|
||||
modules/filters/mod_sed.c | 75 ++++++++----------
|
||||
modules/filters/sed1.c | 158 +++++++++++++++++++++++++++-----------
|
||||
2 files changed, 147 insertions(+), 86 deletions(-)
|
||||
|
||||
diff --git a/modules/filters/mod_sed.c b/modules/filters/mod_sed.c
|
||||
index 4bdb4ce33ae..12cb04a20f9 100644
|
||||
--- a/modules/filters/mod_sed.c
|
||||
+++ b/modules/filters/mod_sed.c
|
||||
@@ -59,7 +59,7 @@ typedef struct sed_filter_ctxt
|
||||
module AP_MODULE_DECLARE_DATA sed_module;
|
||||
|
||||
/* This function will be call back from libsed functions if there is any error
|
||||
- * happend during execution of sed scripts
|
||||
+ * happened during execution of sed scripts
|
||||
*/
|
||||
static apr_status_t log_sed_errf(void *data, const char *error)
|
||||
{
|
||||
@@ -277,7 +277,7 @@ static apr_status_t sed_response_filter(ap_filter_t *f,
|
||||
apr_bucket_brigade *bb)
|
||||
{
|
||||
apr_bucket *b;
|
||||
- apr_status_t status;
|
||||
+ apr_status_t status = APR_SUCCESS;
|
||||
sed_config *cfg = ap_get_module_config(f->r->per_dir_config,
|
||||
&sed_module);
|
||||
sed_filter_ctxt *ctx = f->ctx;
|
||||
@@ -302,9 +302,9 @@ static apr_status_t sed_response_filter(ap_filter_t *f,
|
||||
return status;
|
||||
ctx = f->ctx;
|
||||
apr_table_unset(f->r->headers_out, "Content-Length");
|
||||
- }
|
||||
|
||||
- ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
|
||||
+ ctx->bb = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
|
||||
+ }
|
||||
|
||||
/* Here is the main logic. Iterate through all the buckets, read the
|
||||
* content of the bucket, call sed_eval_buffer on the data.
|
||||
@@ -326,63 +326,52 @@ static apr_status_t sed_response_filter(ap_filter_t *f,
|
||||
* in sed's internal buffer which can't be flushed until new line
|
||||
* character is arrived.
|
||||
*/
|
||||
- for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb);) {
|
||||
- const char *buf = NULL;
|
||||
- apr_size_t bytes = 0;
|
||||
+ while (!APR_BRIGADE_EMPTY(bb)) {
|
||||
+ b = APR_BRIGADE_FIRST(bb);
|
||||
if (APR_BUCKET_IS_EOS(b)) {
|
||||
- apr_bucket *b1 = APR_BUCKET_NEXT(b);
|
||||
/* Now clean up the internal sed buffer */
|
||||
sed_finalize_eval(&ctx->eval, ctx);
|
||||
status = flush_output_buffer(ctx);
|
||||
if (status != APR_SUCCESS) {
|
||||
- clear_ctxpool(ctx);
|
||||
- return status;
|
||||
+ break;
|
||||
}
|
||||
+ /* Move the eos bucket to ctx->bb brigade */
|
||||
APR_BUCKET_REMOVE(b);
|
||||
- /* Insert the eos bucket to ctx->bb brigade */
|
||||
APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
|
||||
- b = b1;
|
||||
}
|
||||
else if (APR_BUCKET_IS_FLUSH(b)) {
|
||||
- apr_bucket *b1 = APR_BUCKET_NEXT(b);
|
||||
- APR_BUCKET_REMOVE(b);
|
||||
status = flush_output_buffer(ctx);
|
||||
if (status != APR_SUCCESS) {
|
||||
- clear_ctxpool(ctx);
|
||||
- return status;
|
||||
+ break;
|
||||
}
|
||||
+ /* Move the flush bucket to ctx->bb brigade */
|
||||
+ APR_BUCKET_REMOVE(b);
|
||||
APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
|
||||
- b = b1;
|
||||
- }
|
||||
- else if (APR_BUCKET_IS_METADATA(b)) {
|
||||
- b = APR_BUCKET_NEXT(b);
|
||||
}
|
||||
- else if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ)
|
||||
- == APR_SUCCESS) {
|
||||
- apr_bucket *b1 = APR_BUCKET_NEXT(b);
|
||||
- status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx);
|
||||
- if (status != APR_SUCCESS) {
|
||||
- clear_ctxpool(ctx);
|
||||
- return status;
|
||||
+ else {
|
||||
+ if (!APR_BUCKET_IS_METADATA(b)) {
|
||||
+ const char *buf = NULL;
|
||||
+ apr_size_t bytes = 0;
|
||||
+
|
||||
+ status = apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ);
|
||||
+ if (status == APR_SUCCESS) {
|
||||
+ status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx);
|
||||
+ }
|
||||
+ if (status != APR_SUCCESS) {
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, f->r, APLOGNO(10394) "error evaluating sed on output");
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
- APR_BUCKET_REMOVE(b);
|
||||
apr_bucket_delete(b);
|
||||
- b = b1;
|
||||
- }
|
||||
- else {
|
||||
- apr_bucket *b1 = APR_BUCKET_NEXT(b);
|
||||
- APR_BUCKET_REMOVE(b);
|
||||
- b = b1;
|
||||
}
|
||||
}
|
||||
- apr_brigade_cleanup(bb);
|
||||
- status = flush_output_buffer(ctx);
|
||||
- if (status != APR_SUCCESS) {
|
||||
- clear_ctxpool(ctx);
|
||||
- return status;
|
||||
+ if (status == APR_SUCCESS) {
|
||||
+ status = flush_output_buffer(ctx);
|
||||
}
|
||||
if (!APR_BRIGADE_EMPTY(ctx->bb)) {
|
||||
- status = ap_pass_brigade(f->next, ctx->bb);
|
||||
+ if (status == APR_SUCCESS) {
|
||||
+ status = ap_pass_brigade(f->next, ctx->bb);
|
||||
+ }
|
||||
apr_brigade_cleanup(ctx->bb);
|
||||
}
|
||||
clear_ctxpool(ctx);
|
||||
@@ -433,7 +422,7 @@ static apr_status_t sed_request_filter(ap_filter_t *f,
|
||||
* the buckets in bbinp and read the data from buckets and invoke
|
||||
* sed_eval_buffer on the data. libsed will generate its output using
|
||||
* sed_write_output which will add data in ctx->bb. Do it until it have
|
||||
- * atleast one bucket in ctx->bb. At the end of data eos bucket
|
||||
+ * at least one bucket in ctx->bb. At the end of data eos bucket
|
||||
* should be there.
|
||||
*
|
||||
* Once eos bucket is seen, then invoke sed_finalize_eval to clear the
|
||||
@@ -475,8 +464,10 @@ static apr_status_t sed_request_filter(ap_filter_t *f,
|
||||
if (apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ)
|
||||
== APR_SUCCESS) {
|
||||
status = sed_eval_buffer(&ctx->eval, buf, bytes, ctx);
|
||||
- if (status != APR_SUCCESS)
|
||||
+ if (status != APR_SUCCESS) {
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, f->r, APLOGNO(10395) "error evaluating sed on input");
|
||||
return status;
|
||||
+ }
|
||||
flush_output_buffer(ctx);
|
||||
}
|
||||
}
|
||||
diff --git a/modules/filters/sed1.c b/modules/filters/sed1.c
|
||||
index 67a8d06515e..047f49ba131 100644
|
||||
--- a/modules/filters/sed1.c
|
||||
+++ b/modules/filters/sed1.c
|
||||
@@ -87,18 +87,20 @@ static void eval_errf(sed_eval_t *eval, const char *fmt, ...)
|
||||
}
|
||||
|
||||
#define INIT_BUF_SIZE 1024
|
||||
+#define MAX_BUF_SIZE 1024*8192
|
||||
|
||||
/*
|
||||
* grow_buffer
|
||||
*/
|
||||
-static void grow_buffer(apr_pool_t *pool, char **buffer,
|
||||
+static apr_status_t grow_buffer(apr_pool_t *pool, char **buffer,
|
||||
char **spend, apr_size_t *cursize,
|
||||
apr_size_t newsize)
|
||||
{
|
||||
char* newbuffer = NULL;
|
||||
apr_size_t spendsize = 0;
|
||||
- if (*cursize >= newsize)
|
||||
- return;
|
||||
+ if (*cursize >= newsize) {
|
||||
+ return APR_SUCCESS;
|
||||
+ }
|
||||
/* Avoid number of times realloc is called. It could cause huge memory
|
||||
* requirement if line size is huge e.g 2 MB */
|
||||
if (newsize < *cursize * 2) {
|
||||
@@ -107,6 +109,9 @@ static void grow_buffer(apr_pool_t *pool, char **buffer,
|
||||
|
||||
/* Align it to 4 KB boundary */
|
||||
newsize = (newsize + ((1 << 12) - 1)) & ~((1 << 12) - 1);
|
||||
+ if (newsize > MAX_BUF_SIZE) {
|
||||
+ return APR_ENOMEM;
|
||||
+ }
|
||||
newbuffer = apr_pcalloc(pool, newsize);
|
||||
if (*spend && *buffer && (*cursize > 0)) {
|
||||
spendsize = *spend - *buffer;
|
||||
@@ -119,63 +124,77 @@ static void grow_buffer(apr_pool_t *pool, char **buffer,
|
||||
if (spend != buffer) {
|
||||
*spend = *buffer + spendsize;
|
||||
}
|
||||
+ return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* grow_line_buffer
|
||||
*/
|
||||
-static void grow_line_buffer(sed_eval_t *eval, apr_size_t newsize)
|
||||
+static apr_status_t grow_line_buffer(sed_eval_t *eval, apr_size_t newsize)
|
||||
{
|
||||
- grow_buffer(eval->pool, &eval->linebuf, &eval->lspend,
|
||||
+ return grow_buffer(eval->pool, &eval->linebuf, &eval->lspend,
|
||||
&eval->lsize, newsize);
|
||||
}
|
||||
|
||||
/*
|
||||
* grow_hold_buffer
|
||||
*/
|
||||
-static void grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize)
|
||||
+static apr_status_t grow_hold_buffer(sed_eval_t *eval, apr_size_t newsize)
|
||||
{
|
||||
- grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend,
|
||||
+ return grow_buffer(eval->pool, &eval->holdbuf, &eval->hspend,
|
||||
&eval->hsize, newsize);
|
||||
}
|
||||
|
||||
/*
|
||||
* grow_gen_buffer
|
||||
*/
|
||||
-static void grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize,
|
||||
+static apr_status_t grow_gen_buffer(sed_eval_t *eval, apr_size_t newsize,
|
||||
char **gspend)
|
||||
{
|
||||
+ apr_status_t rc = 0;
|
||||
if (gspend == NULL) {
|
||||
gspend = &eval->genbuf;
|
||||
}
|
||||
- grow_buffer(eval->pool, &eval->genbuf, gspend,
|
||||
- &eval->gsize, newsize);
|
||||
- eval->lcomend = &eval->genbuf[71];
|
||||
+ rc = grow_buffer(eval->pool, &eval->genbuf, gspend,
|
||||
+ &eval->gsize, newsize);
|
||||
+ if (rc == APR_SUCCESS) {
|
||||
+ eval->lcomend = &eval->genbuf[71];
|
||||
+ }
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* appendmem_to_linebuf
|
||||
*/
|
||||
-static void appendmem_to_linebuf(sed_eval_t *eval, const char* sz, apr_size_t len)
|
||||
+static apr_status_t appendmem_to_linebuf(sed_eval_t *eval, const char* sz, apr_size_t len)
|
||||
{
|
||||
+ apr_status_t rc = 0;
|
||||
apr_size_t reqsize = (eval->lspend - eval->linebuf) + len;
|
||||
if (eval->lsize < reqsize) {
|
||||
- grow_line_buffer(eval, reqsize);
|
||||
+ rc = grow_line_buffer(eval, reqsize);
|
||||
+ if (rc != APR_SUCCESS) {
|
||||
+ return rc;
|
||||
+ }
|
||||
}
|
||||
memcpy(eval->lspend, sz, len);
|
||||
eval->lspend += len;
|
||||
+ return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* append_to_linebuf
|
||||
*/
|
||||
-static void append_to_linebuf(sed_eval_t *eval, const char* sz,
|
||||
+static apr_status_t append_to_linebuf(sed_eval_t *eval, const char* sz,
|
||||
step_vars_storage *step_vars)
|
||||
{
|
||||
apr_size_t len = strlen(sz);
|
||||
char *old_linebuf = eval->linebuf;
|
||||
+ apr_status_t rc = 0;
|
||||
/* Copy string including null character */
|
||||
- appendmem_to_linebuf(eval, sz, len + 1);
|
||||
+ rc = appendmem_to_linebuf(eval, sz, len + 1);
|
||||
+ if (rc != APR_SUCCESS) {
|
||||
+ return rc;
|
||||
+ }
|
||||
--eval->lspend; /* lspend will now point to NULL character */
|
||||
/* Sync step_vars after a possible linebuf expansion */
|
||||
if (step_vars && old_linebuf != eval->linebuf) {
|
||||
@@ -189,68 +208,84 @@ static void append_to_linebuf(sed_eval_t *eval, const char* sz,
|
||||
step_vars->locs = step_vars->locs - old_linebuf + eval->linebuf;
|
||||
}
|
||||
}
|
||||
+ return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy_to_linebuf
|
||||
*/
|
||||
-static void copy_to_linebuf(sed_eval_t *eval, const char* sz,
|
||||
+static apr_status_t copy_to_linebuf(sed_eval_t *eval, const char* sz,
|
||||
step_vars_storage *step_vars)
|
||||
{
|
||||
eval->lspend = eval->linebuf;
|
||||
- append_to_linebuf(eval, sz, step_vars);
|
||||
+ return append_to_linebuf(eval, sz, step_vars);
|
||||
}
|
||||
|
||||
/*
|
||||
* append_to_holdbuf
|
||||
*/
|
||||
-static void append_to_holdbuf(sed_eval_t *eval, const char* sz)
|
||||
+static apr_status_t append_to_holdbuf(sed_eval_t *eval, const char* sz)
|
||||
{
|
||||
apr_size_t len = strlen(sz);
|
||||
apr_size_t reqsize = (eval->hspend - eval->holdbuf) + len + 1;
|
||||
+ apr_status_t rc = 0;
|
||||
if (eval->hsize <= reqsize) {
|
||||
- grow_hold_buffer(eval, reqsize);
|
||||
+ rc = grow_hold_buffer(eval, reqsize);
|
||||
+ if (rc != APR_SUCCESS) {
|
||||
+ return rc;
|
||||
+ }
|
||||
}
|
||||
memcpy(eval->hspend, sz, len + 1);
|
||||
/* hspend will now point to NULL character */
|
||||
eval->hspend += len;
|
||||
+ return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy_to_holdbuf
|
||||
*/
|
||||
-static void copy_to_holdbuf(sed_eval_t *eval, const char* sz)
|
||||
+static apr_status_t copy_to_holdbuf(sed_eval_t *eval, const char* sz)
|
||||
{
|
||||
eval->hspend = eval->holdbuf;
|
||||
- append_to_holdbuf(eval, sz);
|
||||
+ return append_to_holdbuf(eval, sz);
|
||||
}
|
||||
|
||||
/*
|
||||
* append_to_genbuf
|
||||
*/
|
||||
-static void append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend)
|
||||
+static apr_status_t append_to_genbuf(sed_eval_t *eval, const char* sz, char **gspend)
|
||||
{
|
||||
apr_size_t len = strlen(sz);
|
||||
apr_size_t reqsize = (*gspend - eval->genbuf) + len + 1;
|
||||
+ apr_status_t rc = 0;
|
||||
if (eval->gsize < reqsize) {
|
||||
- grow_gen_buffer(eval, reqsize, gspend);
|
||||
+ rc = grow_gen_buffer(eval, reqsize, gspend);
|
||||
+ if (rc != APR_SUCCESS) {
|
||||
+ return rc;
|
||||
+ }
|
||||
}
|
||||
memcpy(*gspend, sz, len + 1);
|
||||
/* *gspend will now point to NULL character */
|
||||
*gspend += len;
|
||||
+ return APR_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy_to_genbuf
|
||||
*/
|
||||
-static void copy_to_genbuf(sed_eval_t *eval, const char* sz)
|
||||
+static apr_status_t copy_to_genbuf(sed_eval_t *eval, const char* sz)
|
||||
{
|
||||
apr_size_t len = strlen(sz);
|
||||
apr_size_t reqsize = len + 1;
|
||||
+ apr_status_t rc = APR_SUCCESS;;
|
||||
if (eval->gsize < reqsize) {
|
||||
- grow_gen_buffer(eval, reqsize, NULL);
|
||||
+ rc = grow_gen_buffer(eval, reqsize, NULL);
|
||||
+ if (rc != APR_SUCCESS) {
|
||||
+ return rc;
|
||||
+ }
|
||||
}
|
||||
memcpy(eval->genbuf, sz, len + 1);
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -397,6 +432,7 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz
|
||||
}
|
||||
|
||||
while (bufsz) {
|
||||
+ apr_status_t rc = 0;
|
||||
char *n;
|
||||
apr_size_t llen;
|
||||
|
||||
@@ -411,7 +447,10 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz
|
||||
break;
|
||||
}
|
||||
|
||||
- appendmem_to_linebuf(eval, buf, llen + 1);
|
||||
+ rc = appendmem_to_linebuf(eval, buf, llen + 1);
|
||||
+ if (rc != APR_SUCCESS) {
|
||||
+ return rc;
|
||||
+ }
|
||||
--eval->lspend;
|
||||
/* replace new line character with NULL */
|
||||
*eval->lspend = '\0';
|
||||
@@ -426,7 +465,10 @@ apr_status_t sed_eval_buffer(sed_eval_t *eval, const char *buf, apr_size_t bufsz
|
||||
|
||||
/* Save the leftovers for later */
|
||||
if (bufsz) {
|
||||
- appendmem_to_linebuf(eval, buf, bufsz);
|
||||
+ apr_status_t rc = appendmem_to_linebuf(eval, buf, bufsz);
|
||||
+ if (rc != APR_SUCCESS) {
|
||||
+ return rc;
|
||||
+ }
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
@@ -448,6 +490,7 @@ apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout)
|
||||
/* Process leftovers */
|
||||
if (eval->lspend > eval->linebuf) {
|
||||
apr_status_t rv;
|
||||
+ apr_status_t rc = 0;
|
||||
|
||||
if (eval->lreadyflag) {
|
||||
eval->lreadyflag = 0;
|
||||
@@ -457,7 +500,10 @@ apr_status_t sed_finalize_eval(sed_eval_t *eval, void *fout)
|
||||
* buffer is not a newline.
|
||||
*/
|
||||
/* Assure space for NULL */
|
||||
- append_to_linebuf(eval, "", NULL);
|
||||
+ rc = append_to_linebuf(eval, "", NULL);
|
||||
+ if (rc != APR_SUCCESS) {
|
||||
+ return rc;
|
||||
+ }
|
||||
}
|
||||
|
||||
*eval->lspend = '\0';
|
||||
@@ -655,11 +701,15 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
|
||||
sp = eval->genbuf;
|
||||
rp = rhsbuf;
|
||||
sp = place(eval, sp, lp, step_vars->loc1);
|
||||
+ if (sp == NULL) {
|
||||
+ return APR_EGENERAL;
|
||||
+ }
|
||||
while ((c = *rp++) != 0) {
|
||||
if (c == '&') {
|
||||
sp = place(eval, sp, step_vars->loc1, step_vars->loc2);
|
||||
- if (sp == NULL)
|
||||
+ if (sp == NULL) {
|
||||
return APR_EGENERAL;
|
||||
+ }
|
||||
}
|
||||
else if (c == '\\') {
|
||||
c = *rp++;
|
||||
@@ -675,13 +725,19 @@ static apr_status_t dosub(sed_eval_t *eval, char *rhsbuf, int n,
|
||||
*sp++ = c;
|
||||
if (sp >= eval->genbuf + eval->gsize) {
|
||||
/* expand genbuf and set the sp appropriately */
|
||||
- grow_gen_buffer(eval, eval->gsize + 1024, &sp);
|
||||
+ rv = grow_gen_buffer(eval, eval->gsize + 1024, &sp);
|
||||
+ if (rv != APR_SUCCESS) {
|
||||
+ return rv;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
lp = step_vars->loc2;
|
||||
step_vars->loc2 = sp - eval->genbuf + eval->linebuf;
|
||||
- append_to_genbuf(eval, lp, &sp);
|
||||
- copy_to_linebuf(eval, eval->genbuf, step_vars);
|
||||
+ rv = append_to_genbuf(eval, lp, &sp);
|
||||
+ if (rv != APR_SUCCESS) {
|
||||
+ return rv;
|
||||
+ }
|
||||
+ rv = copy_to_linebuf(eval, eval->genbuf, step_vars);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -695,7 +751,10 @@ static char *place(sed_eval_t *eval, char *asp, char *al1, char *al2)
|
||||
apr_size_t reqsize = (sp - eval->genbuf) + n + 1;
|
||||
|
||||
if (eval->gsize < reqsize) {
|
||||
- grow_gen_buffer(eval, reqsize, &sp);
|
||||
+ apr_status_t rc = grow_gen_buffer(eval, reqsize, &sp);
|
||||
+ if (rc != APR_SUCCESS) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
}
|
||||
memcpy(sp, al1, n);
|
||||
return sp + n;
|
||||
@@ -750,7 +809,8 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
|
||||
}
|
||||
|
||||
p1++;
|
||||
- copy_to_linebuf(eval, p1, step_vars);
|
||||
+ rv = copy_to_linebuf(eval, p1, step_vars);
|
||||
+ if (rv != APR_SUCCESS) return rv;
|
||||
eval->jflag++;
|
||||
break;
|
||||
|
||||
@@ -760,21 +820,27 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
|
||||
break;
|
||||
|
||||
case GCOM:
|
||||
- copy_to_linebuf(eval, eval->holdbuf, step_vars);
|
||||
+ rv = copy_to_linebuf(eval, eval->holdbuf, step_vars);
|
||||
+ if (rv != APR_SUCCESS) return rv;
|
||||
break;
|
||||
|
||||
case CGCOM:
|
||||
- append_to_linebuf(eval, "\n", step_vars);
|
||||
- append_to_linebuf(eval, eval->holdbuf, step_vars);
|
||||
+ rv = append_to_linebuf(eval, "\n", step_vars);
|
||||
+ if (rv != APR_SUCCESS) return rv;
|
||||
+ rv = append_to_linebuf(eval, eval->holdbuf, step_vars);
|
||||
+ if (rv != APR_SUCCESS) return rv;
|
||||
break;
|
||||
|
||||
case HCOM:
|
||||
- copy_to_holdbuf(eval, eval->linebuf);
|
||||
+ rv = copy_to_holdbuf(eval, eval->linebuf);
|
||||
+ if (rv != APR_SUCCESS) return rv;
|
||||
break;
|
||||
|
||||
case CHCOM:
|
||||
- append_to_holdbuf(eval, "\n");
|
||||
- append_to_holdbuf(eval, eval->linebuf);
|
||||
+ rv = append_to_holdbuf(eval, "\n");
|
||||
+ if (rv != APR_SUCCESS) return rv;
|
||||
+ rv = append_to_holdbuf(eval, eval->linebuf);
|
||||
+ if (rv != APR_SUCCESS) return rv;
|
||||
break;
|
||||
|
||||
case ICOM:
|
||||
@@ -896,7 +962,8 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
|
||||
if (rv != APR_SUCCESS)
|
||||
return rv;
|
||||
}
|
||||
- append_to_linebuf(eval, "\n", step_vars);
|
||||
+ rv = append_to_linebuf(eval, "\n", step_vars);
|
||||
+ if (rv != APR_SUCCESS) return rv;
|
||||
eval->pending = ipc->next;
|
||||
break;
|
||||
|
||||
@@ -970,9 +1037,12 @@ static apr_status_t command(sed_eval_t *eval, sed_reptr_t *ipc,
|
||||
break;
|
||||
|
||||
case XCOM:
|
||||
- copy_to_genbuf(eval, eval->linebuf);
|
||||
- copy_to_linebuf(eval, eval->holdbuf, step_vars);
|
||||
- copy_to_holdbuf(eval, eval->genbuf);
|
||||
+ rv = copy_to_genbuf(eval, eval->linebuf);
|
||||
+ if (rv != APR_SUCCESS) return rv;
|
||||
+ rv = copy_to_linebuf(eval, eval->holdbuf, step_vars);
|
||||
+ if (rv != APR_SUCCESS) return rv;
|
||||
+ rv = copy_to_holdbuf(eval, eval->genbuf);
|
||||
+ if (rv != APR_SUCCESS) return rv;
|
||||
break;
|
||||
|
||||
case YCOM:
|
|
@ -1,246 +0,0 @@
|
|||
From 3a561759fcb37af179585adb8478922dc9bc6a85 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Covener <covener@apache.org>
|
||||
Date: Wed, 1 Jun 2022 12:36:39 +0000
|
||||
Subject: [PATCH] Merge r1901502 from trunk:
|
||||
|
||||
use filters consistently
|
||||
|
||||
|
||||
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1901503 13f79535-47bb-0310-9956-ffa450edef68
|
||||
---
|
||||
modules/lua/lua_request.c | 144 ++++++++++++++------------------------
|
||||
1 file changed, 53 insertions(+), 91 deletions(-)
|
||||
|
||||
diff --git a/modules/lua/lua_request.c b/modules/lua/lua_request.c
|
||||
index a3e3b613bc9..2ec453e86b4 100644
|
||||
--- a/modules/lua/lua_request.c
|
||||
+++ b/modules/lua/lua_request.c
|
||||
@@ -2227,23 +2227,20 @@ static int lua_websocket_greet(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static apr_status_t lua_websocket_readbytes(conn_rec* c, char* buffer,
|
||||
- apr_off_t len)
|
||||
+static apr_status_t lua_websocket_readbytes(conn_rec* c,
|
||||
+ apr_bucket_brigade *brigade,
|
||||
+ char* buffer, apr_off_t len)
|
||||
{
|
||||
- apr_bucket_brigade *brigade = apr_brigade_create(c->pool, c->bucket_alloc);
|
||||
+ apr_size_t delivered;
|
||||
apr_status_t rv;
|
||||
+
|
||||
rv = ap_get_brigade(c->input_filters, brigade, AP_MODE_READBYTES,
|
||||
APR_BLOCK_READ, len);
|
||||
if (rv == APR_SUCCESS) {
|
||||
- if (!APR_BRIGADE_EMPTY(brigade)) {
|
||||
- apr_bucket* bucket = APR_BRIGADE_FIRST(brigade);
|
||||
- const char* data = NULL;
|
||||
- apr_size_t data_length = 0;
|
||||
- rv = apr_bucket_read(bucket, &data, &data_length, APR_BLOCK_READ);
|
||||
- if (rv == APR_SUCCESS) {
|
||||
- memcpy(buffer, data, len);
|
||||
- }
|
||||
- apr_bucket_delete(bucket);
|
||||
+ delivered = len;
|
||||
+ rv = apr_brigade_flatten(brigade, buffer, &delivered);
|
||||
+ if ((rv == APR_SUCCESS) && (delivered < len)) {
|
||||
+ rv = APR_INCOMPLETE;
|
||||
}
|
||||
}
|
||||
apr_brigade_cleanup(brigade);
|
||||
@@ -2273,35 +2270,28 @@ static int lua_websocket_peek(lua_State *L)
|
||||
|
||||
static int lua_websocket_read(lua_State *L)
|
||||
{
|
||||
- apr_socket_t *sock;
|
||||
apr_status_t rv;
|
||||
int do_read = 1;
|
||||
int n = 0;
|
||||
- apr_size_t len = 1;
|
||||
apr_size_t plen = 0;
|
||||
unsigned short payload_short = 0;
|
||||
apr_uint64_t payload_long = 0;
|
||||
unsigned char *mask_bytes;
|
||||
char byte;
|
||||
- int plaintext;
|
||||
-
|
||||
-
|
||||
+ apr_bucket_brigade *brigade;
|
||||
+ conn_rec* c;
|
||||
+
|
||||
request_rec *r = ap_lua_check_request_rec(L, 1);
|
||||
- plaintext = ap_lua_ssl_is_https(r->connection) ? 0 : 1;
|
||||
+ c = r->connection;
|
||||
|
||||
-
|
||||
mask_bytes = apr_pcalloc(r->pool, 4);
|
||||
- sock = ap_get_conn_socket(r->connection);
|
||||
+
|
||||
+ brigade = apr_brigade_create(r->pool, c->bucket_alloc);
|
||||
|
||||
while (do_read) {
|
||||
do_read = 0;
|
||||
/* Get opcode and FIN bit */
|
||||
- if (plaintext) {
|
||||
- rv = apr_socket_recv(sock, &byte, &len);
|
||||
- }
|
||||
- else {
|
||||
- rv = lua_websocket_readbytes(r->connection, &byte, 1);
|
||||
- }
|
||||
+ rv = lua_websocket_readbytes(c, brigade, &byte, 1);
|
||||
if (rv == APR_SUCCESS) {
|
||||
unsigned char ubyte, fin, opcode, mask, payload;
|
||||
ubyte = (unsigned char)byte;
|
||||
@@ -2311,12 +2301,7 @@ static int lua_websocket_read(lua_State *L)
|
||||
opcode = ubyte & 0xf;
|
||||
|
||||
/* Get the payload length and mask bit */
|
||||
- if (plaintext) {
|
||||
- rv = apr_socket_recv(sock, &byte, &len);
|
||||
- }
|
||||
- else {
|
||||
- rv = lua_websocket_readbytes(r->connection, &byte, 1);
|
||||
- }
|
||||
+ rv = lua_websocket_readbytes(c, brigade, &byte, 1);
|
||||
if (rv == APR_SUCCESS) {
|
||||
ubyte = (unsigned char)byte;
|
||||
/* Mask is the first bit */
|
||||
@@ -2327,40 +2312,25 @@ static int lua_websocket_read(lua_State *L)
|
||||
|
||||
/* Extended payload? */
|
||||
if (payload == 126) {
|
||||
- len = 2;
|
||||
- if (plaintext) {
|
||||
- /* XXX: apr_socket_recv does not receive len bits, only up to len bits! */
|
||||
- rv = apr_socket_recv(sock, (char*) &payload_short, &len);
|
||||
- }
|
||||
- else {
|
||||
- rv = lua_websocket_readbytes(r->connection,
|
||||
- (char*) &payload_short, 2);
|
||||
- }
|
||||
- payload_short = ntohs(payload_short);
|
||||
+ rv = lua_websocket_readbytes(c, brigade,
|
||||
+ (char*) &payload_short, 2);
|
||||
|
||||
- if (rv == APR_SUCCESS) {
|
||||
- plen = payload_short;
|
||||
- }
|
||||
- else {
|
||||
+ if (rv != APR_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+ plen = ntohs(payload_short);
|
||||
}
|
||||
/* Super duper extended payload? */
|
||||
if (payload == 127) {
|
||||
- len = 8;
|
||||
- if (plaintext) {
|
||||
- rv = apr_socket_recv(sock, (char*) &payload_long, &len);
|
||||
- }
|
||||
- else {
|
||||
- rv = lua_websocket_readbytes(r->connection,
|
||||
- (char*) &payload_long, 8);
|
||||
- }
|
||||
- if (rv == APR_SUCCESS) {
|
||||
- plen = ap_ntoh64(&payload_long);
|
||||
- }
|
||||
- else {
|
||||
+ rv = lua_websocket_readbytes(c, brigade,
|
||||
+ (char*) &payload_long, 8);
|
||||
+
|
||||
+ if (rv != APR_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+ plen = ap_ntoh64(&payload_long);
|
||||
}
|
||||
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(03210)
|
||||
"Websocket: Reading %" APR_SIZE_T_FMT " (%s) bytes, masking is %s. %s",
|
||||
@@ -2369,46 +2339,27 @@ static int lua_websocket_read(lua_State *L)
|
||||
mask ? "on" : "off",
|
||||
fin ? "This is a final frame" : "more to follow");
|
||||
if (mask) {
|
||||
- len = 4;
|
||||
- if (plaintext) {
|
||||
- rv = apr_socket_recv(sock, (char*) mask_bytes, &len);
|
||||
- }
|
||||
- else {
|
||||
- rv = lua_websocket_readbytes(r->connection,
|
||||
- (char*) mask_bytes, 4);
|
||||
- }
|
||||
+ rv = lua_websocket_readbytes(c, brigade,
|
||||
+ (char*) mask_bytes, 4);
|
||||
+
|
||||
if (rv != APR_SUCCESS) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (plen < (HUGE_STRING_LEN*1024) && plen > 0) {
|
||||
apr_size_t remaining = plen;
|
||||
- apr_size_t received;
|
||||
- apr_off_t at = 0;
|
||||
char *buffer = apr_palloc(r->pool, plen+1);
|
||||
buffer[plen] = 0;
|
||||
|
||||
- if (plaintext) {
|
||||
- while (remaining > 0) {
|
||||
- received = remaining;
|
||||
- rv = apr_socket_recv(sock, buffer+at, &received);
|
||||
- if (received > 0 ) {
|
||||
- remaining -= received;
|
||||
- at += received;
|
||||
- }
|
||||
- }
|
||||
- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
|
||||
- "Websocket: Frame contained %" APR_OFF_T_FMT " bytes, pushed to Lua stack",
|
||||
- at);
|
||||
- }
|
||||
- else {
|
||||
- rv = lua_websocket_readbytes(r->connection, buffer,
|
||||
- remaining);
|
||||
- ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
|
||||
- "Websocket: SSL Frame contained %" APR_SIZE_T_FMT " bytes, "\
|
||||
- "pushed to Lua stack",
|
||||
- remaining);
|
||||
+ rv = lua_websocket_readbytes(c, brigade, buffer, remaining);
|
||||
+
|
||||
+ if (rv != APR_SUCCESS) {
|
||||
+ return 0;
|
||||
}
|
||||
+
|
||||
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
|
||||
+ "Websocket: Frame contained %" APR_SIZE_T_FMT \
|
||||
+ " bytes, pushed to Lua stack", remaining);
|
||||
if (mask) {
|
||||
for (n = 0; n < plen; n++) {
|
||||
buffer[n] ^= mask_bytes[n%4];
|
||||
@@ -2420,14 +2371,25 @@ static int lua_websocket_read(lua_State *L)
|
||||
return 2;
|
||||
}
|
||||
|
||||
-
|
||||
/* Decide if we need to react to the opcode or not */
|
||||
if (opcode == 0x09) { /* ping */
|
||||
char frame[2];
|
||||
- plen = 2;
|
||||
+ apr_bucket *b;
|
||||
+
|
||||
frame[0] = 0x8A;
|
||||
frame[1] = 0;
|
||||
- apr_socket_send(sock, frame, &plen); /* Pong! */
|
||||
+
|
||||
+ /* Pong! */
|
||||
+ b = apr_bucket_transient_create(frame, 2, c->bucket_alloc);
|
||||
+ APR_BRIGADE_INSERT_TAIL(brigade, b);
|
||||
+
|
||||
+ rv = ap_pass_brigade(c->output_filters, brigade);
|
||||
+ apr_brigade_cleanup(brigade);
|
||||
+
|
||||
+ if (rv != APR_SUCCESS) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
do_read = 1;
|
||||
}
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
|
||||
index 3af5aed..bc86253 100644
|
||||
--- a/modules/proxy/proxy_util.c
|
||||
+++ b/modules/proxy/proxy_util.c
|
||||
@@ -3854,12 +3854,14 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
char **old_cl_val,
|
||||
char **old_te_val)
|
||||
{
|
||||
+ int rc = OK;
|
||||
conn_rec *c = r->connection;
|
||||
int counter;
|
||||
char *buf;
|
||||
+ apr_table_t *saved_headers_in = r->headers_in;
|
||||
+ const char *saved_host = apr_table_get(saved_headers_in, "Host");
|
||||
const apr_array_header_t *headers_in_array;
|
||||
const apr_table_entry_t *headers_in;
|
||||
- apr_table_t *saved_headers_in;
|
||||
apr_bucket *e;
|
||||
int do_100_continue;
|
||||
conn_rec *origin = p_conn->connection;
|
||||
@@ -3896,6 +3898,52 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
ap_xlate_proto_to_ascii(buf, strlen(buf));
|
||||
e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(header_brigade, e);
|
||||
+
|
||||
+ /*
|
||||
+ * Make a copy on r->headers_in for the request we make to the backend,
|
||||
+ * modify the copy in place according to our configuration and connection
|
||||
+ * handling, use it to fill in the forwarded headers' brigade, and finally
|
||||
+ * restore the saved/original ones in r->headers_in.
|
||||
+ *
|
||||
+ * Note: We need to take r->pool for apr_table_copy as the key / value
|
||||
+ * pairs in r->headers_in have been created out of r->pool and
|
||||
+ * p might be (and actually is) a longer living pool.
|
||||
+ * This would trigger the bad pool ancestry abort in apr_table_copy if
|
||||
+ * apr is compiled with APR_POOL_DEBUG.
|
||||
+ *
|
||||
+ * icing: if p indeed lives longer than r->pool, we should allocate
|
||||
+ * all new header values from r->pool as well and avoid leakage.
|
||||
+ */
|
||||
+ r->headers_in = apr_table_copy(r->pool, saved_headers_in);
|
||||
+
|
||||
+ /* Return the original Transfer-Encoding and/or Content-Length values
|
||||
+ * then drop the headers, they must be set by the proxy handler based
|
||||
+ * on the actual body being forwarded.
|
||||
+ */
|
||||
+ if ((*old_te_val = (char *)apr_table_get(r->headers_in,
|
||||
+ "Transfer-Encoding"))) {
|
||||
+ apr_table_unset(r->headers_in, "Transfer-Encoding");
|
||||
+ }
|
||||
+ if ((*old_cl_val = (char *)apr_table_get(r->headers_in,
|
||||
+ "Content-Length"))) {
|
||||
+ apr_table_unset(r->headers_in, "Content-Length");
|
||||
+ }
|
||||
+
|
||||
+ /* Clear out hop-by-hop request headers not to forward */
|
||||
+ if (ap_proxy_clear_connection(r, r->headers_in) < 0) {
|
||||
+ rc = HTTP_BAD_REQUEST;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* RFC2616 13.5.1 says we should strip these */
|
||||
+ apr_table_unset(r->headers_in, "Keep-Alive");
|
||||
+ apr_table_unset(r->headers_in, "Upgrade");
|
||||
+ apr_table_unset(r->headers_in, "Trailer");
|
||||
+ apr_table_unset(r->headers_in, "TE");
|
||||
+
|
||||
+ /* We used to send `Host: ` always first, so let's keep it that
|
||||
+ * way. No telling which legacy backend is relying no this.
|
||||
+ */
|
||||
if (dconf->preserve_host == 0) {
|
||||
if (ap_strchr_c(uri->hostname, ':')) { /* if literal IPv6 address */
|
||||
if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) {
|
||||
@@ -3917,7 +3965,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
/* don't want to use r->hostname, as the incoming header might have a
|
||||
* port attached
|
||||
*/
|
||||
- const char* hostname = apr_table_get(r->headers_in,"Host");
|
||||
+ const char* hostname = saved_host;
|
||||
if (!hostname) {
|
||||
hostname = r->server->server_hostname;
|
||||
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01092)
|
||||
@@ -3931,21 +3979,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
ap_xlate_proto_to_ascii(buf, strlen(buf));
|
||||
e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc);
|
||||
APR_BRIGADE_INSERT_TAIL(header_brigade, e);
|
||||
-
|
||||
- /*
|
||||
- * Save the original headers in here and restore them when leaving, since
|
||||
- * we will apply proxy purpose only modifications (eg. clearing hop-by-hop
|
||||
- * headers, add Via or X-Forwarded-* or Expect...), whereas the originals
|
||||
- * will be needed later to prepare the correct response and logging.
|
||||
- *
|
||||
- * Note: We need to take r->pool for apr_table_copy as the key / value
|
||||
- * pairs in r->headers_in have been created out of r->pool and
|
||||
- * p might be (and actually is) a longer living pool.
|
||||
- * This would trigger the bad pool ancestry abort in apr_table_copy if
|
||||
- * apr is compiled with APR_POOL_DEBUG.
|
||||
- */
|
||||
- saved_headers_in = r->headers_in;
|
||||
- r->headers_in = apr_table_copy(r->pool, saved_headers_in);
|
||||
+ apr_table_unset(r->headers_in, "Host");
|
||||
|
||||
/* handle Via */
|
||||
if (conf->viaopt == via_block) {
|
||||
@@ -4012,8 +4046,6 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
*/
|
||||
if (dconf->add_forwarded_headers) {
|
||||
if (PROXYREQ_REVERSE == r->proxyreq) {
|
||||
- const char *buf;
|
||||
-
|
||||
/* Add X-Forwarded-For: so that the upstream has a chance to
|
||||
* determine, where the original request came from.
|
||||
*/
|
||||
@@ -4023,8 +4055,9 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
/* Add X-Forwarded-Host: so that upstream knows what the
|
||||
* original request hostname was.
|
||||
*/
|
||||
- if ((buf = apr_table_get(r->headers_in, "Host"))) {
|
||||
- apr_table_mergen(r->headers_in, "X-Forwarded-Host", buf);
|
||||
+ if (saved_host) {
|
||||
+ apr_table_mergen(r->headers_in, "X-Forwarded-Host",
|
||||
+ saved_host);
|
||||
}
|
||||
|
||||
/* Add X-Forwarded-Server: so that upstream knows what the
|
||||
@@ -4036,11 +4069,28 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
}
|
||||
}
|
||||
|
||||
- proxy_run_fixups(r);
|
||||
- if (ap_proxy_clear_connection(r, r->headers_in) < 0) {
|
||||
- return HTTP_BAD_REQUEST;
|
||||
+ /* Do we want to strip Proxy-Authorization ?
|
||||
+ * If we haven't used it, then NO
|
||||
+ * If we have used it then MAYBE: RFC2616 says we MAY propagate it.
|
||||
+ * So let's make it configurable by env.
|
||||
+ */
|
||||
+ if (r->user != NULL /* we've authenticated */
|
||||
+ && !apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) {
|
||||
+ apr_table_unset(r->headers_in, "Proxy-Authorization");
|
||||
}
|
||||
|
||||
+ /* for sub-requests, ignore freshness/expiry headers */
|
||||
+ if (r->main) {
|
||||
+ apr_table_unset(r->headers_in, "If-Match");
|
||||
+ apr_table_unset(r->headers_in, "If-Modified-Since");
|
||||
+ apr_table_unset(r->headers_in, "If-Range");
|
||||
+ apr_table_unset(r->headers_in, "If-Unmodified-Since");
|
||||
+ apr_table_unset(r->headers_in, "If-None-Match");
|
||||
+ }
|
||||
+
|
||||
+ /* run hook to fixup the request we are about to send */
|
||||
+ proxy_run_fixups(r);
|
||||
+
|
||||
creds = apr_table_get(r->notes, "proxy-basic-creds");
|
||||
if (creds) {
|
||||
apr_table_mergen(r->headers_in, "Proxy-Authorization", creds);
|
||||
@@ -4051,55 +4101,8 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
headers_in = (const apr_table_entry_t *) headers_in_array->elts;
|
||||
for (counter = 0; counter < headers_in_array->nelts; counter++) {
|
||||
if (headers_in[counter].key == NULL
|
||||
- || headers_in[counter].val == NULL
|
||||
-
|
||||
- /* Already sent */
|
||||
- || !ap_cstr_casecmp(headers_in[counter].key, "Host")
|
||||
-
|
||||
- /* Clear out hop-by-hop request headers not to send
|
||||
- * RFC2616 13.5.1 says we should strip these headers
|
||||
- */
|
||||
- || !ap_cstr_casecmp(headers_in[counter].key, "Keep-Alive")
|
||||
- || !ap_cstr_casecmp(headers_in[counter].key, "TE")
|
||||
- || !ap_cstr_casecmp(headers_in[counter].key, "Trailer")
|
||||
- || !ap_cstr_casecmp(headers_in[counter].key, "Upgrade")
|
||||
-
|
||||
- ) {
|
||||
- continue;
|
||||
- }
|
||||
- /* Do we want to strip Proxy-Authorization ?
|
||||
- * If we haven't used it, then NO
|
||||
- * If we have used it then MAYBE: RFC2616 says we MAY propagate it.
|
||||
- * So let's make it configurable by env.
|
||||
- */
|
||||
- if (!ap_cstr_casecmp(headers_in[counter].key,"Proxy-Authorization")) {
|
||||
- if (r->user != NULL) { /* we've authenticated */
|
||||
- if (!apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) {
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* Skip Transfer-Encoding and Content-Length for now.
|
||||
- */
|
||||
- if (!ap_cstr_casecmp(headers_in[counter].key, "Transfer-Encoding")) {
|
||||
- *old_te_val = headers_in[counter].val;
|
||||
- continue;
|
||||
- }
|
||||
- if (!ap_cstr_casecmp(headers_in[counter].key, "Content-Length")) {
|
||||
- *old_cl_val = headers_in[counter].val;
|
||||
- continue;
|
||||
- }
|
||||
-
|
||||
- /* for sub-requests, ignore freshness/expiry headers */
|
||||
- if (r->main) {
|
||||
- if ( !ap_cstr_casecmp(headers_in[counter].key, "If-Match")
|
||||
- || !ap_cstr_casecmp(headers_in[counter].key, "If-Modified-Since")
|
||||
- || !ap_cstr_casecmp(headers_in[counter].key, "If-Range")
|
||||
- || !ap_cstr_casecmp(headers_in[counter].key, "If-Unmodified-Since")
|
||||
- || !ap_cstr_casecmp(headers_in[counter].key, "If-None-Match")) {
|
||||
- continue;
|
||||
- }
|
||||
+ || headers_in[counter].val == NULL) {
|
||||
+ continue;
|
||||
}
|
||||
|
||||
buf = apr_pstrcat(p, headers_in[counter].key, ": ",
|
||||
@@ -4110,11 +4113,9 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
|
||||
APR_BRIGADE_INSERT_TAIL(header_brigade, e);
|
||||
}
|
||||
|
||||
- /* Restore the original headers in (see comment above),
|
||||
- * we won't modify them anymore.
|
||||
- */
|
||||
+cleanup:
|
||||
r->headers_in = saved_headers_in;
|
||||
- return OK;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
PROXY_DECLARE(int) ap_proxy_prefetch_input(request_rec *r,
|
|
@ -1,45 +0,0 @@
|
|||
diff --git a/Makefile.in b/Makefile.in
|
||||
index a2e9c82..bd8045c 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -4,7 +4,7 @@ CLEAN_SUBDIRS = test
|
||||
|
||||
PROGRAM_NAME = $(progname)
|
||||
PROGRAM_SOURCES = modules.c
|
||||
-PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(PCRE_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
|
||||
+PROGRAM_LDADD = buildmark.o $(HTTPD_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(HTTPD_LIBS) $(EXTRA_LIBS) $(AP_LIBS) $(LIBS)
|
||||
PROGRAM_PRELINK = $(COMPILE) -c $(top_srcdir)/server/buildmark.c
|
||||
PROGRAM_DEPENDENCIES = \
|
||||
server/libmain.la \
|
||||
diff --git a/acinclude.m4 b/acinclude.m4
|
||||
index 97484c9..05abe18 100644
|
||||
--- a/acinclude.m4
|
||||
+++ b/acinclude.m4
|
||||
@@ -631,6 +631,7 @@ case $host in
|
||||
if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
|
||||
AC_MSG_WARN([Your system does not support systemd.])
|
||||
else
|
||||
+ APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS])
|
||||
AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported])
|
||||
fi
|
||||
fi
|
||||
diff --git a/configure.in b/configure.in
|
||||
index cf437fe..521fc45 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -239,6 +239,7 @@ if test "x$PCRE_CONFIG" != "x"; then
|
||||
AC_MSG_NOTICE([Using external PCRE library from $PCRE_CONFIG])
|
||||
APR_ADDTO(PCRE_INCLUDES, [`$PCRE_CONFIG --cflags`])
|
||||
APR_ADDTO(PCRE_LIBS, [`$PCRE_CONFIG --libs8 2>/dev/null || $PCRE_CONFIG --libs`])
|
||||
+ APR_ADDTO(HTTPD_LIBS, [\$(PCRE_LIBS)])
|
||||
else
|
||||
AC_MSG_ERROR([pcre(2)-config for libpcre not found. PCRE is required and available from http://pcre.org/])
|
||||
fi
|
||||
@@ -734,6 +735,7 @@ APACHE_SUBST(OS_DIR)
|
||||
APACHE_SUBST(BUILTIN_LIBS)
|
||||
APACHE_SUBST(SHLIBPATH_VAR)
|
||||
APACHE_SUBST(OS_SPECIFIC_VARS)
|
||||
+APACHE_SUBST(HTTPD_LIBS)
|
||||
|
||||
PRE_SHARED_CMDS='echo ""'
|
||||
POST_SHARED_CMDS='echo ""'
|
|
@ -1,49 +0,0 @@
|
|||
diff --git a/docs/conf/extra/httpd-autoindex.conf.in b/docs/conf/extra/httpd-autoindex.conf.in
|
||||
index 51b02ed..93a2b87 100644
|
||||
--- a/docs/conf/extra/httpd-autoindex.conf.in
|
||||
+++ b/docs/conf/extra/httpd-autoindex.conf.in
|
||||
@@ -21,7 +21,7 @@ IndexOptions FancyIndexing HTMLTable VersionSort
|
||||
Alias /icons/ "@exp_iconsdir@/"
|
||||
|
||||
<Directory "@exp_iconsdir@">
|
||||
- Options Indexes MultiViews
|
||||
+ Options Indexes MultiViews FollowSymlinks
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
@@ -37,6 +37,7 @@ AddIconByType (TXT,/icons/text.gif) text/*
|
||||
AddIconByType (IMG,/icons/image2.gif) image/*
|
||||
AddIconByType (SND,/icons/sound2.gif) audio/*
|
||||
AddIconByType (VID,/icons/movie.gif) video/*
|
||||
+AddIconByType /icons/bomb.gif application/x-coredump
|
||||
|
||||
AddIcon /icons/binary.gif .bin .exe
|
||||
AddIcon /icons/binhex.gif .hqx
|
||||
@@ -53,7 +54,6 @@ AddIcon /icons/dvi.gif .dvi
|
||||
AddIcon /icons/uuencoded.gif .uu
|
||||
AddIcon /icons/script.gif .conf .sh .shar .csh .ksh .tcl
|
||||
AddIcon /icons/tex.gif .tex
|
||||
-AddIcon /icons/bomb.gif core
|
||||
|
||||
AddIcon /icons/back.gif ..
|
||||
AddIcon /icons/hand.right.gif README
|
||||
diff --git a/docs/conf/magic b/docs/conf/magic
|
||||
index bc891d9..9a41b44 100644
|
||||
--- a/docs/conf/magic
|
||||
+++ b/docs/conf/magic
|
||||
@@ -383,3 +383,15 @@
|
||||
4 string moov video/quicktime
|
||||
4 string mdat video/quicktime
|
||||
|
||||
+
|
||||
+#------------------------------------------------------------------------------
|
||||
+# application/x-coredump for LE/BE ELF
|
||||
+#
|
||||
+0 string \177ELF
|
||||
+>5 byte 1
|
||||
+>16 leshort 4 application/x-coredump
|
||||
+
|
||||
+0 string \177ELF
|
||||
+>5 byte 2
|
||||
+>16 beshort 4 application/x-coredump
|
||||
+
|
|
@ -1,116 +0,0 @@
|
|||
diff --git a/include/util_ldap.h b/include/util_ldap.h
|
||||
index 28e0760..edb8a81 100644
|
||||
--- a/include/util_ldap.h
|
||||
+++ b/include/util_ldap.h
|
||||
@@ -32,7 +32,6 @@
|
||||
#if APR_MAJOR_VERSION < 2
|
||||
/* The LDAP API is currently only present in APR 1.x */
|
||||
#include "apr_ldap.h"
|
||||
-#include "apr_ldap_rebind.h"
|
||||
#else
|
||||
#define APR_HAS_LDAP 0
|
||||
#endif
|
||||
diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c
|
||||
index 4d92ec9..864bd62 100644
|
||||
--- a/modules/ldap/util_ldap.c
|
||||
+++ b/modules/ldap/util_ldap.c
|
||||
@@ -154,6 +154,38 @@ static int util_ldap_handler(request_rec *r)
|
||||
return OK;
|
||||
}
|
||||
|
||||
+/* For OpenLDAP with the 3-arg version of ldap_set_rebind_proc(), use
|
||||
+ * a simpler rebind callback than the implementation in APR-util.
|
||||
+ * Testing for API version >= 3001 appears safe although OpenLDAP
|
||||
+ * 2.1.x (API version = 2004) also has the 3-arg API. */
|
||||
+#if APR_HAS_OPENLDAP_LDAPSDK && defined(LDAP_API_VERSION) && LDAP_API_VERSION >= 3001
|
||||
+
|
||||
+#define uldap_rebind_init(p) APR_SUCCESS /* noop */
|
||||
+
|
||||
+static int uldap_rebind_proc(LDAP *ld, const char *url, ber_tag_t request,
|
||||
+ ber_int_t msgid, void *params)
|
||||
+{
|
||||
+ util_ldap_connection_t *ldc = params;
|
||||
+
|
||||
+ return ldap_bind_s(ld, ldc->binddn, ldc->bindpw, LDAP_AUTH_SIMPLE);
|
||||
+}
|
||||
+
|
||||
+static apr_status_t uldap_rebind_add(util_ldap_connection_t *ldc)
|
||||
+{
|
||||
+ ldap_set_rebind_proc(ldc->ldap, uldap_rebind_proc, ldc);
|
||||
+ return APR_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+#else /* !APR_HAS_OPENLDAP_LDAPSDK */
|
||||
+
|
||||
+#define USE_APR_LDAP_REBIND
|
||||
+#include <apr_ldap_rebind.h>
|
||||
+
|
||||
+#define uldap_rebind_init(p) apr_ldap_rebind_init(p)
|
||||
+#define uldap_rebind_add(ldc) apr_ldap_rebind_add((ldc)->rebind_pool, \
|
||||
+ (ldc)->ldap, (ldc)->binddn, \
|
||||
+ (ldc)->bindpw)
|
||||
+#endif
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
@@ -195,6 +227,13 @@ static apr_status_t uldap_connection_unbind(void *param)
|
||||
util_ldap_connection_t *ldc = param;
|
||||
|
||||
if (ldc) {
|
||||
+#ifdef USE_APR_LDAP_REBIND
|
||||
+ /* forget the rebind info for this conn */
|
||||
+ if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
|
||||
+ apr_pool_clear(ldc->rebind_pool);
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (ldc->ldap) {
|
||||
if (ldc->r) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, ldc->r, "LDC %pp unbind", ldc);
|
||||
@@ -203,12 +242,6 @@ static apr_status_t uldap_connection_unbind(void *param)
|
||||
ldc->ldap = NULL;
|
||||
}
|
||||
ldc->bound = 0;
|
||||
-
|
||||
- /* forget the rebind info for this conn */
|
||||
- if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
|
||||
- apr_ldap_rebind_remove(ldc->ldap);
|
||||
- apr_pool_clear(ldc->rebind_pool);
|
||||
- }
|
||||
}
|
||||
|
||||
return APR_SUCCESS;
|
||||
@@ -344,7 +377,7 @@ static int uldap_connection_init(request_rec *r,
|
||||
|
||||
if (ldc->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
|
||||
/* Now that we have an ldap struct, add it to the referral list for rebinds. */
|
||||
- rc = apr_ldap_rebind_add(ldc->rebind_pool, ldc->ldap, ldc->binddn, ldc->bindpw);
|
||||
+ rc = uldap_rebind_add(ldc);
|
||||
if (rc != APR_SUCCESS) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server, APLOGNO(01277)
|
||||
"LDAP: Unable to add rebind cross reference entry. Out of memory?");
|
||||
@@ -870,6 +903,7 @@ static util_ldap_connection_t *
|
||||
/* whether or not to keep this connection in the pool when it's returned */
|
||||
l->keep = (st->connection_pool_ttl == 0) ? 0 : 1;
|
||||
|
||||
+#ifdef USE_APR_LDAP_REBIND
|
||||
if (l->ChaseReferrals == AP_LDAP_CHASEREFERRALS_ON) {
|
||||
if (apr_pool_create(&(l->rebind_pool), l->pool) != APR_SUCCESS) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r, APLOGNO(01286)
|
||||
@@ -881,6 +915,7 @@ static util_ldap_connection_t *
|
||||
}
|
||||
apr_pool_tag(l->rebind_pool, "util_ldap_rebind");
|
||||
}
|
||||
+#endif
|
||||
|
||||
if (p) {
|
||||
p->next = l;
|
||||
@@ -3068,7 +3103,7 @@ static int util_ldap_post_config(apr_pool_t *p, apr_pool_t *plog,
|
||||
}
|
||||
|
||||
/* Initialize the rebind callback's cross reference list. */
|
||||
- apr_ldap_rebind_init (p);
|
||||
+ (void) uldap_rebind_init(p);
|
||||
|
||||
#ifdef AP_LDAP_OPT_DEBUG
|
||||
if (st->debug_level > 0) {
|
|
@ -1,336 +0,0 @@
|
|||
--- a/server/mpm/event/event.c 2022/05/24 08:59:30 1901198
|
||||
+++ b/server/mpm/event/event.c 2022/05/24 09:00:19 1901199
|
||||
@@ -379,7 +379,7 @@
|
||||
* We use this value to optimize routines that have to scan the entire
|
||||
* scoreboard.
|
||||
*/
|
||||
- int max_daemons_limit;
|
||||
+ int max_daemon_used;
|
||||
|
||||
/*
|
||||
* All running workers, active and shutting down, including those that
|
||||
@@ -645,7 +645,7 @@
|
||||
*rv = APR_SUCCESS;
|
||||
switch (query_code) {
|
||||
case AP_MPMQ_MAX_DAEMON_USED:
|
||||
- *result = retained->max_daemons_limit;
|
||||
+ *result = retained->max_daemon_used;
|
||||
break;
|
||||
case AP_MPMQ_IS_THREADED:
|
||||
*result = AP_MPMQ_STATIC;
|
||||
@@ -696,14 +696,32 @@
|
||||
return OK;
|
||||
}
|
||||
|
||||
-static void event_note_child_killed(int childnum, pid_t pid, ap_generation_t gen)
|
||||
+static void event_note_child_stopped(int slot, pid_t pid, ap_generation_t gen)
|
||||
{
|
||||
- if (childnum != -1) { /* child had a scoreboard slot? */
|
||||
- ap_run_child_status(ap_server_conf,
|
||||
- ap_scoreboard_image->parent[childnum].pid,
|
||||
- ap_scoreboard_image->parent[childnum].generation,
|
||||
- childnum, MPM_CHILD_EXITED);
|
||||
- ap_scoreboard_image->parent[childnum].pid = 0;
|
||||
+ if (slot != -1) { /* child had a scoreboard slot? */
|
||||
+ process_score *ps = &ap_scoreboard_image->parent[slot];
|
||||
+ int i;
|
||||
+
|
||||
+ pid = ps->pid;
|
||||
+ gen = ps->generation;
|
||||
+ for (i = 0; i < threads_per_child; i++) {
|
||||
+ ap_update_child_status_from_indexes(slot, i, SERVER_DEAD, NULL);
|
||||
+ }
|
||||
+ ap_run_child_status(ap_server_conf, pid, gen, slot, MPM_CHILD_EXITED);
|
||||
+ if (ps->quiescing != 2) { /* vs perform_idle_server_maintenance() */
|
||||
+ retained->active_daemons--;
|
||||
+ }
|
||||
+ retained->total_daemons--;
|
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
|
||||
+ "Child %d stopped: pid %d, gen %d, "
|
||||
+ "active %d/%d, total %d/%d/%d, quiescing %d",
|
||||
+ slot, (int)pid, (int)gen,
|
||||
+ retained->active_daemons, active_daemons_limit,
|
||||
+ retained->total_daemons, retained->max_daemon_used,
|
||||
+ server_limit, ps->quiescing);
|
||||
+ ps->not_accepting = 0;
|
||||
+ ps->quiescing = 0;
|
||||
+ ps->pid = 0;
|
||||
}
|
||||
else {
|
||||
ap_run_child_status(ap_server_conf, pid, gen, -1, MPM_CHILD_EXITED);
|
||||
@@ -713,9 +731,19 @@
|
||||
static void event_note_child_started(int slot, pid_t pid)
|
||||
{
|
||||
ap_generation_t gen = retained->mpm->my_generation;
|
||||
+
|
||||
+ retained->total_daemons++;
|
||||
+ retained->active_daemons++;
|
||||
ap_scoreboard_image->parent[slot].pid = pid;
|
||||
ap_scoreboard_image->parent[slot].generation = gen;
|
||||
ap_run_child_status(ap_server_conf, pid, gen, slot, MPM_CHILD_STARTED);
|
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
|
||||
+ "Child %d started: pid %d, gen %d, "
|
||||
+ "active %d/%d, total %d/%d/%d",
|
||||
+ slot, (int)pid, (int)gen,
|
||||
+ retained->active_daemons, active_daemons_limit,
|
||||
+ retained->total_daemons, retained->max_daemon_used,
|
||||
+ server_limit);
|
||||
}
|
||||
|
||||
static const char *event_get_name(void)
|
||||
@@ -737,7 +765,7 @@
|
||||
}
|
||||
|
||||
if (one_process) {
|
||||
- event_note_child_killed(/* slot */ 0, 0, 0);
|
||||
+ event_note_child_stopped(/* slot */ 0, 0, 0);
|
||||
}
|
||||
|
||||
exit(code);
|
||||
@@ -2712,8 +2740,8 @@
|
||||
{
|
||||
int pid;
|
||||
|
||||
- if (slot + 1 > retained->max_daemons_limit) {
|
||||
- retained->max_daemons_limit = slot + 1;
|
||||
+ if (slot + 1 > retained->max_daemon_used) {
|
||||
+ retained->max_daemon_used = slot + 1;
|
||||
}
|
||||
|
||||
if (ap_scoreboard_image->parent[slot].pid != 0) {
|
||||
@@ -2781,11 +2809,7 @@
|
||||
return -1;
|
||||
}
|
||||
|
||||
- ap_scoreboard_image->parent[slot].quiescing = 0;
|
||||
- ap_scoreboard_image->parent[slot].not_accepting = 0;
|
||||
event_note_child_started(slot, pid);
|
||||
- retained->active_daemons++;
|
||||
- retained->total_daemons++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2805,7 +2829,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
-static void perform_idle_server_maintenance(int child_bucket)
|
||||
+static void perform_idle_server_maintenance(int child_bucket,
|
||||
+ int *max_daemon_used)
|
||||
{
|
||||
int num_buckets = retained->mpm->num_buckets;
|
||||
int idle_thread_count = 0;
|
||||
@@ -2821,7 +2846,7 @@
|
||||
/* We only care about child_bucket in this call */
|
||||
continue;
|
||||
}
|
||||
- if (i >= retained->max_daemons_limit &&
|
||||
+ if (i >= retained->max_daemon_used &&
|
||||
free_length == retained->idle_spawn_rate[child_bucket]) {
|
||||
/* short cut if all active processes have been examined and
|
||||
* enough empty scoreboard slots have been found
|
||||
@@ -2835,6 +2860,13 @@
|
||||
if (ps->quiescing == 1) {
|
||||
ps->quiescing = 2;
|
||||
retained->active_daemons--;
|
||||
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf,
|
||||
+ "Child %d quiescing: pid %d, gen %d, "
|
||||
+ "active %d/%d, total %d/%d/%d",
|
||||
+ i, (int)ps->pid, (int)ps->generation,
|
||||
+ retained->active_daemons, active_daemons_limit,
|
||||
+ retained->total_daemons, retained->max_daemon_used,
|
||||
+ server_limit);
|
||||
}
|
||||
for (j = 0; j < threads_per_child; j++) {
|
||||
int status = ap_scoreboard_image->servers[i][j].status;
|
||||
@@ -2863,8 +2895,9 @@
|
||||
free_slots[free_length++] = i;
|
||||
}
|
||||
}
|
||||
-
|
||||
- retained->max_daemons_limit = last_non_dead + 1;
|
||||
+ if (*max_daemon_used < last_non_dead + 1) {
|
||||
+ *max_daemon_used = last_non_dead + 1;
|
||||
+ }
|
||||
|
||||
if (retained->sick_child_detected) {
|
||||
if (had_healthy_child) {
|
||||
@@ -2893,6 +2926,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ AP_DEBUG_ASSERT(retained->active_daemons <= retained->total_daemons
|
||||
+ && retained->total_daemons <= retained->max_daemon_used
|
||||
+ && retained->max_daemon_used <= server_limit);
|
||||
+
|
||||
if (idle_thread_count > max_spare_threads / num_buckets) {
|
||||
/*
|
||||
* Child processes that we ask to shut down won't die immediately
|
||||
@@ -2915,13 +2952,12 @@
|
||||
active_daemons_limit));
|
||||
ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf,
|
||||
"%shutting down one child: "
|
||||
- "active daemons %d / active limit %d / "
|
||||
- "total daemons %d / ServerLimit %d / "
|
||||
- "idle threads %d / max workers %d",
|
||||
+ "active %d/%d, total %d/%d/%d, "
|
||||
+ "idle threads %d, max workers %d",
|
||||
(do_kill) ? "S" : "Not s",
|
||||
retained->active_daemons, active_daemons_limit,
|
||||
- retained->total_daemons, server_limit,
|
||||
- idle_thread_count, max_workers);
|
||||
+ retained->total_daemons, retained->max_daemon_used,
|
||||
+ server_limit, idle_thread_count, max_workers);
|
||||
if (do_kill) {
|
||||
ap_mpm_podx_signal(all_buckets[child_bucket].pod,
|
||||
AP_MPM_PODX_GRACEFUL);
|
||||
@@ -2970,10 +3006,14 @@
|
||||
else {
|
||||
ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, ap_server_conf,
|
||||
"server is at active daemons limit, spawning "
|
||||
- "of %d children cancelled: %d/%d active, "
|
||||
- "rate %d", free_length,
|
||||
+ "of %d children cancelled: active %d/%d, "
|
||||
+ "total %d/%d/%d, rate %d", free_length,
|
||||
retained->active_daemons, active_daemons_limit,
|
||||
- retained->idle_spawn_rate[child_bucket]);
|
||||
+ retained->total_daemons, retained->max_daemon_used,
|
||||
+ server_limit, retained->idle_spawn_rate[child_bucket]);
|
||||
+ /* reset the spawning rate and prevent its growth below */
|
||||
+ retained->idle_spawn_rate[child_bucket] = 1;
|
||||
+ ++retained->hold_off_on_exponential_spawning;
|
||||
free_length = 0;
|
||||
}
|
||||
}
|
||||
@@ -2989,12 +3029,13 @@
|
||||
retained->total_daemons);
|
||||
}
|
||||
for (i = 0; i < free_length; ++i) {
|
||||
- ap_log_error(APLOG_MARK, APLOG_TRACE5, 0, ap_server_conf,
|
||||
- "Spawning new child: slot %d active / "
|
||||
- "total daemons: %d/%d",
|
||||
- free_slots[i], retained->active_daemons,
|
||||
- retained->total_daemons);
|
||||
- make_child(ap_server_conf, free_slots[i], child_bucket);
|
||||
+ int slot = free_slots[i];
|
||||
+ if (make_child(ap_server_conf, slot, child_bucket) < 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (*max_daemon_used < slot + 1) {
|
||||
+ *max_daemon_used = slot + 1;
|
||||
+ }
|
||||
}
|
||||
/* the next time around we want to spawn twice as many if this
|
||||
* wasn't good enough, but not if we've just done a graceful
|
||||
@@ -3016,6 +3057,7 @@
|
||||
static void server_main_loop(int remaining_children_to_start)
|
||||
{
|
||||
int num_buckets = retained->mpm->num_buckets;
|
||||
+ int max_daemon_used = 0;
|
||||
int child_slot;
|
||||
apr_exit_why_e exitwhy;
|
||||
int status, processed_status;
|
||||
@@ -3061,19 +3103,8 @@
|
||||
}
|
||||
/* non-fatal death... note that it's gone in the scoreboard. */
|
||||
if (child_slot >= 0) {
|
||||
- process_score *ps;
|
||||
+ event_note_child_stopped(child_slot, 0, 0);
|
||||
|
||||
- for (i = 0; i < threads_per_child; i++)
|
||||
- ap_update_child_status_from_indexes(child_slot, i,
|
||||
- SERVER_DEAD, NULL);
|
||||
-
|
||||
- event_note_child_killed(child_slot, 0, 0);
|
||||
- ps = &ap_scoreboard_image->parent[child_slot];
|
||||
- if (ps->quiescing != 2)
|
||||
- retained->active_daemons--;
|
||||
- ps->quiescing = 0;
|
||||
- /* NOTE: We don't dec in the (child_slot < 0) case! */
|
||||
- retained->total_daemons--;
|
||||
if (processed_status == APEXIT_CHILDSICK) {
|
||||
/* resource shortage, minimize the fork rate */
|
||||
retained->idle_spawn_rate[child_slot % num_buckets] = 1;
|
||||
@@ -3123,9 +3154,11 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
+ max_daemon_used = 0;
|
||||
for (i = 0; i < num_buckets; i++) {
|
||||
- perform_idle_server_maintenance(i);
|
||||
+ perform_idle_server_maintenance(i, &max_daemon_used);
|
||||
}
|
||||
+ retained->max_daemon_used = max_daemon_used;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3213,7 +3246,7 @@
|
||||
AP_MPM_PODX_RESTART);
|
||||
}
|
||||
ap_reclaim_child_processes(1, /* Start with SIGTERM */
|
||||
- event_note_child_killed);
|
||||
+ event_note_child_stopped);
|
||||
|
||||
if (!child_fatal) {
|
||||
/* cleanup pid file on normal shutdown */
|
||||
@@ -3239,7 +3272,7 @@
|
||||
ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
|
||||
AP_MPM_PODX_GRACEFUL);
|
||||
}
|
||||
- ap_relieve_child_processes(event_note_child_killed);
|
||||
+ ap_relieve_child_processes(event_note_child_stopped);
|
||||
|
||||
if (!child_fatal) {
|
||||
/* cleanup pid file on normal shutdown */
|
||||
@@ -3261,10 +3294,10 @@
|
||||
apr_sleep(apr_time_from_sec(1));
|
||||
|
||||
/* Relieve any children which have now exited */
|
||||
- ap_relieve_child_processes(event_note_child_killed);
|
||||
+ ap_relieve_child_processes(event_note_child_stopped);
|
||||
|
||||
active_children = 0;
|
||||
- for (index = 0; index < retained->max_daemons_limit; ++index) {
|
||||
+ for (index = 0; index < retained->max_daemon_used; ++index) {
|
||||
if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
|
||||
active_children = 1;
|
||||
/* Having just one child is enough to stay around */
|
||||
@@ -3282,7 +3315,7 @@
|
||||
ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
|
||||
AP_MPM_PODX_RESTART);
|
||||
}
|
||||
- ap_reclaim_child_processes(1, event_note_child_killed);
|
||||
+ ap_reclaim_child_processes(1, event_note_child_stopped);
|
||||
|
||||
return DONE;
|
||||
}
|
||||
@@ -3302,8 +3335,7 @@
|
||||
|
||||
if (!retained->mpm->is_ungraceful) {
|
||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00493)
|
||||
- AP_SIG_GRACEFUL_STRING
|
||||
- " received. Doing graceful restart");
|
||||
+ AP_SIG_GRACEFUL_STRING " received. Doing graceful restart");
|
||||
/* wake up the children...time to die. But we'll have more soon */
|
||||
for (i = 0; i < num_buckets; i++) {
|
||||
ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
|
||||
@@ -3316,6 +3348,8 @@
|
||||
|
||||
}
|
||||
else {
|
||||
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00494)
|
||||
+ "SIGHUP received. Attempting to restart");
|
||||
/* Kill 'em all. Since the child acts the same on the parents SIGTERM
|
||||
* and a SIGHUP, we may as well use the same signal, because some user
|
||||
* pthreads are stealing signals from us left and right.
|
||||
@@ -3326,9 +3360,7 @@
|
||||
}
|
||||
|
||||
ap_reclaim_child_processes(1, /* Start with SIGTERM */
|
||||
- event_note_child_killed);
|
||||
- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00494)
|
||||
- "SIGHUP received. Attempting to restart");
|
||||
+ event_note_child_stopped);
|
||||
}
|
||||
|
||||
return OK;
|
|
@ -1,286 +0,0 @@
|
|||
diff --git a/acinclude.m4 b/acinclude.m4
|
||||
index 05abe18..97484c9 100644
|
||||
--- a/acinclude.m4
|
||||
+++ b/acinclude.m4
|
||||
@@ -631,7 +631,6 @@ case $host in
|
||||
if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then
|
||||
AC_MSG_WARN([Your system does not support systemd.])
|
||||
else
|
||||
- APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS])
|
||||
AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported])
|
||||
fi
|
||||
fi
|
||||
diff --git a/include/ap_listen.h b/include/ap_listen.h
|
||||
index 58c2574..d5ed968 100644
|
||||
--- a/include/ap_listen.h
|
||||
+++ b/include/ap_listen.h
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "apr_network_io.h"
|
||||
#include "httpd.h"
|
||||
#include "http_config.h"
|
||||
+#include "apr_optional.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -143,6 +144,15 @@ AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd,
|
||||
void *dummy,
|
||||
const char *arg);
|
||||
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+APR_DECLARE_OPTIONAL_FN(int,
|
||||
+ ap_find_systemd_socket, (process_rec *, apr_port_t));
|
||||
+
|
||||
+APR_DECLARE_OPTIONAL_FN(int,
|
||||
+ ap_systemd_listen_fds, (int));
|
||||
+#endif
|
||||
+
|
||||
+
|
||||
#define LISTEN_COMMANDS \
|
||||
AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \
|
||||
"Maximum length of the queue of pending connections, as used by listen(2)"), \
|
||||
diff --git a/modules/arch/unix/mod_systemd.c b/modules/arch/unix/mod_systemd.c
|
||||
index eda1272..fc059fc 100644
|
||||
--- a/modules/arch/unix/mod_systemd.c
|
||||
+++ b/modules/arch/unix/mod_systemd.c
|
||||
@@ -35,6 +35,15 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
+APR_DECLARE_OPTIONAL_FN(int,
|
||||
+ ap_find_systemd_socket, (process_rec *, apr_port_t));
|
||||
+
|
||||
+APR_DECLARE_OPTIONAL_FN(int,
|
||||
+ ap_systemd_listen_fds, (int));
|
||||
+
|
||||
+APR_DECLARE_OPTIONAL_FN(int,
|
||||
+ ap_systemd_journal_stream_fd, (const char *, int, int));
|
||||
+
|
||||
static char describe_listeners[30];
|
||||
|
||||
static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
|
||||
@@ -145,8 +154,47 @@ static int systemd_monitor(apr_pool_t *p, server_rec *s)
|
||||
return DECLINED;
|
||||
}
|
||||
|
||||
+static int ap_find_systemd_socket(process_rec * process, apr_port_t port) {
|
||||
+ int fdcount, fd;
|
||||
+ int sdc = sd_listen_fds(0);
|
||||
+
|
||||
+ if (sdc < 0) {
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486)
|
||||
+ "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d",
|
||||
+ sdc);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (sdc == 0) {
|
||||
+ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487)
|
||||
+ "find_systemd_socket: At least one socket must be set.");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ fdcount = atoi(getenv("LISTEN_FDS"));
|
||||
+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) {
|
||||
+ if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) {
|
||||
+ return fd;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static int ap_systemd_listen_fds(int unset_environment){
|
||||
+ return sd_listen_fds(unset_environment);
|
||||
+}
|
||||
+
|
||||
+static int ap_systemd_journal_stream_fd(const char *identifier, int priority, int level_prefix){
|
||||
+ return sd_journal_stream_fd("httpd", priority, 0);
|
||||
+}
|
||||
+
|
||||
static void systemd_register_hooks(apr_pool_t *p)
|
||||
{
|
||||
+ APR_REGISTER_OPTIONAL_FN(ap_systemd_listen_fds);
|
||||
+ APR_REGISTER_OPTIONAL_FN(ap_find_systemd_socket);
|
||||
+ APR_REGISTER_OPTIONAL_FN(ap_systemd_journal_stream_fd);
|
||||
+
|
||||
/* Enable ap_extended_status. */
|
||||
ap_hook_pre_config(systemd_pre_config, NULL, NULL, APR_HOOK_LAST);
|
||||
/* Signal service is ready. */
|
||||
diff --git a/modules/loggers/config.m4 b/modules/loggers/config.m4
|
||||
index 0848d2e..8af2299 100644
|
||||
--- a/modules/loggers/config.m4
|
||||
+++ b/modules/loggers/config.m4
|
||||
@@ -5,7 +5,6 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]])
|
||||
APACHE_MODPATH_INIT(loggers)
|
||||
|
||||
APACHE_MODULE(log_config, logging configuration. You won't be able to log requests to the server without this module., , , yes)
|
||||
-APR_ADDTO(MOD_LOG_CONFIG_LDADD, [$SYSTEMD_LIBS])
|
||||
|
||||
APACHE_MODULE(log_debug, configurable debug logging, , , most)
|
||||
APACHE_MODULE(log_forensic, forensic logging)
|
||||
diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c
|
||||
index 0b11f60..c3f0a51 100644
|
||||
--- a/modules/loggers/mod_log_config.c
|
||||
+++ b/modules/loggers/mod_log_config.c
|
||||
@@ -172,10 +172,6 @@
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
-#ifdef HAVE_SYSTEMD
|
||||
-#include <systemd/sd-journal.h>
|
||||
-#endif
|
||||
-
|
||||
#define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b"
|
||||
|
||||
module AP_MODULE_DECLARE_DATA log_config_module;
|
||||
@@ -1640,8 +1636,15 @@ static apr_status_t wrap_journal_stream(apr_pool_t *p, apr_file_t **outfd,
|
||||
{
|
||||
#ifdef HAVE_SYSTEMD
|
||||
int fd;
|
||||
+ APR_OPTIONAL_FN_TYPE(ap_systemd_journal_stream_fd) *systemd_journal_stream_fd;
|
||||
+
|
||||
+ systemd_journal_stream_fd = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_journal_stream_fd);
|
||||
+ if (systemd_journal_stream_fd == NULL) {
|
||||
+ return APR_ENOTIMPL;
|
||||
+ }
|
||||
|
||||
- fd = sd_journal_stream_fd("httpd", priority, 0);
|
||||
+ fd = systemd_journal_stream_fd("httpd", priority, 0);
|
||||
+
|
||||
if (fd < 0) return fd;
|
||||
|
||||
/* This is an AF_UNIX socket fd so is more pipe-like than
|
||||
diff --git a/modules/loggers/mod_log_config.h b/modules/loggers/mod_log_config.h
|
||||
index 877a593..bd52a98 100644
|
||||
--- a/modules/loggers/mod_log_config.h
|
||||
+++ b/modules/loggers/mod_log_config.h
|
||||
@@ -69,6 +69,10 @@ APR_DECLARE_OPTIONAL_FN(ap_log_writer_init*, ap_log_set_writer_init,(ap_log_writ
|
||||
*/
|
||||
APR_DECLARE_OPTIONAL_FN(ap_log_writer*, ap_log_set_writer, (ap_log_writer* func));
|
||||
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+APR_DECLARE_OPTIONAL_FN(int, ap_systemd_journal_stream_fd, (const char *, int, int));
|
||||
+#endif
|
||||
+
|
||||
#endif /* MOD_LOG_CONFIG */
|
||||
/** @} */
|
||||
|
||||
diff --git a/server/listen.c b/server/listen.c
|
||||
index e2e028a..5d1c0e1 100644
|
||||
--- a/server/listen.c
|
||||
+++ b/server/listen.c
|
||||
@@ -34,10 +34,6 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
-#ifdef HAVE_SYSTEMD
|
||||
-#include <systemd/sd-daemon.h>
|
||||
-#endif
|
||||
-
|
||||
/* we know core's module_index is 0 */
|
||||
#undef APLOG_MODULE_INDEX
|
||||
#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
|
||||
@@ -325,34 +321,6 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
|
||||
}
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
-
|
||||
-static int find_systemd_socket(process_rec * process, apr_port_t port) {
|
||||
- int fdcount, fd;
|
||||
- int sdc = sd_listen_fds(0);
|
||||
-
|
||||
- if (sdc < 0) {
|
||||
- ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486)
|
||||
- "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d",
|
||||
- sdc);
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- if (sdc == 0) {
|
||||
- ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487)
|
||||
- "find_systemd_socket: At least one socket must be set.");
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- fdcount = atoi(getenv("LISTEN_FDS"));
|
||||
- for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) {
|
||||
- if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) {
|
||||
- return fd;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- return -1;
|
||||
-}
|
||||
-
|
||||
static apr_status_t alloc_systemd_listener(process_rec * process,
|
||||
int fd, const char *proto,
|
||||
ap_listen_rec **out_rec)
|
||||
@@ -412,6 +380,14 @@ static const char *set_systemd_listener(process_rec *process, apr_port_t port,
|
||||
{
|
||||
ap_listen_rec *last, *new;
|
||||
apr_status_t rv;
|
||||
+ APR_OPTIONAL_FN_TYPE(ap_find_systemd_socket) *find_systemd_socket;
|
||||
+
|
||||
+ find_systemd_socket = APR_RETRIEVE_OPTIONAL_FN(ap_find_systemd_socket);
|
||||
+
|
||||
+ if (!find_systemd_socket)
|
||||
+ return "Systemd socket activation is used, but mod_systemd is probably "
|
||||
+ "not loaded";
|
||||
+
|
||||
int fd = find_systemd_socket(process, port);
|
||||
if (fd < 0) {
|
||||
return "Systemd socket activation is used, but this port is not "
|
||||
@@ -438,7 +414,6 @@ static const char *set_systemd_listener(process_rec *process, apr_port_t port,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
-
|
||||
#endif /* HAVE_SYSTEMD */
|
||||
|
||||
static const char *alloc_listener(process_rec *process, const char *addr,
|
||||
@@ -707,6 +682,9 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
|
||||
int num_listeners = 0;
|
||||
const char* proto;
|
||||
int found;
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+ APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds;
|
||||
+#endif
|
||||
|
||||
for (ls = s; ls; ls = ls->next) {
|
||||
proto = ap_get_server_protocol(ls);
|
||||
@@ -746,7 +724,10 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
|
||||
apr_pool_cleanup_null, s->process->pool);
|
||||
}
|
||||
else {
|
||||
- sd_listen_fds(1);
|
||||
+ systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds);
|
||||
+ if (systemd_listen_fds != NULL) {
|
||||
+ systemd_listen_fds(1);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -963,6 +944,9 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
|
||||
apr_port_t port;
|
||||
apr_status_t rv;
|
||||
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
|
||||
+#ifdef HAVE_SYSTEMD
|
||||
+ APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds;
|
||||
+#endif
|
||||
|
||||
if (err != NULL) {
|
||||
return err;
|
||||
@@ -973,7 +957,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
|
||||
}
|
||||
#ifdef HAVE_SYSTEMD
|
||||
if (use_systemd == -1) {
|
||||
- use_systemd = sd_listen_fds(0) > 0;
|
||||
+ systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds);
|
||||
+ if (systemd_listen_fds != NULL) {
|
||||
+ use_systemd = systemd_listen_fds(0) > 0;
|
||||
+ } else {
|
||||
+ use_systemd = 0;
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
|
|
@ -8,5 +8,6 @@ ConditionPathExists=|!/etc/pki/tls/private/localhost.key
|
|||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=no
|
||||
PrivateTmp=true
|
||||
|
||||
ExecStart=/usr/libexec/httpd-ssl-gencerts
|
||||
|
|
|
@ -33,6 +33,7 @@ sscg -q \
|
|||
--cert-file /etc/pki/tls/certs/localhost.crt \
|
||||
--cert-key-file /etc/pki/tls/private/localhost.key \
|
||||
--ca-file /etc/pki/tls/certs/localhost.crt \
|
||||
--dhparams-file /tmp/dhparams.pem \
|
||||
--lifetime 365 \
|
||||
--hostname $FQDN \
|
||||
--email root@$FQDN
|
||||
|
|
34
httpd.spec
34
httpd.spec
|
@ -13,7 +13,7 @@
|
|||
Summary: Apache HTTP Server
|
||||
Name: httpd
|
||||
Version: 2.4.37
|
||||
Release: 54%{?dist}
|
||||
Release: 56%{?dist}.5
|
||||
URL: https://httpd.apache.org/
|
||||
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
|
||||
Source2: httpd.logrotate
|
||||
|
@ -240,7 +240,14 @@ Patch232: httpd-2.4.37-CVE-2022-31813.patch
|
|||
Patch233: httpd-2.4.37-CVE-2022-29404.patch
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2094997
|
||||
Patch234: httpd-2.4.37-CVE-2022-26377.patch
|
||||
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2161773
|
||||
Patch235: httpd-2.4.37-CVE-2022-37436.patch
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2161774
|
||||
Patch236: httpd-2.4.37-CVE-2006-20001.patch
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2161777
|
||||
Patch237: httpd-2.4.37-CVE-2022-36760.patch
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2176209
|
||||
Patch238: httpd-2.4.37-CVE-2023-25690.patch
|
||||
|
||||
License: ASL 2.0
|
||||
Group: System Environment/Daemons
|
||||
|
@ -322,7 +329,7 @@ Epoch: 1
|
|||
BuildRequires: openssl-devel
|
||||
Requires(pre): httpd-filesystem
|
||||
Requires: httpd = 0:%{version}-%{release}, httpd-mmn = %{mmnisa}
|
||||
Requires: sscg >= 2.2.0, /usr/bin/hostname
|
||||
Requires: sscg >= 3.0.0-7, /usr/bin/hostname
|
||||
Obsoletes: stronghold-mod_ssl
|
||||
# Require an OpenSSL which supports PROFILE=SYSTEM
|
||||
Conflicts: openssl-libs < 1:1.0.1h-4
|
||||
|
@ -458,6 +465,10 @@ interface for storing and accessing per-user session data.
|
|||
%patch232 -p1 -b .CVE-2022-31813
|
||||
%patch233 -p1 -b .CVE-2022-29404
|
||||
%patch234 -p1 -b .CVE-2022-26377
|
||||
%patch235 -p1 -b .CVE-2022-37436
|
||||
%patch236 -p1 -b .CVE-2006-20001
|
||||
%patch237 -p1 -b .CVE-2022-36760
|
||||
%patch238 -p1 -b .CVE-2023-25690
|
||||
|
||||
# Patch in the vendor string
|
||||
sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h
|
||||
|
@ -963,6 +974,23 @@ rm -rf $RPM_BUILD_ROOT
|
|||
%{_rpmconfigdir}/macros.d/macros.httpd
|
||||
|
||||
%changelog
|
||||
* Thu Apr 27 2023 Luboš Uhliarik <luhliari@redhat.com> - 2.4.37-56.5
|
||||
- Resolves: #2190133 - mod_rewrite regression with CVE-2023-25690
|
||||
|
||||
* Sat Mar 18 2023 Luboš Uhliarik <luhliari@redhat.com> - 2.4.37-56.4
|
||||
- Resolves: #2177748 - CVE-2023-25690 httpd:2.4/httpd: HTTP request splitting
|
||||
with mod_rewrite and mod_proxy
|
||||
|
||||
* Tue Jan 31 2023 Luboš Uhliarik <luhliari@redhat.com> - 2.4.37-56
|
||||
- Resolves: #2162499 - CVE-2006-20001 httpd: mod_dav: out-of-bounds read/write
|
||||
of zero byte
|
||||
- Resolves: #2162485 - CVE-2022-37436 httpd: mod_proxy: HTTP response splitting
|
||||
- Resolves: #2162509 - CVE-2022-36760 httpd: mod_proxy_ajp: Possible request
|
||||
smuggling
|
||||
|
||||
* Thu Jan 26 2023 Luboš Uhliarik <luhliari@redhat.com> - 2.4.37-55
|
||||
- Resolves: #2155961 - prevent sscg creating /dhparams.pem
|
||||
|
||||
* Thu Dec 08 2022 Luboš Uhliarik <luhliari@redhat.com> - 2.4.37-54
|
||||
- Resolves: #2095650 - Dependency from mod_http2 on httpd broken
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
summary: Internal Tier1 beakerlib tests
|
||||
discover:
|
||||
how: fmf
|
||||
url: git://pkgs.devel.redhat.com/tests/httpd
|
||||
filter: 'tier: 1'
|
||||
execute:
|
||||
how: tmt
|
||||
adjust:
|
||||
enabled: false
|
||||
when: distro == centos-stream-9
|
|
@ -1,7 +0,0 @@
|
|||
summary: Public (Fedora) Tier1 beakerlib tests
|
||||
discover:
|
||||
how: fmf
|
||||
url: https://src.fedoraproject.org/tests/httpd.git
|
||||
filter: 'tier: 1'
|
||||
execute:
|
||||
how: tmt
|
|
@ -1,10 +0,0 @@
|
|||
summary: Internal Tier2 beakerlib tests
|
||||
discover:
|
||||
how: fmf
|
||||
url: git://pkgs.devel.redhat.com/tests/httpd
|
||||
filter: 'tier: 2'
|
||||
execute:
|
||||
how: tmt
|
||||
adjust:
|
||||
enabled: false
|
||||
when: distro == centos-stream-9
|
27
pullrev.sh
27
pullrev.sh
|
@ -6,10 +6,10 @@ if [ $# -lt 1 ]; then
|
|||
fi
|
||||
|
||||
repo="https://svn.apache.org/repos/asf/httpd/httpd/trunk"
|
||||
#repo="https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x"
|
||||
ver=2.4.51
|
||||
repo="https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x"
|
||||
ver=2.4.37
|
||||
prefix="httpd-${ver}"
|
||||
suffix="${SUFFIX:-r$1${2:++}}"
|
||||
suffix="r$1${2:++}"
|
||||
fn="${prefix}-${suffix}.patch"
|
||||
vcurl="http://svn.apache.org/viewvc?view=revision&revision="
|
||||
|
||||
|
@ -23,12 +23,8 @@ fi
|
|||
|
||||
new=0
|
||||
for r in $*; do
|
||||
case $r in
|
||||
http*) url=$r ;;
|
||||
*) url=${vcurl}${r} ;;
|
||||
esac
|
||||
if ! grep -q "^${url}" ${fn}; then
|
||||
echo "${url}"
|
||||
if ! grep -q "${vcurl}${r}" ${fn}; then
|
||||
echo "${vcurl}${r}"
|
||||
new=1
|
||||
fi
|
||||
done >> ${fn}
|
||||
|
@ -39,17 +35,10 @@ prev=/dev/null
|
|||
for r in $*; do
|
||||
echo "+ fetching ${r}"
|
||||
this=`mktemp /tmp/pullrevXXXXXX`
|
||||
case $r in
|
||||
http*) curl -s "$r" | filterdiff --strip=3 ;;
|
||||
*) svn diff -c ${r} ${repo} ;;
|
||||
esac | filterdiff --remove-timestamps --clean \
|
||||
-x 'CHANGES' -x '*/next-number' -x 'STATUS' -x '*.xml' \
|
||||
--addprefix="${prefix}/" > ${this}
|
||||
svn diff -c ${r} ${repo} | filterdiff --remove-timestamps -x 'CHANGES' -x 'next-number' -x 'STATUS' \
|
||||
--addprefix="${prefix}/" > ${this}
|
||||
next=`mktemp /tmp/pullrevXXXXXX`
|
||||
if ! combinediff -w ${prev} ${this} > ${next}; then
|
||||
echo "Failed combining previous ${prev} with ${this}";
|
||||
exit 1
|
||||
fi
|
||||
combinediff --quiet ${prev} ${this} > ${next}
|
||||
rm -f "${this}"
|
||||
[ "${prev}" = "/dev/null" ] || rm -f "${prev}"
|
||||
prev=${next}
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
---
|
||||
badfuncs:
|
||||
# mod_proxy uses inet_ntoa (safely) for IPv4 address matching,
|
||||
# and APR interfaces for IPv6 addresses.
|
||||
ignore:
|
||||
- /usr/lib*/httpd/modules/mod_proxy.so
|
|
@ -1,10 +0,0 @@
|
|||
#
|
||||
# Lua-based server-status page; requires mod_lua to be loaded
|
||||
# as per default configuration.
|
||||
#
|
||||
LuaMapHandler ^/server-status$ /usr/share/httpd/server-status/server-status.lua
|
||||
|
||||
<Directory /usr/share/httpd/server-status>
|
||||
AllowOverride None
|
||||
Require local
|
||||
</Directory>
|
1
sources
1
sources
|
@ -1,2 +1 @@
|
|||
SHA512 (apache-poweredby.png) = 51d2796ca0ed0f48c5aaaa207c3778ae99ff3652653099d65d30138ec4568f409db846943ed7c0e2d8a4e1aa29281e0d0daae24056c41cf49760dacba153eb00
|
||||
SHA512 (httpd-2.4.37.tar.bz2) = e802915801bbe885a65dada04b0116d145b293fabfff734dddb61a79ca1c6d65326f51155d1b864b093c3ec00d0bdfdf1401ab55677bae1ea3da1d199d7bcad4
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#
|
||||
# Makefile of /CoreOS/httpd/Sanity/smoke
|
||||
# Description: Simple check of httpd test page
|
||||
# Author: Branislav Nater <bnater@redhat.com>
|
||||
# Makefile of /CoreOS/httpd/Sanity/httpd-php-mysql-sanity-test
|
||||
# Description: test fetching data from mysqldb/mariadb through php
|
||||
# Author: Karel Srot <ksrot@redhat.com>
|
||||
#
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#
|
||||
# Copyright (c) 2021 Red Hat, Inc.
|
||||
# Copyright (c) 2013 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing
|
||||
# to use, modify, copy, or redistribute it subject to the terms
|
||||
|
@ -24,12 +24,12 @@
|
|||
#
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
export TEST=/CoreOS/httpd/Sanity/smoke
|
||||
export TEST=/CoreOS/httpd/Sanity/httpd-php-mysql-sanity-test
|
||||
export TESTVERSION=1.0
|
||||
|
||||
BUILT_FILES=
|
||||
|
||||
FILES=$(METADATA) runtest.sh Makefile PURPOSE
|
||||
FILES=$(METADATA) runtest.sh Makefile PURPOSE mysql.php php_mysql_test.sql php_mysql_test.conf
|
||||
|
||||
.PHONY: all install download clean
|
||||
|
||||
|
@ -43,23 +43,25 @@ clean:
|
|||
rm -f *~ $(BUILT_FILES)
|
||||
|
||||
|
||||
include /usr/share/rhts/lib/rhts-make.include
|
||||
-include /usr/share/rhts/lib/rhts-make.include
|
||||
|
||||
$(METADATA): Makefile
|
||||
@echo "Owner: Branislav Nater <bnater@redhat.com>" > $(METADATA)
|
||||
@echo "Owner: Karel Srot <ksrot@redhat.com>" > $(METADATA)
|
||||
@echo "Name: $(TEST)" >> $(METADATA)
|
||||
@echo "TestVersion: $(TESTVERSION)" >> $(METADATA)
|
||||
@echo "Path: $(TEST_DIR)" >> $(METADATA)
|
||||
@echo "Description: Simple check of httpd test page" >> $(METADATA)
|
||||
@echo "Description: test fetching data from mysqldb/mariadb through php" >> $(METADATA)
|
||||
@echo "Type: Sanity" >> $(METADATA)
|
||||
@echo "TestTime: 5m" >> $(METADATA)
|
||||
@echo "RunFor: httpd" >> $(METADATA)
|
||||
@echo "Requires: httpd mod_ssl" >> $(METADATA)
|
||||
@echo "Requires: httpd php php-zts php-mysqlnd mysql-server mariadb-server" >> $(METADATA)
|
||||
@echo "RhtsRequires: library(httpd/http)" >> $(METADATA)
|
||||
@echo "RhtsRequires: library(mysql/basic)" >> $(METADATA)
|
||||
@echo "RhtsRequires: library(mariadb55/basic)" >> $(METADATA)
|
||||
@echo "RhtsRequires: library(php/utils)" >> $(METADATA)
|
||||
@echo "Priority: Normal" >> $(METADATA)
|
||||
@echo "License: GPLv2" >> $(METADATA)
|
||||
@echo "Confidential: no" >> $(METADATA)
|
||||
@echo "Destructive: no" >> $(METADATA)
|
||||
@echo "Releases: -RHEL4 -RHELClient5 -RHELServer5" >> $(METADATA)
|
||||
|
||||
rhts-lint $(METADATA)
|
|
@ -0,0 +1,3 @@
|
|||
PURPOSE of /CoreOS/httpd/Sanity/httpd-php-mysql-sanity-test
|
||||
Description: test fetching data from mysqldb/mariadb through php
|
||||
Author: Karel Srot <ksrot@redhat.com>
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
$db = mysqli_connect("localhost", "root");
|
||||
if (!$db) {
|
||||
die("Could not connect");
|
||||
}
|
||||
if (!mysqli_select_db($db, "php_mysql_test")) {
|
||||
die("Could not select database");
|
||||
}
|
||||
$res = mysqli_query($db, "SELECT * from foobar");
|
||||
$row = mysqli_fetch_assoc($res);
|
||||
printf("%s is %d\n", $row['name'], $row['value']);
|
||||
?>
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
$db = mysql_connect("localhost", "root");
|
||||
if (!$db) {
|
||||
die("Could not connect");
|
||||
}
|
||||
if (!mysql_select_db("php_mysql_test")) {
|
||||
die("Could not select database");
|
||||
}
|
||||
$res = mysql_query("SELECT * from foobar");
|
||||
$row = mysql_fetch_assoc($res);
|
||||
printf("%s is %d\n", $row['name'], $row['value']);
|
||||
?>
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
Alias /php_mysql_test /var/www/php_mysql_test
|
||||
|
||||
<Directory /var/www/php_mysql_test>
|
||||
</Directory>
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
CREATE DATABASE php_mysql_test;
|
||||
USE php_mysql_test;
|
||||
|
||||
CREATE TABLE foobar (name VARCHAR(10), value INTEGER);
|
||||
INSERT INTO foobar VALUES("fish", 42);
|
|
@ -0,0 +1,102 @@
|
|||
#!/bin/bash
|
||||
# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#
|
||||
# runtest.sh of /CoreOS/httpd/Sanity/httpd-php-mysql-sanity-test
|
||||
# Description: test fetching data from mysqldb/mariadb through php
|
||||
# Author: Karel Srot <ksrot@redhat.com>
|
||||
#
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#
|
||||
# Copyright (c) 2013 Red Hat, Inc. All rights reserved.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing
|
||||
# to use, modify, copy, or redistribute it subject to the terms
|
||||
# and conditions of the GNU General Public License version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be
|
||||
# useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
# PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
# Include Beaker environment
|
||||
[ -e /usr/bin/rhts-environment.sh ] && . /usr/bin/rhts-environment.sh
|
||||
. /usr/share/beakerlib/beakerlib.sh || exit 1
|
||||
|
||||
PACKAGES="${PACKAGES:-httpd}"
|
||||
REQUIRES="${REQUIRES:-php $DB}"
|
||||
|
||||
rlJournalStart
|
||||
rlPhaseStartSetup
|
||||
rlRun "rlImport httpd/http" 0 "Import httpd library"
|
||||
if rlIsRHEL 5 6 && [ $httpCOLLECTION = 0 ]; then
|
||||
DB="mysql-server"
|
||||
rlRun "rlImport mysql/basic" 0 "Import mysqld library"
|
||||
SERVICE=${mysqlServiceName}
|
||||
else
|
||||
DB="mariadb-server"
|
||||
rlRun "rlImport mariadb55/basic" 0 "Import mariadb library"
|
||||
SERVICE=${mariadbServiceName}
|
||||
fi
|
||||
# install also php-mysql on rhel-6 (instead of php-mysqlnd on rhel-7)
|
||||
rlRun "rlImport php/utils"
|
||||
phpPdoPhpMysqlSetup
|
||||
rlAssertRpm --all
|
||||
rlRun "rlServiceStart $SERVICE" 0
|
||||
rlRun "echo DROP DATABASE php_mysql_test | mysql -u root" 0,1
|
||||
rlRun "mysql --verbose -u root < php_mysql_test.sql"
|
||||
rlRun "httpStop" 0 "Stop httpd if running"
|
||||
rlRun "> $httpLOGDIR/error_log"
|
||||
rlRun "rm -rvf $httpROOTDIR/php_mysql_test"
|
||||
rlRun "mkdir -v $httpROOTDIR/php_mysql_test"
|
||||
rlRun "cp -v php_mysql_test.conf $httpCONFDIR/conf.d/"
|
||||
rlRun "php_version=`rlCheckRpm php`"
|
||||
if [[ $php_version =~ php-7* ]] || [[ $php_version =~ php-5.[5-6]* ]]; then
|
||||
rlRun "cp -v new_mysql.php $httpROOTDIR/php_mysql_test/mysql.php"
|
||||
else
|
||||
rlRun "cp -v old_mysql.php $httpROOTDIR/php_mysql_test/mysql.php"
|
||||
fi
|
||||
rlRun "sed -i 's|/var/www|$httpROOTDIR|' $httpCONFDIR/conf.d/php_mysql_test.conf"
|
||||
rlRun "chown -R apache: $httpROOTDIR/php_mysql_test"
|
||||
#rlRun "restorecon $httpROOTDIR/php_mysql_test"
|
||||
selinuxenabled && rlRun "chcon -Rv -t httpd_sys_content_t $httpROOTDIR/php_mysql_test"
|
||||
rlRun "httpStart" 0 "Start httpd"
|
||||
rlPhaseEnd
|
||||
|
||||
rlPhaseStartTest
|
||||
URL="http://localhost/php_mysql_test/"
|
||||
RETVAL=0
|
||||
tries=`seq 1 10`
|
||||
|
||||
for n in ${tries}; do
|
||||
output=`curl -s $URL/mysql.php`
|
||||
rv=$?
|
||||
echo "PHP output ${n}: ${rv} x${output}y"
|
||||
[ ${rv} -ne 0 -o "x${output}y" != "xfish is 42y" ] && RETVAL=66
|
||||
done
|
||||
|
||||
if [ $RETVAL -ne 0 ]; then
|
||||
rlFail
|
||||
else
|
||||
rlPass
|
||||
fi
|
||||
rlPhaseEnd
|
||||
|
||||
rlPhaseStartCleanup
|
||||
rlRun "rm -f $httpCONFDIR/conf.d/php_mysql_test.conf"
|
||||
rlRun "rm -rf $httpROOTDIR/php_mysql_test"
|
||||
rlRun "echo DROP DATABASE php_mysql_test | mysql -u root"
|
||||
rlRun "rlServiceRestore ${SERVICE}" 0
|
||||
rlRun "httpStop" 0 "Stop httpd if running"
|
||||
# uninstall php-mysql on rhel-6 if it was installed during setup
|
||||
phpPdoPhpMysqlCleanup
|
||||
rlPhaseEnd
|
||||
rlJournalPrintText
|
||||
rlJournalEnd
|
|
@ -1,3 +0,0 @@
|
|||
PURPOSE of /CoreOS/httpd/Sanity/smoke
|
||||
Description: Simple check of httpd
|
||||
Author: Branislav Nater <bnater@redhat.com>
|
|
@ -1,64 +0,0 @@
|
|||
#!/bin/bash
|
||||
# vim: dict+=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#
|
||||
# runtest.sh of /CoreOS/httpd/Sanity/smoke
|
||||
# Description: Simple check of httpd test page
|
||||
# Author: Branislav Nater <bnater@redhat.com>
|
||||
#
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#
|
||||
# Copyright (c) 2021 Red Hat, Inc.
|
||||
#
|
||||
# This copyrighted material is made available to anyone wishing
|
||||
# to use, modify, copy, or redistribute it subject to the terms
|
||||
# and conditions of the GNU General Public License version 2.
|
||||
#
|
||||
# This program is distributed in the hope that it will be
|
||||
# useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
# PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
# Include rhts environment
|
||||
. /usr/share/beakerlib/beakerlib.sh || exit 1
|
||||
|
||||
PACKAGES="${PACKAGES:-httpd}"
|
||||
REQUIRES=${REQUIRES:-}
|
||||
|
||||
rlJournalStart
|
||||
rlPhaseStartSetup
|
||||
rlRun "rlImport --all" 0 "Importing Beaker libraries" || rlDie
|
||||
rlAssertRpm --all
|
||||
rlFileBackup --clean ${httpCONFDIR}/conf/
|
||||
rlFileBackup --clean ${httpCONFDIR}/conf.d/
|
||||
rlFileBackup --clean ${httpCONFDIR}/conf.modules.d/
|
||||
rlRun "TmpDir=\$(mktemp -d)" 0 "Creating tmp directory"
|
||||
rlRun "pushd $TmpDir"
|
||||
rlPhaseEnd
|
||||
|
||||
rlPhaseStartTest
|
||||
rlRun "httpStart" 0 "Start httpd"
|
||||
rlRun "httpStatus" 0 "Check status"
|
||||
rlRun "httpStop" 0 "Stop httpd"
|
||||
|
||||
rlRun "httpSecureStart" 0 "Start httpd with ssl"
|
||||
rlRun "httpInstallCa $(hostname)" 0 "Install CA"
|
||||
rlRun "httpSecureStatus" 0 "Check status"
|
||||
rlRun "httpRemoveCa" 0 "Remove CA"
|
||||
rlRun "httpSecureStop" 0 "Stop httpd with ssl"
|
||||
rlPhaseEnd
|
||||
|
||||
rlPhaseStartCleanup
|
||||
rlRun "rlFileRestore" 0 "Restoring original configuration"
|
||||
rlRun "popd"
|
||||
rlRun "rm -r $TmpDir" 0 "Removing tmp directory"
|
||||
rlPhaseEnd
|
||||
rlJournalEnd
|
||||
rlJournalPrintText
|
|
@ -1,12 +1,15 @@
|
|||
---
|
||||
# Tests that run in all contexts
|
||||
- hosts: localhost
|
||||
vars:
|
||||
use_beakerlib_libraries: true
|
||||
roles:
|
||||
- role: standard-test-beakerlib
|
||||
- role: standard-test-rhts
|
||||
tags:
|
||||
- classic
|
||||
- container
|
||||
tests:
|
||||
- smoke
|
||||
- httpd-php-mysql-sanity-test
|
||||
required_packages:
|
||||
- findutils # beakerlib needs find command
|
||||
- which # smoke requires which command
|
Loading…
Reference in New Issue