Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package nginx for openSUSE:Factory checked in at 2025-08-15 21:51:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/nginx (Old) and /work/SRC/openSUSE:Factory/.nginx.new.1085 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "nginx" Fri Aug 15 21:51:02 2025 rev:103 rq:1299344 version:1.29.1 Changes: -------- --- /work/SRC/openSUSE:Factory/nginx/nginx.changes 2025-07-20 15:28:50.275488200 +0200 +++ /work/SRC/openSUSE:Factory/.nginx.new.1085/nginx.changes 2025-08-15 21:51:11.377947750 +0200 @@ -1,0 +2,19 @@ +Thu Aug 14 08:19:23 UTC 2025 - Илья Индиго <i...@ilya.top> + +- Updated to 1.29.1 + * https://nginx.org/en/CHANGES + * Fixed processing of a specially crafted login/password when using + the "none" authentication method in the ngx_mail_smtp_module might + cause worker process memory disclosure to the authentication server + (CVE-2025-53859). + * Changed TLSv1.3 certificate compression is disabled by default. + * Added the "ssl_certificate_compression" directive. + * Added support for 0-RTT in QUIC when using OpenSSL 3.5.1 or newer. + * Fixed the 103 response might be buffered when using HTTP/2 and the + "early_hints" directive. + * Fixed in handling "Host" and ":authority" header lines with equal + values when using HTTP/2; the bug had appeared in 1.17.9. + * Fixed in handling "Host" header lines with a port when using HTTP/3. + * Fixed in the "none" parameter of the "smtp_auth" directive. + +------------------------------------------------------------------- Old: ---- nginx-1.29.0.tar.gz nginx-1.29.0.tar.gz.asc New: ---- nginx-1.29.1.tar.gz nginx-1.29.1.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ nginx.spec ++++++ --- /var/tmp/diff_new_pack.COs9pp/_old 2025-08-15 21:51:14.502077640 +0200 +++ /var/tmp/diff_new_pack.COs9pp/_new 2025-08-15 21:51:14.538079137 +0200 @@ -23,7 +23,7 @@ %bcond_with ngx_google_perftools # Name: nginx -Version: 1.29.0 +Version: 1.29.1 Release: 0 Summary: A HTTP server and IMAP/POP3 proxy server License: BSD-2-Clause @@ -70,7 +70,6 @@ Provides: httpd %{?systemd_ordering} %sysusers_requires - %if %{with ngx_google_perftools} BuildRequires: google-perftools-devel %endif ++++++ nginx-1.29.0.tar.gz -> nginx-1.29.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/CHANGES new/nginx-1.29.1/CHANGES --- old/nginx-1.29.0/CHANGES 2025-06-24 19:30:10.000000000 +0200 +++ new/nginx-1.29.1/CHANGES 2025-08-13 16:38:34.000000000 +0200 @@ -1,4 +1,26 @@ +Changes with nginx 1.29.1 13 Aug 2025 + + *) Change: now TLSv1.3 certificate compression is disabled by default. + + *) Feature: the "ssl_certificate_compression" directive. + + *) Feature: support for 0-RTT in QUIC when using OpenSSL 3.5.1 or newer. + + *) Bugfix: the 103 response might be buffered when using HTTP/2 and the + "early_hints" directive. + + *) Bugfix: in handling "Host" and ":authority" header lines with equal + values when using HTTP/2; the bug had appeared in 1.17.9. + + *) Bugfix: in handling "Host" header lines with a port when using + HTTP/3. + + *) Bugfix: nginx could not be built on NetBSD 10.0. + + *) Bugfix: in the "none" parameter of the "smtp_auth" directive. + + Changes with nginx 1.29.0 24 Jun 2025 *) Feature: support for response code 103 from proxy and gRPC backends; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/CHANGES.ru new/nginx-1.29.1/CHANGES.ru --- old/nginx-1.29.0/CHANGES.ru 2025-06-24 19:30:10.000000000 +0200 +++ new/nginx-1.29.1/CHANGES.ru 2025-08-13 16:38:33.000000000 +0200 @@ -1,4 +1,29 @@ +Изменения в nginx 1.29.1 13.08.2025 + + *) Изменение: теперь сжатие сертификатов в протоколе TLSv1.3 по + умолчанию запрещено. + + *) Добавление: директива ssl_certificate_compression. + + *) Добавление: поддержка 0-RTT в QUIC при использовании OpenSSL 3.5.1 и + новее. + + *) Исправление: при использовании HTTP/2 и директивы early_hints ответ + 103 мог буферизироваться. + + *) Исправление: в обработке заголовков запроса "Host" и ":authority" с + одинаковыми значениями при использовании HTTP/2; ошибка появилась в + 1.17.9. + + *) Исправление: в обработке заголовка запроса "Host" с портом при + использовании HTTP/3. + + *) Исправление: nginx не собирался под NetBSD 10.0. + + *) Исправление: в работе параметра none директивы smtp_auth. + + Изменения в nginx 1.29.0 24.06.2025 *) Добавление: поддержка ответа с кодом 103 от proxy- и gRPC-бэкендов; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/auto/unix new/nginx-1.29.1/auto/unix --- old/nginx-1.29.0/auto/unix 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/auto/unix 2025-08-13 16:33:41.000000000 +0200 @@ -129,26 +129,6 @@ fi -if [ "$NGX_SYSTEM" = "NetBSD" ]; then - - # NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t" - - cat << END >> $NGX_AUTO_CONFIG_H - -#define NGX_KQUEUE_UDATA_T - -END - -else - cat << END >> $NGX_AUTO_CONFIG_H - -#define NGX_KQUEUE_UDATA_T (void *) - -END - -fi - - ngx_feature="crypt()" ngx_feature_name="NGX_HAVE_CRYPT" ngx_feature_run=no diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/core/nginx.h new/nginx-1.29.1/src/core/nginx.h --- old/nginx-1.29.0/src/core/nginx.h 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/core/nginx.h 2025-08-13 16:33:41.000000000 +0200 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1029000 -#define NGINX_VERSION "1.29.0" +#define nginx_version 1029001 +#define NGINX_VERSION "1.29.1" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/event/modules/ngx_kqueue_module.c new/nginx-1.29.1/src/event/modules/ngx_kqueue_module.c --- old/nginx-1.29.0/src/event/modules/ngx_kqueue_module.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/event/modules/ngx_kqueue_module.c 2025-08-13 16:33:41.000000000 +0200 @@ -10,6 +10,15 @@ #include <ngx_event.h> +/* NetBSD up to 10.0 incompatibly defines kevent.udata as "intptr_t" */ + +#if (__NetBSD__ && __NetBSD_Version__ < 1000000000) +#define NGX_KQUEUE_UDATA_T +#else +#define NGX_KQUEUE_UDATA_T (void *) +#endif + + typedef struct { ngx_uint_t changes; ngx_uint_t events; @@ -191,7 +200,7 @@ kev.flags = EV_ADD|EV_ENABLE; kev.fflags = 0; kev.data = timer; - kev.udata = 0; + kev.udata = NGX_KQUEUE_UDATA_T (uintptr_t) 0; ts.tv_sec = 0; ts.tv_nsec = 0; @@ -237,7 +246,7 @@ notify_kev.data = 0; notify_kev.flags = EV_ADD|EV_CLEAR; notify_kev.fflags = 0; - notify_kev.udata = 0; + notify_kev.udata = NGX_KQUEUE_UDATA_T (uintptr_t) 0; if (kevent(ngx_kqueue, ¬ify_kev, 1, NULL, 0, NULL) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/event/ngx_event_openssl.c new/nginx-1.29.1/src/event/ngx_event_openssl.c --- old/nginx-1.29.0/src/event/ngx_event_openssl.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/event/ngx_event_openssl.c 2025-08-13 16:33:41.000000000 +0200 @@ -387,6 +387,11 @@ SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION); #endif +#ifdef SSL_OP_NO_TX_CERTIFICATE_COMPRESSION + SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TX_CERTIFICATE_COMPRESSION); + SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_RX_CERTIFICATE_COMPRESSION); +#endif + #ifdef SSL_OP_NO_ANTI_REPLAY SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_ANTI_REPLAY); #endif @@ -660,6 +665,36 @@ ngx_int_t +ngx_ssl_certificate_compression(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_uint_t enable) +{ + if (!enable) { + return NGX_OK; + } + +#ifdef SSL_OP_NO_TX_CERTIFICATE_COMPRESSION + + if (SSL_CTX_compress_certs(ssl->ctx, 0) == 0) { + ngx_ssl_error(NGX_LOG_WARN, ssl->log, 0, + "SSL_CTX_compress_certs() failed, ignored"); + return NGX_OK; + } + + SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TX_CERTIFICATE_COMPRESSION); + +#else + + ngx_log_error(NGX_LOG_WARN, ssl->log, 0, + "\"ssl_certificate_compression\" is not supported " + "on this platform, ignored"); + +#endif + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, ngx_uint_t prefer_server_ciphers) { @@ -1374,7 +1409,7 @@ if (SSL_CTX_set0_tmp_dh_pkey(ssl->ctx, dh) != 1) { ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "SSL_CTX_set0_tmp_dh_pkey(\"%s\") failed", file->data); -#if (OPENSSL_VERSION_NUMBER >= 0x3000001fL) +#if (OPENSSL_VERSION_NUMBER >= 0x30000010L) EVP_PKEY_free(dh); #endif BIO_free(bio); @@ -5055,11 +5090,7 @@ return NGX_OK; } -#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL) name = SSL_group_to_name(c->ssl->connection, nid); -#else - name = NULL; -#endif s->len = name ? ngx_strlen(name) : sizeof("0x0000") - 1; s->data = ngx_pnalloc(pool, s->len); @@ -5113,11 +5144,7 @@ nid = curves[i]; if (nid & TLSEXT_nid_unknown) { -#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL) name = SSL_group_to_name(c->ssl->connection, nid); -#else - name = NULL; -#endif len += name ? ngx_strlen(name) : sizeof("0x0000") - 1; @@ -5139,11 +5166,7 @@ nid = curves[i]; if (nid & TLSEXT_nid_unknown) { -#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL) name = SSL_group_to_name(c->ssl->connection, nid); -#else - name = NULL; -#endif p = name ? ngx_cpymem(p, name, ngx_strlen(name)) : ngx_sprintf(p, "0x%04xd", nid & 0xffff); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/event/ngx_event_openssl.h new/nginx-1.29.1/src/event/ngx_event_openssl.h --- old/nginx-1.29.0/src/event/ngx_event_openssl.h 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/event/ngx_event_openssl.h 2025-08-13 16:33:41.000000000 +0200 @@ -96,6 +96,11 @@ #endif +#if (OPENSSL_VERSION_NUMBER < 0x30000000L) +#define SSL_group_to_name(s, nid) NULL +#endif + + typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t; @@ -231,6 +236,8 @@ ngx_int_t ngx_ssl_connection_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *cert, ngx_str_t *key, ngx_ssl_cache_t *cache, ngx_array_t *passwords); +ngx_int_t ngx_ssl_certificate_compression(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_uint_t enable); ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, ngx_uint_t prefer_server_ciphers); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/event/quic/ngx_event_quic.h new/nginx-1.29.1/src/event/quic/ngx_event_quic.h --- old/nginx-1.29.0/src/event/quic/ngx_event_quic.h 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/event/quic/ngx_event_quic.h 2025-08-13 16:33:41.000000000 +0200 @@ -12,11 +12,8 @@ #include <ngx_core.h> -#ifdef OSSL_RECORD_PROTECTION_LEVEL_NONE -#ifndef NGX_QUIC_OPENSSL_API -#define NGX_QUIC_BORINGSSL_API 1 -#define NGX_QUIC_OPENSSL_COMPAT 1 -#endif +#if (OPENSSL_VERSION_NUMBER >= 0x30500010L) +#define NGX_QUIC_OPENSSL_API 1 #elif (defined SSL_R_MISSING_QUIC_TRANSPORT_PARAMETERS_EXTENSION) #define NGX_QUIC_QUICTLS_API 1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/http/modules/ngx_http_auth_basic_module.c new/nginx-1.29.1/src/http/modules/ngx_http_auth_basic_module.c --- old/nginx-1.29.0/src/http/modules/ngx_http_auth_basic_module.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/http/modules/ngx_http_auth_basic_module.c 2025-08-13 16:33:41.000000000 +0200 @@ -253,7 +253,8 @@ pwd.len = i - passwd; pwd.data = ngx_pnalloc(r->pool, pwd.len + 1); if (pwd.data == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_HTTP_INTERNAL_SERVER_ERROR; + goto cleanup; } ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/http/modules/ngx_http_ssl_module.c new/nginx-1.29.1/src/http/modules/ngx_http_ssl_module.c --- old/nginx-1.29.0/src/http/modules/ngx_http_ssl_module.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/http/modules/ngx_http_ssl_module.c 2025-08-13 16:33:41.000000000 +0200 @@ -124,6 +124,13 @@ 0, NULL }, + { ngx_string("ssl_certificate_compression"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_ssl_srv_conf_t, certificate_compression), + NULL }, + { ngx_string("ssl_dhparam"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -621,6 +628,7 @@ */ sscf->prefer_server_ciphers = NGX_CONF_UNSET; + sscf->certificate_compression = NGX_CONF_UNSET; sscf->early_data = NGX_CONF_UNSET; sscf->reject_handshake = NGX_CONF_UNSET; sscf->buffer_size = NGX_CONF_UNSET_SIZE; @@ -658,6 +666,9 @@ ngx_conf_merge_value(conf->prefer_server_ciphers, prev->prefer_server_ciphers, 0); + ngx_conf_merge_value(conf->certificate_compression, + prev->certificate_compression, 0); + ngx_conf_merge_value(conf->early_data, prev->early_data, 0); ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0); @@ -791,6 +802,13 @@ != NGX_OK) { return NGX_CONF_ERROR; + } + + if (ngx_ssl_certificate_compression(cf, &conf->ssl, + conf->certificate_compression) + != NGX_OK) + { + return NGX_CONF_ERROR; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/http/modules/ngx_http_ssl_module.h new/nginx-1.29.1/src/http/modules/ngx_http_ssl_module.h --- old/nginx-1.29.0/src/http/modules/ngx_http_ssl_module.h 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/http/modules/ngx_http_ssl_module.h 2025-08-13 16:33:41.000000000 +0200 @@ -18,6 +18,7 @@ ngx_ssl_t ssl; ngx_flag_t prefer_server_ciphers; + ngx_flag_t certificate_compression; ngx_flag_t early_data; ngx_flag_t reject_handshake; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/http/ngx_http.h new/nginx-1.29.1/src/http/ngx_http.h --- old/nginx-1.29.0/src/http/ngx_http.h 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/http/ngx_http.h 2025-08-13 16:33:41.000000000 +0200 @@ -122,7 +122,6 @@ ngx_http_request_t *ngx_http_create_request(ngx_connection_t *c); ngx_int_t ngx_http_process_request_uri(ngx_http_request_t *r); -ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); void ngx_http_process_request(ngx_http_request_t *r); void ngx_http_update_location_config(ngx_http_request_t *r); void ngx_http_handler(ngx_http_request_t *r); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/http/ngx_http_request.c new/nginx-1.29.1/src/http/ngx_http_request.c --- old/nginx-1.29.0/src/http/ngx_http_request.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/http/ngx_http_request.c 2025-08-13 16:33:41.000000000 +0200 @@ -29,6 +29,7 @@ static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); +static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c, ngx_http_virtual_names_t *virtual_names, ngx_str_t *host, ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp); @@ -1984,7 +1985,7 @@ } -ngx_int_t +static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) { if (r->headers_in.server.len == 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/http/v2/ngx_http_v2.c new/nginx-1.29.1/src/http/v2/ngx_http_v2.c --- old/nginx-1.29.0/src/http/v2/ngx_http_v2.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/http/v2/ngx_http_v2.c 2025-08-13 16:33:41.000000000 +0200 @@ -158,6 +158,7 @@ static ngx_int_t ngx_http_v2_cookie(ngx_http_request_t *r, ngx_http_v2_header_t *header); static ngx_int_t ngx_http_v2_construct_cookie_header(ngx_http_request_t *r); +static ngx_int_t ngx_http_v2_construct_host_header(ngx_http_request_t *r); static void ngx_http_v2_run_request(ngx_http_request_t *r); static ngx_int_t ngx_http_v2_process_request_body(ngx_http_request_t *r, u_char *pos, size_t size, ngx_uint_t last, ngx_uint_t flush); @@ -3517,44 +3518,40 @@ static ngx_int_t ngx_http_v2_parse_authority(ngx_http_request_t *r, ngx_str_t *value) { - ngx_table_elt_t *h; - ngx_http_header_t *hh; - ngx_http_core_main_conf_t *cmcf; + ngx_int_t rc; - static ngx_str_t host = ngx_string("host"); - - h = ngx_list_push(&r->headers_in.headers); - if (h == NULL) { - return NGX_ERROR; + if (r->host_start) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent duplicate \":authority\" header"); + return NGX_DECLINED; } - h->hash = ngx_hash(ngx_hash(ngx_hash('h', 'o'), 's'), 't'); - - h->key.len = host.len; - h->key.data = host.data; - - h->value.len = value->len; - h->value.data = value->data; + r->host_start = value->data; + r->host_end = value->data + value->len; - h->lowcase_key = host.data; + rc = ngx_http_validate_host(value, r->pool, 0); - cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); - - hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash, - h->lowcase_key, h->key.len); + if (rc == NGX_DECLINED) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent invalid \":authority\" header"); + return NGX_DECLINED; + } - if (hh == NULL) { - return NGX_ERROR; + if (rc == NGX_ERROR) { + ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_ABORT; } - if (hh->handler(r, h, hh->offset) != NGX_OK) { + if (ngx_http_set_virtual_server(r, value) == NGX_ERROR) { /* * request has been finalized already - * in ngx_http_process_host() + * in ngx_http_set_virtual_server() */ return NGX_ABORT; } + r->headers_in.server = *value; + return NGX_OK; } @@ -3725,7 +3722,54 @@ if (hh->handler(r, h, hh->offset) != NGX_OK) { /* * request has been finalized already - * in ngx_http_process_multi_header_lines() + * in ngx_http_process_header_line() + */ + return NGX_ERROR; + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_http_v2_construct_host_header(ngx_http_request_t *r) +{ + ngx_table_elt_t *h; + ngx_http_header_t *hh; + ngx_http_core_main_conf_t *cmcf; + + static ngx_str_t host = ngx_string("host"); + + h = ngx_list_push(&r->headers_in.headers); + if (h == NULL) { + ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_ERROR; + } + + h->hash = ngx_hash(ngx_hash(ngx_hash('h', 'o'), 's'), 't'); + + h->key.len = host.len; + h->key.data = host.data; + + h->value.len = r->host_end - r->host_start; + h->value.data = r->host_start; + + h->lowcase_key = host.data; + + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); + + hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash, + h->lowcase_key, h->key.len); + + if (hh == NULL) { + ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_ERROR; + } + + if (hh->handler(r, h, hh->offset) != NGX_OK) { + /* + * request has been finalized already + * in ngx_http_process_host() */ return NGX_ERROR; } @@ -3737,6 +3781,7 @@ static void ngx_http_v2_run_request(ngx_http_request_t *r) { + ngx_str_t host; ngx_connection_t *fc; ngx_http_v2_srv_conf_t *h2scf; ngx_http_v2_connection_t *h2c; @@ -3764,24 +3809,78 @@ r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE; - if (ngx_http_process_request_header(r) != NGX_OK) { + if (r->headers_in.server.len == 0) { + ngx_log_error(NGX_LOG_INFO, fc->log, 0, + "client sent neither \":authority\" nor \"Host\" header"); + ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); goto failed; } - if (r->headers_in.content_length_n > 0 && r->stream->in_closed) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client prematurely closed stream"); + if (r->host_end) { - r->stream->skip_data = 1; + host.len = r->host_end - r->host_start; + host.data = r->host_start; - ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); - goto failed; + if (r->headers_in.host) { + if (r->headers_in.host->value.len != host.len + || ngx_memcmp(r->headers_in.host->value.data, host.data, + host.len) + != 0) + { + ngx_log_error(NGX_LOG_INFO, fc->log, 0, + "client sent \":authority\" and \"Host\" headers " + "with different values"); + ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + goto failed; + } + + } else { + /* compatibility for $http_host */ + + if (ngx_http_v2_construct_host_header(r) != NGX_OK) { + goto failed; + } + } } - if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) { + if (r->headers_in.content_length) { + r->headers_in.content_length_n = + ngx_atoof(r->headers_in.content_length->value.data, + r->headers_in.content_length->value.len); + + if (r->headers_in.content_length_n == NGX_ERROR) { + ngx_log_error(NGX_LOG_INFO, fc->log, 0, + "client sent invalid \"Content-Length\" header"); + ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + goto failed; + } + + if (r->headers_in.content_length_n > 0 && r->stream->in_closed) { + ngx_log_error(NGX_LOG_INFO, fc->log, 0, + "client prematurely closed stream"); + + r->stream->skip_data = 1; + + ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + goto failed; + } + + } else if (!r->stream->in_closed) { r->headers_in.chunked = 1; } + if (r->method == NGX_HTTP_CONNECT) { + ngx_log_error(NGX_LOG_INFO, fc->log, 0, "client sent CONNECT method"); + ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED); + goto failed; + } + + if (r->method == NGX_HTTP_TRACE) { + ngx_log_error(NGX_LOG_INFO, fc->log, 0, "client sent TRACE method"); + ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED); + goto failed; + } + h2c = r->stream->connection; h2c->payload_bytes += r->request_length; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/http/v2/ngx_http_v2_filter_module.c new/nginx-1.29.1/src/http/v2/ngx_http_v2_filter_module.c --- old/nginx-1.29.0/src/http/v2/ngx_http_v2_filter_module.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/http/v2/ngx_http_v2_filter_module.c 2025-08-13 16:33:41.000000000 +0200 @@ -32,7 +32,8 @@ static ngx_int_t ngx_http_v2_init_stream(ngx_http_request_t *r); static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame( - ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin); + ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin, + ngx_uint_t flush); static ngx_http_v2_out_frame_t *ngx_http_v2_create_trailers_frame( ngx_http_request_t *r); @@ -609,7 +610,7 @@ fin = r->header_only || (r->headers_out.content_length_n == 0 && !r->expect_trailers); - frame = ngx_http_v2_create_headers_frame(r, start, pos, fin); + frame = ngx_http_v2_create_headers_frame(r, start, pos, fin, 0); if (frame == NULL) { return NGX_ERROR; } @@ -774,7 +775,7 @@ header[i].value.len, tmp); } - frame = ngx_http_v2_create_headers_frame(r, start, pos, 0); + frame = ngx_http_v2_create_headers_frame(r, start, pos, 0, 1); if (frame == NULL) { return NGX_ERROR; } @@ -825,7 +826,7 @@ static ngx_http_v2_out_frame_t * ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos, - u_char *end, ngx_uint_t fin) + u_char *end, ngx_uint_t fin, ngx_uint_t flush) { u_char type, flags; size_t rest, frame_size; @@ -916,6 +917,7 @@ } b->last_buf = fin; + b->flush = flush; cl->next = NULL; frame->last = cl; @@ -1038,7 +1040,7 @@ header[i].value.len, tmp); } - return ngx_http_v2_create_headers_frame(r, start, pos, 1); + return ngx_http_v2_create_headers_frame(r, start, pos, 1, 0); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/http/v3/ngx_http_v3_parse.c new/nginx-1.29.1/src/http/v3/ngx_http_v3_parse.c --- old/nginx-1.29.0/src/http/v3/ngx_http_v3_parse.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/http/v3/ngx_http_v3_parse.c 2025-08-13 16:33:41.000000000 +0200 @@ -623,6 +623,12 @@ } if (st->huffman) { + if (n > NGX_MAX_INT_T_VALUE / 8) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, + "client sent too large field line"); + return NGX_HTTP_V3_ERR_EXCESSIVE_LOAD; + } + n = n * 8 / 5; st->huffstate = 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/http/v3/ngx_http_v3_request.c new/nginx-1.29.1/src/http/v3/ngx_http_v3_request.c --- old/nginx-1.29.0/src/http/v3/ngx_http_v3_request.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/http/v3/ngx_http_v3_request.c 2025-08-13 16:33:41.000000000 +0200 @@ -965,7 +965,7 @@ if (rc == NGX_DECLINED) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent invalid host in request line"); + "client sent invalid \":authority\" header"); goto failed; } @@ -1003,6 +1003,7 @@ { ssize_t n; ngx_buf_t *b; + ngx_str_t host; ngx_connection_t *c; ngx_http_v3_session_t *h3c; ngx_http_v3_srv_conf_t *h3scf; @@ -1034,11 +1035,13 @@ goto failed; } - if (r->headers_in.host) { - if (r->headers_in.host->value.len != r->headers_in.server.len - || ngx_memcmp(r->headers_in.host->value.data, - r->headers_in.server.data, - r->headers_in.server.len) + if (r->headers_in.host && r->host_end) { + + host.len = r->host_end - r->host_start; + host.data = r->host_start; + + if (r->headers_in.host->value.len != host.len + || ngx_memcmp(r->headers_in.host->value.data, host.data, host.len) != 0) { ngx_log_error(NGX_LOG_INFO, c->log, 0, @@ -1213,7 +1216,7 @@ if (hh->handler(r, h, hh->offset) != NGX_OK) { /* * request has been finalized already - * in ngx_http_process_multi_header_lines() + * in ngx_http_process_header_line() */ return NGX_ERROR; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/mail/ngx_mail_auth_http_module.c new/nginx-1.29.1/src/mail/ngx_mail_auth_http_module.c --- old/nginx-1.29.0/src/mail/ngx_mail_auth_http_module.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/mail/ngx_mail_auth_http_module.c 2025-08-13 16:33:41.000000000 +0200 @@ -1321,7 +1321,10 @@ b->last = ngx_copy(b->last, passwd.data, passwd.len); *b->last++ = CR; *b->last++ = LF; - if (s->auth_method != NGX_MAIL_AUTH_PLAIN && s->salt.len) { + if ((s->auth_method == NGX_MAIL_AUTH_APOP + || s->auth_method == NGX_MAIL_AUTH_CRAM_MD5) + && s->salt.len) + { b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") - 1); b->last = ngx_copy(b->last, s->salt.data, s->salt.len); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/mail/ngx_mail_handler.c new/nginx-1.29.1/src/mail/ngx_mail_handler.c --- old/nginx-1.29.0/src/mail/ngx_mail_handler.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/mail/ngx_mail_handler.c 2025-08-13 16:33:41.000000000 +0200 @@ -523,7 +523,7 @@ ngx_int_t ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n) { - u_char *p, *last; + u_char *p, *pos, *last; ngx_str_t *arg, plain; arg = s->args.elts; @@ -555,7 +555,7 @@ return NGX_MAIL_PARSE_INVALID_COMMAND; } - s->login.data = p; + pos = p; while (p < last && *p) { p++; } @@ -565,7 +565,8 @@ return NGX_MAIL_PARSE_INVALID_COMMAND; } - s->login.len = p++ - s->login.data; + s->login.len = p++ - pos; + s->login.data = pos; s->passwd.len = last - p; s->passwd.data = p; @@ -583,24 +584,26 @@ ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n) { - ngx_str_t *arg; + ngx_str_t *arg, login; arg = s->args.elts; ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail auth login username: \"%V\"", &arg[n]); - s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len)); - if (s->login.data == NULL) { + login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len)); + if (login.data == NULL) { return NGX_ERROR; } - if (ngx_decode_base64(&s->login, &arg[n]) != NGX_OK) { + if (ngx_decode_base64(&login, &arg[n]) != NGX_OK) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent invalid base64 encoding in AUTH LOGIN command"); return NGX_MAIL_PARSE_INVALID_COMMAND; } + s->login = login; + ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail auth login username: \"%V\"", &s->login); @@ -611,7 +614,7 @@ ngx_int_t ngx_mail_auth_login_password(ngx_mail_session_t *s, ngx_connection_t *c) { - ngx_str_t *arg; + ngx_str_t *arg, passwd; arg = s->args.elts; @@ -620,18 +623,19 @@ "mail auth login password: \"%V\"", &arg[0]); #endif - s->passwd.data = ngx_pnalloc(c->pool, - ngx_base64_decoded_length(arg[0].len)); - if (s->passwd.data == NULL) { + passwd.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len)); + if (passwd.data == NULL) { return NGX_ERROR; } - if (ngx_decode_base64(&s->passwd, &arg[0]) != NGX_OK) { + if (ngx_decode_base64(&passwd, &arg[0]) != NGX_OK) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent invalid base64 encoding in AUTH LOGIN command"); return NGX_MAIL_PARSE_INVALID_COMMAND; } + s->passwd = passwd; + #if (NGX_DEBUG_MAIL_PASSWD) ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail auth login password: \"%V\"", &s->passwd); @@ -674,24 +678,26 @@ ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c) { u_char *p, *last; - ngx_str_t *arg; + ngx_str_t *arg, login; arg = s->args.elts; ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, "mail auth cram-md5: \"%V\"", &arg[0]); - s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len)); - if (s->login.data == NULL) { + login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len)); + if (login.data == NULL) { return NGX_ERROR; } - if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) { + if (ngx_decode_base64(&login, &arg[0]) != NGX_OK) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent invalid base64 encoding in AUTH CRAM-MD5 command"); return NGX_MAIL_PARSE_INVALID_COMMAND; } + s->login = login; + p = s->login.data; last = p + s->login.len; @@ -1000,14 +1006,12 @@ len -= p - buf; buf = p; - if (s->login.len == 0) { - return p; + if (s->login.len) { + p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login); + len -= p - buf; + buf = p; } - p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login); - len -= p - buf; - buf = p; - if (s->proxy == NULL) { return p; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/mail/ngx_mail_smtp_handler.c new/nginx-1.29.1/src/mail/ngx_mail_smtp_handler.c --- old/nginx-1.29.0/src/mail/ngx_mail_smtp_handler.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/mail/ngx_mail_smtp_handler.c 2025-08-13 16:33:41.000000000 +0200 @@ -782,6 +782,9 @@ ngx_str_set(&s->out, smtp_ok); + ngx_str_null(&s->login); + ngx_str_null(&s->passwd); + return NGX_OK; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/mail/ngx_mail_ssl_module.c new/nginx-1.29.1/src/mail/ngx_mail_ssl_module.c --- old/nginx-1.29.0/src/mail/ngx_mail_ssl_module.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/mail/ngx_mail_ssl_module.c 2025-08-13 16:33:41.000000000 +0200 @@ -97,6 +97,13 @@ 0, NULL }, + { ngx_string("ssl_certificate_compression"), + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_MAIL_SRV_CONF_OFFSET, + offsetof(ngx_mail_ssl_conf_t, certificate_compression), + NULL }, + { ngx_string("ssl_dhparam"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -314,6 +321,7 @@ scf->passwords = NGX_CONF_UNSET_PTR; scf->conf_commands = NGX_CONF_UNSET_PTR; scf->prefer_server_ciphers = NGX_CONF_UNSET; + scf->certificate_compression = NGX_CONF_UNSET; scf->verify = NGX_CONF_UNSET_UINT; scf->verify_depth = NGX_CONF_UNSET_UINT; scf->builtin_session_cache = NGX_CONF_UNSET; @@ -343,6 +351,9 @@ ngx_conf_merge_value(conf->prefer_server_ciphers, prev->prefer_server_ciphers, 0); + ngx_conf_merge_value(conf->certificate_compression, + prev->certificate_compression, 0); + ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, (NGX_CONF_BITMASK_SET|NGX_SSL_DEFAULT_PROTOCOLS)); @@ -444,6 +455,13 @@ != NGX_OK) { return NGX_CONF_ERROR; + } + + if (ngx_ssl_certificate_compression(cf, &conf->ssl, + conf->certificate_compression) + != NGX_OK) + { + return NGX_CONF_ERROR; } if (conf->verify) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/mail/ngx_mail_ssl_module.h new/nginx-1.29.1/src/mail/ngx_mail_ssl_module.h --- old/nginx-1.29.0/src/mail/ngx_mail_ssl_module.h 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/mail/ngx_mail_ssl_module.h 2025-08-13 16:33:41.000000000 +0200 @@ -21,6 +21,7 @@ typedef struct { ngx_flag_t prefer_server_ciphers; + ngx_flag_t certificate_compression; ngx_ssl_t ssl; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/stream/ngx_stream_ssl_module.c new/nginx-1.29.1/src/stream/ngx_stream_ssl_module.c --- old/nginx-1.29.0/src/stream/ngx_stream_ssl_module.c 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/stream/ngx_stream_ssl_module.c 2025-08-13 16:33:41.000000000 +0200 @@ -133,6 +133,13 @@ 0, NULL }, + { ngx_string("ssl_certificate_compression"), + NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG, + ngx_conf_set_flag_slot, + NGX_STREAM_SRV_CONF_OFFSET, + offsetof(ngx_stream_ssl_srv_conf_t, certificate_compression), + NULL }, + { ngx_string("ssl_dhparam"), NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -881,6 +888,7 @@ sscf->passwords = NGX_CONF_UNSET_PTR; sscf->conf_commands = NGX_CONF_UNSET_PTR; sscf->prefer_server_ciphers = NGX_CONF_UNSET; + sscf->certificate_compression = NGX_CONF_UNSET; sscf->reject_handshake = NGX_CONF_UNSET; sscf->verify = NGX_CONF_UNSET_UINT; sscf->verify_depth = NGX_CONF_UNSET_UINT; @@ -914,6 +922,9 @@ ngx_conf_merge_value(conf->prefer_server_ciphers, prev->prefer_server_ciphers, 0); + ngx_conf_merge_value(conf->certificate_compression, + prev->certificate_compression, 0); + ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0); ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, @@ -1038,6 +1049,13 @@ != NGX_OK) { return NGX_CONF_ERROR; + } + + if (ngx_ssl_certificate_compression(cf, &conf->ssl, + conf->certificate_compression) + != NGX_OK) + { + return NGX_CONF_ERROR; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.29.0/src/stream/ngx_stream_ssl_module.h new/nginx-1.29.1/src/stream/ngx_stream_ssl_module.h --- old/nginx-1.29.0/src/stream/ngx_stream_ssl_module.h 2025-06-24 19:22:41.000000000 +0200 +++ new/nginx-1.29.1/src/stream/ngx_stream_ssl_module.h 2025-08-13 16:33:41.000000000 +0200 @@ -18,6 +18,7 @@ ngx_msec_t handshake_timeout; ngx_flag_t prefer_server_ciphers; + ngx_flag_t certificate_compression; ngx_flag_t reject_handshake; ngx_ssl_t ssl;