From 5bc2bd77739ef948c9b8cd733e955f1da254fd7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sun, 12 Jan 2025 14:30:37 +0100 Subject: [PATCH 01/20] Rebuilt for the bin-sbin merge (2nd attempt) https://fedoraproject.org/wiki/Changes/Unify_bin_and_sbin --- httpd.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/httpd.spec b/httpd.spec index 43fa7dc..5b47408 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.62 -Release: 4%{?dist} +Release: 5%{?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 @@ -852,6 +852,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 2.4.62-5 +- Rebuilt for the bin-sbin merge (2nd attempt) + * Fri Oct 11 2024 Luboš Uhliarik - 2.4.62-4 - mod_rewrite: regression fixes From 4bfb30c1fa2da3cbb064c0fbeea00d4d0c611965 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 17 Jan 2025 06:05:57 +0000 Subject: [PATCH 02/20] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- httpd.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/httpd.spec b/httpd.spec index 5b47408..1d84a2f 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.62 -Release: 5%{?dist} +Release: 6%{?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 @@ -852,6 +852,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Fri Jan 17 2025 Fedora Release Engineering - 2.4.62-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 2.4.62-5 - Rebuilt for the bin-sbin merge (2nd attempt) From 6763440aa7164c462878d35379212d28eba22190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Fri, 24 Jan 2025 14:25:33 +0100 Subject: [PATCH 03/20] new version 2.4.63 --- .gitignore | 1 + httpd-2.4.62-r1919325.patch | 242 ------------------ httpd-2.4.62-r1920980+.patch | 94 ------- ...477+.patch => httpd-2.4.63-r1912477+.patch | 80 +++--- httpd.spec | 15 +- sources | 4 +- 6 files changed, 49 insertions(+), 387 deletions(-) delete mode 100644 httpd-2.4.62-r1919325.patch delete mode 100644 httpd-2.4.62-r1920980+.patch rename httpd-2.4.58-r1912477+.patch => httpd-2.4.63-r1912477+.patch (85%) diff --git a/.gitignore b/.gitignore index 5bb7aaa..0969db5 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,4 @@ x86_64 /httpd-2.4.59.tar.bz2.asc /httpd-2.4.61.tar.bz2.asc /httpd-2.4.62.tar.bz2.asc +/httpd-2.4.63.tar.bz2.asc diff --git a/httpd-2.4.62-r1919325.patch b/httpd-2.4.62-r1919325.patch deleted file mode 100644 index 1b344e5..0000000 --- a/httpd-2.4.62-r1919325.patch +++ /dev/null @@ -1,242 +0,0 @@ -From a0a68b99d131741c1867cff321424892838fc4b3 Mon Sep 17 00:00:00 2001 -From: Yann Ylavic -Date: Sat, 27 Jul 2024 13:35:53 +0000 -Subject: [PATCH] mod_rewrite: Better question mark tracking to avoid - UnsafeAllow3F. PR 69197. - -Track in do_expand() whether a '?' in the uri-path comes from a literal in -the substitution string or from an expansion (variable, lookup, ...). -In the former case it's safe to assume that it's the query-string separator -but for the other case it's not (could be a decoded %3f from r->uri). - -This allows to avoid [UnsafeAllow3F] for most cases. - - -Merges r1919325 from trunk -Reviewed by: ylavic, covener, jorton -Github: closes #462 - - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1919545 13f79535-47bb-0310-9956-ffa450edef68 ---- - modules/mappers/mod_rewrite.c | 107 ++++++++++++++++++++++++++++------ - 1 file changed, 89 insertions(+), 18 deletions(-) - -diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c -index f1c22e3235b..53fb1e91ffb 100644 ---- a/modules/mappers/mod_rewrite.c -+++ b/modules/mappers/mod_rewrite.c -@@ -2376,9 +2376,16 @@ static APR_INLINE char *find_char_in_curlies(char *s, int c) - * of an earlier expansion to include expansion specifiers that - * are interpreted by a later expansion, producing results that - * were not intended by the administrator. -+ * -+ * unsafe_qmark if not NULL will be set to 1 or 0 if a question mark -+ * is found respectively in a literal or in a lookup/expansion (whether -+ * it's the first or last qmark depends on [QSL]). Should be initialized -+ * to -1 and remains so if no qmark is found. - */ --static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) -+static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry, -+ int *unsafe_qmark) - { -+#define EXPAND_SPECIALS "\\$%" - result_list *result, *current; - result_list sresult[SMALL_EXPANSION]; - unsigned spc = 0; -@@ -2386,8 +2393,29 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) - char *p, *c; - apr_pool_t *pool = ctx->r->pool; - -- span = strcspn(input, "\\$%"); - inputlen = strlen(input); -+ if (!unsafe_qmark) { -+ span = strcspn(input, EXPAND_SPECIALS); -+ } -+ else { -+ span = strcspn(input, EXPAND_SPECIALS "?"); -+ if (input[span] == '?') { -+ /* this qmark is not from an expansion thus safe */ -+ *unsafe_qmark = 0; -+ -+ /* keep tracking only if interested in the last qmark */ -+ if (entry && (entry->flags & RULEFLAG_QSLAST)) { -+ do { -+ span++; -+ span += strcspn(input + span, EXPAND_SPECIALS "?"); -+ } while (input[span] == '?'); -+ } -+ else { -+ unsafe_qmark = NULL; -+ span += strcspn(input + span, EXPAND_SPECIALS); -+ } -+ } -+ } - - /* fast exit */ - if (inputlen == span) { -@@ -2405,6 +2433,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) - - /* loop for specials */ - do { -+ int expanded = 0; -+ - /* prepare next entry */ - if (current->len) { - current->next = (spc < SMALL_EXPANSION) -@@ -2450,6 +2480,8 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) - current->len = span; - current->string = p; - outlen += span; -+ -+ expanded = 1; - p = endp + 1; - } - -@@ -2489,19 +2521,18 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) - } - - /* reuse of key variable as result */ -- key = lookup_map(ctx->r, map, do_expand(key, ctx, entry)); -- -+ key = lookup_map(ctx->r, map, do_expand(key, ctx, entry, NULL)); - if (!key && dflt && *dflt) { -- key = do_expand(dflt, ctx, entry); -+ key = do_expand(dflt, ctx, entry, NULL); - } -- -- if (key) { -+ if (key && *key) { - span = strlen(key); - current->len = span; - current->string = key; - outlen += span; - } - -+ expanded = 1; - p = endp + 1; - } - } -@@ -2531,8 +2562,9 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) - current->len = span; - current->string = bri->source + bri->regmatch[n].rm_so; - } -- - outlen += span; -+ -+ expanded = 1; - } - - p += 2; -@@ -2545,8 +2577,41 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry) - ++outlen; - } - -+ if (unsafe_qmark && expanded && current->len -+ && memchr(current->string, '?', current->len)) { -+ /* this qmark is from an expansion thus unsafe */ -+ *unsafe_qmark = 1; -+ -+ /* keep tracking only if interested in the last qmark */ -+ if (!entry || !(entry->flags & RULEFLAG_QSLAST)) { -+ unsafe_qmark = NULL; -+ } -+ } -+ - /* check the remainder */ -- if (*p && (span = strcspn(p, "\\$%")) > 0) { -+ if (!unsafe_qmark) { -+ span = strcspn(p, EXPAND_SPECIALS); -+ } -+ else { -+ span = strcspn(p, EXPAND_SPECIALS "?"); -+ if (p[span] == '?') { -+ /* this qmark is not from an expansion thus safe */ -+ *unsafe_qmark = 0; -+ -+ /* keep tracking only if interested in the last qmark */ -+ if (entry && (entry->flags & RULEFLAG_QSLAST)) { -+ do { -+ span++; -+ span += strcspn(p + span, EXPAND_SPECIALS "?"); -+ } while (p[span] == '?'); -+ } -+ else { -+ unsafe_qmark = NULL; -+ span += strcspn(p + span, EXPAND_SPECIALS); -+ } -+ } -+ } -+ if (span > 0) { - if (current->len) { - current->next = (spc < SMALL_EXPANSION) - ? &(sresult[spc++]) -@@ -2591,7 +2656,7 @@ static void do_expand_env(data_item *env, rewrite_ctx *ctx) - char *name, *val; - - while (env) { -- name = do_expand(env->data, ctx, NULL); -+ name = do_expand(env->data, ctx, NULL, NULL); - if (*name == '!') { - name++; - apr_table_unset(ctx->r->subprocess_env, name); -@@ -2725,7 +2790,7 @@ static void add_cookie(request_rec *r, char *s) - static void do_expand_cookie(data_item *cookie, rewrite_ctx *ctx) - { - while (cookie) { -- add_cookie(ctx->r, do_expand(cookie->data, ctx, NULL)); -+ add_cookie(ctx->r, do_expand(cookie->data, ctx, NULL, NULL)); - cookie = cookie->next; - } - -@@ -4014,7 +4079,7 @@ static int apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ctx) - int basis; - - if (p->ptype != CONDPAT_AP_EXPR) -- input = do_expand(p->input, ctx, NULL); -+ input = do_expand(p->input, ctx, NULL, NULL); - - switch (p->ptype) { - case CONDPAT_FILE_EXISTS: -@@ -4178,7 +4243,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p, - char *expanded; - - if (p->forced_mimetype) { -- expanded = do_expand(p->forced_mimetype, ctx, p); -+ expanded = do_expand(p->forced_mimetype, ctx, p, NULL); - - if (*expanded) { - ap_str_tolower(expanded); -@@ -4192,7 +4257,7 @@ static APR_INLINE void force_type_handler(rewriterule_entry *p, - } - - if (p->forced_handler) { -- expanded = do_expand(p->forced_handler, ctx, p); -+ expanded = do_expand(p->forced_handler, ctx, p, NULL); - - if (*expanded) { - ap_str_tolower(expanded); -@@ -4329,12 +4394,18 @@ static rule_return_type apply_rewrite_rule(rewriterule_entry *p, - - /* expand the result */ - if (!(p->flags & RULEFLAG_NOSUB)) { -- newuri = do_expand(p->output, ctx, p); -+ int unsafe_qmark = -1; -+ -+ if (p->flags & RULEFLAG_UNSAFE_ALLOW3F) { -+ newuri = do_expand(p->output, ctx, p, NULL); -+ } -+ else { -+ newuri = do_expand(p->output, ctx, p, &unsafe_qmark); -+ } - rewritelog((r, 2, ctx->perdir, "rewrite '%s' -> '%s'", ctx->uri, - newuri)); -- if (!(p->flags & RULEFLAG_UNSAFE_ALLOW3F) && -- ap_strcasestr(r->unparsed_uri, "%3f") && -- ap_strchr_c(newuri, '?')) { -+ -+ if (unsafe_qmark > 0) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10508) - "Unsafe URL with %%3f URL rewritten without " - "UnsafeAllow3F"); - diff --git a/httpd-2.4.62-r1920980+.patch b/httpd-2.4.62-r1920980+.patch deleted file mode 100644 index 42ca023..0000000 --- a/httpd-2.4.62-r1920980+.patch +++ /dev/null @@ -1,94 +0,0 @@ - -https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1920566 -https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1920980 - -diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c -index 53fb1e9..93ae7ac 100644 ---- a/modules/mappers/mod_rewrite.c -+++ b/modules/mappers/mod_rewrite.c -@@ -2404,21 +2404,19 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry, - *unsafe_qmark = 0; - - /* keep tracking only if interested in the last qmark */ -- if (entry && (entry->flags & RULEFLAG_QSLAST)) { -- do { -- span++; -- span += strcspn(input + span, EXPAND_SPECIALS "?"); -- } while (input[span] == '?'); -- } -- else { -+ if (!entry || !(entry->flags & RULEFLAG_QSLAST)) { - unsafe_qmark = NULL; -- span += strcspn(input + span, EXPAND_SPECIALS); - } -+ -+ /* find the next real special char, any (last) qmark up to -+ * there is safe too -+ */ -+ span += strcspn(input + span, EXPAND_SPECIALS); - } - } - -- /* fast exit */ -- if (inputlen == span) { -+ /* fast path (no specials) */ -+ if (span >= inputlen) { - return apr_pstrmemdup(pool, input, inputlen); - } - -@@ -2599,16 +2597,14 @@ static char *do_expand(char *input, rewrite_ctx *ctx, rewriterule_entry *entry, - *unsafe_qmark = 0; - - /* keep tracking only if interested in the last qmark */ -- if (entry && (entry->flags & RULEFLAG_QSLAST)) { -- do { -- span++; -- span += strcspn(p + span, EXPAND_SPECIALS "?"); -- } while (p[span] == '?'); -- } -- else { -+ if (!entry || !(entry->flags & RULEFLAG_QSLAST)) { - unsafe_qmark = NULL; -- span += strcspn(p + span, EXPAND_SPECIALS); - } -+ -+ /* find the next real special char, any (last) qmark up to -+ * there is safe too -+ */ -+ span += strcspn(p + span, EXPAND_SPECIALS); - } - } - if (span > 0) { -@@ -4284,6 +4280,7 @@ static rule_return_type apply_rewrite_rule(rewriterule_entry *p, - char *newuri = NULL; - request_rec *r = ctx->r; - int is_proxyreq = 0; -+ int prefix_added = 0; - - ctx->uri = r->filename; - -@@ -4444,6 +4441,7 @@ static rule_return_type apply_rewrite_rule(rewriterule_entry *p, - 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); -+ prefix_added = 1; - } - else if (!(p->flags & (RULEFLAG_PROXY | RULEFLAG_FORCEREDIRECT))) { - /* Not an absolute URI-path and the scheme (if any) is unknown, -@@ -4457,6 +4455,7 @@ static rule_return_type apply_rewrite_rule(rewriterule_entry *p, - newuri, newuri)); - - newuri = apr_pstrcat(r->pool, "/", newuri, NULL); -+ prefix_added = 1; - } - } - -@@ -4537,7 +4536,7 @@ static rule_return_type apply_rewrite_rule(rewriterule_entry *p, - return RULE_RC_MATCH; - } - -- if (!(p->flags & RULEFLAG_UNC)) { -+ if (!((p->flags & RULEFLAG_UNC) || prefix_added)) { - /* merge leading slashes, unless they were literals in the sub */ - if (!AP_IS_SLASH(p->output[0]) || !AP_IS_SLASH(p->output[1])) { - while (AP_IS_SLASH(r->filename[0]) && diff --git a/httpd-2.4.58-r1912477+.patch b/httpd-2.4.63-r1912477+.patch similarity index 85% rename from httpd-2.4.58-r1912477+.patch rename to httpd-2.4.63-r1912477+.patch index eb3deff..35e5866 100644 --- a/httpd-2.4.58-r1912477+.patch +++ b/httpd-2.4.63-r1912477+.patch @@ -7,9 +7,11 @@ http://svn.apache.org/viewvc?view=revision&revision=1914438 Upstream-Status: in trunk, not proposed for 2.4.x ---- httpd-2.4.58/modules/dav/fs/config6.m4.r1912477+ -+++ httpd-2.4.58/modules/dav/fs/config6.m4 -@@ -20,4 +20,10 @@ +diff --git a/modules/dav/fs/config6.m4 b/modules/dav/fs/config6.m4 +index dd26ec8..72fff9a 100644 +--- a/modules/dav/fs/config6.m4 ++++ b/modules/dav/fs/config6.m4 +@@ -20,4 +20,10 @@ esac APACHE_MODULE(dav_fs, DAV provider for the filesystem. --enable-dav also enables mod_dav_fs., $dav_fs_objects, , $dav_fs_enable,,dav) @@ -20,8 +22,10 @@ Upstream-Status: in trunk, not proposed for 2.4.x +fi + APACHE_MODPATH_FINISH ---- httpd-2.4.58/modules/dav/fs/dbm.c.r1912477+ -+++ httpd-2.4.58/modules/dav/fs/dbm.c +diff --git a/modules/dav/fs/dbm.c b/modules/dav/fs/dbm.c +index 39ab4ad..4551f70 100644 +--- a/modules/dav/fs/dbm.c ++++ b/modules/dav/fs/dbm.c @@ -47,6 +47,10 @@ #include "http_log.h" #include "http_main.h" /* for ap_server_conf */ @@ -33,16 +37,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x APLOG_USE_MODULE(dav_fs); struct dav_db { -@@ -100,7 +104,7 @@ - /* There might not be a if we had problems creating it. */ - if (db == NULL) { - errcode = 1; -- errstr = "Could not open property database."; -+ errstr = "Could not open database."; - if (APR_STATUS_IS_EDSOOPEN(status)) - ap_log_error(APLOG_MARK, APLOG_CRIT, status, ap_server_conf, APLOGNO(00576) - "The DBM driver could not be loaded"); -@@ -129,10 +133,10 @@ +@@ -129,10 +133,10 @@ void dav_fs_ensure_state_dir(apr_pool_t * p, const char *dirname) /* dav_dbm_open_direct: Opens a *dbm database specified by path. * ro = boolean read-only flag. */ @@ -56,7 +51,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x const apr_dbm_driver_t *driver; const apu_err_t *err; #endif -@@ -141,13 +145,13 @@ +@@ -141,11 +145,12 @@ dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro, *pdb = NULL; @@ -64,18 +59,16 @@ Upstream-Status: in trunk, not proposed for 2.4.x - if ((status = apr_dbm_get_driver(&driver, NULL, &err, p)) != APR_SUCCESS) { +#if APR_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 7) + if ((status = apr_dbm_get_driver(&driver, dbmtype, &err, p)) != APR_SUCCESS) { ++ ap_log_error(APLOG_MARK, APLOG_ERR, status, ap_server_conf, APLOGNO(10289) - "mod_dav_fs: The DBM library '%s' could not be loaded: %s", - err->reason, err->msg); + "mod_dav_fs: The DBM library '%s' for '%s' could not be loaded: %s", + err->reason, dbmtype, err->msg); return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 1, status, -- "Could not load library for property database."); -+ "Could not load library for database."); + "Could not load library for database."); } - if ((status = apr_dbm_open2(&file, driver, pathname, - ro ? APR_DBM_READONLY : APR_DBM_RWCREATE, -@@ -156,7 +160,7 @@ +@@ -156,7 +161,7 @@ dav_error * dav_dbm_open_direct(apr_pool_t *p, const char *pathname, int ro, return dav_fs_dbm_error(NULL, p, status); } #else @@ -84,7 +77,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x ro ? APR_DBM_READONLY : APR_DBM_RWCREATE, APR_OS_DEFAULT, p)) != APR_SUCCESS -@@ -206,7 +210,7 @@ +@@ -206,7 +211,7 @@ static dav_error * dav_dbm_open(apr_pool_t * p, const dav_resource *resource, /* ### do we need to deal with the umask? */ @@ -93,9 +86,11 @@ Upstream-Status: in trunk, not proposed for 2.4.x } void dav_dbm_close(dav_db *db) ---- httpd-2.4.58/modules/dav/fs/lock.c.r1912477+ -+++ httpd-2.4.58/modules/dav/fs/lock.c -@@ -181,8 +181,7 @@ +diff --git a/modules/dav/fs/lock.c b/modules/dav/fs/lock.c +index ef18c4a..29d167d 100644 +--- a/modules/dav/fs/lock.c ++++ b/modules/dav/fs/lock.c +@@ -181,8 +181,7 @@ struct dav_lockdb_private { request_rec *r; /* for accessing the uuid state */ apr_pool_t *pool; /* a pool to use */ @@ -105,7 +100,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x int opened; /* we opened the database */ dav_db *db; /* if non-NULL, the lock database */ }; -@@ -292,6 +291,19 @@ +@@ -292,6 +291,19 @@ static int dav_fs_compare_locktoken( return dav_compare_locktoken(lt1, lt2); } @@ -125,7 +120,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x /* ** dav_fs_really_open_lockdb: ** -@@ -300,15 +312,27 @@ +@@ -300,15 +312,27 @@ static int dav_fs_compare_locktoken( static dav_error * dav_fs_really_open_lockdb(dav_lockdb *lockdb) { dav_error *err; @@ -154,7 +149,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x return dav_push_error(lockdb->info->pool, HTTP_INTERNAL_SERVER_ERROR, DAV_ERR_LOCK_OPENDB, -@@ -316,6 +340,10 @@ +@@ -316,6 +340,10 @@ static dav_error * dav_fs_really_open_lockdb(dav_lockdb *lockdb) err); } @@ -165,7 +160,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x /* all right. it is opened now. */ lockdb->info->opened = 1; -@@ -341,9 +369,9 @@ +@@ -341,9 +369,9 @@ static dav_error * dav_fs_open_lockdb(request_rec *r, int ro, int force, comb->pub.info = &comb->priv; comb->priv.r = r; comb->priv.pool = r->pool; @@ -178,7 +173,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x return dav_new_error(r->pool, HTTP_INTERNAL_SERVER_ERROR, DAV_ERR_LOCK_NO_DB, 0, "A lock database was not specified with the " -@@ -369,8 +397,8 @@ +@@ -369,8 +397,8 @@ static dav_error * dav_fs_open_lockdb(request_rec *r, int ro, int force, */ static void dav_fs_close_lockdb(dav_lockdb *lockdb) { @@ -189,8 +184,10 @@ Upstream-Status: in trunk, not proposed for 2.4.x } /* ---- httpd-2.4.58/modules/dav/fs/mod_dav_fs.c.r1912477+ -+++ httpd-2.4.58/modules/dav/fs/mod_dav_fs.c +diff --git a/modules/dav/fs/mod_dav_fs.c b/modules/dav/fs/mod_dav_fs.c +index 2389f8f..4bf6c51 100644 +--- a/modules/dav/fs/mod_dav_fs.c ++++ b/modules/dav/fs/mod_dav_fs.c @@ -14,31 +14,35 @@ * limitations under the License. */ @@ -238,7 +235,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x } static void *dav_fs_create_server_config(apr_pool_t *p, server_rec *s) -@@ -57,15 +61,50 @@ +@@ -57,15 +61,50 @@ static void *dav_fs_merge_server_config(apr_pool_t *p, newconf->lockdb_path = child->lockdb_path ? child->lockdb_path : parent->lockdb_path; @@ -272,8 +269,9 @@ Upstream-Status: in trunk, not proposed for 2.4.x apr_pool_t *ptemp, server_rec *base_server) { server_rec *s; +- + apr_status_t rv; - ++ + /* Ignore first pass through the config. */ + if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) + return OK; @@ -289,7 +287,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x for (s = base_server; s; s = s->next) { dav_fs_server_conf *conf; -@@ -74,6 +113,13 @@ +@@ -74,6 +113,13 @@ static apr_status_t dav_fs_post_config(apr_pool_t *p, apr_pool_t *plog, if (!conf->lockdb_path) { conf->lockdb_path = ap_state_dir_relative(p, DEFAULT_DAV_LOCKDB); } @@ -303,7 +301,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x } return OK; -@@ -98,19 +144,36 @@ +@@ -98,19 +144,36 @@ static const char *dav_fs_cmd_davlockdb(cmd_parms *cmd, void *config, return NULL; } @@ -341,8 +339,10 @@ Upstream-Status: in trunk, not proposed for 2.4.x dav_hook_gather_propsets(dav_fs_gather_propsets, NULL, NULL, APR_HOOK_MIDDLE); dav_hook_find_liveprop(dav_fs_find_liveprop, NULL, NULL, APR_HOOK_MIDDLE); ---- httpd-2.4.58/modules/dav/fs/repos.h.r1912477+ -+++ httpd-2.4.58/modules/dav/fs/repos.h +diff --git a/modules/dav/fs/repos.h b/modules/dav/fs/repos.h +index b164611..d3a55a5 100644 +--- a/modules/dav/fs/repos.h ++++ b/modules/dav/fs/repos.h @@ -25,6 +25,8 @@ #ifndef _DAV_FS_REPOS_H_ #define _DAV_FS_REPOS_H_ @@ -352,7 +352,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x /* the subdirectory to hold all DAV-related information for a directory */ #define DAV_FS_STATE_DIR ".DAV" #define DAV_FS_STATE_FILE_FOR_DIR ".state_for_dir" -@@ -53,8 +55,8 @@ +@@ -53,8 +55,8 @@ dav_error * dav_fs_get_locknull_members(const dav_resource *resource, /* DBM functions used by the repository and locking providers */ extern const dav_hooks_db dav_hooks_db_dbm; @@ -363,7 +363,7 @@ Upstream-Status: in trunk, not proposed for 2.4.x void dav_dbm_get_statefiles(apr_pool_t *p, const char *fname, const char **state1, const char **state2); dav_error * dav_dbm_delete(dav_db *db, apr_datum_t key); -@@ -64,8 +66,15 @@ +@@ -64,8 +66,15 @@ void dav_dbm_freedatum(dav_db *db, apr_datum_t data); int dav_dbm_exists(dav_db *db, apr_datum_t key); void dav_dbm_close(dav_db *db); diff --git a/httpd.spec b/httpd.spec index 1d84a2f..a563b58 100644 --- a/httpd.spec +++ b/httpd.spec @@ -30,8 +30,8 @@ Summary: Apache HTTP Server Name: httpd -Version: 2.4.62 -Release: 6%{?dist} +Version: 2.4.63 +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 @@ -99,18 +99,12 @@ Patch27: httpd-2.4.43-sslciphdefault.patch Patch28: httpd-2.4.43-sslprotdefault.patch Patch29: httpd-2.4.43-logjournal.patch Patch30: httpd-2.4.53-separate-systemd-fns.patch -Patch31: httpd-2.4.58-r1912477+.patch +Patch31: httpd-2.4.63-r1912477+.patch Patch32: httpd-2.4.54-selinux.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 Patch60: httpd-2.4.43-enable-sslv3.patch -# https://bz.apache.org/bugzilla/show_bug.cgi?id=69197 -Patch61: httpd-2.4.62-r1919325.patch -# https://github.com/apache/httpd/pull/473 -# https://github.com/apache/httpd/commit/c91445b7f905587aa86ad552f4a1a3f29345e695 -Patch62: httpd-2.4.62-r1920980+.patch - # Security fixes # Patch200: ... @@ -852,6 +846,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Fri Jan 24 2025 Luboš Uhliarik - 2.4.63-1 +- new version 2.4.63 + * Fri Jan 17 2025 Fedora Release Engineering - 2.4.62-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild diff --git a/sources b/sources index 2d4ff61..f188c2a 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (httpd-2.4.62.tar.bz2) = 7db1876805d5c0f60f49bcb51f75cdf567120f2ff6349e68f084e9a86ae38265d9f1c67e7fca0082c9db136f3c408a88501ee11f26b1b68724ba240867171d77 -SHA512 (httpd-2.4.62.tar.bz2.asc) = ed4d59fca7e134aa378dddfd0d62973da99fe77a82a48e268e11262af8aca4a4e90133cc979fb39a4f9cb33abbebb10b1345cb52cfad6eb58fc84d3308bc5a39 +SHA512 (httpd-2.4.63.tar.bz2) = a804ca564dfee5907fe4ce4f36884815bace0621bc7b8c9aa7c99472a954aa19cb13733f90678ff3d58ab3c76cc0e33a27e1035dc1d8cb597a9622154c59ef48 +SHA512 (httpd-2.4.63.tar.bz2.asc) = 3496290be3ff202c820636f6c1548dda363eb6a5c6c1ae88e7154eb839a71c32b6531a33a5a62159601d4a079ed6d7bbbfcf9cbe143d0941b3ffcbed783db9bf SHA512 (KEYS) = 88c848b7ab9e4915d6625dcad3e8328673b0448f2ce76f2c44eecc612cf6afbce3287a4ee7219a44c6fcc61d5ecb2a1a8545456a4a16b90400263d7249cbf192 From 52584b92651dbb041020e0f12152383e968acb34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Esser?= Date: Sat, 1 Feb 2025 19:54:38 +0100 Subject: [PATCH 04/20] Add explicit BR: libxcrypt-devel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Björn Esser --- httpd.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/httpd.spec b/httpd.spec index a563b58..a92de53 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.63 -Release: 1%{?dist} +Release: 2%{?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 @@ -121,6 +121,7 @@ BuildRequires: zlib-devel, libselinux-devel, lua-devel, brotli-devel BuildRequires: apr-devel >= 1.5.0, apr-util-devel >= 1.5.0 BuildRequires: openldap-devel BuildRequires: systemd-rpm-macros +BuildRequires: libxcrypt-devel %if %{with pcre2} BuildRequires: pcre2-devel %endif @@ -846,6 +847,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Sat Feb 01 2025 Björn Esser - 2.4.63-2 +- Add explicit BR: libxcrypt-devel + * Fri Jan 24 2025 Luboš Uhliarik - 2.4.63-1 - new version 2.4.63 From d91306617e86ebb7f9d4ada7b457b0a699d87764 Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Mon, 10 Feb 2025 14:53:51 +0000 Subject: [PATCH 05/20] sync default httpd.conf with upstream --- httpd.conf | 18 +++++++++++++++++- httpd.spec | 5 ++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/httpd.conf b/httpd.conf index 609b2e2..e49ab6a 100644 --- a/httpd.conf +++ b/httpd.conf @@ -151,7 +151,7 @@ DocumentRoot "/var/www/html" # # AllowOverride controls what directives may be placed in .htaccess files. # It can be "All", "None", or any combination of the keywords: - # Options FileInfo AuthConfig Limit + # AllowOverride FileInfo AuthConfig Limit # AllowOverride None @@ -263,6 +263,15 @@ LogLevel warn Require all granted + + # + # Avoid passing HTTP_PROXY environment to CGI's on this or any proxied + # backend servers which have lingering "httpoxy" defects. + # 'Proxy' request header is undefined by the IETF, not listed by IANA + # + RequestHeader unset Proxy early + + # # TypesConfig points to the file containing the list of mappings from @@ -340,6 +349,13 @@ AddDefaultCharset UTF-8 #ErrorDocument 402 http://www.example.com/subscription_info.html # +# +# MaxRanges: Maximum number of Ranges in a request before +# returning the entire resource, or one of the special +# values 'default', 'none' or 'unlimited'. +# Default setting is to accept 200 Ranges. +#MaxRanges unlimited + # # EnableMMAP and EnableSendfile: On systems that support it, # memory-mapping or the sendfile syscall may be used to deliver diff --git a/httpd.spec b/httpd.spec index a92de53..295aff9 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.63 -Release: 2%{?dist} +Release: 3%{?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 @@ -847,6 +847,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Mon Feb 10 2025 Joe Orton - 2.4.63-3 +- sync default httpd.conf with upstream + * Sat Feb 01 2025 Björn Esser - 2.4.63-2 - Add explicit BR: libxcrypt-devel From 243d8d79fbbf3adcc15a7be19ab6958bc0747a68 Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Fri, 14 Feb 2025 08:05:47 +0000 Subject: [PATCH 06/20] - remove unused patch --- httpd-2.4.59-pr426.patch | 244 --------------------------------------- 1 file changed, 244 deletions(-) delete mode 100644 httpd-2.4.59-pr426.patch diff --git a/httpd-2.4.59-pr426.patch b/httpd-2.4.59-pr426.patch deleted file mode 100644 index c0ede88..0000000 --- a/httpd-2.4.59-pr426.patch +++ /dev/null @@ -1,244 +0,0 @@ - -https://github.com/apache/httpd/pull/426.patch - -Upstream-Status: in trunk, proposed for 2.4.60 - ---- httpd-2.4.59/modules/ssl/ssl_engine_init.c.mr426 -+++ httpd-2.4.59/modules/ssl/ssl_engine_init.c -@@ -880,6 +880,13 @@ - } - #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 -+ - #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF - /* For server-side SSL_CTX, enable ignoring unexpected EOF */ - /* (OpenSSL 1.1.1 behavioural compatibility).. */ -@@ -908,6 +915,14 @@ - } - } - -+#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, -@@ -921,7 +936,13 @@ - 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); ---- httpd-2.4.59/modules/ssl/ssl_engine_io.c.mr426 -+++ httpd-2.4.59/modules/ssl/ssl_engine_io.c -@@ -208,11 +208,13 @@ - - 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); -@@ -473,11 +475,13 @@ - - 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; ---- httpd-2.4.59/modules/ssl/ssl_engine_kernel.c.mr426 -+++ httpd-2.4.59/modules/ssl/ssl_engine_kernel.c -@@ -992,7 +992,7 @@ - - /* 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 @@ - */ - 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 @@ - (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 @@ - 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 @@ - */ - SSL_peek(ssl, peekbuf, 0); - -- sslconn->reneg_state = old_state; - modssl_set_app_data2(ssl, NULL); - - /* -@@ -2263,8 +2260,8 @@ - /* - * 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 @@ - 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 @@ - sslconn->reneg_state = RENEG_REJECT; - } - } -+#endif - - s = mySrvFromConn(c); - if (s && APLOGdebug(s)) { ---- httpd-2.4.59/modules/ssl/ssl_private.h.mr426 -+++ httpd-2.4.59/modules/ssl/ssl_private.h -@@ -558,6 +558,16 @@ - 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) -@@ -589,18 +599,13 @@ - 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; -@@ -1207,6 +1212,9 @@ - * 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 */ - /** @} */ - ---- httpd-2.4.59/modules/ssl/ssl_util_ssl.c.mr426 -+++ httpd-2.4.59/modules/ssl/ssl_util_ssl.c -@@ -612,3 +612,19 @@ - } - 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 -+} From cbd0a3cf612e54b38e9f2c46f403989166e55ba4 Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Tue, 24 Jun 2025 11:43:21 +0100 Subject: [PATCH 07/20] mod_dav: add dav_get_base_path() API --- httpd-2.4.63-r1926064.patch | 54 +++++++++++++++++++++++++++++++++++++ httpd.spec | 6 ++++- pullrev.sh | 5 ++-- 3 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 httpd-2.4.63-r1926064.patch diff --git a/httpd-2.4.63-r1926064.patch b/httpd-2.4.63-r1926064.patch new file mode 100644 index 0000000..e8115c7 --- /dev/null +++ b/httpd-2.4.63-r1926064.patch @@ -0,0 +1,54 @@ +# ./pullrev.sh 1926064 +http://svn.apache.org/viewvc?view=revision&revision=1926064 + +--- httpd-2.4.63/include/ap_mmn.h ++++ httpd-2.4.63/include/ap_mmn.h +@@ -608,6 +608,7 @@ + * 20120211.136 (2.4.63-dev) Add wait_io field to struct process_score + * 20120211.137 (2.4.63-dev) Add AP_MPMQ_CAN_WAITIO + * 20120211.138 (2.4.63-dev) Add is_host_matchable to proxy_worker_shared ++ * 20120211.139 (2.4.63-dev) Add dav_get_base_path() to mod_dav + */ + + #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ +@@ -615,7 +616,7 @@ + #ifndef MODULE_MAGIC_NUMBER_MAJOR + #define MODULE_MAGIC_NUMBER_MAJOR 20120211 + #endif +-#define MODULE_MAGIC_NUMBER_MINOR 138 /* 0...n */ ++#define MODULE_MAGIC_NUMBER_MINOR 139 /* 0...n */ + + /** + * Determine if the server's current MODULE_MAGIC_NUMBER is at least a +only in patch2: +--- httpd-2.4.63/modules/dav/main/mod_dav.c ++++ httpd-2.4.63/modules/dav/main/mod_dav.c +@@ -250,6 +250,13 @@ + return dav_get_provider(r)->search; + } + ++DAV_DECLARE(const char *) dav_get_base_path(request_rec *r) ++{ ++ dav_dir_conf *conf = ap_get_module_config(r->per_dir_config, &dav_module); ++ ++ return conf && conf->base ? conf->base : NULL; ++} ++ + /* + * Command handler for the DAV directive, which is TAKE1. + */ +only in patch2: +--- httpd-2.4.63/modules/dav/main/mod_dav.h ++++ httpd-2.4.63/modules/dav/main/mod_dav.h +@@ -430,6 +430,11 @@ + DAV_DECLARE(dav_error *) dav_get_resource(request_rec *r, int label_allowed, + int use_checked_in, dav_resource **res_p); + ++/* ++** If DavBasePath is configured for the request location, return the ++** configured path, otherwise NULL. ++*/ ++DAV_DECLARE(const char *) dav_get_base_path(request_rec *r); + + /* -------------------------------------------------------------------- + ** diff --git a/httpd.spec b/httpd.spec index 295aff9..a9cd66c 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.63 -Release: 3%{?dist} +Release: 4%{?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 @@ -101,6 +101,7 @@ Patch29: httpd-2.4.43-logjournal.patch Patch30: httpd-2.4.53-separate-systemd-fns.patch Patch31: httpd-2.4.63-r1912477+.patch Patch32: httpd-2.4.54-selinux.patch +Patch33: httpd-2.4.63-r1926064.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 @@ -847,6 +848,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Tue Jun 24 2025 Joe Orton - 2.4.63-4 +- mod_dav: add dav_get_base_path() API + * Mon Feb 10 2025 Joe Orton - 2.4.63-3 - sync default httpd.conf with upstream diff --git a/pullrev.sh b/pullrev.sh index f21a7fb..a87d0dc 100755 --- a/pullrev.sh +++ b/pullrev.sh @@ -6,8 +6,8 @@ if [ $# -lt 1 ]; then fi repo="https://svn.apache.org/repos/asf/httpd/httpd/trunk" -#repo="https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x" -ver=2.4.59 +repo="https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x" +ver=$(rpm -q --specfile httpd.spec --qf '%{VERSION}\n' | sed 1q) prefix="httpd-${ver}" suffix="${SUFFIX:-r$1${2:++}}" fn="${prefix}-${suffix}.patch" @@ -64,4 +64,3 @@ echo "+ git add ${fn}" git add "${fn}" echo "+ spec template:" echo "PatchN: ${fn}" -echo "%patch -PN -p1 -b .${suffix}" From 70f6633789e59838cad7e3b31f57bfdfaba65295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Fri, 11 Jul 2025 16:10:54 +0200 Subject: [PATCH 08/20] new version 2.4.64 --- .gitignore | 1 + httpd-2.4.43-socket-activation.patch | 300 ------------------ httpd-2.4.53-separate-systemd-fns.patch | 286 ----------------- httpd-2.4.54-selinux.patch | 64 ---- httpd-2.4.63-r1926064.patch | 54 ---- ...md.patch => httpd-2.4.64-mod_systemd.patch | 32 +- httpd-2.4.64-separate-systemd-fns.patch | 101 ++++++ ...patch => httpd-2.4.64-sslprotdefault.patch | 21 +- httpd.spec | 23 +- sources | 4 +- 10 files changed, 143 insertions(+), 743 deletions(-) delete mode 100644 httpd-2.4.43-socket-activation.patch delete mode 100644 httpd-2.4.53-separate-systemd-fns.patch delete mode 100644 httpd-2.4.54-selinux.patch delete mode 100644 httpd-2.4.63-r1926064.patch rename httpd-2.4.43-mod_systemd.patch => httpd-2.4.64-mod_systemd.patch (78%) create mode 100644 httpd-2.4.64-separate-systemd-fns.patch rename httpd-2.4.43-sslprotdefault.patch => httpd-2.4.64-sslprotdefault.patch (84%) diff --git a/.gitignore b/.gitignore index 0969db5..0453dd4 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,4 @@ x86_64 /httpd-2.4.61.tar.bz2.asc /httpd-2.4.62.tar.bz2.asc /httpd-2.4.63.tar.bz2.asc +/httpd-2.4.64.tar.bz2.asc diff --git a/httpd-2.4.43-socket-activation.patch b/httpd-2.4.43-socket-activation.patch deleted file mode 100644 index 77eaa45..0000000 --- a/httpd-2.4.43-socket-activation.patch +++ /dev/null @@ -1,300 +0,0 @@ -diff --git a/server/listen.c b/server/listen.c -index 9577d60..d718db1 100644 ---- a/server/listen.c -+++ b/server/listen.c -@@ -35,6 +35,10 @@ - #include - #endif - -+#ifdef HAVE_SYSTEMD -+#include -+#endif -+ - /* we know core's module_index is 0 */ - #undef APLOG_MODULE_INDEX - #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX -@@ -60,9 +64,12 @@ static int ap_listenbacklog; - static int ap_listencbratio; - static int send_buffer_size; - static int receive_buffer_size; -+#ifdef HAVE_SYSTEMD -+static int use_systemd = -1; -+#endif - - /* TODO: make_sock is just begging and screaming for APR abstraction */ --static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server) -+static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server, int do_bind_listen) - { - apr_socket_t *s = server->sd; - int one = 1; -@@ -95,20 +102,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server) - return stat; - } - --#if APR_HAVE_IPV6 -- if (server->bind_addr->family == APR_INET6) { -- stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting); -- if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { -- ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069) -- "make_sock: for address %pI, apr_socket_opt_set: " -- "(IPV6_V6ONLY)", -- server->bind_addr); -- apr_socket_close(s); -- return stat; -- } -- } --#endif -- - /* - * To send data over high bandwidth-delay connections at full - * speed we must force the TCP window to open wide enough to keep the -@@ -170,21 +163,37 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server) - } - #endif - -- if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) { -- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072) -- "make_sock: could not bind to address %pI", -- server->bind_addr); -- apr_socket_close(s); -- return stat; -- } -+ if (do_bind_listen) { -+#if APR_HAVE_IPV6 -+ if (server->bind_addr->family == APR_INET6) { -+ stat = apr_socket_opt_set(s, APR_IPV6_V6ONLY, v6only_setting); -+ if (stat != APR_SUCCESS && stat != APR_ENOTIMPL) { -+ ap_log_perror(APLOG_MARK, APLOG_CRIT, stat, p, APLOGNO(00069) -+ "make_sock: for address %pI, apr_socket_opt_set: " -+ "(IPV6_V6ONLY)", -+ server->bind_addr); -+ apr_socket_close(s); -+ return stat; -+ } -+ } -+#endif - -- if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) { -- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073) -- "make_sock: unable to listen for connections " -- "on address %pI", -- server->bind_addr); -- apr_socket_close(s); -- return stat; -+ if ((stat = apr_socket_bind(s, server->bind_addr)) != APR_SUCCESS) { -+ ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_CRIT, stat, p, APLOGNO(00072) -+ "make_sock: could not bind to address %pI", -+ server->bind_addr); -+ apr_socket_close(s); -+ return stat; -+ } -+ -+ if ((stat = apr_socket_listen(s, ap_listenbacklog)) != APR_SUCCESS) { -+ ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_ERR, stat, p, APLOGNO(00073) -+ "make_sock: unable to listen for connections " -+ "on address %pI", -+ server->bind_addr); -+ apr_socket_close(s); -+ return stat; -+ } - } - - #ifdef WIN32 -@@ -335,6 +344,123 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to, - return found; - } - -+#ifdef HAVE_SYSTEMD -+ -+static int find_systemd_socket(process_rec * process, apr_port_t port) { -+ int fdcount, fd; -+ int sdc = sd_listen_fds(0); -+ -+ if (sdc < 0) { -+ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486) -+ "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d", -+ sdc); -+ return -1; -+ } -+ -+ if (sdc == 0) { -+ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487) -+ "find_systemd_socket: At least one socket must be set."); -+ return -1; -+ } -+ -+ fdcount = atoi(getenv("LISTEN_FDS")); -+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) { -+ if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) { -+ return fd; -+ } -+ } -+ -+ return -1; -+} -+ -+static apr_status_t alloc_systemd_listener(process_rec * process, -+ int fd, const char *proto, -+ ap_listen_rec **out_rec) -+{ -+ apr_status_t rv; -+ struct sockaddr sa; -+ socklen_t len = sizeof(struct sockaddr); -+ apr_os_sock_info_t si; -+ ap_listen_rec *rec; -+ *out_rec = NULL; -+ -+ memset(&si, 0, sizeof(si)); -+ -+ rv = getsockname(fd, &sa, &len); -+ -+ if (rv != 0) { -+ rv = apr_get_netos_error(); -+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02489) -+ "getsockname on %d failed.", fd); -+ return rv; -+ } -+ -+ si.os_sock = &fd; -+ si.family = sa.sa_family; -+ si.local = &sa; -+ si.type = SOCK_STREAM; -+ si.protocol = APR_PROTO_TCP; -+ -+ rec = apr_palloc(process->pool, sizeof(ap_listen_rec)); -+ rec->active = 0; -+ rec->next = 0; -+ -+ -+ rv = apr_os_sock_make(&rec->sd, &si, process->pool); -+ if (rv != APR_SUCCESS) { -+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02490) -+ "apr_os_sock_make on %d failed.", fd); -+ return rv; -+ } -+ -+ rv = apr_socket_addr_get(&rec->bind_addr, APR_LOCAL, rec->sd); -+ if (rv != APR_SUCCESS) { -+ ap_log_perror(APLOG_MARK, APLOG_CRIT, rv, process->pool, APLOGNO(02491) -+ "apr_socket_addr_get on %d failed.", fd); -+ return rv; -+ } -+ -+ rec->protocol = apr_pstrdup(process->pool, proto); -+ -+ *out_rec = rec; -+ -+ return make_sock(process->pool, rec, 0); -+} -+ -+static const char *set_systemd_listener(process_rec *process, apr_port_t port, -+ const char *proto) -+{ -+ ap_listen_rec *last, *new; -+ apr_status_t rv; -+ int fd = find_systemd_socket(process, port); -+ if (fd < 0) { -+ return "Systemd socket activation is used, but this port is not " -+ "configured in systemd"; -+ } -+ -+ last = ap_listeners; -+ while (last && last->next) { -+ last = last->next; -+ } -+ -+ rv = alloc_systemd_listener(process, fd, proto, &new); -+ if (rv != APR_SUCCESS) { -+ return "Failed to setup socket passed by systemd using socket activation"; -+ } -+ -+ if (last == NULL) { -+ ap_listeners = last = new; -+ } -+ else { -+ last->next = new; -+ last = new; -+ } -+ -+ return NULL; -+} -+ -+#endif /* HAVE_SYSTEMD */ -+ - static const char *alloc_listener(process_rec *process, const char *addr, - apr_port_t port, const char* proto, - const char *scope_id, void *slave, -@@ -529,7 +655,7 @@ static int open_listeners(apr_pool_t *pool) - } - } - #endif -- if (make_sock(pool, lr) == APR_SUCCESS) { -+ if (make_sock(pool, lr, 1) == APR_SUCCESS) { - ++num_open; - } - else { -@@ -641,8 +767,28 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s) - } - } - -- if (open_listeners(s->process->pool)) { -- return 0; -+#ifdef HAVE_SYSTEMD -+ if (use_systemd) { -+ const char *userdata_key = "ap_open_systemd_listeners"; -+ void *data; -+ /* clear the enviroment on our second run -+ * so that none of our future children get confused. -+ */ -+ apr_pool_userdata_get(&data, userdata_key, s->process->pool); -+ if (!data) { -+ apr_pool_userdata_set((const void *)1, userdata_key, -+ apr_pool_cleanup_null, s->process->pool); -+ } -+ else { -+ sd_listen_fds(1); -+ } -+ } -+ else -+#endif -+ { -+ if (open_listeners(s->process->pool)) { -+ return 0; -+ } - } - - for (lr = ap_listeners; lr; lr = lr->next) { -@@ -732,7 +878,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s, - duplr->bind_addr); - return stat; - } -- make_sock(p, duplr); -+ make_sock(p, duplr, 1); - #if AP_NONBLOCK_WHEN_MULTI_LISTEN - use_nonblock = (ap_listeners && ap_listeners->next); - stat = apr_socket_opt_set(duplr->sd, APR_SO_NONBLOCK, use_nonblock); -@@ -859,6 +1005,11 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, - if (argc < 1 || argc > 2) { - return "Listen requires 1 or 2 arguments."; - } -+#ifdef HAVE_SYSTEMD -+ if (use_systemd == -1) { -+ use_systemd = sd_listen_fds(0) > 0; -+ } -+#endif - - rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool); - if (rv != APR_SUCCESS) { -@@ -894,6 +1045,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, - ap_str_tolower(proto); - } - -+#ifdef HAVE_SYSTEMD -+ if (use_systemd) { -+ return set_systemd_listener(cmd->server->process, port, proto); -+ } -+#endif -+ - return alloc_listener(cmd->server->process, host, port, proto, - scope_id, NULL, cmd->temp_pool); - } diff --git a/httpd-2.4.53-separate-systemd-fns.patch b/httpd-2.4.53-separate-systemd-fns.patch deleted file mode 100644 index 8db5c57..0000000 --- a/httpd-2.4.53-separate-systemd-fns.patch +++ /dev/null @@ -1,286 +0,0 @@ -diff --git a/acinclude.m4 b/acinclude.m4 -index 05abe18..97484c9 100644 ---- a/acinclude.m4 -+++ b/acinclude.m4 -@@ -631,7 +631,6 @@ case $host in - if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then - AC_MSG_WARN([Your system does not support systemd.]) - else -- APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS]) - AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported]) - fi - fi -diff --git a/include/ap_listen.h b/include/ap_listen.h -index 58c2574..d5ed968 100644 ---- a/include/ap_listen.h -+++ b/include/ap_listen.h -@@ -29,6 +29,7 @@ - #include "apr_network_io.h" - #include "httpd.h" - #include "http_config.h" -+#include "apr_optional.h" - - #ifdef __cplusplus - extern "C" { -@@ -143,6 +144,15 @@ AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, - void *dummy, - const char *arg); - -+#ifdef HAVE_SYSTEMD -+APR_DECLARE_OPTIONAL_FN(int, -+ ap_find_systemd_socket, (process_rec *, apr_port_t)); -+ -+APR_DECLARE_OPTIONAL_FN(int, -+ ap_systemd_listen_fds, (int)); -+#endif -+ -+ - #define LISTEN_COMMANDS \ - AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \ - "Maximum length of the queue of pending connections, as used by listen(2)"), \ -diff --git a/modules/arch/unix/mod_systemd.c b/modules/arch/unix/mod_systemd.c -index eda1272..fc059fc 100644 ---- a/modules/arch/unix/mod_systemd.c -+++ b/modules/arch/unix/mod_systemd.c -@@ -35,6 +35,15 @@ - #include - #endif - -+APR_DECLARE_OPTIONAL_FN(int, -+ ap_find_systemd_socket, (process_rec *, apr_port_t)); -+ -+APR_DECLARE_OPTIONAL_FN(int, -+ ap_systemd_listen_fds, (int)); -+ -+APR_DECLARE_OPTIONAL_FN(int, -+ ap_systemd_journal_stream_fd, (const char *, int, int)); -+ - static char describe_listeners[30]; - - static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog, -@@ -145,8 +154,47 @@ static int systemd_monitor(apr_pool_t *p, server_rec *s) - return DECLINED; - } - -+static int ap_find_systemd_socket(process_rec * process, apr_port_t port) { -+ int fdcount, fd; -+ int sdc = sd_listen_fds(0); -+ -+ if (sdc < 0) { -+ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486) -+ "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d", -+ sdc); -+ return -1; -+ } -+ -+ if (sdc == 0) { -+ ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487) -+ "find_systemd_socket: At least one socket must be set."); -+ return -1; -+ } -+ -+ fdcount = atoi(getenv("LISTEN_FDS")); -+ for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) { -+ if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) { -+ return fd; -+ } -+ } -+ -+ return -1; -+} -+ -+static int ap_systemd_listen_fds(int unset_environment){ -+ return sd_listen_fds(unset_environment); -+} -+ -+static int ap_systemd_journal_stream_fd(const char *identifier, int priority, int level_prefix){ -+ return sd_journal_stream_fd("httpd", priority, 0); -+} -+ - static void systemd_register_hooks(apr_pool_t *p) - { -+ APR_REGISTER_OPTIONAL_FN(ap_systemd_listen_fds); -+ APR_REGISTER_OPTIONAL_FN(ap_find_systemd_socket); -+ APR_REGISTER_OPTIONAL_FN(ap_systemd_journal_stream_fd); -+ - /* Enable ap_extended_status. */ - ap_hook_pre_config(systemd_pre_config, NULL, NULL, APR_HOOK_LAST); - /* Signal service is ready. */ -diff --git a/modules/loggers/config.m4 b/modules/loggers/config.m4 -index 0848d2e..8af2299 100644 ---- a/modules/loggers/config.m4 -+++ b/modules/loggers/config.m4 -@@ -5,7 +5,6 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) - APACHE_MODPATH_INIT(loggers) - - APACHE_MODULE(log_config, logging configuration. You won't be able to log requests to the server without this module., , , yes) --APR_ADDTO(MOD_LOG_CONFIG_LDADD, [$SYSTEMD_LIBS]) - - APACHE_MODULE(log_debug, configurable debug logging, , , most) - APACHE_MODULE(log_forensic, forensic logging) -diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c -index 0b11f60..c3f0a51 100644 ---- a/modules/loggers/mod_log_config.c -+++ b/modules/loggers/mod_log_config.c -@@ -172,10 +172,6 @@ - #include - #endif - --#ifdef HAVE_SYSTEMD --#include --#endif -- - #define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b" - - module AP_MODULE_DECLARE_DATA log_config_module; -@@ -1640,8 +1636,15 @@ static apr_status_t wrap_journal_stream(apr_pool_t *p, apr_file_t **outfd, - { - #ifdef HAVE_SYSTEMD - int fd; -+ APR_OPTIONAL_FN_TYPE(ap_systemd_journal_stream_fd) *systemd_journal_stream_fd; -+ -+ systemd_journal_stream_fd = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_journal_stream_fd); -+ if (systemd_journal_stream_fd == NULL) { -+ return APR_ENOTIMPL; -+ } - -- fd = sd_journal_stream_fd("httpd", priority, 0); -+ fd = systemd_journal_stream_fd("httpd", priority, 0); -+ - if (fd < 0) return fd; - - /* This is an AF_UNIX socket fd so is more pipe-like than -diff --git a/modules/loggers/mod_log_config.h b/modules/loggers/mod_log_config.h -index 877a593..bd52a98 100644 ---- a/modules/loggers/mod_log_config.h -+++ b/modules/loggers/mod_log_config.h -@@ -69,6 +69,10 @@ APR_DECLARE_OPTIONAL_FN(ap_log_writer_init*, ap_log_set_writer_init,(ap_log_writ - */ - APR_DECLARE_OPTIONAL_FN(ap_log_writer*, ap_log_set_writer, (ap_log_writer* func)); - -+#ifdef HAVE_SYSTEMD -+APR_DECLARE_OPTIONAL_FN(int, ap_systemd_journal_stream_fd, (const char *, int, int)); -+#endif -+ - #endif /* MOD_LOG_CONFIG */ - /** @} */ - -diff --git a/server/listen.c b/server/listen.c -index d718db1..2a4e87a 100644 ---- a/server/listen.c -+++ b/server/listen.c -@@ -35,10 +35,6 @@ - #include - #endif - --#ifdef HAVE_SYSTEMD --#include --#endif -- - /* we know core's module_index is 0 */ - #undef APLOG_MODULE_INDEX - #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX -@@ -345,34 +341,6 @@ static int find_listeners(ap_listen_rec **from, ap_listen_rec **to, - } - - #ifdef HAVE_SYSTEMD -- --static int find_systemd_socket(process_rec * process, apr_port_t port) { -- int fdcount, fd; -- int sdc = sd_listen_fds(0); -- -- if (sdc < 0) { -- ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486) -- "find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d", -- sdc); -- return -1; -- } -- -- if (sdc == 0) { -- ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487) -- "find_systemd_socket: At least one socket must be set."); -- return -1; -- } -- -- fdcount = atoi(getenv("LISTEN_FDS")); -- for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) { -- if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) { -- return fd; -- } -- } -- -- return -1; --} -- - static apr_status_t alloc_systemd_listener(process_rec * process, - int fd, const char *proto, - ap_listen_rec **out_rec) -@@ -432,6 +400,14 @@ static const char *set_systemd_listener(process_rec *process, apr_port_t port, - { - ap_listen_rec *last, *new; - apr_status_t rv; -+ APR_OPTIONAL_FN_TYPE(ap_find_systemd_socket) *find_systemd_socket; -+ -+ find_systemd_socket = APR_RETRIEVE_OPTIONAL_FN(ap_find_systemd_socket); -+ -+ if (!find_systemd_socket) -+ return "Systemd socket activation is used, but mod_systemd is probably " -+ "not loaded"; -+ - int fd = find_systemd_socket(process, port); - if (fd < 0) { - return "Systemd socket activation is used, but this port is not " -@@ -458,7 +434,6 @@ static const char *set_systemd_listener(process_rec *process, apr_port_t port, - - return NULL; - } -- - #endif /* HAVE_SYSTEMD */ - - static const char *alloc_listener(process_rec *process, const char *addr, -@@ -741,6 +716,9 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s) - int num_listeners = 0; - const char* proto; - int found; -+#ifdef HAVE_SYSTEMD -+ APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds; -+#endif - - for (ls = s; ls; ls = ls->next) { - proto = ap_get_server_protocol(ls); -@@ -780,7 +758,10 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s) - apr_pool_cleanup_null, s->process->pool); - } - else { -- sd_listen_fds(1); -+ systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds); -+ if (systemd_listen_fds != NULL) { -+ systemd_listen_fds(1); -+ } - } - } - else -@@ -997,6 +978,9 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, - apr_port_t port; - apr_status_t rv; - const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); -+#ifdef HAVE_SYSTEMD -+ APR_OPTIONAL_FN_TYPE(ap_systemd_listen_fds) *systemd_listen_fds; -+#endif - - if (err != NULL) { - return err; -@@ -1007,7 +991,12 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, - } - #ifdef HAVE_SYSTEMD - if (use_systemd == -1) { -- use_systemd = sd_listen_fds(0) > 0; -+ systemd_listen_fds = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_listen_fds); -+ if (systemd_listen_fds != NULL) { -+ use_systemd = systemd_listen_fds(0) > 0; -+ } else { -+ use_systemd = 0; -+ } - } - #endif - diff --git a/httpd-2.4.54-selinux.patch b/httpd-2.4.54-selinux.patch deleted file mode 100644 index 661b983..0000000 --- a/httpd-2.4.54-selinux.patch +++ /dev/null @@ -1,64 +0,0 @@ - -Upstream-Status: in trunk not in 2.4.x - -diff --git a/configure.in b/configure.in -index 74015ca..8c0ee10 100644 ---- httpd-2.4.54/modules/arch/unix/config5.m4.selinux -+++ httpd-2.4.54/modules/arch/unix/config5.m4 -@@ -23,6 +23,11 @@ - AC_MSG_WARN([Your system does not support systemd.]) - enable_systemd="no" - else -+ AC_CHECK_LIB(selinux, is_selinux_enabled, [ -+ AC_DEFINE(HAVE_SELINUX, 1, [Defined if SELinux is supported]) -+ APR_ADDTO(MOD_SYSTEMD_LDADD, [-lselinux]) -+ ]) -+ - APR_ADDTO(MOD_SYSTEMD_LDADD, [$SYSTEMD_LIBS]) - fi - ]) ---- httpd-2.4.54/modules/arch/unix/mod_systemd.c.selinux -+++ httpd-2.4.54/modules/arch/unix/mod_systemd.c -@@ -35,6 +35,10 @@ - #include - #endif - -+#ifdef HAVE_SELINUX -+#include -+#endif -+ - APR_DECLARE_OPTIONAL_FN(int, - ap_find_systemd_socket, (process_rec *, apr_port_t)); - -@@ -70,6 +74,20 @@ - return apr_psprintf(p, "%s port %u", addr, sa->port); - } - -+#ifdef HAVE_SELINUX -+static void log_selinux_context(void) -+{ -+ char *con; -+ -+ if (is_selinux_enabled() && getcon(&con) == 0) { -+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, -+ "SELinux policy enabled; " -+ "httpd running as context %s", con); -+ freecon(con); -+ } -+} -+#endif -+ - /* Report the service is ready in post_config, which could be during - * startup or after a reload. The server could still hit a fatal - * startup error after this point during ap_run_mpm(), so this is -@@ -87,6 +105,10 @@ - if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) - return OK; - -+#ifdef HAVE_SELINUX -+ log_selinux_context(); -+#endif -+ - for (lr = ap_listeners; lr; lr = lr->next) { - char *s = dump_listener(lr, ptemp); - diff --git a/httpd-2.4.63-r1926064.patch b/httpd-2.4.63-r1926064.patch deleted file mode 100644 index e8115c7..0000000 --- a/httpd-2.4.63-r1926064.patch +++ /dev/null @@ -1,54 +0,0 @@ -# ./pullrev.sh 1926064 -http://svn.apache.org/viewvc?view=revision&revision=1926064 - ---- httpd-2.4.63/include/ap_mmn.h -+++ httpd-2.4.63/include/ap_mmn.h -@@ -608,6 +608,7 @@ - * 20120211.136 (2.4.63-dev) Add wait_io field to struct process_score - * 20120211.137 (2.4.63-dev) Add AP_MPMQ_CAN_WAITIO - * 20120211.138 (2.4.63-dev) Add is_host_matchable to proxy_worker_shared -+ * 20120211.139 (2.4.63-dev) Add dav_get_base_path() to mod_dav - */ - - #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ -@@ -615,7 +616,7 @@ - #ifndef MODULE_MAGIC_NUMBER_MAJOR - #define MODULE_MAGIC_NUMBER_MAJOR 20120211 - #endif --#define MODULE_MAGIC_NUMBER_MINOR 138 /* 0...n */ -+#define MODULE_MAGIC_NUMBER_MINOR 139 /* 0...n */ - - /** - * Determine if the server's current MODULE_MAGIC_NUMBER is at least a -only in patch2: ---- httpd-2.4.63/modules/dav/main/mod_dav.c -+++ httpd-2.4.63/modules/dav/main/mod_dav.c -@@ -250,6 +250,13 @@ - return dav_get_provider(r)->search; - } - -+DAV_DECLARE(const char *) dav_get_base_path(request_rec *r) -+{ -+ dav_dir_conf *conf = ap_get_module_config(r->per_dir_config, &dav_module); -+ -+ return conf && conf->base ? conf->base : NULL; -+} -+ - /* - * Command handler for the DAV directive, which is TAKE1. - */ -only in patch2: ---- httpd-2.4.63/modules/dav/main/mod_dav.h -+++ httpd-2.4.63/modules/dav/main/mod_dav.h -@@ -430,6 +430,11 @@ - DAV_DECLARE(dav_error *) dav_get_resource(request_rec *r, int label_allowed, - int use_checked_in, dav_resource **res_p); - -+/* -+** If DavBasePath is configured for the request location, return the -+** configured path, otherwise NULL. -+*/ -+DAV_DECLARE(const char *) dav_get_base_path(request_rec *r); - - /* -------------------------------------------------------------------- - ** diff --git a/httpd-2.4.43-mod_systemd.patch b/httpd-2.4.64-mod_systemd.patch similarity index 78% rename from httpd-2.4.43-mod_systemd.patch rename to httpd-2.4.64-mod_systemd.patch index 8d7922e..cad4a01 100644 --- a/httpd-2.4.43-mod_systemd.patch +++ b/httpd-2.4.64-mod_systemd.patch @@ -1,10 +1,12 @@ More verbose startup logging for mod_systemd. ---- httpd-2.4.43/modules/arch/unix/mod_systemd.c.mod_systemd -+++ httpd-2.4.43/modules/arch/unix/mod_systemd.c -@@ -29,11 +29,14 @@ - #include "mpm_common.h" +diff --git a/modules/arch/unix/mod_systemd.c b/modules/arch/unix/mod_systemd.c +index 22482fd..b46d3ef 100644 +--- a/modules/arch/unix/mod_systemd.c ++++ b/modules/arch/unix/mod_systemd.c +@@ -34,11 +34,14 @@ + #endif #include "systemd/sd-daemon.h" +#include "systemd/sd-journal.h" @@ -18,9 +20,9 @@ More verbose startup logging for mod_systemd. static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp) { -@@ -44,6 +47,20 @@ - return OK; +@@ -63,6 +66,20 @@ static void log_selinux_context(void) } + #endif +static char *dump_listener(ap_listen_rec *lr, apr_pool_t *p) +{ @@ -39,21 +41,17 @@ More verbose startup logging for mod_systemd. /* Report the service is ready in post_config, which could be during * startup or after a reload. The server could still hit a fatal * startup error after this point during ap_run_mpm(), so this is -@@ -51,19 +68,51 @@ - * the TCP ports so new connections will not be rejected. There will - * always be a possible async failure event simultaneous to the - * service reporting "ready", so this should be good enough. */ --static int systemd_post_config(apr_pool_t *p, apr_pool_t *plog, -+static int systemd_post_config(apr_pool_t *pconf, apr_pool_t *plog, +@@ -73,23 +90,52 @@ static void log_selinux_context(void) + static int systemd_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *main_server) { + ap_listen_rec *lr; + apr_size_t plen = sizeof describe_listeners; + char *p = describe_listeners; + -+ if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) -+ return OK; -+ + if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG) + return OK; + + for (lr = ap_listeners; lr; lr = lr->next) { + char *s = dump_listener(lr, ptemp); + @@ -74,6 +72,10 @@ More verbose startup logging for mod_systemd. + } + } + + #ifdef HAVE_SELINUX + log_selinux_context(); + #endif + sd_notify(0, "READY=1\n" "STATUS=Configuration loaded.\n"); + diff --git a/httpd-2.4.64-separate-systemd-fns.patch b/httpd-2.4.64-separate-systemd-fns.patch new file mode 100644 index 0000000..6947ee6 --- /dev/null +++ b/httpd-2.4.64-separate-systemd-fns.patch @@ -0,0 +1,101 @@ +diff --git a/acinclude.m4 b/acinclude.m4 +index 05abe18..97484c9 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -631,7 +631,6 @@ case $host in + if test "${ac_cv_header_systemd_sd_daemon_h}" = "no" || test -z "${SYSTEMD_LIBS}"; then + AC_MSG_WARN([Your system does not support systemd.]) + else +- APR_ADDTO(HTTPD_LIBS, [$SYSTEMD_LIBS]) + AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is supported]) + fi + fi +diff --git a/modules/arch/unix/mod_systemd.c b/modules/arch/unix/mod_systemd.c +index af68249..7232a45 100644 +--- a/modules/arch/unix/mod_systemd.c ++++ b/modules/arch/unix/mod_systemd.c +@@ -40,6 +40,9 @@ + #include + #endif + ++APR_DECLARE_OPTIONAL_FN(int, ++ ap_systemd_journal_stream_fd, (const char *, int, int)); ++ + static char describe_listeners[30]; + + static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog, +@@ -217,10 +220,15 @@ static int ap_systemd_listen_fds(int unset_environment){ + return sd_listen_fds(unset_environment); + } + ++static int ap_systemd_journal_stream_fd(const char *identifier, int priority, int level_prefix){ ++ return sd_journal_stream_fd("httpd", priority, 0); ++} ++ + static void systemd_register_hooks(apr_pool_t *p) + { + APR_REGISTER_OPTIONAL_FN(ap_systemd_listen_fds); + APR_REGISTER_OPTIONAL_FN(ap_find_systemd_socket); ++ APR_REGISTER_OPTIONAL_FN(ap_systemd_journal_stream_fd); + + /* Enable ap_extended_status. */ + ap_hook_pre_config(systemd_pre_config, NULL, NULL, APR_HOOK_LAST); +diff --git a/modules/loggers/config.m4 b/modules/loggers/config.m4 +index 0848d2e..8af2299 100644 +--- a/modules/loggers/config.m4 ++++ b/modules/loggers/config.m4 +@@ -5,7 +5,6 @@ dnl APACHE_MODULE(name, helptext[, objects[, structname[, default[, config]]]]) + APACHE_MODPATH_INIT(loggers) + + APACHE_MODULE(log_config, logging configuration. You won't be able to log requests to the server without this module., , , yes) +-APR_ADDTO(MOD_LOG_CONFIG_LDADD, [$SYSTEMD_LIBS]) + + APACHE_MODULE(log_debug, configurable debug logging, , , most) + APACHE_MODULE(log_forensic, forensic logging) +diff --git a/modules/loggers/mod_log_config.c b/modules/loggers/mod_log_config.c +index 694f447..a65b982 100644 +--- a/modules/loggers/mod_log_config.c ++++ b/modules/loggers/mod_log_config.c +@@ -172,10 +172,6 @@ + #include + #endif + +-#ifdef HAVE_SYSTEMD +-#include +-#endif +- + #define DEFAULT_LOG_FORMAT "%h %l %u %t \"%r\" %>s %b" + + module AP_MODULE_DECLARE_DATA log_config_module; +@@ -1640,8 +1636,15 @@ static apr_status_t wrap_journal_stream(apr_pool_t *p, apr_file_t **outfd, + { + #ifdef HAVE_SYSTEMD + int fd; ++ APR_OPTIONAL_FN_TYPE(ap_systemd_journal_stream_fd) *systemd_journal_stream_fd; ++ ++ systemd_journal_stream_fd = APR_RETRIEVE_OPTIONAL_FN(ap_systemd_journal_stream_fd); ++ if (systemd_journal_stream_fd == NULL) { ++ return APR_ENOTIMPL; ++ } + +- fd = sd_journal_stream_fd("httpd", priority, 0); ++ fd = systemd_journal_stream_fd("httpd", priority, 0); ++ + if (fd < 0) return fd; + + /* This is an AF_UNIX socket fd so is more pipe-like than +diff --git a/modules/loggers/mod_log_config.h b/modules/loggers/mod_log_config.h +index 877a593..bd52a98 100644 +--- a/modules/loggers/mod_log_config.h ++++ b/modules/loggers/mod_log_config.h +@@ -69,6 +69,10 @@ APR_DECLARE_OPTIONAL_FN(ap_log_writer_init*, ap_log_set_writer_init,(ap_log_writ + */ + APR_DECLARE_OPTIONAL_FN(ap_log_writer*, ap_log_set_writer, (ap_log_writer* func)); + ++#ifdef HAVE_SYSTEMD ++APR_DECLARE_OPTIONAL_FN(int, ap_systemd_journal_stream_fd, (const char *, int, int)); ++#endif ++ + #endif /* MOD_LOG_CONFIG */ + /** @} */ + diff --git a/httpd-2.4.43-sslprotdefault.patch b/httpd-2.4.64-sslprotdefault.patch similarity index 84% rename from httpd-2.4.43-sslprotdefault.patch rename to httpd-2.4.64-sslprotdefault.patch index d089823..6d97935 100644 --- a/httpd-2.4.43-sslprotdefault.patch +++ b/httpd-2.4.64-sslprotdefault.patch @@ -1,8 +1,8 @@ diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c -index 27e7a53..b53f3f8 100644 +index 8fae1f8..c5dce7f 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c -@@ -119,7 +119,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p) +@@ -127,7 +127,7 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p) mctx->ticket_key = NULL; #endif @@ -11,7 +11,7 @@ index 27e7a53..b53f3f8 100644 mctx->protocol_set = 0; mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET; -@@ -263,6 +263,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p, +@@ -268,6 +268,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p, if (add->protocol_set) { mrg->protocol_set = 1; mrg->protocol = add->protocol; @@ -19,20 +19,19 @@ index 27e7a53..b53f3f8 100644 } else { mrg->protocol_set = base->protocol_set; - diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c -index bfad47a..b0fcf81 100644 +index 4e265b3..2fbd076 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c -@@ -577,6 +577,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, +@@ -638,6 +638,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, MODSSL_SSL_METHOD_CONST SSL_METHOD *method = NULL; char *cp; int protocol = mctx->protocol; + int protocol_set = mctx->protocol_set; SSLSrvConfigRec *sc = mySrvConfig(s); #if OPENSSL_VERSION_NUMBER >= 0x10100000L - int prot; -@@ -586,12 +587,18 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, + /* default is highest supported version, will be overridden below */ +@@ -652,12 +653,18 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, * Create the new per-server SSL context */ if (protocol == SSL_PROTOCOL_NONE) { @@ -56,7 +55,7 @@ index bfad47a..b0fcf81 100644 #ifndef OPENSSL_NO_SSL3 (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""), #endif -@@ -604,7 +611,8 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, +@@ -670,7 +677,8 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, #endif #endif NULL); @@ -66,7 +65,7 @@ index bfad47a..b0fcf81 100644 ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s, "Creating new SSL context (protocols: %s)", cp); -@@ -705,13 +713,15 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, +@@ -776,13 +784,15 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, prot = SSL3_VERSION; #endif } else { @@ -88,7 +87,7 @@ index bfad47a..b0fcf81 100644 /* Next we scan for the minimal protocol version we should provide, * but we do not allow holes between max and min */ -@@ -731,7 +741,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, +@@ -806,7 +816,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s, prot = SSL3_VERSION; } #endif diff --git a/httpd.spec b/httpd.spec index a9cd66c..15453d2 100644 --- a/httpd.spec +++ b/httpd.spec @@ -30,8 +30,8 @@ Summary: Apache HTTP Server Name: httpd -Version: 2.4.63 -Release: 4%{?dist} +Version: 2.4.64 +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 @@ -89,19 +89,17 @@ Patch3: httpd-2.4.43-deplibs.patch Patch19: httpd-2.4.53-detect-systemd.patch # Features/functional changes Patch20: httpd-2.4.48-r1842929+.patch -Patch21: httpd-2.4.43-mod_systemd.patch +Patch21: httpd-2.4.64-mod_systemd.patch Patch22: httpd-2.4.53-export.patch Patch23: httpd-2.4.43-corelimit.patch Patch24: httpd-2.4.54-icons.patch Patch25: httpd-2.4.43-cachehardmax.patch -Patch26: httpd-2.4.43-socket-activation.patch -Patch27: httpd-2.4.43-sslciphdefault.patch -Patch28: httpd-2.4.43-sslprotdefault.patch -Patch29: httpd-2.4.43-logjournal.patch -Patch30: httpd-2.4.53-separate-systemd-fns.patch -Patch31: httpd-2.4.63-r1912477+.patch -Patch32: httpd-2.4.54-selinux.patch -Patch33: httpd-2.4.63-r1926064.patch +Patch26: httpd-2.4.43-sslciphdefault.patch +Patch27: httpd-2.4.64-sslprotdefault.patch +Patch28: httpd-2.4.43-logjournal.patch +Patch29: httpd-2.4.63-r1912477+.patch +Patch30: httpd-2.4.64-selinux.patch +Patch31: httpd-2.4.64-separate-systemd-fns.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 @@ -848,6 +846,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Fri Jul 11 2025 Luboš Uhliarik - 2.4.64-1 +- new version 2.4.64 + * Tue Jun 24 2025 Joe Orton - 2.4.63-4 - mod_dav: add dav_get_base_path() API diff --git a/sources b/sources index f188c2a..c5568c0 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (httpd-2.4.63.tar.bz2) = a804ca564dfee5907fe4ce4f36884815bace0621bc7b8c9aa7c99472a954aa19cb13733f90678ff3d58ab3c76cc0e33a27e1035dc1d8cb597a9622154c59ef48 -SHA512 (httpd-2.4.63.tar.bz2.asc) = 3496290be3ff202c820636f6c1548dda363eb6a5c6c1ae88e7154eb839a71c32b6531a33a5a62159601d4a079ed6d7bbbfcf9cbe143d0941b3ffcbed783db9bf +SHA512 (httpd-2.4.64.tar.bz2) = 299cb0d87a7e0e0a99d22bba7349b6b07c69222897410f9670af29896288d1f4e1da81d22ac9e1d8d6ea096e88044ab1dd34555b40a4b1b1cb3fd4b1d1897a7a +SHA512 (httpd-2.4.64.tar.bz2.asc) = 1a28214c8468288477f706422ab3419e186ef37dc1eb55760a7e951605e08e295230b6d828948693a9d5ba247e352b205254c999763fa6845dab2f703152e1d8 SHA512 (KEYS) = 88c848b7ab9e4915d6625dcad3e8328673b0448f2ce76f2c44eecc612cf6afbce3287a4ee7219a44c6fcc61d5ecb2a1a8545456a4a16b90400263d7249cbf192 From 1f087eb8b1e670cc371e8ca639aa98de477311e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Fri, 11 Jul 2025 17:05:03 +0200 Subject: [PATCH 09/20] Remove obsolete patch --- httpd.spec | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/httpd.spec b/httpd.spec index 15453d2..702f62f 100644 --- a/httpd.spec +++ b/httpd.spec @@ -98,8 +98,7 @@ Patch26: httpd-2.4.43-sslciphdefault.patch Patch27: httpd-2.4.64-sslprotdefault.patch Patch28: httpd-2.4.43-logjournal.patch Patch29: httpd-2.4.63-r1912477+.patch -Patch30: httpd-2.4.64-selinux.patch -Patch31: httpd-2.4.64-separate-systemd-fns.patch +Patch30: httpd-2.4.64-separate-systemd-fns.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 From 47d73dc1b5021b420fca68e7ac1cbb5e1b441987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Thu, 17 Jul 2025 14:49:12 +0200 Subject: [PATCH 10/20] Fix RewriteRule with inverted pattern and RewriteCond regression --- httpd-2.4.64-r1927270.patch | 25 +++++++++++++++++++++++++ httpd.spec | 7 ++++++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 httpd-2.4.64-r1927270.patch diff --git a/httpd-2.4.64-r1927270.patch b/httpd-2.4.64-r1927270.patch new file mode 100644 index 0000000..21b2b9d --- /dev/null +++ b/httpd-2.4.64-r1927270.patch @@ -0,0 +1,25 @@ +From 6e59b124221014bd1c23053e9bb63fb3362387d9 Mon Sep 17 00:00:00 2001 +From: Eric Covener +Date: Wed, 16 Jul 2025 17:33:21 +0000 +Subject: [PATCH] rc already is set by result of expression eval + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1927270 13f79535-47bb-0310-9956-ffa450edef68 +--- + modules/mappers/mod_rewrite.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c +index a6c35a0be1f..a71110bc76e 100644 +--- a/modules/mappers/mod_rewrite.c ++++ b/modules/mappers/mod_rewrite.c +@@ -4283,9 +4283,6 @@ static cond_return_type apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ct + p->pattern - p->pskip, err); + rc = COND_RC_NOMATCH; + } +- else { +- rc = COND_RC_MATCH; +- } + /* update briRC backref info */ + if (rc && !(p->flags & CONDFLAG_NOTMATCH)) { + ctx->briRC.source = source; + diff --git a/httpd.spec b/httpd.spec index 702f62f..1e33f96 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.64 -Release: 1%{?dist} +Release: 2%{?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 @@ -103,6 +103,8 @@ Patch30: httpd-2.4.64-separate-systemd-fns.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 Patch60: httpd-2.4.43-enable-sslv3.patch +# https://bz.apache.org/bugzilla/show_bug.cgi?id=69745 +Patch61: httpd-2.4.64-r1927270.patch # Security fixes # Patch200: ... @@ -845,6 +847,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Thu Jul 17 2025 Luboš Uhliarik - 2.4.64-2 +- Fix RewriteRule with inverted pattern and RewriteCond regression + * Fri Jul 11 2025 Luboš Uhliarik - 2.4.64-1 - new version 2.4.64 From b4edf40a550e2f2ebd249a7442d9bddc8313ba08 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 24 Jul 2025 17:06:59 +0000 Subject: [PATCH 11/20] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- httpd.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/httpd.spec b/httpd.spec index 1e33f96..2952a56 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.64 -Release: 2%{?dist} +Release: 3%{?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 @@ -847,6 +847,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Thu Jul 24 2025 Fedora Release Engineering - 2.4.64-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Thu Jul 17 2025 Luboš Uhliarik - 2.4.64-2 - Fix RewriteRule with inverted pattern and RewriteCond regression From 4797340d3d5d3ed81b86cc82bafb3a654df93a54 Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Wed, 6 Aug 2025 14:26:22 -0400 Subject: [PATCH 12/20] genssl: Disable dhparams generation SSCG 3.0.3+ has a --no-dhparams-file argument, which we should use instead of creating an unused one in a private /tmp path. Signed-off-by: Stephen Gallagher --- httpd-ssl-gencerts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpd-ssl-gencerts b/httpd-ssl-gencerts index 5c271f7..5a3d8ed 100755 --- a/httpd-ssl-gencerts +++ b/httpd-ssl-gencerts @@ -33,7 +33,7 @@ sscg -q \ --cert-file /etc/pki/tls/certs/localhost.crt \ --cert-key-file /etc/pki/tls/private/localhost.key \ --ca-file /etc/pki/tls/certs/localhost.crt \ - --dhparams-file /tmp/dhparams.pem \ + --no-dhparams-file \ --lifetime 365 \ --hostname $FQDN \ --email root@$FQDN From 817134c70cec8e5f183de160cface9d46dc27893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Mon, 8 Sep 2025 16:29:34 +0200 Subject: [PATCH 13/20] Add tmpfiles.d rules for /var directories (bootc compatibility) --- httpd.spec | 5 ++++- httpd.tmpfiles | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/httpd.spec b/httpd.spec index 2952a56..20d6771 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.64 -Release: 3%{?dist} +Release: 4%{?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 @@ -847,6 +847,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Mon Sep 08 2025 Luboš Uhliarik - 2.4.64-4 +- Add tmpfiles.d rules for /var directories (bootc compatibility) + * Thu Jul 24 2025 Fedora Release Engineering - 2.4.64-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/httpd.tmpfiles b/httpd.tmpfiles index f148886..a845ab5 100644 --- a/httpd.tmpfiles +++ b/httpd.tmpfiles @@ -1,2 +1,9 @@ d /run/httpd 710 root apache d /run/httpd/htcacheclean 700 apache apache +d /var/log/httpd 700 root root - +d /var/www 755 root root - +d /var/www/html 755 root root - +d /var/www/cgi-bin 755 root root - +d /var/lib/httpd 700 apache apache - +d /var/cache/httpd 700 apache apache - +d /var/cache/httpd/proxy 700 apache apache - From 04d6a208061cc5627fb7af9db8b9c6a8383ffbb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Sat, 18 Oct 2025 03:30:41 +0200 Subject: [PATCH 14/20] new version 2.4.65 mod_proxy_hcheck: reschedule health checks after child process restart --- .gitignore | 1 + httpd-2.4.64-r1927270.patch | 25 ------------- httpd-2.4.65-hcheck-stuck.patch | 66 +++++++++++++++++++++++++++++++++ httpd.spec | 11 ++++-- sources | 4 +- 5 files changed, 76 insertions(+), 31 deletions(-) delete mode 100644 httpd-2.4.64-r1927270.patch create mode 100644 httpd-2.4.65-hcheck-stuck.patch diff --git a/.gitignore b/.gitignore index 0453dd4..f2fccfd 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,4 @@ x86_64 /httpd-2.4.62.tar.bz2.asc /httpd-2.4.63.tar.bz2.asc /httpd-2.4.64.tar.bz2.asc +/httpd-2.4.65.tar.bz2.asc diff --git a/httpd-2.4.64-r1927270.patch b/httpd-2.4.64-r1927270.patch deleted file mode 100644 index 21b2b9d..0000000 --- a/httpd-2.4.64-r1927270.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 6e59b124221014bd1c23053e9bb63fb3362387d9 Mon Sep 17 00:00:00 2001 -From: Eric Covener -Date: Wed, 16 Jul 2025 17:33:21 +0000 -Subject: [PATCH] rc already is set by result of expression eval - -git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1927270 13f79535-47bb-0310-9956-ffa450edef68 ---- - modules/mappers/mod_rewrite.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/modules/mappers/mod_rewrite.c b/modules/mappers/mod_rewrite.c -index a6c35a0be1f..a71110bc76e 100644 ---- a/modules/mappers/mod_rewrite.c -+++ b/modules/mappers/mod_rewrite.c -@@ -4283,9 +4283,6 @@ static cond_return_type apply_rewrite_cond(rewritecond_entry *p, rewrite_ctx *ct - p->pattern - p->pskip, err); - rc = COND_RC_NOMATCH; - } -- else { -- rc = COND_RC_MATCH; -- } - /* update briRC backref info */ - if (rc && !(p->flags & CONDFLAG_NOTMATCH)) { - ctx->briRC.source = source; - diff --git a/httpd-2.4.65-hcheck-stuck.patch b/httpd-2.4.65-hcheck-stuck.patch new file mode 100644 index 0000000..315b9c2 --- /dev/null +++ b/httpd-2.4.65-hcheck-stuck.patch @@ -0,0 +1,66 @@ +--- a/modules/proxy/mod_proxy_hcheck.c ++++ b/modules/proxy/mod_proxy_hcheck.c +@@ -989,12 +989,30 @@ static apr_status_t hc_watchdog_callback(int state + sctx_t *ctx = (sctx_t *)data; + server_rec *s = ctx->s; + proxy_server_conf *conf; ++ proxy_worker **workers; ++ proxy_worker *worker; ++ apr_time_t now; ++ int i, n; + ++ conf = (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); ++ balancer = (proxy_balancer *)conf->balancers->elts; ++ + switch (state) { + case AP_WATCHDOG_STATE_STARTING: + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03258) + "%s watchdog started.", + HCHECK_WATHCHDOG_NAME); ++ /* set last update time for all workers */ ++ now = apr_time_now(); ++ for (i = 0; i < conf->balancers->nelts; i++, balancer++) { ++ workers = (proxy_worker **)balancer->workers->elts; ++ for (n = 0; n < balancer->workers->nelts; n++, ++workers) { ++ worker = *workers; ++ if (worker->s->updated == 0) { ++ worker->s->updated = now; ++ } ++ } ++ } + #if HC_USE_THREADS + if (tpsize && hctp == NULL) { + rv = apr_thread_pool_create(&hctp, tpsize, +@@ -1020,21 +1038,13 @@ static apr_status_t hc_watchdog_callback(int state + + case AP_WATCHDOG_STATE_RUNNING: + /* loop thru all workers */ +- if (s) { +- int i; +- conf = (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); +- balancer = (proxy_balancer *)conf->balancers->elts; +- ctx->s = s; ++ { ++ now = apr_time_now(); + for (i = 0; i < conf->balancers->nelts; i++, balancer++) { +- int n; +- apr_time_t now; +- proxy_worker **workers; +- proxy_worker *worker; + /* Have any new balancers or workers been added dynamically? */ + ap_proxy_sync_balancer(balancer, s, conf); + workers = (proxy_worker **)balancer->workers->elts; +- now = apr_time_now(); +- for (n = 0; n < balancer->workers->nelts; n++) { ++ for (n = 0; n < balancer->workers->nelts; n++, workers++) { + worker = *workers; + if (!PROXY_WORKER_IS(worker, PROXY_WORKER_STOPPED) && + (worker->s->method != NONE) && +@@ -1074,7 +1084,6 @@ static apr_status_t hc_watchdog_callback(int state + hc_check(NULL, baton); + } + } +- workers++; + } + } + } diff --git a/httpd.spec b/httpd.spec index 20d6771..9d718a5 100644 --- a/httpd.spec +++ b/httpd.spec @@ -30,8 +30,8 @@ Summary: Apache HTTP Server Name: httpd -Version: 2.4.64 -Release: 4%{?dist} +Version: 2.4.65 +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 @@ -103,8 +103,7 @@ Patch30: httpd-2.4.64-separate-systemd-fns.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 Patch60: httpd-2.4.43-enable-sslv3.patch -# https://bz.apache.org/bugzilla/show_bug.cgi?id=69745 -Patch61: httpd-2.4.64-r1927270.patch +Patch61: httpd-2.4.65-hcheck-stuck.patch # Security fixes # Patch200: ... @@ -847,6 +846,10 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Sat Oct 18 2025 Luboš Uhliarik - 2.4.65-1 +- new version 2.4.65 +- mod_proxy_hcheck: reschedule health checks after child process restart + * Mon Sep 08 2025 Luboš Uhliarik - 2.4.64-4 - Add tmpfiles.d rules for /var directories (bootc compatibility) diff --git a/sources b/sources index c5568c0..8d4165c 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (httpd-2.4.64.tar.bz2) = 299cb0d87a7e0e0a99d22bba7349b6b07c69222897410f9670af29896288d1f4e1da81d22ac9e1d8d6ea096e88044ab1dd34555b40a4b1b1cb3fd4b1d1897a7a -SHA512 (httpd-2.4.64.tar.bz2.asc) = 1a28214c8468288477f706422ab3419e186ef37dc1eb55760a7e951605e08e295230b6d828948693a9d5ba247e352b205254c999763fa6845dab2f703152e1d8 +SHA512 (httpd-2.4.65.tar.bz2) = 202f8bfe2aafcfbcd7315191d466e9c10b9a8c0abafb7864510b6e1abe4cb660aaacc2456aa77d43e48ef7a49e591d0b54170d3daf67abc3e06c3da1c63fdffc +SHA512 (httpd-2.4.65.tar.bz2.asc) = edcf02be97567fb28fef78f757e3355802575782ab452eaea79da70812b20ef4ba49a609e409a9664ec2546720b303deebbd563f3079ce4e77d67b91816210d1 SHA512 (KEYS) = 88c848b7ab9e4915d6625dcad3e8328673b0448f2ce76f2c44eecc612cf6afbce3287a4ee7219a44c6fcc61d5ecb2a1a8545456a4a16b90400263d7249cbf192 From 23f7eb497eefd8e1fba1494b946e39757ec46e51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Tue, 4 Nov 2025 12:08:54 +0100 Subject: [PATCH 15/20] mod_ssl: Add SSLVHostSNIPolicy directive to set the compatibility level required for VirtualHost matching. --- httpd-2.4.65-sslvhostsnipolicy.patch | 545 +++++++++++++++++++++++++++ httpd.spec | 7 +- 2 files changed, 551 insertions(+), 1 deletion(-) create mode 100644 httpd-2.4.65-sslvhostsnipolicy.patch diff --git a/httpd-2.4.65-sslvhostsnipolicy.patch b/httpd-2.4.65-sslvhostsnipolicy.patch new file mode 100644 index 0000000..401882a --- /dev/null +++ b/httpd-2.4.65-sslvhostsnipolicy.patch @@ -0,0 +1,545 @@ +From 0e0995bef84a66c9dabe75d6e81376896cc819bd Mon Sep 17 00:00:00 2001 +From: Joe Orton +Date: Tue, 4 Nov 2025 12:05:05 +0100 +Subject: [PATCH] [PATCH] mod_ssl: Add SSLVHostSNIPolicy directive to set the + compatibility level required for VirtualHost matching. + +For "secure" and "authonly" modes, a hash of the policy-relevant vhost +configuration is created and stored in the post_config hooks, reducing +the runtime code complexity (and overhead). + +* modules/ssl/ssl_engine_kernel.c (ssl_check_vhost_sni_policy): New + function, replacing ssl_server_compatible et al. + +* modules/ssl/ssl_engine_config.c (ssl_cmd_SSLVHostSNIPolicy): New + function. + +* modules/ssl/ssl_engine_init.c (md5_strarray_cmp, md5_strarray_hash, + hash_sni_policy_pk, hash_sni_policy_auth, create_sni_policy_hash): + New functions. + (ssl_init_Module): Invoke create_sni_policy_hash to store the hash + for every SSLSrvConfigRec. + +* modules/ssl/ssl_private.h (SSLModConfigRec): Add snivh_policy field. + (SSLSrvConfigRec): Add sni_policy_hash field. + +PR: 69743 +GitHub: closes #561 +--- + docs/manual/mod/mod_ssl.html.en | 77 +++++++++++++++++++ + modules/ssl/mod_ssl.c | 2 + + modules/ssl/ssl_engine_config.c | 41 ++++++++++ + modules/ssl/ssl_engine_init.c | 106 ++++++++++++++++++++++++++ + modules/ssl/ssl_engine_kernel.c | 131 ++++++-------------------------- + modules/ssl/ssl_private.h | 17 +++++ + 6 files changed, 265 insertions(+), 109 deletions(-) + +diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en +index e2a4a99..95f0667 100644 +--- a/docs/manual/mod/mod_ssl.html.en ++++ b/docs/manual/mod/mod_ssl.html.en +@@ -125,6 +125,7 @@ to provide the cryptography engine.

+
  • SSLUseStapling
  • +
  • SSLVerifyClient
  • +
  • SSLVerifyDepth
  • ++
  • SSLVHostSNIPolicy
  • + +

    Bugfix checklist

    See also

    +
      +@@ -2863,6 +2864,82 @@ known to the server (i.e. the CA's certificate is under +

      Example

      SSLVerifyDepth 10
      +
      + ++ ++
      top
      ++

      SSLVHostSNIPolicy Directive

      ++ ++ ++ ++ ++ ++ ++ ++ ++
      Description:Set compatibility policy for SNI client access to virtual hosts.
      Syntax:SSLVHostSNIPolicy strict|secure|authonly|insecure
      Default:SSLVHostSNIPolicy secure
      Context:server config
      Status:Extension
      Module:mod_ssl
      Compatibility:Available in httpd 2.4.65 and later

      This directive sets the policy applied when checking whether the ++<VirtualHost> ++identified by the Host request header in an HTTP request ++is compatible with the <VirtualHost> identified from the SNI ++extension sent during the initial TLS connection handshake. If an HTTP ++request is associated with a virtual host which has an incompatible ++SSL/TLS configuration under the policy used, an HTTP error response ++with status code 421 ("Misdirected Request") will be sent.

      ++ ++

      The policy also applies to TLS connections where an SNI extension ++is not sent during the handshake, implicitly using the default or ++first virtual host definition. If the Host header in an HTTP request ++on such a connection identifies any other non-default virtual host, ++the compatibility policy is tested.

      ++ ++

      The strict policy blocks all HTTP requests which are ++identified with a different virtual host to that identifed by SNI. ++The insecure policy allows all HTTP requests regardless ++of virtual host identified; such a configuration may be vulnerable to ++CVE-2025-23048. ++

      ++ ++

      The (default) secure, and authonly ++policies compare specific aspects of the SSL configuration for the two ++virtual hosts, which are grouped into two categories: ++ ++

      ++ ++This table illustrates whether an HTTP request will be blocked or ++allowed when the virtual host configurations differ as described, ++under each different policy setting: ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++
      Policy modeAny VirtualHost mismatchServer certificate/key,
      or protocol/cipher restrictions
      Client verification/
      authentication settings
      strictblockedblockedblocked
      secureallowedblockedblocked
      authonlyallowedblockedallowed
      insecureallowedallowedallowed
      ++

      ++

      Example

      SSLVHostSNIPolicy authonly
      ++
      ++ ++ +
      + +
      +diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c +index fb66d18..c0fdafd 100644 +--- a/modules/ssl/mod_ssl.c ++++ b/modules/ssl/mod_ssl.c +@@ -80,6 +80,8 @@ static const command_rec ssl_config_cmds[] = { + SSL_CMD_SRV(RandomSeed, TAKE23, + "SSL Pseudo Random Number Generator (PRNG) seeding source " + "('startup|connect builtin|file:/path|exec:/path [bytes]')") ++ SSL_CMD_SRV(VHostSNIPolicy, TAKE1, ++ "SSL VirtualHost SNI compatibility policy setting") + + /* + * Per-server context configuration directives +diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c +index c5dce7f..31a1942 100644 +--- a/modules/ssl/ssl_engine_config.c ++++ b/modules/ssl/ssl_engine_config.c +@@ -82,6 +82,9 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s) + #ifdef HAVE_FIPS + mc->fips = UNSET; + #endif ++#ifdef HAVE_TLSEXT ++ mc->snivh_policy = MODSSL_SNIVH_SECURE; ++#endi + + apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY, + apr_pool_cleanup_null, +@@ -1918,6 +1921,44 @@ const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag + #endif + } + ++const char *ssl_cmd_SSLVHostSNIPolicy(cmd_parms *cmd, void *dcfg, const char *arg) ++{ ++#ifdef HAVE_TLSEXT ++ SSLModConfigRec *mc = myModConfig(cmd->server); ++ const char *err; ++ ++ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { ++ return err; ++ } ++ if (!mc) { ++ return "SSLVHostSNIPolicy cannot be used inside SSLPolicyDefine"; ++ } ++ ++ if (strcEQ(arg, "secure")) { ++ mc->snivh_policy = MODSSL_SNIVH_SECURE; ++ } ++ else if (strcEQ(arg, "strict")) { ++ mc->snivh_policy = MODSSL_SNIVH_STRICT; ++ } ++ else if (strcEQ(arg, "insecure")) { ++ mc->snivh_policy = MODSSL_SNIVH_INSECURE; ++ } ++ else if (strcEQ(arg, "authonly")) { ++ mc->snivh_policy = MODSSL_SNIVH_AUTHONLY; ++ } ++ else { ++ return apr_psprintf(cmd->pool, "Invalid SSLVhostSNIPolicy " ++ "argument '%s'", arg); ++ } ++ ++ return NULL; ++#else ++ return "SSLVHostSNIPolicy cannot be used, OpenSSL is not built with " ++ "support for TLS extensions and SNI indication. Refer to the " ++ "documentation, and build a compatible version of OpenSSL." ++#endif ++} ++ + #ifdef HAVE_OCSP_STAPLING + + const char *ssl_cmd_SSLStaplingCache(cmd_parms *cmd, +diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c +index 2fbd076..64a9f32 100644 +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -186,6 +186,110 @@ static void ssl_add_version_components(apr_pool_t *ptemp, apr_pool_t *pconf, + modver, AP_SERVER_BASEVERSION, incver); + } + ++#ifdef HAVE_TLSEXT ++/* Helper functions to create the SNI vhost policy hash. The policy ++ * hash captures the configuration elements relevant to the mode ++ * selected at runtime by SSLVHostSNIPolicy. */ ++ ++#define md5_str_update(ctx_, pfx_, str_) do { apr_md5_update(ctx_, pfx_, strlen(pfx_)); apr_md5_update(ctx_, str_, strlen(str_)); } while (0) ++#define md5_ifstr_update(ctx_, pfx_, str_) do { apr_md5_update(ctx_, pfx_, strlen(pfx_)); if (str_) apr_md5_update(ctx_, str_, strlen(str_)); } while (0) ++#define md5_fmt_update(ctx_, fmt_, i_) do { char s_[128]; apr_snprintf(s_, sizeof s_, fmt_, i_); \ ++ apr_md5_update(ctx_, s_, strlen(s_)); } while (0) ++ ++static int md5_strarray_cmp(const void *p1, const void *p2) ++{ ++ return strcmp(*(char **)p1, *(char **)p2); ++} ++ ++/* Hashes an array of strings in sorted order. */ ++static void md5_strarray_hash(apr_pool_t *ptemp, apr_md5_ctx_t *hash, ++ const char *pfx, apr_array_header_t *s) ++{ ++ char **elts = apr_pmemdup(ptemp, s->elts, s->nelts * sizeof *elts); ++ int i; ++ ++ qsort(elts, s->nelts, sizeof(char *), md5_strarray_cmp); ++ ++ apr_md5_update(hash, pfx, strlen(pfx)); ++ for (i = 0; i < s->nelts; i++) { ++ md5_str_update(hash, "elm:", elts[i]); ++ } ++} ++ ++static void hash_sni_policy_pk(apr_pool_t *ptemp, apr_md5_ctx_t *hash, modssl_ctx_t *ctx) ++{ ++ md5_fmt_update(hash, "protocol:%d", ctx->protocol); ++ ++ md5_ifstr_update(hash, "ciphers:", ctx->auth.cipher_suite); ++ md5_ifstr_update(hash, "tls13_ciphers:", ctx->auth.tls13_ciphers); ++ ++ md5_strarray_hash(ptemp, hash, "cert_files:", ctx->pks->cert_files); ++ md5_strarray_hash(ptemp, hash, "key_files:", ctx->pks->key_files); ++} ++ ++static void hash_sni_policy_auth(apr_md5_ctx_t *hash, modssl_ctx_t *ctx) ++{ ++ modssl_pk_server_t *pks = ctx->pks; ++ modssl_auth_ctx_t *a = &ctx->auth; ++ ++ md5_fmt_update(hash, "verify_depth:%d", a->verify_depth); ++ md5_fmt_update(hash, "verify_mode:%d", a->verify_mode); ++ ++ md5_ifstr_update(hash, "ca_name_path:", pks->ca_name_path); ++ md5_ifstr_update(hash, "ca_name_file:", pks->ca_name_file); ++ md5_ifstr_update(hash, "ca_cert_path:", a->ca_cert_path); ++ md5_ifstr_update(hash, "ca_cert_file:", a->ca_cert_file); ++ md5_ifstr_update(hash, "crl_path:", ctx->crl_path); ++ md5_ifstr_update(hash, "crl_file:", ctx->crl_file); ++ md5_fmt_update(hash, "crl_check_mask:%d", ctx->crl_check_mask); ++ md5_fmt_update(hash, "ocsp_mask:%d", ctx->ocsp_mask); ++ md5_fmt_update(hash, "ocsp_force_default:%d", ctx->ocsp_force_default); ++ md5_ifstr_update(hash, "ocsp_responder:", ctx->ocsp_responder); ++ ++#ifdef HAVE_SRP ++ md5_ifstr_update(hash, "srp_vfile:", ctx->srp_vfile); ++#endif ++ ++#ifdef HAVE_SSL_CONF_CMD ++ { ++ apr_array_header_t *parms = ctx->ssl_ctx_param; ++ int n; ++ ++ for (n = 0; n < parms->nelts; n++) { ++ ssl_ctx_param_t *p = &APR_ARRAY_IDX(parms, n, ssl_ctx_param_t); ++ ++ md5_str_update(hash, "param:", p->name); ++ md5_str_update(hash, "value:", p->value); ++ } ++ } ++#endif ++} ++#endif ++ ++static char *create_sni_policy_hash(apr_pool_t *p, apr_pool_t *ptemp, ++ modssl_snivhpolicy_t policy, ++ SSLSrvConfigRec *sc) ++{ ++ char *rv = NULL; ++#ifdef HAVE_TLSEXT ++ if (policy != MODSSL_SNIVH_STRICT && policy != MODSSL_SNIVH_INSECURE) { ++ apr_md5_ctx_t hash; ++ unsigned char digest[APR_MD5_DIGESTSIZE]; ++ ++ /* Create the vhost policy hash for comparison later. */ ++ apr_md5_init(&hash); ++ hash_sni_policy_auth(&hash, sc->server); ++ if (policy == MODSSL_SNIVH_SECURE) ++ hash_sni_policy_pk(ptemp, &hash, sc->server); ++ apr_md5_final(digest, &hash); ++ ++ rv = apr_palloc(p, 2 * APR_MD5_DIGESTSIZE + 1); ++ ap_bin2hex(digest, APR_MD5_DIGESTSIZE, rv); /* sets final '\0' */ ++ } ++#endif ++ return rv; ++} ++ + /* _________________________________________________________________ + ** + ** Let other answer special connection attempts. +@@ -439,6 +543,8 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, + return rv; + } + } ++ ++ sc->sni_policy_hash = create_sni_policy_hash(p, ptemp, mc->snivh_policy, sc); + } + + /* +diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c +index 33aa1f7..a6af633 100644 +--- a/modules/ssl/ssl_engine_kernel.c ++++ b/modules/ssl/ssl_engine_kernel.c +@@ -101,112 +101,28 @@ static int fill_reneg_buffer(request_rec *r, SSLDirConfigRec *dc) + } + + #ifdef HAVE_TLSEXT +-static int ap_array_same_str_set(apr_array_header_t *s1, apr_array_header_t *s2) ++/* Check whether a transition from vhost sc1 to sc2 from SNI to Host: ++ * vhost selection is permitted according to the SSLVHostSNIPolicy ++ * setting. Returns 1 if the policy treats the vhosts as compatible, ++ * else 0. */ ++static int ssl_check_vhost_sni_policy(SSLSrvConfigRec *sc1, ++ SSLSrvConfigRec *sc2) + { +- int i; +- const char *c; +- +- if (s1 == s2) { ++ modssl_snivhpolicy_t policy = sc1->mc->snivh_policy; ++ ++ /* Policy: insecure => allow everything. */ ++ if (policy == MODSSL_SNIVH_INSECURE) + return 1; +- } +- else if (!s1 || !s2 || (s1->nelts != s2->nelts)) { +- return 0; +- } + +- for (i = 0; i < s1->nelts; i++) { +- c = APR_ARRAY_IDX(s1, i, const char *); +- if (!c || !ap_array_str_contains(s2, c)) { +- return 0; +- } +- } +- return 1; +-} +- +-static int ssl_pk_server_compatible(modssl_pk_server_t *pks1, +- modssl_pk_server_t *pks2) +-{ +- if (!pks1 || !pks2) { +- return 0; +- } +- /* both have the same certificates? */ +- if ((pks1->ca_name_path != pks2->ca_name_path) +- && (!pks1->ca_name_path || !pks2->ca_name_path +- || strcmp(pks1->ca_name_path, pks2->ca_name_path))) { +- return 0; +- } +- if ((pks1->ca_name_file != pks2->ca_name_file) +- && (!pks1->ca_name_file || !pks2->ca_name_file +- || strcmp(pks1->ca_name_file, pks2->ca_name_file))) { +- return 0; +- } +- if (!ap_array_same_str_set(pks1->cert_files, pks2->cert_files) +- || !ap_array_same_str_set(pks1->key_files, pks2->key_files)) { +- return 0; +- } +- return 1; +-} +- +-static int ssl_auth_compatible(modssl_auth_ctx_t *a1, +- modssl_auth_ctx_t *a2) +-{ +- if (!a1 || !a2) { +- return 0; +- } +- /* both have the same verification */ +- if ((a1->verify_depth != a2->verify_depth) +- || (a1->verify_mode != a2->verify_mode)) { +- return 0; +- } +- /* both have the same ca path/file */ +- if ((a1->ca_cert_path != a2->ca_cert_path) +- && (!a1->ca_cert_path || !a2->ca_cert_path +- || strcmp(a1->ca_cert_path, a2->ca_cert_path))) { +- return 0; +- } +- if ((a1->ca_cert_file != a2->ca_cert_file) +- && (!a1->ca_cert_file || !a2->ca_cert_file +- || strcmp(a1->ca_cert_file, a2->ca_cert_file))) { +- return 0; +- } +- /* both have the same ca cipher suite string */ +- if ((a1->cipher_suite != a2->cipher_suite) +- && (!a1->cipher_suite || !a2->cipher_suite +- || strcmp(a1->cipher_suite, a2->cipher_suite))) { +- return 0; +- } +- /* both have the same ca cipher suite string */ +- if ((a1->tls13_ciphers != a2->tls13_ciphers) +- && (!a1->tls13_ciphers || !a2->tls13_ciphers +- || strcmp(a1->tls13_ciphers, a2->tls13_ciphers))) { +- return 0; +- } +- return 1; +-} +- +-static int ssl_ctx_compatible(modssl_ctx_t *ctx1, +- modssl_ctx_t *ctx2) +-{ +- if (!ctx1 || !ctx2 +- || (ctx1->protocol != ctx2->protocol) +- || !ssl_auth_compatible(&ctx1->auth, &ctx2->auth) +- || !ssl_pk_server_compatible(ctx1->pks, ctx2->pks)) { ++ /* Policy: strict => fail for any vhost transition. */ ++ if (policy == MODSSL_SNIVH_STRICT && sc1 != sc2) + return 0; +- } +- return 1; +-} + +-static int ssl_server_compatible(server_rec *s1, server_rec *s2) +-{ +- SSLSrvConfigRec *sc1 = s1? mySrvConfig(s1) : NULL; +- SSLSrvConfigRec *sc2 = s2? mySrvConfig(s2) : NULL; ++ /* For authonly/secure policy, compare the hash. */ ++ AP_DEBUG_ASSERT(sc1->sni_policy_hash); ++ AP_DEBUG_ASSERT(sc2->sni_policy_hash); + +- /* both use the same TLS protocol? */ +- if (!sc1 || !sc2 +- || !ssl_ctx_compatible(sc1->server, sc2->server)) { +- return 0; +- } +- +- return 1; ++ return strcmp(sc1->sni_policy_hash, sc2->sni_policy_hash) == 0; + } + #endif + +@@ -275,6 +191,8 @@ int ssl_hook_ReadReq(request_rec *r) + server_rec *handshakeserver = sslconn->server; + SSLSrvConfigRec *hssc = mySrvConfig(handshakeserver); + ++ AP_DEBUG_ASSERT(hssc); ++ + if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { + /* + * The SNI extension supplied a hostname. So don't accept requests +@@ -315,19 +233,14 @@ int ssl_hook_ReadReq(request_rec *r) + "which is required to access this server.
      \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 +- */ +- ++ /* Enforce SSL SNI vhost compatibility policy. */ ++ if (!ssl_check_vhost_sni_policy(sc, hssc)) { + 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", ++ " via HTTP have no compatible SSL setup for policy '%s'", + servername ? servername : handshakeserver->server_hostname, + servername ? "provided via SNI" : "(default host as no SNI was provided)", +- r->hostname); ++ r->hostname, MODSSL_SNIVH_NAME(sc->mc->snivh_policy)); + return HTTP_MISDIRECTED_REQUEST; + } + } +diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h +index 2b18189..dbef182 100644 +--- a/modules/ssl/ssl_private.h ++++ b/modules/ssl/ssl_private.h +@@ -556,6 +556,19 @@ typedef struct { + int nBytes; + } ssl_randseed_t; + ++/* SNI vhost compatibility policy. */ ++typedef enum { ++ MODSSL_SNIVH_STRICT = 0, ++ MODSSL_SNIVH_SECURE = 1, ++ MODSSL_SNIVH_AUTHONLY = 2, ++ MODSSL_SNIVH_INSECURE = 3 ++} modssl_snivhpolicy_t; ++ ++/* Maps modssl_snivhpolicy_t back into a config option string. */ ++#define MODSSL_SNIVH_NAME(p_) ((p_) == MODSSL_SNIVH_STRICT ? "strict" : \ ++ ((p_) == MODSSL_SNIVH_SECURE ? "secure" : \ ++ ((p_) == MODSSL_SNIVH_AUTHONLY ? "authonly" : "insecure" ))) ++ + /** + * Define the structure of an ASN.1 anything + */ +@@ -689,6 +702,8 @@ typedef struct { + #ifdef HAVE_FIPS + BOOL fips; + #endif ++ ++ modssl_snivhpolicy_t snivh_policy; + } SSLModConfigRec; + + /** Structure representing configured filenames for certs and keys for +@@ -843,6 +858,7 @@ struct SSLSrvConfigRec { + modssl_ctx_t *server; + #ifdef HAVE_TLSEXT + ssl_enabled_t strict_sni_vhost_check; ++ const char *sni_policy_hash; + #endif + #ifndef OPENSSL_NO_COMP + BOOL compression; +@@ -918,6 +934,7 @@ const char *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *); + const char *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *); + const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg); + const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag); ++const char *ssl_cmd_SSLVHostSNIPolicy(cmd_parms *cmd, void *dcfg, const char *arg); + const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag); + + const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag); +-- +2.44.0 + diff --git a/httpd.spec b/httpd.spec index 9d718a5..6d06795 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.65 -Release: 1%{?dist} +Release: 2%{?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 @@ -99,6 +99,7 @@ Patch27: httpd-2.4.64-sslprotdefault.patch Patch28: httpd-2.4.43-logjournal.patch Patch29: httpd-2.4.63-r1912477+.patch Patch30: httpd-2.4.64-separate-systemd-fns.patch +Patch31: httpd-2.4.65-sslvhostsnipolicy.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 @@ -846,6 +847,10 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Tue Nov 04 2025 Luboš Uhliarik - 2.4.65-2 +- mod_ssl: Add SSLVHostSNIPolicy directive to set the compatibility level + required for VirtualHost matching. + * Sat Oct 18 2025 Luboš Uhliarik - 2.4.65-1 - new version 2.4.65 - mod_proxy_hcheck: reschedule health checks after child process restart From 943e0af2d4905f60d87dc4bb49e886b79fed3909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Tue, 4 Nov 2025 13:14:49 +0100 Subject: [PATCH 16/20] Fix typo in patch + include util_md5.h mod_ssl: Add SSLVHostSNIPolicy directive to set the compatibility level required for VirtualHost matching. --- httpd-2.4.65-sslvhostsnipolicy.patch | 30 ++++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/httpd-2.4.65-sslvhostsnipolicy.patch b/httpd-2.4.65-sslvhostsnipolicy.patch index 401882a..6767cbc 100644 --- a/httpd-2.4.65-sslvhostsnipolicy.patch +++ b/httpd-2.4.65-sslvhostsnipolicy.patch @@ -1,7 +1,7 @@ -From 0e0995bef84a66c9dabe75d6e81376896cc819bd Mon Sep 17 00:00:00 2001 -From: Joe Orton -Date: Tue, 4 Nov 2025 12:05:05 +0100 -Subject: [PATCH] [PATCH] mod_ssl: Add SSLVHostSNIPolicy directive to set the +From ba168444686368377c6e69373e20e6dae8ebb702 Mon Sep 17 00:00:00 2001 +From: Joe Orton +Date: Tue, 4 Nov 2025 12:49:36 +0100 +Subject: [PATCH] [PATCH] mod_ssl: Add SSLVHostSNIPolicy directive to set the compatibility level required for VirtualHost matching. For "secure" and "authonly" modes, a hash of the policy-relevant vhost @@ -29,10 +29,10 @@ GitHub: closes #561 docs/manual/mod/mod_ssl.html.en | 77 +++++++++++++++++++ modules/ssl/mod_ssl.c | 2 + modules/ssl/ssl_engine_config.c | 41 ++++++++++ - modules/ssl/ssl_engine_init.c | 106 ++++++++++++++++++++++++++ + modules/ssl/ssl_engine_init.c | 107 ++++++++++++++++++++++++++ modules/ssl/ssl_engine_kernel.c | 131 ++++++-------------------------- modules/ssl/ssl_private.h | 17 +++++ - 6 files changed, 265 insertions(+), 109 deletions(-) + 6 files changed, 266 insertions(+), 109 deletions(-) diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en index e2a4a99..95f0667 100644 @@ -143,7 +143,7 @@ index fb66d18..c0fdafd 100644 /* * Per-server context configuration directives diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c -index c5dce7f..31a1942 100644 +index c5dce7f..f856b18 100644 --- a/modules/ssl/ssl_engine_config.c +++ b/modules/ssl/ssl_engine_config.c @@ -82,6 +82,9 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s) @@ -152,7 +152,7 @@ index c5dce7f..31a1942 100644 #endif +#ifdef HAVE_TLSEXT + mc->snivh_policy = MODSSL_SNIVH_SECURE; -+#endi ++#endif apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY, apr_pool_cleanup_null, @@ -202,10 +202,18 @@ index c5dce7f..31a1942 100644 const char *ssl_cmd_SSLStaplingCache(cmd_parms *cmd, diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c -index 2fbd076..64a9f32 100644 +index 2fbd076..1bf6ac4 100644 --- a/modules/ssl/ssl_engine_init.c +++ b/modules/ssl/ssl_engine_init.c -@@ -186,6 +186,110 @@ static void ssl_add_version_components(apr_pool_t *ptemp, apr_pool_t *pconf, +@@ -30,6 +30,7 @@ + + #include "mpm_common.h" + #include "mod_md.h" ++#include "util_md5.h" + + static apr_status_t ssl_init_ca_cert_path(server_rec *, apr_pool_t *, const char *, + STACK_OF(X509_NAME) *, STACK_OF(X509_INFO) *); +@@ -186,6 +187,110 @@ static void ssl_add_version_components(apr_pool_t *ptemp, apr_pool_t *pconf, modver, AP_SERVER_BASEVERSION, incver); } @@ -316,7 +324,7 @@ index 2fbd076..64a9f32 100644 /* _________________________________________________________________ ** ** Let other answer special connection attempts. -@@ -439,6 +543,8 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, +@@ -439,6 +544,8 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, return rv; } } From fb46d5df49d5e1b081507d639f028fd2fda0d267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Wed, 12 Nov 2025 11:16:19 +0100 Subject: [PATCH 17/20] mod_ssl: SSLVHostSNIPolicy - Fix handling of STRICT mode --- httpd-2.4.65-sslvhostsnipolicy.patch | 41 ++++++++++++++-------------- httpd.spec | 5 +++- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/httpd-2.4.65-sslvhostsnipolicy.patch b/httpd-2.4.65-sslvhostsnipolicy.patch index 6767cbc..0831efc 100644 --- a/httpd-2.4.65-sslvhostsnipolicy.patch +++ b/httpd-2.4.65-sslvhostsnipolicy.patch @@ -1,7 +1,7 @@ -From ba168444686368377c6e69373e20e6dae8ebb702 Mon Sep 17 00:00:00 2001 +From 0263d1e290bc029c5c059fdaa4f21ca9885f9c84 Mon Sep 17 00:00:00 2001 From: Joe Orton -Date: Tue, 4 Nov 2025 12:49:36 +0100 -Subject: [PATCH] [PATCH] mod_ssl: Add SSLVHostSNIPolicy directive to set the +Date: Wed, 12 Nov 2025 11:11:41 +0100 +Subject: [PATCH] mod_ssl: Add SSLVHostSNIPolicy directive to set the compatibility level required for VirtualHost matching. For "secure" and "authonly" modes, a hash of the policy-relevant vhost @@ -26,13 +26,13 @@ the runtime code complexity (and overhead). PR: 69743 GitHub: closes #561 --- - docs/manual/mod/mod_ssl.html.en | 77 +++++++++++++++++++ + docs/manual/mod/mod_ssl.html.en | 77 ++++++++++++++++++ modules/ssl/mod_ssl.c | 2 + modules/ssl/ssl_engine_config.c | 41 ++++++++++ - modules/ssl/ssl_engine_init.c | 107 ++++++++++++++++++++++++++ - modules/ssl/ssl_engine_kernel.c | 131 ++++++-------------------------- - modules/ssl/ssl_private.h | 17 +++++ - 6 files changed, 266 insertions(+), 109 deletions(-) + modules/ssl/ssl_engine_init.c | 107 +++++++++++++++++++++++++ + modules/ssl/ssl_engine_kernel.c | 133 ++++++-------------------------- + modules/ssl/ssl_private.h | 17 ++++ + 6 files changed, 267 insertions(+), 110 deletions(-) diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en index e2a4a99..95f0667 100644 @@ -60,7 +60,7 @@ index e2a4a99..95f0667 100644 +Context:server config +Status:Extension +Module:mod_ssl -+Compatibility:Available in httpd 2.4.65 and later ++Compatibility:Available in httpd 2.4.65 in Fedora Linux +

      This directive sets the policy applied when checking whether the +<VirtualHost> +identified by the Host request header in an HTTP request @@ -334,7 +334,7 @@ index 2fbd076..1bf6ac4 100644 /* diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c -index 33aa1f7..a6af633 100644 +index 33aa1f7..83ae90e 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -101,112 +101,28 @@ static int fill_reneg_buffer(request_rec *r, SSLDirConfigRec *dc) @@ -371,7 +371,10 @@ index 33aa1f7..a6af633 100644 - } - return 1; -} -- ++ /* Policy: strict => fail for any vhost transition. */ ++ if (policy == MODSSL_SNIVH_STRICT) ++ return sc1 == sc2; + -static int ssl_pk_server_compatible(modssl_pk_server_t *pks1, - modssl_pk_server_t *pks2) -{ @@ -395,7 +398,10 @@ index 33aa1f7..a6af633 100644 - } - return 1; -} -- ++ /* For authonly/secure policy, compare the hash. */ ++ AP_DEBUG_ASSERT(sc1->sni_policy_hash); ++ AP_DEBUG_ASSERT(sc2->sni_policy_hash); + -static int ssl_auth_compatible(modssl_auth_ctx_t *a1, - modssl_auth_ctx_t *a2) -{ @@ -440,21 +446,16 @@ index 33aa1f7..a6af633 100644 - || (ctx1->protocol != ctx2->protocol) - || !ssl_auth_compatible(&ctx1->auth, &ctx2->auth) - || !ssl_pk_server_compatible(ctx1->pks, ctx2->pks)) { -+ /* Policy: strict => fail for any vhost transition. */ -+ if (policy == MODSSL_SNIVH_STRICT && sc1 != sc2) - return 0; +- return 0; - } - return 1; -} - +- -static int ssl_server_compatible(server_rec *s1, server_rec *s2) -{ - SSLSrvConfigRec *sc1 = s1? mySrvConfig(s1) : NULL; - SSLSrvConfigRec *sc2 = s2? mySrvConfig(s2) : NULL; -+ /* For authonly/secure policy, compare the hash. */ -+ AP_DEBUG_ASSERT(sc1->sni_policy_hash); -+ AP_DEBUG_ASSERT(sc2->sni_policy_hash); - +- - /* both use the same TLS protocol? */ - if (!sc1 || !sc2 - || !ssl_ctx_compatible(sc1->server, sc2->server)) { diff --git a/httpd.spec b/httpd.spec index 6d06795..9d762d8 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.65 -Release: 2%{?dist} +Release: 3%{?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 @@ -847,6 +847,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Wed Nov 12 2025 Luboš Uhliarik - 2.4.65-3 +- mod_ssl: SSLVHostSNIPolicy - Fix handling of STRICT mode + * Tue Nov 04 2025 Luboš Uhliarik - 2.4.65-2 - mod_ssl: Add SSLVHostSNIPolicy directive to set the compatibility level required for VirtualHost matching. From f3e631b085b7583155b87f52d5f6b3096d3d4ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Thu, 27 Nov 2025 16:40:28 +0100 Subject: [PATCH 18/20] Improve default httpd LogFormats for better support diagnostics --- httpd.conf | 4 ++-- httpd.spec | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/httpd.conf b/httpd.conf index e49ab6a..2be277d 100644 --- a/httpd.conf +++ b/httpd.conf @@ -198,8 +198,8 @@ LogLevel warn # The following directives define some format nicknames for use with # a CustomLog directive (see below). # - LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined - LogFormat "%h %l %u %t \"%r\" %>s %b" common + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" PID: %P %{tid}P %T" combined + LogFormat "%h %l %u %t \"%r\" %>s %b PID: %P %{tid}P %T" common # You need to enable mod_logio.c to use %I and %O diff --git a/httpd.spec b/httpd.spec index 9d762d8..151bac6 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.65 -Release: 3%{?dist} +Release: 4%{?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 @@ -847,6 +847,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Thu Nov 27 2025 Luboš Uhliarik - 2.4.65-4 +- Improve default httpd LogFormats for better support diagnostics + * Wed Nov 12 2025 Luboš Uhliarik - 2.4.65-3 - mod_ssl: SSLVHostSNIPolicy - Fix handling of STRICT mode From 0914a96ecc2516806333cb0e8b11cce87eb07110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Mon, 1 Dec 2025 12:58:07 +0100 Subject: [PATCH 19/20] Improve default httpd LogFormats for better support diagnostics --- httpd.conf | 12 +++++++----- httpd.spec | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/httpd.conf b/httpd.conf index 2be277d..ad5c7ee 100644 --- a/httpd.conf +++ b/httpd.conf @@ -198,8 +198,9 @@ LogLevel warn # The following directives define some format nicknames for use with # a CustomLog directive (see below). # - LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" PID: %P %{tid}P %T" combined - LogFormat "%h %l %u %t \"%r\" %>s %b PID: %P %{tid}P %T" common + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined + LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" PID: %P %{tid}P %T" combined_ext + LogFormat "%h %l %u %t \"%r\" %>s %b" common # You need to enable mod_logio.c to use %I and %O @@ -216,10 +217,11 @@ LogLevel warn #CustomLog "logs/access_log" common # - # If you prefer a logfile with access, agent, and referer information - # (Combined Logfile Format) you can use the following directive. + # If you prefer a logfile with access, agent, referer, and process/thread + # information (an extended Combined Logfile Format), you can use the + # following directive. # - CustomLog "logs/access_log" combined + CustomLog "logs/access_log" combined_ext diff --git a/httpd.spec b/httpd.spec index 151bac6..91c8d2f 100644 --- a/httpd.spec +++ b/httpd.spec @@ -31,7 +31,7 @@ Summary: Apache HTTP Server Name: httpd Version: 2.4.65 -Release: 4%{?dist} +Release: 5%{?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 @@ -847,7 +847,7 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog -* Thu Nov 27 2025 Luboš Uhliarik - 2.4.65-4 +* Thu Nov 27 2025 Luboš Uhliarik - 2.4.65-5 - Improve default httpd LogFormats for better support diagnostics * Wed Nov 12 2025 Luboš Uhliarik - 2.4.65-3 From 0c203aeed682395c663f7afef328f754fa629b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= Date: Tue, 9 Dec 2025 12:48:50 +0100 Subject: [PATCH 20/20] new version 2.4.66 --- .gitignore | 1 + httpd-2.4.65-sslvhostsnipolicy.patch | 554 --------------------------- httpd.spec | 8 +- sources | 4 +- 4 files changed, 8 insertions(+), 559 deletions(-) delete mode 100644 httpd-2.4.65-sslvhostsnipolicy.patch diff --git a/.gitignore b/.gitignore index f2fccfd..8df7f18 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,4 @@ x86_64 /httpd-2.4.63.tar.bz2.asc /httpd-2.4.64.tar.bz2.asc /httpd-2.4.65.tar.bz2.asc +/httpd-2.4.66.tar.bz2.asc diff --git a/httpd-2.4.65-sslvhostsnipolicy.patch b/httpd-2.4.65-sslvhostsnipolicy.patch deleted file mode 100644 index 0831efc..0000000 --- a/httpd-2.4.65-sslvhostsnipolicy.patch +++ /dev/null @@ -1,554 +0,0 @@ -From 0263d1e290bc029c5c059fdaa4f21ca9885f9c84 Mon Sep 17 00:00:00 2001 -From: Joe Orton -Date: Wed, 12 Nov 2025 11:11:41 +0100 -Subject: [PATCH] mod_ssl: Add SSLVHostSNIPolicy directive to set the - compatibility level required for VirtualHost matching. - -For "secure" and "authonly" modes, a hash of the policy-relevant vhost -configuration is created and stored in the post_config hooks, reducing -the runtime code complexity (and overhead). - -* modules/ssl/ssl_engine_kernel.c (ssl_check_vhost_sni_policy): New - function, replacing ssl_server_compatible et al. - -* modules/ssl/ssl_engine_config.c (ssl_cmd_SSLVHostSNIPolicy): New - function. - -* modules/ssl/ssl_engine_init.c (md5_strarray_cmp, md5_strarray_hash, - hash_sni_policy_pk, hash_sni_policy_auth, create_sni_policy_hash): - New functions. - (ssl_init_Module): Invoke create_sni_policy_hash to store the hash - for every SSLSrvConfigRec. - -* modules/ssl/ssl_private.h (SSLModConfigRec): Add snivh_policy field. - (SSLSrvConfigRec): Add sni_policy_hash field. - -PR: 69743 -GitHub: closes #561 ---- - docs/manual/mod/mod_ssl.html.en | 77 ++++++++++++++++++ - modules/ssl/mod_ssl.c | 2 + - modules/ssl/ssl_engine_config.c | 41 ++++++++++ - modules/ssl/ssl_engine_init.c | 107 +++++++++++++++++++++++++ - modules/ssl/ssl_engine_kernel.c | 133 ++++++-------------------------- - modules/ssl/ssl_private.h | 17 ++++ - 6 files changed, 267 insertions(+), 110 deletions(-) - -diff --git a/docs/manual/mod/mod_ssl.html.en b/docs/manual/mod/mod_ssl.html.en -index e2a4a99..95f0667 100644 ---- a/docs/manual/mod/mod_ssl.html.en -+++ b/docs/manual/mod/mod_ssl.html.en -@@ -125,6 +125,7 @@ to provide the cryptography engine.

      -
    • SSLUseStapling
    • -
    • SSLVerifyClient
    • -
    • SSLVerifyDepth
    • -+
    • SSLVHostSNIPolicy
    • -
    -

    Bugfix checklist

    See also

    -
      -@@ -2863,6 +2864,82 @@ known to the server (i.e. the CA's certificate is under -

      Example

      SSLVerifyDepth 10
      -
      - -+ -+
      top
      -+

      SSLVHostSNIPolicy Directive

      -+ -+ -+ -+ -+ -+ -+ -+ -+
      Description:Set compatibility policy for SNI client access to virtual hosts.
      Syntax:SSLVHostSNIPolicy strict|secure|authonly|insecure
      Default:SSLVHostSNIPolicy secure
      Context:server config
      Status:Extension
      Module:mod_ssl
      Compatibility:Available in httpd 2.4.65 in Fedora Linux

      This directive sets the policy applied when checking whether the -+<VirtualHost> -+identified by the Host request header in an HTTP request -+is compatible with the <VirtualHost> identified from the SNI -+extension sent during the initial TLS connection handshake. If an HTTP -+request is associated with a virtual host which has an incompatible -+SSL/TLS configuration under the policy used, an HTTP error response -+with status code 421 ("Misdirected Request") will be sent.

      -+ -+

      The policy also applies to TLS connections where an SNI extension -+is not sent during the handshake, implicitly using the default or -+first virtual host definition. If the Host header in an HTTP request -+on such a connection identifies any other non-default virtual host, -+the compatibility policy is tested.

      -+ -+

      The strict policy blocks all HTTP requests which are -+identified with a different virtual host to that identifed by SNI. -+The insecure policy allows all HTTP requests regardless -+of virtual host identified; such a configuration may be vulnerable to -+CVE-2025-23048. -+

      -+ -+

      The (default) secure, and authonly -+policies compare specific aspects of the SSL configuration for the two -+virtual hosts, which are grouped into two categories: -+ -+

      -+ -+This table illustrates whether an HTTP request will be blocked or -+allowed when the virtual host configurations differ as described, -+under each different policy setting: -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+
      Policy modeAny VirtualHost mismatchServer certificate/key,
      or protocol/cipher restrictions
      Client verification/
      authentication settings
      strictblockedblockedblocked
      secureallowedblockedblocked
      authonlyallowedblockedallowed
      insecureallowedallowedallowed
      -+

      -+

      Example

      SSLVHostSNIPolicy authonly
      -+
      -+ -+ -
      - -
      -diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c -index fb66d18..c0fdafd 100644 ---- a/modules/ssl/mod_ssl.c -+++ b/modules/ssl/mod_ssl.c -@@ -80,6 +80,8 @@ static const command_rec ssl_config_cmds[] = { - SSL_CMD_SRV(RandomSeed, TAKE23, - "SSL Pseudo Random Number Generator (PRNG) seeding source " - "('startup|connect builtin|file:/path|exec:/path [bytes]')") -+ SSL_CMD_SRV(VHostSNIPolicy, TAKE1, -+ "SSL VirtualHost SNI compatibility policy setting") - - /* - * Per-server context configuration directives -diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c -index c5dce7f..f856b18 100644 ---- a/modules/ssl/ssl_engine_config.c -+++ b/modules/ssl/ssl_engine_config.c -@@ -82,6 +82,9 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s) - #ifdef HAVE_FIPS - mc->fips = UNSET; - #endif -+#ifdef HAVE_TLSEXT -+ mc->snivh_policy = MODSSL_SNIVH_SECURE; -+#endif - - apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY, - apr_pool_cleanup_null, -@@ -1918,6 +1921,44 @@ const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag - #endif - } - -+const char *ssl_cmd_SSLVHostSNIPolicy(cmd_parms *cmd, void *dcfg, const char *arg) -+{ -+#ifdef HAVE_TLSEXT -+ SSLModConfigRec *mc = myModConfig(cmd->server); -+ const char *err; -+ -+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) { -+ return err; -+ } -+ if (!mc) { -+ return "SSLVHostSNIPolicy cannot be used inside SSLPolicyDefine"; -+ } -+ -+ if (strcEQ(arg, "secure")) { -+ mc->snivh_policy = MODSSL_SNIVH_SECURE; -+ } -+ else if (strcEQ(arg, "strict")) { -+ mc->snivh_policy = MODSSL_SNIVH_STRICT; -+ } -+ else if (strcEQ(arg, "insecure")) { -+ mc->snivh_policy = MODSSL_SNIVH_INSECURE; -+ } -+ else if (strcEQ(arg, "authonly")) { -+ mc->snivh_policy = MODSSL_SNIVH_AUTHONLY; -+ } -+ else { -+ return apr_psprintf(cmd->pool, "Invalid SSLVhostSNIPolicy " -+ "argument '%s'", arg); -+ } -+ -+ return NULL; -+#else -+ return "SSLVHostSNIPolicy cannot be used, OpenSSL is not built with " -+ "support for TLS extensions and SNI indication. Refer to the " -+ "documentation, and build a compatible version of OpenSSL." -+#endif -+} -+ - #ifdef HAVE_OCSP_STAPLING - - const char *ssl_cmd_SSLStaplingCache(cmd_parms *cmd, -diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c -index 2fbd076..1bf6ac4 100644 ---- a/modules/ssl/ssl_engine_init.c -+++ b/modules/ssl/ssl_engine_init.c -@@ -30,6 +30,7 @@ - - #include "mpm_common.h" - #include "mod_md.h" -+#include "util_md5.h" - - static apr_status_t ssl_init_ca_cert_path(server_rec *, apr_pool_t *, const char *, - STACK_OF(X509_NAME) *, STACK_OF(X509_INFO) *); -@@ -186,6 +187,110 @@ static void ssl_add_version_components(apr_pool_t *ptemp, apr_pool_t *pconf, - modver, AP_SERVER_BASEVERSION, incver); - } - -+#ifdef HAVE_TLSEXT -+/* Helper functions to create the SNI vhost policy hash. The policy -+ * hash captures the configuration elements relevant to the mode -+ * selected at runtime by SSLVHostSNIPolicy. */ -+ -+#define md5_str_update(ctx_, pfx_, str_) do { apr_md5_update(ctx_, pfx_, strlen(pfx_)); apr_md5_update(ctx_, str_, strlen(str_)); } while (0) -+#define md5_ifstr_update(ctx_, pfx_, str_) do { apr_md5_update(ctx_, pfx_, strlen(pfx_)); if (str_) apr_md5_update(ctx_, str_, strlen(str_)); } while (0) -+#define md5_fmt_update(ctx_, fmt_, i_) do { char s_[128]; apr_snprintf(s_, sizeof s_, fmt_, i_); \ -+ apr_md5_update(ctx_, s_, strlen(s_)); } while (0) -+ -+static int md5_strarray_cmp(const void *p1, const void *p2) -+{ -+ return strcmp(*(char **)p1, *(char **)p2); -+} -+ -+/* Hashes an array of strings in sorted order. */ -+static void md5_strarray_hash(apr_pool_t *ptemp, apr_md5_ctx_t *hash, -+ const char *pfx, apr_array_header_t *s) -+{ -+ char **elts = apr_pmemdup(ptemp, s->elts, s->nelts * sizeof *elts); -+ int i; -+ -+ qsort(elts, s->nelts, sizeof(char *), md5_strarray_cmp); -+ -+ apr_md5_update(hash, pfx, strlen(pfx)); -+ for (i = 0; i < s->nelts; i++) { -+ md5_str_update(hash, "elm:", elts[i]); -+ } -+} -+ -+static void hash_sni_policy_pk(apr_pool_t *ptemp, apr_md5_ctx_t *hash, modssl_ctx_t *ctx) -+{ -+ md5_fmt_update(hash, "protocol:%d", ctx->protocol); -+ -+ md5_ifstr_update(hash, "ciphers:", ctx->auth.cipher_suite); -+ md5_ifstr_update(hash, "tls13_ciphers:", ctx->auth.tls13_ciphers); -+ -+ md5_strarray_hash(ptemp, hash, "cert_files:", ctx->pks->cert_files); -+ md5_strarray_hash(ptemp, hash, "key_files:", ctx->pks->key_files); -+} -+ -+static void hash_sni_policy_auth(apr_md5_ctx_t *hash, modssl_ctx_t *ctx) -+{ -+ modssl_pk_server_t *pks = ctx->pks; -+ modssl_auth_ctx_t *a = &ctx->auth; -+ -+ md5_fmt_update(hash, "verify_depth:%d", a->verify_depth); -+ md5_fmt_update(hash, "verify_mode:%d", a->verify_mode); -+ -+ md5_ifstr_update(hash, "ca_name_path:", pks->ca_name_path); -+ md5_ifstr_update(hash, "ca_name_file:", pks->ca_name_file); -+ md5_ifstr_update(hash, "ca_cert_path:", a->ca_cert_path); -+ md5_ifstr_update(hash, "ca_cert_file:", a->ca_cert_file); -+ md5_ifstr_update(hash, "crl_path:", ctx->crl_path); -+ md5_ifstr_update(hash, "crl_file:", ctx->crl_file); -+ md5_fmt_update(hash, "crl_check_mask:%d", ctx->crl_check_mask); -+ md5_fmt_update(hash, "ocsp_mask:%d", ctx->ocsp_mask); -+ md5_fmt_update(hash, "ocsp_force_default:%d", ctx->ocsp_force_default); -+ md5_ifstr_update(hash, "ocsp_responder:", ctx->ocsp_responder); -+ -+#ifdef HAVE_SRP -+ md5_ifstr_update(hash, "srp_vfile:", ctx->srp_vfile); -+#endif -+ -+#ifdef HAVE_SSL_CONF_CMD -+ { -+ apr_array_header_t *parms = ctx->ssl_ctx_param; -+ int n; -+ -+ for (n = 0; n < parms->nelts; n++) { -+ ssl_ctx_param_t *p = &APR_ARRAY_IDX(parms, n, ssl_ctx_param_t); -+ -+ md5_str_update(hash, "param:", p->name); -+ md5_str_update(hash, "value:", p->value); -+ } -+ } -+#endif -+} -+#endif -+ -+static char *create_sni_policy_hash(apr_pool_t *p, apr_pool_t *ptemp, -+ modssl_snivhpolicy_t policy, -+ SSLSrvConfigRec *sc) -+{ -+ char *rv = NULL; -+#ifdef HAVE_TLSEXT -+ if (policy != MODSSL_SNIVH_STRICT && policy != MODSSL_SNIVH_INSECURE) { -+ apr_md5_ctx_t hash; -+ unsigned char digest[APR_MD5_DIGESTSIZE]; -+ -+ /* Create the vhost policy hash for comparison later. */ -+ apr_md5_init(&hash); -+ hash_sni_policy_auth(&hash, sc->server); -+ if (policy == MODSSL_SNIVH_SECURE) -+ hash_sni_policy_pk(ptemp, &hash, sc->server); -+ apr_md5_final(digest, &hash); -+ -+ rv = apr_palloc(p, 2 * APR_MD5_DIGESTSIZE + 1); -+ ap_bin2hex(digest, APR_MD5_DIGESTSIZE, rv); /* sets final '\0' */ -+ } -+#endif -+ return rv; -+} -+ - /* _________________________________________________________________ - ** - ** Let other answer special connection attempts. -@@ -439,6 +544,8 @@ apr_status_t ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, - return rv; - } - } -+ -+ sc->sni_policy_hash = create_sni_policy_hash(p, ptemp, mc->snivh_policy, sc); - } - - /* -diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c -index 33aa1f7..83ae90e 100644 ---- a/modules/ssl/ssl_engine_kernel.c -+++ b/modules/ssl/ssl_engine_kernel.c -@@ -101,112 +101,28 @@ static int fill_reneg_buffer(request_rec *r, SSLDirConfigRec *dc) - } - - #ifdef HAVE_TLSEXT --static int ap_array_same_str_set(apr_array_header_t *s1, apr_array_header_t *s2) -+/* Check whether a transition from vhost sc1 to sc2 from SNI to Host: -+ * vhost selection is permitted according to the SSLVHostSNIPolicy -+ * setting. Returns 1 if the policy treats the vhosts as compatible, -+ * else 0. */ -+static int ssl_check_vhost_sni_policy(SSLSrvConfigRec *sc1, -+ SSLSrvConfigRec *sc2) - { -- int i; -- const char *c; -- -- if (s1 == s2) { -+ modssl_snivhpolicy_t policy = sc1->mc->snivh_policy; -+ -+ /* Policy: insecure => allow everything. */ -+ if (policy == MODSSL_SNIVH_INSECURE) - return 1; -- } -- else if (!s1 || !s2 || (s1->nelts != s2->nelts)) { -- return 0; -- } - -- for (i = 0; i < s1->nelts; i++) { -- c = APR_ARRAY_IDX(s1, i, const char *); -- if (!c || !ap_array_str_contains(s2, c)) { -- return 0; -- } -- } -- return 1; --} -+ /* Policy: strict => fail for any vhost transition. */ -+ if (policy == MODSSL_SNIVH_STRICT) -+ return sc1 == sc2; - --static int ssl_pk_server_compatible(modssl_pk_server_t *pks1, -- modssl_pk_server_t *pks2) --{ -- if (!pks1 || !pks2) { -- return 0; -- } -- /* both have the same certificates? */ -- if ((pks1->ca_name_path != pks2->ca_name_path) -- && (!pks1->ca_name_path || !pks2->ca_name_path -- || strcmp(pks1->ca_name_path, pks2->ca_name_path))) { -- return 0; -- } -- if ((pks1->ca_name_file != pks2->ca_name_file) -- && (!pks1->ca_name_file || !pks2->ca_name_file -- || strcmp(pks1->ca_name_file, pks2->ca_name_file))) { -- return 0; -- } -- if (!ap_array_same_str_set(pks1->cert_files, pks2->cert_files) -- || !ap_array_same_str_set(pks1->key_files, pks2->key_files)) { -- return 0; -- } -- return 1; --} -+ /* For authonly/secure policy, compare the hash. */ -+ AP_DEBUG_ASSERT(sc1->sni_policy_hash); -+ AP_DEBUG_ASSERT(sc2->sni_policy_hash); - --static int ssl_auth_compatible(modssl_auth_ctx_t *a1, -- modssl_auth_ctx_t *a2) --{ -- if (!a1 || !a2) { -- return 0; -- } -- /* both have the same verification */ -- if ((a1->verify_depth != a2->verify_depth) -- || (a1->verify_mode != a2->verify_mode)) { -- return 0; -- } -- /* both have the same ca path/file */ -- if ((a1->ca_cert_path != a2->ca_cert_path) -- && (!a1->ca_cert_path || !a2->ca_cert_path -- || strcmp(a1->ca_cert_path, a2->ca_cert_path))) { -- return 0; -- } -- if ((a1->ca_cert_file != a2->ca_cert_file) -- && (!a1->ca_cert_file || !a2->ca_cert_file -- || strcmp(a1->ca_cert_file, a2->ca_cert_file))) { -- return 0; -- } -- /* both have the same ca cipher suite string */ -- if ((a1->cipher_suite != a2->cipher_suite) -- && (!a1->cipher_suite || !a2->cipher_suite -- || strcmp(a1->cipher_suite, a2->cipher_suite))) { -- return 0; -- } -- /* both have the same ca cipher suite string */ -- if ((a1->tls13_ciphers != a2->tls13_ciphers) -- && (!a1->tls13_ciphers || !a2->tls13_ciphers -- || strcmp(a1->tls13_ciphers, a2->tls13_ciphers))) { -- return 0; -- } -- return 1; --} -- --static int ssl_ctx_compatible(modssl_ctx_t *ctx1, -- modssl_ctx_t *ctx2) --{ -- if (!ctx1 || !ctx2 -- || (ctx1->protocol != ctx2->protocol) -- || !ssl_auth_compatible(&ctx1->auth, &ctx2->auth) -- || !ssl_pk_server_compatible(ctx1->pks, ctx2->pks)) { -- return 0; -- } -- return 1; --} -- --static int ssl_server_compatible(server_rec *s1, server_rec *s2) --{ -- SSLSrvConfigRec *sc1 = s1? mySrvConfig(s1) : NULL; -- SSLSrvConfigRec *sc2 = s2? mySrvConfig(s2) : NULL; -- -- /* both use the same TLS protocol? */ -- if (!sc1 || !sc2 -- || !ssl_ctx_compatible(sc1->server, sc2->server)) { -- return 0; -- } -- -- return 1; -+ return strcmp(sc1->sni_policy_hash, sc2->sni_policy_hash) == 0; - } - #endif - -@@ -275,6 +191,8 @@ int ssl_hook_ReadReq(request_rec *r) - server_rec *handshakeserver = sslconn->server; - SSLSrvConfigRec *hssc = mySrvConfig(handshakeserver); - -+ AP_DEBUG_ASSERT(hssc); -+ - if ((servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name))) { - /* - * The SNI extension supplied a hostname. So don't accept requests -@@ -315,19 +233,14 @@ int ssl_hook_ReadReq(request_rec *r) - "which is required to access this server.
      \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 -- */ -- -+ /* Enforce SSL SNI vhost compatibility policy. */ -+ if (!ssl_check_vhost_sni_policy(sc, hssc)) { - 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", -+ " via HTTP have no compatible SSL setup for policy '%s'", - servername ? servername : handshakeserver->server_hostname, - servername ? "provided via SNI" : "(default host as no SNI was provided)", -- r->hostname); -+ r->hostname, MODSSL_SNIVH_NAME(sc->mc->snivh_policy)); - return HTTP_MISDIRECTED_REQUEST; - } - } -diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h -index 2b18189..dbef182 100644 ---- a/modules/ssl/ssl_private.h -+++ b/modules/ssl/ssl_private.h -@@ -556,6 +556,19 @@ typedef struct { - int nBytes; - } ssl_randseed_t; - -+/* SNI vhost compatibility policy. */ -+typedef enum { -+ MODSSL_SNIVH_STRICT = 0, -+ MODSSL_SNIVH_SECURE = 1, -+ MODSSL_SNIVH_AUTHONLY = 2, -+ MODSSL_SNIVH_INSECURE = 3 -+} modssl_snivhpolicy_t; -+ -+/* Maps modssl_snivhpolicy_t back into a config option string. */ -+#define MODSSL_SNIVH_NAME(p_) ((p_) == MODSSL_SNIVH_STRICT ? "strict" : \ -+ ((p_) == MODSSL_SNIVH_SECURE ? "secure" : \ -+ ((p_) == MODSSL_SNIVH_AUTHONLY ? "authonly" : "insecure" ))) -+ - /** - * Define the structure of an ASN.1 anything - */ -@@ -689,6 +702,8 @@ typedef struct { - #ifdef HAVE_FIPS - BOOL fips; - #endif -+ -+ modssl_snivhpolicy_t snivh_policy; - } SSLModConfigRec; - - /** Structure representing configured filenames for certs and keys for -@@ -843,6 +858,7 @@ struct SSLSrvConfigRec { - modssl_ctx_t *server; - #ifdef HAVE_TLSEXT - ssl_enabled_t strict_sni_vhost_check; -+ const char *sni_policy_hash; - #endif - #ifndef OPENSSL_NO_COMP - BOOL compression; -@@ -918,6 +934,7 @@ const char *ssl_cmd_SSLRequire(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLUserName(cmd_parms *, void *, const char *); - const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg); - const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag); -+const char *ssl_cmd_SSLVHostSNIPolicy(cmd_parms *cmd, void *dcfg, const char *arg); - const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag); - - const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag); --- -2.44.0 - diff --git a/httpd.spec b/httpd.spec index 91c8d2f..45f21c9 100644 --- a/httpd.spec +++ b/httpd.spec @@ -30,8 +30,8 @@ Summary: Apache HTTP Server Name: httpd -Version: 2.4.65 -Release: 5%{?dist} +Version: 2.4.66 +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 @@ -99,7 +99,6 @@ Patch27: httpd-2.4.64-sslprotdefault.patch Patch28: httpd-2.4.43-logjournal.patch Patch29: httpd-2.4.63-r1912477+.patch Patch30: httpd-2.4.64-separate-systemd-fns.patch -Patch31: httpd-2.4.65-sslvhostsnipolicy.patch # Bug fixes # https://bugzilla.redhat.com/show_bug.cgi?id=1397243 @@ -847,6 +846,9 @@ exit $rv %{_rpmconfigdir}/macros.d/macros.httpd %changelog +* Tue Dec 09 2025 Luboš Uhliarik - 2.4.66-1 +- new version 2.4.66 + * Thu Nov 27 2025 Luboš Uhliarik - 2.4.65-5 - Improve default httpd LogFormats for better support diagnostics diff --git a/sources b/sources index 8d4165c..d84ddb9 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (httpd-2.4.65.tar.bz2) = 202f8bfe2aafcfbcd7315191d466e9c10b9a8c0abafb7864510b6e1abe4cb660aaacc2456aa77d43e48ef7a49e591d0b54170d3daf67abc3e06c3da1c63fdffc -SHA512 (httpd-2.4.65.tar.bz2.asc) = edcf02be97567fb28fef78f757e3355802575782ab452eaea79da70812b20ef4ba49a609e409a9664ec2546720b303deebbd563f3079ce4e77d67b91816210d1 +SHA512 (httpd-2.4.66.tar.bz2) = 49031a3465d956ee3b755e65810b6c35561ddd5fac2c624a273b733c238e115b914cd7b246837e5a3090ccfded6e0b8b3059bfd1f8ce4419081c805a38d05a4b +SHA512 (httpd-2.4.66.tar.bz2.asc) = 3fc7a4c6c0705adc3f8223ed3d6ebc45f09b7a19ab63a8b4d359835d2b592cf11f0fd0438a40b5a43c0684b36602484bb908bf46b0c068dd22bacc2c194e7fbd SHA512 (KEYS) = 88c848b7ab9e4915d6625dcad3e8328673b0448f2ce76f2c44eecc612cf6afbce3287a4ee7219a44c6fcc61d5ecb2a1a8545456a4a16b90400263d7249cbf192