import UBI httpd-2.4.62-1.el9
This commit is contained in:
		
							parent
							
								
									aa7f1b5cf5
								
							
						
					
					
						commit
						7519b10b67
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -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 | ||||
|  | ||||
| @ -7,5 +7,10 @@ Documentation=man:htcacheclean.service(8) | ||||
| Type=forking | ||||
| User=apache | ||||
| PIDFile=/run/httpd/htcacheclean/pid | ||||
| Environment=LANG=C | ||||
| EnvironmentFile=/etc/sysconfig/htcacheclean | ||||
| ExecStart=/usr/sbin/htcacheclean -P /run/httpd/htcacheclean/pid -d $INTERVAL -p $CACHE_ROOT -l $LIMIT $OPTIONS | ||||
| PrivateTmp=true | ||||
| 
 | ||||
| [Install] | ||||
| WantedBy=multi-user.target | ||||
|  | ||||
| @ -1,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,8 +1,8 @@ | ||||
| diff --git a/configure.in b/configure.in
 | ||||
| index 1e342bb..a3c994b 100644
 | ||||
| index 3932407..00e2369 100644
 | ||||
| --- a/configure.in
 | ||||
| +++ b/configure.in
 | ||||
| @@ -530,6 +530,11 @@ getloadavg
 | ||||
| @@ -531,6 +531,11 @@ gettid
 | ||||
|  dnl confirm that a void pointer is large enough to store a long integer | ||||
|  APACHE_CHECK_VOID_PTR_LEN | ||||
|   | ||||
| @ -11,11 +11,11 @@ index 1e342bb..a3c994b 100644 | ||||
| +   APR_ADDTO(HTTPD_LIBS, [-lselinux])
 | ||||
| +])
 | ||||
| +
 | ||||
|  AC_CACHE_CHECK([for gettid()], ac_cv_gettid, | ||||
|  [AC_TRY_RUN(#define _GNU_SOURCE | ||||
|  #include <unistd.h> | ||||
|  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, | ||||
| diff --git a/server/core.c b/server/core.c
 | ||||
| index ca33d94..41e9bdc 100644
 | ||||
| index 8970a50..ff1024d 100644
 | ||||
| --- a/server/core.c
 | ||||
| +++ b/server/core.c
 | ||||
| @@ -65,6 +65,10 @@
 | ||||
| @ -29,7 +29,7 @@ index ca33d94..41e9bdc 100644 | ||||
|  /* LimitRequestBody handling */ | ||||
|  #define AP_LIMIT_REQ_BODY_UNSET         ((apr_off_t) -1) | ||||
|  #define AP_DEFAULT_LIMIT_REQ_BODY       ((apr_off_t) 1<<30) /* 1GB */ | ||||
| @@ -5157,6 +5161,28 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
 | ||||
| @@ -5170,6 +5174,28 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
 | ||||
|      } | ||||
|  #endif | ||||
|   | ||||
|  | ||||
| @ -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 | ||||
| @ -1,5 +1,5 @@ | ||||
| diff --git a/docs/manual/mod/mpm_common.html.en b/docs/manual/mod/mpm_common.html.en
 | ||||
| index e7af21d..01d54b7 100644
 | ||||
| index d7a2fea..c911a4e 100644
 | ||||
| --- a/docs/manual/mod/mpm_common.html.en
 | ||||
| +++ b/docs/manual/mod/mpm_common.html.en
 | ||||
| @@ -42,6 +42,7 @@ more than one multi-processing module (MPM)</td></tr>
 | ||||
| @ -43,10 +43,10 @@ index e7af21d..01d54b7 100644 | ||||
|  <div class="directive-section"><h2><a name="ListenBackLog" id="ListenBackLog">ListenBackLog</a> <a name="listenbacklog" id="listenbacklog">Directive</a></h2> | ||||
|  <table class="directive"> | ||||
| diff --git a/include/ap_listen.h b/include/ap_listen.h
 | ||||
| index 58c2574..1a53292 100644
 | ||||
| index d5ed968..be1a60c 100644
 | ||||
| --- a/include/ap_listen.h
 | ||||
| +++ b/include/ap_listen.h
 | ||||
| @@ -137,6 +137,9 @@ AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy
 | ||||
| @@ -138,6 +138,9 @@ AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy
 | ||||
|  AP_DECLARE_NONSTD(const char *) ap_set_listencbratio(cmd_parms *cmd, void *dummy, const char *arg); | ||||
|  AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, | ||||
|                                                  int argc, char *const argv[]); | ||||
| @ -56,7 +56,7 @@ index 58c2574..1a53292 100644 | ||||
|  AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, void *dummy, | ||||
|                                                          const char *arg); | ||||
|  AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, | ||||
| @@ -150,6 +153,8 @@ AP_INIT_TAKE1("ListenCoresBucketsRatio", ap_set_listencbratio, NULL, RSRC_CONF,
 | ||||
| @@ -160,6 +163,8 @@ AP_INIT_TAKE1("ListenCoresBucketsRatio", ap_set_listencbratio, NULL, RSRC_CONF,
 | ||||
|    "Ratio between the number of CPU cores (online) and the number of listeners buckets"), \ | ||||
|  AP_INIT_TAKE_ARGV("Listen", ap_set_listener, NULL, RSRC_CONF, \ | ||||
|    "A port number or a numeric IP address and a port number, and an optional protocol"), \ | ||||
| @ -66,10 +66,10 @@ index 58c2574..1a53292 100644 | ||||
|    "Send buffer size in bytes"), \ | ||||
|  AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \ | ||||
| diff --git a/server/listen.c b/server/listen.c
 | ||||
| index e2e028a..6ef664b 100644
 | ||||
| index 2a4e87a..280bbe7 100644
 | ||||
| --- a/server/listen.c
 | ||||
| +++ b/server/listen.c
 | ||||
| @@ -63,6 +63,7 @@ static int ap_listenbacklog;
 | ||||
| @@ -60,6 +60,7 @@ static int ap_listenbacklog;
 | ||||
|  static int ap_listencbratio; | ||||
|  static int send_buffer_size; | ||||
|  static int receive_buffer_size; | ||||
| @ -77,7 +77,7 @@ index e2e028a..6ef664b 100644 | ||||
|  #ifdef HAVE_SYSTEMD | ||||
|  static int use_systemd = -1; | ||||
|  #endif | ||||
| @@ -162,6 +163,21 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_
 | ||||
| @@ -159,6 +160,21 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_
 | ||||
|      } | ||||
|  #endif | ||||
|   | ||||
| @ -99,7 +99,7 @@ index e2e028a..6ef664b 100644 | ||||
|      if (do_bind_listen) { | ||||
|  #if APR_HAVE_IPV6 | ||||
|          if (server->bind_addr->family == APR_INET6) { | ||||
| @@ -956,6 +972,7 @@ AP_DECLARE(void) ap_listen_pre_config(void)
 | ||||
| @@ -971,6 +987,7 @@ AP_DECLARE(void) ap_listen_pre_config(void)
 | ||||
|      } | ||||
|  } | ||||
|   | ||||
| @ -107,8 +107,8 @@ index e2e028a..6ef664b 100644 | ||||
|  AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, | ||||
|                                                  int argc, char *const argv[]) | ||||
|  { | ||||
| @@ -1016,6 +1033,14 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
 | ||||
|      return alloc_listener(cmd->server->process, host, port, proto, NULL); | ||||
| @@ -1044,6 +1061,14 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
 | ||||
|                            scope_id, NULL, cmd->temp_pool); | ||||
|  } | ||||
|   | ||||
| +AP_DECLARE_NONSTD(const char *) ap_set_freelistener(cmd_parms *cmd, void *dummy,
 | ||||
| @ -22,12 +22,11 @@ git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1919545 | ||||
|  modules/mappers/mod_rewrite.c | 107 ++++++++++++++++++++++++++++------ | ||||
|  1 file changed, 89 insertions(+), 18 deletions(-) | ||||
| 
 | ||||
| 
 | ||||
| diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c
 | ||||
| index 226602f..a56a85c 100644
 | ||||
| index f1c22e3235b..53fb1e91ffb 100644
 | ||||
| --- a/modules/mappers/mod_rewrite.c
 | ||||
| +++ b/modules/mappers/mod_rewrite.c
 | ||||
| @@ -2365,9 +2365,16 @@ static APR_INLINE char *find_char_in_curlies(char *s, int c)
 | ||||
| @@ -2376,9 +2376,16 @@ static APR_INLINE char *find_char_in_curlies(char *s, int c)
 | ||||
|   * of an earlier expansion to include expansion specifiers that | ||||
|   * are interpreted by a later expansion, producing results that | ||||
|   * were not intended by the administrator. | ||||
| @ -45,7 +44,7 @@ index 226602f..a56a85c 100644 | ||||
|      result_list *result, *current; | ||||
|      result_list sresult[SMALL_EXPANSION]; | ||||
|      unsigned spc = 0; | ||||
| @@ -2375,8 +2382,29 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
| @@ -2386,8 +2393,29 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
|      char *p, *c; | ||||
|      apr_pool_t *pool = ctx->r->pool; | ||||
|   | ||||
| @ -76,7 +75,7 @@ index 226602f..a56a85c 100644 | ||||
|   | ||||
|      /* fast exit */ | ||||
|      if (inputlen == span) { | ||||
| @@ -2394,6 +2422,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
| @@ -2405,6 +2433,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
|   | ||||
|      /* loop for specials */ | ||||
|      do { | ||||
| @ -85,7 +84,7 @@ index 226602f..a56a85c 100644 | ||||
|          /* prepare next entry */ | ||||
|          if (current->len) { | ||||
|              current->next = (spc < SMALL_EXPANSION) | ||||
| @@ -2439,6 +2469,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
| @@ -2450,6 +2480,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
|                  current->len = span; | ||||
|                  current->string = p; | ||||
|                  outlen += span; | ||||
| @ -94,7 +93,7 @@ index 226602f..a56a85c 100644 | ||||
|                  p = endp + 1; | ||||
|              } | ||||
|   | ||||
| @@ -2478,19 +2510,18 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
| @@ -2489,19 +2521,18 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
|                      } | ||||
|   | ||||
|                      /* reuse of key variable as result */ | ||||
| @ -118,7 +117,7 @@ index 226602f..a56a85c 100644 | ||||
|                      p = endp + 1; | ||||
|                  } | ||||
|              } | ||||
| @@ -2520,8 +2551,9 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
| @@ -2531,8 +2562,9 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
|                      current->len = span; | ||||
|                      current->string = bri->source + bri->regmatch[n].rm_so; | ||||
|                  } | ||||
| @ -129,7 +128,7 @@ index 226602f..a56a85c 100644 | ||||
|              } | ||||
|   | ||||
|              p += 2; | ||||
| @@ -2534,8 +2566,41 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
| @@ -2545,8 +2577,41 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry)
 | ||||
|              ++outlen; | ||||
|          } | ||||
|   | ||||
| @ -172,7 +171,7 @@ index 226602f..a56a85c 100644 | ||||
|              if (current->len) { | ||||
|                  current->next = (spc < SMALL_EXPANSION) | ||||
|                                  ? &(sresult[spc++]) | ||||
| @@ -2580,7 +2645,7 @@ static void do_expand_env(data_item *env, rewrite_ctx *ctx)
 | ||||
| @@ -2591,7 +2656,7 @@ static void do_expand_env(data_item *env, rewrite_ctx *ctx)
 | ||||
|      char *name, *val; | ||||
|   | ||||
|      while (env) { | ||||
| @ -181,7 +180,7 @@ index 226602f..a56a85c 100644 | ||||
|          if (*name == '!') { | ||||
|              name++; | ||||
|              apr_table_unset(ctx->r->subprocess_env, name); | ||||
| @@ -2714,7 +2779,7 @@ static void add_cookie(request_rec *r, char *s)
 | ||||
| @@ -2725,7 +2790,7 @@ static void add_cookie(request_rec *r, char *s)
 | ||||
|  static void do_expand_cookie(data_item *cookie, rewrite_ctx *ctx) | ||||
|  { | ||||
|      while (cookie) { | ||||
| @ -190,7 +189,7 @@ index 226602f..a56a85c 100644 | ||||
|          cookie = cookie->next; | ||||
|      } | ||||
|   | ||||
| @@ -3992,7 +4057,7 @@ static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx)
 | ||||
| @@ -4014,7 +4079,7 @@ static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx)
 | ||||
|      int basis; | ||||
|   | ||||
|      if (p->ptype != CONDPAT_AP_EXPR) | ||||
| @ -199,7 +198,7 @@ index 226602f..a56a85c 100644 | ||||
|   | ||||
|      switch (p->ptype) { | ||||
|      case CONDPAT_FILE_EXISTS: | ||||
| @@ -4156,7 +4221,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p,
 | ||||
| @@ -4178,7 +4243,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p,
 | ||||
|      char *expanded; | ||||
|   | ||||
|      if (p->forced_mimetype) { | ||||
| @ -208,7 +207,7 @@ index 226602f..a56a85c 100644 | ||||
|   | ||||
|          if (*expanded) { | ||||
|              ap_str_tolower(expanded); | ||||
| @@ -4170,7 +4235,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p,
 | ||||
| @@ -4192,7 +4257,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p,
 | ||||
|      } | ||||
|   | ||||
|      if (p->forced_handler) { | ||||
| @ -217,7 +216,7 @@ index 226602f..a56a85c 100644 | ||||
|   | ||||
|          if (*expanded) { | ||||
|              ap_str_tolower(expanded); | ||||
| @@ -4307,12 +4372,18 @@ static rule_return_type apply_rewrite_rule(rewriterule_entry *p,
 | ||||
| @@ -4329,12 +4394,18 @@ static rule_return_type apply_rewrite_rule(rewriterule_entry *p,
 | ||||
|   | ||||
|      /* expand the result */ | ||||
|      if (!(p->flags & RULEFLAG_NOSUB)) { | ||||
| @ -237,6 +236,7 @@ index 226602f..a56a85c 100644 | ||||
| -            ap_strchr_c(newuri, '?')) {
 | ||||
| +
 | ||||
| +        if (unsafe_qmark > 0) {
 | ||||
|              ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO() | ||||
|              ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10508) | ||||
|                      "Unsafe URL with %%3f URL rewritten without " | ||||
|                      "UnsafeAllow3F"); | ||||
| 
 | ||||
| @ -1,8 +1,8 @@ | ||||
| diff --git a/server/listen.c b/server/listen.c
 | ||||
| index 5242c2a..e2e028a 100644
 | ||||
| index 9577d60..d718db1 100644
 | ||||
| --- a/server/listen.c
 | ||||
| +++ b/server/listen.c
 | ||||
| @@ -34,6 +34,10 @@
 | ||||
| @@ -35,6 +35,10 @@
 | ||||
|  #include <unistd.h> | ||||
|  #endif | ||||
|   | ||||
| @ -13,7 +13,7 @@ index 5242c2a..e2e028a 100644 | ||||
|  /* we know core's module_index is 0 */ | ||||
|  #undef APLOG_MODULE_INDEX | ||||
|  #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX | ||||
| @@ -59,9 +63,12 @@ static int ap_listenbacklog;
 | ||||
| @@ -60,9 +64,12 @@ static int ap_listenbacklog;
 | ||||
|  static int ap_listencbratio; | ||||
|  static int send_buffer_size; | ||||
|  static int receive_buffer_size; | ||||
| @ -27,7 +27,7 @@ index 5242c2a..e2e028a 100644 | ||||
|  { | ||||
|      apr_socket_t *s = server->sd; | ||||
|      int one = 1; | ||||
| @@ -94,20 +101,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
 | ||||
| @@ -95,20 +102,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
 | ||||
|          return stat; | ||||
|      } | ||||
|   | ||||
| @ -48,7 +48,7 @@ index 5242c2a..e2e028a 100644 | ||||
|      /* | ||||
|       * To send data over high bandwidth-delay connections at full | ||||
|       * speed we must force the TCP window to open wide enough to keep the | ||||
| @@ -169,21 +162,37 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
 | ||||
| @@ -170,21 +163,37 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
 | ||||
|      } | ||||
|  #endif | ||||
|   | ||||
| @ -100,7 +100,7 @@ index 5242c2a..e2e028a 100644 | ||||
|      } | ||||
|   | ||||
|  #ifdef WIN32 | ||||
| @@ -315,6 +324,123 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
 | ||||
| @@ -335,6 +344,123 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to,
 | ||||
|      return found; | ||||
|  } | ||||
|   | ||||
| @ -223,8 +223,8 @@ index 5242c2a..e2e028a 100644 | ||||
| +
 | ||||
|  static const char *alloc_listener(process_rec *process, const char *addr, | ||||
|                                    apr_port_t port, const char* proto, | ||||
|                                    void *slave) | ||||
| @@ -495,7 +621,7 @@ static int open_listeners(apr_pool_t *pool)
 | ||||
|                                    const char *scope_id, void *slave, | ||||
| @@ -529,7 +655,7 @@ static int open_listeners(apr_pool_t *pool)
 | ||||
|                  } | ||||
|              } | ||||
|  #endif | ||||
| @ -233,7 +233,7 @@ index 5242c2a..e2e028a 100644 | ||||
|                  ++num_open; | ||||
|              } | ||||
|              else { | ||||
| @@ -607,8 +733,28 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
 | ||||
| @@ -641,8 +767,28 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
 | ||||
|          } | ||||
|      } | ||||
|   | ||||
| @ -264,7 +264,7 @@ index 5242c2a..e2e028a 100644 | ||||
|      } | ||||
|   | ||||
|      for (lr = ap_listeners; lr; lr = lr->next) { | ||||
| @@ -698,7 +844,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
 | ||||
| @@ -732,7 +878,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
 | ||||
|                              duplr->bind_addr); | ||||
|                  return stat; | ||||
|              } | ||||
| @ -273,7 +273,7 @@ index 5242c2a..e2e028a 100644 | ||||
|  #if AP_NONBLOCK_WHEN_MULTI_LISTEN | ||||
|              use_nonblock = (ap_listeners && ap_listeners->next); | ||||
|              stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock); | ||||
| @@ -825,6 +971,11 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
 | ||||
| @@ -859,6 +1005,11 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
 | ||||
|      if (argc < 1 || argc > 2) { | ||||
|          return "Listen requires 1 or 2 arguments."; | ||||
|      } | ||||
| @ -285,7 +285,7 @@ index 5242c2a..e2e028a 100644 | ||||
|   | ||||
|      rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool); | ||||
|      if (rv != APR_SUCCESS) { | ||||
| @@ -856,6 +1007,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
 | ||||
| @@ -894,6 +1045,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
 | ||||
|          ap_str_tolower(proto); | ||||
|      } | ||||
|   | ||||
| @ -295,6 +295,6 @@ index 5242c2a..e2e028a 100644 | ||||
| +    }
 | ||||
| +#endif
 | ||||
| +
 | ||||
|      return alloc_listener(cmd->server->process, host, port, proto, NULL); | ||||
|      return alloc_listener(cmd->server->process, host, port, proto, | ||||
|                            scope_id, NULL, cmd->temp_pool); | ||||
|  } | ||||
|   | ||||
							
								
								
									
										16
									
								
								SOURCES/httpd-2.4.62.tar.bz2.asc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								SOURCES/httpd-2.4.62.tar.bz2.asc
									
									
									
									
									
										Normal file
									
								
							| @ -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----- | ||||
							
								
								
									
										2
									
								
								SOURCES/httpd.sysusers
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								SOURCES/httpd.sysusers
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| g apache 48 | ||||
| u apache 48 "Apache" /usr/share/httpd /sbin/nologin | ||||
							
								
								
									
										195
									
								
								SPECS/httpd.spec
									
									
									
									
									
								
							
							
						
						
									
										195
									
								
								SPECS/httpd.spec
									
									
									
									
									
								
							| @ -12,8 +12,8 @@ | ||||
| 
 | ||||
| Summary: Apache HTTP Server | ||||
| Name: httpd | ||||
| Version: 2.4.57 | ||||
| Release: 11%{?dist}.1 | ||||
| Version: 2.4.62 | ||||
| Release: 1%{?dist} | ||||
| URL: https://httpd.apache.org/ | ||||
| Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2 | ||||
| Source1: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2.asc | ||||
| @ -62,10 +62,11 @@ Source45: config.layout | ||||
| Source46: apachectl.sh | ||||
| Source47: apachectl.xml | ||||
| Source48: apache-poweredby.png | ||||
| Source49: httpd.sysusers | ||||
| 
 | ||||
| # build/scripts patches | ||||
| Patch2: httpd-2.4.43-apxs.patch | ||||
| Patch3: httpd-2.4.43-deplibs.patch | ||||
| Patch3: httpd-2.4.59-deplibs.patch | ||||
| # Needed for socket activation and mod_systemd patch | ||||
| Patch19: httpd-2.4.53-detect-systemd.patch | ||||
| # Features/functional changes | ||||
| @ -74,77 +75,34 @@ Patch22: httpd-2.4.43-mod_systemd.patch | ||||
| Patch23: httpd-2.4.48-export.patch | ||||
| Patch24: httpd-2.4.43-corelimit.patch | ||||
| Patch25: httpd-2.4.57-selinux.patch | ||||
| Patch26: httpd-2.4.57-gettid.patch | ||||
| Patch27: httpd-2.4.53-icons.patch | ||||
| Patch30: httpd-2.4.43-cachehardmax.patch | ||||
| Patch34: httpd-2.4.43-socket-activation.patch | ||||
| Patch38: httpd-2.4.43-sslciphdefault.patch | ||||
| Patch39: httpd-2.4.43-sslprotdefault.patch | ||||
| Patch41: httpd-2.4.43-r1861793+.patch | ||||
| Patch42: httpd-2.4.48-r1828172+.patch | ||||
| Patch45: httpd-2.4.43-logjournal.patch | ||||
| Patch46: httpd-2.4.48-proxy-ws-idle-timeout.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=1949969 | ||||
| Patch47: httpd-2.4.57-pr37355.patch | ||||
| Patch26: httpd-2.4.53-icons.patch | ||||
| Patch27: httpd-2.4.43-cachehardmax.patch | ||||
| Patch28: httpd-2.4.62-socket-activation.patch | ||||
| Patch29: httpd-2.4.43-sslciphdefault.patch | ||||
| Patch30: httpd-2.4.43-sslprotdefault.patch | ||||
| Patch31: httpd-2.4.43-logjournal.patch | ||||
| Patch32: httpd-2.4.48-proxy-ws-idle-timeout.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=1949606 | ||||
| Patch48: httpd-2.4.46-freebind.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=1950021 | ||||
| Patch49: httpd-2.4.48-ssl-proxy-chains.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2004143 | ||||
| Patch50: httpd-2.4.57-r1825120.patch | ||||
| Patch33: httpd-2.4.62-freebind.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2065677 | ||||
| Patch52: httpd-2.4.53-separate-systemd-fns.patch | ||||
| Patch34: httpd-2.4.53-separate-systemd-fns.patch | ||||
| # https://issues.redhat.com/browse/RHEL-5071 | ||||
| Patch53: httpd-2.4.57-r1912477+.patch | ||||
| # https://issues.redhat.com/browse/RHEL-6600 | ||||
| Patch54: httpd-2.4.57-r1912081.patch | ||||
| Patch35: httpd-2.4.57-r1912477+.patch | ||||
| 
 | ||||
| # Bug fixes | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 | ||||
| Patch60: httpd-2.4.43-enable-sslv3.patch | ||||
| Patch61: httpd-2.4.46-htcacheclean-dont-break.patch | ||||
| Patch100: httpd-2.4.43-enable-sslv3.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=1932442 | ||||
| Patch64: httpd-2.4.48-full-release.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=1950011 | ||||
| Patch65: httpd-2.4.51-r1877397.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=1938740 | ||||
| Patch66: httpd-2.4.51-r1892413+.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2073459 | ||||
| Patch67: httpd-2.4.51-r1811831.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2098056 | ||||
| Patch68: httpd-2.4.53-r1878890.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2186645 | ||||
| Patch69: httpd-2.4.57-covscan.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2222001 | ||||
| Patch70: httpd-2.4.57-mod_status-duplicate-key.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2217726 | ||||
| Patch71: httpd-2.4.57-davenoent.patch | ||||
| # https://issues.redhat.com/browse/RHEL-17686 | ||||
| Patch72: httpd-2.4.57-r1884505+.patch | ||||
| Patch101: httpd-2.4.48-full-release.patch | ||||
| # https://bz.apache.org/bugzilla/show_bug.cgi?id=69197 | ||||
| Patch73: httpd-2.4.57-r1919325.patch | ||||
| Patch102: httpd-2.4.62-r1919325.patch | ||||
| 
 | ||||
| # Security fixes | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=... | ||||
| # | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2245332 | ||||
| Patch200: httpd-2.4.57-CVE-2023-31122.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2295016 | ||||
| Patch201: httpd-2.4.57-CVE-2024-38477.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2295022 | ||||
| Patch202: httpd-2.4.57-CVE-2024-39573.patch | ||||
| # CVE-2024-38474 and CVE-2024-38475 fixed in one patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2295013 | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2295014 | ||||
| Patch204: httpd-2.4.57-CVE-2024-38474+.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2295012 | ||||
| Patch206: httpd-2.4.57-CVE-2024-38473.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2295015 | ||||
| Patch207: httpd-2.4.57-CVE-2024-38476.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2297362 | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id=2295761 | ||||
| # part of CVE-2024-38476 fix | ||||
| Patch208: httpd-2.4.57-CVE-2024-39884+.patch | ||||
| # https://bugzilla.redhat.com/show_bug.cgi?id= | ||||
| # Patch200: httpd-2.4.X-CVE-XXXX-YYYYY.patch | ||||
| 
 | ||||
| 
 | ||||
| License: ASL 2.0 | ||||
| BuildRequires: gcc, autoconf, pkgconfig, findutils, xmlto | ||||
| @ -152,13 +110,12 @@ BuildRequires: perl-interpreter, perl-generators, systemd-devel | ||||
| BuildRequires: zlib-devel, libselinux-devel, lua-devel, brotli-devel | ||||
| BuildRequires: apr-devel >= 1.5.0, apr-util-devel >= 1.5.0, pcre-devel >= 5.0 | ||||
| BuildRequires: gnupg2 | ||||
| BuildRequires: systemd-rpm-macros | ||||
| Requires: system-logos-httpd | ||||
| Provides: webserver | ||||
| Requires: httpd-core = 0:%{version}-%{release} | ||||
| Recommends: mod_http2, mod_lua | ||||
| Requires(preun): systemd-units | ||||
| Requires(postun): systemd-units | ||||
| Requires(post): systemd-units | ||||
| %{?systemd_requires} | ||||
| 
 | ||||
| %description | ||||
| The Apache HTTP Server is a powerful, efficient, and extensible | ||||
| @ -208,7 +165,7 @@ also be found at https://httpd.apache.org/docs/2.4/. | ||||
| %package filesystem | ||||
| Summary: The basic directory layout for the Apache HTTP Server | ||||
| BuildArch: noarch | ||||
| Requires(pre): /usr/sbin/useradd | ||||
| %{?sysusers_requires_compat} | ||||
| 
 | ||||
| %description filesystem | ||||
| The httpd-filesystem package contains the basic directory layout | ||||
| @ -287,45 +244,20 @@ written in the Lua programming language. | ||||
| %patch23 -p1 -b .export | ||||
| %patch24 -p1 -b .corelimit | ||||
| %patch25 -p1 -b .selinux | ||||
| %patch26 -p1 -b .gettid | ||||
| %patch27 -p1 -b .icons | ||||
| %patch30 -p1 -b .cachehardmax | ||||
| %patch34 -p1 -b .socketactivation | ||||
| %patch38 -p1 -b .sslciphdefault | ||||
| %patch39 -p1 -b .sslprotdefault | ||||
| %patch41 -p1 -b .r1861793+ | ||||
| %patch42 -p1 -b .r1828172+ | ||||
| %patch45 -p1 -b .logjournal | ||||
| %patch46 -p1 -b .proxy-ws-idle-timeout | ||||
| %patch47 -p1 -b .pr37355 | ||||
| %patch48 -p1 -b .freebind | ||||
| %patch49 -p1 -b .ssl-proxy-chains | ||||
| %patch50 -p1 -b .r1825120 | ||||
| %patch52 -p1 -b .separatesystemd | ||||
| %patch53 -p1 -b .r1912477+ | ||||
| %patch54 -p1 -b .r1912081 | ||||
| %patch26 -p1 -b .icons | ||||
| %patch27 -p1 -b .cachehardmax | ||||
| %patch28 -p1 -b .socketactivation | ||||
| %patch29 -p1 -b .sslciphdefault | ||||
| %patch30 -p1 -b .sslprotdefault | ||||
| %patch31 -p1 -b .logjournal | ||||
| %patch32 -p1 -b .proxy-ws-idle-timeout | ||||
| %patch33 -p1 -b .freebind | ||||
| %patch34 -p1 -b .separatesystemd | ||||
| %patch35 -p1 -b .r1912477+ | ||||
| 
 | ||||
| %patch60 -p1 -b .enable-sslv3 | ||||
| %patch61 -p1 -b .htcacheclean-dont-break | ||||
| %patch64 -p1 -b .full-release | ||||
| %patch65 -p1 -b .r1877397 | ||||
| %patch66 -p1 -b .r1892413+ | ||||
| %patch67 -p1 -b .r1811831 | ||||
| %patch68 -p1 -b .r1878890 | ||||
| %patch69 -p1 -b .covstan | ||||
| %patch70 -p1 -b .duplicate-key | ||||
| %patch71 -p1 -b .davenoent | ||||
| %patch72 -p1 -b .r1884505+ | ||||
| 
 | ||||
| %patch200 -p1 -b .CVE-2023-31122 | ||||
| %patch201 -p1 -b .CVE-2024-38477 | ||||
| %patch202 -p1 -b .CVE-2024-39573 | ||||
| %patch204 -p1 -b .CVE-2024-38474+ | ||||
| # CVE-2024-38474 regression fix | ||||
| %patch73 -p1 -b .r1919325 | ||||
| %patch206 -p1 -b .CVE-2024-38473 | ||||
| %patch207 -p1 -b .CVE-2024-38476 | ||||
| %patch208 -p1 -b .CVE-2024-39884+ | ||||
| %patch100 -p1 -b .enable-sslv3 | ||||
| %patch101 -p1 -b .full-release | ||||
| %patch102 -p1 -b .r1919325 | ||||
| 
 | ||||
| # Patch in the vendor string | ||||
| sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h | ||||
| @ -651,6 +583,9 @@ touch -r $RPM_BUILD_ROOT%{_bindir}/apxs \ | ||||
|       $RPM_BUILD_ROOT%{_libdir}/httpd/build/vendor-apxs | ||||
| chmod 755 $RPM_BUILD_ROOT%{_libdir}/httpd/build/vendor-apxs | ||||
| 
 | ||||
| # Fix content dir in sysusers file and install it | ||||
| install -p -D -m 0644 %{SOURCE49} %{buildroot}%{_sysusersdir}/httpd.conf | ||||
| 
 | ||||
| # Remove unpackaged files | ||||
| rm -vf \ | ||||
|       $RPM_BUILD_ROOT%{_libdir}/*.exp \ | ||||
| @ -666,11 +601,8 @@ rm -vf \ | ||||
| rm -rf $RPM_BUILD_ROOT/etc/httpd/conf/{original,extra} | ||||
| 
 | ||||
| %pre filesystem | ||||
| getent group apache >/dev/null || groupadd -g 48 -r apache | ||||
| getent passwd apache >/dev/null || \ | ||||
|   useradd -r -u 48 -g apache -s /sbin/nologin \ | ||||
|     -d %{contentdir} -c "Apache" apache | ||||
| exit 0 | ||||
| %sysusers_create_compat %{SOURCE49} | ||||
| 
 | ||||
| 
 | ||||
| %post | ||||
| %systemd_post httpd.service htcacheclean.service httpd.socket | ||||
| @ -834,6 +766,7 @@ exit $rv | ||||
| %dir %{contentdir}/icons | ||||
| %attr(755,root,root) %dir %{_unitdir}/httpd.service.d | ||||
| %attr(755,root,root) %dir %{_unitdir}/httpd.socket.d | ||||
| %{_sysusersdir}/httpd.conf | ||||
| 
 | ||||
| %files tools | ||||
| %{_bindir}/* | ||||
| @ -886,23 +819,37 @@ exit $rv | ||||
| %{_rpmconfigdir}/macros.d/macros.httpd | ||||
| 
 | ||||
| %changelog | ||||
| * Mon Aug 05 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.57-11.1 | ||||
| - Resolves: RHEL-46047 - httpd: Security issues via backend applications whose | ||||
|   response headers are malicious or exploitable (CVE-2024-38476) | ||||
| - Resolves: RHEL-53021 - Regression introduced by CVE-2024-38474 fix | ||||
| * Sat Aug 03 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.62-1 | ||||
| - new version 2.4.62 | ||||
| - Resolves: RHEL-52724 - Regression introduced by CVE-2024-38474 fix | ||||
| 
 | ||||
| * Thu Jul 04 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.57-11 | ||||
| - Resolves: RHEL-45792 -  httpd: Encoding problem in | ||||
|   mod_proxy (CVE-2024-38473) | ||||
| * Fri Jul 19 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.59-7 | ||||
| - Resolves: RHEL-49856: htcacheclean.service missing [Install] section | ||||
| 
 | ||||
| * Wed Jul 03 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.57-9 | ||||
| - Resolves: RHEL-45766 -  httpd: null pointer dereference in | ||||
|   mod_proxy (CVE-2024-38477) | ||||
| - Resolves: RHEL-45749 - httpd: Potential SSRF in mod_rewrite (CVE-2024-39573) | ||||
| - Resolves: RHEL-45818 - httpd: Substitution encoding issue in | ||||
|   mod_rewrite (CVE-2024-38474) | ||||
| - Resolves: RHEL-45771 - httpd: Improper escaping of output in | ||||
|   mod_rewrite (CVE-2024-38475) | ||||
| * Thu May 30 2024 Joe Orton <jorton@redhat.com> - 2.4.59-6 | ||||
| - mod_ssl: restore SSL_OP_NO_RENEGOTIATE support | ||||
|   Related: RHEL-14668 | ||||
| 
 | ||||
| * Tue May 21 2024 Joe Orton <jorton@redhat.com> - 2.4.59-5 | ||||
| - mod_ssl: defer ENGINE_finish() calls to a cleanup | ||||
|   Resolves: RHEL-36755 | ||||
| 
 | ||||
| * Mon May 20 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.59-4 | ||||
| - Resolves: RHEL-6575 - [RFE] httpd use systemd-sysusers | ||||
| 
 | ||||
| * Wed May 08 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.59-3 | ||||
| - Related: RHEL-14668 - RFE: httpd rebase to 2.4.59 | ||||
| 
 | ||||
| * Wed May  8 2024 Joe Orton <jorton@redhat.com> - 2.4.59-2 | ||||
| - Resolves: RHEL-35870 - httpd mod_cgi/cgid unification | ||||
| 
 | ||||
| * Fri May 03 2024 Luboš Uhliarik <luhliari@redhat.com> - 2.4.59-1 | ||||
| - new version 2.4.59 | ||||
| - Resolves: RHEL-14668 - RFE: httpd rebase to 2.4.59 | ||||
| - Resolves: RHEL-31856 - httpd: HTTP response splitting | ||||
|   (CVE-2023-38709) | ||||
| - Resolves: RHEL-31859 - httpd: HTTP Response Splitting in multiple | ||||
|   modules (CVE-2024-24795) | ||||
| 
 | ||||
| * Wed Feb  7 2024 Joe Orton <jorton@redhat.com> - 2.4.57-8 | ||||
| - mod_xml2enc: fix media type handling | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user