parent
8f268ad56c
commit
2a06ec2d28
@ -1,2 +1,2 @@
|
||||
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
|
||||
01044512374941fad939ec4b1537428cc7edc769 SOURCES/httpd-2.4.57.tar.bz2
|
||||
c968e2a0e556a8d3b7f6d6fc9732ddc456b5c229 SOURCES/httpd-2.4.62.tar.bz2
|
||||
|
@ -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"> en </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> </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,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
|
||||
index f8f9442..f276550 100644
|
||||
index 7194de5..00e2369 100644
|
||||
--- a/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
|
||||
if test x${apu_found} != xobsolete; then
|
@ -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
|
Loading…
Reference in new issue