12 Commits

Author SHA256 Message Date
d082bdaab8 Accepting request 1325323 from Apache
OBS-URL: https://build.opensuse.org/request/show/1325323
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=223
2026-01-06 16:41:57 +00:00
1238d9e94c - Include a sane HTTPD_SYSCONFIG_FILE env. variable when invoking
/usr/sbin/httpd.
  The appropriate MPM was not being located when calling /usr/sbin/httpd
  directly.
- Rename event's 'mod_cgi' to 'mod_cgid' in loadmodule.conf, as that's what
  the event MPM ships.

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=733
2026-01-04 21:20:48 +00:00
b26dd5fe1e Accepting request 1321637 from Apache
OBS-URL: https://build.opensuse.org/request/show/1321637
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=222
2025-12-10 14:29:37 +00:00
5051842ca9 - version update to 2.4.66
*) SECURITY: CVE-2025-66200: Apache HTTP Server: mod_userdir+suexec
     bypass via AllowOverride FileInfo (cve.mitre.org)
     mod_userdir+suexec bypass via AllowOverride FileInfo
     vulnerability in Apache HTTP Server. Users with access to use
     the RequestHeader directive in htaccess can cause some CGI
     scripts to run under an unexpected userid.
     This issue affects Apache HTTP Server: from 2.4.7 through
     2.4.65.
  *) SECURITY: CVE-2025-65082: Apache HTTP Server: CGI environment
     variable override (cve.mitre.org)
     Improper Neutralization of Escape, Meta, or Control Sequences
     vulnerability in Apache HTTP Server through environment
     variables set via the Apache configuration unexpectedly
     superseding variables calculated by the server for CGI programs.
     This issue affects Apache HTTP Server from 2.4.0 through 2.4.65.
  *) SECURITY: CVE-2025-59775: Apache HTTP Server: NTLM Leakage on
     Windows through UNC SSRF (cve.mitre.org)
     Server-Side Request Forgery (SSRF) vulnerability
     Â in Apache HTTP Server on Windows
     with AllowEncodedSlashes On and MergeSlashes Off  allows to
     potentially leak NTLM
     hashes to a malicious server via SSRF and malicious requests or
     content
  *) SECURITY: CVE-2025-58098: Apache HTTP Server: Server Side
     Includes adds query string to #exec cmd=... (cve.mitre.org)
     Apache HTTP Server 2.4.65 and earlier with Server Side Includes
     (SSI) enabled and mod_cgid (but not mod_cgi) passes the
     shell-escaped query string to #exec cmd="..." directives.
     This issue affects Apache HTTP Server before 2.4.66.
  *) SECURITY: CVE-2025-55753: Apache HTTP Server: mod_md (ACME),
     unintended retry intervals (cve.mitre.org)
     An integer overflow in the case of failed ACME certificate
     renewal leads, after a number of failures (~30 days in default
     configurations), to the backoff timer becoming 0. Attempts to
     renew the certificate then are repeated without delays until it
     succeeds.
     This issue affects Apache HTTP Server: from 2.4.30 before 2.4.66.
  *) mod_http2: Fix handling of 304 responses from mod_cache.
  *) mod_http2/mod_proxy_http2: fix a bug in calculating the log2 value of
     integers, used in push diaries and proxy window size calculations.
  *) mod_md: update to version 2.6.5
     - New directive `MDInitialDelay`, controlling how longer to wait after
       a server restart before checking certificates for renewal.
       [Michael Kaufmann]
     - Hardening: when build with OpenSSL older than 1.0.2 or old libressl
       versions, the parsing of ASN.1 time strings did not do a length check.
     - Hardening: when reading back OCSP responses stored in the local JSON
       store, missing 'valid' key led to uninitialized values, resulting in
       wrong refresh behaviour.
  *) mod_md: update to version 2.6.6
     - Fix a small memory leak when using OpenSSL's BIGNUMs.
     - Fix reuse of curl easy handles by resetting them.
  *) mod_http2: update to version 2.0.35
     New directive `H2MaxStreamErrors` to control how much bad behaviour
     by clients is tolerated before the connection is closed.
  *) mod_proxy_http2: add support for ProxyErrorOverride directive.
  *) mpm_common: Add new ListenTCPDeferAccept directive that allows to specify
     the value set for the TCP_DEFER_ACCEPT socket option on listen sockets.
  *) mod_ssl: Add SSLVHostSNIPolicy directive to control the virtual
     host compatibility policy.
  *) mod_md: update to version 2.6.2
     - Fix error retry delay calculation to not already doubling the wait
       on the first error.
  *) mod_md: update to version 2.6.1
     - Increasing default `MDRetryDelay` to 30 seconds to generate less bursty
       traffic on errored renewals for the ACME CA. This leads to error retries
        of 30s, 1 minute, 2, 4, etc. up to daily attempts.
     - Checking that configuring `MDRetryDelay` will result in a positive
       duration. A delay of 0 is not accepted.
     - Fix a bug in checking Content-Type of responses from the ACME server.
     - Added ACME ARI support (rfc9773) to the module. Enabled by default. New
       directive "MDRenewViaARI on|off" for controlling this.
     - Removing tailscale support. It has not been working for a long time
       as the company decided to change their APIs. Away with the dead code,
       documentation and tests.
     - Fixed a compilation issue with pre-industrial versions of libcurl.
- httpd testsuite of svn revision 1929573

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=731
2025-12-08 20:36:56 +00:00
27da36009c Accepting request 1317188 from Apache
Automatic submission by obs-autosubmit

OBS-URL: https://build.opensuse.org/request/show/1317188
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=221
2025-11-13 16:25:57 +00:00
e9e8bec142 - Make /usr/sbin/httpd a dedicated script again, this fixes building modules
while still making Apache free of update-alternatives, relying entirely
  on sysconfig to dispatch the appropriate MPM.

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=729
2025-11-04 20:43:03 +00:00
829550ca66 - Ensure the mpm subpackages sync their rebuild counter with the
main package to have the installations work reliably.

Otherwise, things like
https://build.opensuse.org/package/show/openSUSE:Factory:zSystems/apache2
can happen; apache2 had more rebuilds than the MPMs and thus we can end up with
 unresolvable: nothing provides (apache2-prefork = 2.4.65-3.4 if apache2-prefork) needed by apache2

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=728
2025-11-04 18:42:23 +00:00
fb07bcc3b6 Accepting request 1314067 from Apache
Automatic submission by obs-autosubmit

OBS-URL: https://build.opensuse.org/request/show/1314067
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=220
2025-10-30 16:09:35 +00:00
74bf3248c9 - Re-introduce /usr/sbin/httpd
- Links to start_apache2, which now contains the logic to dispatch
  to the appropriate MPM respecting sysconfig's decision.

OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=726
2025-10-21 11:32:54 +00:00
2d2e6834bc Accepting request 1311136 from home:mschreiner:branches:Apache
- Migrate from update-alternatives (bsc#1245830).
- The APACHE_MPM environment variable now controls which MPM will be used.
  If an empty string is provided, the script-helpers file implements its own logic
  to pick an MPM from the currently installed ones.
  As at least one MPM is always required, this will work just fine.

OBS-URL: https://build.opensuse.org/request/show/1311136
OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=725
2025-10-13 20:58:48 +00:00
043857b216 Accepting request 1308207 from Apache
Automatic submission by obs-autosubmit

OBS-URL: https://build.opensuse.org/request/show/1308207
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/apache2?expand=0&rev=219
2025-10-02 17:19:19 +00:00
a3d1b861c4 Accepting request 1306753 from home:pgajdos:libxml2
- httpd testsuite of svn revision 1928711, fixes the failure
  caused by libxml2 version update to 2.14

OBS-URL: https://build.opensuse.org/request/show/1306753
OBS-URL: https://build.opensuse.org/package/show/Apache/apache2?expand=0&rev=723
2025-09-23 14:02:23 +00:00
27 changed files with 326 additions and 5727 deletions

View File

@@ -1,303 +0,0 @@
From a7a9d814c7c23e990283277230ddd5a9efec27c7 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 11:59:38 +0000
Subject: [PATCH] fix header merging
Reviewed By: rpluem, jorton, ylavic
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927039 13f79535-47bb-0310-9956-ffa450edef68
---
modules/http/http_filters.c | 248 +++++++++++++++++++-----------------
1 file changed, 128 insertions(+), 120 deletions(-)
Index: httpd-2.4.58/modules/http/http_filters.c
===================================================================
--- httpd-2.4.58.orig/modules/http/http_filters.c
+++ httpd-2.4.58/modules/http/http_filters.c
@@ -1300,107 +1300,10 @@ typedef struct header_filter_ctx {
int headers_sent;
} header_filter_ctx;
-AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
- apr_bucket_brigade *b)
+static void merge_response_headers(request_rec *r, const char **protocol)
{
- request_rec *r = f->r;
- conn_rec *c = r->connection;
- const char *clheader;
- int header_only = (r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status));
- const char *protocol = NULL;
- apr_bucket *e;
- apr_bucket_brigade *b2;
- header_struct h;
- header_filter_ctx *ctx = f->ctx;
- const char *ctype;
- ap_bucket_error *eb = NULL;
- apr_status_t rv = APR_SUCCESS;
- int recursive_error = 0;
-
- AP_DEBUG_ASSERT(!r->main);
-
- if (!ctx) {
- ctx = f->ctx = apr_pcalloc(r->pool, sizeof(header_filter_ctx));
- }
- else if (ctx->headers_sent) {
- /* Eat body if response must not have one. */
- if (header_only) {
- /* Still next filters may be waiting for EOS, so pass it (alone)
- * when encountered and be done with this filter.
- */
- e = APR_BRIGADE_LAST(b);
- if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
- APR_BUCKET_REMOVE(e);
- apr_brigade_cleanup(b);
- APR_BRIGADE_INSERT_HEAD(b, e);
- ap_remove_output_filter(f);
- rv = ap_pass_brigade(f->next, b);
- }
- apr_brigade_cleanup(b);
- return rv;
- }
- }
-
- for (e = APR_BRIGADE_FIRST(b);
- e != APR_BRIGADE_SENTINEL(b);
- e = APR_BUCKET_NEXT(e))
- {
- if (AP_BUCKET_IS_ERROR(e) && !eb) {
- eb = e->data;
- continue;
- }
- /*
- * If we see an EOC bucket it is a signal that we should get out
- * of the way doing nothing.
- */
- if (AP_BUCKET_IS_EOC(e)) {
- ap_remove_output_filter(f);
- return ap_pass_brigade(f->next, b);
- }
- }
-
- if (!ctx->headers_sent && !check_headers(r)) {
- /* We may come back here from ap_die() below,
- * so clear anything from this response.
- */
- apr_table_clear(r->headers_out);
- apr_table_clear(r->err_headers_out);
- r->content_type = r->content_encoding = NULL;
- r->content_languages = NULL;
- r->clength = r->chunked = 0;
- apr_brigade_cleanup(b);
-
- /* Don't recall ap_die() if we come back here (from its own internal
- * redirect or error response), otherwise we can end up in infinite
- * recursion; better fall through with 500, minimal headers and an
- * empty body (EOS only).
- */
- if (!check_headers_recursion(r)) {
- ap_die(HTTP_INTERNAL_SERVER_ERROR, r);
- return AP_FILTER_ERROR;
- }
- r->status = HTTP_INTERNAL_SERVER_ERROR;
- e = ap_bucket_eoc_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(b, e);
- e = apr_bucket_eos_create(c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(b, e);
- ap_set_content_length(r, 0);
- recursive_error = 1;
- }
- else if (eb) {
- int status;
- status = eb->status;
- apr_brigade_cleanup(b);
- ap_die(status, r);
- return AP_FILTER_ERROR;
- }
-
- if (r->assbackwards) {
- r->sent_bodyct = 1;
- ap_remove_output_filter(f);
- rv = ap_pass_brigade(f->next, b);
- goto out;
- }
+ const char *ctype = NULL;
+ const char *clheader = NULL;
/*
* Now that we are ready to send a response, we need to combine the two
@@ -1430,6 +1333,9 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
fixup_vary(r);
}
+ /* determine the protocol and whether we should use keepalives. */
+ basic_http_header_check(r, protocol);
+ ap_set_keepalive(r);
/*
* Control cachability for non-cacheable responses if not already set by
@@ -1449,10 +1355,6 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
apr_table_unset(r->headers_out, "ETag");
}
- /* determine the protocol and whether we should use keepalives. */
- basic_http_header_check(r, &protocol);
- ap_set_keepalive(r);
-
/* 204/304 responses don't have content related headers */
if (AP_STATUS_IS_HEADER_ONLY(r->status)) {
apr_table_unset(r->headers_out, "Transfer-Encoding");
@@ -1520,30 +1422,136 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
&& conf->http_cl_head_zero != AP_HTTP_CL_HEAD_ZERO_ENABLE) {
apr_table_unset(r->headers_out, "Content-Length");
}
+}
- b2 = apr_brigade_create(r->pool, c->bucket_alloc);
- basic_http_header(r, b2, protocol);
-
- h.pool = r->pool;
- h.bb = b2;
+AP_CORE_DECLARE_NONSTD(apr_status_t) ap_http_header_filter(ap_filter_t *f,
+ apr_bucket_brigade *b)
+{
+ request_rec *r = f->r;
+ conn_rec *c = r->connection;
+ int header_only = (r->header_only || AP_STATUS_IS_HEADER_ONLY(r->status));
+ apr_bucket *e;
+ apr_bucket_brigade *b2;
+ header_struct h;
+ header_filter_ctx *ctx = f->ctx;
+ ap_bucket_error *eb = NULL;
+ apr_status_t rv = APR_SUCCESS;
+ int recursive_error = 0;
+ const char *protocol;
- send_all_header_fields(&h, r);
+ AP_DEBUG_ASSERT(!r->main);
- terminate_header(b2);
+ if (!ctx) {
+ ctx = f->ctx = apr_pcalloc(r->pool, sizeof(header_filter_ctx));
+ }
+ else if (ctx->headers_sent) {
+ /* Eat body if response must not have one. */
+ if (header_only) {
+ /* Still next filters may be waiting for EOS, so pass it (alone)
+ * when encountered and be done with this filter.
+ */
+ e = APR_BRIGADE_LAST(b);
+ if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
+ APR_BUCKET_REMOVE(e);
+ apr_brigade_cleanup(b);
+ APR_BRIGADE_INSERT_HEAD(b, e);
+ ap_remove_output_filter(f);
+ rv = ap_pass_brigade(f->next, b);
+ }
+ apr_brigade_cleanup(b);
+ return rv;
+ }
+ }
- if (header_only) {
- e = APR_BRIGADE_LAST(b);
- if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
- APR_BUCKET_REMOVE(e);
- APR_BRIGADE_INSERT_TAIL(b2, e);
+ for (e = APR_BRIGADE_FIRST(b);
+ e != APR_BRIGADE_SENTINEL(b);
+ e = APR_BUCKET_NEXT(e))
+ {
+ if (AP_BUCKET_IS_ERROR(e) && !eb) {
+ eb = e->data;
+ continue;
+ }
+ /*
+ * If we see an EOC bucket it is a signal that we should get out
+ * of the way doing nothing.
+ */
+ if (AP_BUCKET_IS_EOC(e)) {
ap_remove_output_filter(f);
+ return ap_pass_brigade(f->next, b);
+ }
+ }
+
+ if (!ctx->headers_sent) {
+ merge_response_headers(r, &protocol);
+ if (!check_headers(r)) {
+ /* We may come back here from ap_die() below,
+ * so clear anything from this response.
+ */
+ apr_table_clear(r->headers_out);
+ apr_table_clear(r->err_headers_out);
+ r->content_type = r->content_encoding = NULL;
+ r->content_languages = NULL;
+ r->clength = r->chunked = 0;
+ apr_brigade_cleanup(b);
+
+ /* Don't recall ap_die() if we come back here (from its own internal
+ * redirect or error response), otherwise we can end up in infinite
+ * recursion; better fall through with 500, minimal headers and an
+ * empty body (EOS only).
+ */
+ if (!check_headers_recursion(r)) {
+ ap_die(HTTP_INTERNAL_SERVER_ERROR, r);
+ return AP_FILTER_ERROR;
+ }
+ r->status = HTTP_INTERNAL_SERVER_ERROR;
+ e = ap_bucket_eoc_create(c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(b, e);
+ e = apr_bucket_eos_create(c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(b, e);
+ ap_set_content_length(r, 0);
+ recursive_error = 1;
+ }
+ else if (eb) {
+ int status;
+ status = eb->status;
+ apr_brigade_cleanup(b);
+ ap_die(status, r);
+ return AP_FILTER_ERROR;
}
- apr_brigade_cleanup(b);
}
- rv = ap_pass_brigade(f->next, b2);
- apr_brigade_cleanup(b2);
- ctx->headers_sent = 1;
+ if (r->assbackwards) {
+ r->sent_bodyct = 1;
+ ap_remove_output_filter(f);
+ rv = ap_pass_brigade(f->next, b);
+ goto out;
+ }
+
+ if (!ctx->headers_sent) {
+ b2 = apr_brigade_create(r->pool, c->bucket_alloc);
+ basic_http_header(r, b2, protocol);
+
+ h.pool = r->pool;
+ h.bb = b2;
+
+ send_all_header_fields(&h, r);
+
+ terminate_header(b2);
+
+ if (header_only) {
+ e = APR_BRIGADE_LAST(b);
+ if (e != APR_BRIGADE_SENTINEL(b) && APR_BUCKET_IS_EOS(e)) {
+ APR_BUCKET_REMOVE(e);
+ APR_BRIGADE_INSERT_TAIL(b2, e);
+ ap_remove_output_filter(f);
+ }
+ apr_brigade_cleanup(b);
+ }
+
+ rv = ap_pass_brigade(f->next, b2);
+ apr_brigade_cleanup(b2);
+ ctx->headers_sent = 1;
+ }
if (rv != APR_SUCCESS || header_only) {
goto out;

View File

@@ -1,37 +0,0 @@
From b3d3ded288815bea063c3bf77dd80b26446f76ce Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 12:01:02 +0000
Subject: [PATCH] backport 1927032 from trunk
header only
Reviewed By: rpluem, jorton, ylavic
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927040 13f79535-47bb-0310-9956-ffa450edef68
---
modules/metadata/mod_headers.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: httpd-2.4.51/modules/metadata/mod_headers.c
===================================================================
--- httpd-2.4.51.orig/modules/metadata/mod_headers.c
+++ httpd-2.4.51/modules/metadata/mod_headers.c
@@ -783,14 +783,14 @@ static int do_headers_fixup(request_rec
break;
case hdr_set:
if (!ap_cstr_casecmp(hdr->header, "Content-Type")) {
- ap_set_content_type_ex(r, process_tags(hdr, r), 1);
+ ap_set_content_type(r, process_tags(hdr, r));
}
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_ex(r, process_tags(hdr, r), 1);
+ ap_set_content_type(r, process_tags(hdr, r));
}
apr_table_setn(headers, hdr->header, process_tags(hdr, r));
}

View File

@@ -1,44 +0,0 @@
From c01e60707048be14a510f0a92128a5227923215c Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 12:03:42 +0000
Subject: [PATCH] backport 1927034 from trunk
escape ssl vars
Reviewed By: rpluem, jorton, covener, ylavic
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927042 13f79535-47bb-0310-9956-ffa450edef68
---
modules/ssl/ssl_engine_vars.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c
index 418d849e00e..4060c0f6a63 100644
--- a/modules/ssl/ssl_engine_vars.c
+++ b/modules/ssl/ssl_engine_vars.c
@@ -1208,8 +1208,9 @@ static const char *ssl_var_log_handler_c(request_rec *r, char *a)
result = "-";
else if (strEQ(a, "errstr"))
result = (char *)sslconn->verify_error;
- if (result != NULL && result[0] == NUL)
- result = NULL;
+ if (result) {
+ result = *result ? ap_escape_logitem(r->pool, result) : NULL;
+ }
return result;
}
@@ -1222,8 +1223,9 @@ static const char *ssl_var_log_handler_x(request_rec *r, char *a)
char *result;
result = ssl_var_lookup(r->pool, r->server, r->connection, r, a);
- if (result != NULL && result[0] == NUL)
- result = NULL;
+ if (result) {
+ result = *result ? ap_escape_logitem(r->pool, result) : NULL;
+ }
return result;
}

View File

@@ -1,62 +0,0 @@
From c4cfa50c9068e8b8134c530ab21674e77d1278a2 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 12:04:49 +0000
Subject: [PATCH] backport 1927035 from trunk
update SNI validation
Reviewed By: rpluem, jorton, covener, ylavic
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927043 13f79535-47bb-0310-9956-ffa450edef68
---
modules/ssl/ssl_engine_kernel.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index 9c510218441..d912a874dd9 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -371,19 +371,6 @@ int ssl_hook_ReadReq(request_rec *r)
" provided in HTTP request", servername);
return HTTP_BAD_REQUEST;
}
- if (r->server != handshakeserver
- && !ssl_server_compatible(sslconn->server, r->server)) {
- /*
- * The request does not select the virtual host that was
- * selected by the SNI and its SSL parameters are different
- */
-
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02032)
- "Hostname %s provided via SNI and hostname %s provided"
- " via HTTP have no compatible SSL setup",
- servername, r->hostname);
- return HTTP_MISDIRECTED_REQUEST;
- }
}
else if (((sc->strict_sni_vhost_check == SSL_ENABLED_TRUE)
|| hssc->strict_sni_vhost_check == SSL_ENABLED_TRUE)
@@ -404,6 +391,21 @@ int ssl_hook_ReadReq(request_rec *r)
"which is required to access this server.<br />\n");
return HTTP_FORBIDDEN;
}
+ if (r->server != handshakeserver
+ && !ssl_server_compatible(sslconn->server, r->server)) {
+ /*
+ * The request does not select the virtual host that was
+ * selected for handshaking and its SSL parameters are different
+ */
+
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02032)
+ "Hostname %s %s and hostname %s provided"
+ " via HTTP have no compatible SSL setup",
+ servername ? servername : handshakeserver->server_hostname,
+ servername ? "provided via SNI" : "(default host as no SNI was provided)",
+ r->hostname);
+ return HTTP_MISDIRECTED_REQUEST;
+ }
}
#endif
modssl_set_app_data2(ssl, r);

View File

@@ -1,39 +0,0 @@
From 88304321841a2fe8bd5eacc70e69418b0b545ca5 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 12:05:49 +0000
Subject: [PATCH] backport 1927036 from trunk
tolerate missing host header in h2 proxy
Reviewed By: jorton, icing, rpluem
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927044 13f79535-47bb-0310-9956-ffa450edef68
---
modules/http2/h2_proxy_session.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/modules/http2/h2_proxy_session.c b/modules/http2/h2_proxy_session.c
index d5d0f9bc6bc..2cfbb5f5d4b 100644
--- a/modules/http2/h2_proxy_session.c
+++ b/modules/http2/h2_proxy_session.c
@@ -850,6 +850,18 @@ static apr_status_t open_stream(h2_proxy_session *session, const char *url,
dconf = ap_get_module_config(r->per_dir_config, &proxy_module);
if (dconf->preserve_host) {
authority = orig_host;
+ if (!authority) {
+ /* Duplicate mod_proxy behaviour if ProxyPreserveHost is
+ * used but an "HTTP/0.9" request is received without a
+ * Host: header */
+ authority = r->server->server_hostname;
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(10511)
+ "HTTP/0.9 request (with no host line) "
+ "on incoming request and preserve host set "
+ "forcing hostname to be %s for uri %s",
+ authority, r->uri);
+ apr_table_setn(r->headers_in, "Host", authority);
+ }
}
else {
authority = puri.hostname;

View File

@@ -1,198 +0,0 @@
From 87a7351c755c9ef8ab386e3090e44838c2a06d48 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 12:09:30 +0000
Subject: [PATCH] backport 1927037 from trunk
remove antiquated 'SSLEngine optional' TLS upgrade
Reviewed By: rpluem, jorton, covener
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927045 13f79535-47bb-0310-9956-ffa450edef68
---
modules/ssl/ssl_engine_config.c | 6 ++-
modules/ssl/ssl_engine_init.c | 6 +--
modules/ssl/ssl_engine_kernel.c | 86 ---------------------------------
modules/ssl/ssl_private.h | 1 -
4 files changed, 7 insertions(+), 92 deletions(-)
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
index 9af6f70fd03..d1f4fad8e23 100644
--- a/modules/ssl/ssl_engine_config.c
+++ b/modules/ssl/ssl_engine_config.c
@@ -741,11 +741,13 @@ const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg)
return NULL;
}
else if (!strcasecmp(arg, "Optional")) {
- sc->enabled = SSL_ENABLED_OPTIONAL;
+ sc->enabled = SSL_ENABLED_FALSE;
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, cmd->server, APLOGNO(10510)
+ "'SSLEngine optional' is no longer supported");
return NULL;
}
- return "Argument must be On, Off, or Optional";
+ return "Argument must be On or Off";
}
const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag)
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index f9eca79e462..94cc2772e01 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -427,7 +427,7 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
&ssl_module);
sc = mySrvConfig(s);
- if (sc->enabled == SSL_ENABLED_TRUE || sc->enabled == SSL_ENABLED_OPTIONAL) {
+ if (sc->enabled == SSL_ENABLED_TRUE) {
if ((rv = ssl_run_init_server(s, p, 0, sc->server->ssl_ctx)) != APR_SUCCESS) {
return rv;
}
@@ -2126,9 +2126,9 @@ apr_status_t ssl_init_ConfigureServer(server_rec *s,
&ssl_module);
apr_status_t rv;
- /* Initialize the server if SSL is enabled or optional.
+ /* Initialize the server if SSL is enabled.
*/
- if ((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL)) {
+ if (sc->enabled == SSL_ENABLED_TRUE) {
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01914)
"Configuring server %s for SSL protocol", sc->vhost_id);
if ((rv = ssl_init_server_ctx(s, p, ptemp, sc, pphrases))
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index d912a874dd9..33aa1f71dc7 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -38,59 +38,6 @@ static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn);
static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s);
#endif
-#define SWITCH_STATUS_LINE "HTTP/1.1 101 Switching Protocols"
-#define UPGRADE_HEADER "Upgrade: TLS/1.0, HTTP/1.1"
-#define CONNECTION_HEADER "Connection: Upgrade"
-
-/* Perform an upgrade-to-TLS for the given request, per RFC 2817. */
-static apr_status_t upgrade_connection(request_rec *r)
-{
- struct conn_rec *conn = r->connection;
- apr_bucket_brigade *bb;
- SSLConnRec *sslconn;
- apr_status_t rv;
- SSL *ssl;
-
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02028)
- "upgrading connection to TLS");
-
- bb = apr_brigade_create(r->pool, conn->bucket_alloc);
-
- rv = ap_fputs(conn->output_filters, bb, SWITCH_STATUS_LINE CRLF
- UPGRADE_HEADER CRLF CONNECTION_HEADER CRLF CRLF);
- if (rv == APR_SUCCESS) {
- APR_BRIGADE_INSERT_TAIL(bb,
- apr_bucket_flush_create(conn->bucket_alloc));
- rv = ap_pass_brigade(conn->output_filters, bb);
- }
-
- if (rv) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02029)
- "failed to send 101 interim response for connection "
- "upgrade");
- return rv;
- }
-
- ssl_init_ssl_connection(conn, r);
-
- sslconn = myConnConfig(conn);
- ssl = sslconn->ssl;
-
- /* Perform initial SSL handshake. */
- SSL_set_accept_state(ssl);
- SSL_do_handshake(ssl);
-
- if (!SSL_is_init_finished(ssl)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02030)
- "TLS upgrade handshake failed");
- ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
-
- return APR_ECONNABORTED;
- }
-
- return APR_SUCCESS;
-}
-
/* Perform a speculative (and non-blocking) read from the connection
* filters for the given request, to determine whether there is any
* pending data to read. Return non-zero if there is, else zero. */
@@ -270,40 +217,17 @@ int ssl_hook_ReadReq(request_rec *r)
{
SSLSrvConfigRec *sc = mySrvConfig(r->server);
SSLConnRec *sslconn;
- const char *upgrade;
#ifdef HAVE_TLSEXT
const char *servername;
#endif
SSL *ssl;
- /* Perform TLS upgrade here if "SSLEngine optional" is configured,
- * SSL is not already set up for this connection, and the client
- * has sent a suitable Upgrade header. */
- if (sc->enabled == SSL_ENABLED_OPTIONAL && !myConnConfig(r->connection)
- && (upgrade = apr_table_get(r->headers_in, "Upgrade")) != NULL
- && ap_find_token(r->pool, upgrade, "TLS/1.0")) {
- if (upgrade_connection(r)) {
- return AP_FILTER_ERROR;
- }
- }
-
/* If we are on a slave connection, we do not expect to have an SSLConnRec,
* but our master connection might. */
sslconn = myConnConfig(r->connection);
if (!(sslconn && sslconn->ssl) && r->connection->master) {
sslconn = myConnConfig(r->connection->master);
}
-
- /* If "SSLEngine optional" is configured, this is not an SSL
- * connection, and this isn't a subrequest, send an Upgrade
- * response header. Note this must happen before map_to_storage
- * and OPTIONS * request processing is completed.
- */
- if (sc->enabled == SSL_ENABLED_OPTIONAL && !(sslconn && sslconn->ssl)
- && !r->main) {
- apr_table_setn(r->headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
- apr_table_mergen(r->headers_out, "Connection", "upgrade");
- }
if (!sslconn) {
return DECLINED;
@@ -1238,16 +1162,6 @@ int ssl_hook_Access(request_rec *r)
* Support for SSLRequireSSL directive
*/
if (dc->bSSLRequired && !ssl) {
- if ((sc->enabled == SSL_ENABLED_OPTIONAL) && !r->connection->master) {
- /* This vhost was configured for optional SSL, just tell the
- * client that we need to upgrade.
- */
- apr_table_setn(r->err_headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
- apr_table_setn(r->err_headers_out, "Connection", "Upgrade");
-
- return HTTP_UPGRADE_REQUIRED;
- }
-
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02219)
"access to %s failed, reason: %s",
r->filename, "SSL connection required");
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index fb9edaa5eeb..794e51aa937 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -526,7 +526,6 @@ typedef enum {
SSL_ENABLED_UNSET = UNSET,
SSL_ENABLED_FALSE = 0,
SSL_ENABLED_TRUE = 1,
- SSL_ENABLED_OPTIONAL = 3
} ssl_enabled_t;
/**

View File

@@ -1,496 +0,0 @@
From ef98f4f494ff2f99d736a3716cd31219688b46f5 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 7 Jul 2025 12:12:49 +0000
Subject: [PATCH] backport 1927038 from trunk
improve h2 header error handling
Rewviewed By: icing, covener, rpluem
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1927046 13f79535-47bb-0310-9956-ffa450edef68
---
modules/http2/h2_request.c | 12 ++--
modules/http2/h2_request.h | 8 ++-
modules/http2/h2_session.c | 31 ++++++++-
modules/http2/h2_session.h | 3 +
modules/http2/h2_stream.c | 69 ++++++++++++-------
modules/http2/h2_util.c | 51 ++++++++------
modules/http2/h2_util.h | 11 ++-
test/modules/http2/test_200_header_invalid.py | 4 +-
8 files changed, 130 insertions(+), 59 deletions(-)
diff --git a/modules/http2/h2_request.c b/modules/http2/h2_request.c
index 2713947c377..6373e0a244d 100644
--- a/modules/http2/h2_request.c
+++ b/modules/http2/h2_request.c
@@ -64,18 +64,20 @@ typedef struct {
apr_table_t *headers;
apr_pool_t *pool;
apr_status_t status;
+ h2_hd_scratch *scratch;
} h1_ctx;
static int set_h1_header(void *ctx, const char *key, const char *value)
{
h1_ctx *x = ctx;
int was_added;
- h2_req_add_header(x->headers, x->pool, key, strlen(key), value, strlen(value), 0, &was_added);
+ h2_req_add_header(x->headers, x->pool, key, strlen(key),
+ value, strlen(value), x->scratch, &was_added);
return 1;
}
apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool,
- request_rec *r)
+ request_rec *r, h2_hd_scratch *scratch)
{
h2_request *req;
const char *scheme, *authority, *path;
@@ -125,6 +127,7 @@ apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool,
x.pool = pool;
x.headers = req->headers;
x.status = APR_SUCCESS;
+ x.scratch = scratch;
apr_table_do(set_h1_header, &x, r->headers_in, NULL);
*preq = req;
@@ -134,7 +137,8 @@ apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool,
apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
const char *name, size_t nlen,
const char *value, size_t vlen,
- size_t max_field_len, int *pwas_added)
+ struct h2_hd_scratch *scratch,
+ int *pwas_added)
{
apr_status_t status = APR_SUCCESS;
@@ -185,7 +189,7 @@ apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
else {
/* non-pseudo header, add to table */
status = h2_req_add_header(req->headers, pool, name, nlen, value, vlen,
- max_field_len, pwas_added);
+ scratch, pwas_added);
}
return status;
diff --git a/modules/http2/h2_request.h b/modules/http2/h2_request.h
index 7e20b697246..ae6b6a2510c 100644
--- a/modules/http2/h2_request.h
+++ b/modules/http2/h2_request.h
@@ -19,17 +19,21 @@
#include "h2.h"
+struct h2_hd_scratch;
+
h2_request *h2_request_create(int id, apr_pool_t *pool, const char *method,
const char *scheme, const char *authority,
const char *path, apr_table_t *header);
apr_status_t h2_request_rcreate(h2_request **preq, apr_pool_t *pool,
- request_rec *r);
+ request_rec *r,
+ struct h2_hd_scratch *scratch);
apr_status_t h2_request_add_header(h2_request *req, apr_pool_t *pool,
const char *name, size_t nlen,
const char *value, size_t vlen,
- size_t max_field_len, int *pwas_added);
+ struct h2_hd_scratch *scratch,
+ int *pwas_added);
apr_status_t h2_request_add_trailer(h2_request *req, apr_pool_t *pool,
const char *name, size_t nlen,
diff --git a/modules/http2/h2_session.c b/modules/http2/h2_session.c
index fc8b6119ae8..a5f1872bc20 100644
--- a/modules/http2/h2_session.c
+++ b/modules/http2/h2_session.c
@@ -109,13 +109,29 @@ static void cleanup_unprocessed_streams(h2_session *session)
h2_mplx_c1_streams_do(session->mplx, rst_unprocessed_stream, session);
}
+/* APR callback invoked if allocation fails. */
+static int abort_on_oom(int retcode)
+{
+ ap_abort_on_oom();
+ return retcode; /* unreachable, hopefully. */
+}
+
static h2_stream *h2_session_open_stream(h2_session *session, int stream_id,
int initiated_on)
{
h2_stream * stream;
+ apr_allocator_t *allocator;
apr_pool_t *stream_pool;
+ apr_status_t rv;
- apr_pool_create(&stream_pool, session->pool);
+ rv = apr_allocator_create(&allocator);
+ if (rv != APR_SUCCESS)
+ return NULL;
+
+ apr_allocator_max_free_set(allocator, ap_max_mem_free);
+ apr_pool_create_ex(&stream_pool, session->pool, NULL, allocator);
+ apr_allocator_owner_set(allocator, stream_pool);
+ apr_pool_abort_set(abort_on_oom, stream_pool);
apr_pool_tag(stream_pool, "h2_stream");
stream = h2_stream_create(stream_id, stream_pool, session,
@@ -972,6 +988,14 @@ apr_status_t h2_session_create(h2_session **psession, conn_rec *c, request_rec *
}
h2_c1_io_init(&session->io, session);
+ /* setup request header scratch buffers */
+ session->hd_scratch.max_len = session->s->limit_req_fieldsize?
+ session->s->limit_req_fieldsize : 8190;
+ session->hd_scratch.name =
+ apr_pcalloc(session->pool, session->hd_scratch.max_len + 1);
+ session->hd_scratch.value =
+ apr_pcalloc(session->pool, session->hd_scratch.max_len + 1);
+
session->padding_max = h2_config_sgeti(s, H2_CONF_PADDING_BITS);
if (session->padding_max) {
session->padding_max = (0x01 << session->padding_max) - 1;
@@ -1032,7 +1056,7 @@ apr_status_t h2_session_create(h2_session **psession, conn_rec *c, request_rec *
n = h2_config_sgeti(s, H2_CONF_PUSH_DIARY_SIZE);
session->push_diary = h2_push_diary_create(session->pool, n);
-
+
if (APLOGcdebug(c)) {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
H2_SSSN_LOG(APLOGNO(03200), session,
@@ -1699,9 +1723,10 @@ static void on_stream_state_enter(void *ctx, h2_stream *stream)
break;
case H2_SS_CLEANUP:
nghttp2_session_set_stream_user_data(session->ngh2, stream->id, NULL);
+ update_child_status(session, SERVER_BUSY_WRITE, "done", stream);
h2_mplx_c1_stream_cleanup(session->mplx, stream, &session->open_streams);
+ stream = NULL;
++session->streams_done;
- update_child_status(session, SERVER_BUSY_WRITE, "done", stream);
break;
default:
break;
diff --git a/modules/http2/h2_session.h b/modules/http2/h2_session.h
index 2c8f334cce0..7932a9e2ccf 100644
--- a/modules/http2/h2_session.h
+++ b/modules/http2/h2_session.h
@@ -29,6 +29,7 @@
*/
#include "h2.h"
+#include "h2_util.h"
struct apr_thread_mutext_t;
struct apr_thread_cond_t;
@@ -118,6 +119,8 @@ typedef struct h2_session {
struct h2_iqueue *out_c1_blocked; /* all streams with output blocked on c1 buffer full */
struct h2_iqueue *ready_to_process; /* all streams ready for processing */
+ h2_hd_scratch hd_scratch;
+
} h2_session;
const char *h2_session_state_str(h2_session_state state);
diff --git a/modules/http2/h2_stream.c b/modules/http2/h2_stream.c
index 35b53860c03..f8214019404 100644
--- a/modules/http2/h2_stream.c
+++ b/modules/http2/h2_stream.c
@@ -659,7 +659,8 @@ apr_status_t h2_stream_set_request_rec(h2_stream *stream,
if (stream->rst_error) {
return APR_ECONNRESET;
}
- status = h2_request_rcreate(&req, stream->pool, r);
+ status = h2_request_rcreate(&req, stream->pool, r,
+ &stream->session->hd_scratch);
if (status == APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, status, r,
H2_STRM_LOG(APLOGNO(03058), stream,
@@ -691,13 +692,11 @@ static void set_error_response(h2_stream *stream, int http_status)
static apr_status_t add_trailer(h2_stream *stream,
const char *name, size_t nlen,
const char *value, size_t vlen,
- size_t max_field_len, int *pwas_added)
+ h2_hd_scratch *scratch)
{
conn_rec *c = stream->session->c1;
- char *hname, *hvalue;
const char *existing;
- *pwas_added = 0;
if (nlen == 0 || name[0] == ':') {
ap_log_cerror(APLOG_MARK, APLOG_DEBUG, APR_EINVAL, c,
H2_STRM_LOG(APLOGNO(03060), stream,
@@ -710,20 +709,35 @@ static apr_status_t add_trailer(h2_stream *stream,
if (!stream->trailers_in) {
stream->trailers_in = apr_table_make(stream->pool, 5);
}
- hname = apr_pstrndup(stream->pool, name, nlen);
- h2_util_camel_case_header(hname, nlen);
- existing = apr_table_get(stream->trailers_in, hname);
- if (max_field_len
- && ((existing? strlen(existing)+2 : 0) + vlen + nlen + 2 > max_field_len)) {
- /* "key: (oldval, )?nval" is too long */
+
+ if (((nlen + vlen + 2) > scratch->max_len))
return APR_EINVAL;
+
+ /* We need 0-terminated strings to operate on apr_table */
+ AP_DEBUG_ASSERT(nlen < scratch->max_len);
+ memcpy(scratch->name, name, nlen);
+ scratch->name[nlen] = 0;
+ AP_DEBUG_ASSERT(vlen < scratch->max_len);
+ memcpy(scratch->value, value, vlen);
+ scratch->value[vlen] = 0;
+
+ existing = apr_table_get(stream->trailers_in, scratch->name);
+ if(existing) {
+ if (!vlen) /* not adding a 0-length value to existing */
+ return APR_SUCCESS;
+ if ((strlen(existing) + 2 + vlen + nlen + 2 > scratch->max_len)) {
+ /* "name: existing, value" is too long */
+ return APR_EINVAL;
+ }
+ apr_table_merge(stream->trailers_in, scratch->name, scratch->value);
}
- if (!existing) *pwas_added = 1;
- hvalue = apr_pstrndup(stream->pool, value, vlen);
- apr_table_mergen(stream->trailers_in, hname, hvalue);
- ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
- H2_STRM_MSG(stream, "added trailer '%s: %s'"), hname, hvalue);
-
+ else {
+ h2_util_camel_case_header(scratch->name, nlen);
+ apr_table_set(stream->trailers_in, scratch->name, scratch->value);
+ }
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
+ H2_STRM_MSG(stream, "added trailer '%s: %s'"),
+ scratch->name, scratch->value);
return APR_SUCCESS;
}
@@ -732,7 +746,7 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
const char *value, size_t vlen)
{
h2_session *session = stream->session;
- int error = 0, was_added = 0;
+ int error = 0;
apr_status_t status = APR_SUCCESS;
H2_STRM_ASSERT_MAGIC(stream, H2_STRM_MAGIC_OK);
@@ -760,6 +774,7 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
++stream->request_headers_added;
}
else if (H2_SS_IDLE == stream->state) {
+ int was_added;
if (!stream->rtmp) {
if (H2_STREAM_CLIENT_INITIATED(stream->id)) {
++stream->session->remote.emitted_count;
@@ -771,7 +786,7 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
}
status = h2_request_add_header(stream->rtmp, stream->pool,
name, nlen, value, vlen,
- session->s->limit_req_fieldsize, &was_added);
+ &session->hd_scratch, &was_added);
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, status, session->c1,
H2_STRM_MSG(stream, "add_header: '%.*s: %.*s"),
(int)nlen, name, (int)vlen, value);
@@ -779,8 +794,8 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
}
else if (H2_SS_OPEN == stream->state) {
status = add_trailer(stream, name, nlen, value, vlen,
- session->s->limit_req_fieldsize, &was_added);
- if (was_added) ++stream->request_headers_added;
+ &session->hd_scratch);
+ if (!status) ++stream->request_headers_added;
}
else {
status = APR_EINVAL;
@@ -789,16 +804,17 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
if (APR_EINVAL == status) {
/* header too long */
- if (!h2_stream_is_ready(stream)) {
+ if (!h2_stream_is_ready(stream) && !stream->request_headers_failed) {
ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, session->c1,
- H2_STRM_LOG(APLOGNO(10180), stream,"Request header exceeds "
- "LimitRequestFieldSize: %.*s"),
+ H2_STRM_LOG(APLOGNO(10180), stream,
+ "Request header exceeds LimitRequestFieldSize(%d): %.*s"),
+ (int)session->hd_scratch.max_len,
(int)H2MIN(nlen, 80), name);
}
error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE;
goto cleanup;
}
-
+
if (session->s->limit_req_fields > 0
&& stream->request_headers_added > session->s->limit_req_fields) {
/* too many header lines */
@@ -810,12 +826,13 @@ apr_status_t h2_stream_add_header(h2_stream *stream,
if (!h2_stream_is_ready(stream)) {
ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, session->c1,
H2_STRM_LOG(APLOGNO(10181), stream, "Number of request headers "
- "exceeds LimitRequestFields"));
+ "exceeds LimitRequestFields(%d)"),
+ (int)session->s->limit_req_fields);
}
error = HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE;
goto cleanup;
}
-
+
cleanup:
if (error) {
++stream->request_headers_failed;
diff --git a/modules/http2/h2_util.c b/modules/http2/h2_util.c
index 8e53cebdf92..605c348ca12 100644
--- a/modules/http2/h2_util.c
+++ b/modules/http2/h2_util.c
@@ -1693,10 +1693,9 @@ int h2_ignore_resp_trailer(const char *name, size_t len)
}
static apr_status_t req_add_header(apr_table_t *headers, apr_pool_t *pool,
- nghttp2_nv *nv, size_t max_field_len,
+ nghttp2_nv *nv, h2_hd_scratch *scratch,
int *pwas_added)
{
- char *hname, *hvalue;
const char *existing;
*pwas_added = 0;
@@ -1712,15 +1711,14 @@ static apr_status_t req_add_header(apr_table_t *headers, apr_pool_t *pool,
/* Cookie header come separately in HTTP/2, but need
* to be merged by "; " (instead of default ", ")
*/
- if (max_field_len
- && strlen(existing) + nv->valuelen + nv->namelen + 4
- > max_field_len) {
+ if ((strlen(existing) + nv->valuelen + nv->namelen + 4)
+ > scratch->max_len) {
/* "key: oldval, nval" is too long */
return APR_EINVAL;
}
- hvalue = apr_pstrndup(pool, (const char*)nv->value, nv->valuelen);
apr_table_setn(headers, "Cookie",
- apr_psprintf(pool, "%s; %s", existing, hvalue));
+ apr_psprintf(pool, "%s; %.*s", existing,
+ (int)nv->valuelen, nv->value));
return APR_SUCCESS;
}
}
@@ -1731,27 +1729,40 @@ static apr_status_t req_add_header(apr_table_t *headers, apr_pool_t *pool,
}
}
- hname = apr_pstrndup(pool, (const char*)nv->name, nv->namelen);
- h2_util_camel_case_header(hname, nv->namelen);
- existing = apr_table_get(headers, hname);
- if (max_field_len) {
- if ((existing? strlen(existing)+2 : 0) + nv->valuelen + nv->namelen + 2
- > max_field_len) {
- /* "key: (oldval, )?nval" is too long */
+ if (((nv->namelen + nv->valuelen + 2) > scratch->max_len))
+ return APR_EINVAL;
+
+ /* We need 0-terminated strings to operate on apr_table */
+ AP_DEBUG_ASSERT(nv->namelen < scratch->max_len);
+ memcpy(scratch->name, nv->name, nv->namelen);
+ scratch->name[nv->namelen] = 0;
+ AP_DEBUG_ASSERT(nv->valuelen < scratch->max_len);
+ memcpy(scratch->value, nv->value, nv->valuelen);
+ scratch->value[nv->valuelen] = 0;
+
+ *pwas_added = 1;
+ existing = apr_table_get(headers, scratch->name);
+ if (existing) {
+ if (!nv->valuelen) /* not adding a 0-length value to existing */
+ return APR_SUCCESS;
+ if ((strlen(existing) + 2 + nv->valuelen + nv->namelen + 2)
+ > scratch->max_len) {
+ /* "name: existing, value" is too long */
return APR_EINVAL;
}
+ apr_table_merge(headers, scratch->name, scratch->value);
+ }
+ else {
+ h2_util_camel_case_header(scratch->name, nv->namelen);
+ apr_table_set(headers, scratch->name, scratch->value);
}
- if (!existing) *pwas_added = 1;
- hvalue = apr_pstrndup(pool, (const char*)nv->value, nv->valuelen);
- apr_table_mergen(headers, hname, hvalue);
-
return APR_SUCCESS;
}
apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool,
const char *name, size_t nlen,
const char *value, size_t vlen,
- size_t max_field_len, int *pwas_added)
+ h2_hd_scratch *scratch, int *pwas_added)
{
nghttp2_nv nv;
@@ -1759,7 +1770,7 @@ apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool,
nv.namelen = nlen;
nv.value = (uint8_t*)value;
nv.valuelen = vlen;
- return req_add_header(headers, pool, &nv, max_field_len, pwas_added);
+ return req_add_header(headers, pool, &nv, scratch, pwas_added);
}
/*******************************************************************************
diff --git a/modules/http2/h2_util.h b/modules/http2/h2_util.h
index d2e6548ba87..c2cab4afa45 100644
--- a/modules/http2/h2_util.h
+++ b/modules/http2/h2_util.h
@@ -397,14 +397,21 @@ apr_status_t h2_req_create_ngheader(h2_ngheader **ph, apr_pool_t *p,
const struct h2_request *req);
#endif
+typedef struct h2_hd_scratch {
+ size_t max_len; /* header field size name + ': ' + value */
+ char *name; /* max_len+1 sized */
+ char *value; /* max_len+1 sized */
+
+} h2_hd_scratch;
+
/**
* Add a HTTP/2 header and return the table key if it really was added
* and not ignored.
*/
-apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool,
+apr_status_t h2_req_add_header(apr_table_t *headers, apr_pool_t *pool,
const char *name, size_t nlen,
const char *value, size_t vlen,
- size_t max_field_len, int *pwas_added);
+ h2_hd_scratch *scratch, int *pwas_added);
/*******************************************************************************
* apr brigade helpers
diff --git a/test/modules/http2/test_200_header_invalid.py b/test/modules/http2/test_200_header_invalid.py
index 6b73301c282..1687e3d9818 100644
--- a/test/modules/http2/test_200_header_invalid.py
+++ b/test/modules/http2/test_200_header_invalid.py
@@ -133,7 +133,7 @@ def test_h2_200_11(self, env):
assert 431 == r.response["status"]
# test header field count, LimitRequestFields (default 100)
- # see #201: several headers with same name are mered and count only once
+ # see #201: several headers with same name are merged and counted
def test_h2_200_12(self, env):
url = env.mkurl("https", "cgi", "/")
opt = []
@@ -143,7 +143,7 @@ def test_h2_200_12(self, env):
r = env.curl_get(url, options=opt)
assert r.response["status"] == 200
r = env.curl_get(url, options=(opt + ["-H", "y: 2"]))
- assert r.response["status"] == 200
+ assert r.response["status"] == 431
# test header field count, LimitRequestFields (default 100)
# different header names count each

View File

@@ -1,203 +0,0 @@
From ab9dd8e2cfe7d62efe5ff8925fbef1de756a2fc2 Mon Sep 17 00:00:00 2001
From: Stefan Eissing <icing@apache.org>
Date: Thu, 20 Nov 2025 13:00:23 +0000
Subject: [PATCH] Merged /httpd/httpd/trunk:r1929514,1929883
Update mod_md to v2.6.6
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1929884 13f79535-47bb-0310-9956-ffa450edef68
---
STATUS | 8 --------
changes-entries/md_v2.6.5.txt | 9 +++++++++
changes-entries/md_v2.6.6.txt | 3 +++
docs/manual/mod/mod_md.xml | 17 +++++++++++++++++
modules/md/md_crypt.c | 10 +++++++---
modules/md/md_curl.c | 14 ++++++++------
modules/md/md_ocsp.c | 3 ++-
modules/md/md_version.h | 4 ++--
modules/md/mod_md_config.c | 21 +++++++++++++++++++++
modules/md/mod_md_config.h | 1 +
modules/md/mod_md_drive.c | 2 +-
11 files changed, 71 insertions(+), 21 deletions(-)
create mode 100644 changes-entries/md_v2.6.5.txt
create mode 100644 changes-entries/md_v2.6.6.txt
Index: httpd-2.4.63/changes-entries/md_v2.6.5.txt
===================================================================
--- /dev/null
+++ httpd-2.4.63/changes-entries/md_v2.6.5.txt
@@ -0,0 +1,9 @@
+ *) mod_md: update to version 2.6.5
+ - New directive `MDInitialDelay`, controlling how longer to wait after
+ a server restart before checking certificates for renewal.
+ [Michael Kaufmann]
+ - Hardening: when build with OpenSSL older than 1.0.2 or old libressl
+ versions, the parsing of ASN.1 time strings did not do a length check.
+ - Hardening: when reading back OCSP responses stored in the local JSON
+ store, missing 'valid' key led to uninitialized values, resulting in
+ wrong refresh behaviour.
Index: httpd-2.4.63/changes-entries/md_v2.6.6.txt
===================================================================
--- /dev/null
+++ httpd-2.4.63/changes-entries/md_v2.6.6.txt
@@ -0,0 +1,3 @@
+ *) mod_md: update to version 2.6.6
+ - Fix a small memory leak when using OpenSSL's BIGNUMs. [Theo Buehler]
+ - Fix reuse of curl easy handles by resetting them. [Michael Kaufmann]
Index: httpd-2.4.63/modules/md/md_crypt.c
===================================================================
--- httpd-2.4.63.orig/modules/md/md_crypt.c
+++ httpd-2.4.63/modules/md/md_crypt.c
@@ -198,7 +198,7 @@ static int pem_passwd(char *buf, int siz
/* Get the apr time (micro seconds, since 1970) from an ASN1 time, as stored in X509
* certificates. OpenSSL now has a utility function, but other *SSL derivatives have
- * not caughts up yet or chose to ignore. An alternative is implemented, we prefer
+ * not caught up yet or chose to ignore. An alternative is implemented, we prefer
* however the *SSL to maintain such things.
*/
static apr_time_t md_asn1_time_get(const ASN1_TIME* time)
@@ -212,6 +212,10 @@ static apr_time_t md_asn1_time_get(const
const char* str = (const char*) time->data;
apr_size_t i = 0;
+ if ((time->length < 12) || (
+ (time->type == V_ASN1_GENERALIZEDTIME) && time->length < 16))
+ return 0;
+
memset(&t, 0, sizeof(t));
if (time->type == V_ASN1_UTCTIME) {/* two digit year */
@@ -1188,7 +1192,7 @@ const char *md_cert_get_serial_number(co
serial = BN_bn2hex(bn);
s = apr_pstrdup(p, serial);
OPENSSL_free((void*)serial);
- OPENSSL_free((void*)bn);
+ BN_free(bn);
}
return s;
}
Index: httpd-2.4.63/modules/md/md_curl.c
===================================================================
--- httpd-2.4.63.orig/modules/md/md_curl.c
+++ httpd-2.4.63/modules/md/md_curl.c
@@ -253,17 +253,19 @@ static apr_status_t internals_setup(md_h
rv = APR_EGENERAL;
goto leave;
}
- curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb);
- curl_easy_setopt(curl, CURLOPT_HEADERDATA, NULL);
- curl_easy_setopt(curl, CURLOPT_READFUNCTION, req_data_cb);
- curl_easy_setopt(curl, CURLOPT_READDATA, NULL);
- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, resp_data_cb);
- curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
}
else {
md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, req->pool, "reusing curl instance from http");
+ curl_easy_reset(curl);
}
+ curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_cb);
+ curl_easy_setopt(curl, CURLOPT_HEADERDATA, NULL);
+ curl_easy_setopt(curl, CURLOPT_READFUNCTION, req_data_cb);
+ curl_easy_setopt(curl, CURLOPT_READDATA, NULL);
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, resp_data_cb);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
+
internals = apr_pcalloc(req->pool, sizeof(*internals));
internals->curl = curl;
Index: httpd-2.4.63/modules/md/md_ocsp.c
===================================================================
--- httpd-2.4.63.orig/modules/md/md_ocsp.c
+++ httpd-2.4.63/modules/md/md_ocsp.c
@@ -190,6 +190,7 @@ static apr_status_t ostat_from_json(md_o
md_timeperiod_t valid;
apr_status_t rv = APR_ENOENT;
+ memset(&valid, 0, sizeof(valid));
memset(resp_der, 0, sizeof(*resp_der));
memset(resp_valid, 0, sizeof(*resp_valid));
s = md_json_dups(p, json, MD_KEY_VALID, MD_KEY_FROM, NULL);
@@ -531,7 +532,7 @@ static const char *certid_summary(const
bn = ASN1_INTEGER_to_BN(aserial, NULL);
s = BN_bn2hex(bn);
serial = apr_pstrdup(p, s);
- OPENSSL_free((void*)bn);
+ BN_free(bn);
OPENSSL_free((void*)s);
}
return apr_psprintf(p, "certid[der=%s, issuer=%s, key=%s, serial=%s]",
Index: httpd-2.4.63/modules/md/mod_md_config.c
===================================================================
--- httpd-2.4.63.orig/modules/md/mod_md_config.c
+++ httpd-2.4.63/modules/md/mod_md_config.c
@@ -84,6 +84,7 @@ static md_mod_conf_t defmc = {
"crt.sh", /* default cert checker site name */
"https://crt.sh?q=", /* default cert checker site url */
NULL, /* CA cert file to use */
+ APR_TIME_C(0), /* initial cert check delay */
apr_time_from_sec(MD_SECS_PER_DAY/2), /* default time between cert checks */
apr_time_from_sec(5), /* minimum delay for retries */
13, /* retry_failover after 14 errors, with 5s delay ~ half a day */
@@ -625,6 +626,24 @@ static const char *md_config_set_base_se
return set_on_off(&config->mc->manage_base_server, value, cmd->pool);
}
+static const char *md_config_set_initial_delay(cmd_parms *cmd, void *dc, const char *value)
+{
+ md_srv_conf_t *config = md_config_get(cmd->server);
+ const char *err = md_conf_check_location(cmd, MD_LOC_NOT_MD);
+ apr_time_t delay;
+
+ (void)dc;
+ if (err) return err;
+ if (md_duration_parse(&delay, value, "s") != APR_SUCCESS) {
+ return "unrecognized duration format";
+ }
+ if (delay < 0) {
+ return "initial delay must not be negative";
+ }
+ config->mc->initial_delay = delay;
+ return NULL;
+}
+
static const char *md_config_set_check_interval(cmd_parms *cmd, void *dc, const char *value)
{
md_srv_conf_t *config = md_config_get(cmd->server);
@@ -1323,6 +1342,8 @@ const command_rec md_cmds[] = {
"Configure locking of store for updates."),
AP_INIT_TAKE1("MDMatchNames", md_config_set_match_mode, NULL, RSRC_CONF,
"Determines how DNS names are matched to vhosts."),
+ AP_INIT_TAKE1("MDInitialDelay", md_config_set_initial_delay, NULL, RSRC_CONF,
+ "How long to delay the first certificate check."),
AP_INIT_TAKE1("MDCheckInterval", md_config_set_check_interval, NULL, RSRC_CONF,
"Time between certificate checks."),
AP_INIT_TAKE1(NULL, NULL, NULL, RSRC_CONF, NULL)
Index: httpd-2.4.63/modules/md/mod_md_config.h
===================================================================
--- httpd-2.4.63.orig/modules/md/mod_md_config.h
+++ httpd-2.4.63/modules/md/mod_md_config.h
@@ -75,6 +75,7 @@ struct md_mod_conf_t {
const char *cert_check_name; /* name of the linked certificate check site */
const char *cert_check_url; /* url "template for" checking a certificate */
const char *ca_certs; /* root certificates to use for connections */
+ apr_time_t initial_delay; /* how long to delay the first cert renewal check */
apr_time_t check_interval; /* duration between cert renewal checks */
apr_time_t min_delay; /* minimum delay for retries */
int retry_failover; /* number of errors to trigger CA failover */
Index: httpd-2.4.63/modules/md/mod_md_drive.c
===================================================================
--- httpd-2.4.63.orig/modules/md/mod_md_drive.c
+++ httpd-2.4.63/modules/md/mod_md_drive.c
@@ -346,7 +346,7 @@ apr_status_t md_renew_start_watching(md_
"create md renew watchdog(%s)", MD_RENEW_WATCHDOG_NAME);
return rv;
}
- rv = wd_register_callback(dctx->watchdog, 0, dctx, run_watchdog);
+ rv = wd_register_callback(dctx->watchdog, mc->initial_delay, dctx, run_watchdog);
ap_log_error(APLOG_MARK, rv? APLOG_CRIT : APLOG_DEBUG, rv, s, APLOGNO(10067)
"register md renew watchdog(%s)", MD_RENEW_WATCHDOG_NAME);
return rv;

View File

@@ -1,35 +0,0 @@
From ecc1b8f3817e3dcab9c1f24f905752d3c0a279af Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 1 Dec 2025 12:00:14 +0000
Subject: [PATCH] don't pass args for SSI request
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1930161 13f79535-47bb-0310-9956-ffa450edef68
---
modules/generators/mod_cgid.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c
index b27dd802d80..94ad7ee8733 100644
--- a/modules/generators/mod_cgid.c
+++ b/modules/generators/mod_cgid.c
@@ -239,7 +239,7 @@ static char **create_argv(apr_pool_t *p, char *path, char *user, char *group,
char *w;
int idx = 0;
- if (!(*args) || ap_strchr_c(args, '=')) {
+ if (!args || !(*args) || ap_strchr_c(args, '=')) {
numwords = 0;
}
else {
@@ -932,7 +932,10 @@ static int cgid_server(void *data)
apr_pool_userdata_set(r, ERRFN_USERDATA_KEY, apr_pool_cleanup_null, ptrans);
}
- argv = (const char * const *)create_argv(r->pool, NULL, NULL, NULL, argv0, r->args);
+ /* Do not pass args in case of SSI requests */
+ argv = (const char * const *)create_argv(r->pool, NULL, NULL, NULL,
+ argv0,
+ cgid_req.req_type == SSI_REQ ? NULL : r->args);
/* We want to close sd2 for the new CGI process too.
* If it is left open it'll make ap_pass_brigade() block

View File

@@ -1,63 +0,0 @@
From e4f00c5eb71d8a7aa1f52b5279832986f669d463 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 1 Dec 2025 12:03:12 +0000
Subject: [PATCH] envvars from HTTP headers low precedence
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1930163 13f79535-47bb-0310-9956-ffa450edef68
---
server/util_script.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/server/util_script.c b/server/util_script.c
index 72175e75824..6a18aec8c90 100644
--- a/server/util_script.c
+++ b/server/util_script.c
@@ -126,6 +126,8 @@ AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
}
}
for (i = 0; i < env_arr->nelts; ++i) {
+ int changed = 0;
+
if (!elts[i].key) {
continue;
}
@@ -133,18 +135,36 @@ AP_DECLARE(char **) ap_create_environment(apr_pool_t *p, apr_table_t *t)
whack = env[j];
if (apr_isdigit(*whack)) {
*whack++ = '_';
+ changed = 1;
}
while (*whack != '=') {
#ifdef WIN32
- if (!apr_isalnum(*whack) && *whack != '(' && *whack != ')') {
+ if (!apr_isalnum(*whack) && *whack != '_' && *whack != '(' && *whack != ')') {
#else
- if (!apr_isalnum(*whack)) {
+ if (!apr_isalnum(*whack) && *whack != '_') {
#endif
*whack = '_';
+ changed = 1;
}
++whack;
}
- ++j;
+ if (changed) {
+ *whack = '\0';
+ /*
+ * If after cleaning up the key the key is identical to an existing key
+ * in the table drop this environment variable. This also prevents
+ * to override CGI reserved environment variables with variables whose
+ * names have an invalid character instead of '_', but are otherwise
+ * equal to the names CGI reserved environment variables.
+ */
+ if (!apr_table_get(t, env[j])) {
+ ++j;
+ *whack = '=';
+ }
+ }
+ else {
+ ++j;
+ }
}
env[j] = NULL;

View File

@@ -1,39 +0,0 @@
From 9d26b95787b229a3f6195d7beead774d131eeda1 Mon Sep 17 00:00:00 2001
From: Eric Covener <covener@apache.org>
Date: Mon, 1 Dec 2025 12:04:29 +0000
Subject: [PATCH] don't use request notes for suexec
also, stop accepting the obscure "note" option in
RequestHeader, it is only documented/described as being
meant for Header (output filter).
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1930164 13f79535-47bb-0310-9956-ffa450edef68
---
modules/mappers/mod_userdir.c | 4 ++--
modules/metadata/mod_headers.c | 6 +++++-
2 files changed, 7 insertions(+), 3 deletions(-)
Index: httpd-2.4.63/modules/mappers/mod_userdir.c
===================================================================
--- httpd-2.4.63.orig/modules/mappers/mod_userdir.c
+++ httpd-2.4.63/modules/mappers/mod_userdir.c
@@ -334,7 +334,7 @@ static int translate_userdir(request_rec
r->finfo = statbuf;
/* For use in the get_suexec_identity phase */
- apr_table_setn(r->notes, "mod_userdir_user", user);
+ ap_set_module_config(r->request_config, &userdir_module, (void *)user);
return OK;
}
@@ -348,7 +348,7 @@ static ap_unix_identity_t *get_suexec_id
{
ap_unix_identity_t *ugid = NULL;
#if APR_HAS_USER
- const char *username = apr_table_get(r->notes, "mod_userdir_user");
+ const char *username = (const char*) ap_get_module_config(r->request_config, &userdir_module);
if (username == NULL) {
return NULL;

View File

@@ -1,8 +1,8 @@
Index: httpd-framework/t/conf/extra.conf.in
Index: httpd-2.4.64/httpd-framework/t/conf/extra.conf.in
===================================================================
--- a/httpd-framework/t/conf/extra.conf.in 2020-06-15 10:43:26.156701553 +0200
+++ b/httpd-framework/t/conf/extra.conf.in 2020-06-15 10:46:16.141693081 +0200
@@ -875,6 +875,7 @@ LimitRequestFields 32
--- httpd-2.4.64.orig/httpd-framework/t/conf/extra.conf.in
+++ httpd-2.4.64/httpd-framework/t/conf/extra.conf.in
@@ -983,6 +983,7 @@ LimitRequestFields 32
</IfModule>
</Directory>
<Directory @SERVERROOT@/htdocs/modules/filter/bytype>

View File

@@ -1,8 +1,8 @@
Index: httpd-framework/t/ssl/varlookup.t
Index: httpd-2.4.64/httpd-framework/t/ssl/varlookup.t
===================================================================
--- a/httpd-framework/t/ssl/varlookup.t 2016-10-25 14:30:54.250707932 +0200
+++ b/httpd-framework/t/ssl/varlookup.t 2016-10-27 15:38:52.440667690 +0200
@@ -210,9 +210,7 @@ SSL_SERVER_S_DN_UID
--- httpd-2.4.64.orig/httpd-framework/t/ssl/varlookup.t
+++ httpd-2.4.64/httpd-framework/t/ssl/varlookup.t
@@ -227,9 +227,7 @@ SSL_SERVER_S_DN_UID
SSL_CLIENT_S_DN_Email "$client_dn{$email_field}"
SSL_SERVER_S_DN_Email "$server_dn{$email_field}"
SSL_CLIENT_SAN_Email_0 "$san_email"

View File

@@ -42,11 +42,11 @@ Conflicts:
server/protocol.c | 25 +++++++++++++++++--------
6 files changed, 77 insertions(+), 10 deletions(-)
Index: httpd-2.4.49/modules/http/http_filters.c
Index: httpd-2.4.64/modules/http/http_filters.c
===================================================================
--- httpd-2.4.49.orig/modules/http/http_filters.c 2021-05-11 17:21:43.000000000 +0200
+++ httpd-2.4.49/modules/http/http_filters.c 2021-09-17 09:33:49.496853894 +0200
@@ -1488,10 +1488,17 @@ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_
--- httpd-2.4.64.orig/modules/http/http_filters.c
+++ httpd-2.4.64/modules/http/http_filters.c
@@ -1409,10 +1409,17 @@ static void merge_response_headers(reque
* zero C-L to the client. We can't just remove the C-L filter,
* because well behaved 2.0 handlers will send their data down the stack,
* and we will compute a real C-L for the head request. RBB
@@ -64,12 +64,12 @@ Index: httpd-2.4.49/modules/http/http_filters.c
+ && conf->http_cl_head_zero != AP_HTTP_CL_HEAD_ZERO_ENABLE) {
apr_table_unset(r->headers_out, "Content-Length");
}
Index: httpd-2.4.49/server/core.c
}
Index: httpd-2.4.64/server/core.c
===================================================================
--- httpd-2.4.49.orig/server/core.c 2021-05-27 15:08:21.000000000 +0200
+++ httpd-2.4.49/server/core.c 2021-09-17 09:33:49.496853894 +0200
@@ -551,6 +551,12 @@ static void *merge_core_server_configs(a
--- httpd-2.4.64.orig/server/core.c
+++ httpd-2.4.64/server/core.c
@@ -564,6 +564,12 @@ static void *merge_core_server_configs(a
if (virt->http_methods != AP_HTTP_METHODS_UNSET)
conf->http_methods = virt->http_methods;
@@ -82,7 +82,7 @@ Index: httpd-2.4.49/server/core.c
/* no action for virt->accf_map, not allowed per-vhost */
if (virt->protocol)
@@ -4142,6 +4148,32 @@ static const char *set_http_method(cmd_p
@@ -4166,6 +4172,32 @@ static const char *set_http_method(cmd_p
return NULL;
}
@@ -115,7 +115,7 @@ Index: httpd-2.4.49/server/core.c
static apr_hash_t *errorlog_hash;
static int log_constant_item(const ap_errorlog_info *info, const char *arg,
@@ -4685,6 +4717,10 @@ AP_INIT_TAKE1("TraceEnable", set_trace_e
@@ -4732,6 +4764,10 @@ AP_INIT_TAKE1("TraceEnable", set_trace_e
"'on' (default), 'off' or 'extended' to trace request body content"),
AP_INIT_FLAG("MergeTrailers", set_merge_trailers, NULL, RSRC_CONF,
"merge request trailers into request headers or not"),
@@ -126,11 +126,11 @@ Index: httpd-2.4.49/server/core.c
AP_INIT_ITERATE("Protocols", set_protocols, NULL, RSRC_CONF,
"Controls which protocols are allowed"),
AP_INIT_TAKE1("ProtocolsHonorOrder", set_protocols_honor_order, NULL, RSRC_CONF,
Index: httpd-2.4.49/server/protocol.c
Index: httpd-2.4.64/server/protocol.c
===================================================================
--- httpd-2.4.49.orig/server/protocol.c 2021-09-17 09:33:49.496853894 +0200
+++ httpd-2.4.49/server/protocol.c 2021-09-17 10:15:28.643596021 +0200
@@ -1056,6 +1056,11 @@ AP_DECLARE(int) ap_check_request_header(
--- httpd-2.4.64.orig/server/protocol.c
+++ httpd-2.4.64/server/protocol.c
@@ -1058,6 +1058,11 @@ AP_DECLARE(int) ap_check_request_header(
if (ap_cstr_casecmp(expect, "100-continue") == 0) {
r->expecting_100 = 1;
}
@@ -142,11 +142,11 @@ Index: httpd-2.4.49/server/protocol.c
else {
ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(00570)
"client sent an unrecognized expectation value "
Index: httpd-2.4.49/include/http_core.h
Index: httpd-2.4.64/include/http_core.h
===================================================================
--- httpd-2.4.49.orig/include/http_core.h 2021-05-27 15:08:21.000000000 +0200
+++ httpd-2.4.49/include/http_core.h 2021-09-17 09:33:49.496853894 +0200
@@ -733,6 +733,16 @@ typedef struct {
--- httpd-2.4.64.orig/include/http_core.h
+++ httpd-2.4.64/include/http_core.h
@@ -734,6 +734,16 @@ typedef struct {
#define AP_MERGE_TRAILERS_DISABLE 2
int merge_trailers;
@@ -163,7 +163,7 @@ Index: httpd-2.4.49/include/http_core.h
apr_array_header_t *protocols;
int protocols_honor_order;
@@ -776,7 +786,6 @@ apr_status_t ap_core_input_filter(ap_fil
@@ -780,7 +790,6 @@ apr_status_t ap_core_input_filter(ap_fil
apr_off_t readbytes);
apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *b);

View File

@@ -1,8 +1,8 @@
Index: httpd-2.4.46/server/util_script.c
Index: httpd-2.4.64/server/util_script.c
===================================================================
--- httpd-2.4.46.orig/server/util_script.c 2020-07-20 07:58:49.000000000 +0200
+++ httpd-2.4.46/server/util_script.c 2020-11-10 16:10:54.525476516 +0100
@@ -468,11 +468,20 @@ AP_DECLARE(int) ap_scan_script_header_er
--- httpd-2.4.64.orig/server/util_script.c
+++ httpd-2.4.64/server/util_script.c
@@ -472,11 +472,20 @@ AP_DECLARE(int) ap_scan_script_header_er
apr_table_t *cookie_table;
int trace_log = APLOG_R_MODULE_IS_LEVEL(r, module_index, APLOG_TRACE1);
int first_header = 1;
@@ -24,7 +24,7 @@ Index: httpd-2.4.46/server/util_script.c
/* temporary place to hold headers to merge in later */
merge = apr_table_make(r->pool, 10);
@@ -488,7 +497,7 @@ AP_DECLARE(int) ap_scan_script_header_er
@@ -492,7 +501,7 @@ AP_DECLARE(int) ap_scan_script_header_er
while (1) {
@@ -33,7 +33,7 @@ Index: httpd-2.4.46/server/util_script.c
if (rv == 0) {
const char *msg = "Premature end of script headers";
if (first_header)
@@ -603,10 +612,13 @@ AP_DECLARE(int) ap_scan_script_header_er
@@ -607,10 +616,13 @@ AP_DECLARE(int) ap_scan_script_header_er
if (!(l = strchr(w, ':'))) {
if (!buffer) {
/* Soak up all the script output - may save an outright kill */

25
apache2-httpd Normal file
View File

@@ -0,0 +1,25 @@
#!/bin/bash
#
# Copyright (c) 1996, 1997, 1998 S.u.S.E. GmbH
# Copyright (c) 1998, 1999, 2000, 2001 SuSE GmbH
# Copyright (c) 2002, 2003, (2004?) SuSE Linux AG
# Copyright (c) 2004(?), 2005, 2006, 2007, 2008 SUSE Linux Products GmbH
#
# Authors: Rolf Haberrecker <apache@suse.de>, 2001
# Peter Poeml <apache@suse.de>, 2002, 2003, 2004, 2005, 2006, 2007,
# 2008, 2009, 2010
#
#
export HTTPD_SYSCONFIG_FILE="/etc/sysconfig/apache2"
. /usr/share/apache2/script-helpers
find_mpm
apache_bin="$HTTPD_SBIN_BASE-$HTTPD_MPM"
if ! [ -x $apache_bin ]; then
echo >&2 "$apache_bin is not a valid httpd binary."
echo >&2 "Check your APACHE_MPM setting in /etc/sysconfig/apache2."
exit 1
fi
exec $apache_bin "$@"

View File

@@ -57,7 +57,7 @@
LoadModule authz_groupfile_module /usr/lib64/apache2-event/mod_authz_groupfile.so
LoadModule authz_user_module /usr/lib64/apache2-event/mod_authz_user.so
LoadModule autoindex_module /usr/lib64/apache2-event/mod_autoindex.so
LoadModule cgi_module /usr/lib64/apache2-event/mod_cgi.so
LoadModule cgid_module /usr/lib64/apache2-event/mod_cgid.so
LoadModule dir_module /usr/lib64/apache2-event/mod_dir.so
LoadModule env_module /usr/lib64/apache2-event/mod_env.so
LoadModule expires_module /usr/lib64/apache2-event/mod_expires.so

View File

@@ -32,13 +32,23 @@ function find_mpm
# try to read from sysconfig's APACHE_MPM
HTTPD_MPM="$APACHE_MPM"
# if empty, then choose the one chosen by
# update alternatives
# if the value is empty, we try to determine the MPM based on what's
# installed, with the priority that is encoded below
if [ -z "$HTTPD_MPM" ]; then
HTTPD_MPM=$(readlink $(readlink /usr/sbin/httpd) | sed "s:/usr/sbin/httpd-::")
if [ -x "$HTTPD_SBIN_BASE-prefork" ]; then
HTTPD_MPM="prefork"
elif [ -x "$HTTPD_SBIN_BASE-worker" ]; then
HTTPD_MPM="worker"
elif [ -x "$HTTPD_SBIN_BASE-event" ]; then
HTTPD_MPM="event"
else
echo >&2 "No usable APACHE_MPM was found."
echo >&2 "Check your APACHE_MPM setting in /etc/sysconfig/apache2."
exit 1
fi
fi
# in case no
export HTTPD_MPM
}

View File

@@ -49,17 +49,11 @@ fi
# /usr/sbin/httpd-worker, etc.) and serverflags
#
find_mpm
if [ -n "$HTTPD_MPM" ]; then
apache_bin="$HTTPD_SBIN_BASE-$HTTPD_MPM"
if ! [ -x $apache_bin ]; then
echo >&2 "$apache_bin-$APACHE_MPM is not a valid httpd binary."
apache_bin="$HTTPD_SBIN_BASE-$HTTPD_MPM"
if ! [ -x $apache_bin ]; then
echo >&2 "$apache_bin is not a valid httpd binary."
echo >&2 "Check your APACHE_MPM setting in /etc/sysconfig/apache2."
exit 1
fi
else
# take /usr/sbin/httpd, which will
# exist thanks to update alternatives
apache_bin="$HTTPD_SBIN_BASE"
fi
# server flags from APACHE_SERVER_FLAGS

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
#
# spec file for package apache2
#
# Copyright (c) 2025 SUSE LLC
# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,9 +16,11 @@
#
%global apache2_evr %{?epoch:%{epoch}:}%{version}-%{release}
%global upstream_name httpd
%global testsuite_name %{upstream_name}-framework
%global tversion svn1921782
%global tversion svn1929573
%global flavor @BUILD_FLAVOR@%{nil}
%define mpm %{nil}
%if "%{flavor}" == "prefork" || "%{flavor}" == "test_prefork"
@@ -38,14 +40,9 @@
%define unittest 1
%endif
%endif
%if "%{mpm}" == "prefork"
%define mpm_alt_prio 10
%endif
%if "%{mpm}" == "worker"
%define mpm_alt_prio 20
%endif
%if "%{mpm}" == "event"
%define mpm_alt_prio 30
%if "%{flavor}" == "prefork" || "%{flavor}" == "worker" || "%{flavor}" == "event"
# Ensure the mpm packages have a synced rebuild counter, as we insisit on requiring the package = %apache2_evr
#!BcntSyncTag: apache2
%endif
%define default_mpm prefork
%define suse_maintenance_mmn 0
@@ -107,7 +104,7 @@
%define build_http2 1
Name: apache2%{psuffix}
Version: 2.4.63
Version: 2.4.66
Release: 0
Summary: The Apache HTTPD Server
License: Apache-2.0
@@ -141,6 +138,7 @@ Source101: apache2-a2enflag
Source102: apache2-systemd-ask-pass
Source103: apache2-start_apache2
Source104: apache2-script-helpers
Source105: apache2-httpd
# additional support
Source130: apache2-gensslcert
Source131: apache2-check_forensic
@@ -181,21 +179,6 @@ Patch2: apache2-logresolve-tmp-security.patch
Patch3: apache2-LimitRequestFieldSize-limits-headers.patch
# [fate317766] backport of an upstream commit
Patch4: apache2-HttpContentLengthHeadZero-HttpExpectStrict.patch
# FIX-UPSTREAM: bsc#1246477 CVE-2024-42516: HTTP response splitting
Patch5: CVE-2024-42516.patch
# FIX-UPSTREAM: bsc#1246305 CVE-2024-43204: SSRF when mod_proxy is loaded allows an attacker to send outbound proxy requests to a URL controlled by them
Patch6: CVE-2024-43204.patch
# FIX-UPSTREAM: bsc#1246303 CVE-2024-47252: insufficient escaping of user-supplied data in mod_ssl allows an untrusted SSL/TLS client to insert escape characters into log files
Patch7: CVE-2024-47252.patch
# FIX-UPSTREAM: bsc#1246302 CVE-2025-23048: access control bypass by trusted clients through TLS 1.3 session resumption in some mod_ssl configurations
Patch8: CVE-2025-23048.patch
# FIX-UPSTREAM: bsc#1246307 CVE-2025-49630: denial of service can be triggered by untrusted clients causing an assertion in mod_proxy_http2
Patch9: CVE-2025-49630.patch
# FIX-UPSTREAM: bsc#1246169 CVE-2025-49812: Opossum Attack Application Layer Desynchronization using Opportunistic TLS
Patch10: CVE-2025-49812.patch
# FIX-UPSTREAM: bsc#1246306 CVE-2025-53020: HTTP/2 denial of service due to late release of memory after effective lifetime
Patch11: CVE-2025-53020.patch
# PATCH: https://marc.info/?l=apache-httpd-users&m=147448312531134&w=2
Patch100: apache-test-application-xml-type.patch
# PATCH: /test_ssl_var_lookup?SSL_SERVER_SAN_DNS_0 returns <build-host-name>
@@ -205,15 +188,6 @@ Patch100: apache-test-application-xml-type.patch
# even if in live system I do not experience this inconsistency, let's turn off
# these variables from the test
Patch101: apache-test-turn-off-variables-in-ssl-var-lookup.patch
#FIX-UPSTREAM: bsc#1254511 CVE-2025-55753
Patch102: CVE-2025-55753.patch
#FIX-UPSTREAM: bsc#1254512 CVE-2025-58098
Patch103: CVE-2025-58098.patch
#FIX-UPSTREAM: bsc#1254514 CVE-2025-65082
Patch104: CVE-2025-65082.patch
#FIX-UPSTREAM: bsc#1254515 CVE-2025-66200
Patch105: CVE-2025-66200.patch
BuildRequires: apache-rpm-macros-control
#Since 2.4.7 the event MPM requires apr 1.5.0 or later.
BuildRequires: apr-devel >= 1.5.0
@@ -286,12 +260,12 @@ BuildRequires: netcfg
# /SECTION
%if "%{mpm}" != ""
Provides: apache2-MPM
Requires: apache2
Requires: apache2 = %{apache2_evr}
%endif
%if "%{flavor}" == ""
Requires: %{_sysconfdir}/mime.types
Requires: apache2-MPM
Suggests: apache2-%{default_mpm}
Suggests: apache2-%{default_mpm} = %{apache2_evr}
Recommends: apache2-utils
Requires: logrotate
Provides: %{apache_mmn}
@@ -322,7 +296,6 @@ Obsoletes: apache2-doc <= %{version}
Requires(pre): permissions
Requires(post): %fillup_prereq
Requires(post): grep
Requires(post): update-alternatives
Requires(postun): update-alternatives
%endif
%if %{test} || "%{flavor}" == "manual"
@@ -508,18 +481,9 @@ make DESTDIR=%{buildroot} program-install
pushd modules
make DESTDIR=%{buildroot} install -j1
popd
# install alternative links (httpd binary, modules)
mkdir -p %{buildroot}%{_sysconfdir}/alternatives
ln -sf %{_sysconfdir}/alternatives/httpd %{buildroot}%{_sbindir}/httpd
mkdir -p %{buildroot}%{_libdir}/apache2/
for module in %{dynamic_modules}; do
if [ -e %{buildroot}%{libexecdir}/mod_$module.so ]; then
ln -sf %{_sysconfdir}/alternatives/mod_$module.so %{buildroot}%{_libdir}/apache2/mod_$module.so
fi
done
%endif
# main packge install
# main package install
%if "%{flavor}" == ""
mkdir -p %{buildroot}%{logfiledir} \
%{buildroot}%{proxycachedir} \
@@ -555,6 +519,7 @@ install -m 755 %{SOURCE100} %{buildroot}%{_sbindir}/a2enmod
ln -s a2enmod %{buildroot}%{_sbindir}/a2dismod
install -m 755 %{SOURCE101} %{buildroot}%{_sbindir}/a2enflag
ln -s a2enflag %{buildroot}%{_sbindir}/a2disflag
install -m 755 %{SOURCE105} %{buildroot}%{_sbindir}/httpd
install -m 744 %{SOURCE103} %{buildroot}%{_sbindir}/start_apache2
mkdir -p %{buildroot}/%{_datadir}/apache2/
install -m 644 %{SOURCE104} %{buildroot}/%{_datadir}/apache2/script-helpers
@@ -846,14 +811,8 @@ exit 0
# MPMs files
%if ! %{test} && "%{mpm}" != ""
%files
%{_sbindir}/httpd
%{_sbindir}/httpd-%{mpm}
%ghost %{_sysconfdir}/alternatives/httpd
# %%ghost %%{_sysconfdir}/alternatives/mod_*.so does not work
%(for module in %{dynamic_modules}; do echo "%ghost %{_sysconfdir}/alternatives/mod_$module.so"; done)
%dir %{_libdir}/apache2-%{mpm}
%dir %{_libdir}/apache2
%{_libdir}/apache2/*.so
%{libexecdir}/mod_*.so
%endif
@@ -898,6 +857,7 @@ exit 0
%{_sbindir}/a2enmod
%{_sbindir}/a2disflag
%{_sbindir}/a2dismod
%{_sbindir}/httpd
%{_sbindir}/start_apache2
%{_sbindir}/rcapache2
%{_datadir}/apache2/script-helpers
@@ -951,21 +911,7 @@ exit 0
# MPMs scriptlets
%if ! %{test} && "%{mpm}" != ""
%post
%{_sbindir}/update-alternatives --quiet --force \
--install %{_sbindir}/httpd httpd %{_sbindir}/httpd-%{mpm} %{mpm_alt_prio}
for module in %{dynamic_modules}; do
if [ -e %{libexecdir}/mod_$module.so ]; then
%{_sbindir}/update-alternatives --quiet --force \
--install %{_libdir}/apache2/mod_$module.so mod_$module.so %{libexecdir}/mod_$module.so %{mpm_alt_prio}
fi
done
exit 0
%postun
if [ "$1" = 1 ]; then
%apache_request_restart
fi
%pre
if [ "$1" = 0 ]; then
%{_sbindir}/update-alternatives --quiet --force --remove httpd %{_sbindir}/httpd
for module in %{dynamic_modules}; do
@@ -974,6 +920,12 @@ if [ "$1" = 0 ]; then
fi
exit 0
%postun
if [ "$1" = 1 ]; then
%apache_request_restart
fi
exit 0
%posttrans
%apache_restart_if_needed
exit 0

Binary file not shown.

View File

@@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEqT1i7MPI6hLbIg7JNOp25nkUhagFAmeOpZMACgkQNOp25nkU
hajzCg/+I/j8u/tCFeaQAf5ZKyGZ8Kcpxf+/lP4Kr79emBwdROZFGP+ipfuyRpax
A8/WXTeVs6bWmg5edPIQAC1mDpj7rx2Pwa7xKV+/3/npQMPV4cqgbZfzgQD2NnoD
8Qs6pkjwF6ygn+4y/KQLF5MIh4G0lIkx/ddt+lHbt2FkJXT5JV1cyJ+kKrTLJdlB
RDMXcF2XleFFzApf9VCYWFPTlgmxAe4FG65JMwxh3WJeiX0vrLH+GnOyAXHotBOs
NbXQKQD5cM6/JzA3F4Jni/2co9Wsjg+zENx3hIjxJZvVtXRIC4BpmAJOeQIyoNwo
VVwe3Uo9Cz+ZFTYMecwnR/B5tm4IkQ0K9MXRK/jxxKds4CF/bnt0BClaSRqXrJJW
hwciu0Yw9nsCCQbz+vwMKVMRtQ1m2/Cl3+9K/9RYwdgfTQmNYcu3J+19trvRx2Vf
OVtwFNm2tps2YtOV1NAnr2huHt257WVis9ElCOwIpUqwJZvzLCG2VaSq0vlYZqP8
iQoQA25f9Ln34KdpF7BU2PO9LraFJNTHFIed3cd8L7U14H9iQ93mSUlibzY3HvK4
B3qeXmsn3YpJpgsvhOUPR7mTlhOsPSIdRW0vuLOrN5Rz3uVWRG8vpjCeZCYSYWBf
4KzbwEZ6n9dfc2D5N6Yx3uTdmKhAg1O1ryk7E6Sp+pVybFQrzsc=
=ttO/
-----END PGP SIGNATURE-----

3
httpd-2.4.66.tar.bz2 Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:94d7ff2b42acbb828e870ba29e4cbad48e558a79c623ad3596e4116efcfea25a
size 7504564

16
httpd-2.4.66.tar.bz2.asc Normal file
View File

@@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEZbLUT+dL1ePeOsPwgngd5G1ZVPoFAmktjZ4ACgkQgngd5G1Z
VPqmbA/9FHUJgIj9awZMhhzr3s7FVSL5fKnOxd/IFIZWn7iDRnEexAoX3QWbwbiu
jD31GVidPBSTNph+5LHe/wHYe6mwwaohQ8egpqtuclOk8ct9kxbbbBFIWcg+wy7h
xGHukI4FqY32PKAtCFsoNpbApwjZY8i8vL/5v9BEzY7FVWkviamXw3KsjB5GWLC9
Nf3PrhonMDkHbLqFh8bohJXxzV/1sqKYu5CJ/HJshxCcNU98wSQ7ToUsaI7RHKn8
l60MN92n2ziaD/ziskVsNS/xyvuv1Timf+QCWEr0k7lL6j2Kx0PRikqsm4BySMbh
clGgswxQL1rhjPn6JFG1Ez+DharvVD+gDSlQfVS+ZiHhqNxvqR/rI/n780acXxeq
nJUjjqKfoulq8FkxfSsMDvmS8c4QaZMjb6jCG5DoCMaxHcqH2DUADnYRikUTTKrm
uhsjnSj5hBm1+h/gceOfxKgOSTTXzEyqHqG/aTwGqJDnMpZ0rYMe1kFjWQ2UMk/Q
ak1A617ukMvmM6D1ReB+uewOVdneMTr26S5xjPtuc7IQtfOFWnlznWHF2pUPokAM
NX+W0A9VbS6EmcI2HT2usH3iA3yx3fpJgm3KUCV3lGal3kRJYz+xedY3P25Q9PGn
1lahIAbehWLUC2nLUBTRE5YQXLii1bvNKOXbfMUP0rtOI3o7ZZE=
=IxDB
-----END PGP SIGNATURE-----

Binary file not shown.

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2904b51b05b5f718966f11b4aeed0905d3a17ed9d53825a3caa4d3d3c569b246
size 838260