import httpd-2.4.62-1.el9

c9 imports/c9/httpd-2.4.62-1.el9
MSVSphere Packaging Team 1 month ago
parent 8f268ad56c
commit 2a06ec2d28
Signed by: sys_gitsync
GPG Key ID: B2B0B9F29E528FE8

2
.gitignore vendored

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

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

@ -7,5 +7,10 @@ Documentation=man:htcacheclean.service(8)
Type=forking Type=forking
User=apache User=apache
PIDFile=/run/httpd/htcacheclean/pid PIDFile=/run/httpd/htcacheclean/pid
Environment=LANG=C
EnvironmentFile=/etc/sysconfig/htcacheclean EnvironmentFile=/etc/sysconfig/htcacheclean
ExecStart=/usr/sbin/htcacheclean -P /run/httpd/htcacheclean/pid -d $INTERVAL -p $CACHE_ROOT -l $LIMIT $OPTIONS 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,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,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;
}
}
}

File diff suppressed because it is too large Load Diff

@ -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,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,11 +0,0 @@
--- 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) {

@ -1,172 +0,0 @@
diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c
index 596320d..046fc40 100644
--- a/modules/proxy/mod_proxy.c
+++ b/modules/proxy/mod_proxy.c
@@ -1227,6 +1227,7 @@ static int proxy_fixup(request_rec *r)
return OK; /* otherwise; we've done the best we can */
}
+
/* Send a redirection if the request contains a hostname which is not */
/* fully qualified, i.e. doesn't have a domain name appended. Some proxy */
/* servers like Netscape's allow this and access hosts from the local */
@@ -1280,7 +1281,7 @@ static int proxy_handler(request_rec *r)
ap_get_module_config(sconf, &proxy_module);
apr_array_header_t *proxies = conf->proxies;
struct proxy_remote *ents = (struct proxy_remote *) proxies->elts;
- int i, rc, access_status;
+ int rc = DECLINED, access_status, i;
int direct_connect = 0;
const char *str;
apr_int64_t maxfwd;
@@ -1295,19 +1296,28 @@ static int proxy_handler(request_rec *r)
return DECLINED;
}
- if (!r->proxyreq) {
- /* We may have forced the proxy handler via config or .htaccess */
- if (r->handler &&
- strncmp(r->handler, "proxy:", 6) == 0 &&
- strncmp(r->filename, "proxy:", 6) != 0) {
- r->proxyreq = PROXYREQ_REVERSE;
- r->filename = apr_pstrcat(r->pool, r->handler, r->filename, NULL);
+ /* We may have forced the proxy handler via config or .htaccess */
+ if (!r->proxyreq && r->handler && strncmp(r->handler, "proxy:", 6) == 0) {
+ char *old_filename = r->filename;
+
+ r->proxyreq = PROXYREQ_REVERSE;
+ r->filename = apr_pstrcat(r->pool, r->handler, r->filename, NULL);
+
+ /* Still need to fixup/canonicalize r->filename */
+ rc = ap_proxy_fixup_uds_filename(r);
+ if (rc <= OK) {
+ rc = proxy_fixup(r);
}
- else {
- return DECLINED;
+ if (rc != OK) {
+ r->filename = old_filename;
+ r->proxyreq = 0;
}
- } else if (strncmp(r->filename, "proxy:", 6) != 0) {
- return DECLINED;
+ }
+ else if (r->proxyreq && strncmp(r->filename, "proxy:", 6) == 0) {
+ rc = OK;
+ }
+ if (rc != OK) {
+ return rc;
}
/* handle max-forwards / OPTIONS / TRACE */
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
index eaf431d..523304d 100644
--- a/modules/proxy/mod_proxy.h
+++ b/modules/proxy/mod_proxy.h
@@ -994,6 +994,14 @@ PROXY_DECLARE(proxy_balancer_shared *) ap_proxy_find_balancershm(ap_slotmem_prov
proxy_balancer *balancer,
unsigned int *index);
+/*
+ * Strip the UDS part of r->filename if any, and put the UDS path in
+ * r->notes ("uds_path")
+ * @param r current request
+ * @return OK if fixed up, DECLINED if not UDS, or an HTTP_XXX error
+ */
+PROXY_DECLARE(int) ap_proxy_fixup_uds_filename(request_rec *r);
+
/**
* Get the most suitable worker and/or balancer for the request
* @param worker worker used for processing request
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index fce4f1b..eba541b 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -2315,7 +2315,7 @@ static int ap_proxy_retry_worker(const char *proxy_function, proxy_worker *worke
* were passed a UDS url (eg: from mod_proxy) and adjust uds_path
* as required.
*/
-static int fix_uds_filename(request_rec *r, char **url)
+PROXY_DECLARE(int) ap_proxy_fixup_uds_filename(request_rec *r)
{
char *uds_url = r->filename + 6, *origin_url;
@@ -2323,7 +2323,6 @@ static int fix_uds_filename(request_rec *r, char **url)
!ap_cstr_casecmpn(uds_url, "unix:", 5) &&
(origin_url = ap_strchr(uds_url + 5, '|'))) {
char *uds_path = NULL;
- apr_size_t url_len;
apr_uri_t urisock;
apr_status_t rv;
@@ -2338,20 +2337,20 @@ static int fix_uds_filename(request_rec *r, char **url)
if (!uds_path) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10292)
"Invalid proxy UDS filename (%s)", r->filename);
- return 0;
+ return HTTP_BAD_REQUEST;
}
apr_table_setn(r->notes, "uds_path", uds_path);
- /* Remove the UDS path from *url and r->filename */
- url_len = strlen(origin_url);
- *url = apr_pstrmemdup(r->pool, origin_url, url_len);
- memcpy(uds_url, *url, url_len + 1);
-
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
- "*: rewrite of url due to UDS(%s): %s (%s)",
- uds_path, *url, r->filename);
+ "*: fixup UDS from %s: %s (%s)",
+ r->filename, origin_url, uds_path);
+
+ /* Overwrite the UDS part in place */
+ memmove(uds_url, origin_url, strlen(origin_url) + 1);
+ return OK;
}
- return 1;
+
+ return DECLINED;
}
PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
@@ -2370,9 +2369,6 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
ap_log_rerror(APLOG_MARK, APLOG_TRACE2, 0, r,
"%s: found worker %s for %s",
(*worker)->s->scheme, (*worker)->s->name_ex, *url);
- if (!forward && !fix_uds_filename(r, url)) {
- return HTTP_INTERNAL_SERVER_ERROR;
- }
access_status = OK;
}
else if (forward) {
@@ -2402,9 +2398,6 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
* regarding the Connection header in the request.
*/
apr_table_setn(r->subprocess_env, "proxy-nokeepalive", "1");
- if (!fix_uds_filename(r, url)) {
- return HTTP_INTERNAL_SERVER_ERROR;
- }
}
}
}
@@ -2414,6 +2407,20 @@ PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker,
"all workers are busy. Unable to serve %s", *url);
access_status = HTTP_SERVICE_UNAVAILABLE;
}
+
+ if (access_status == OK && r->proxyreq == PROXYREQ_REVERSE) {
+ int rc = ap_proxy_fixup_uds_filename(r);
+ if (ap_is_HTTP_ERROR(rc)) {
+ return rc;
+ }
+ /* If the URL has changed in r->filename, take everything after
+ * the "proxy:" prefix.
+ */
+ if (rc == OK) {
+ *url = apr_pstrdup(r->pool, r->filename + 6);
+ }
+ }
+
return access_status;
}

@ -1,439 +0,0 @@
diff --git a/docs/manual/mod/mod_rewrite.html.en b/docs/manual/mod/mod_rewrite.html.en
index 30d7434..c4be044 100644
--- a/docs/manual/mod/mod_rewrite.html.en
+++ b/docs/manual/mod/mod_rewrite.html.en
@@ -1446,6 +1446,16 @@ cannot use <code>$N</code> in the substitution string!
<td>Force the <a class="glossarylink" href="../glossary.html#mime-type" title="see glossary">MIME-type</a> of the target file
to be the specified type. <em><a href="../rewrite/flags.html#flag_t">details ...</a></em></td>
</tr>
+<tr>
+ <td>UnsafeAllow3F</td>
+ <td>Allows substitutions from URL's that may be unsafe.
+ <em><a href="../rewrite/flags.html#flag_unsafe_allow_3f">details ...</a></em></td>
+ </tr>
+<tr>
+ <td>UnsafePrefixStat</td>
+ <td>Allows potentially unsafe substitutions from a leading variable or backreference to a filesystem path.
+ <em><a href="../rewrite/flags.html#flag_unsafe_prefix_stat">details ...</a></em></td>
+ </tr>
</table>
<div class="note"><h3>Home directory expansion</h3>
diff --git a/docs/manual/rewrite/flags.html.en b/docs/manual/rewrite/flags.html.en
index 5e175f1..a43aa82 100644
--- a/docs/manual/rewrite/flags.html.en
+++ b/docs/manual/rewrite/flags.html.en
@@ -811,6 +811,30 @@ re-processing (including subsequent rounds of mod_rewrite processing).
The <code>L</code> flag can be useful in this context to end the
<em>current</em> round of mod_rewrite processing.</p>
+</div>
+
+<div class="section">
+<h2><a name="flag_unsafe_allow_3f" id="flag_unsafe_allow_3f">UnsafeAllow3F</a></h2>
+
+<p>
+Setting this flag is required to allow a rewrite to continue If the
+HTTP request being written has an encoded question mark, '%3f', and the
+rewritten result has a '?' in the substiution. This protects from a malicious
+URL taking advantage of a capture and re-substitution of the encoded
+question mark.</p>
+
+</div>
+<div class="section">
+<h2><a name="flag_unsafe_prefix_status" id="flag_unsafe_prefix_status">UnsafePrefixStat</a></h2>
+
+<p>
+Setting this flag is required in server-scoped substitutions
+start with a variable or backreference and resolve to a filesystem path.
+These substitutions are not prefixed with the document root.
+This protects from a malicious URL causing the expanded substitution to
+map to an unexpected filesystem location.
+</p>
+
</div></div>
<div class="bottomlang">
<p><span>Available Languages: </span><a href="../en/rewrite/flags.html" title="English">&nbsp;en&nbsp;</a> |
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 0df25ee..e3f7510 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -177,6 +177,8 @@ static const char* really_last_key = "rewrite_really_last";
#define RULEFLAG_QSLAST (1<<19)
#define RULEFLAG_QSNONE (1<<20) /* programattic only */
#define RULEFLAG_ESCAPECTLS (1<<21)
+#define RULEFLAG_UNSAFE_PREFIX_STAT (1<<22)
+#define RULEFLAG_UNSAFE_ALLOW3F (1<<23)
/* return code of the rewrite rule
* the result may be escaped - or not
@@ -184,7 +186,7 @@ static const char* really_last_key = "rewrite_really_last";
#define ACTION_NORMAL (1<<0)
#define ACTION_NOESCAPE (1<<1)
#define ACTION_STATUS (1<<2)
-
+#define ACTION_STATUS_SET (1<<3)
#define MAPTYPE_TXT (1<<0)
#define MAPTYPE_DBM (1<<1)
@@ -208,6 +210,7 @@ static const char* really_last_key = "rewrite_really_last";
#define OPTION_IGNORE_INHERIT (1<<8)
#define OPTION_IGNORE_CONTEXT_INFO (1<<9)
#define OPTION_LEGACY_PREFIX_DOCROOT (1<<10)
+#define OPTION_UNSAFE_PREFIX_STAT (1<<12)
#ifndef RAND_MAX
#define RAND_MAX 32767
@@ -301,6 +304,14 @@ typedef enum {
CONDPAT_AP_EXPR
} pattern_type;
+typedef enum {
+ RULE_RC_NOMATCH = 0, /* the rule didn't match */
+ RULE_RC_MATCH = 1, /* a matching rule w/ substitution */
+ RULE_RC_NOSUB = 2, /* a matching rule w/ no substitution */
+ RULE_RC_STATUS_SET = 3 /* a matching rule that has set an HTTP error
+ to be returned in r->status */
+} rule_return_type;
+
typedef struct {
char *input; /* Input string of RewriteCond */
char *pattern; /* the RegExp pattern string */
@@ -927,10 +938,15 @@ static void fully_qualify_uri(request_rec *r)
return;
}
+static int startsWith(request_rec *r, const char *haystack, const char *needle) {
+ int rc = (ap_strstr_c(haystack, needle) == haystack);
+ rewritelog((r, 5, NULL, "prefix_stat startsWith(%s, %s) %d", haystack, needle, rc));
+ return rc;
+}
/*
- * stat() only the first segment of a path
+ * stat() only the first segment of a path, and only if it matches the output of the last matching rule
*/
-static int prefix_stat(const char *path, apr_pool_t *pool)
+static int prefix_stat(request_rec *r, const char *path, apr_pool_t *pool, rewriterule_entry *lastsub)
{
const char *curpath = path;
const char *root;
@@ -964,10 +980,36 @@ static int prefix_stat(const char *path, apr_pool_t *pool)
apr_finfo_t sb;
if (apr_stat(&sb, statpath, APR_FINFO_MIN, pool) == APR_SUCCESS) {
- return 1;
+ if (!lastsub) {
+ rewritelog((r, 3, NULL, "prefix_stat no lastsub subst prefix %s", statpath));
+ return 1;
+ }
+
+ rewritelog((r, 3, NULL, "prefix_stat compare statpath %s and lastsub output %s STATOK %d ",
+ statpath, lastsub->output, lastsub->flags & RULEFLAG_UNSAFE_PREFIX_STAT));
+ if (lastsub->flags & RULEFLAG_UNSAFE_PREFIX_STAT) {
+ return 1;
+ }
+ else {
+ const char *docroot = ap_document_root(r);
+ const char *context_docroot = ap_context_document_root(r);
+ /*
+ * As an example, path (r->filename) is /var/foo/bar/baz.html
+ * even if the flag is not set, we can accept a rule that
+ * began with a literal /var (stapath), or if the entire path
+ * starts with the docroot or context document root
+ */
+ if (startsWith(r, lastsub->output, statpath) ||
+ startsWith(r, path, docroot) ||
+ ((docroot != context_docroot) &&
+ startsWith(r, path, context_docroot))) {
+ return 1;
+ }
+ }
}
}
+ /* prefix will be added */
return 0;
}
@@ -3072,6 +3114,9 @@ static const char *cmd_rewriteoptions(cmd_parms *cmd,
else if (!strcasecmp(w, "legacyprefixdocroot")) {
options |= OPTION_LEGACY_PREFIX_DOCROOT;
}
+ else if (!strcasecmp(w, "UnsafePrefixStat")) {
+ options |= OPTION_UNSAFE_PREFIX_STAT;
+ }
else {
return apr_pstrcat(cmd->pool, "RewriteOptions: unknown option '",
w, "'", NULL);
@@ -3780,6 +3825,18 @@ static const char *cmd_rewriterule_setflag(apr_pool_t *p, void *_cfg,
++error;
}
break;
+ case 'u':
+ case 'U':
+ if (!strcasecmp(key, "nsafePrefixStat")){
+ cfg->flags |= (RULEFLAG_UNSAFE_PREFIX_STAT);
+ }
+ else if(!strcasecmp(key, "nsafeAllow3F")) {
+ cfg->flags |= RULEFLAG_UNSAFE_ALLOW3F;
+ }
+ else {
+ ++error;
+ }
+ break;
default:
++error;
break;
@@ -4130,7 +4187,8 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p,
/*
* Apply a single RewriteRule
*/
-static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
+static rule_return_type apply_rewrite_rule(rewriterule_entry *p,
+ rewrite_ctx *ctx)
{
ap_regmatch_t regmatch[AP_MAX_REG_MATCH];
apr_array_header_t *rewriteconds;
@@ -4181,7 +4239,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
rc = !ap_regexec(p->regexp, ctx->uri, AP_MAX_REG_MATCH, regmatch, 0);
if (! (( rc && !(p->flags & RULEFLAG_NOTMATCH)) ||
(!rc && (p->flags & RULEFLAG_NOTMATCH)) ) ) {
- return 0;
+ return RULE_RC_NOMATCH;
}
/* It matched, wow! Now it's time to prepare the context structure for
@@ -4232,7 +4290,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
}
}
else if (!rc) {
- return 0;
+ return RULE_RC_NOMATCH;
}
/* If some HTTP header was involved in the condition, remember it
@@ -4252,6 +4310,15 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
newuri = do_expand(p->output, ctx, p);
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, '?')) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO()
+ "Unsafe URL with %%3f URL rewritten without "
+ "UnsafeAllow3F");
+ r->status = HTTP_FORBIDDEN;
+ return RULE_RC_STATUS_SET;
+ }
}
/* expand [E=var:val] and [CO=<cookie>] */
@@ -4269,7 +4336,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
r->status = p->forced_responsecode;
}
- return 2;
+ return RULE_RC_NOSUB;
}
/* Add the previously stripped per-directory location prefix, unless
@@ -4335,7 +4402,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
r->filename));
r->filename = apr_pstrcat(r->pool, "proxy:", r->filename, NULL);
- return 1;
+ return RULE_RC_MATCH;
}
/* If this rule is explicitly forced for HTTP redirection
@@ -4350,7 +4417,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
r->filename));
r->status = p->forced_responsecode;
- return 1;
+ return RULE_RC_MATCH;
}
/* Special Rewriting Feature: Self-Reduction
@@ -4372,7 +4439,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
"with %s", p->forced_responsecode, r->filename));
r->status = p->forced_responsecode;
- return 1;
+ return RULE_RC_MATCH;
}
/* Finally remember the forced mime-type */
@@ -4381,7 +4448,7 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
/* Puuhhhhhhhh... WHAT COMPLICATED STUFF ;_)
* But now we're done for this particular rule.
*/
- return 1;
+ return RULE_RC_MATCH;
}
/*
@@ -4389,13 +4456,13 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
* i.e. a list of rewrite rules
*/
static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules,
- char *perdir)
+ char *perdir, rewriterule_entry **lastsub)
{
rewriterule_entry *entries;
rewriterule_entry *p;
int i;
int changed;
- int rc;
+ rule_return_type rc;
int s;
rewrite_ctx *ctx;
int round = 1;
@@ -4403,6 +4470,7 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules,
ctx = apr_palloc(r->pool, sizeof(*ctx));
ctx->perdir = perdir;
ctx->r = r;
+ *lastsub = NULL;
/*
* Iterate over all existing rules
@@ -4430,7 +4498,12 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules,
ctx->vary = NULL;
rc = apply_rewrite_rule(p, ctx);
- if (rc) {
+ if (rc != RULE_RC_NOMATCH) {
+
+ if (!(p->flags & RULEFLAG_NOSUB)) {
+ rewritelog((r, 2, perdir, "setting lastsub to rule with output %s", p->output));
+ *lastsub = p;
+ }
/* Catch looping rules with pathinfo growing unbounded */
if ( strlen( r->filename ) > 2*r->server->limit_req_line ) {
@@ -4450,6 +4523,12 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules,
apr_table_merge(r->headers_out, "Vary", ctx->vary);
}
+
+ /* Error while evaluating rule, r->status set */
+ if (RULE_RC_STATUS_SET == rc) {
+ return ACTION_STATUS_SET;
+ }
+
/*
* The rule sets the response code (implies match-only)
*/
@@ -4460,7 +4539,7 @@ static int apply_rewrite_list(request_rec *r, apr_array_header_t *rewriterules,
/*
* Indicate a change if this was not a match-only rule.
*/
- if (rc != 2) {
+ if (rc != RULE_RC_NOSUB) {
changed = ((p->flags & RULEFLAG_NOESCAPE)
? ACTION_NOESCAPE : ACTION_NORMAL);
}
@@ -4649,6 +4728,7 @@ static int hook_uri2file(request_rec *r)
int rulestatus;
void *skipdata;
const char *oargs;
+ rewriterule_entry *lastsub = NULL;
/*
* retrieve the config structures
@@ -4760,7 +4840,7 @@ static int hook_uri2file(request_rec *r)
/*
* now apply the rules ...
*/
- rulestatus = apply_rewrite_list(r, conf->rewriterules, NULL);
+ rulestatus = apply_rewrite_list(r, conf->rewriterules, NULL, &lastsub);
apr_table_setn(r->notes, "mod_rewrite_rewritten",
apr_psprintf(r->pool,"%d",rulestatus));
}
@@ -4798,6 +4878,9 @@ static int hook_uri2file(request_rec *r)
r->status = HTTP_OK;
return n;
}
+ else if (ACTION_STATUS_SET == rulestatus) {
+ return r->status;
+ }
if (to_proxyreq) {
/* it should be go on as an internal proxy request */
@@ -4917,23 +5000,29 @@ static int hook_uri2file(request_rec *r)
return HTTP_BAD_REQUEST;
}
- /* if there is no valid prefix, we call
- * the translator from the core and
- * prefix the filename with document_root
+ /* We have r->filename as a path in a server-context rewrite without
+ * the PT flag. The historical behavior is to treat it as a verbatim
+ * filesystem path iff the first component of the path exists and is
+ * readable by httpd. Otherwise, it is interpreted as DocumentRoot
+ * relative.
*
* NOTICE:
* We cannot leave out the prefix_stat because
- * - when we always prefix with document_root
- * then no absolute path can be created, e.g. via
- * emulating a ScriptAlias directive, etc.
- * - when we always NOT prefix with document_root
+ * - If we always prefix with document_root
+ * then no absolute path can could ever be used in
+ * a substitution. e.g. emulating an Alias.
+ * - If we never prefix with document_root
* then the files under document_root have to
* be references directly and document_root
* gets never used and will be a dummy parameter -
- * this is also bad
+ * this is also bad.
+ * - Later addition: This part is questionable.
+ * If we had never prefixed, users would just
+ * need %{DOCUMENT_ROOT} in substitutions or the
+ * [PT] flag.
*
* BUT:
- * Under real Unix systems this is no problem,
+ * Under real Unix systems this is no perf problem,
* because we only do stat() on the first directory
* and this gets cached by the kernel for along time!
*/
@@ -4942,7 +5031,9 @@ static int hook_uri2file(request_rec *r)
uri_reduced = apr_table_get(r->notes, "mod_rewrite_uri_reduced");
}
- if (!prefix_stat(r->filename, r->pool) || uri_reduced != NULL) {
+ if (!prefix_stat(r, r->filename, r->pool,
+ conf->options & OPTION_UNSAFE_PREFIX_STAT ? NULL : lastsub)
+ || uri_reduced != NULL) {
int res;
char *tmp = r->uri;
@@ -4987,6 +5078,7 @@ static int hook_fixup(request_rec *r)
char *ofilename, *oargs;
int is_proxyreq;
void *skipdata;
+ rewriterule_entry *lastsub;
dconf = (rewrite_perdir_conf *)ap_get_module_config(r->per_dir_config,
&rewrite_module);
@@ -5071,7 +5163,7 @@ static int hook_fixup(request_rec *r)
/*
* now apply the rules ...
*/
- rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory);
+ rulestatus = apply_rewrite_list(r, dconf->rewriterules, dconf->directory, &lastsub);
if (rulestatus) {
unsigned skip_absolute = is_absolute_uri(r->filename, NULL);
int to_proxyreq = 0;
@@ -5100,6 +5192,9 @@ static int hook_fixup(request_rec *r)
r->status = HTTP_OK;
return n;
}
+ else if (ACTION_STATUS_SET == rulestatus) {
+ return r->status;
+ }
if (to_proxyreq) {
/* it should go on as an internal proxy request */

@ -1,303 +0,0 @@
From 554554b0ebb14d6578adb70a389c57a0d5f18a3b Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 24 Jun 2024 17:54:34 +0000
Subject: [PATCH] Merge r1918551 from trunk:
add ap_set_content_type_ex to differentiate
trusted sources
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1918560 13f79535-47bb-0310-9956-ffa450edef68
---
include/http_protocol.h | 11 +++++++++++
include/httpd.h | 7 +++++++
modules/http/http_protocol.c | 6 ++++++
modules/http/mod_mime.c | 20 ++++++++++----------
modules/mappers/mod_actions.c | 6 ++++--
modules/mappers/mod_negotiation.c | 8 ++++----
modules/mappers/mod_rewrite.c | 2 +-
modules/metadata/mod_headers.c | 6 +++---
modules/metadata/mod_mime_magic.c | 4 ++--
server/config.c | 2 +-
server/core.c | 2 +-
11 files changed, 50 insertions(+), 24 deletions(-)
diff --git a/include/http_protocol.h b/include/http_protocol.h
index 94c481e5f43..f2c99c9e86e 100644
--- a/include/http_protocol.h
+++ b/include/http_protocol.h
@@ -438,6 +438,17 @@ AP_DECLARE(void) ap_clear_method_list(ap_method_list_t *l);
*/
AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct);
+/**
+ * Set the content type for this request (r->content_type).
+ * @param r The current request
+ * @param ct The new content type
+ * @param trusted If non-zero, The content-type should come from a
+ * trusted source such as server configuration rather
+ * than application output.
+ * for the AddOutputFilterByType directive to work correctly.
+ */
+AP_DECLARE(void) ap_set_content_type_ex(request_rec *r, const char *ct, int trusted);
+
/**
* Set the Accept-Ranges header for this response
* @param r The current request
diff --git a/include/httpd.h b/include/httpd.h
index 826c46ef591..766df2bde00 100644
--- a/include/httpd.h
+++ b/include/httpd.h
@@ -667,6 +667,7 @@ typedef apr_uint64_t ap_request_bnotes_t;
*
*/
#define AP_REQUEST_STRONG_ETAG 1 >> 0
+#define AP_REQUEST_TRUSTED_CT 1 << 1
/**
* This is a convenience macro to ease with getting specific request
@@ -689,6 +690,12 @@ typedef apr_uint64_t ap_request_bnotes_t;
AP_REQUEST_GET_BNOTE((r), AP_REQUEST_STRONG_ETAG)
/** @} */
+/**
+ * Returns true if the content-type field is from a trusted source
+ */
+#define AP_REQUEST_IS_TRUSTED_CT(r) \
+ (!!AP_REQUEST_GET_BNOTE((r), AP_REQUEST_TRUSTED_CT))
+/** @} */
/**
* @defgroup module_magic Module Magic mime types
diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c
index d031f245188..c31e8737337 100644
--- a/modules/http/http_protocol.c
+++ b/modules/http/http_protocol.c
@@ -1097,8 +1097,14 @@ AP_DECLARE(void) ap_set_content_type(request_rec *r, const char *ct)
}
else if (!r->content_type || strcmp(r->content_type, ct)) {
r->content_type = ct;
+ AP_REQUEST_SET_BNOTE(r, AP_REQUEST_TRUSTED_CT, 0);
}
}
+AP_DECLARE(void) ap_set_content_type_ex(request_rec *r, const char *ct, int trusted)
+{
+ ap_set_content_type(r, ct);
+ AP_REQUEST_SET_BNOTE(r, AP_REQUEST_TRUSTED_CT, trusted ? AP_REQUEST_TRUSTED_CT : 0);
+}
AP_DECLARE(void) ap_set_accept_ranges(request_rec *r)
{
diff --git a/modules/http/mod_mime.c b/modules/http/mod_mime.c
index 700f824f32a..51095a0e74c 100644
--- a/modules/http/mod_mime.c
+++ b/modules/http/mod_mime.c
@@ -759,7 +759,7 @@ static int find_ct(request_rec *r)
int found_metadata = 0;
if (r->finfo.filetype == APR_DIR) {
- ap_set_content_type(r, DIR_MAGIC_TYPE);
+ ap_set_content_type_ex(r, DIR_MAGIC_TYPE, 1);
return OK;
}
@@ -850,7 +850,7 @@ static int find_ct(request_rec *r)
if (exinfo == NULL || !exinfo->forced_type) {
if ((type = apr_hash_get(mime_type_extensions, ext,
APR_HASH_KEY_STRING)) != NULL) {
- ap_set_content_type(r, (char*) type);
+ ap_set_content_type_ex(r, (char*) type, 1);
found = 1;
}
}
@@ -859,7 +859,7 @@ static int find_ct(request_rec *r)
/* empty string is treated as special case for RemoveType */
if (exinfo->forced_type && *exinfo->forced_type) {
- ap_set_content_type(r, exinfo->forced_type);
+ ap_set_content_type_ex(r, exinfo->forced_type, 1);
found = 1;
}
@@ -964,33 +964,33 @@ static int find_ct(request_rec *r)
memcpy(tmp, ctp->subtype, ctp->subtype_len);
tmp += ctp->subtype_len;
*tmp = 0;
- ap_set_content_type(r, base_content_type);
+ ap_set_content_type_ex(r, base_content_type, AP_REQUEST_IS_TRUSTED_CT(r));
while (pp != NULL) {
if (charset && !strcmp(pp->attr, "charset")) {
if (!override) {
- ap_set_content_type(r,
+ ap_set_content_type_ex(r,
apr_pstrcat(r->pool,
r->content_type,
"; charset=",
charset,
- NULL));
+ NULL), AP_REQUEST_IS_TRUSTED_CT(r));
override = 1;
}
}
else {
- ap_set_content_type(r,
+ ap_set_content_type_ex(r,
apr_pstrcat(r->pool,
r->content_type,
"; ", pp->attr,
"=", pp->val,
- NULL));
+ NULL), AP_REQUEST_IS_TRUSTED_CT(r));
}
pp = pp->next;
}
if (charset && !override) {
- ap_set_content_type(r, apr_pstrcat(r->pool, r->content_type,
+ ap_set_content_type_ex(r, apr_pstrcat(r->pool, r->content_type,
"; charset=", charset,
- NULL));
+ NULL), AP_REQUEST_IS_TRUSTED_CT(r));
}
}
}
diff --git a/modules/mappers/mod_actions.c b/modules/mappers/mod_actions.c
index ac9c3b7428f..5e398b53d9e 100644
--- a/modules/mappers/mod_actions.c
+++ b/modules/mappers/mod_actions.c
@@ -182,8 +182,10 @@ static int action_handler(request_rec *r)
return DECLINED;
/* Second, check for actions (which override the method scripts) */
- action = r->handler ? r->handler :
- ap_field_noparam(r->pool, r->content_type);
+ action = r->handler;
+ if (!action && AP_REQUEST_IS_TRUSTED_CT(r)) {
+ action = ap_field_noparam(r->pool, r->content_type);
+ }
if (action && (t = apr_table_get(conf->action_types, action))) {
int virtual = (*t++ == '0' ? 0 : 1);
diff --git a/modules/mappers/mod_negotiation.c b/modules/mappers/mod_negotiation.c
index c056b284550..a528f814397 100644
--- a/modules/mappers/mod_negotiation.c
+++ b/modules/mappers/mod_negotiation.c
@@ -1167,7 +1167,7 @@ static int read_types_multi(negotiation_state *neg)
* might be doing.
*/
if (sub_req->handler && !sub_req->content_type) {
- ap_set_content_type(sub_req, CGI_MAGIC_TYPE);
+ ap_set_content_type_ex(sub_req, CGI_MAGIC_TYPE, 1);
}
/*
@@ -3003,14 +3003,14 @@ static int handle_map_file(request_rec *r)
/* set MIME type and charset as negotiated */
if (best->mime_type && *best->mime_type) {
if (best->content_charset && *best->content_charset) {
- ap_set_content_type(r, apr_pstrcat(r->pool,
+ ap_set_content_type_ex(r, apr_pstrcat(r->pool,
best->mime_type,
"; charset=",
best->content_charset,
- NULL));
+ NULL), 1);
}
else {
- ap_set_content_type(r, apr_pstrdup(r->pool, best->mime_type));
+ ap_set_content_type_ex(r, apr_pstrdup(r->pool, best->mime_type), 1);
}
}
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index bbcc11b3c52..df6f16b83f0 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -5333,7 +5333,7 @@ static int hook_mimetype(request_rec *r)
rewritelog((r, 1, NULL, "force filename %s to have MIME-type '%s'",
r->filename, t));
- ap_set_content_type(r, t);
+ ap_set_content_type_ex(r, t, 1);
}
/* handler */
diff --git a/modules/metadata/mod_headers.c b/modules/metadata/mod_headers.c
index ef812cd3edc..4838bd6cd0d 100644
--- a/modules/metadata/mod_headers.c
+++ b/modules/metadata/mod_headers.c
@@ -783,14 +783,14 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers,
break;
case hdr_set:
if (!ap_cstr_casecmp(hdr->header, "Content-Type")) {
- ap_set_content_type(r, process_tags(hdr, r));
+ ap_set_content_type_ex(r, process_tags(hdr, r), 1);
}
apr_table_setn(headers, hdr->header, process_tags(hdr, r));
break;
case hdr_setifempty:
if (NULL == apr_table_get(headers, hdr->header)) {
if (!ap_cstr_casecmp(hdr->header, "Content-Type")) {
- ap_set_content_type(r, process_tags(hdr, r));
+ ap_set_content_type_ex(r, process_tags(hdr, r), 1);
}
apr_table_setn(headers, hdr->header, process_tags(hdr, r));
}
@@ -809,7 +809,7 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers,
const char *repl = process_regexp(hdr, r->content_type, r);
if (repl == NULL)
return 0;
- ap_set_content_type(r, repl);
+ ap_set_content_type_ex(r, repl, 1);
}
if (apr_table_get(headers, hdr->header)) {
edit_do ed;
diff --git a/modules/metadata/mod_mime_magic.c b/modules/metadata/mod_mime_magic.c
index 7dac4fdbd3d..1c96db4cd7a 100644
--- a/modules/metadata/mod_mime_magic.c
+++ b/modules/metadata/mod_mime_magic.c
@@ -788,7 +788,7 @@ static int magic_rsl_to_request(request_rec *r)
/* XXX: this could be done at config time I'm sure... but I'm
* confused by all this magic_rsl stuff. -djg */
ap_content_type_tolower(tmp);
- ap_set_content_type(r, tmp);
+ ap_set_content_type_ex(r, tmp, 1);
if (state == rsl_encoding) {
tmp = rsl_strdup(r, encoding_frag,
@@ -2326,7 +2326,7 @@ static int revision_suffix(request_rec *r)
/* extract content type/encoding/language from sub-request */
if (sub->content_type) {
- ap_set_content_type(r, apr_pstrdup(r->pool, sub->content_type));
+ ap_set_content_type_ex(r, apr_pstrdup(r->pool, sub->content_type), 1);
#if MIME_MAGIC_DEBUG
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01557)
MODNAME ": subrequest %s got %s",
diff --git a/server/config.c b/server/config.c
index 3d11ff58a44..635b65def1d 100644
--- a/server/config.c
+++ b/server/config.c
@@ -418,7 +418,7 @@ AP_CORE_DECLARE(int) ap_invoke_handler(request_rec *r)
}
if (!r->handler) {
- if (r->content_type) {
+ if (r->content_type && AP_REQUEST_IS_TRUSTED_CT(r)) {
handler = r->content_type;
if ((p=ap_strchr_c(handler, ';')) != NULL) {
char *new_handler = (char *)apr_pmemdup(r->pool, handler,
diff --git a/server/core.c b/server/core.c
index f511bba4897..843b97320f8 100644
--- a/server/core.c
+++ b/server/core.c
@@ -4835,7 +4835,7 @@ static int core_override_type(request_rec *r)
/* Check for overrides with ForceType / SetHandler
*/
if (conf->mime_type && strcmp(conf->mime_type, "none"))
- ap_set_content_type(r, (char*) conf->mime_type);
+ ap_set_content_type_ex(r, (char*) conf->mime_type, 1);
if (conf->expr_handler) {
const char *err;

@ -1,43 +0,0 @@
From 1d98d4db186e708f059336fb9342d0adb6925e85 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Tue, 25 Jun 2024 17:29:32 +0000
Subject: [PATCH] Merge r1918606 from trunk:
validate hostname
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1918607 13f79535-47bb-0310-9956-ffa450edef68
---
modules/proxy/proxy_util.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
index ea36465..fce4f1b 100644
--- a/modules/proxy/proxy_util.c
+++ b/modules/proxy/proxy_util.c
@@ -2619,6 +2619,13 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
apr_pstrcat(p,"URI cannot be parsed: ", *url,
NULL));
}
+
+ if (!uri->hostname) {
+ return ap_proxyerror(r, HTTP_BAD_REQUEST,
+ apr_pstrcat(p,"URI has no hostname: ", *url,
+ NULL));
+ }
+
if (!uri->port) {
uri->port = ap_proxy_port_of_scheme(uri->scheme);
}
@@ -3989,6 +3996,10 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p,
/* Compute Host header */
if (dconf->preserve_host == 0) {
+ if (!uri->hostname) {
+ rc = HTTP_BAD_REQUEST;
+ goto cleanup;
+ }
if (ap_strchr_c(uri->hostname, ':')) { /* if literal IPv6 address */
if (uri->port_str && uri->port != DEFAULT_HTTP_PORT) {
host = apr_pstrcat(r->pool, "[", uri->hostname, "]:",

@ -1,72 +0,0 @@
From 93aec0e3ca451bcc97f6d91c14d5399d13a73365 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Tue, 25 Jun 2024 15:28:00 +0000
Subject: [PATCH] Merge r1918553 from trunk:
block inadvertent subst of special filenames
+ cosmetic merge conflicts
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1918600 13f79535-47bb-0310-9956-ffa450edef68
---
modules/mappers/mod_rewrite.c | 38 ++++++++++++++++++++++++-----------
1 file changed, 26 insertions(+), 12 deletions(-)
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 4be51de..0df25ee 100644
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -4272,6 +4272,32 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
return 2;
}
+ /* Add the previously stripped per-directory location prefix, unless
+ * (1) it's an absolute URL path and
+ * (2) it's a full qualified URL
+ */
+ if (!is_proxyreq && *newuri != '/' && !is_absolute_uri(newuri, NULL)) {
+ if (ctx->perdir) {
+ rewritelog((r, 3, ctx->perdir, "add per-dir prefix: %s -> %s%s",
+ newuri, ctx->perdir, newuri));
+
+ newuri = apr_pstrcat(r->pool, ctx->perdir, newuri, NULL);
+ }
+ else if (!(p->flags & (RULEFLAG_PROXY | RULEFLAG_FORCEREDIRECT))) {
+ /* Not an absolute URI-path and the scheme (if any) is unknown,
+ * and it won't be passed to fully_qualify_uri() below either,
+ * so add an implicit '/' prefix. This avoids potentially a common
+ * rule like "RewriteRule ^/some/path(.*) $1" that is given a path
+ * like "/some/pathscheme:..." to produce the fully qualified URL
+ * "scheme:..." which could be misinterpreted later.
+ */
+ rewritelog((r, 3, ctx->perdir, "add root prefix: %s -> /%s",
+ newuri, newuri));
+
+ newuri = apr_pstrcat(r->pool, "/", newuri, NULL);
+ }
+ }
+
/* Now adjust API's knowledge about r->filename and r->args */
r->filename = newuri;
@@ -4281,18 +4307,6 @@ static int apply_rewrite_rule(rewriterule_entry *p, rewrite_ctx *ctx)
splitout_queryargs(r, p->flags);
- /* Add the previously stripped per-directory location prefix, unless
- * (1) it's an absolute URL path and
- * (2) it's a full qualified URL
- */
- if ( ctx->perdir && !is_proxyreq && *r->filename != '/'
- && !is_absolute_uri(r->filename, NULL)) {
- rewritelog((r, 3, ctx->perdir, "add per-dir prefix: %s -> %s%s",
- r->filename, ctx->perdir, r->filename));
-
- r->filename = apr_pstrcat(r->pool, ctx->perdir, r->filename, NULL);
- }
-
/* If this rule is forced for proxy throughput
* (`RewriteRule ... ... [P]') then emulate mod_proxy's
* URL-to-filename handler to be sure mod_proxy is triggered

@ -1,269 +0,0 @@
-- Contains also regression fix (CVE-2024-40725) - https://svn.apache.org/viewvc?view=revision&revision=1919249
diff --git a/modules/cluster/mod_heartmonitor.c b/modules/cluster/mod_heartmonitor.c
index 53b6504..68db585 100644
--- a/modules/cluster/mod_heartmonitor.c
+++ b/modules/cluster/mod_heartmonitor.c
@@ -782,7 +782,7 @@ static int hm_handler(request_rec *r)
hmserver.seen = apr_time_now();
hm_update_stat(ctx, &hmserver, r->pool);
- ap_set_content_type(r, "text/plain");
+ ap_set_content_type_ex(r, "text/plain", 1);
ap_set_content_length(r, 2);
ap_rputs("OK", r);
ap_rflush(r);
diff --git a/modules/dav/main/mod_dav.c b/modules/dav/main/mod_dav.c
index dea3f18..7a3eed7 100644
--- a/modules/dav/main/mod_dav.c
+++ b/modules/dav/main/mod_dav.c
@@ -355,7 +355,7 @@ static int dav_error_response(request_rec *r, int status, const char *body)
r->status = status;
r->status_line = ap_get_status_line(status);
- ap_set_content_type(r, "text/html; charset=ISO-8859-1");
+ ap_set_content_type_ex(r, "text/html; charset=ISO-8859-1", 1);
/* begin the response now... */
ap_rvputs(r,
@@ -386,7 +386,7 @@ static int dav_error_response_tag(request_rec *r,
{
r->status = err->status;
- ap_set_content_type(r, DAV_XML_CONTENT_TYPE);
+ ap_set_content_type_ex(r, DAV_XML_CONTENT_TYPE, 1);
ap_rputs(DAV_XML_HEADER DEBUG_CR
"<D:error xmlns:D=\"DAV:\"", r);
@@ -544,7 +544,7 @@ DAV_DECLARE(void) dav_begin_multistatus(apr_bucket_brigade *bb,
{
/* Set the correct status and Content-Type */
r->status = status;
- ap_set_content_type(r, DAV_XML_CONTENT_TYPE);
+ ap_set_content_type_ex(r, DAV_XML_CONTENT_TYPE, 1);
/* Send the headers and actual multistatus response now... */
ap_fputs(r->output_filters, bb, DAV_XML_HEADER DEBUG_CR
@@ -2016,7 +2016,7 @@ static int dav_method_options(request_rec *r)
/* send the options response */
r->status = HTTP_OK;
- ap_set_content_type(r, DAV_XML_CONTENT_TYPE);
+ ap_set_content_type_ex(r, DAV_XML_CONTENT_TYPE, 1);
/* send the headers and response body */
ap_rputs(DAV_XML_HEADER DEBUG_CR
@@ -3328,7 +3328,7 @@ static int dav_method_lock(request_rec *r)
(*locks_hooks->close_lockdb)(lockdb);
r->status = HTTP_OK;
- ap_set_content_type(r, DAV_XML_CONTENT_TYPE);
+ ap_set_content_type_ex(r, DAV_XML_CONTENT_TYPE, 1);
ap_rputs(DAV_XML_HEADER DEBUG_CR "<D:prop xmlns:D=\"DAV:\">" DEBUG_CR, r);
if (lock == NULL)
diff --git a/modules/examples/mod_example_hooks.c b/modules/examples/mod_example_hooks.c
index f7ef5a5..d937906 100644
--- a/modules/examples/mod_example_hooks.c
+++ b/modules/examples/mod_example_hooks.c
@@ -993,7 +993,7 @@ static int x_handler(request_rec *r)
* Set the Content-type header. Note that we do not actually have to send
* the headers: this is done by the http core.
*/
- ap_set_content_type(r, "text/html");
+ ap_set_content_type_ex(r, "text/html", 1);
/*
* If we're only supposed to send header information (HEAD request), we're
* already there.
diff --git a/modules/filters/mod_data.c b/modules/filters/mod_data.c
index ddadd1b..4e6e636 100644
--- a/modules/filters/mod_data.c
+++ b/modules/filters/mod_data.c
@@ -117,7 +117,7 @@ static apr_status_t data_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
}
}
- ap_set_content_type(r, "text/plain");
+ ap_set_content_type_ex(r, "text/plain", 1);
}
diff --git a/modules/filters/mod_include.c b/modules/filters/mod_include.c
index 584d8fb..2c0cc67 100644
--- a/modules/filters/mod_include.c
+++ b/modules/filters/mod_include.c
@@ -3972,7 +3972,7 @@ static int include_fixup(request_rec *r)
if (r->handler && (strcmp(r->handler, "server-parsed") == 0))
{
if (!r->content_type || !*r->content_type) {
- ap_set_content_type(r, "text/html");
+ ap_set_content_type_ex(r, "text/html", 1);
}
r->handler = "default-handler";
}
diff --git a/modules/filters/mod_proxy_html.c b/modules/filters/mod_proxy_html.c
index 7783da1..4205a61 100644
--- a/modules/filters/mod_proxy_html.c
+++ b/modules/filters/mod_proxy_html.c
@@ -952,7 +952,7 @@ static apr_status_t proxy_html_filter(ap_filter_t *f, apr_bucket_brigade *bb)
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, f->r, APLOGNO(01422)
"No i18n support found. Install mod_xml2enc if required");
enc = XML_CHAR_ENCODING_NONE;
- ap_set_content_type(f->r, "text/html;charset=utf-8");
+ ap_set_content_type_ex(f->r, "text/html;charset=utf-8", 1);
}
else {
/* if we wanted a non-default charset_out, insert the
@@ -968,7 +968,7 @@ static apr_status_t proxy_html_filter(ap_filter_t *f, apr_bucket_brigade *bb)
cenc, NULL));
}
else /* Normal case, everything worked, utf-8 output */
- ap_set_content_type(f->r, "text/html;charset=utf-8");
+ ap_set_content_type_ex(f->r, "text/html;charset=utf-8", 1);
}
ap_fputs(f->next, ctxt->bb, ctxt->cfg->doctype);
diff --git a/modules/generators/mod_cgi.c b/modules/generators/mod_cgi.c
index ecca381..b486dfe 100644
--- a/modules/generators/mod_cgi.c
+++ b/modules/generators/mod_cgi.c
@@ -795,7 +795,7 @@ static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f,
/* Force sub_req to be treated as a CGI request, even if ordinary
* typing rules would have called it something else.
*/
- ap_set_content_type(rr, CGI_MAGIC_TYPE);
+ ap_set_content_type_ex(rr, CGI_MAGIC_TYPE, 1);
/* Run it. */
rr_status = ap_run_sub_req(rr);
diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c
index dd91b99..ce744bc 100644
--- a/modules/generators/mod_cgid.c
+++ b/modules/generators/mod_cgid.c
@@ -1802,7 +1802,7 @@ static apr_status_t include_cgi(include_ctx_t *ctx, ap_filter_t *f,
/* Force sub_req to be treated as a CGI request, even if ordinary
* typing rules would have called it something else.
*/
- ap_set_content_type(rr, CGI_MAGIC_TYPE);
+ ap_set_content_type_ex(rr, CGI_MAGIC_TYPE, 1);
/* Run it. */
rr_status = ap_run_sub_req(rr);
diff --git a/modules/generators/mod_info.c b/modules/generators/mod_info.c
index 1662242..a94e4e4 100644
--- a/modules/generators/mod_info.c
+++ b/modules/generators/mod_info.c
@@ -784,7 +784,7 @@ static int display_info(request_rec * r)
return DECLINED;
}
- ap_set_content_type(r, "text/html; charset=ISO-8859-1");
+ ap_set_content_type_ex(r, "text/html; charset=ISO-8859-1", 1);
ap_rputs(DOCTYPE_XHTML_1_0T
"<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
diff --git a/modules/generators/mod_status.c b/modules/generators/mod_status.c
index 5bada07..2cb38c7 100644
--- a/modules/generators/mod_status.c
+++ b/modules/generators/mod_status.c
@@ -273,7 +273,7 @@ static int status_handler(request_rec *r)
if (r->method_number != M_GET)
return DECLINED;
- ap_set_content_type(r, "text/html; charset=ISO-8859-1");
+ ap_set_content_type_ex(r, "text/html; charset=ISO-8859-1", 1);
/*
* Simple table-driven form data set parser that lets you alter the header
@@ -301,7 +301,7 @@ static int status_handler(request_rec *r)
no_table_report = 1;
break;
case STAT_OPT_AUTO:
- ap_set_content_type(r, "text/plain; charset=ISO-8859-1");
+ ap_set_content_type_ex(r, "text/plain; charset=ISO-8859-1", 1);
short_report = 1;
break;
}
diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c
index 1a8df34..99ccbbb 100644
--- a/modules/http/http_filters.c
+++ b/modules/http/http_filters.c
@@ -1249,7 +1249,7 @@ AP_DECLARE_NONSTD(int) ap_send_http_trace(request_rec *r)
}
}
- ap_set_content_type(r, "message/http");
+ ap_set_content_type_ex(r, "message/http", 1);
/* Now we recreate the request, and echo it back */
diff --git a/modules/http/http_protocol.c b/modules/http/http_protocol.c
index c31e873..3bc666e 100644
--- a/modules/http/http_protocol.c
+++ b/modules/http/http_protocol.c
@@ -1443,10 +1443,10 @@ AP_DECLARE(void) ap_send_error_response(request_rec *r, int recursive_error)
request_conf->suppress_charset = 1; /* avoid adding default
* charset later
*/
- ap_set_content_type(r, "text/html");
+ ap_set_content_type_ex(r, "text/html", 1);
}
else {
- ap_set_content_type(r, "text/html; charset=iso-8859-1");
+ ap_set_content_type_ex(r, "text/html; charset=iso-8859-1", 1);
}
if ((status == HTTP_METHOD_NOT_ALLOWED)
diff --git a/modules/http/http_request.c b/modules/http/http_request.c
index d59cfe2..7e9477b 100644
--- a/modules/http/http_request.c
+++ b/modules/http/http_request.c
@@ -708,7 +708,7 @@ AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r)
r->args = rr->args;
r->finfo = rr->finfo;
r->handler = rr->handler;
- ap_set_content_type(r, rr->content_type);
+ ap_set_content_type_ex(r, rr->content_type, AP_REQUEST_IS_TRUSTED_CT(rr));
r->content_encoding = rr->content_encoding;
r->content_languages = rr->content_languages;
r->per_dir_config = rr->per_dir_config;
diff --git a/modules/ldap/util_ldap.c b/modules/ldap/util_ldap.c
index 39b1890..5e35852 100644
--- a/modules/ldap/util_ldap.c
+++ b/modules/ldap/util_ldap.c
@@ -139,7 +139,7 @@ static int util_ldap_handler(request_rec *r)
st = (util_ldap_state_t *) ap_get_module_config(r->server->module_config,
&ldap_module);
- ap_set_content_type(r, "text/html; charset=ISO-8859-1");
+ ap_set_content_type_ex(r, "text/html; charset=ISO-8859-1", 1);
if (r->header_only)
return OK;
diff --git a/modules/mappers/mod_imagemap.c b/modules/mappers/mod_imagemap.c
index 206c0b6..b2dca7e 100644
--- a/modules/mappers/mod_imagemap.c
+++ b/modules/mappers/mod_imagemap.c
@@ -475,7 +475,7 @@ static int imap_reply(request_rec *r, const char *redirect)
static void menu_header(request_rec *r, char *menu)
{
- ap_set_content_type(r, "text/html; charset=ISO-8859-1");
+ ap_set_content_type_ex(r, "text/html; charset=ISO-8859-1", 1);
ap_rvputs(r, DOCTYPE_HTML_3_2, "<html><head>\n<title>Menu for ",
ap_escape_html(r->pool, r->uri),
diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c
index b8b452d..3c0f5a8 100644
--- a/modules/proxy/mod_proxy_balancer.c
+++ b/modules/proxy/mod_proxy_balancer.c
@@ -1471,7 +1471,7 @@ static void balancer_display_page(request_rec *r, proxy_server_conf *conf,
if (usexml) {
char date[APR_RFC822_DATE_LEN];
- ap_set_content_type(r, "text/xml");
+ ap_set_content_type_ex(r, "text/xml", 1);
ap_rputs("<?xml version='1.0' encoding='UTF-8' ?>\n", r);
ap_rputs("<httpd:manager xmlns:httpd='http://httpd.apache.org'>\n", r);
ap_rputs(" <httpd:balancers>\n", r);

@ -1,14 +0,0 @@
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);

@ -1,51 +0,0 @@
--- 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);

@ -1,81 +0,0 @@
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

@ -1,170 +0,0 @@
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);
}

@ -1,143 +0,0 @@
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

@ -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;
}

@ -1,39 +0,0 @@
# ./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) ;
}

@ -1,91 +0,0 @@
# ./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 diff --git a/configure.in b/configure.in
index 1e342bb..a3c994b 100644 index 3932407..00e2369 100644
--- a/configure.in --- a/configure.in
+++ b/configure.in +++ b/configure.in
@@ -530,6 +530,11 @@ getloadavg @@ -531,6 +531,11 @@ gettid
dnl confirm that a void pointer is large enough to store a long integer dnl confirm that a void pointer is large enough to store a long integer
APACHE_CHECK_VOID_PTR_LEN APACHE_CHECK_VOID_PTR_LEN
@ -11,11 +11,11 @@ index 1e342bb..a3c994b 100644
+ APR_ADDTO(HTTPD_LIBS, [-lselinux]) + APR_ADDTO(HTTPD_LIBS, [-lselinux])
+]) +])
+ +
AC_CACHE_CHECK([for gettid()], ac_cv_gettid, if test $ac_cv_func_gettid = no; then
[AC_TRY_RUN(#define _GNU_SOURCE # On Linux before glibc 2.30, gettid() is only usable via syscall()
#include <unistd.h> AC_CACHE_CHECK([for gettid() via syscall], ap_cv_gettid,
diff --git a/server/core.c b/server/core.c diff --git a/server/core.c b/server/core.c
index ca33d94..41e9bdc 100644 index 8970a50..ff1024d 100644
--- a/server/core.c --- a/server/core.c
+++ b/server/core.c +++ b/server/core.c
@@ -65,6 +65,10 @@ @@ -65,6 +65,10 @@
@ -29,7 +29,7 @@ index ca33d94..41e9bdc 100644
/* LimitRequestBody handling */ /* LimitRequestBody handling */
#define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1) #define AP_LIMIT_REQ_BODY_UNSET ((apr_off_t) -1)
#define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 1<<30) /* 1GB */ #define AP_DEFAULT_LIMIT_REQ_BODY ((apr_off_t) 1<<30) /* 1GB */
@@ -5157,6 +5161,28 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte @@ -5170,6 +5174,28 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
} }
#endif #endif

@ -1,16 +0,0 @@
-----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,8 +1,8 @@
diff --git a/configure.in b/configure.in diff --git a/configure.in b/configure.in
index f8f9442..f276550 100644 index 7194de5..00e2369 100644
--- a/configure.in --- a/configure.in
+++ b/configure.in +++ b/configure.in
@@ -786,9 +786,9 @@ APACHE_SUBST(INSTALL_SUEXEC) @@ -843,9 +843,9 @@ APACHE_SUBST(INSTALL_SUEXEC)
dnl APR should go after the other libs, so the right symbols can be picked up dnl APR should go after the other libs, so the right symbols can be picked up
if test x${apu_found} != xobsolete; then if test x${apu_found} != xobsolete; then

@ -1,5 +1,5 @@
diff --git a/docs/manual/mod/mpm_common.html.en b/docs/manual/mod/mpm_common.html.en diff --git a/docs/manual/mod/mpm_common.html.en b/docs/manual/mod/mpm_common.html.en
index e7af21d..01d54b7 100644 index d7a2fea..c911a4e 100644
--- a/docs/manual/mod/mpm_common.html.en --- a/docs/manual/mod/mpm_common.html.en
+++ b/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> @@ -42,6 +42,7 @@ more than one multi-processing module (MPM)</td></tr>
@ -43,10 +43,10 @@ index e7af21d..01d54b7 100644
<div class="directive-section"><h2><a name="ListenBackLog" id="ListenBackLog">ListenBackLog</a> <a name="listenbacklog" id="listenbacklog">Directive</a></h2> <div class="directive-section"><h2><a name="ListenBackLog" id="ListenBackLog">ListenBackLog</a> <a name="listenbacklog" id="listenbacklog">Directive</a></h2>
<table class="directive"> <table class="directive">
diff --git a/include/ap_listen.h b/include/ap_listen.h diff --git a/include/ap_listen.h b/include/ap_listen.h
index 58c2574..1a53292 100644 index d5ed968..be1a60c 100644
--- a/include/ap_listen.h --- a/include/ap_listen.h
+++ b/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 @@ -138,6 +138,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_listencbratio(cmd_parms *cmd, void *dummy, const char *arg);
AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
int argc, char *const argv[]); int argc, char *const argv[]);
@ -56,7 +56,7 @@ index 58c2574..1a53292 100644
AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, void *dummy, AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, void *dummy,
const char *arg); const char *arg);
AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, 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, @@ -160,6 +163,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"), \ "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, \ 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"), \ "A port number or a numeric IP address and a port number, and an optional protocol"), \
@ -66,10 +66,10 @@ index 58c2574..1a53292 100644
"Send buffer size in bytes"), \ "Send buffer size in bytes"), \
AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \ AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \
diff --git a/server/listen.c b/server/listen.c diff --git a/server/listen.c b/server/listen.c
index e2e028a..6ef664b 100644 index 2a4e87a..280bbe7 100644
--- a/server/listen.c --- a/server/listen.c
+++ b/server/listen.c +++ b/server/listen.c
@@ -63,6 +63,7 @@ static int ap_listenbacklog; @@ -60,6 +60,7 @@ static int ap_listenbacklog;
static int ap_listencbratio; static int ap_listencbratio;
static int send_buffer_size; static int send_buffer_size;
static int receive_buffer_size; static int receive_buffer_size;
@ -77,7 +77,7 @@ index e2e028a..6ef664b 100644
#ifdef HAVE_SYSTEMD #ifdef HAVE_SYSTEMD
static int use_systemd = -1; static int use_systemd = -1;
#endif #endif
@@ -162,6 +163,21 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_ @@ -159,6 +160,21 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_
} }
#endif #endif
@ -99,7 +99,7 @@ index e2e028a..6ef664b 100644
if (do_bind_listen) { if (do_bind_listen) {
#if APR_HAVE_IPV6 #if APR_HAVE_IPV6
if (server->bind_addr->family == APR_INET6) { if (server->bind_addr->family == APR_INET6) {
@@ -956,6 +972,7 @@ AP_DECLARE(void) ap_listen_pre_config(void) @@ -971,6 +987,7 @@ AP_DECLARE(void) ap_listen_pre_config(void)
} }
} }
@ -107,8 +107,8 @@ index e2e028a..6ef664b 100644
AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
int argc, char *const argv[]) int argc, char *const argv[])
{ {
@@ -1016,6 +1033,14 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, @@ -1044,6 +1061,14 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
return alloc_listener(cmd->server->process, host, port, proto, NULL); scope_id, NULL, cmd->temp_pool);
} }
+AP_DECLARE_NONSTD(const char *) ap_set_freelistener(cmd_parms *cmd, void *dummy, +AP_DECLARE_NONSTD(const char *) ap_set_freelistener(cmd_parms *cmd, void *dummy,

@ -22,12 +22,11 @@ git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1919545
modules/mappers/mod_rewrite.c | 107 ++++++++++++++++++++++++++++------ modules/mappers/mod_rewrite.c | 107 ++++++++++++++++++++++++++++------
1 file changed, 89 insertions(+), 18 deletions(-) 1 file changed, 89 insertions(+), 18 deletions(-)
diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
index 226602f..a56a85c 100644 index f1c22e3235b..53fb1e91ffb 100644
--- a/modules/mappers/mod_rewrite.c --- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c +++ b/modules/mappers/mod_rewrite.c
@@ -2365,9 +2365,16 @@ static APR_INLINE char *find_char_in_curlies(char *s, int 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 * of an earlier expansion to include expansion specifiers that
* are interpreted by a later expansion, producing results that * are interpreted by a later expansion, producing results that
* were not intended by the administrator. * were not intended by the administrator.
@ -45,7 +44,7 @@ index 226602f..a56a85c 100644
result_list *result, *current; result_list *result, *current;
result_list sresult[SMALL_EXPANSION]; result_list sresult[SMALL_EXPANSION];
unsigned spc = 0; unsigned spc = 0;
@@ -2375,8 +2382,29 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) @@ -2386,8 +2393,29 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
char *p, *c; char *p, *c;
apr_pool_t *pool = ctx->r->pool; apr_pool_t *pool = ctx->r->pool;
@ -76,7 +75,7 @@ index 226602f..a56a85c 100644
/* fast exit */ /* fast exit */
if (inputlen == span) { if (inputlen == span) {
@@ -2394,6 +2422,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) @@ -2405,6 +2433,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
/* loop for specials */ /* loop for specials */
do { do {
@ -85,7 +84,7 @@ index 226602f..a56a85c 100644
/* prepare next entry */ /* prepare next entry */
if (current->len) { if (current->len) {
current->next = (spc < SMALL_EXPANSION) current->next = (spc < SMALL_EXPANSION)
@@ -2439,6 +2469,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) @@ -2450,6 +2480,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
current->len = span; current->len = span;
current->string = p; current->string = p;
outlen += span; outlen += span;
@ -94,7 +93,7 @@ index 226602f..a56a85c 100644
p = endp + 1; p = endp + 1;
} }
@@ -2478,19 +2510,18 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) @@ -2489,19 +2521,18 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
} }
/* reuse of key variable as result */ /* reuse of key variable as result */
@ -118,7 +117,7 @@ index 226602f..a56a85c 100644
p = endp + 1; p = endp + 1;
} }
} }
@@ -2520,8 +2551,9 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) @@ -2531,8 +2562,9 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
current->len = span; current->len = span;
current->string = bri->source + bri->regmatch[n].rm_so; current->string = bri->source + bri->regmatch[n].rm_so;
} }
@ -129,7 +128,7 @@ index 226602f..a56a85c 100644
} }
p += 2; p += 2;
@@ -2534,8 +2566,41 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) @@ -2545,8 +2577,41 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
++outlen; ++outlen;
} }
@ -172,7 +171,7 @@ index 226602f..a56a85c 100644
if (current->len) { if (current->len) {
current->next = (spc < SMALL_EXPANSION) current->next = (spc < SMALL_EXPANSION)
? &(sresult[spc++]) ? &(sresult[spc++])
@@ -2580,7 +2645,7 @@ static void do_expand_env(data_item *env, rewrite_ctx *ctx) @@ -2591,7 +2656,7 @@ static void do_expand_env(data_item *env, rewrite_ctx *ctx)
char *name, *val; char *name, *val;
while (env) { while (env) {
@ -181,7 +180,7 @@ index 226602f..a56a85c 100644
if (*name == '!') { if (*name == '!') {
name++; name++;
apr_table_unset(ctx->r->subprocess_env, name); apr_table_unset(ctx->r->subprocess_env, name);
@@ -2714,7 +2779,7 @@ static void add_cookie(request_rec *r, char *s) @@ -2725,7 +2790,7 @@ static void add_cookie(request_rec *r, char *s)
static void do_expand_cookie(data_item *cookie, rewrite_ctx *ctx) static void do_expand_cookie(data_item *cookie, rewrite_ctx *ctx)
{ {
while (cookie) { while (cookie) {
@ -190,7 +189,7 @@ index 226602f..a56a85c 100644
cookie = cookie->next; cookie = cookie->next;
} }
@@ -3992,7 +4057,7 @@ static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx) @@ -4014,7 +4079,7 @@ static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx)
int basis; int basis;
if (p->ptype != CONDPAT_AP_EXPR) if (p->ptype != CONDPAT_AP_EXPR)
@ -199,7 +198,7 @@ index 226602f..a56a85c 100644
switch (p->ptype) { switch (p->ptype) {
case CONDPAT_FILE_EXISTS: case CONDPAT_FILE_EXISTS:
@@ -4156,7 +4221,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p, @@ -4178,7 +4243,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p,
char *expanded; char *expanded;
if (p->forced_mimetype) { if (p->forced_mimetype) {
@ -208,7 +207,7 @@ index 226602f..a56a85c 100644
if (*expanded) { if (*expanded) {
ap_str_tolower(expanded); ap_str_tolower(expanded);
@@ -4170,7 +4235,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p, @@ -4192,7 +4257,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p,
} }
if (p->forced_handler) { if (p->forced_handler) {
@ -217,7 +216,7 @@ index 226602f..a56a85c 100644
if (*expanded) { if (*expanded) {
ap_str_tolower(expanded); ap_str_tolower(expanded);
@@ -4307,12 +4372,18 @@ static rule_return_type apply_rewrite_rule(rewriterule_entry *p, @@ -4329,12 +4394,18 @@ static rule_return_type apply_rewrite_rule(rewriterule_entry *p,
/* expand the result */ /* expand the result */
if (!(p->flags & RULEFLAG_NOSUB)) { if (!(p->flags & RULEFLAG_NOSUB)) {
@ -237,6 +236,7 @@ index 226602f..a56a85c 100644
- ap_strchr_c(newuri, '?')) { - ap_strchr_c(newuri, '?')) {
+ +
+ if (unsafe_qmark > 0) { + if (unsafe_qmark > 0) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10508)
"Unsafe URL with %%3f URL rewritten without " "Unsafe URL with %%3f URL rewritten without "
"UnsafeAllow3F"); "UnsafeAllow3F");

@ -1,8 +1,8 @@
diff --git a/server/listen.c b/server/listen.c diff --git a/server/listen.c b/server/listen.c
index 5242c2a..e2e028a 100644 index 9577d60..d718db1 100644
--- a/server/listen.c --- a/server/listen.c
+++ b/server/listen.c +++ b/server/listen.c
@@ -34,6 +34,10 @@ @@ -35,6 +35,10 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
@ -13,7 +13,7 @@ index 5242c2a..e2e028a 100644
/* we know core's module_index is 0 */ /* we know core's module_index is 0 */
#undef APLOG_MODULE_INDEX #undef APLOG_MODULE_INDEX
#define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
@@ -59,9 +63,12 @@ static int ap_listenbacklog; @@ -60,9 +64,12 @@ static int ap_listenbacklog;
static int ap_listencbratio; static int ap_listencbratio;
static int send_buffer_size; static int send_buffer_size;
static int receive_buffer_size; static int receive_buffer_size;
@ -27,7 +27,7 @@ index 5242c2a..e2e028a 100644
{ {
apr_socket_t *s = server->sd; apr_socket_t *s = server->sd;
int one = 1; int one = 1;
@@ -94,20 +101,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server) @@ -95,20 +102,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
return stat; return stat;
} }
@ -48,7 +48,7 @@ index 5242c2a..e2e028a 100644
/* /*
* To send data over high bandwidth-delay connections at full * To send data over high bandwidth-delay connections at full
* speed we must force the TCP window to open wide enough to keep the * 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) @@ -170,21 +163,37 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
} }
#endif #endif
@ -100,7 +100,7 @@ index 5242c2a..e2e028a 100644
} }
#ifdef WIN32 #ifdef WIN32
@@ -315,6 +324,123 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to, @@ -335,6 +344,123 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
return found; return found;
} }
@ -223,8 +223,8 @@ index 5242c2a..e2e028a 100644
+ +
static const char *alloc_listener(process_rec *process, const char *addr, static const char *alloc_listener(process_rec *process, const char *addr,
apr_port_t port, const char* proto, apr_port_t port, const char* proto,
void *slave) const char *scope_id, void *slave,
@@ -495,7 +621,7 @@ static int open_listeners(apr_pool_t *pool) @@ -529,7 +655,7 @@ static int open_listeners(apr_pool_t *pool)
} }
} }
#endif #endif
@ -233,7 +233,7 @@ index 5242c2a..e2e028a 100644
++num_open; ++num_open;
} }
else { else {
@@ -607,8 +733,28 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s) @@ -641,8 +767,28 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
} }
} }
@ -264,7 +264,7 @@ index 5242c2a..e2e028a 100644
} }
for (lr = ap_listeners; lr; lr = lr->next) { 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, @@ -732,7 +878,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
duplr->bind_addr); duplr->bind_addr);
return stat; return stat;
} }
@ -273,7 +273,7 @@ index 5242c2a..e2e028a 100644
#if AP_NONBLOCK_WHEN_MULTI_LISTEN #if AP_NONBLOCK_WHEN_MULTI_LISTEN
use_nonblock = (ap_listeners && ap_listeners->next); use_nonblock = (ap_listeners && ap_listeners->next);
stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock); 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, @@ -859,6 +1005,11 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
if (argc < 1 || argc > 2) { if (argc < 1 || argc > 2) {
return "Listen requires 1 or 2 arguments."; return "Listen requires 1 or 2 arguments.";
} }
@ -285,7 +285,7 @@ index 5242c2a..e2e028a 100644
rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool); rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool);
if (rv != APR_SUCCESS) { if (rv != APR_SUCCESS) {
@@ -856,6 +1007,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, @@ -894,6 +1045,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
ap_str_tolower(proto); ap_str_tolower(proto);
} }
@ -295,6 +295,6 @@ index 5242c2a..e2e028a 100644
+ } + }
+#endif +#endif
+ +
return alloc_listener(cmd->server->process, host, port, proto, NULL); return alloc_listener(cmd->server->process, host, port, proto,
scope_id, NULL, cmd->temp_pool);
} }

@ -0,0 +1,16 @@
-----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-----

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

@ -12,8 +12,8 @@
Summary: Apache HTTP Server Summary: Apache HTTP Server
Name: httpd Name: httpd
Version: 2.4.57 Version: 2.4.62
Release: 11%{?dist}.1 Release: 1%{?dist}
URL: https://httpd.apache.org/ URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2 Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
Source1: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2.asc Source1: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2.asc
@ -62,10 +62,11 @@ Source45: config.layout
Source46: apachectl.sh Source46: apachectl.sh
Source47: apachectl.xml Source47: apachectl.xml
Source48: apache-poweredby.png Source48: apache-poweredby.png
Source49: httpd.sysusers
# build/scripts patches # build/scripts patches
Patch2: httpd-2.4.43-apxs.patch Patch2: httpd-2.4.43-apxs.patch
Patch3: httpd-2.4.43-deplibs.patch Patch3: httpd-2.4.59-deplibs.patch
# Needed for socket activation and mod_systemd patch # Needed for socket activation and mod_systemd patch
Patch19: httpd-2.4.53-detect-systemd.patch Patch19: httpd-2.4.53-detect-systemd.patch
# Features/functional changes # Features/functional changes
@ -74,77 +75,34 @@ Patch22: httpd-2.4.43-mod_systemd.patch
Patch23: httpd-2.4.48-export.patch Patch23: httpd-2.4.48-export.patch
Patch24: httpd-2.4.43-corelimit.patch Patch24: httpd-2.4.43-corelimit.patch
Patch25: httpd-2.4.57-selinux.patch Patch25: httpd-2.4.57-selinux.patch
Patch26: httpd-2.4.57-gettid.patch Patch26: httpd-2.4.53-icons.patch
Patch27: httpd-2.4.53-icons.patch Patch27: httpd-2.4.43-cachehardmax.patch
Patch30: httpd-2.4.43-cachehardmax.patch Patch28: httpd-2.4.62-socket-activation.patch
Patch34: httpd-2.4.43-socket-activation.patch Patch29: httpd-2.4.43-sslciphdefault.patch
Patch38: httpd-2.4.43-sslciphdefault.patch Patch30: httpd-2.4.43-sslprotdefault.patch
Patch39: httpd-2.4.43-sslprotdefault.patch Patch31: httpd-2.4.43-logjournal.patch
Patch41: httpd-2.4.43-r1861793+.patch Patch32: httpd-2.4.48-proxy-ws-idle-timeout.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 # https://bugzilla.redhat.com/show_bug.cgi?id=1949606
Patch48: httpd-2.4.46-freebind.patch Patch33: httpd-2.4.62-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 # https://bugzilla.redhat.com/show_bug.cgi?id=2065677
Patch52: httpd-2.4.53-separate-systemd-fns.patch Patch34: httpd-2.4.53-separate-systemd-fns.patch
# https://issues.redhat.com/browse/RHEL-5071 # https://issues.redhat.com/browse/RHEL-5071
Patch53: httpd-2.4.57-r1912477+.patch Patch35: httpd-2.4.57-r1912477+.patch
# https://issues.redhat.com/browse/RHEL-6600
Patch54: httpd-2.4.57-r1912081.patch
# Bug fixes # Bug fixes
# https://bugzilla.redhat.com/show_bug.cgi?id=1397243 # https://bugzilla.redhat.com/show_bug.cgi?id=1397243
Patch60: httpd-2.4.43-enable-sslv3.patch Patch100: 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 # https://bugzilla.redhat.com/show_bug.cgi?id=1932442
Patch64: httpd-2.4.48-full-release.patch Patch101: 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
# https://bz.apache.org/bugzilla/show_bug.cgi?id=69197 # https://bz.apache.org/bugzilla/show_bug.cgi?id=69197
Patch73: httpd-2.4.57-r1919325.patch Patch102: httpd-2.4.62-r1919325.patch
# Security fixes # Security fixes
# https://bugzilla.redhat.com/show_bug.cgi?id=... # https://bugzilla.redhat.com/show_bug.cgi?id=...
# #
# https://bugzilla.redhat.com/show_bug.cgi?id=2245332 # https://bugzilla.redhat.com/show_bug.cgi?id=
Patch200: httpd-2.4.57-CVE-2023-31122.patch # Patch200: httpd-2.4.X-CVE-XXXX-YYYYY.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2295016
Patch201: httpd-2.4.57-CVE-2024-38477.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2295022
Patch202: httpd-2.4.57-CVE-2024-39573.patch
# CVE-2024-38474 and CVE-2024-38475 fixed in one patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2295013
# https://bugzilla.redhat.com/show_bug.cgi?id=2295014
Patch204: httpd-2.4.57-CVE-2024-38474+.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2295012
Patch206: httpd-2.4.57-CVE-2024-38473.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2295015
Patch207: httpd-2.4.57-CVE-2024-38476.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2297362
# https://bugzilla.redhat.com/show_bug.cgi?id=2295761
# part of CVE-2024-38476 fix
Patch208: httpd-2.4.57-CVE-2024-39884+.patch
License: ASL 2.0 License: ASL 2.0
BuildRequires: gcc, autoconf, pkgconfig, findutils, xmlto BuildRequires: gcc, autoconf, pkgconfig, findutils, xmlto
@ -152,13 +110,12 @@ BuildRequires: perl-interpreter, perl-generators, systemd-devel
BuildRequires: zlib-devel, libselinux-devel, lua-devel, brotli-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: apr-devel >= 1.5.0, apr-util-devel >= 1.5.0, pcre-devel >= 5.0
BuildRequires: gnupg2 BuildRequires: gnupg2
BuildRequires: systemd-rpm-macros
Requires: system-logos-httpd Requires: system-logos-httpd
Provides: webserver Provides: webserver
Requires: httpd-core = 0:%{version}-%{release} Requires: httpd-core = 0:%{version}-%{release}
Recommends: mod_http2, mod_lua Recommends: mod_http2, mod_lua
Requires(preun): systemd-units %{?systemd_requires}
Requires(postun): systemd-units
Requires(post): systemd-units
%description %description
The Apache HTTP Server is a powerful, efficient, and extensible The Apache HTTP Server is a powerful, efficient, and extensible
@ -208,7 +165,7 @@ also be found at https://httpd.apache.org/docs/2.4/.
%package filesystem %package filesystem
Summary: The basic directory layout for the Apache HTTP Server Summary: The basic directory layout for the Apache HTTP Server
BuildArch: noarch BuildArch: noarch
Requires(pre): /usr/sbin/useradd %{?sysusers_requires_compat}
%description filesystem %description filesystem
The httpd-filesystem package contains the basic directory layout The httpd-filesystem package contains the basic directory layout
@ -287,45 +244,20 @@ written in the Lua programming language.
%patch23 -p1 -b .export %patch23 -p1 -b .export
%patch24 -p1 -b .corelimit %patch24 -p1 -b .corelimit
%patch25 -p1 -b .selinux %patch25 -p1 -b .selinux
%patch26 -p1 -b .gettid %patch26 -p1 -b .icons
%patch27 -p1 -b .icons %patch27 -p1 -b .cachehardmax
%patch30 -p1 -b .cachehardmax %patch28 -p1 -b .socketactivation
%patch34 -p1 -b .socketactivation %patch29 -p1 -b .sslciphdefault
%patch38 -p1 -b .sslciphdefault %patch30 -p1 -b .sslprotdefault
%patch39 -p1 -b .sslprotdefault %patch31 -p1 -b .logjournal
%patch41 -p1 -b .r1861793+ %patch32 -p1 -b .proxy-ws-idle-timeout
%patch42 -p1 -b .r1828172+ %patch33 -p1 -b .freebind
%patch45 -p1 -b .logjournal %patch34 -p1 -b .separatesystemd
%patch46 -p1 -b .proxy-ws-idle-timeout %patch35 -p1 -b .r1912477+
%patch47 -p1 -b .pr37355
%patch48 -p1 -b .freebind %patch100 -p1 -b .enable-sslv3
%patch49 -p1 -b .ssl-proxy-chains %patch101 -p1 -b .full-release
%patch50 -p1 -b .r1825120 %patch102 -p1 -b .r1919325
%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
%patch201 -p1 -b .CVE-2024-38477
%patch202 -p1 -b .CVE-2024-39573
%patch204 -p1 -b .CVE-2024-38474+
# CVE-2024-38474 regression fix
%patch73 -p1 -b .r1919325
%patch206 -p1 -b .CVE-2024-38473
%patch207 -p1 -b .CVE-2024-38476
%patch208 -p1 -b .CVE-2024-39884+
# Patch in the vendor string # Patch in the vendor string
sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h
@ -651,6 +583,9 @@ touch -r $RPM_BUILD_ROOT%{_bindir}/apxs \
$RPM_BUILD_ROOT%{_libdir}/httpd/build/vendor-apxs $RPM_BUILD_ROOT%{_libdir}/httpd/build/vendor-apxs
chmod 755 $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 # Remove unpackaged files
rm -vf \ rm -vf \
$RPM_BUILD_ROOT%{_libdir}/*.exp \ $RPM_BUILD_ROOT%{_libdir}/*.exp \
@ -666,11 +601,8 @@ rm -vf \
rm -rf $RPM_BUILD_ROOT/etc/httpd/conf/{original,extra} rm -rf $RPM_BUILD_ROOT/etc/httpd/conf/{original,extra}
%pre filesystem %pre filesystem
getent group apache >/dev/null || groupadd -g 48 -r apache %sysusers_create_compat %{SOURCE49}
getent passwd apache >/dev/null || \
useradd -r -u 48 -g apache -s /sbin/nologin \
-d %{contentdir} -c "Apache" apache
exit 0
%post %post
%systemd_post httpd.service htcacheclean.service httpd.socket %systemd_post httpd.service htcacheclean.service httpd.socket
@ -834,6 +766,7 @@ exit $rv
%dir %{contentdir}/icons %dir %{contentdir}/icons
%attr(755,root,root) %dir %{_unitdir}/httpd.service.d %attr(755,root,root) %dir %{_unitdir}/httpd.service.d
%attr(755,root,root) %dir %{_unitdir}/httpd.socket.d %attr(755,root,root) %dir %{_unitdir}/httpd.socket.d
%{_sysusersdir}/httpd.conf
%files tools %files tools
%{_bindir}/* %{_bindir}/*
@ -886,23 +819,37 @@ exit $rv
%{_rpmconfigdir}/macros.d/macros.httpd %{_rpmconfigdir}/macros.d/macros.httpd
%changelog %changelog
* Mon Aug 05 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.57-11.1 * Sat Aug 03 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.62-1
- Resolves: RHEL-46047 - httpd: Security issues via backend applications whose - new version 2.4.62
response headers are malicious or exploitable (CVE-2024-38476) - Resolves: RHEL-52724 - Regression introduced by CVE-2024-38474 fix
- Resolves: RHEL-53021 - Regression introduced by CVE-2024-38474 fix
* Fri Jul 19 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.59-7
* Thu Jul 04 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.57-11 - Resolves: RHEL-49856: htcacheclean.service missing [Install] section
- Resolves: RHEL-45792 - httpd: Encoding problem in
mod_proxy (CVE-2024-38473) * Thu May 30 2024 Joe Orton <jorton@redhat.com> - 2.4.59-6
- mod_ssl: restore SSL_OP_NO_RENEGOTIATE support
* Wed Jul 03 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.57-9 Related: RHEL-14668
- Resolves: RHEL-45766 - httpd: null pointer dereference in
mod_proxy (CVE-2024-38477) * Tue May 21 2024 Joe Orton <jorton@redhat.com> - 2.4.59-5
- Resolves: RHEL-45749 - httpd: Potential SSRF in mod_rewrite (CVE-2024-39573) - mod_ssl: defer ENGINE_finish() calls to a cleanup
- Resolves: RHEL-45818 - httpd: Substitution encoding issue in Resolves: RHEL-36755
mod_rewrite (CVE-2024-38474)
- Resolves: RHEL-45771 - httpd: Improper escaping of output in * Mon May 20 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.59-4
mod_rewrite (CVE-2024-38475) - 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 * Wed Feb 7 2024 Joe Orton <jorton@redhat.com> - 2.4.57-8
- mod_xml2enc: fix media type handling - mod_xml2enc: fix media type handling

Loading…
Cancel
Save