Compare commits

...

No commits in common. 'c9' and 'i9-beta' have entirely different histories.
c9 ... i9-beta

2
.gitignore vendored

@ -1,2 +1,2 @@
SOURCES/apache-poweredby.png
SOURCES/httpd-2.4.62.tar.bz2
SOURCES/httpd-2.4.57.tar.bz2

@ -1,2 +1,2 @@
3a7449d6cff00e5ccb3ed8571f34c0528555d38f SOURCES/apache-poweredby.png
c968e2a0e556a8d3b7f6d6fc9732ddc456b5c229 SOURCES/httpd-2.4.62.tar.bz2
01044512374941fad939ec4b1537428cc7edc769 SOURCES/httpd-2.4.57.tar.bz2

@ -7,10 +7,5 @@ Documentation=man:htcacheclean.service(8)
Type=forking
User=apache
PIDFile=/run/httpd/htcacheclean/pid
Environment=LANG=C
EnvironmentFile=/etc/sysconfig/htcacheclean
ExecStart=/usr/sbin/htcacheclean -P /run/httpd/htcacheclean/pid -d $INTERVAL -p $CACHE_ROOT -l $LIMIT $OPTIONS
PrivateTmp=true
[Install]
WantedBy=multi-user.target

@ -1,8 +1,8 @@
diff --git a/configure.in b/configure.in
index 7194de5..00e2369 100644
index f8f9442..f276550 100644
--- a/configure.in
+++ b/configure.in
@@ -843,9 +843,9 @@ APACHE_SUBST(INSTALL_SUEXEC)
@@ -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

@ -0,0 +1,271 @@
diff --git a/configure.in b/configure.in
index cb43246..0bb6b0d 100644
--- httpd-2.4.43/configure.in.r1861793+
+++ httpd-2.4.43/configure.in
@@ -465,6 +465,28 @@
AC_SEARCH_LIBS(crypt, crypt)
CRYPT_LIBS="$LIBS"
APACHE_SUBST(CRYPT_LIBS)
+
+if test "$ac_cv_search_crypt" != "no"; then
+ # Test crypt() with the SHA-512 test vector from https://akkadia.org/drepper/SHA-crypt.txt
+ AC_CACHE_CHECK([whether crypt() supports SHA-2], [ap_cv_crypt_sha2], [
+ AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <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,8 +1,8 @@
diff --git a/server/listen.c b/server/listen.c
index 9577d60..d718db1 100644
index 5242c2a..e2e028a 100644
--- a/server/listen.c
+++ b/server/listen.c
@@ -35,6 +35,10 @@
@@ -34,6 +34,10 @@
#include <unistd.h>
#endif
@ -13,7 +13,7 @@ index 9577d60..d718db1 100644
/* we know core's module_index is 0 */
#undef APLOG_MODULE_INDEX
#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
@@ -60,9 +64,12 @@ static int ap_listenbacklog;
@@ -59,9 +63,12 @@ static int ap_listenbacklog;
static int ap_listencbratio;
static int send_buffer_size;
static int receive_buffer_size;
@ -27,7 +27,7 @@ index 9577d60..d718db1 100644
{
apr_socket_t *s = server->sd;
int one = 1;
@@ -95,20 +102,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
@@ -94,20 +101,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
return stat;
}
@ -48,7 +48,7 @@ index 9577d60..d718db1 100644
/*
* To send data over high bandwidth-delay connections at full
* speed we must force the TCP window to open wide enough to keep the
@@ -170,21 +163,37 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
@@ -169,21 +162,37 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
}
#endif
@ -100,7 +100,7 @@ index 9577d60..d718db1 100644
}
#ifdef WIN32
@@ -335,6 +344,123 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
@@ -315,6 +324,123 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
return found;
}
@ -223,8 +223,8 @@ index 9577d60..d718db1 100644
+
static const char *alloc_listener(process_rec *process, const char *addr,
apr_port_t port, const char* proto,
const char *scope_id, void *slave,
@@ -529,7 +655,7 @@ static int open_listeners(apr_pool_t *pool)
void *slave)
@@ -495,7 +621,7 @@ static int open_listeners(apr_pool_t *pool)
}
}
#endif
@ -233,7 +233,7 @@ index 9577d60..d718db1 100644
++num_open;
}
else {
@@ -641,8 +767,28 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
@@ -607,8 +733,28 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
}
}
@ -264,7 +264,7 @@ index 9577d60..d718db1 100644
}
for (lr = ap_listeners; lr; lr = lr->next) {
@@ -732,7 +878,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
@@ -698,7 +844,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
duplr->bind_addr);
return stat;
}
@ -273,7 +273,7 @@ index 9577d60..d718db1 100644
#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);
@@ -859,6 +1005,11 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
@@ -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.";
}
@ -285,7 +285,7 @@ index 9577d60..d718db1 100644
rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool);
if (rv != APR_SUCCESS) {
@@ -894,6 +1045,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
@@ -856,6 +1007,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
ap_str_tolower(proto);
}
@ -295,6 +295,6 @@ index 9577d60..d718db1 100644
+ }
+#endif
+
return alloc_listener(cmd->server->process, host, port, proto,
scope_id, NULL, cmd->temp_pool);
return alloc_listener(cmd->server->process, host, port, proto, NULL);
}

@ -1,5 +1,5 @@
diff --git a/docs/manual/mod/mpm_common.html.en b/docs/manual/mod/mpm_common.html.en
index d7a2fea..c911a4e 100644
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>
@ -43,10 +43,10 @@ index d7a2fea..c911a4e 100644
<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 d5ed968..be1a60c 100644
index 58c2574..1a53292 100644
--- a/include/ap_listen.h
+++ b/include/ap_listen.h
@@ -138,6 +138,9 @@ AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy
@@ -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[]);
@ -56,7 +56,7 @@ index d5ed968..be1a60c 100644
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,
@@ -160,6 +163,8 @@ AP_INIT_TAKE1("ListenCoresBucketsRatio", ap_set_listencbratio, NULL, RSRC_CONF,
@@ -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"), \
@ -66,10 +66,10 @@ index d5ed968..be1a60c 100644
"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 2a4e87a..280bbe7 100644
index e2e028a..6ef664b 100644
--- a/server/listen.c
+++ b/server/listen.c
@@ -60,6 +60,7 @@ static int ap_listenbacklog;
@@ -63,6 +63,7 @@ static int ap_listenbacklog;
static int ap_listencbratio;
static int send_buffer_size;
static int receive_buffer_size;
@ -77,7 +77,7 @@ index 2a4e87a..280bbe7 100644
#ifdef HAVE_SYSTEMD
static int use_systemd = -1;
#endif
@@ -159,6 +160,21 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_
@@ -162,6 +163,21 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_
}
#endif
@ -99,7 +99,7 @@ index 2a4e87a..280bbe7 100644
if (do_bind_listen) {
#if APR_HAVE_IPV6
if (server->bind_addr->family == APR_INET6) {
@@ -971,6 +987,7 @@ AP_DECLARE(void) ap_listen_pre_config(void)
@@ -956,6 +972,7 @@ AP_DECLARE(void) ap_listen_pre_config(void)
}
}
@ -107,8 +107,8 @@ index 2a4e87a..280bbe7 100644
AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
int argc, char *const argv[])
{
@@ -1044,6 +1061,14 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
scope_id, NULL, cmd->temp_pool);
@@ -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,

@ -0,0 +1,13 @@
diff --git a/support/htcacheclean.c b/support/htcacheclean.c
index 958ba6d..0a7fe3c 100644
--- a/support/htcacheclean.c
+++ b/support/htcacheclean.c
@@ -557,8 +557,6 @@ static int list_urls(char *path, apr_pool_t *pool, apr_off_t round)
}
}
}
-
- break;
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,79 @@
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 15f68f9..e67c81d 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -1682,6 +1682,10 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
STACK_OF(X509) *chain;
X509_STORE_CTX *sctx;
X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
+ int addl_chain = 0; /* non-zero if additional chain certs were
+ * added to store */
+
+ ap_assert(store != NULL); /* safe to assume always non-NULL? */
#if OPENSSL_VERSION_NUMBER >= 0x1010100fL
/* For OpenSSL >=1.1.1, turn on client cert support which is
@@ -1707,20 +1711,28 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
ssl_init_ca_cert_path(s, ptemp, pkp->cert_path, NULL, sk);
}
- if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
- sk_X509_INFO_free(sk);
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
- "no client certs found for SSL proxy");
- return APR_SUCCESS;
- }
-
/* Check that all client certs have got certificates and private
- * keys. */
- for (n = 0; n < ncerts; n++) {
+ * keys. Note the number of certs in the stack may decrease
+ * during the loop. */
+ for (n = 0; n < sk_X509_INFO_num(sk); n++) {
X509_INFO *inf = sk_X509_INFO_value(sk, n);
+ int has_privkey = inf->x_pkey && inf->x_pkey->dec_pkey;
- if (!inf->x509 || !inf->x_pkey || !inf->x_pkey->dec_pkey ||
- inf->enc_data) {
+ /* For a lone certificate in the file, trust it as a
+ * CA/intermediate certificate. */
+ if (inf->x509 && !has_privkey && !inf->enc_data) {
+ ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, inf->x509,
+ APLOGNO(10261) "Trusting non-leaf certificate");
+ X509_STORE_add_cert(store, inf->x509); /* increments inf->x509 */
+ /* Delete from the stack and iterate again. */
+ X509_INFO_free(inf);
+ sk_X509_INFO_delete(sk, n);
+ n--;
+ addl_chain = 1;
+ continue;
+ }
+
+ if (!has_privkey || inf->enc_data) {
sk_X509_INFO_free(sk);
ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252)
"incomplete client cert configured for SSL proxy "
@@ -1737,13 +1749,21 @@ static apr_status_t ssl_init_proxy_certs(server_rec *s,
}
}
+ if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
+ sk_X509_INFO_free(sk);
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
+ "no client certs found for SSL proxy");
+ return APR_SUCCESS;
+ }
+
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02207)
"loaded %d client certs for SSL proxy",
ncerts);
pkp->certs = sk;
-
- if (!pkp->ca_cert_file || !store) {
+ /* If any chain certs are configured, build the ->ca_certs chains
+ * corresponding to the loaded keypairs. */
+ if (!pkp->ca_cert_file && !addl_chain) {
return APR_SUCCESS;
}

@ -0,0 +1,81 @@
diff --git a/server/util_script.c b/server/util_script.c
index 4121ae0..b7f8674 100644
--- a/server/util_script.c
+++ b/server/util_script.c
@@ -92,9 +92,21 @@ static void add_unless_null(apr_table_t *table, const char *name, const char *va
}
}
-static void env2env(apr_table_t *table, const char *name)
+/* Sets variable @name in table @dest from r->subprocess_env if
+ * available, else from the environment, else from @fallback if
+ * non-NULL. */
+static void env2env(apr_table_t *dest, request_rec *r,
+ const char *name, const char *fallback)
{
- add_unless_null(table, name, getenv(name));
+ const char *val;
+
+ val = apr_table_get(r->subprocess_env, name);
+ if (!val)
+ val = apr_pstrdup(r->pool, getenv(name));
+ if (!val)
+ val = apr_pstrdup(r->pool, fallback);
+ if (val)
+ apr_table_addn(dest, name, val);
}
AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
@@ -211,37 +223,29 @@ AP_DECLARE(void) ap_add_common_vars(request_rec *r)
add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
}
- env_temp = apr_table_get(r->subprocess_env, "PATH");
- if (env_temp == NULL) {
- env_temp = getenv("PATH");
- }
- if (env_temp == NULL) {
- env_temp = DEFAULT_PATH;
- }
- apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_temp));
-
+ env2env(e, r, "PATH", DEFAULT_PATH);
#if defined(WIN32)
- env2env(e, "SystemRoot");
- env2env(e, "COMSPEC");
- env2env(e, "PATHEXT");
- env2env(e, "WINDIR");
+ env2env(e, r, "SystemRoot", NULL);
+ env2env(e, r, "COMSPEC", NULL);
+ env2env(e, r, "PATHEXT", NULL);
+ env2env(e, r, "WINDIR", NULL);
#elif defined(OS2)
- env2env(e, "COMSPEC");
- env2env(e, "ETC");
- env2env(e, "DPATH");
- env2env(e, "PERLLIB_PREFIX");
+ env2env(e, r, "COMSPEC", NULL);
+ env2env(e, r, "ETC", NULL);
+ env2env(e, r, "DPATH", NULL);
+ env2env(e, r, "PERLLIB_PREFIX", NULL);
#elif defined(BEOS)
- env2env(e, "LIBRARY_PATH");
+ env2env(e, r, "LIBRARY_PATH", NULL);
#elif defined(DARWIN)
- env2env(e, "DYLD_LIBRARY_PATH");
+ env2env(e, r, "DYLD_LIBRARY_PATH", NULL);
#elif defined(_AIX)
- env2env(e, "LIBPATH");
+ env2env(e, r, "LIBPATH", NULL);
#elif defined(__HPUX__)
/* HPUX PARISC 2.0W knows both, otherwise redundancy is harmless */
- env2env(e, "SHLIB_PATH");
- env2env(e, "LD_LIBRARY_PATH");
+ env2env(e, r, "SHLIB_PATH", NULL);
+ env2env(e, r, "LD_LIBRARY_PATH", NULL);
#else /* Some Unix */
- env2env(e, "LD_LIBRARY_PATH");
+ env2env(e, r, "LD_LIBRARY_PATH", NULL);
#endif
apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));

@ -0,0 +1,249 @@
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 211ebff..c8cb1af 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -871,6 +871,13 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
SSL_CTX_set_keylog_callback(ctx, modssl_callback_keylog);
}
#endif
+
+#ifdef SSL_OP_NO_RENEGOTIATION
+ /* For server-side SSL_CTX, disable renegotiation by default.. */
+ if (!mctx->pkp) {
+ SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION);
+ }
+#endif
return APR_SUCCESS;
}
@@ -892,6 +899,14 @@ static void ssl_init_ctx_session_cache(server_rec *s,
}
}
+#ifdef SSL_OP_NO_RENEGOTIATION
+/* OpenSSL-level renegotiation protection. */
+#define MODSSL_BLOCKS_RENEG (0)
+#else
+/* mod_ssl-level renegotiation protection. */
+#define MODSSL_BLOCKS_RENEG (1)
+#endif
+
static void ssl_init_ctx_callbacks(server_rec *s,
apr_pool_t *p,
apr_pool_t *ptemp,
@@ -905,7 +920,13 @@ static void ssl_init_ctx_callbacks(server_rec *s,
SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
#endif
- SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
+ /* The info callback is used for debug-level tracing. For OpenSSL
+ * versions where SSL_OP_NO_RENEGOTIATION is not available, the
+ * callback is also used to prevent use of client-initiated
+ * renegotiation. Enable it in either case. */
+ if (APLOGdebug(s) || MODSSL_BLOCKS_RENEG) {
+ SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
+ }
#ifdef HAVE_TLS_ALPN
SSL_CTX_set_alpn_select_cb(ctx, ssl_callback_alpn_select, NULL);
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
index 79b9a70..3a0c22a 100644
--- a/modules/ssl/ssl_engine_io.c
+++ b/modules/ssl/ssl_engine_io.c
@@ -209,11 +209,13 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl)
BIO_clear_retry_flags(bio);
+#ifndef SSL_OP_NO_RENEGOTIATION
/* Abort early if the client has initiated a renegotiation. */
if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) {
outctx->rc = APR_ECONNABORTED;
return -1;
}
+#endif
ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, outctx->c,
"bio_filter_out_write: %i bytes", inl);
@@ -474,11 +476,13 @@ static int bio_filter_in_read(BIO *bio, char *in, int inlen)
BIO_clear_retry_flags(bio);
+#ifndef SSL_OP_NO_RENEGOTIATION
/* Abort early if the client has initiated a renegotiation. */
if (inctx->filter_ctx->config->reneg_state == RENEG_ABORT) {
inctx->rc = APR_ECONNABORTED;
return -1;
}
+#endif
if (!inctx->bb) {
inctx->rc = APR_EOF;
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index 591f6ae..8416864 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -992,7 +992,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo
/* Toggle the renegotiation state to allow the new
* handshake to proceed. */
- sslconn->reneg_state = RENEG_ALLOW;
+ modssl_set_reneg_state(sslconn, RENEG_ALLOW);
SSL_renegotiate(ssl);
SSL_do_handshake(ssl);
@@ -1019,7 +1019,7 @@ static int ssl_hook_Access_classic(request_rec *r, SSLSrvConfigRec *sc, SSLDirCo
*/
SSL_peek(ssl, peekbuf, 0);
- sslconn->reneg_state = RENEG_REJECT;
+ modssl_set_reneg_state(sslconn, RENEG_REJECT);
if (!SSL_is_init_finished(ssl)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02261)
@@ -1078,7 +1078,7 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
(sc->server->auth.verify_mode != SSL_CVERIFY_UNSET)) {
int vmode_inplace, vmode_needed;
int change_vmode = FALSE;
- int old_state, n, rc;
+ int n, rc;
vmode_inplace = SSL_get_verify_mode(ssl);
vmode_needed = SSL_VERIFY_NONE;
@@ -1180,8 +1180,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
return HTTP_FORBIDDEN;
}
- old_state = sslconn->reneg_state;
- sslconn->reneg_state = RENEG_ALLOW;
modssl_set_app_data2(ssl, r);
SSL_do_handshake(ssl);
@@ -1191,7 +1189,6 @@ static int ssl_hook_Access_modern(request_rec *r, SSLSrvConfigRec *sc, SSLDirCon
*/
SSL_peek(ssl, peekbuf, 0);
- sslconn->reneg_state = old_state;
modssl_set_app_data2(ssl, NULL);
/*
@@ -2263,8 +2260,8 @@ static void log_tracing_state(const SSL *ssl, conn_rec *c,
/*
* This callback function is executed while OpenSSL processes the SSL
* handshake and does SSL record layer stuff. It's used to trap
- * client-initiated renegotiations, and for dumping everything to the
- * log.
+ * client-initiated renegotiations (where SSL_OP_NO_RENEGOTIATION is
+ * not available), and for dumping everything to the log.
*/
void ssl_callback_Info(const SSL *ssl, int where, int rc)
{
@@ -2276,14 +2273,12 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
return;
}
- /* With TLS 1.3 this callback may be called multiple times on the first
- * negotiation, so the below logic to detect renegotiations can't work.
- * Fortunately renegotiations are forbidden starting with TLS 1.3, and
- * this is enforced by OpenSSL so there's nothing to be done here.
- */
-#if SSL_HAVE_PROTOCOL_TLSV1_3
- if (SSL_version(ssl) < TLS1_3_VERSION)
-#endif
+#ifndef SSL_OP_NO_RENEGOTIATION
+ /* With OpenSSL < 1.1.1 (implying TLS v1.2 or earlier), this
+ * callback is used to block client-initiated renegotiation. With
+ * TLSv1.3 it is unnecessary since renegotiation is forbidden at
+ * protocol level. Otherwise (TLSv1.2 with OpenSSL >=1.1.1),
+ * SSL_OP_NO_RENEGOTIATION is used to block renegotiation. */
{
SSLConnRec *sslconn;
@@ -2308,6 +2303,7 @@ void ssl_callback_Info(const SSL *ssl, int where, int rc)
sslconn->reneg_state = RENEG_REJECT;
}
}
+#endif
s = mySrvFromConn(c);
if (s && APLOGdebug(s)) {
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index a329d99..7666c31 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -512,6 +512,16 @@ typedef struct {
apr_time_t source_mtime;
} ssl_asn1_t;
+typedef enum {
+ RENEG_INIT = 0, /* Before initial handshake */
+ RENEG_REJECT, /* After initial handshake; any client-initiated
+ * renegotiation should be rejected */
+ RENEG_ALLOW, /* A server-initiated renegotiation is taking
+ * place (as dictated by configuration) */
+ RENEG_ABORT /* Renegotiation initiated by client, abort the
+ * connection */
+} modssl_reneg_state;
+
/**
* Define the mod_ssl per-module configuration structure
* (i.e. the global configuration for each httpd process)
@@ -543,18 +553,13 @@ typedef struct {
NON_SSL_SET_ERROR_MSG /* Need to set the error message */
} non_ssl_request;
- /* Track the handshake/renegotiation state for the connection so
- * that all client-initiated renegotiations can be rejected, as a
- * partial fix for CVE-2009-3555. */
- enum {
- RENEG_INIT = 0, /* Before initial handshake */
- RENEG_REJECT, /* After initial handshake; any client-initiated
- * renegotiation should be rejected */
- RENEG_ALLOW, /* A server-initiated renegotiation is taking
- * place (as dictated by configuration) */
- RENEG_ABORT /* Renegotiation initiated by client, abort the
- * connection */
- } reneg_state;
+#ifndef SSL_OP_NO_RENEGOTIATION
+ /* For OpenSSL < 1.1.1, track the handshake/renegotiation state
+ * for the connection to block client-initiated renegotiations.
+ * For OpenSSL >=1.1.1, the SSL_OP_NO_RENEGOTIATION flag is used in
+ * the SSL * options state with equivalent effect. */
+ modssl_reneg_state reneg_state;
+#endif
server_rec *server;
SSLDirConfigRec *dc;
@@ -1158,6 +1163,9 @@ int ssl_is_challenge(conn_rec *c, const char *servername,
* the configured ENGINE. */
int modssl_is_engine_id(const char *name);
+/* Set the renegotation state for connection. */
+void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state);
+
#endif /* SSL_PRIVATE_H */
/** @} */
diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c
index 38079a9..dafb833 100644
--- a/modules/ssl/ssl_util_ssl.c
+++ b/modules/ssl/ssl_util_ssl.c
@@ -589,3 +589,19 @@ cleanup:
}
return rv;
}
+
+void modssl_set_reneg_state(SSLConnRec *sslconn, modssl_reneg_state state)
+{
+#ifdef SSL_OP_NO_RENEGOTIATION
+ switch (state) {
+ case RENEG_ALLOW:
+ SSL_clear_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION);
+ break;
+ default:
+ SSL_set_options(sslconn->ssl, SSL_OP_NO_RENEGOTIATION);
+ break;
+ }
+#else
+ sslconn->reneg_state = state;
+#endif
+}

@ -0,0 +1,156 @@
# ./pullrev.sh 1892413 1895552
https://bugzilla.redhat.com/show_bug.cgi?id=1938740
http://svn.apache.org/viewvc?view=revision&revision=1892413
http://svn.apache.org/viewvc?view=revision&revision=1895552
- also mod_cgi/mod_cgid log_flags fix from r1881559
--- httpd-2.4.51/modules/filters/mod_deflate.c.r1892413+
+++ httpd-2.4.51/modules/filters/mod_deflate.c
@@ -1275,44 +1275,46 @@
if (APR_BUCKET_IS_FLUSH(bkt)) {
apr_bucket *tmp_b;
- ctx->inflate_total += ctx->stream.avail_out;
- zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH);
- ctx->inflate_total -= ctx->stream.avail_out;
- if (zRC != Z_OK) {
- inflateEnd(&ctx->stream);
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01391)
- "Zlib error %d inflating data (%s)", zRC,
- ctx->stream.msg);
- return APR_EGENERAL;
- }
+ if (!ctx->done) {
+ ctx->inflate_total += ctx->stream.avail_out;
+ zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH);
+ ctx->inflate_total -= ctx->stream.avail_out;
+ if (zRC != Z_OK) {
+ inflateEnd(&ctx->stream);
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(01391)
+ "Zlib error %d inflating data (%s)", zRC,
+ ctx->stream.msg);
+ return APR_EGENERAL;
+ }
- if (inflate_limit && ctx->inflate_total > inflate_limit) {
- inflateEnd(&ctx->stream);
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02647)
- "Inflated content length of %" APR_OFF_T_FMT
- " is larger than the configured limit"
- " of %" APR_OFF_T_FMT,
- ctx->inflate_total, inflate_limit);
- return APR_ENOSPC;
- }
+ if (inflate_limit && ctx->inflate_total > inflate_limit) {
+ inflateEnd(&ctx->stream);
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02647)
+ "Inflated content length of %" APR_OFF_T_FMT
+ " is larger than the configured limit"
+ " of %" APR_OFF_T_FMT,
+ ctx->inflate_total, inflate_limit);
+ return APR_ENOSPC;
+ }
- if (!check_ratio(r, ctx, dc)) {
- inflateEnd(&ctx->stream);
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02805)
- "Inflated content ratio is larger than the "
- "configured limit %i by %i time(s)",
- dc->ratio_limit, dc->ratio_burst);
- return APR_EINVAL;
- }
+ if (!check_ratio(r, ctx, dc)) {
+ inflateEnd(&ctx->stream);
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02805)
+ "Inflated content ratio is larger than the "
+ "configured limit %i by %i time(s)",
+ dc->ratio_limit, dc->ratio_burst);
+ return APR_EINVAL;
+ }
- len = c->bufferSize - ctx->stream.avail_out;
- ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
- tmp_b = apr_bucket_heap_create((char *)ctx->buffer, len,
- NULL, f->c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_b);
+ len = c->bufferSize - ctx->stream.avail_out;
+ ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
+ tmp_b = apr_bucket_heap_create((char *)ctx->buffer, len,
+ NULL, f->c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_b);
- ctx->stream.next_out = ctx->buffer;
- ctx->stream.avail_out = c->bufferSize;
+ ctx->stream.next_out = ctx->buffer;
+ ctx->stream.avail_out = c->bufferSize;
+ }
/* Flush everything so far in the returning brigade, but continue
* reading should EOS/more follow (don't lose them).
--- httpd-2.4.51/modules/generators/mod_cgi.c.r1892413+
+++ httpd-2.4.51/modules/generators/mod_cgi.c
@@ -191,11 +191,10 @@
apr_file_t *f = NULL;
apr_finfo_t finfo;
char time_str[APR_CTIME_LEN];
- int log_flags = rv ? APLOG_ERR : APLOG_ERR;
/* Intentional no APLOGNO */
/* Callee provides APLOGNO in error text */
- ap_log_rerror(APLOG_MARK, log_flags, rv, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
"%s%s: %s", logno ? logno : "", error, r->filename);
/* XXX Very expensive mainline case! Open, then getfileinfo! */
--- httpd-2.4.51/modules/generators/mod_cgid.c.r1892413+
+++ httpd-2.4.51/modules/generators/mod_cgid.c
@@ -1190,11 +1190,10 @@
apr_file_t *f = NULL;
struct stat finfo;
char time_str[APR_CTIME_LEN];
- int log_flags = rv ? APLOG_ERR : APLOG_ERR;
/* Intentional no APLOGNO */
/* Callee provides APLOGNO in error text */
- ap_log_rerror(APLOG_MARK, log_flags, rv, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
"%s: %s", error, r->filename);
/* XXX Very expensive mainline case! Open, then getfileinfo! */
--- httpd-2.4.51/server/mpm_unix.c.r1892413+
+++ httpd-2.4.51/server/mpm_unix.c
@@ -259,10 +259,12 @@
while (cur_extra) {
ap_generation_t old_gen;
extra_process_t *next = cur_extra->next;
+ pid_t pid = cur_extra->pid;
- if (reclaim_one_pid(cur_extra->pid, action_table[cur_action].action)) {
- if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
- mpm_callback(-1, cur_extra->pid, old_gen);
+ if (reclaim_one_pid(pid, action_table[cur_action].action)) {
+ if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) {
+ /* cur_extra dangling pointer from here. */
+ mpm_callback(-1, pid, old_gen);
}
else {
AP_DEBUG_ASSERT(1 == 0);
@@ -307,10 +309,12 @@
while (cur_extra) {
ap_generation_t old_gen;
extra_process_t *next = cur_extra->next;
+ pid_t pid = cur_extra->pid;
- if (reclaim_one_pid(cur_extra->pid, DO_NOTHING)) {
- if (ap_unregister_extra_mpm_process(cur_extra->pid, &old_gen) == 1) {
- mpm_callback(-1, cur_extra->pid, old_gen);
+ if (reclaim_one_pid(pid, DO_NOTHING)) {
+ if (ap_unregister_extra_mpm_process(pid, &old_gen) == 1) {
+ /* cur_extra dangling pointer from here. */
+ mpm_callback(-1, pid, old_gen);
}
else {
AP_DEBUG_ASSERT(1 == 0);

@ -0,0 +1,116 @@
diff --git a/include/util_ldap.h b/include/util_ldap.h
index 28e0760..edb8a81 100644
--- a/include/util_ldap.h
+++ b/include/util_ldap.h
@@ -32,7 +32,6 @@
#if APR_MAJOR_VERSION < 2
/* The LDAP API is currently only present in APR 1.x */
#include "apr_ldap.h"
-#include "apr_ldap_rebind.h"
#else
#define APR_HAS_LDAP 0
#endif
diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c
index 4d92ec9..864bd62 100644
--- a/modules/ldap/util_ldap.c
+++ b/modules/ldap/util_ldap.c
@@ -154,6 +154,38 @@ static int util_ldap_handler(request_rec *r)
return OK;
}
+/* For OpenLDAP with the 3-arg version of ldap_set_rebind_proc(), use
+ * a simpler rebind callback than the implementation in APR-util.
+ * Testing for API version >= 3001 appears safe although OpenLDAP
+ * 2.1.x (API version = 2004) also has the 3-arg API. */
+#if APR_HAS_OPENLDAP_LDAPSDK && defined(LDAP_API_VERSION) && LDAP_API_VERSION >= 3001
+
+#define uldap_rebind_init(p) APR_SUCCESS /* noop */
+
+static int uldap_rebind_proc(LDAP *ld, const char *url, ber_tag_t request,
+ ber_int_t msgid, void *params)
+{
+ util_ldap_connection_t *ldc = params;
+
+ return ldap_bind_s(ld, ldc->binddn, ldc->bindpw, LDAP_AUTH_SIMPLE);
+}
+
+static apr_status_t uldap_rebind_add(util_ldap_connection_t *ldc)
+{
+ ldap_set_rebind_proc(ldc->ldap, uldap_rebind_proc, ldc);
+ return APR_SUCCESS;
+}
+
+#else /* !APR_HAS_OPENLDAP_LDAPSDK */
+
+#define USE_APR_LDAP_REBIND
+#include <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) {

@ -0,0 +1,11 @@
--- a/modules/core/mod_macro.c 2023/10/16 06:19:16 1912992
+++ b/modules/core/mod_macro.c 2023/10/16 06:38:32 1912993
@@ -483,7 +483,7 @@
for (i = 0; i < contents->nelts; i++) {
const char *errmsg;
/* copy the line and substitute macro parameters */
- strncpy(line, ((char **) contents->elts)[i], MAX_STRING_LEN - 1);
+ apr_cpystrn(line, ((char **) contents->elts)[i], MAX_STRING_LEN);
errmsg = substitute_macro_args(line, MAX_STRING_LEN,
macro, replacements, used);
if (errmsg) {

@ -0,0 +1,14 @@
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index f93f23f..4be51de 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -4758,8 +4758,8 @@ static int hook_uri2file(request_rec *r)
}
if (rulestatus) {
- unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
apr_size_t flen = r->filename ? strlen(r->filename) : 0;
+ unsigned skip_absolute = flen ? is_absolute_uri(r->filename, NULL) : 0;
int to_proxyreq = (flen > 6 && strncmp(r->filename, "proxy:", 6) == 0);
int will_escape = skip_absolute && (rulestatus != ACTION_NOESCAPE);

@ -0,0 +1,51 @@
--- httpd-2.4.57/modules/dav/fs/repos.c.davenoent
+++ httpd-2.4.57/modules/dav/fs/repos.c
@@ -35,6 +35,7 @@
#include "mod_dav.h"
#include "repos.h"
+APLOG_USE_MODULE(dav_fs);
/* to assist in debugging mod_dav's GET handling */
#define DEBUG_GET_HANDLER 0
@@ -1586,6 +1587,19 @@
status = apr_stat(&fsctx->info1.finfo, fsctx->path1.buf,
DAV_FINFO_MASK, pool);
if (status != APR_SUCCESS && status != APR_INCOMPLETE) {
+ dav_resource_private *ctx = params->root->info;
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, status, ctx->r,
+ APLOGNO(10472) "could not access file (%s) during directory walk",
+ fsctx->path1.buf);
+
+ /* If being tolerant, ignore failure due to losing a race
+ * with some other process deleting files out from under
+ * the directory walk. */
+ if ((params->walk_type & DAV_WALKTYPE_TOLERANT)
+ && APR_STATUS_IS_ENOENT(status)) {
+ continue;
+ }
/* woah! where'd it go? */
/* ### should have a better error here */
err = dav_new_error(pool, HTTP_NOT_FOUND, 0, status, NULL);
--- httpd-2.4.57/modules/dav/main/mod_dav.c.davenoent
+++ httpd-2.4.57/modules/dav/main/mod_dav.c
@@ -2187,7 +2187,7 @@
return HTTP_BAD_REQUEST;
}
- ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH;
+ ctx.w.walk_type = DAV_WALKTYPE_NORMAL | DAV_WALKTYPE_AUTH | DAV_WALKTYPE_TOLERANT;
ctx.w.func = dav_propfind_walker;
ctx.w.walk_ctx = &ctx;
ctx.w.pool = r->pool;
--- httpd-2.4.57/modules/dav/main/mod_dav.h.davenoent
+++ httpd-2.4.57/modules/dav/main/mod_dav.h
@@ -1823,6 +1823,7 @@
#define DAV_WALKTYPE_AUTH 0x0001 /* limit to authorized files */
#define DAV_WALKTYPE_NORMAL 0x0002 /* walk normal files */
#define DAV_WALKTYPE_LOCKNULL 0x0004 /* walk locknull resources */
+#define DAV_WALKTYPE_TOLERANT 0x0008 /* tolerate non-fatal errors */
/* callback function and a client context for the walk */
dav_error * (*func)(dav_walk_resource *wres, int calltype);

@ -0,0 +1,81 @@
diff --git a/configure.in b/configure.in
index a3c994b..9a4351a 100644
--- a/configure.in
+++ b/configure.in
@@ -524,7 +524,8 @@ prctl \
timegm \
getpgid \
fopen64 \
-getloadavg
+getloadavg \
+gettid
)
dnl confirm that a void pointer is large enough to store a long integer
@@ -535,16 +536,19 @@ AC_CHECK_LIB(selinux, is_selinux_enabled, [
APR_ADDTO(HTTPD_LIBS, [-lselinux])
])
-AC_CACHE_CHECK([for gettid()], ac_cv_gettid,
+if test $ac_cv_func_gettid = no; then
+ # On Linux before glibc 2.30, gettid() is only usable via syscall()
+ AC_CACHE_CHECK([for gettid() via syscall], ap_cv_gettid,
[AC_TRY_RUN(#define _GNU_SOURCE
#include <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
diff --git a/server/log.c b/server/log.c
index cc04c38..ed3b920 100644
--- a/server/log.c
+++ b/server/log.c
@@ -55,7 +55,7 @@
#include "ap_mpm.h"
#include "ap_listen.h"
-#if HAVE_GETTID
+#if HAVE_SYS_GETTID
#include <sys/syscall.h>
#include <sys/types.h>
#endif
@@ -627,14 +627,18 @@ static int log_tid(const ap_errorlog_info *info, const char *arg,
#if APR_HAS_THREADS
int result;
#endif
-#if HAVE_GETTID
+#if defined(HAVE_GETTID) || defined(HAVE_SYS_GETTID)
if (arg && *arg == 'g') {
+#ifdef HAVE_GETTID
+ pid_t tid = gettid();
+#else
pid_t tid = syscall(SYS_gettid);
+#endif
if (tid == -1)
return 0;
return apr_snprintf(buf, buflen, "%"APR_PID_T_FMT, tid);
}
-#endif
+#endif /* HAVE_GETTID || HAVE_SYS_GETTID */
#if APR_HAS_THREADS
if (ap_mpm_query(AP_MPMQ_IS_THREADED, &result) == APR_SUCCESS
&& result != AP_MPMQ_NOT_SUPPORTED)
@@ -968,7 +972,7 @@ static int do_errorlog_default(const ap_errorlog_info *info, char *buf,
#if APR_HAS_THREADS
field_start = len;
len += cpystrn(buf + len, ":tid ", buflen - len);
- item_len = log_tid(info, NULL, buf + len, buflen - len);
+ item_len = log_tid(info, "g", buf + len, buflen - len);
if (!item_len)
len = field_start;
else

@ -0,0 +1,170 @@
commit af065bb14238c2877f16dc955f6db69579d45b03
Author: Tomas Korbar <tkorbar@redhat.com>
Date: Thu Jul 20 09:48:17 2023 +0200
Fix duplicate presence of keys printed by mod_status
diff --git a/modules/generators/mod_status.c b/modules/generators/mod_status.c
index 5917953..5bada07 100644
--- a/modules/generators/mod_status.c
+++ b/modules/generators/mod_status.c
@@ -186,7 +186,8 @@ static int status_handler(request_rec *r)
apr_uint32_t up_time;
ap_loadavg_t t;
int j, i, res, written;
- int ready;
+ int idle;
+ int graceful;
int busy;
unsigned long count;
unsigned long lres, my_lres, conn_lres;
@@ -203,6 +204,7 @@ static int status_handler(request_rec *r)
char *stat_buffer;
pid_t *pid_buffer, worker_pid;
int *thread_idle_buffer = NULL;
+ int *thread_graceful_buffer = NULL;
int *thread_busy_buffer = NULL;
clock_t tu, ts, tcu, tcs;
clock_t gu, gs, gcu, gcs;
@@ -231,7 +233,8 @@ static int status_handler(request_rec *r)
#endif
#endif
- ready = 0;
+ idle = 0;
+ graceful = 0;
busy = 0;
count = 0;
bcount = 0;
@@ -250,6 +253,7 @@ static int status_handler(request_rec *r)
stat_buffer = apr_palloc(r->pool, server_limit * thread_limit * sizeof(char));
if (is_async) {
thread_idle_buffer = apr_palloc(r->pool, server_limit * sizeof(int));
+ thread_graceful_buffer = apr_palloc(r->pool, server_limit * sizeof(int));
thread_busy_buffer = apr_palloc(r->pool, server_limit * sizeof(int));
}
@@ -318,6 +322,7 @@ static int status_handler(request_rec *r)
ps_record = ap_get_scoreboard_process(i);
if (is_async) {
thread_idle_buffer[i] = 0;
+ thread_graceful_buffer[i] = 0;
thread_busy_buffer[i] = 0;
}
for (j = 0; j < thread_limit; ++j) {
@@ -336,18 +341,20 @@ static int status_handler(request_rec *r)
&& ps_record->pid) {
if (res == SERVER_READY) {
if (ps_record->generation == mpm_generation)
- ready++;
+ idle++;
if (is_async)
thread_idle_buffer[i]++;
}
else if (res != SERVER_DEAD &&
res != SERVER_STARTING &&
res != SERVER_IDLE_KILL) {
- busy++;
- if (is_async) {
- if (res == SERVER_GRACEFUL)
- thread_idle_buffer[i]++;
- else
+ if (res == SERVER_GRACEFUL) {
+ graceful++;
+ if (is_async)
+ thread_graceful_buffer[i]++;
+ } else {
+ busy++;
+ if (is_async)
thread_busy_buffer[i]++;
}
}
@@ -548,10 +555,10 @@ static int status_handler(request_rec *r)
} /* ap_extended_status */
if (!short_report)
- ap_rprintf(r, "<dt>%d requests currently being processed, "
- "%d idle workers</dt>\n", busy, ready);
+ ap_rprintf(r, "<dt>%d requests currently being processed, %d workers gracefully restarting, "
+ "%d idle workers</dt>\n", busy, graceful, idle);
else
- ap_rprintf(r, "BusyWorkers: %d\nIdleWorkers: %d\n", busy, ready);
+ ap_rprintf(r, "BusyWorkers: %d\nGracefulWorkers: %d\nIdleWorkers: %d\n", busy, graceful, idle);
if (!short_report)
ap_rputs("</dl>", r);
@@ -559,11 +566,6 @@ static int status_handler(request_rec *r)
if (is_async) {
int write_completion = 0, lingering_close = 0, keep_alive = 0,
connections = 0, stopping = 0, procs = 0;
- /*
- * These differ from 'busy' and 'ready' in how gracefully finishing
- * threads are counted. XXX: How to make this clear in the html?
- */
- int busy_workers = 0, idle_workers = 0;
if (!short_report)
ap_rputs("\n\n<table rules=\"all\" cellpadding=\"1%\">\n"
"<tr><th rowspan=\"2\">Slot</th>"
@@ -573,7 +575,7 @@ static int status_handler(request_rec *r)
"<th colspan=\"2\">Threads</th>"
"<th colspan=\"3\">Async connections</th></tr>\n"
"<tr><th>total</th><th>accepting</th>"
- "<th>busy</th><th>idle</th>"
+ "<th>busy</th><th>graceful</th><th>idle</th>"
"<th>writing</th><th>keep-alive</th><th>closing</th></tr>\n", r);
for (i = 0; i < server_limit; ++i) {
ps_record = ap_get_scoreboard_process(i);
@@ -582,8 +584,6 @@ static int status_handler(request_rec *r)
write_completion += ps_record->write_completion;
keep_alive += ps_record->keep_alive;
lingering_close += ps_record->lingering_close;
- busy_workers += thread_busy_buffer[i];
- idle_workers += thread_idle_buffer[i];
procs++;
if (ps_record->quiescing) {
stopping++;
@@ -599,7 +599,7 @@ static int status_handler(request_rec *r)
ap_rprintf(r, "<tr><td>%u</td><td>%" APR_PID_T_FMT "</td>"
"<td>%s%s</td>"
"<td>%u</td><td>%s</td>"
- "<td>%u</td><td>%u</td>"
+ "<td>%u</td><td>%u</td><td>%u</td>"
"<td>%u</td><td>%u</td><td>%u</td>"
"</tr>\n",
i, ps_record->pid,
@@ -607,6 +607,7 @@ static int status_handler(request_rec *r)
ps_record->connections,
ps_record->not_accepting ? "no" : "yes",
thread_busy_buffer[i],
+ thread_graceful_buffer[i],
thread_idle_buffer[i],
ps_record->write_completion,
ps_record->keep_alive,
@@ -618,25 +619,22 @@ static int status_handler(request_rec *r)
ap_rprintf(r, "<tr><td>Sum</td>"
"<td>%d</td><td>%d</td>"
"<td>%d</td><td>&nbsp;</td>"
- "<td>%d</td><td>%d</td>"
+ "<td>%d</td><td>%d</td><td>%d</td>"
"<td>%d</td><td>%d</td><td>%d</td>"
"</tr>\n</table>\n",
procs, stopping,
connections,
- busy_workers, idle_workers,
+ busy, graceful, idle,
write_completion, keep_alive, lingering_close);
}
else {
ap_rprintf(r, "Processes: %d\n"
"Stopping: %d\n"
- "BusyWorkers: %d\n"
- "IdleWorkers: %d\n"
"ConnsTotal: %d\n"
"ConnsAsyncWriting: %d\n"
"ConnsAsyncKeepAlive: %d\n"
"ConnsAsyncClosing: %d\n",
procs, stopping,
- busy_workers, idle_workers,
connections,
write_completion, keep_alive, lingering_close);
}

@ -0,0 +1,143 @@
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index 537c3c2..596320d 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -1460,11 +1460,20 @@ static int proxy_handler(request_rec *r)
/* handle the scheme */
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01142)
"Trying to run scheme_handler against proxy");
+
+ if (ents[i].creds) {
+ apr_table_set(r->notes, "proxy-basic-creds", ents[i].creds);
+ ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
+ "Using proxy auth creds %s", ents[i].creds);
+ }
+
access_status = proxy_run_scheme_handler(r, worker,
conf, url,
ents[i].hostname,
ents[i].port);
+ if (ents[i].creds) apr_table_unset(r->notes, "proxy-basic-creds");
+
/* Did the scheme handler process the request? */
if (access_status != DECLINED) {
const char *cl_a;
@@ -1902,8 +1911,8 @@ static void *merge_proxy_dir_config(apr_pool_t *p, void *basev, void *addv)
return new;
}
-static const char *
- add_proxy(cmd_parms *cmd, void *dummy, const char *f1, const char *r1, int regex)
+static const char *add_proxy(cmd_parms *cmd, void *dummy, const char *f1,
+ const char *r1, const char *creds, int regex)
{
server_rec *s = cmd->server;
proxy_server_conf *conf =
@@ -1961,19 +1970,24 @@ static const char *
new->port = port;
new->regexp = reg;
new->use_regex = regex;
+ if (creds) {
+ new->creds = apr_pstrcat(cmd->pool, "Basic ",
+ ap_pbase64encode(cmd->pool, (char *)creds),
+ NULL);
+ }
return NULL;
}
-static const char *
- add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1)
+static const char *add_proxy_noregex(cmd_parms *cmd, void *dummy, const char *f1,
+ const char *r1, const char *creds)
{
- return add_proxy(cmd, dummy, f1, r1, 0);
+ return add_proxy(cmd, dummy, f1, r1, creds, 0);
}
-static const char *
- add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1, const char *r1)
+static const char *add_proxy_regex(cmd_parms *cmd, void *dummy, const char *f1,
+ const char *r1, const char *creds)
{
- return add_proxy(cmd, dummy, f1, r1, 1);
+ return add_proxy(cmd, dummy, f1, r1, creds, 1);
}
PROXY_DECLARE(const char *) ap_proxy_de_socketfy(apr_pool_t *p, const char *url)
@@ -3012,9 +3026,9 @@ static const command_rec proxy_cmds[] =
"location, in regular expression syntax"),
AP_INIT_FLAG("ProxyRequests", set_proxy_req, NULL, RSRC_CONF,
"on if the true proxy requests should be accepted"),
- AP_INIT_TAKE2("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF,
+ AP_INIT_TAKE23("ProxyRemote", add_proxy_noregex, NULL, RSRC_CONF,
"a scheme, partial URL or '*' and a proxy server"),
- AP_INIT_TAKE2("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF,
+ AP_INIT_TAKE23("ProxyRemoteMatch", add_proxy_regex, NULL, RSRC_CONF,
"a regex pattern and a proxy server"),
AP_INIT_FLAG("ProxyPassInterpolateEnv", ap_set_flag_slot_char,
(void*)APR_OFFSETOF(proxy_dir_conf, interpolate_env),
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
index c51145e..eaf431d 100644
--- a/modules/proxy/mod_proxy.h
+++ b/modules/proxy/mod_proxy.h
@@ -121,6 +121,7 @@ struct proxy_remote {
const char *protocol; /* the scheme used to talk to this proxy */
const char *hostname; /* the hostname of this proxy */
ap_regex_t *regexp; /* compiled regex (if any) for the remote */
+ const char *creds; /* auth credentials (if any) for the proxy */
int use_regex; /* simple boolean. True if we have a regex pattern */
apr_port_t port; /* the port for this proxy */
};
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index caafde0..ea36465 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -2708,11 +2708,14 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
* So let's make it configurable by env.
* The logic here is the same used in mod_proxy_http.
*/
- proxy_auth = apr_table_get(r->headers_in, "Proxy-Authorization");
+ proxy_auth = apr_table_get(r->notes, "proxy-basic-creds");
+ if (proxy_auth == NULL)
+ proxy_auth = apr_table_get(r->headers_in, "Proxy-Authorization");
+
if (proxy_auth != NULL &&
proxy_auth[0] != '\0' &&
- r->user == NULL && /* we haven't yet authenticated */
- apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) {
+ (r->user == NULL /* we haven't yet authenticated */
+ || apr_table_get(r->subprocess_env, "Proxy-Chain-Auth"))) {
forward->proxy_auth = apr_pstrdup(conn->pool, proxy_auth);
}
}
@@ -2948,7 +2951,8 @@ static apr_status_t send_http_connect(proxy_conn_rec *backend,
nbytes = apr_snprintf(buffer, sizeof(buffer),
"CONNECT %s:%d HTTP/1.0" CRLF,
forward->target_host, forward->target_port);
- /* Add proxy authorization from the initial request if necessary */
+ /* Add proxy authorization from the configuration, or initial
+ * request if necessary */
if (forward->proxy_auth != NULL) {
nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes,
"Proxy-Authorization: %s" CRLF,
@@ -3909,6 +3913,7 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
int force10 = 0, do_100_continue = 0;
conn_rec *origin = p_conn->connection;
const char *host, *val;
+ const char *creds;
proxy_dir_conf *dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
/*
@@ -4131,6 +4136,11 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
/* run hook to fixup the request we are about to send */
proxy_run_fixups(r);
+ creds = apr_table_get(r->notes, "proxy-basic-creds");
+ if (creds) {
+ apr_table_mergen(r->headers_in, "Proxy-Authorization", creds);
+ }
+
/* We used to send `Host: ` always first, so let's keep it that
* way. No telling which legacy backend is relying on this.
* If proxy_run_fixups() changed the value, use it (though removal

@ -0,0 +1,99 @@
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 4e2e80d..10a2c86 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -2256,51 +2256,6 @@ int ssl_proxy_section_post_config(apr_pool_t *p, apr_pool_t *plog,
return OK;
}
-static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a,
- const X509_NAME * const *b)
-{
- return(X509_NAME_cmp(*a, *b));
-}
-
-static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list,
- server_rec *s, apr_pool_t *ptemp,
- const char *file)
-{
- int n;
- STACK_OF(X509_NAME) *sk;
-
- sk = (STACK_OF(X509_NAME) *)
- SSL_load_client_CA_file(file);
-
- if (!sk) {
- return;
- }
-
- for (n = 0; n < sk_X509_NAME_num(sk); n++) {
- X509_NAME *name = sk_X509_NAME_value(sk, n);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02209)
- "CA certificate: %s",
- modssl_X509_NAME_to_string(ptemp, name, 0));
-
- /*
- * note that SSL_load_client_CA_file() checks for duplicates,
- * but since we call it multiple times when reading a directory
- * we must also check for duplicates ourselves.
- */
-
- if (sk_X509_NAME_find(ca_list, name) < 0) {
- /* this will be freed when ca_list is */
- sk_X509_NAME_push(ca_list, name);
- }
- else {
- /* need to free this ourselves, else it will leak */
- X509_NAME_free(name);
- }
- }
-
- sk_X509_NAME_free(sk);
-}
static apr_status_t ssl_init_ca_cert_path(server_rec *s,
apr_pool_t *ptemp,
@@ -2324,7 +2279,7 @@ static apr_status_t ssl_init_ca_cert_path(server_rec *s,
}
file = apr_pstrcat(ptemp, path, "/", direntry.name, NULL);
if (ca_list) {
- ssl_init_PushCAList(ca_list, s, ptemp, file);
+ SSL_add_file_cert_subjects_to_stack(ca_list, file);
}
if (xi_list) {
load_x509_info(ptemp, xi_list, file);
@@ -2341,19 +2296,13 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
const char *ca_file,
const char *ca_path)
{
- STACK_OF(X509_NAME) *ca_list;
-
- /*
- * Start with a empty stack/list where new
- * entries get added in sorted order.
- */
- ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp);
+ STACK_OF(X509_NAME) *ca_list = sk_X509_NAME_new_null();;
/*
* Process CA certificate bundle file
*/
if (ca_file) {
- ssl_init_PushCAList(ca_list, s, ptemp, ca_file);
+ SSL_add_file_cert_subjects_to_stack(ca_list, ca_file);
/*
* If ca_list is still empty after trying to load ca_file
* then the file failed to load, and users should hear about that.
@@ -2377,11 +2326,6 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
return NULL;
}
- /*
- * Cleanup
- */
- (void) sk_X509_NAME_set_cmp_func(ca_list, NULL);
-
return ca_list;
}

@ -0,0 +1,39 @@
# ./pullrev.sh 1884505 1915625
http://svn.apache.org/viewvc?view=revision&revision=1884505
http://svn.apache.org/viewvc?view=revision&revision=1915625
--- httpd-2.4.57/modules/filters/mod_xml2enc.c
+++ httpd-2.4.57/modules/filters/mod_xml2enc.c
@@ -329,7 +329,7 @@
apr_bucket* bstart;
apr_size_t insz = 0;
int pending_meta = 0;
- char *ctype;
+ char *mtype;
char *p;
if (!ctx || !f->r->content_type) {
@@ -338,13 +338,17 @@
return ap_pass_brigade(f->next, bb) ;
}
- ctype = apr_pstrdup(f->r->pool, f->r->content_type);
- for (p = ctype; *p; ++p)
- if (isupper(*p))
- *p = tolower(*p);
+ /* Extract the media type, ignoring parameters in content-type. */
+ mtype = apr_pstrdup(f->r->pool, f->r->content_type);
+ if ((p = ap_strchr(mtype, ';')) != NULL) *p = '\0';
+ ap_str_tolower(mtype);
- /* only act if starts-with "text/" or contains "xml" */
- if (strncmp(ctype, "text/", 5) && !strstr(ctype, "xml")) {
+ /* Accept text/ types, plus any XML media type per RFC 7303. */
+ if (!(strncmp(mtype, "text/", 5) == 0
+ || strcmp(mtype, "application/xml") == 0
+ || (strlen(mtype) > 7 /* minimum 'a/b+xml' length */
+ && (p = strstr(mtype, "+xml")) != NULL
+ && strlen(p) == 4 /* ensures +xml is a suffix */))) {
ap_remove_output_filter(f);
return ap_pass_brigade(f->next, bb) ;
}

@ -0,0 +1,91 @@
# ./pullrev.sh 1912081
http://svn.apache.org/viewvc?view=revision&revision=1912081
Upstream-Status: merged in 2.4.58
--- httpd-2.4.57/modules/dav/main/mod_dav.c
+++ httpd-2.4.57/modules/dav/main/mod_dav.c
@@ -81,6 +81,7 @@
const char *provider_name;
const dav_provider *provider;
const char *dir;
+ const char *base;
int locktimeout;
int allow_depthinfinity;
int allow_lockdiscovery;
@@ -196,6 +197,7 @@
newconf->locktimeout = DAV_INHERIT_VALUE(parent, child, locktimeout);
newconf->dir = DAV_INHERIT_VALUE(parent, child, dir);
+ newconf->base = DAV_INHERIT_VALUE(parent, child, base);
newconf->allow_depthinfinity = DAV_INHERIT_VALUE(parent, child,
allow_depthinfinity);
newconf->allow_lockdiscovery = DAV_INHERIT_VALUE(parent, child,
@@ -283,6 +285,18 @@
}
/*
+ * Command handler for the DAVBasePath directive, which is TAKE1
+ */
+static const char *dav_cmd_davbasepath(cmd_parms *cmd, void *config, const char *arg1)
+{
+ dav_dir_conf *conf = config;
+
+ conf->base = arg1;
+
+ return NULL;
+}
+
+/*
* Command handler for the DAVDepthInfinity directive, which is FLAG.
*/
static const char *dav_cmd_davdepthinfinity(cmd_parms *cmd, void *config,
@@ -748,7 +762,7 @@
int use_checked_in, dav_resource **res_p)
{
dav_dir_conf *conf;
- const char *label = NULL;
+ const char *label = NULL, *base;
dav_error *err;
/* if the request target can be overridden, get any target selector */
@@ -765,11 +779,27 @@
ap_escape_html(r->pool, r->uri)));
}
+ /* Take the repos root from DAVBasePath if configured, else the
+ * path of the enclosing section. */
+ base = conf->base ? conf->base : conf->dir;
+
/* resolve the resource */
- err = (*conf->provider->repos->get_resource)(r, conf->dir,
+ err = (*conf->provider->repos->get_resource)(r, base,
label, use_checked_in,
res_p);
if (err != NULL) {
+ /* In the error path, give a hint that DavBasePath needs to be
+ * used if the location was configured via a regex match. */
+ if (!conf->base) {
+ core_dir_config *cdc = ap_get_core_module_config(r->per_dir_config);
+
+ if (cdc->r) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, APLOGNO(10484)
+ "failed to find repository for location configured "
+ "via regex match - missing DAVBasePath?");
+ }
+ }
+
err = dav_push_error(r->pool, err->status, 0,
"Could not fetch resource information.", err);
return err;
@@ -5164,6 +5194,10 @@
AP_INIT_TAKE1("DAV", dav_cmd_dav, NULL, ACCESS_CONF,
"specify the DAV provider for a directory or location"),
+ /* per directory/location */
+ AP_INIT_TAKE1("DAVBasePath", dav_cmd_davbasepath, NULL, ACCESS_CONF,
+ "specify the DAV repository base URL"),
+
/* per directory/location, or per server */
AP_INIT_TAKE1("DAVMinTimeout", dav_cmd_davmintimeout, NULL,
ACCESS_CONF|RSRC_CONF,

@ -1,8 +1,8 @@
diff --git a/configure.in b/configure.in
index 3932407..00e2369 100644
index 1e342bb..a3c994b 100644
--- a/configure.in
+++ b/configure.in
@@ -531,6 +531,11 @@ gettid
@@ -530,6 +530,11 @@ getloadavg
dnl confirm that a void pointer is large enough to store a long integer
APACHE_CHECK_VOID_PTR_LEN
@ -11,11 +11,11 @@ index 3932407..00e2369 100644
+ APR_ADDTO(HTTPD_LIBS, [-lselinux])
+])
+
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_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 8970a50..ff1024d 100644
index ca33d94..41e9bdc 100644
--- a/server/core.c
+++ b/server/core.c
@@ -65,6 +65,10 @@
@ -29,7 +29,7 @@ index 8970a50..ff1024d 100644
/* LimitRequestBody handling */
#define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1)
#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 1<<30) /* 1GB */
@@ -5170,6 +5174,28 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
@@ -5157,6 +5161,28 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
}
#endif

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEZbLUT+dL1ePeOsPwgngd5G1ZVPoFAmQpqJUACgkQgngd5G1Z
VPrSqhAAge2udhX49FI9zwhoxeCND0dxB/DZ8vWc6MbDryYUYZBA2+o7cvwSRSdZ
fxghFliJUWDSDD7YFjIrsAKPcjdKS2vn6+vmNRU05dw+JoZuQuyzg9PMuEOo3qRN
poVd7SsxFhAT3ow6+j2ns3ei+B87BWrgkN6P2A4UNiUKKej+EACL3JnrOGbcPoLa
ThEdphd5B6qTegw3Sz3aHgJ06833mH5KdrUNXwjmhsZCdgmBORyepjAQFKQChOq6
JExsk/PTPgy0KX27IWMgrgQohW0zEzr8BtrZsu+DXxuhjen7bKm06uEoYDCR6xF1
gu/oGBLVuDkktnRfleGUtmXoJ+yVMyz06ILL/ka5Jy3ob8sdWqD37oAcGQJeZYog
uUnW+FoCmfv6uLRxZbFr2SCr2Jc8cnI45cPpppG0OraBJHHja99W60lInDpjFvHF
U9Ev+UNU3PwtYuIhwp8tJB61cnQzxyH0Frt5lQfXxPKWTuFY3MSuoNJi1x3IqZvx
fan2kxN0R0RyvXOhD6eJcQpydRHNDj/zgIo46gL7XRPB4aFBZRPyXwTVejcT6juL
CHX/AUk18DIlBd+X7wJ115UQg9m6bABrj+Jg6ujoTb62Vstuju3P6XJ/qbCpGQcY
ZyLOwbFiDD8CMm06ELQixDa9momkXXWH6mH+cEQDkPl+Scz5pf0=
=qbuf
-----END PGP SIGNATURE-----

@ -1,242 +0,0 @@
From a0a68b99d131741c1867cff321424892838fc4b3 Mon Sep 17 00:00:00 2001
From: Yann Ylavic <ylavic@apache.org>
Date: Sat, 27 Jul 2024 13:35:53 +0000
Subject: [PATCH] mod_rewrite: Better question mark tracking to avoid
UnsafeAllow3F. PR 69197.
Track in do_expand() whether a '?' in the uri-path comes from a literal in
the substitution string or from an expansion (variable, lookup, ...).
In the former case it's safe to assume that it's the query-string separator
but for the other case it's not (could be a decoded %3f from r->uri).
This allows to avoid [UnsafeAllow3F] for most cases.
Merges r1919325 from trunk
Reviewed by: ylavic, covener, jorton
Github: closes #462
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1919545 13f79535-47bb-0310-9956-ffa450edef68
---
modules/mappers/mod_rewrite.c | 107 ++++++++++++++++++++++++++++------
1 file changed, 89 insertions(+), 18 deletions(-)
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index f1c22e3235b..53fb1e91ffb 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -2376,9 +2376,16 @@ static APR_INLINE char *find_char_in_curlies(char *s, int c)
* of an earlier expansion to include expansion specifiers that
* are interpreted by a later expansion, producing results that
* were not intended by the administrator.
+ *
+ * unsafe_qmark if not NULL will be set to 1 or 0 if a question mark
+ * is found respectively in a literal or in a lookup/expansion (whether
+ * it's the first or last qmark depends on [QSL]). Should be initialized
+ * to -1 and remains so if no qmark is found.
*/
-static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
+static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry,
+ int *unsafe_qmark)
{
+#define EXPAND_SPECIALS "\\$%"
result_list *result, *current;
result_list sresult[SMALL_EXPANSION];
unsigned spc = 0;
@@ -2386,8 +2393,29 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
char *p, *c;
apr_pool_t *pool = ctx->r->pool;
- span = strcspn(input, "\\$%");
inputlen = strlen(input);
+ if (!unsafe_qmark) {
+ span = strcspn(input, EXPAND_SPECIALS);
+ }
+ else {
+ span = strcspn(input, EXPAND_SPECIALS "?");
+ if (input[span] == '?') {
+ /* this qmark is not from an expansion thus safe */
+ *unsafe_qmark = 0;
+
+ /* keep tracking only if interested in the last qmark */
+ if (entry && (entry->flags & RULEFLAG_QSLAST)) {
+ do {
+ span++;
+ span += strcspn(input + span, EXPAND_SPECIALS "?");
+ } while (input[span] == '?');
+ }
+ else {
+ unsafe_qmark = NULL;
+ span += strcspn(input + span, EXPAND_SPECIALS);
+ }
+ }
+ }
/* fast exit */
if (inputlen == span) {
@@ -2405,6 +2433,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
/* loop for specials */
do {
+ int expanded = 0;
+
/* prepare next entry */
if (current->len) {
current->next = (spc < SMALL_EXPANSION)
@@ -2450,6 +2480,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
current->len = span;
current->string = p;
outlen += span;
+
+ expanded = 1;
p = endp + 1;
}
@@ -2489,19 +2521,18 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
}
/* reuse of key variable as result */
- key = lookup_map(ctx->r, map, do_expand(key, ctx, entry));
-
+ key = lookup_map(ctx->r, map, do_expand(key, ctx, entry, NULL));
if (!key && dflt && *dflt) {
- key = do_expand(dflt, ctx, entry);
+ key = do_expand(dflt, ctx, entry, NULL);
}
-
- if (key) {
+ if (key && *key) {
span = strlen(key);
current->len = span;
current->string = key;
outlen += span;
}
+ expanded = 1;
p = endp + 1;
}
}
@@ -2531,8 +2562,9 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
current->len = span;
current->string = bri->source + bri->regmatch[n].rm_so;
}
-
outlen += span;
+
+ expanded = 1;
}
p += 2;
@@ -2545,8 +2577,41 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
++outlen;
}
+ if (unsafe_qmark && expanded && current->len
+ && memchr(current->string, '?', current->len)) {
+ /* this qmark is from an expansion thus unsafe */
+ *unsafe_qmark = 1;
+
+ /* keep tracking only if interested in the last qmark */
+ if (!entry || !(entry->flags & RULEFLAG_QSLAST)) {
+ unsafe_qmark = NULL;
+ }
+ }
+
/* check the remainder */
- if (*p && (span = strcspn(p, "\\$%")) > 0) {
+ if (!unsafe_qmark) {
+ span = strcspn(p, EXPAND_SPECIALS);
+ }
+ else {
+ span = strcspn(p, EXPAND_SPECIALS "?");
+ if (p[span] == '?') {
+ /* this qmark is not from an expansion thus safe */
+ *unsafe_qmark = 0;
+
+ /* keep tracking only if interested in the last qmark */
+ if (entry && (entry->flags & RULEFLAG_QSLAST)) {
+ do {
+ span++;
+ span += strcspn(p + span, EXPAND_SPECIALS "?");
+ } while (p[span] == '?');
+ }
+ else {
+ unsafe_qmark = NULL;
+ span += strcspn(p + span, EXPAND_SPECIALS);
+ }
+ }
+ }
+ if (span > 0) {
if (current->len) {
current->next = (spc < SMALL_EXPANSION)
? &(sresult[spc++])
@@ -2591,7 +2656,7 @@ static void do_expand_env(data_item *env, rewrite_ctx *ctx)
char *name, *val;
while (env) {
- name = do_expand(env->data, ctx, NULL);
+ name = do_expand(env->data, ctx, NULL, NULL);
if (*name == '!') {
name++;
apr_table_unset(ctx->r->subprocess_env, name);
@@ -2725,7 +2790,7 @@ static void add_cookie(request_rec *r, char *s)
static void do_expand_cookie(data_item *cookie, rewrite_ctx *ctx)
{
while (cookie) {
- add_cookie(ctx->r, do_expand(cookie->data, ctx, NULL));
+ add_cookie(ctx->r, do_expand(cookie->data, ctx, NULL, NULL));
cookie = cookie->next;
}
@@ -4014,7 +4079,7 @@ static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx)
int basis;
if (p->ptype != CONDPAT_AP_EXPR)
- input = do_expand(p->input, ctx, NULL);
+ input = do_expand(p->input, ctx, NULL, NULL);
switch (p->ptype) {
case CONDPAT_FILE_EXISTS:
@@ -4178,7 +4243,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p,
char *expanded;
if (p->forced_mimetype) {
- expanded = do_expand(p->forced_mimetype, ctx, p);
+ expanded = do_expand(p->forced_mimetype, ctx, p, NULL);
if (*expanded) {
ap_str_tolower(expanded);
@@ -4192,7 +4257,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p,
}
if (p->forced_handler) {
- expanded = do_expand(p->forced_handler, ctx, p);
+ expanded = do_expand(p->forced_handler, ctx, p, NULL);
if (*expanded) {
ap_str_tolower(expanded);
@@ -4329,12 +4394,18 @@ static rule_return_type apply_rewrite_rule(rewriterule_entry *p,
/* expand the result */
if (!(p->flags & RULEFLAG_NOSUB)) {
- newuri = do_expand(p->output, ctx, p);
+ int unsafe_qmark = -1;
+
+ if (p->flags & RULEFLAG_UNSAFE_ALLOW3F) {
+ newuri = do_expand(p->output, ctx, p, NULL);
+ }
+ else {
+ newuri = do_expand(p->output, ctx, p, &unsafe_qmark);
+ }
rewritelog((r, 2, ctx->perdir, "rewrite '%s' -> '%s'", ctx->uri,
newuri));
- if (!(p->flags & RULEFLAG_UNSAFE_ALLOW3F) &&
- ap_strcasestr(r->unparsed_uri, "%3f") &&
- ap_strchr_c(newuri, '?')) {
+
+ if (unsafe_qmark > 0) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10508)
"Unsafe URL with %%3f URL rewritten without "
"UnsafeAllow3F");

@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEZbLUT+dL1ePeOsPwgngd5G1ZVPoFAmaVEjgACgkQgngd5G1Z
VPqlUA//dMZ01CalmRf4Li2gDH+ETlQXkMST+2IYNCWZzV78g5wfjpZtApKOk+6O
73WxdNSvnB15CJVIi/wXN/8ZQHu3u9kHCHw+ydDhOq7CiSAe1x5k0PcodR+me299
PErBiAaBct+oJOnPCRdw5c5g3jomZgg1Nt5xS5NmI83UnbT9KHd92nNFdIjp6nFE
mKzsQSWSSXkObj83inJ3HvT8ALGr5TpMjHSJAC/YP9B9FuTW4lQh0XFEESz6LcR/
Z8GWAV0qfauRhNYcp5qYcVdreVAk0J9vfnruv9OdYsMI/sDM2PYAyDk9pCMuVIfv
PuZd8n/EpMuQfeWBOLzkft2TjNYx0UAt0xLK0/FLQqbZSKgCxce3mnbm0N3qXl8h
OpWYC86h4y4shaBOCAHI4oqRFbIlbf9bssMRSYfBYTJ1k8zmADWAhIsr5276A33G
S8Z+Ah1XeYkvy1blSJDRqECAPLtAXgesLadpkTKTwu+9BmHXYllSmfdhW8D3v6SA
Ab7RMonp7poBexO0o0mm14cEAwetffUhSrFfvGp7sTBjQYH3s309HtRBuLJOwmP2
uZvAKo84nJVaZIe7TTjpA/om7sq08Jq8xdzGbEhfGnOrtg/34d3K5S9tDvBMkmDq
HfYjFxCmfTbUDy4nqVNZcwno6jApweon+KAHbG/vJ2uMWozn2Bo=
=Lelg
-----END PGP SIGNATURE-----

@ -1,2 +0,0 @@
g apache 48
u apache 48 "Apache" /usr/share/httpd /sbin/nologin

@ -17,4 +17,4 @@
Alias /.noindex.html /usr/share/httpd/noindex/index.html
Alias /poweredby.png /usr/share/httpd/icons/apache_pb3.png
Alias /system_noindex_logo.png /usr/share/httpd/icons/system_noindex_logo.png
Alias /test-page-background.png /usr/share/httpd/icons/test-page-background.png

@ -12,8 +12,8 @@
Summary: Apache HTTP Server
Name: httpd
Version: 2.4.62
Release: 1%{?dist}
Version: 2.4.57
Release: 8%{?dist}.inferit
URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
Source1: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2.asc
@ -62,11 +62,10 @@ Source45: config.layout
Source46: apachectl.sh
Source47: apachectl.xml
Source48: apache-poweredby.png
Source49: httpd.sysusers
# build/scripts patches
Patch2: httpd-2.4.43-apxs.patch
Patch3: httpd-2.4.59-deplibs.patch
Patch3: httpd-2.4.43-deplibs.patch
# Needed for socket activation and mod_systemd patch
Patch19: httpd-2.4.53-detect-systemd.patch
# Features/functional changes
@ -75,33 +74,60 @@ Patch22: httpd-2.4.43-mod_systemd.patch
Patch23: httpd-2.4.48-export.patch
Patch24: httpd-2.4.43-corelimit.patch
Patch25: httpd-2.4.57-selinux.patch
Patch26: httpd-2.4.53-icons.patch
Patch27: httpd-2.4.43-cachehardmax.patch
Patch28: httpd-2.4.62-socket-activation.patch
Patch29: httpd-2.4.43-sslciphdefault.patch
Patch30: httpd-2.4.43-sslprotdefault.patch
Patch31: httpd-2.4.43-logjournal.patch
Patch32: httpd-2.4.48-proxy-ws-idle-timeout.patch
Patch26: httpd-2.4.57-gettid.patch
Patch27: httpd-2.4.53-icons.patch
Patch30: httpd-2.4.43-cachehardmax.patch
Patch34: httpd-2.4.43-socket-activation.patch
Patch38: httpd-2.4.43-sslciphdefault.patch
Patch39: httpd-2.4.43-sslprotdefault.patch
Patch41: httpd-2.4.43-r1861793+.patch
Patch42: httpd-2.4.48-r1828172+.patch
Patch45: httpd-2.4.43-logjournal.patch
Patch46: httpd-2.4.48-proxy-ws-idle-timeout.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1949969
Patch47: httpd-2.4.57-pr37355.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1949606
Patch33: httpd-2.4.62-freebind.patch
Patch48: httpd-2.4.46-freebind.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1950021
Patch49: httpd-2.4.48-ssl-proxy-chains.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2004143
Patch50: httpd-2.4.57-r1825120.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2065677
Patch34: httpd-2.4.53-separate-systemd-fns.patch
Patch52: httpd-2.4.53-separate-systemd-fns.patch
# https://issues.redhat.com/browse/RHEL-5071
Patch35: httpd-2.4.57-r1912477+.patch
Patch53: httpd-2.4.57-r1912477+.patch
# https://issues.redhat.com/browse/RHEL-6600
Patch54: httpd-2.4.57-r1912081.patch
# Bug fixes
# https://bugzilla.redhat.com/show_bug.cgi?id=1397243
Patch100: httpd-2.4.43-enable-sslv3.patch
Patch60: httpd-2.4.43-enable-sslv3.patch
Patch61: httpd-2.4.46-htcacheclean-dont-break.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1932442
Patch101: httpd-2.4.48-full-release.patch
# https://bz.apache.org/bugzilla/show_bug.cgi?id=69197
Patch102: httpd-2.4.62-r1919325.patch
Patch64: httpd-2.4.48-full-release.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1950011
Patch65: httpd-2.4.51-r1877397.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1938740
Patch66: httpd-2.4.51-r1892413+.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2073459
Patch67: httpd-2.4.51-r1811831.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2098056
Patch68: httpd-2.4.53-r1878890.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2186645
Patch69: httpd-2.4.57-covscan.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2222001
Patch70: httpd-2.4.57-mod_status-duplicate-key.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2217726
Patch71: httpd-2.4.57-davenoent.patch
# https://issues.redhat.com/browse/RHEL-17686
Patch72: httpd-2.4.57-r1884505+.patch
# Security fixes
# https://bugzilla.redhat.com/show_bug.cgi?id=...
#
# https://bugzilla.redhat.com/show_bug.cgi?id=
# Patch200: httpd-2.4.X-CVE-XXXX-YYYYY.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2245332
Patch200: httpd-2.4.57-CVE-2023-31122.patch
License: ASL 2.0
@ -110,12 +136,13 @@ BuildRequires: perl-interpreter, perl-generators, systemd-devel
BuildRequires: zlib-devel, libselinux-devel, lua-devel, brotli-devel
BuildRequires: apr-devel >= 1.5.0, apr-util-devel >= 1.5.0, pcre-devel >= 5.0
BuildRequires: gnupg2
BuildRequires: systemd-rpm-macros
Requires: system-logos-httpd
Provides: webserver
Requires: httpd-core = 0:%{version}-%{release}
Recommends: mod_http2, mod_lua
%{?systemd_requires}
Requires(preun): systemd-units
Requires(postun): systemd-units
Requires(post): systemd-units
%description
The Apache HTTP Server is a powerful, efficient, and extensible
@ -165,7 +192,7 @@ also be found at https://httpd.apache.org/docs/2.4/.
%package filesystem
Summary: The basic directory layout for the Apache HTTP Server
BuildArch: noarch
%{?sysusers_requires_compat}
Requires(pre): /usr/sbin/useradd
%description filesystem
The httpd-filesystem package contains the basic directory layout
@ -244,20 +271,37 @@ written in the Lua programming language.
%patch23 -p1 -b .export
%patch24 -p1 -b .corelimit
%patch25 -p1 -b .selinux
%patch26 -p1 -b .icons
%patch27 -p1 -b .cachehardmax
%patch28 -p1 -b .socketactivation
%patch29 -p1 -b .sslciphdefault
%patch30 -p1 -b .sslprotdefault
%patch31 -p1 -b .logjournal
%patch32 -p1 -b .proxy-ws-idle-timeout
%patch33 -p1 -b .freebind
%patch34 -p1 -b .separatesystemd
%patch35 -p1 -b .r1912477+
%patch100 -p1 -b .enable-sslv3
%patch101 -p1 -b .full-release
%patch102 -p1 -b .r1919325
%patch26 -p1 -b .gettid
%patch27 -p1 -b .icons
%patch30 -p1 -b .cachehardmax
%patch34 -p1 -b .socketactivation
%patch38 -p1 -b .sslciphdefault
%patch39 -p1 -b .sslprotdefault
%patch41 -p1 -b .r1861793+
%patch42 -p1 -b .r1828172+
%patch45 -p1 -b .logjournal
%patch46 -p1 -b .proxy-ws-idle-timeout
%patch47 -p1 -b .pr37355
%patch48 -p1 -b .freebind
%patch49 -p1 -b .ssl-proxy-chains
%patch50 -p1 -b .r1825120
%patch52 -p1 -b .separatesystemd
%patch53 -p1 -b .r1912477+
%patch54 -p1 -b .r1912081
%patch60 -p1 -b .enable-sslv3
%patch61 -p1 -b .htcacheclean-dont-break
%patch64 -p1 -b .full-release
%patch65 -p1 -b .r1877397
%patch66 -p1 -b .r1892413+
%patch67 -p1 -b .r1811831
%patch68 -p1 -b .r1878890
%patch69 -p1 -b .covstan
%patch70 -p1 -b .duplicate-key
%patch71 -p1 -b .davenoent
%patch72 -p1 -b .r1884505+
%patch200 -p1 -b .CVE-2023-31122
# Patch in the vendor string
sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h
@ -478,6 +522,8 @@ mkdir $RPM_BUILD_ROOT%{contentdir}/noindex \
$RPM_BUILD_ROOT%{contentdir}/server-status
ln -s ../../testpage/index.html \
$RPM_BUILD_ROOT%{contentdir}/noindex/index.html
ln -s ../../pixmaps/test-page-background.png \
$RPM_BUILD_ROOT%{contentdir}/icons/test-page-background.png
install -m 644 -p docs/server-status/* \
$RPM_BUILD_ROOT%{contentdir}/server-status
rm -rf %{contentdir}/htdocs
@ -583,9 +629,6 @@ touch -r $RPM_BUILD_ROOT%{_bindir}/apxs \
$RPM_BUILD_ROOT%{_libdir}/httpd/build/vendor-apxs
chmod 755 $RPM_BUILD_ROOT%{_libdir}/httpd/build/vendor-apxs
# Fix content dir in sysusers file and install it
install -p -D -m 0644 %{SOURCE49} %{buildroot}%{_sysusersdir}/httpd.conf
# Remove unpackaged files
rm -vf \
$RPM_BUILD_ROOT%{_libdir}/*.exp \
@ -601,8 +644,11 @@ rm -vf \
rm -rf $RPM_BUILD_ROOT/etc/httpd/conf/{original,extra}
%pre filesystem
%sysusers_create_compat %{SOURCE49}
getent group apache >/dev/null || groupadd -g 48 -r apache
getent passwd apache >/dev/null || \
useradd -r -u 48 -g apache -s /sbin/nologin \
-d %{contentdir} -c "Apache" apache
exit 0
%post
%systemd_post httpd.service htcacheclean.service httpd.socket
@ -766,7 +812,6 @@ exit $rv
%dir %{contentdir}/icons
%attr(755,root,root) %dir %{_unitdir}/httpd.service.d
%attr(755,root,root) %dir %{_unitdir}/httpd.socket.d
%{_sysusersdir}/httpd.conf
%files tools
%{_bindir}/*
@ -819,38 +864,6 @@ exit $rv
%{_rpmconfigdir}/macros.d/macros.httpd
%changelog
* Sat Aug 03 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.62-1
- new version 2.4.62
- Resolves: RHEL-52724 - Regression introduced by CVE-2024-38474 fix
* Fri Jul 19 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.59-7
- Resolves: RHEL-49856: htcacheclean.service missing [Install] section
* Thu May 30 2024 Joe Orton <jorton@redhat.com> - 2.4.59-6
- mod_ssl: restore SSL_OP_NO_RENEGOTIATE support
Related: RHEL-14668
* Tue May 21 2024 Joe Orton <jorton@redhat.com> - 2.4.59-5
- mod_ssl: defer ENGINE_finish() calls to a cleanup
Resolves: RHEL-36755
* Mon May 20 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.59-4
- Resolves: RHEL-6575 - [RFE] httpd use systemd-sysusers
* Wed May 08 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.59-3
- Related: RHEL-14668 - RFE: httpd rebase to 2.4.59
* Wed May 8 2024 Joe Orton <jorton@redhat.com> - 2.4.59-2
- Resolves: RHEL-35870 - httpd mod_cgi/cgid unification
* Fri May 03 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.59-1
- new version 2.4.59
- Resolves: RHEL-14668 - RFE: httpd rebase to 2.4.59
- Resolves: RHEL-31856 - httpd: HTTP response splitting
(CVE-2023-38709)
- Resolves: RHEL-31859 - httpd: HTTP Response Splitting in multiple
modules (CVE-2024-24795)
* Wed Feb 7 2024 Joe Orton <jorton@redhat.com> - 2.4.57-8
- mod_xml2enc: fix media type handling
Resolves: RHEL-17686
@ -865,6 +878,10 @@ exit $rv
- Resolves: RHEL-5071 - mod_dav_fs: add DavLockDBType
- mod_dav_fs: add global mutex around lockdb interaction
* Wed Oct 4 2023 Sergey Cherevko <s.cherevko@msvsphere-os.ru> - 2.4.57-5.inferit
- Symlinking and creating alias for test-page-background.png
- Rebuilt for MSVSphere 9.3
* Thu Jul 20 2023 Tomas Korbar <tkorbar@redhat.com> - 2.4.57-5
- Fix issue found by covscan
- Related: #2222001
@ -879,6 +896,9 @@ exit $rv
- Resolves: #2186645 - Fix issue found by covscan in httpd package
- Resolves: #2173295 - Include Apache httpd module mod_authnz_fcgi
* Thu Apr 13 2023 MSVSphere Packaging Team <packager@msvsphere.ru> - 2.4.57-1
- Rebuilt for MSVSphere 9.2 beta
* Tue Apr 11 2023 Luboš Uhliarik <luhliari@redhat.com> - 2.4.57-1
- Resolves: #2184403 - rebase httpd to 2.4.57
- Resolves: #2177753 - CVE-2023-25690 httpd: HTTP request splitting with

Loading…
Cancel
Save