Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package nginx for openSUSE:Factory checked in at 2026-06-19 16:30:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/nginx (Old) and /work/SRC/openSUSE:Factory/.nginx.new.1956 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "nginx" Fri Jun 19 16:30:11 2026 rev:115 rq:1360101 version:1.31.2 Changes: -------- --- /work/SRC/openSUSE:Factory/nginx/nginx.changes 2026-05-28 17:24:25.245464249 +0200 +++ /work/SRC/openSUSE:Factory/.nginx.new.1956/nginx.changes 2026-06-19 17:17:44.962592949 +0200 @@ -1,0 +2,38 @@ +Wed Jun 17 18:52:48 UTC 2026 - Marcus Rueckert <[email protected]> + +- Extend keyring file based on https://nginx.org/en/pgp_keys.html + https://github.com/nginx/nginx/issues/1477 + +------------------------------------------------------------------- +Wed Jun 17 17:14:57 UTC 2026 - Marcus Rueckert <[email protected]> + +- Update to 1.31.2 + *) Security: use-after-free might occur when using HTTP/3 and + processing a specially crafted QUIC session, allowing an + attacker to cause worker process memory corruption or + segmentation fault in a worker process (CVE-2026-42530). + Thanks to Trung Nguyen of CyStack. + *) Security: a heap memory buffer overflow might occur in a + worker process when using a configuration with + "ignore_invalid_headers off;" and + "large_client_header_buffers" with large configured values + when proxying a specially crafted request to HTTP/2 or gRPC + backend, allowing an attacker to cause worker process memory + corruption or segmentation fault in a worker process + (CVE-2026-42055). Thanks to Mufeed VH of Winfunc Research. + *) Security: a heap memory buffer overread might occur in a + worker process while handling a specially sent response with + decoding from UTF-8 via the "charset_map" directive, allowing + an attacker to cause a limited disclosure of worker proccess + memory or segmentation fault in a worker process + (CVE-2026-48142). Thanks to Han Yan of Xiaomi and p4p3r of + CYBERONE. + *) Change: now the $request_id variable uses SipHash-2-4. + *) Feature: the $ssl_sigalgs variable. + *) Bugfix: a variable defined by the "split_clients" directive + might be empty if all percentages were specified explicitly + and summed up to 100%. + *) Bugfix: constant time "secure_link" hash comparison. + Thanks to kodareef5. + +------------------------------------------------------------------- Old: ---- nginx-1.31.1.tar.gz nginx-1.31.1.tar.gz.asc New: ---- nginx-1.31.2.tar.gz nginx-1.31.2.tar.gz.asc ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ nginx.spec ++++++ --- /var/tmp/diff_new_pack.tcSLF1/_old 2026-06-19 17:17:46.386642039 +0200 +++ /var/tmp/diff_new_pack.tcSLF1/_new 2026-06-19 17:17:46.390642177 +0200 @@ -24,7 +24,7 @@ %bcond_with awslc # Name: nginx -Version: 1.31.1 +Version: 1.31.2 Release: 0 Summary: A HTTP server and IMAP/POP3 proxy server License: BSD-2-Clause ++++++ nginx-1.31.1.tar.gz -> nginx-1.31.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/CHANGES new/nginx-1.31.2/CHANGES --- old/nginx-1.31.1/CHANGES 2026-05-22 14:53:13.000000000 +0200 +++ new/nginx-1.31.2/CHANGES 2026-06-17 16:48:09.000000000 +0200 @@ -1,4 +1,39 @@ +Changes with nginx 1.31.2 17 Jun 2026 + + *) Security: use-after-free might occur when using HTTP/3 and processing + a specially crafted QUIC session, allowing an attacker to cause + worker process memory corruption or segmentation fault in a worker + process (CVE-2026-42530). + Thanks to Trung Nguyen of CyStack. + + *) Security: a heap memory buffer overflow might occur in a worker + process when using a configuration with "ignore_invalid_headers off;" + and "large_client_header_buffers" with large configured values when + proxying a specially crafted request to HTTP/2 or gRPC backend, + allowing an attacker to cause worker process memory corruption or + segmentation fault in a worker process (CVE-2026-42055). + Thanks to Mufeed VH of Winfunc Research. + + *) Security: a heap memory buffer overread might occur in a worker + process while handling a specially sent response with decoding from + UTF-8 via the "charset_map" directive, allowing an attacker to cause + a limited disclosure of worker proccess memory or segmentation fault + in a worker process (CVE-2026-48142). + Thanks to Han Yan of Xiaomi and p4p3r of CYBERONE. + + *) Change: now the $request_id variable uses SipHash-2-4. + + *) Feature: the $ssl_sigalgs variable. + + *) Bugfix: a variable defined by the "split_clients" directive might be + empty if all percentages were specified explicitly and summed up to + 100%. + + *) Bugfix: constant time "secure_link" hash comparison. + Thanks to kodareef5. + + Changes with nginx 1.31.1 22 May 2026 *) Security: a heap memory buffer overflow might occur in a worker diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/CHANGES.ru new/nginx-1.31.2/CHANGES.ru --- old/nginx-1.31.1/CHANGES.ru 2026-05-22 14:53:12.000000000 +0200 +++ new/nginx-1.31.2/CHANGES.ru 2026-06-17 16:48:08.000000000 +0200 @@ -1,4 +1,40 @@ +Изменения в nginx 1.31.2 17.06.2026 + + *) Безопасность: при использовании HTTP/3 обработка специально созданной + QUIC-сессии могла приводить к обращению к ранее освобождённой памяти, + что позволяло атакующему повредить память рабочего процесса или + вызвать segmentation fault в рабочем процессе (CVE-2026-42530). + Спасибо Trung Nguyen из CyStack. + + *) Безопасность: при проксировании специально созданного запроса на + HTTP/2 или gRPC-бэкенд с использованием директив + "ignore_invalid_headers off;" и "large_client_header_buffers" с + большим значением могло происходить переполнение буфера в рабочем + процессе, что позволяло атакующему повредить память рабочего процесса + или вызвать segmentation fault в рабочем процессе (CVE-2026-42055). + Спасибо Mufeed VH из Winfunc Research. + + *) Безопасность: при обработке специально переданного ответа с + декодированием из UTF-8 через директиву charset_map могло происходить + чтение данных за границами буфера рабочего процесса, что позволяло + атакующему отправить клиенту ограниченное содержимое памяти рабочего + процесса или вызвать segmentation fault в рабочем процессе + (CVE-2026-48142). + Спасибо Han Yan из Xiaomi и p4p3r из CYBERONE. + + *) Изменение: теперь переменная $request_id использует SipHash-2-4. + + *) Добавление: переменная $ssl_sigalgs. + + *) Исправление: переменная заданная директивой split_clients могла быть + пустой, если все проценты были заданы явно и их сумма была равна + 100%. + + *) Исправление: сравнение хешей secure_link за константное время. + Спасибо kodareef5. + + Изменения в nginx 1.31.1 22.05.2026 *) Безопасность: при использовании конфигурации модуля diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/auto/sources new/nginx-1.31.2/auto/sources --- old/nginx-1.31.1/auto/sources 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/auto/sources 2026-06-17 16:40:35.000000000 +0200 @@ -25,6 +25,7 @@ src/core/ngx_crc.h \ src/core/ngx_crc32.h \ src/core/ngx_murmurhash.h \ + src/core/ngx_siphash.h \ src/core/ngx_md5.h \ src/core/ngx_sha1.h \ src/core/ngx_rbtree.h \ @@ -60,6 +61,7 @@ src/core/ngx_file.c \ src/core/ngx_crc32.c \ src/core/ngx_murmurhash.c \ + src/core/ngx_siphash.c \ src/core/ngx_md5.c \ src/core/ngx_sha1.c \ src/core/ngx_rbtree.c \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/core/nginx.h new/nginx-1.31.2/src/core/nginx.h --- old/nginx-1.31.1/src/core/nginx.h 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/core/nginx.h 2026-06-17 16:40:35.000000000 +0200 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1031001 -#define NGINX_VERSION "1.31.1" +#define nginx_version 1031002 +#define NGINX_VERSION "1.31.2" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/core/ngx_core.h new/nginx-1.31.2/src/core/ngx_core.h --- old/nginx-1.31.1/src/core/ngx_core.h 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/core/ngx_core.h 2026-06-17 16:40:35.000000000 +0200 @@ -71,6 +71,7 @@ #include <ngx_crc.h> #include <ngx_crc32.h> #include <ngx_murmurhash.h> +#include <ngx_siphash.h> #if (NGX_PCRE) #include <ngx_regex.h> #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/core/ngx_siphash.c new/nginx-1.31.2/src/core/ngx_siphash.c --- old/nginx-1.31.1/src/core/ngx_siphash.c 1970-01-01 01:00:00.000000000 +0100 +++ new/nginx-1.31.2/src/core/ngx_siphash.c 2026-06-17 16:40:35.000000000 +0200 @@ -0,0 +1,95 @@ + +/* + * Copyright (C) Nginx, Inc. + */ + + +#include <ngx_config.h> +#include <ngx_core.h> + + +/* + * SipHash-2-4 implementation based on the SipHash specification by + * Jean-Philippe Aumasson and Daniel J. Bernstein. + * https://eprint.iacr.org/2012/351.pdf + */ + + +#define ngx_siphash_rotl(x, b) \ + (uint64_t) (((x) << (b)) | ((x) >> (64 - (b)))) + +#define ngx_sipround \ + do { \ + v0 += v1; v1 = ngx_siphash_rotl(v1, 13); v1 ^= v0; \ + v0 = ngx_siphash_rotl(v0, 32); \ + v2 += v3; v3 = ngx_siphash_rotl(v3, 16); v3 ^= v2; \ + v0 += v3; v3 = ngx_siphash_rotl(v3, 21); v3 ^= v0; \ + v2 += v1; v1 = ngx_siphash_rotl(v1, 17); v1 ^= v2; \ + v2 = ngx_siphash_rotl(v2, 32); \ + } while (0) + + +uint64_t +ngx_siphash(uint64_t k0, uint64_t k1, u_char *data, size_t len) +{ + u_char *end; + size_t remainder; + uint64_t v0, v1, v2, v3, m; + + v0 = k0 ^ 0x736f6d6570736575ULL; + v1 = k1 ^ 0x646f72616e646f6dULL; + v2 = k0 ^ 0x6c7967656e657261ULL; + v3 = k1 ^ 0x7465646279746573ULL; + + remainder = len & 7; + end = data + len - remainder; + + for ( /* void */ ; data != end; data += 8) { + ngx_memcpy(&m, data, 8); + v3 ^= m; + ngx_sipround; + ngx_sipround; + v0 ^= m; + } + + m = (uint64_t) len << 56; + + switch (remainder) { + case 7: + m |= (uint64_t) data[6] << 48; + /* fall through */ + case 6: + m |= (uint64_t) data[5] << 40; + /* fall through */ + case 5: + m |= (uint64_t) data[4] << 32; + /* fall through */ + case 4: + m |= (uint64_t) data[3] << 24; + /* fall through */ + case 3: + m |= (uint64_t) data[2] << 16; + /* fall through */ + case 2: + m |= (uint64_t) data[1] << 8; + /* fall through */ + case 1: + m |= (uint64_t) data[0]; + break; + case 0: + break; + } + + v3 ^= m; + ngx_sipround; + ngx_sipround; + v0 ^= m; + + v2 ^= 0xff; + ngx_sipround; + ngx_sipround; + ngx_sipround; + ngx_sipround; + + return v0 ^ v1 ^ v2 ^ v3; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/core/ngx_siphash.h new/nginx-1.31.2/src/core/ngx_siphash.h --- old/nginx-1.31.1/src/core/ngx_siphash.h 1970-01-01 01:00:00.000000000 +0100 +++ new/nginx-1.31.2/src/core/ngx_siphash.h 2026-06-17 16:40:35.000000000 +0200 @@ -0,0 +1,18 @@ + +/* + * Copyright (C) Nginx, Inc. + */ + + +#ifndef _NGX_SIPHASH_H_INCLUDED_ +#define _NGX_SIPHASH_H_INCLUDED_ + + +#include <ngx_config.h> +#include <ngx_core.h> + + +uint64_t ngx_siphash(uint64_t k0, uint64_t k1, u_char *data, size_t len); + + +#endif /* _NGX_SIPHASH_H_INCLUDED_ */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/event/modules/ngx_kqueue_module.c new/nginx-1.31.2/src/event/modules/ngx_kqueue_module.c --- old/nginx-1.31.1/src/event/modules/ngx_kqueue_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/event/modules/ngx_kqueue_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -438,8 +438,8 @@ if (filter == EVFILT_VNODE) { kev->fflags = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND |NOTE_ATTRIB|NOTE_RENAME -#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \ - || __FreeBSD_version >= 500018 +#if (__FreeBSD__ == 4 && __FreeBSD_version >= 430000) \ + || __FreeBSD_version >= 500018 |NOTE_REVOKE #endif ; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/event/ngx_event_openssl.c new/nginx-1.31.2/src/event/ngx_event_openssl.c --- old/nginx-1.31.1/src/event/ngx_event_openssl.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/event/ngx_event_openssl.c 2026-06-17 16:40:35.000000000 +0200 @@ -1171,7 +1171,7 @@ static ngx_inline ngx_int_t ngx_ssl_cert_already_in_hash(void) { -#if !(OPENSSL_VERSION_NUMBER >= 0x1010009fL \ +#if !(OPENSSL_VERSION_NUMBER >= 0x1010009fL \ || LIBRESSL_VERSION_NUMBER >= 0x3050000fL) u_long error; @@ -3251,7 +3251,7 @@ * OpenSSL 1.1.1 fails to return SSL_ERROR_SYSCALL if an error * happens during SSL_write() after close_notify alert from the * peer, and returns SSL_ERROR_ZERO_RETURN instead, - * https://git.openssl.org/?p=openssl.git;a=commitdiff;h=8051ab2 + * see https://github.com/openssl/openssl/commit/8051ab2 */ sslerr = SSL_ERROR_SYSCALL; @@ -5668,6 +5668,104 @@ return NGX_OK; } + +ngx_int_t +ngx_ssl_get_sigalgs(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) +{ +#if (OPENSSL_VERSION_NUMBER >= 0x40000000L) + + int n, i; + size_t len; + u_char *p; + const char *name; + unsigned int codepoint; + + n = SSL_get0_sigalg(c->ssl->connection, -1, NULL, NULL); + + if (n <= 0) { + s->len = 0; + return NGX_OK; + } + + len = 0; + + for (i = 0; i < n; i++) { + SSL_get0_sigalg(c->ssl->connection, i, &codepoint, &name); + len += name ? ngx_strlen(name) : sizeof("0x0000") - 1; + len += sizeof(":") - 1; + } + + s->data = ngx_pnalloc(pool, len); + if (s->data == NULL) { + return NGX_ERROR; + } + + p = s->data; + + for (i = 0; i < n; i++) { + SSL_get0_sigalg(c->ssl->connection, i, &codepoint, &name); + + if (name) { + p = ngx_cpymem(p, name, ngx_strlen(name)); + + } else { + p = ngx_sprintf(p, "0x%04xd", codepoint); + } + + *p++ = ':'; + } + + p--; + + s->len = p - s->data; + +#elif defined SSL_CTRL_SET_SIGALGS + + /* + * SSL_get_sigalgs() is only available in OpenSSL 1.0.2+, + * but uses a different naming, so emit raw codes + */ + + int n, i; + size_t len; + u_char *p; + unsigned char rsig, rhash; + + n = SSL_get_sigalgs(c->ssl->connection, -1, NULL, NULL, NULL, NULL, NULL); + + if (n <= 0) { + s->len = 0; + return NGX_OK; + } + + len = n * (sizeof("0x0000") - 1 + sizeof(":") - 1); + + s->data = ngx_pnalloc(pool, len); + if (s->data == NULL) { + return NGX_ERROR; + } + + p = s->data; + + for (i = 0; i < n; i++) { + SSL_get_sigalgs(c->ssl->connection, i, NULL, NULL, NULL, &rsig, &rhash); + p = ngx_sprintf(p, "0x%04xd", rhash << 8 | rsig); + *p++ = ':'; + } + + p--; + + s->len = p - s->data; + +#else + + s->len = 0; + +#endif + + return NGX_OK; +} + ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/event/ngx_event_openssl.h new/nginx-1.31.2/src/event/ngx_event_openssl.h --- old/nginx-1.31.1/src/event/ngx_event_openssl.h 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/event/ngx_event_openssl.h 2026-06-17 16:40:35.000000000 +0200 @@ -337,6 +337,8 @@ ngx_str_t *s); ngx_int_t ngx_ssl_get_sigalg(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); +ngx_int_t ngx_ssl_get_sigalgs(ngx_connection_t *c, ngx_pool_t *pool, + ngx_str_t *s); ngx_int_t ngx_ssl_get_session_id(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s); ngx_int_t ngx_ssl_get_session_reused(ngx_connection_t *c, ngx_pool_t *pool, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/modules/ngx_http_charset_filter_module.c new/nginx-1.31.2/src/http/modules/ngx_http_charset_filter_module.c --- old/nginx-1.31.1/src/http/modules/ngx_http_charset_filter_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/modules/ngx_http_charset_filter_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -855,6 +855,10 @@ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, pool->log, 0, "http charset invalid utf 1"); + if (saved < &ctx->saved[ctx->saved_len]) { + saved = &ctx->saved[ctx->saved_len]; + } + } else { dst = ngx_sprintf(dst, "&#%uD;", n); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/modules/ngx_http_grpc_module.c new/nginx-1.31.2/src/http/modules/ngx_http_grpc_module.c --- old/nginx-1.31.1/src/http/modules/ngx_http_grpc_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/modules/ngx_http_grpc_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -750,6 +750,12 @@ tmp_len = 0; } else { + if (r->method_name.len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 method: \"%V\"", &r->method_name); + return NGX_ERROR; + } + len += 1 + NGX_HTTP_V2_INT_OCTETS + r->method_name.len; tmp_len = r->method_name.len; } @@ -770,6 +776,12 @@ uri_len = r->uri.len + escape + sizeof("?") - 1 + r->args.len; } + if (uri_len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 URI"); + return NGX_ERROR; + } + len += 1 + NGX_HTTP_V2_INT_OCTETS + uri_len; if (tmp_len < uri_len) { @@ -779,6 +791,12 @@ /* :authority header */ if (!glcf->host_set) { + if (ctx->host.len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 host: \"%V\"", &ctx->host); + return NGX_ERROR; + } + len += 1 + NGX_HTTP_V2_INT_OCTETS + ctx->host.len; if (tmp_len < ctx->host.len) { @@ -809,6 +827,18 @@ continue; } + if (key_len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 header name"); + return NGX_ERROR; + } + + if (val_len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 header value"); + return NGX_ERROR; + } + len += 1 + NGX_HTTP_V2_INT_OCTETS + key_len + NGX_HTTP_V2_INT_OCTETS + val_len; @@ -843,6 +873,20 @@ continue; } + if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 header name: \"%V\"", + &header[i].key); + return NGX_ERROR; + } + + if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 header value: \"%V: %V\"", + &header[i].key, &header[i].value); + return NGX_ERROR; + } + len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len + NGX_HTTP_V2_INT_OCTETS + header[i].value.len; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/modules/ngx_http_log_module.c new/nginx-1.31.2/src/http/modules/ngx_http_log_module.c --- old/nginx-1.31.1/src/http/modules/ngx_http_log_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/modules/ngx_http_log_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -243,7 +243,7 @@ { ngx_string("bytes_sent"), NGX_OFF_T_LEN, ngx_http_log_bytes_sent }, { ngx_string("body_bytes_sent"), NGX_OFF_T_LEN, ngx_http_log_body_bytes_sent }, - { ngx_string("request_length"), NGX_SIZE_T_LEN, + { ngx_string("request_length"), NGX_OFF_T_LEN, ngx_http_log_request_length }, { ngx_null_string, 0, NULL } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/modules/ngx_http_proxy_v2_module.c new/nginx-1.31.2/src/http/modules/ngx_http_proxy_v2_module.c --- old/nginx-1.31.1/src/http/modules/ngx_http_proxy_v2_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/modules/ngx_http_proxy_v2_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -379,6 +379,12 @@ tmp_len = 0; } else { + if (method.len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 method: \"%V\"", &method); + return NGX_ERROR; + } + len += 1 + NGX_HTTP_V2_INT_OCTETS + method.len; tmp_len = method.len; } @@ -419,6 +425,12 @@ return NGX_ERROR; } + if (uri_len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 URI"); + return NGX_ERROR; + } + len += 1 + NGX_HTTP_V2_INT_OCTETS + uri_len; if (tmp_len < uri_len) { @@ -430,6 +442,12 @@ host = &ctx->ctx.vars.host_header; if (!plcf->host_set) { + if (host->len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 host: \"%V\"", host); + return NGX_ERROR; + } + len += 1 + NGX_HTTP_V2_INT_OCTETS + host->len; if (tmp_len < host->len) { @@ -483,6 +501,18 @@ continue; } + if (key_len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 header name"); + return NGX_ERROR; + } + + if (val_len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 header value"); + return NGX_ERROR; + } + len += 1 + NGX_HTTP_V2_INT_OCTETS + key_len + NGX_HTTP_V2_INT_OCTETS + val_len; @@ -517,6 +547,20 @@ continue; } + if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 header name: \"%V\"", + &header[i].key); + return NGX_ERROR; + } + + if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "too long http2 header value: \"%V: %V\"", + &header[i].key, &header[i].value); + return NGX_ERROR; + } + len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len + NGX_HTTP_V2_INT_OCTETS + header[i].value.len; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/modules/ngx_http_secure_link_module.c new/nginx-1.31.2/src/http/modules/ngx_http_secure_link_module.c --- old/nginx-1.31.1/src/http/modules/ngx_http_secure_link_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/modules/ngx_http_secure_link_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -101,10 +101,11 @@ ngx_http_secure_link_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - u_char *p, *last; - ngx_str_t val, hash; + u_char *p, *last, ch; time_t expires; + ngx_str_t val, hash; ngx_md5_t md5; + ngx_uint_t i; ngx_http_secure_link_ctx_t *ctx; ngx_http_secure_link_conf_t *conf; u_char hash_buf[18], md5_buf[16]; @@ -175,7 +176,13 @@ ngx_md5_update(&md5, val.data, val.len); ngx_md5_final(md5_buf, &md5); - if (ngx_memcmp(hash_buf, md5_buf, 16) != 0) { + /* constant time comparison */ + + for (ch = 0, i = 0; i < 16; i++) { + ch |= (hash_buf[i] ^ md5_buf[i]); + } + + if (ch) { goto not_found; } @@ -200,11 +207,11 @@ ngx_http_secure_link_conf_t *conf, ngx_http_variable_value_t *v, uintptr_t data) { - u_char *p, *start, *end, *last; + u_char *p, *start, *end, *last, ch; size_t len; ngx_int_t n; - ngx_uint_t i; ngx_md5_t md5; + ngx_uint_t i; u_char hash[16]; p = &r->unparsed_uri.data[1]; @@ -243,11 +250,19 @@ ngx_md5_update(&md5, conf->secret.data, conf->secret.len); ngx_md5_final(hash, &md5); - for (i = 0; i < 16; i++) { + for (ch = 0, i = 0; i < 16; i++) { n = ngx_hextoi(&start[2 * i], 2); - if (n == NGX_ERROR || n != hash[i]) { + if (n == NGX_ERROR) { goto not_found; } + + /* constant time comparison */ + + ch |= (u_char) n ^ hash[i]; + } + + if (ch) { + goto not_found; } v->len = len; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/modules/ngx_http_split_clients_module.c new/nginx-1.31.2/src/http/modules/ngx_http_split_clients_module.c --- old/nginx-1.31.1/src/http/modules/ngx_http_split_clients_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/modules/ngx_http_split_clients_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -182,6 +182,11 @@ for (i = 0; i < ctx->parts.nelts; i++) { sum = part[i].percent ? sum + part[i].percent : 10000; + + if (sum == 10000) { + part[i].percent = 0; + } + if (sum > 10000) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "percent total is greater than 100%%"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/modules/ngx_http_ssl_module.c new/nginx-1.31.2/src/http/modules/ngx_http_ssl_module.c --- old/nginx-1.31.1/src/http/modules/ngx_http_ssl_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/modules/ngx_http_ssl_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -368,6 +368,9 @@ { ngx_string("ssl_sigalg"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_sigalg, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_sigalgs"), NULL, ngx_http_ssl_variable, + (uintptr_t) ngx_ssl_get_sigalgs, NGX_HTTP_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable, (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/modules/ngx_http_upstream_least_time_module.c new/nginx-1.31.2/src/http/modules/ngx_http_upstream_least_time_module.c --- old/nginx-1.31.1/src/http/modules/ngx_http_upstream_least_time_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/modules/ngx_http_upstream_least_time_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -663,4 +663,3 @@ return ngx_conf_set_enum_slot(cf, cmd, conf); } - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/modules/ngx_http_xslt_filter_module.c new/nginx-1.31.2/src/http/modules/ngx_http_xslt_filter_module.c --- old/nginx-1.31.1/src/http/modules/ngx_http_xslt_filter_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/modules/ngx_http_xslt_filter_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -465,7 +465,7 @@ { xmlParserCtxtPtr ctxt = data; - size_t n; + int n; va_list args; ngx_http_xslt_filter_ctx_t *ctx; u_char buf[NGX_MAX_ERROR_STR]; @@ -475,13 +475,23 @@ buf[0] = '\0'; va_start(args, msg); - n = (size_t) vsnprintf((char *) buf, NGX_MAX_ERROR_STR, msg, args); + n = vsnprintf((char *) buf, NGX_MAX_ERROR_STR, msg, args); va_end(args); + if (n <= 0) { + ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, ngx_errno, + "libxml2 error"); + return; + } + + if (n > NGX_MAX_ERROR_STR) { + n = NGX_MAX_ERROR_STR; + } + while (--n && (buf[n] == CR || buf[n] == LF)) { /* void */ } ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0, - "libxml2 error: \"%*s\"", n + 1, buf); + "libxml2 error: \"%*s\"", (size_t) (n + 1), buf); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/ngx_http_variables.c new/nginx-1.31.2/src/http/ngx_http_variables.c --- old/nginx-1.31.1/src/http/ngx_http_variables.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/ngx_http_variables.c 2026-06-17 16:40:35.000000000 +0200 @@ -2298,11 +2298,10 @@ ngx_http_variable_request_id(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - u_char *id; + u_char *id; + uint64_t random_bytes[2]; -#if (NGX_OPENSSL) - u_char random_bytes[16]; -#endif + static uint64_t counter, key[2]; id = ngx_pnalloc(r->pool, 32); if (id == NULL) { @@ -2316,20 +2315,25 @@ v->len = 32; v->data = id; + if (counter == 0) { #if (NGX_OPENSSL) - - if (RAND_bytes(random_bytes, 16) == 1) { - ngx_hex_dump(id, random_bytes, 16); - return NGX_OK; + if (RAND_bytes((u_char *) key, 16) != 1) +#endif + { + key[0] = ((uint64_t) ngx_random() << 32) | (uint32_t) ngx_random(); + key[1] = ((uint64_t) ngx_random() << 32) | (uint32_t) ngx_random(); + key[0] ^= (uint64_t) ngx_pid << 16; + key[1] ^= (uint64_t) ngx_time(); + } } - ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, "RAND_bytes() failed"); + counter++; + random_bytes[0] = ngx_siphash(key[0], key[1], (u_char *) &counter, 8); -#endif + counter++; + random_bytes[1] = ngx_siphash(key[0], key[1], (u_char *) &counter, 8); - ngx_sprintf(id, "%08xD%08xD%08xD%08xD", - (uint32_t) ngx_random(), (uint32_t) ngx_random(), - (uint32_t) ngx_random(), (uint32_t) ngx_random()); + ngx_hex_dump(id, (u_char *) random_bytes, 16); return NGX_OK; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/v3/ngx_http_v3.h new/nginx-1.31.2/src/http/v3/ngx_http_v3.h --- old/nginx-1.31.1/src/http/v3/ngx_http_v3.h 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/v3/ngx_http_v3.h 2026-06-17 16:40:35.000000000 +0200 @@ -138,6 +138,7 @@ unsigned goaway:1; unsigned hq:1; + unsigned created_streams:NGX_HTTP_V3_MAX_KNOWN_STREAM; ngx_connection_t *known_streams[NGX_HTTP_V3_MAX_KNOWN_STREAM]; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/v3/ngx_http_v3_table.c new/nginx-1.31.2/src/http/v3/ngx_http_v3_table.c --- old/nginx-1.31.1/src/http/v3/ngx_http_v3_table.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/v3/ngx_http_v3_table.c 2026-06-17 16:40:35.000000000 +0200 @@ -159,13 +159,17 @@ ngx_http_v3_get_insert_buffer(ngx_connection_t *c) { ngx_http_v3_session_t *h3c; + ngx_http_v3_srv_conf_t *h3scf; ngx_http_v3_dynamic_table_t *dt; h3c = ngx_http_v3_get_session(c); dt = &h3c->table; if (dt->insert_buffer == NULL) { - dt->insert_buffer = ngx_create_temp_buf(c->pool, dt->capacity); + h3scf = ngx_http_v3_get_module_srv_conf(c, ngx_http_v3_module); + + dt->insert_buffer = ngx_create_temp_buf(c->quic->parent->pool, + h3scf->max_table_capacity); if (dt->insert_buffer == NULL) { return NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/http/v3/ngx_http_v3_uni.c new/nginx-1.31.2/src/http/v3/ngx_http_v3_uni.c --- old/nginx-1.31.1/src/http/v3/ngx_http_v3_uni.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/http/v3/ngx_http_v3_uni.c 2026-06-17 16:40:35.000000000 +0200 @@ -105,6 +105,7 @@ ngx_http_v3_register_uni_stream(ngx_connection_t *c, uint64_t type) { ngx_int_t index; + ngx_uint_t streams; ngx_http_v3_session_t *h3c; ngx_http_v3_uni_stream_t *us; @@ -139,10 +140,11 @@ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 stream 0x%02xL", type); - if (h3c->known_streams[NGX_HTTP_V3_STREAM_CLIENT_ENCODER] == NULL - || h3c->known_streams[NGX_HTTP_V3_STREAM_CLIENT_DECODER] == NULL - || h3c->known_streams[NGX_HTTP_V3_STREAM_CLIENT_CONTROL] == NULL) - { + streams = (1 << NGX_HTTP_V3_STREAM_CLIENT_ENCODER) + | (1 << NGX_HTTP_V3_STREAM_CLIENT_DECODER) + | (1 << NGX_HTTP_V3_STREAM_CLIENT_CONTROL); + + if ((h3c->created_streams & streams) != streams) { ngx_log_error(NGX_LOG_INFO, c->log, 0, "missing mandatory stream"); return NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR; } @@ -151,12 +153,13 @@ } if (index >= 0) { - if (h3c->known_streams[index]) { - ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream exists"); + if (h3c->created_streams & (1 << index)) { + ngx_log_error(NGX_LOG_INFO, c->log, 0, "stream already created"); return NGX_HTTP_V3_ERR_STREAM_CREATION_ERROR; } h3c->known_streams[index] = c; + h3c->created_streams |= 1 << index; us = c->data; us->index = index; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/os/unix/ngx_freebsd_init.c new/nginx-1.31.2/src/os/unix/ngx_freebsd_init.c --- old/nginx-1.31.1/src/os/unix/ngx_freebsd_init.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/os/unix/ngx_freebsd_init.c 2026-06-17 16:40:35.000000000 +0200 @@ -162,8 +162,8 @@ * to allow an old binary to run correctly on an updated FreeBSD system. */ -#if (__FreeBSD__ == 4 && __FreeBSD_version >= 460102) \ - || __FreeBSD_version == 460002 || __FreeBSD_version >= 500039 +#if (__FreeBSD__ == 4 && __FreeBSD_version >= 460102) \ + || __FreeBSD_version == 460002 || __FreeBSD_version >= 500039 /* a new syscall without the bug */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/stream/ngx_stream_split_clients_module.c new/nginx-1.31.2/src/stream/ngx_stream_split_clients_module.c --- old/nginx-1.31.1/src/stream/ngx_stream_split_clients_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/stream/ngx_stream_split_clients_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -180,6 +180,11 @@ for (i = 0; i < ctx->parts.nelts; i++) { sum = part[i].percent ? sum + part[i].percent : 10000; + + if (sum == 10000) { + part[i].percent = 0; + } + if (sum > 10000) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "percent total is greater than 100%%"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/stream/ngx_stream_ssl_module.c new/nginx-1.31.2/src/stream/ngx_stream_ssl_module.c --- old/nginx-1.31.1/src/stream/ngx_stream_ssl_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/stream/ngx_stream_ssl_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -367,6 +367,9 @@ { ngx_string("ssl_sigalg"), NULL, ngx_stream_ssl_variable, (uintptr_t) ngx_ssl_get_sigalg, NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_sigalgs"), NULL, ngx_stream_ssl_variable, + (uintptr_t) ngx_ssl_get_sigalgs, NGX_STREAM_VAR_CHANGEABLE, 0 }, + { ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable, (uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nginx-1.31.1/src/stream/ngx_stream_upstream_least_time_module.c new/nginx-1.31.2/src/stream/ngx_stream_upstream_least_time_module.c --- old/nginx-1.31.1/src/stream/ngx_stream_upstream_least_time_module.c 2026-05-22 14:50:47.000000000 +0200 +++ new/nginx-1.31.2/src/stream/ngx_stream_upstream_least_time_module.c 2026-06-17 16:40:35.000000000 +0200 @@ -664,4 +664,3 @@ return ngx_conf_set_enum_slot(cf, cmd, conf); } - ++++++ nginx.keyring ++++++ --- /var/tmp/diff_new_pack.tcSLF1/_old 2026-06-19 17:17:47.254671961 +0200 +++ /var/tmp/diff_new_pack.tcSLF1/_new 2026-06-19 17:17:47.262672237 +0200 @@ -63,4 +63,306 @@ x0VGHDmuaYQ= =HmVo -----END PGP PUBLIC KEY BLOCK----- +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBGYXyiQBEAC4jm1y+ODV4+YDGj9vp2BgHB4FJeQdgrBiVX+Mb2qCrEqJgeKV +fVwKjkVYqnb76TTybdOKqCP5wdQrncKAKlXsMq6sdsiwPSrdRcjkeiE29WWrtbB4 +i+VObnoWklMblMxFQ1XQIkjs2wviidKjJw2VV3i4XnLSrHhWaWqviTLZCMQymoPs +F+Tfu1WX9OUfOquekZ5KjkyBxB4ep6+NPeuIkPnW0SiTUhU8tbi8v0aBZEHSZLqE +mq8KLROVuYSPvtU+NtaXAM09BHEVCfb409aDps9p6AFT+IN8yoOegGdEZjp6hJvS +HxbhuwqNEtg4dTEV515YUCgKabqU1QaqI/Y0+Pdkpep1KRFc9YUYttDkCw7Ybu2u +fwTGzwAbD+ThAIOdzmMDodzZaEMf+9fQG4bnO1PdNbXzyP7Kv9qzGa65+9oGCPOS +qTpISR8pvzoI8w/Z/vG71ob/nQ6Xm0L986ksErdGhu16ZI7lW2eDYqy2IoFfbeSz +HHxk484/pEibrlCRbP2Id+zULfxo1HGOGg+PAY9Q2uNzABsGDMnOhIvXHS+hP7oB +sO9A4Prqu6K6cMp3QI219tmmOUegJpmGGPzoNgxR7H30wNcjZPv4PWr/c0fP70Ny +ilgbdcEMDSHks30AmiuIvcUxo3A21p2nnpxsKAKYx42UJkyEK0HILMzcqwARAQAB +tCZSb21hbiBBcnV0eXVueWFuIDxyLmFydXR5dW55YW5AZjUuY29tPokCTgQTAQgA +OBYhBEM4eCXdsbuX7Da6XQB8jXwV2HNpBQJmF8pXAhsDBQsJCAcCBhUKCQgLAgQW +AgMBAh4BAheAAAoJEAB8jXwV2HNppvQP/AjzdPKkGRzJkb1ioto/IEP1YhA/Eayk +hvejJ0vyWVHXXH7FLW9fIZoApcsD1J8/7zIANm+62IfT3QNbL2R44IyhJB3AY22l +t0ToLxodfugegF3NPYYyFOSRUoPD4g2T/dMCPOBX4MNEAnAlCmxAMaJNmQUO76IY +GwELa3CH3Aqf7bthKy8P36G11hu7NgH6V9mVIRIpfnfpXFQIztj+vsWtswu4M5t7 +BNJwx4a2KTCVQpTdff5/0dO/5drQDxLbIg681WZk3Oe8Eu6nSc0Ud02NIkg1TQH/ +MryAp7o/ua3LRem+W/cktnT60p4uXPVZ3Rvg3zOmJSNJ+eIXY2+sDeZEPaROKldA +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 +kZv2zEcTtzlAYNEumy8KrJzICmPLS7BEC8w= +=ilJ3 +-----END PGP PUBLIC KEY BLOCK----- +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.11 (FreeBSD) + +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 +CoHAyoqJeb/xLBwuKWg0/4U= +=iFlP +-----END PGP PUBLIC KEY BLOCK----- +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQGNBFrwMiUBDADo56OlDknN+ReCMP+8CN1biK5izmGd755TxktHLI9nAP8ociIq +Hjrps22pBtAIQ6eZpwCFBys2mR/441rOgZW+O6uqBYrttbxTMvE43EmKYGuFCmuR +u0JGMPuqnzF3Y+6uoKzqMzazSrZIBWsBKAkNYTw8+yPlxGgffhBp1ueME7Lskglh +EV9gmrEM0QlWod7wSQvyruExPm5INx3MG63Xfvc0bPiWUOGKyMb7kXA5VgnWuzmS +BCMm17+A32vMyxhYcvSEgUayQjGghI1uPDSqBQBMEFTgSK2wWzvAXf/M45nxKBgQ +IEDmvoC8RM9JTtUr7RE/E1mjsuefF2vYYYsWBstRFGAlUV1/lPNNibu3NqbCug6b +1IWJuV1DX9T9/f81GZJrsPgYYKC6Ai8C1B0NGWjos7/GzgEFENQgf5duOhFPadQz +QbRxBoId4Fe/Uwe2HxI8ESCQMwsq8bowcCn6XRA2EYkAt17Kab6LH6tTP54XG9TL +bV7bAhyrvZAk1lUAEQEAAbQjS29uc3RhbnRpbiBQYXZsb3YgPGsucGF2bG92QGY1 +LmNvbT6JAdcEEwEIAEECGwMFCwkIBwICIgIGFQoJCAsCBBYCAwECHgcCF4AWIQQT +yCpjtgNXYVbjCk6g6pgbZrDZZwUCYoTfvAUJEPqvFwAKCRCg6pgbZrDZZxFYDADK +R02XgC+AoyrqMwBNXC8Y6aiilEsyppsgj+KwZcGKDYN488gEmff+/KIEdtglw3I3 +tCMbo+FzFjHveeVCb0qrIMerWJg+o4YrxxqlQ9Q1InpduKLrIuGae0J1ybITS8+v +iYAmwzy1Wb2CDDuCnhCR/QDfOE1CvRILVqIKezC0tRrBTEvRO84m6YMBtJ1DP75Z +2cTNyjPos9+uxi4JcMKrMUBwZKya+z5i+Uxd66wuPj9KmggNG1x+bqMWmpTrSKUn +gbLabFUth+uWumpj3/7HBT8Ov7rPgzY/vn3Fn5mKdLQm+kRwSX9/FbtHAE3Qsm+f +6WW8CZ4XzL9ONfhQYwO2Jrq4HzgYloZkL+1Zs61X+zeEyr4o/mzt5DHbQRsD1UzQ +gnh7t3YdSAy6gBqevjPWkQlq9e8eoFRydN/htwjS7dleikOsYktSnTIKlRXAWGCm +jkRpQyZYuuPcWcGRt/0MVewRJmLemH6O+NviqhgGRePO9QR0R+yfdCwewPJEDk6J +AjMEEAEKAB0WIQTWeGzjA9mpAimY3GzIRk1UmvdcCgUCYoeH1wAKCRDIRk1Umvdc +Cqa9EAC8Li+w/sRwiu39vNUBogWiAKj3mlfS9lEdmPWx/MSzWtik+IlI931flFWI +GL3OWC0ZXVV9G3WXQmVUqMtW2Eachy1DOSwAh4nRn03udfeMG79DUJBvMpAKTSua +cVr2tRCFXQcx+6hmkZaANGjalzVu8tEcWfOiT19LS1QM+PH36adQCtRD+wwLgvVq +qVowo6yO6jdhCATakRWO9uqeQXvdhJ7n5A3/Hg4QKtbb5vbz6QTPOs1+prICBdfF +rVEdLx9BeZGVVoWeJNzbv9ZciC+8YYo/HOTbkccJSJ+G/FeHvshYL9Saxrsl1nUX +yNCHBdrUyxPfZMgPWD2k431uplUVCwV5MOaQR4KU8AO3lcKVs02viw4smo0mWa6O +pnMIHQ/cWgNxB5/66ch3r7YqosBi8KWHMVBejD+tOv/Y1Ey7v0mF7nBdIclbQz8t +6PlKN8cOggqWjczPo1BtwPxiAkI8Y4VyhOk4ncZnluY1CtM2rQipLfcVFC/z3UGh +ZuZ9WIi31ns8Va+msHyIaQx51PB0hSmL+AkDjUuB5APO9zFE2tGV9elbmant6f5c +k4F65i19kDcfPe397FjqgyCdIduEDDtoaSS+a6oUgffHgXMXhtP2hI9zQ6c8Bnnd +f10HDxakJEcNEz7m8i7VZ0xb+UsOej2rSgdyTIW+an9t8NF9eIkBMwQQAQgAHRYh +BHM4lzBp7T9EP00336ZP1bF62zmoBQJii0M3AAoJEKZP1bF62zmoEZYIAIK8SaCJ +KT/0NtCyzmFdjX6v+H+EYjEUJCx1QPsHt35Qglco24L/X9hnPJF9P6MY3S3PDLyd +9JsmD+mujgsShqYFME/GzSScYy5Mzm5FM0xXs9UJ51YL+frKknenN5eIr7WVjXnh +g0fKn2ZqXlZ/MozHKjKQhhzl9SN6b8eDbi1SFHS/FC7C4Tymnrkhi2KAvpEtUyvg +mRSCU5Hrqh6wvi1bCpZ4+vXzQG20CT2cxa1YmgJIDhBqKiWGLyEY2hMCoRKsx5CI +UVllc83Hrpk182DDOoVVhxFpStYD/4CNCP46oSeOtjv6EPLIIug25rsjBHPHPfMf +p64DcAoKkk6cuFWJAjMEEAEKAB0WIQRB25JxPTv0v/PukQacXn+i9Ul31AUCYoeM +ZQAKCRCcXn+i9Ul31EVUD/kB3lxEMDKFg/lFpSBxm1nxplmOCp5Nq9F8Rs9KDsbR +Rc4zKL+2PLkgfxh/Nk5+9zjclUjFMBzYS0vEEml7f1R6ceG1a9r7HrdkO581Mvwe +x90qVkMMKsShqIcuLzOK0LpvTobBlQpZCBImsNaEVHnmMR3hCz5OmUsGjxNgym87 ++ovRJKCZRbbJ36w+COf/jVEkczm+7OrG5BeTTPwWjoIkqs6dajYikfZI79J7FZ2C +pWpWeIgJA5emc3sAZWi0KTxlPZ9K4ff3iuV+Xf2PyuRC3iZlOuO66RJ/sl441ebN +ckn1Ngu3s48PyMjgD3VG8WDh4RCqBtLpMQJc60wboq9gPMhyyd5eyTYMI90HAEg9 +pYGsw6Wk8NpUmBzbSzqSOOdN/SvAXkJmQVGKEzgvDLEsmTeddsjE6U+KUS+8Y69k +Dc3sRIR3p5cKoPgZuK2mgbiXvF+TyVGODsyUUCygCGBNN8vsDDw4gpTuOhUm1nMP +3jagHWz2NnMRo00x2nayjffjpMHCKSoNy+UTBKhVLffeZ8df6fCD9SAK+UavPVFW +kMKhd+gofhrIbnca9ZL4K+CdyD1d0sxWNtoiDGi9HSnTwXhyGujv2QnNpBxCUZTD +nvOEUSNFP/9N+tkAAGiAvk5L5ZuwHRppvnv6t6JEbM7ryRBwWHwgWHConwiFWImN +XYkCMwQQAQoAHRYhBC6ZFqS4exJw9J8ez+sX9nTHmkCiBQJii1dOAAoJEOsX9nTH +mkCiKu4P/0+je/GsBE69YVAwEFBrrfhEJtVUY8GSYM8WeFoq20SX8SqwltGLFB5R +kbZGgPLe0lJrgXzL01GqjU1tnXPbtI7LEq1FKiTkcKVdne140oX1XJuxmFWBcldG +1IetinhJt5EkaYc6nyk9iWgCz9n5YDq9Lr/9jLhFQAgawuicwAfuB13MGbJZYm/Z +5eSdxnivXbrGAYR2TI6/kcf0JLGR03fKbrEM8uBnfZNkKZELyYrBCj4FYODT++Sx +pDyrNr2/FlierISJrs272JT7ICg7Knjh6X7BSzsgK7JxyG2UtJKK7qJXYEqMtYhH +U1tdh4Ru6zSd4DklgrFHwuUNlTm8f1gPQ4I46p2RCQy2HMnA9WhJ8kwE2JOAj83y +87f9hDwjmn8Pf/iksXGRFQcfDqkOIUf2EnyBvxrzS57Dfvk6WCaH+OLKn1jMyxL8 +BekCyk7L7wrMJI4yH51jyJySScGBg1CM0fYqLFWU/I+jw9bHROdCOK2LBajkAYgx +/eLG9WtS4etlNmpsxhSOi48wxa6kIOnD2rJGvQMALxhWJlVBEOMumv96qNCQCzHd +6NRLBWBva4qlKM5RlZreeVyArFtTiUmnp6RST4FrMpVgmhoeyos6P6GIG6QVPS2b +4dSRbeKmJFb15kZN8eYP4/BW7DMBzkFwtkRFDV5f/4W6CU6UIGzViQEcBBABCAAG +BQJii68XAAoJEFIKmZOhwFL4HY0IAKejouSXBCQWJmpdsA9TV2WVdMspUZHDGRAH +epQetm0+eX5Jh62ktuAZG+KCZ0bMdd8FJd6+RRpftUGhDibu9IFfyIK1v8jrChTU +/EwK8cPgLn4KveTgC58UrKt4NMpqcETUCrXHVwZzYK/sGZxxKVHhmnQJtfsvg7FV +7Ia9ohiUy1/rz9UlwLPUGmrDnSemSR9w1B3XeNN8SmTHQ5gpZt/rvsII0wMhvS7p +TXDpK5YNAqItC+7ZDaU1T21xeZx9OGSt/T2ETXb0rjIJAhKiSShqbiRonZHrxOcg +p0vSM1IAsgfnRihHu9YZ3Vj5ntegHh4fWdcTSZUx0n/YggArsyG0JEtvbnN0YW50 +aW4gUGF2bG92IDx0aHJlc2hAbmdpbnguY29tPokB1AQTAQgAPgIbAwULCQgHAwUV +CgkICwUWAwIBAAIeAQIXgBYhBBPIKmO2A1dhVuMKTqDqmBtmsNlnBQJihN+8BQkQ ++q8XAAoJEKDqmBtmsNlncQ0L/0Yk1QejO06gWwV1J2eK9LmjbMofy2ujZBgW1IGt +/goo5R4PzC8lBBcsBtsKyN0Rsh7QdLrtKKLQrE/gpwMTMdKhJTdP/c5tUY3EwgId +BMYVaxArZQiWlPgSnoKuKydnn6Rb+Qtrhvb9pjn5XlGd/VSbAXZe8YTj6B8qjUa2 +YY+IreyB6wkPN/ytV5vcocbS7mzXaibGPVT35e0Pl1Be+xbJkbTmJTSJCSPwyHm9 +t2Vuq4e/c3fMwhOUbBjfssspR103vo91XO5sY+v2aQJOctNrv4ZpHMrwBH7MeqDI +SCWg9PICUv0ewHzAEGB+K0v342rVAzVNEctwM3Jic7fEJYsItdw+Zk4r8NYqACoR +CdSUEHqhP0DbYoWdthpUwD1J5ryWyKTCpTL4wNhKEMcNaiHH3qorSssyMHMFRPoX +Kw9Pcay+Uo8NXc2KKxhEHTbQts0jYUNcq0yuWHoNQ4vhKkf9CHBrb/vS22vfEJyd +6FX6ZRYK56A3EFAV8hK0BvZAw4kCMwQQAQoAHRYhBNZ4bOMD2akCKZjcbMhGTVSa +91wKBQJih4fSAAoJEMhGTVSa91wKipoQAI3wkWd8HLQ0w4IFA6W3/igrZTut9sV+ +K5Veb61zCbJn6I2aO3ldSClMWpJfvG1OPKyaA6o4QfWt7KV9of8tu68k1rTrKKYe +qXe/0KNp9nzEwVmLASG2U6onwaCehGocvhWc9tE6MF2Gi+l+OufqsMzmx7gkdwE+ +4d/VpY/i+eZzqNi1WWNUR45mrItvw84enGW2u4JOaFdSOE2PAbSTUOlcLxfC9yCo +lxAkCsy+CsXM8WKlIDH8GpWh/mWyqjoAhZhrlGhdABjygqFAOrDhIaecc8eSOcD3 +6MQvhj/y1kh0Fe0rMCSdxUWtSjv+Sw5g1IG6GxhsqFxunxfGDpdbaLnyTQWahDfi +5OsOFl6JbPFiTaF9Xqz+8r0hiwusT4AJvM5M+q18f5dNCeqVKmuAn3BVBw4RdG62 +WXt4q6uE5rDI513dR8t84dTgOr9+tHKh5TJqw46aI+kMe36z7FPXBgDsGSkNtM4J +BYdZzxSoJCfsGCjlfapkLHrvI+S7AP2952WfYy36uuxBiuTp3vCghvKkXZUeN2kh +P++0Zo4OjZGOllhab1X5xZGO8AjWeei4pq66Ys94Veidw5VRi/eWyvB3OhfCq9fb +qZIKUfbgTu0y7vOEWWY9wQml12gpxQfkcI72NTiNMCH268WZoXYQJp0+NZtxjsHQ +PdhNxQOaJPqziQEzBBABCAAdFiEEcziXMGntP0Q/TTffpk/VsXrbOagFAmKLQzAA +CgkQpk/VsXrbOairRggArvsikhDrA1d/x1BXnzOxE2sznq/d84QCKMSQpavrzXHF +LQF/qIB+ePA4bmzwvTxQup7yTLK3mQDl0rejXEQMnXHvgfH73c6l6TdAwsoLmrpt +oGNzfzJsbiKD2hJT9jJVnipuqqOA7hPT73TA5KM4GzPupFTadB57lDxzzcRfALXi +t5Qa6A83tLelQXLOWP6IdyPjraa/kva5jYsMavZU0xWTx9nPeGCwqAnqdEN4Hp8K +WKYn9EzkBOL6pPB7GyG/G20ocTCv/ZCJMkamAxjprUovu9BUEg5fCcHrSBtsgGE0 +doPfqyOb4tCofZ8aXZYIu3+BEcNO0e5la+eW0YYYPIkCMwQQAQoAHRYhBEHbknE9 +O/S/8+6RBpxef6L1SXfUBQJih4xhAAoJEJxef6L1SXfUb8AQAML5vwKOTw6Bn0tA +1ypo6DmlJUWalGgEkFheUC02s+BT+bL/fMsiXd6dBHHl/93bVBQBL/AjVBVv7viQ +kfQLLk7iQmEQ/mljvImGkA/W+vyHKDue6n79Ccjfx/ECQB4Y8mmFhOqhDjEC6oR6 +ny77QbqmzvjkhfncD26cJq+qRGnE7EwuQI49bR1deQGxr5apqx5XRbf+GPnXlPTc +nKxctRsw6PLOjFoyGhBnvC/rEzBUx+wE7jK+bY1TSdW8x91LA/SseWqsmEFzbZRt +KKaHE9wD2DB9UvdBAjXdBZvKQ35zSJRWQByODztI9ZcaOWopK3UtIhG/eNIaJGcD +9h3SaeVE8PcUkvZqhLtQf49KlUBc8/g6Nj1wqcBbHDXjbwzt9Qoh6uFyjMkbG3NP +BXn7cT8888fJ9Oi53XjjZEVKA88AdcqWpUZtyElNwGtj8IvJ0R9SMKR/7KIYPFWm +R04Uok+oj0wQABHkcLmYMUd8psw6aQWG7oybfgPokRChExigLWrCJbYd00banL18 +W6RxOQzceiKeZ5sZ5Y+yjQIrKxXKSLl42s8zol05TPScnBn+SAWigG4eEEJhT2by +2WqbhCG9snN9/YMlY8MffOFnD05ps40CSdSCsRgcmaqxgjy75h/z5LYO4HnHwPdY +p2ysNzlruScewHvijYJhEKxo17lBiQIzBBABCgAdFiEELpkWpLh7EnD0nx7P6xf2 +dMeaQKIFAmKLV00ACgkQ6xf2dMeaQKLLQg//etbDTflbm+HbxI/YyNQhyQfk7icE +ytLL+wT9zDW9iq3AMdaPZwT690CsJhr7yzqjk0AGoMyuPfntvcvYb1mPTObXHMzh +Rh7+tViPixkJd3hnjSrPBEOkpAghk6xWMx1wldZ9x5XyJ0yC+toBkSaB/KIQeRG2 +8/jHtxIQKvPGL28gUjdzW+jopSA4x6gSZAgQLyfsjoUHcMrRJXrwWcmSe8faD8qX +XD4z4hN3wQg6olSuaxLM7OoNgbiEjKaL1LaX/xzvC0lGs9o2JBfNFDrng9Y/fZ4o +9aGqx7AZey+4wTKjXqbdEqfDiHfzHxkLBunPxSjJAploOcuvhNOQAY7tv19/mYY1 +UoILY9ninCrXthe9ZqhaXxhRhqYhzrE8svF+R01I/U+N4985AnDKRkJ944pZfeh1 +wYzEZOPXWvvTsiBLbgi9LuAzoFjA4WJsJBp4AP/U7DtsuhMTmxyBJa+zg8PHj1Ew +jBYYuE++ulsilS+76sQawT5KbszpYmEDJiQUuEJkujPQ+hGzuuocoqHrM/IcoAoy +i5I/JMAYRqCQfGMFjirmVj3c01jgsOYl7ZgchtCBJfG8V6rlYdTq2FTdaLYdleZC +kS7N4jtm+6/KEsf6ukeGNEMbsxTSPHq4RL13eSitRd9Ms+ukSZFFgE0rEiztcdxQ +h1PeaEVaxHaSSWiJARwEEAEIAAYFAmKLrxcACgkQUgqZk6HAUvihvAgAk1ETByL3 +FZtIlk8scREfwzyqyXuSYWdJ5ED61fKnpcfwGKsOkd+4MwHOSgvxPdnLhBEsMkNq +sV82EqX7lTIGoFBLTeW8ZGAxmt/88j3z6mnm33lSTreeVwsQ+B9ZKVAv4E/liDVm +6iq9aYJni4FUoFjFhtgsvJUNs3oX0gaEXdaCqzIDysU2m01vOPx0HTeI95+HdlJW +Iwwh/cp+YuclHppI+b0OQKJwLQDVyudzX0JYTWvgE/NCS6/rP8fjaqtFMWwL0tZl +3JJAoLSAuhPyc+V2LkRVoETQGF9nRil2zSyy77Stfm2fRGstnQGOrNTud06el68/ +hYfWcCqooHNiMrkBjQRa8DInAQwA2Rk7UdUgpCWl+BMz9B9eKj0XtsNEciXHHKnS +FYaSNCWNwib/FsiMfcPFh7xwUTof7e7HBFkvv0QEMCEp7R1MVNBfMiGtG1ICFIt9 +nByznPsRk4VvbY/prK4DZy2AmlwhNcT2pQO3AascgsCWdf6G+wcwnHg9tWCp0Xs9 +BNXuppmcRrpP4M1PPRIVeG1jeVXvuSHO2HjqPSXP5DhGgSGN7uLOhiLTnPINd186 +vf6tqRdqYw3g0W1ImEjGXHeNQfnieIWdU3X4C8KTEPsV3lvtmSAQCoge0CyKfz4c +ORi4j8Edp8JpDQlbAThe529+R3eKUw7I/3ESxJBdqzLE/ItWvAcbGEserLDFrg9J +1ojiKhsw3TVcDk+HIDzVakMz6HTd4ExSijMqTehzgKSVHDL+l2jc0f4VSecI+xwC +3/kNsNTBpiPoUYtXBbJllHgQAakREkSKQBas02eqRu8SlQ3yEn87zTtNW8L7xpe7 +ZVtxwUgp40PUrsb8uMDJG7ZP5rhLABEBAAGJAbwEGAEIACYCGwwWIQQTyCpjtgNX +YVbjCk6g6pgbZrDZZwUCYoTfwQUJEPqvGgAKCRCg6pgbZrDZZ3oEDAC1J3BVwlkX ++eoo8VsXAYxMXm8kIaTqOn/tHMOYepK+cWUdHaeCH3N8LigwN4Ve2LtzLBqN3WRA +xFNy0DIzdBfA7QdcAoDLnB2FNrWTmwvC9nXkCogFfSCq7c+1oFHdn7M/VZNU4o0n +hVOnqM8NLGcgzX3K3hr+WLYUgNQ9G6x0N9VU43tqVwJhvNv4pyiRpRdLlmhOEf35 +a/sWE1dttSKdrBhyzTbptw4dXr4lUpvlswWs+dLpSPPhWAuifORv/amWh3bxIxYE +qE4o5NI/PQLJvJJLsJvMIIjpKlAGBJg5h3WCiIAkl7H+BesOUIIg8ava5ZUyjlFd +szBMaBosZvRgFAlfnYhSGqzhip6PvXfK1YokNv7kqw43c0f1SmtSXZR43SRv/4vp +XG7IqtTuqgSwn1qDJgr4yfs8QQykO/jG+cz7X+5OKSAulWi9OoqLyDWlsm3WccPI +cJfbm71P+I/ha7ESVQfOxC92fQ7HQAboj7NhecJ4RLqjzrWSHmPGClI= +=t1B0 +-----END PGP PUBLIC KEY BLOCK-----
