+diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
+index 0c4bf1f..ca5f702 100644
+--- a/modules/ssl/ssl_engine_config.c
++++ b/modules/ssl/ssl_engine_config.c
+@@ -269,6 +269,7 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p,
+ mrg->protocol_set = 1;
+ }
+ else {
++ mrg->protocol_set = base->protocol_set;
+ mrg->protocol = base->protocol;
+ }
+
+diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
+index 31062bc..70d151e 100644
+--- a/modules/ssl/ssl_engine_init.c
++++ b/modules/ssl/ssl_engine_init.c
+@@ -520,7 +520,9 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s,
+ "Configuring TLS extension handling");
+
+ /*
+- * Server name indication (SNI)
++ * The Server Name Indication (SNI) provided by the ClientHello can be
++ * used to select the right (name-based-)vhost and its SSL configuration
++ * before the handshake takes place.
+ */
+ if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
+ ssl_callback_ServerNameIndication) ||
+@@ -532,6 +534,16 @@ static apr_status_t ssl_init_ctx_tls_extensions(server_rec *s,
+ return ssl_die(s);
+ }
+
++#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
++ /*
++ * The ClientHello callback also allows to retrieve the SNI, but since it
++ * runs at the earliest possible connection stage we can even set the TLS
++ * protocol version(s) according to the selected (name-based-)vhost, which
++ * is not possible at the SNI callback stage (due to OpenSSL internals).
++ */
++ SSL_CTX_set_client_hello_cb(mctx->ssl_ctx, ssl_callback_ClientHello, NULL);
++#endif
++
+ #ifdef HAVE_OCSP_STAPLING
+ /*
+ * OCSP Stapling support, status_request extension
+@@ -708,7 +720,7 @@ static apr_status_t ssl_init_ctx_protocol(server_rec *s,
+ #else /* #if OPENSSL_VERSION_NUMBER < 0x10100000L */
+ /* We first determine the maximum protocol version we should provide */
+ #if SSL_HAVE_PROTOCOL_TLSV1_3
+- if (SSL_HAVE_PROTOCOL_TLSV1_3 && (protocol & SSL_PROTOCOL_TLSV1_3)) {
++ if (protocol & SSL_PROTOCOL_TLSV1_3) {
+ prot = TLS1_3_VERSION;
+ } else
+ #endif
+diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
+index 8b44674..7313a55 100644
+--- a/modules/ssl/ssl_engine_kernel.c
++++ b/modules/ssl/ssl_engine_kernel.c
+@@ -2357,28 +2357,31 @@ static apr_status_t set_challenge_creds(conn_rec *c, const char *servername,
+ * This function sets the virtual host from an extended
+ * client hello with a server name indication extension ("SNI", cf. RFC 6066).
+ */
+-static apr_status_t init_vhost(conn_rec *c, SSL *ssl)
++static apr_status_t init_vhost(conn_rec *c, SSL *ssl, const char *servername)
+ {
+- const char *servername;
+ X509 *cert;
+ EVP_PKEY *key;
+
+ if (c) {
+ SSLConnRec *sslcon = myConnConfig(c);
+-
+- if (sslcon->server != c->base_server) {
+- /* already found the vhost */
+- return APR_SUCCESS;
++
++ if (sslcon->vhost_found) {
++ /* already found the vhost? */
++ return sslcon->vhost_found > 0 ? APR_SUCCESS : APR_NOTFOUND;
+ }
++ sslcon->vhost_found = -1;
+
+- servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
++ if (!servername) {
++ servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
++ }
+ if (servername) {
+ if (ap_vhost_iterate_given_conn(c, ssl_find_vhost,
+ (void *)servername)) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02043)
+ "SSL virtual host for servername %s found",
+ servername);
+-
++
++ sslcon->vhost_found = +1;
+ return APR_SUCCESS;
+ }
+ else if (ssl_is_challenge(c, servername, &cert, &key)) {
+@@ -2428,11 +2431,72 @@ static apr_status_t init_vhost(conn_rec *c, SSL *ssl)
+ int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx)
+ {
+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
+- apr_status_t status = init_vhost(c, ssl);
++ apr_status_t status = init_vhost(c, ssl, NULL);
+
+ return (status == APR_SUCCESS)? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_NOACK;
+ }
+
++#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
++/*
++ * This callback function is called when the ClientHello is received.
++ */
++int ssl_callback_ClientHello(SSL *ssl, int *al, void *arg)
++{
++ char *servername = NULL;
++ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
++ const unsigned char *pos;
++ size_t len, remaining;
++ (void)arg;
++
++ /* We can't use SSL_get_servername() at this earliest OpenSSL connection
++ * stage, and there is no SSL_client_hello_get0_servername() provided as
++ * of OpenSSL 1.1.1. So the code below, that extracts the SNI from the
++ * ClientHello's TLS extensions, is taken from some test code in OpenSSL,
++ * i.e. client_hello_select_server_ctx() in "test/handshake_helper.c".
++ */
++
++ /*
++ * The server_name extension was given too much extensibility when it
++ * was written, so parsing the normal case is a bit complex.
++ */
++ if (!SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &pos,
++ &remaining)
++ || remaining <= 2)
++ goto give_up;
++
++ /* Extract the length of the supplied list of names. */
++ len = (*(pos++) << 8);
++ len += *(pos++);
++ if (len + 2 != remaining)
++ goto give_up;
++ remaining = len;
++
++ /*
++ * The list in practice only has a single element, so we only consider
++ * the first one.
++ */
++ if (remaining <= 3 || *pos++ != TLSEXT_NAMETYPE_host_name)
++ goto give_up;
++ remaining--;
++
++ /* Now we can finally pull out the byte array with the actual hostname. */
++ len = (*(pos++) << 8);
++ len += *(pos++);
++ if (len + 2 != remaining)
++ goto give_up;
++
++ /* Use the SNI to switch to the relevant vhost, should it differ from
++ * c->base_server.
++ */
++ servername = apr_pstrmemdup(c->pool, (const char *)pos, len);
++
++give_up:
++ init_vhost(c, ssl, servername);
++ return SSL_CLIENT_HELLO_SUCCESS;
++}
++#endif /* OPENSSL_VERSION_NUMBER < 0x10101000L */
++
++
+ /*
+ * Find a (name-based) SSL virtual host where either the ServerName
+ * or one of the ServerAliases matches the supplied name (to be used
+@@ -2452,12 +2516,25 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
+ if (found && (ssl = sslcon->ssl) &&
+ (sc = mySrvConfig(s))) {
+ SSL_CTX *ctx = SSL_set_SSL_CTX(ssl, sc->server->ssl_ctx);
++
+ /*
+ * SSL_set_SSL_CTX() only deals with the server cert,
+ * so we need to duplicate a few additional settings
+ * from the ctx by hand
+ */
+ SSL_set_options(ssl, SSL_CTX_get_options(ctx));
++#if OPENSSL_VERSION_NUMBER >= 0x10100000L \
++ && (!defined(LIBRESSL_VERSION_NUMBER) \
++ || LIBRESSL_VERSION_NUMBER >= 0x20800000L)
++ /*
++ * Don't switch the protocol if none is configured for this vhost,
++ * the default in this case is still the base server's SSLProtocol.
++ */
++ if (myCtxConfig(sslcon, sc)->protocol_set) {
++ SSL_set_min_proto_version(ssl, SSL_CTX_get_min_proto_version(ctx));
++ SSL_set_max_proto_version(ssl, SSL_CTX_get_max_proto_version(ctx));
++ }
++#endif
+ if ((SSL_get_verify_mode(ssl) == SSL_VERIFY_NONE) ||
+ (SSL_num_renegotiations(ssl) == 0)) {
+ /*
+@@ -2654,7 +2731,7 @@ int ssl_callback_alpn_select(SSL *ssl,
+ * they callback the SNI. We need to make sure that we know which vhost
+ * we are dealing with so we respect the correct protocols.
+ */
+- init_vhost(c, ssl);
++ init_vhost(c, ssl, NULL);
+
+ proposed = ap_select_protocol(c, NULL, sslconn->server, client_protos);
+ if (!proposed) {
+diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
+index 8055200..f8a1db7 100644
+--- a/modules/ssl/ssl_private.h
++++ b/modules/ssl/ssl_private.h
+@@ -563,6 +563,7 @@ typedef struct {
+
+ const char *cipher_suite; /* cipher suite used in last reneg */
+ int service_unavailable; /* thouugh we negotiate SSL, no requests will be served */
++ int vhost_found; /* whether we found vhost from SNI already */
+ } SSLConnRec;
+
+ /* BIG FAT WARNING: SSLModConfigRec has unusual memory lifetime: it is
+@@ -946,6 +947,9 @@ void ssl_callback_Info(const SSL *, int, int);
+ #ifdef HAVE_TLSEXT
+ int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
+ #endif
++#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
++int ssl_callback_ClientHello(SSL *, int *, void *);
++#endif
+ #ifdef HAVE_TLS_SESSION_TICKETS
+ int ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *,
+ EVP_CIPHER_CTX *, HMAC_CTX *, int);
diff --git a/SOURCES/httpd-2.4.37-reply-two-tls-rec.patch b/SOURCES/httpd-2.4.37-reply-two-tls-rec.patch
new file mode 100644
index 0000000..a4a3835
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-reply-two-tls-rec.patch
@@ -0,0 +1,188 @@
+diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
+index 018b667..4e3875a 100644
+--- a/modules/ssl/ssl_engine_io.c
++++ b/modules/ssl/ssl_engine_io.c
+@@ -1598,18 +1598,32 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
+ }
+
+
+-/* ssl_io_filter_output() produces one SSL/TLS message per bucket
++/* ssl_io_filter_output() produces one SSL/TLS record per bucket
+ * passed down the output filter stack. This results in a high
+- * overhead (network packets) for any output comprising many small
+- * buckets. SSI page applied through the HTTP chunk filter, for
+- * example, may produce many brigades containing small buckets -
+- * [chunk-size CRLF] [chunk-data] [CRLF].
++ * overhead (more network packets & TLS processing) for any output
++ * comprising many small buckets. SSI output passed through the HTTP
++ * chunk filter, for example, may produce many brigades containing
++ * small buckets - [chunk-size CRLF] [chunk-data] [CRLF].
+ *
+- * The coalescing filter merges many small buckets into larger buckets
+- * where possible, allowing the SSL I/O output filter to handle them
+- * more efficiently. */
++ * Sending HTTP response headers as a separate TLS record to the
++ * response body also reveals information to a network observer (the
++ * size of headers) which can be significant.
++ *
++ * The coalescing filter merges data buckets with the aim of producing
++ * fewer, larger TLS records - without copying/buffering all content
++ * and introducing unnecessary overhead.
++ *
++ * ### This buffering could be probably be done more comprehensively
++ * ### in ssl_io_filter_output itself.
++ *
++ * ### Another possible performance optimisation in particular for the
++ * ### [HEAP] [FILE] HTTP response case is using a brigade rather than
++ * ### a char array to buffer; using apr_brigade_write() to append
++ * ### will use already-allocated memory from the HEAP, reducing # of
++ * ### copies.
++ */
+
+-#define COALESCE_BYTES (2048)
++#define COALESCE_BYTES (AP_IOBUFSIZE)
+
+ struct coalesce_ctx {
+ char buffer[COALESCE_BYTES];
+@@ -1622,11 +1636,12 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f,
+ apr_bucket *e, *upto;
+ apr_size_t bytes = 0;
+ struct coalesce_ctx *ctx = f->ctx;
++ apr_size_t buffered = ctx ? ctx->bytes : 0; /* space used on entry */
+ unsigned count = 0;
+
+ /* The brigade consists of zero-or-more small data buckets which
+- * can be coalesced (the prefix), followed by the remainder of the
+- * brigade.
++ * can be coalesced (referred to as the "prefix"), followed by the
++ * remainder of the brigade.
+ *
+ * Find the last bucket - if any - of that prefix. count gives
+ * the number of buckets in the prefix. The "prefix" must contain
+@@ -1641,24 +1656,97 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f,
+ e != APR_BRIGADE_SENTINEL(bb)
+ && !APR_BUCKET_IS_METADATA(e)
+ && e->length != (apr_size_t)-1
+- && e->length < COALESCE_BYTES
+- && (bytes + e->length) < COALESCE_BYTES
+- && (ctx == NULL
+- || bytes + ctx->bytes + e->length < COALESCE_BYTES);
++ && e->length <= COALESCE_BYTES
++ && (buffered + bytes + e->length) <= COALESCE_BYTES;
+ e = APR_BUCKET_NEXT(e)) {
+ if (e->length) count++; /* don't count zero-length buckets */
+ bytes += e->length;
+ }
++
++ /* If there is room remaining and the next bucket is a data
++ * bucket, try to include it in the prefix to coalesce. For a
++ * typical [HEAP] [FILE] HTTP response brigade, this handles
++ * merging the headers and the start of the body into a single TLS
++ * record. */
++ if (bytes + buffered > 0
++ && bytes + buffered < COALESCE_BYTES
++ && e != APR_BRIGADE_SENTINEL(bb)
++ && !APR_BUCKET_IS_METADATA(e)) {
++ apr_status_t rv = APR_SUCCESS;
++
++ /* For an indeterminate length bucket (PIPE/CGI/...), try a
++ * non-blocking read to have it morph into a HEAP. If the
++ * read fails with EAGAIN, it is harmless to try a split
++ * anyway, split is ENOTIMPL for most PIPE-like buckets. */
++ if (e->length == (apr_size_t)-1) {
++ const char *discard;
++ apr_size_t ignore;
++
++ rv = apr_bucket_read(e, &discard, &ignore, APR_NONBLOCK_READ);
++ if (rv != APR_SUCCESS && !APR_STATUS_IS_EAGAIN(rv)) {
++ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(10232)
++ "coalesce failed to read from %s bucket",
++ e->type->name);
++ return AP_FILTER_ERROR;
++ }
++ }
++
++ if (rv == APR_SUCCESS) {
++ /* If the read above made the bucket morph, it may now fit
++ * entirely within the buffer. Otherwise, split it so it does
++ * fit. */
++ if (e->length > COALESCE_BYTES
++ || e->length + buffered + bytes > COALESCE_BYTES) {
++ rv = apr_bucket_split(e, COALESCE_BYTES - (buffered + bytes));
++ }
++
++ if (rv == APR_SUCCESS && e->length == 0) {
++ /* As above, don't count in the prefix if the bucket is
++ * now zero-length. */
++ }
++ else if (rv == APR_SUCCESS) {
++ ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
++ "coalesce: adding %" APR_SIZE_T_FMT " bytes "
++ "from split %s bucket, total %" APR_SIZE_T_FMT,
++ e->length, e->type->name, bytes + buffered);
++
++ count++;
++ bytes += e->length;
++ e = APR_BUCKET_NEXT(e);
++ }
++ else if (rv != APR_ENOTIMPL) {
++ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(10233)
++ "coalesce: failed to split data bucket");
++ return AP_FILTER_ERROR;
++ }
++ }
++ }
++
++ /* The prefix is zero or more buckets. upto now points to the
++ * bucket AFTER the end of the prefix, which may be the brigade
++ * sentinel. */
+ upto = e;
+
+- /* Coalesce the prefix, if:
+- * a) more than one bucket is found to coalesce, or
+- * b) the brigade contains only a single data bucket, or
+- * c) the data bucket is not last but we have buffered data already.
++ /* Coalesce the prefix, if any of the following are true:
++ *
++ * a) the prefix is more than one bucket
++ * OR
++ * b) the prefix is the entire brigade, which is a single bucket
++ * AND the prefix length is smaller than the buffer size,
++ * OR
++ * c) the prefix is a single bucket
++ * AND there is buffered data from a previous pass.
++ *
++ * The aim with (b) is to buffer a small bucket so it can be
++ * coalesced with future invocations of this filter. e.g. three
++ * calls each with a single 100 byte HEAP bucket should get
++ * coalesced together. But an invocation with a 8192 byte HEAP
++ * should pass through untouched.
+ */
+ if (bytes > 0
+ && (count > 1
+- || (upto == APR_BRIGADE_SENTINEL(bb))
++ || (upto == APR_BRIGADE_SENTINEL(bb)
++ && bytes < COALESCE_BYTES)
+ || (ctx && ctx->bytes > 0))) {
+ /* If coalescing some bytes, ensure a context has been
+ * created. */
+@@ -1669,7 +1757,8 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f,
+
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
+ "coalesce: have %" APR_SIZE_T_FMT " bytes, "
+- "adding %" APR_SIZE_T_FMT " more", ctx->bytes, bytes);
++ "adding %" APR_SIZE_T_FMT " more (buckets=%u)",
++ ctx->bytes, bytes, count);
+
+ /* Iterate through the prefix segment. For non-fatal errors
+ * in this loop it is safe to break out and fall back to the
+@@ -1684,7 +1773,8 @@ static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f,
+ if (APR_BUCKET_IS_METADATA(e)
+ || e->length == (apr_size_t)-1) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(02012)
+- "unexpected bucket type during coalesce");
++ "unexpected %s bucket during coalesce",
++ e->type->name);
+ break; /* non-fatal error; break out */
+ }
+
diff --git a/SOURCES/httpd-2.4.37-usertrack-samesite.patch b/SOURCES/httpd-2.4.37-usertrack-samesite.patch
new file mode 100644
index 0000000..592616e
--- /dev/null
+++ b/SOURCES/httpd-2.4.37-usertrack-samesite.patch
@@ -0,0 +1,178 @@
+diff --git a/docs/manual/mod/mod_usertrack.html.en b/docs/manual/mod/mod_usertrack.html.en
+index b212747..d2da9b9 100644
+--- a/docs/manual/mod/mod_usertrack.html.en
++++ b/docs/manual/mod/mod_usertrack.html.en
+@@ -47,7 +47,10 @@
+
+@@ -127,6 +130,22 @@ CustomLog "logs/clickstream.log" usertrack
+
CookieExpires "3 weeks"
+
+
++
++
+diff --git a/modules/metadata/mod_usertrack.c b/modules/metadata/mod_usertrack.c
+index 73a9f45..65759c2 100644
+--- a/modules/metadata/mod_usertrack.c
++++ b/modules/metadata/mod_usertrack.c
+@@ -86,6 +86,9 @@ typedef struct {
+ const char *cookie_domain;
+ char *regexp_string; /* used to compile regexp; save for debugging */
+ ap_regex_t *regexp; /* used to find usertrack cookie in cookie header */
++ int is_secure;
++ int is_httponly;
++ const char *samesite;
+ } cookie_dir_rec;
+
+ /* Make Cookie: Now we have to generate something that is going to be
+@@ -143,6 +146,21 @@ static void make_cookie(request_rec *r)
+ : ""),
+ NULL);
+ }
++ if (dcfg->samesite != NULL) {
++ new_cookie = apr_pstrcat(r->pool, new_cookie, "; ",
++ dcfg->samesite,
++ NULL);
++ }
++ if (dcfg->is_secure) {
++ new_cookie = apr_pstrcat(r->pool, new_cookie, "; Secure",
++ NULL);
++ }
++ if (dcfg->is_httponly) {
++ new_cookie = apr_pstrcat(r->pool, new_cookie, "; HttpOnly",
++ NULL);
++ }
++
++
+
+ apr_table_addn(r->err_headers_out,
+ (dcfg->style == CT_COOKIE2 ? "Set-Cookie2" : "Set-Cookie"),
+@@ -269,6 +287,7 @@ static void *make_cookie_dir(apr_pool_t *p, char *d)
+ dcfg->cookie_domain = NULL;
+ dcfg->style = CT_UNSET;
+ dcfg->enabled = 0;
++ /* calloc'ed to disabled: samesite, is_secure, is_httponly */
+
+ /* In case the user does not use the CookieName directive,
+ * we need to compile the regexp for the default cookie name. */
+@@ -429,6 +448,31 @@ static const char *set_cookie_style(cmd_parms *cmd, void *mconfig,
+ return NULL;
+ }
+
++/*
++ * SameSite enabled disabled
++ */
++
++static const char *set_samesite_value(cmd_parms *cmd, void *mconfig,
++ const char *name)
++{
++ cookie_dir_rec *dcfg;
++
++ dcfg = (cookie_dir_rec *) mconfig;
++
++ if (strcasecmp(name, "strict") == 0) {
++ dcfg->samesite = "SameSite=Strict";
++ } else if (strcasecmp(name, "lax") == 0) {
++ dcfg->samesite = "SameSite=Lax";
++ } else if (strcasecmp(name, "none") == 0) {
++ dcfg->samesite = "SameSite=None";
++ } else {
++ return "CookieSameSite accepts 'Strict', 'Lax', or 'None'";
++ }
++
++
++ return NULL;
++}
++
+ static const command_rec cookie_log_cmds[] = {
+ AP_INIT_TAKE1("CookieExpires", set_cookie_exp, NULL, OR_FILEINFO,
+ "an expiry date code"),
+@@ -440,6 +484,17 @@ static const command_rec cookie_log_cmds[] = {
+ "whether or not to enable cookies"),
+ AP_INIT_TAKE1("CookieName", set_cookie_name, NULL, OR_FILEINFO,
+ "name of the tracking cookie"),
++ AP_INIT_FLAG("CookieTracking", set_cookie_enable, NULL, OR_FILEINFO,
++ "whether or not to enable cookies"),
++ AP_INIT_TAKE1("CookieSameSite", set_samesite_value, NULL, OR_FILEINFO,
++ "SameSite setting"),
++ AP_INIT_FLAG("CookieSecure", ap_set_flag_slot,
++ (void *)APR_OFFSETOF(cookie_dir_rec, is_secure), OR_FILEINFO,
++ "is cookie secure"),
++ AP_INIT_FLAG("CookieHttpOnly", ap_set_flag_slot,
++ (void *)APR_OFFSETOF(cookie_dir_rec, is_httponly),OR_FILEINFO,
++ "is cookie http only"),
++
+ {NULL}
+ };
+
diff --git a/SOURCES/welcome.conf b/SOURCES/welcome.conf
index 5158e8b..37b7394 100644
--- a/SOURCES/welcome.conf
+++ b/SOURCES/welcome.conf
@@ -16,4 +16,4 @@
Alias /.noindex.html /usr/share/httpd/noindex/index.html
-Alias /poweredby.png /usr/share/httpd/icons/apache_pb2.png
\ No newline at end of file
+Alias /poweredby.png /usr/share/httpd/icons/apache_pb3.png
\ No newline at end of file
diff --git a/SPECS/httpd.spec b/SPECS/httpd.spec
index db8f959..2d766e0 100644
--- a/SPECS/httpd.spec
+++ b/SPECS/httpd.spec
@@ -13,7 +13,7 @@
Summary: Apache HTTP Server
Name: httpd
Version: 2.4.37
-Release: 39%{?dist}.2
+Release: 43%{?dist}.1
URL: https://httpd.apache.org/
Source0: https://www.apache.org/dist/httpd/httpd-%{version}.tar.bz2
Source2: httpd.logrotate
@@ -54,6 +54,7 @@ Source42: httpd-init.service
Source43: httpd-ssl-gencerts
Source44: httpd@.service
Source45: config.layout
+Source46: apache-poweredby.png
# build/scripts patches
# http://bugzilla.redhat.com/show_bug.cgi?id=1231924
@@ -101,6 +102,8 @@ Patch38: httpd-2.4.37-pr37355.patch
Patch39: httpd-2.4.37-proxy-ws-idle-timeout.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1883648
Patch40: httpd-2.4.37-ssl-proxy-chains.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1935742
+Patch41: httpd-2.4.37-usertrack-samesite.patch
# Bug fixes
# https://bugzilla.redhat.com/show_bug.cgi?id=1397243
@@ -150,6 +153,12 @@ Patch83: httpd-2.4.37-r1878890.patch
Patch84: httpd-2.4.37-r1878280.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1891594
Patch85: httpd-2.4.37-htcacheclean-dont-break.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1937334
+Patch86: httpd-2.4.37-r1873907.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1680111
+Patch87: httpd-2.4.37-reply-two-tls-rec.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1905613
+Patch88: httpd-2.4.37-r1845768+.patch
# Security fixes
Patch200: httpd-2.4.37-r1851471.patch
@@ -179,10 +188,16 @@ Patch209: httpd-2.4.37-CVE-2020-1934.patch
Patch210: httpd-2.4.37-CVE-2018-17199.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1866563
Patch211: httpd-2.4.37-CVE-2020-11984.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1972500
+Patch212: httpd-2.4.37-CVE-2021-30641.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1968307
+Patch213: httpd-2.4.37-CVE-2021-26690.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=2005117
-Patch212: httpd-2.4.37-CVE-2021-40438.patch
+Patch214: httpd-2.4.37-CVE-2021-40438.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1966732
-Patch213: httpd-2.4.37-CVE-2021-26691.patch
+Patch215: httpd-2.4.37-CVE-2021-26691.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2034674
+Patch216: httpd-2.4.37-CVE-2021-44790.patch
License: ASL 2.0
Group: System Environment/Daemons
@@ -192,7 +207,8 @@ BuildRequires: zlib-devel, libselinux-devel, lua-devel, brotli-devel
BuildRequires: apr-devel >= 1.5.0, apr-util-devel >= 1.5.0, pcre-devel >= 5.0
BuildRequires: systemd-devel
# web server testpage added to redhat-logos in 82.0 (rhbz1896319)
-Requires: /etc/mime.types, system-logos-httpd >= 82.0
+# new logo requires new footer copyring which was added in rhbz1934800
+Requires: /etc/mime.types, system-logos(httpd-logo-ng)
Obsoletes: httpd-suexec
Provides: webserver
Provides: mod_dav = %{version}-%{release}, httpd-suexec = %{version}-%{release}
@@ -332,6 +348,7 @@ interface for storing and accessing per-user session data.
%patch38 -p1 -b .pr37355
%patch39 -p1 -b .proxy-ws-idle-timeout
%patch40 -p1 -b .ssl-proxy-chains
+%patch41 -p1 -b .usertrack-samesite
%patch61 -p1 -b .r1738878
%patch62 -p1 -b .r1633085
@@ -356,6 +373,9 @@ interface for storing and accessing per-user session data.
%patch83 -p1 -b .r1878890
%patch84 -p1 -b .r1878280
%patch85 -p1 -b .htcacheclean-dont-break
+%patch86 -p1 -b .r1873907
+%patch87 -p1 -b .reply-two-tls-rec
+%patch88 -p1 -b .r1845768+
%patch200 -p1 -b .r1851471
%patch201 -p1 -b .CVE-2019-0211
@@ -369,8 +389,11 @@ interface for storing and accessing per-user session data.
%patch209 -p1 -b .CVE-2020-1934
%patch210 -p1 -b .CVE-2018-17199
%patch211 -p1 -b .CVE-2020-11984
-%patch212 -p1 -b .CVE-2021-40438
-%patch213 -p1 -b .CVE-2021-26691
+%patch212 -p1 -b .CVE-2021-30641
+%patch213 -p1 -b .CVE-2021-26690
+%patch214 -p1 -b .CVE-2021-40438
+%patch215 -p1 -b .CVE-2021-26691
+%patch216 -p1 -b .CVE-2021-44790
# Patch in the vendor string
sed -i '/^#define PLATFORM/s/Unix/%{vstring}/' os/unix/os.h
@@ -397,6 +420,9 @@ if test "x${vmmn}" != "x%{mmn}"; then
exit 1
fi
+# A new logo which comes together with a new test page
+cp %{SOURCE46} ./docs/icons/apache_pb3.png
+
# Provide default layout
cp $RPM_SOURCE_DIR/config.layout .
@@ -873,19 +899,34 @@ rm -rf $RPM_BUILD_ROOT
%{_rpmconfigdir}/macros.d/macros.httpd
%changelog
-* Wed Nov 10 2021 CentOS Sources
- 2.4.37-39.el8.centos.2
-- Apply debranding changes
+* Mon Jan 10 2022 Luboš Uhliarik - 2.4.37-43.1
+- Resolves: #2035062 - CVE-2021-44790 httpd:2.4/httpd: mod_lua: possible buffer
+ overflow when parsing multipart content
-* Fri Oct 29 2021 Luboš Uhliarik - 2.4.37-39.2
-- Resolves: #2017856 - proxy rewrite to unix socket fails with CVE-2021-40438
- fix
+* Tue Oct 26 2021 Luboš Uhliarik - 2.4.37-43
+- Related: #2007235 - CVE-2021-40438 httpd:2.4/httpd: mod_proxy: SSRF via
+ a crafted request uri-path
-* Thu Sep 30 2021 Luboš Uhliarik - 2.4.37-39.1
-- Resolves: #2007234 - CVE-2021-40438 httpd:2.4/httpd: mod_proxy: SSRF via
+* Thu Sep 30 2021 Luboš Uhliarik - 2.4.37-42
+- Resolves: #2007235 - CVE-2021-40438 httpd:2.4/httpd: mod_proxy: SSRF via
a crafted request uri-path
-- Resolves: #2007646 - CVE-2021-26691 httpd:2.4/httpd: Heap overflow in
+- Resolves: #2014063 - CVE-2021-26691 httpd:2.4/httpd: Heap overflow in
mod_session
+* Fri Jul 09 2021 Luboš Uhliarik - 2.4.37-41
+- Resolves: #1680111 - httpd sends reply to HTTPS GET using two TLS records
+- Resolves: #1905613 - mod_ssl does not like valid certificate chain
+- Resolves: #1935742 - [RFE] backport samesite/httponly/secure flags for
+ usertrack
+- Resolves: #1972500 - CVE-2021-30641 httpd:2.4/httpd: MergeSlashes regression
+- Resolves: #1968307 - CVE-2021-26690 httpd:2.4/httpd: mod_session NULL pointer
+ dereference in parser
+- Resolves: #1934741 - Apache trademark update - new logo
+
+* Fri May 14 2021 Lubos Uhliarik - 2.4.37-40
+- Resolves: #1952557 - mod_proxy_wstunnel.html is a malformed XML
+- Resolves: #1937334 - SSLProtocol with based virtual hosts
+
* Tue Jan 26 2021 Artem Egorenkov - 2.4.37-39
- prevent htcacheclean from while break when first file processed