diff --git a/SPECS/nginx/0001-remove-Werror-in-upstream-build-scripts.patch b/SPECS/nginx/0001-remove-Werror-in-upstream-build-scripts.patch new file mode 100644 index 00000000000..cd3873c1c92 --- /dev/null +++ b/SPECS/nginx/0001-remove-Werror-in-upstream-build-scripts.patch @@ -0,0 +1,30 @@ +From d6baea50cd55bc1ae9df1b8d1327b998ac738e0e Mon Sep 17 00:00:00 2001 +From: Felix Kaechele +Date: Sun, 7 Jun 2020 12:14:02 -0400 +Subject: [PATCH 1/5] remove Werror in upstream build scripts + +removes -Werror in upstream build scripts. -Werror conflicts with +-D_FORTIFY_SOURCE=2 causing warnings to turn into errors. + +Signed-off-by: Felix Kaechele +--- + auto/cc/gcc | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/auto/cc/gcc b/auto/cc/gcc +index a5c5c18fba3f..cdbbadb54023 100644 +--- a/auto/cc/gcc ++++ b/auto/cc/gcc +@@ -166,7 +166,9 @@ esac + + + # stop on warning +-CFLAGS="$CFLAGS -Werror" ++# This combined with Fedora's FORTIFY_SOURCE=2 option causes it nginx ++# to not compile. ++#CFLAGS="$CFLAGS -Werror" + + # debug + CFLAGS="$CFLAGS -g" +-- +2.52.0 diff --git a/SPECS/nginx/0002-fix-PIDFile-handling.patch b/SPECS/nginx/0002-fix-PIDFile-handling.patch new file mode 100644 index 00000000000..6c51db190cb --- /dev/null +++ b/SPECS/nginx/0002-fix-PIDFile-handling.patch @@ -0,0 +1,107 @@ +From 03b18ac401de8df804b1cc455ded06359dae2374 Mon Sep 17 00:00:00 2001 +From: Felix Kaechele +Date: Tue, 20 Apr 2021 21:28:18 -0400 +Subject: [PATCH 2/5] fix PIDFile handling + +Corresponding RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1869026 + +Rejected upstream: https://trac.nginx.org/nginx/ticket/1897 + +Taken from: https://git.launchpad.net/ubuntu/+source/nginx/tree/debian/patches/nginx-fix-pidfile.patch + +From original patch: +Author: Tj +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/nginx/+bug/1581864 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=876365 +Last-Update: 2020-06-24 + +Signed-off-by: Felix Kaechele +--- + src/core/nginx.c | 24 +++++++++++++++++++++--- + src/os/unix/ngx_daemon.c | 8 ++++++-- + 2 files changed, 27 insertions(+), 5 deletions(-) + +diff --git a/src/core/nginx.c b/src/core/nginx.c +index 0deb27b7f98a..23edb59ff105 100644 +--- a/src/core/nginx.c ++++ b/src/core/nginx.c +@@ -340,14 +340,21 @@ main(int argc, char *const *argv) + ngx_process = NGX_PROCESS_MASTER; + } + ++ /* tell-tale to detect if this is parent or child process */ ++ ngx_int_t child_pid = NGX_BUSY; ++ + #if !(NGX_WIN32) + + if (ngx_init_signals(cycle->log) != NGX_OK) { + return 1; + } + ++ /* tell-tale that this code has been executed */ ++ child_pid--; ++ + if (!ngx_inherited && ccf->daemon) { +- if (ngx_daemon(cycle->log) != NGX_OK) { ++ child_pid = ngx_daemon(cycle->log); ++ if (child_pid == NGX_ERROR) { + return 1; + } + +@@ -360,8 +367,19 @@ main(int argc, char *const *argv) + + #endif + +- if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) { +- return 1; ++ /* If ngx_daemon() returned the child's PID in the parent process ++ * after the fork() set ngx_pid to the child_pid, which gets ++ * written to the PID file, then exit. ++ * For NGX_WIN32 always write the PID file ++ * For others, only write it from the parent process */ ++ if (child_pid < NGX_OK || child_pid > NGX_OK) { ++ ngx_pid = child_pid > NGX_OK ? child_pid : ngx_pid; ++ if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) { ++ return 1; ++ } ++ } ++ if (child_pid > NGX_OK) { ++ exit(0); + } + + if (ngx_log_redirect_stderr(cycle) != NGX_OK) { +diff --git a/src/os/unix/ngx_daemon.c b/src/os/unix/ngx_daemon.c +index 385c49b6c3d1..3719854c52b0 100644 +--- a/src/os/unix/ngx_daemon.c ++++ b/src/os/unix/ngx_daemon.c +@@ -7,14 +7,17 @@ + + #include + #include ++#include + + + ngx_int_t + ngx_daemon(ngx_log_t *log) + { + int fd; ++ /* retain the return value for passing back to caller */ ++ pid_t pid_child = fork(); + +- switch (fork()) { ++ switch (pid_child) { + case -1: + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed"); + return NGX_ERROR; +@@ -23,7 +26,8 @@ ngx_daemon(ngx_log_t *log) + break; + + default: +- exit(0); ++ /* let caller do the exit() */ ++ return pid_child; + } + + ngx_parent = ngx_pid; +-- +2.52.0 diff --git a/SPECS/nginx/0003-Add-SSL-passphrase-dialog.patch b/SPECS/nginx/0003-Add-SSL-passphrase-dialog.patch new file mode 100644 index 00000000000..9966c521054 --- /dev/null +++ b/SPECS/nginx/0003-Add-SSL-passphrase-dialog.patch @@ -0,0 +1,805 @@ +From a9ba90c8c01ab88884c93b655ca22c2ade06e6d2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= +Date: Tue, 8 Jul 2025 15:19:41 +0200 +Subject: [PATCH 3/5] Add SSL passphrase dialog + +--- + contrib/vim/syntax/nginx.vim | 1 + + src/event/ngx_event_openssl.c | 34 ++++++-- + src/event/ngx_event_openssl.h | 16 +++- + src/event/ngx_event_openssl_cache.c | 102 ++++++++++++++++++++++- + src/http/modules/ngx_http_grpc_module.c | 2 +- + src/http/modules/ngx_http_proxy_module.c | 2 +- + src/http/modules/ngx_http_ssl_module.c | 70 +++++++++++++++- + src/http/modules/ngx_http_ssl_module.h | 2 + + src/http/modules/ngx_http_uwsgi_module.c | 2 +- + src/mail/ngx_mail_ssl_module.c | 66 ++++++++++++++- + src/mail/ngx_mail_ssl_module.h | 2 + + src/stream/ngx_stream_proxy_module.c | 2 +- + src/stream/ngx_stream_ssl_module.c | 61 +++++++++++++- + src/stream/ngx_stream_ssl_module.h | 2 + + 14 files changed, 344 insertions(+), 20 deletions(-) + +diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim +index 29eef7a23cd7..e7227eb7f873 100644 +--- a/contrib/vim/syntax/nginx.vim ++++ b/contrib/vim/syntax/nginx.vim +@@ -593,6 +593,7 @@ syn keyword ngxDirective contained ssl_ocsp + syn keyword ngxDirective contained ssl_ocsp_cache + syn keyword ngxDirective contained ssl_ocsp_responder + syn keyword ngxDirective contained ssl_password_file ++syn keyword ngxDirective contained ssl_pass_phrase_dialog + syn keyword ngxDirective contained ssl_prefer_server_ciphers + syn keyword ngxDirective contained ssl_preread + syn keyword ngxDirective contained ssl_protocols +diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c +index defffa583eb5..fb6a5e950504 100644 +--- a/src/event/ngx_event_openssl.c ++++ b/src/event/ngx_event_openssl.c +@@ -419,7 +419,7 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data) + + ngx_int_t + ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, +- ngx_array_t *keys, ngx_array_t *passwords) ++ ngx_array_t *keys, ngx_array_t *passwords, ngx_ssl_ppdialog_conf_t *dlg) + { + ngx_str_t *cert, *key; + ngx_uint_t i; +@@ -429,7 +429,7 @@ ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, + + for (i = 0; i < certs->nelts; i++) { + +- if (ngx_ssl_certificate(cf, ssl, &cert[i], &key[i], passwords) ++ if (ngx_ssl_certificate(cf, ssl, &cert[i], &key[i], passwords, dlg) + != NGX_OK) + { + return NGX_ERROR; +@@ -442,7 +442,7 @@ ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, + + ngx_int_t + ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, +- ngx_str_t *key, ngx_array_t *passwords) ++ ngx_str_t *key, ngx_array_t *passwords, ngx_ssl_ppdialog_conf_t *dlg) + { + char *err; + X509 *x509, **elm; +@@ -450,6 +450,7 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, + EVP_PKEY *pkey; + ngx_uint_t mask; + STACK_OF(X509) *chain; ++ EVP_PKEY *pubkey; + + mask = 0; + elm = NULL; +@@ -457,7 +458,7 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, + retry: + + chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CERT | mask, +- &err, cert, NULL); ++ &err, cert, NULL, dlg); + if (chain == NULL) { + if (err != NULL) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, +@@ -562,9 +563,24 @@ retry: + + #endif + ++ pubkey = X509_get_pubkey(x509); ++ if (!pubkey) { ++ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, ++ "X509_get_pubkey() failed"); ++ return NGX_ERROR; ++ } ++ ++ if (dlg) { ++ dlg->cryptosystem = EVP_PKEY_get_base_id(pubkey); ++ } ++ ++ EVP_PKEY_free(pubkey); ++ + pkey = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_PKEY | mask, +- &err, key, passwords); +- if (pkey == NULL) { ++ &err, key, passwords, dlg); ++ if (ngx_test_config) { ++ return NGX_OK; ++ } else if (pkey == NULL) { + if (err != NULL) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "cannot load certificate key \"%s\": %s", +@@ -751,7 +767,7 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, + return NGX_ERROR; + } + +- chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CA, &err, cert, NULL); ++ chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CA, &err, cert, NULL, NULL); + if (chain == NULL) { + if (err != NULL) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, +@@ -849,7 +865,7 @@ ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, + return NGX_ERROR; + } + +- chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CA, &err, cert, NULL); ++ chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CA, &err, cert, NULL, NULL); + if (chain == NULL) { + if (err != NULL) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, +@@ -905,7 +921,7 @@ ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl) + return NGX_ERROR; + } + +- chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CRL, &err, crl, NULL); ++ chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CRL, &err, crl, NULL, NULL); + if (chain == NULL) { + if (err != NULL) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, +diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h +index fe5107fb6915..43bddc7be736 100644 +--- a/src/event/ngx_event_openssl.h ++++ b/src/event/ngx_event_openssl.h +@@ -100,9 +100,19 @@ + #define SSL_group_to_name(s, nid) NULL + #endif + ++#define NGX_SSL_PASS_PHRASE_ARG_MAX_LEN 255 ++#define NGX_SSL_PASS_PHRASE_DEFAULT_VAL "builtin" ++#define NGX_SSL_SERVER_NULL "undefined" + + typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t; + ++typedef struct ngx_ssl_ppdialog_conf_s ngx_ssl_ppdialog_conf_t; ++ ++struct ngx_ssl_ppdialog_conf_s { ++ ngx_str_t *data; ++ ngx_str_t *server; ++ ngx_int_t cryptosystem; ++}; + + struct ngx_ssl_s { + SSL_CTX *ctx; +@@ -230,9 +240,9 @@ ngx_int_t ngx_ssl_init(ngx_log_t *log); + ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); + + ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, +- ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); ++ ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords, ngx_ssl_ppdialog_conf_t *dlg); + ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, +- ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); ++ ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords, ngx_ssl_ppdialog_conf_t *dlg); + 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); +@@ -261,7 +271,7 @@ ngx_int_t ngx_ssl_ocsp_cache_init(ngx_shm_zone_t *shm_zone, void *data); + ngx_ssl_cache_t *ngx_ssl_cache_init(ngx_pool_t *pool, ngx_uint_t max, + time_t valid, time_t inactive); + void *ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err, +- ngx_str_t *path, void *data); ++ ngx_str_t *path, void *data, ngx_ssl_ppdialog_conf_t *dlg); + void *ngx_ssl_cache_connection_fetch(ngx_ssl_cache_t *cache, ngx_pool_t *pool, + ngx_uint_t index, char **err, ngx_str_t *path, void *data); + +diff --git a/src/event/ngx_event_openssl_cache.c b/src/event/ngx_event_openssl_cache.c +index d5488f89a69b..83ddbbaeb97e 100644 +--- a/src/event/ngx_event_openssl_cache.c ++++ b/src/event/ngx_event_openssl_cache.c +@@ -15,6 +15,7 @@ + + #define NGX_SSL_CACHE_DISABLED (ngx_array_t *) (uintptr_t) -1 + ++#define NGX_PASS_PHRASE_ARG_MAX_LEN 255 + + #define ngx_ssl_cache_get_conf(cycle) \ + (ngx_ssl_cache_t *) ngx_get_conf(cycle->conf_ctx, ngx_openssl_cache_module) +@@ -116,6 +117,13 @@ static void ngx_ssl_cache_node_insert(ngx_rbtree_node_t *temp, + static void ngx_ssl_cache_node_free(ngx_rbtree_t *rbtree, + ngx_ssl_cache_node_t *cn); + ++static int ngx_ssl_cache_read_pstream(const char *cmd, char *buf, ++ ngx_int_t bufsize); ++ ++static int ngx_ssl_cache_pass_phrase_callback(char *buf, int bufsize, ++ int rwflag, void *u); ++ ++static ngx_ssl_ppdialog_conf_t *pass_dlg = NULL; + + static ngx_command_t ngx_openssl_cache_commands[] = { + +@@ -179,7 +187,7 @@ static ngx_ssl_cache_type_t ngx_ssl_cache_types[] = { + + void * + ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err, +- ngx_str_t *path, void *data) ++ ngx_str_t *path, void *data, ngx_ssl_ppdialog_conf_t *dlg) + { + void *value; + time_t mtime; +@@ -263,7 +271,9 @@ ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err, + } + + if (value == NULL) { ++ pass_dlg = dlg; + value = type->create(&id, err, &data); ++ pass_dlg = NULL; + + if (value == NULL || data == NGX_SSL_CACHE_DISABLED) { + return value; +@@ -674,6 +684,7 @@ static void * + ngx_ssl_cache_pkey_create(ngx_ssl_cache_key_t *id, char **err, void *data) + { + ngx_array_t **passwords = data; ++ ngx_ssl_ppdialog_conf_t *dlg = pass_dlg; + + BIO *bio; + EVP_PKEY *pkey; +@@ -745,6 +756,22 @@ ngx_ssl_cache_pkey_create(ngx_ssl_cache_key_t *id, char **err, void *data) + tries = 1; + pwd = NULL; + cb = NULL; ++ ++ /** directive format: ssl_pass_phrase_dialog builtin|exec:filepath */ ++ if (dlg && ngx_strncasecmp(dlg->data->data, (u_char *)"exec:", 5) == 0){ ++ pwd = (void *)dlg; ++ cb = ngx_ssl_cache_pass_phrase_callback; ++ cb_data.encrypted = 1; ++ } else { ++ pwd = NULL; ++ cb = NULL; ++ } ++ } ++ ++ /* skip decrypting private keys in config test phase to avoid ++ asking for pass phase twice */ ++ if (ngx_test_config){ ++ return NULL; + } + + for ( ;; ) { +@@ -1170,3 +1197,76 @@ ngx_ssl_cache_node_insert(ngx_rbtree_node_t *temp, + node->right = sentinel; + ngx_rbt_red(node); + } ++ ++static int ++ngx_ssl_cache_read_pstream(const char *cmd, char *buf, ngx_int_t bufsize) ++{ ++ FILE *fp; ++ ngx_int_t i; ++ char c; ++ ++ fp = popen(cmd, "r"); ++ if (fp == NULL) { ++ return -1; ++ } ++ ++ for (i = 0; (c = fgetc(fp)) != EOF && ++ (i < bufsize - 1); i++) { ++ ++ if (c == '\n' || c == '\r'){ ++ break; ++ } ++ ++ buf[i] = c; ++ } ++ buf[i] = '\0'; ++ ++ pclose(fp); ++ ++ return 0; ++} ++ ++static int ++ngx_ssl_cache_pass_phrase_callback(char *buf, int bufsize, int rwflag, void *u) ++{ ++ u_char cmd[NGX_PASS_PHRASE_ARG_MAX_LEN + 1] = {0}; ++ u_char *cmd_end; ++ ngx_ssl_ppdialog_conf_t *dlg = (ngx_ssl_ppdialog_conf_t *)u; ++ ngx_str_t *pass_phrase_dialog = dlg->data; ++ char cryptosystem[4] = {0}; ++ int ret; ++ ++ /* remove exec: str from pass_phrase_dialog */ ++ pass_phrase_dialog->data = pass_phrase_dialog->data + 5; ++ pass_phrase_dialog->len = pass_phrase_dialog->len - 5; ++ ++ switch (dlg->cryptosystem){ ++ case EVP_PKEY_RSA: ++ strncpy(cryptosystem, "RSA", 4); ++ break; ++ case EVP_PKEY_DSA: ++ strncpy(cryptosystem, "DSA", 4); ++ break; ++ case EVP_PKEY_EC: ++ strncpy(cryptosystem, "EC", 3); ++ break; ++ case EVP_PKEY_DH: ++ strncpy(cryptosystem, "DH", 3); ++ break; ++ default: ++ strncpy(cryptosystem, "UNK", 4); ++ break; ++ } ++ ++ cmd_end = ngx_snprintf(cmd, NGX_PASS_PHRASE_ARG_MAX_LEN, "%V %V %s", ++ pass_phrase_dialog, dlg->server, cryptosystem); ++ *cmd_end = '\0'; ++ ++ ngx_log_stderr(0, "Executing external script: %s\n", cmd); ++ ++ if ((ret = ngx_ssl_cache_read_pstream((char *)cmd, buf, bufsize)) != 0){ ++ return -1; ++ } ++ ++ return strlen(buf); ++} +diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c +index 80046d6a4165..d4aa313f083d 100644 +--- a/src/http/modules/ngx_http_grpc_module.c ++++ b/src/http/modules/ngx_http_grpc_module.c +@@ -5088,7 +5088,7 @@ ngx_http_grpc_set_ssl(ngx_conf_t *cf, ngx_http_grpc_loc_conf_t *glcf) + if (ngx_ssl_certificate(cf, glcf->upstream.ssl, + &glcf->upstream.ssl_certificate->value, + &glcf->upstream.ssl_certificate_key->value, +- glcf->upstream.ssl_passwords) ++ glcf->upstream.ssl_passwords, NULL) + != NGX_OK) + { + return NGX_ERROR; +diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c +index 0778ec728d50..686168986001 100644 +--- a/src/http/modules/ngx_http_proxy_module.c ++++ b/src/http/modules/ngx_http_proxy_module.c +@@ -5349,7 +5349,7 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *plcf) + if (ngx_ssl_certificate(cf, plcf->upstream.ssl, + &plcf->upstream.ssl_certificate->value, + &plcf->upstream.ssl_certificate_key->value, +- plcf->upstream.ssl_passwords) ++ plcf->upstream.ssl_passwords, NULL) + != NGX_OK) + { + return NGX_ERROR; +diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c +index 320d1ee044f2..47b84103a311 100644 +--- a/src/http/modules/ngx_http_ssl_module.c ++++ b/src/http/modules/ngx_http_ssl_module.c +@@ -21,6 +21,8 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c, + #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" + #define NGX_DEFAULT_ECDH_CURVE "auto" + ++static ngx_str_t ngx_ssl_server_null = ngx_string(NGX_SSL_SERVER_NULL); ++ + #define NGX_HTTP_ALPN_PROTOS "\x08http/1.1\x08http/1.0\x08http/0.9" + + +@@ -61,6 +63,9 @@ static ngx_int_t ngx_http_ssl_quic_compat_init(ngx_conf_t *cf, + ngx_http_conf_addr_t *addr); + #endif + ++static char *ngx_conf_set_pass_phrase_dialog(ngx_conf_t *cf, ngx_command_t *cmd, ++ void *conf); ++ + + static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = { + { ngx_string("SSLv2"), NGX_SSL_SSLv2 }, +@@ -299,6 +304,13 @@ static ngx_command_t ngx_http_ssl_commands[] = { + offsetof(ngx_http_ssl_srv_conf_t, reject_handshake), + NULL }, + ++ { ngx_string("ssl_pass_phrase_dialog"), ++ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ++ ngx_conf_set_pass_phrase_dialog, ++ NGX_HTTP_SRV_CONF_OFFSET, ++ offsetof(ngx_http_ssl_srv_conf_t, pass_phrase_dialog), ++ NULL }, ++ + ngx_null_command + }; + +@@ -618,6 +630,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf) + * sscf->ocsp_responder = { 0, NULL }; + * sscf->stapling_file = { 0, NULL }; + * sscf->stapling_responder = { 0, NULL }; ++ * sscf->pass_phrase_dialog = NULL; + */ + + sscf->prefer_server_ciphers = NGX_CONF_UNSET; +@@ -649,6 +662,8 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + { + ngx_http_ssl_srv_conf_t *prev = parent; + ngx_http_ssl_srv_conf_t *conf = child; ++ ngx_http_core_srv_conf_t *cscf; ++ ngx_ssl_ppdialog_conf_t dlg; + + ngx_pool_cleanup_t *cln; + +@@ -705,6 +720,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + ngx_conf_merge_str_value(conf->stapling_responder, + prev->stapling_responder, ""); + ++ ngx_conf_merge_str_value(conf->pass_phrase_dialog, ++ prev->pass_phrase_dialog, NGX_SSL_PASS_PHRASE_DEFAULT_VAL); ++ + conf->ssl.log = cf->log; + + if (conf->certificates) { +@@ -737,6 +755,30 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + cln->handler = ngx_ssl_cleanup_ctx; + cln->data = &conf->ssl; + ++ /** directive format: ssl_pass_phrase_dialog builtin|exec:filepath */ ++ if (ngx_strncasecmp(conf->pass_phrase_dialog.data, (u_char *)"exec:", 5) == 0){ ++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0, ++ "ssl_pass_phrase_dialog config directive SET: %s ", conf->pass_phrase_dialog.data); ++ } else if (ngx_strncasecmp(conf->pass_phrase_dialog.data, (u_char *)NGX_SSL_PASS_PHRASE_DEFAULT_VAL, ++ sizeof(NGX_SSL_PASS_PHRASE_DEFAULT_VAL)) != 0){ ++ ++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0, ++ "ssl_pass_phrase_dialog config directive accepts only the following " ++ "values: %s | exec:filepath", NGX_SSL_PASS_PHRASE_DEFAULT_VAL); ++ ++ return NGX_CONF_ERROR; ++ } ++ ++ cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module); ++ ++ dlg.data = &conf->pass_phrase_dialog; ++ if (cscf->server_name.len != 0) { ++ dlg.server = &cscf->server_name; ++ } else { ++ dlg.server = &ngx_ssl_server_null; ++ } ++ ++ + #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + + if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx, +@@ -787,7 +829,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + /* configure certificates */ + + if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, +- conf->certificate_keys, conf->passwords) ++ conf->certificate_keys, conf->passwords, &dlg) + != NGX_OK) + { + return NGX_CONF_ERROR; +@@ -1437,6 +1479,32 @@ ngx_http_ssl_init(ngx_conf_t *cf) + return NGX_OK; + } + ++static char * ++ngx_conf_set_pass_phrase_dialog(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ++{ ++ ngx_http_ssl_srv_conf_t *sscf = conf; ++ ngx_str_t *value; ++ ++ if (sscf->pass_phrase_dialog.data){ ++ return "is duplicate"; ++ } ++ ++ value = cf->args->elts; ++ ++ sscf->pass_phrase_dialog = value[1]; ++ ++ if (sscf->pass_phrase_dialog.len == 0) { ++ return NGX_CONF_OK; ++ } else if (sscf->pass_phrase_dialog.len > NGX_SSL_PASS_PHRASE_ARG_MAX_LEN) { ++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0, ++ "ssl_pass_phrase_dialog argument length exceeded maximum possible length: %d", ++ NGX_SSL_PASS_PHRASE_ARG_MAX_LEN); ++ ++ return NGX_CONF_ERROR; ++ } ++ ++ return NGX_CONF_OK; ++} + + #if (NGX_QUIC_OPENSSL_COMPAT) + +diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h +index 8650fab9376c..798cdda4c5ec 100644 +--- a/src/http/modules/ngx_http_ssl_module.h ++++ b/src/http/modules/ngx_http_ssl_module.h +@@ -64,6 +64,8 @@ typedef struct { + ngx_flag_t stapling_verify; + ngx_str_t stapling_file; + ngx_str_t stapling_responder; ++ ++ ngx_str_t pass_phrase_dialog; + } ngx_http_ssl_srv_conf_t; + + +diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c +index c1d0035cc8b5..406018e65728 100644 +--- a/src/http/modules/ngx_http_uwsgi_module.c ++++ b/src/http/modules/ngx_http_uwsgi_module.c +@@ -2696,7 +2696,7 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *uwcf) + if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, + &uwcf->upstream.ssl_certificate->value, + &uwcf->upstream.ssl_certificate_key->value, +- uwcf->upstream.ssl_passwords) ++ uwcf->upstream.ssl_passwords, NULL) + != NGX_OK) + { + return NGX_ERROR; +diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c +index 176e9c624724..a44bedcf77b6 100644 +--- a/src/mail/ngx_mail_ssl_module.c ++++ b/src/mail/ngx_mail_ssl_module.c +@@ -13,6 +13,7 @@ + #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" + #define NGX_DEFAULT_ECDH_CURVE "auto" + ++static ngx_str_t ngx_ssl_server_null = ngx_string(NGX_SSL_SERVER_NULL); + + #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation + static int ngx_mail_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, +@@ -33,6 +34,8 @@ static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, + static char *ngx_mail_ssl_conf_command_check(ngx_conf_t *cf, void *post, + void *data); + ++static char *ngx_conf_set_pass_phrase_dialog(ngx_conf_t *cf, ngx_command_t *cmd, ++ void *conf); + + static ngx_conf_enum_t ngx_mail_starttls_state[] = { + { ngx_string("off"), NGX_MAIL_STARTTLS_OFF }, +@@ -202,6 +205,13 @@ static ngx_command_t ngx_mail_ssl_commands[] = { + offsetof(ngx_mail_ssl_conf_t, conf_commands), + &ngx_mail_ssl_conf_command_post }, + ++ { ngx_string("ssl_pass_phrase_dialog"), ++ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, ++ ngx_conf_set_pass_phrase_dialog, ++ NGX_MAIL_SRV_CONF_OFFSET, ++ offsetof(ngx_mail_ssl_conf_t, pass_phrase_dialog), ++ NULL }, ++ + ngx_null_command + }; + +@@ -330,6 +340,8 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child) + { + ngx_mail_ssl_conf_t *prev = parent; + ngx_mail_ssl_conf_t *conf = child; ++ ngx_mail_core_srv_conf_t *cscf; ++ ngx_ssl_ppdialog_conf_t dlg; + + char *mode; + ngx_pool_cleanup_t *cln; +@@ -370,6 +382,8 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child) + + ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL); + ++ ngx_conf_merge_str_value(conf->pass_phrase_dialog, ++ prev->pass_phrase_dialog, NGX_SSL_PASS_PHRASE_DEFAULT_VAL); + + conf->ssl.log = cf->log; + +@@ -428,6 +442,29 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child) + cln->handler = ngx_ssl_cleanup_ctx; + cln->data = &conf->ssl; + ++ /** directive format: ssl_pass_phrase_dialog builtin|exec:filepath */ ++ if (ngx_strncasecmp(conf->pass_phrase_dialog.data, (u_char *)"exec:", 5) == 0){ ++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0, ++ "ssl_pass_phrase_dialog config directive SET: %s ", conf->pass_phrase_dialog.data); ++ } else if (ngx_strncasecmp(conf->pass_phrase_dialog.data, (u_char *)NGX_SSL_PASS_PHRASE_DEFAULT_VAL, ++ sizeof(NGX_SSL_PASS_PHRASE_DEFAULT_VAL)) != 0){ ++ ++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0, ++ "ssl_pass_phrase_dialog config directive accepts only the following " ++ "values: %s | exec:filepath", NGX_SSL_PASS_PHRASE_DEFAULT_VAL); ++ ++ return NGX_CONF_ERROR; ++ } ++ ++ cscf = ngx_mail_conf_get_module_srv_conf(cf, ngx_mail_core_module); ++ ++ dlg.data = &conf->pass_phrase_dialog; ++ if (cscf->server_name.len != 0) { ++ dlg.server = &cscf->server_name; ++ } else { ++ dlg.server = &ngx_ssl_server_null; ++ } ++ + #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation + SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_mail_ssl_alpn_select, NULL); + #endif +@@ -440,7 +477,7 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child) + } + + if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, +- conf->certificate_keys, conf->passwords) ++ conf->certificate_keys, conf->passwords, &dlg) + != NGX_OK) + { + return NGX_CONF_ERROR; +@@ -694,3 +731,30 @@ ngx_mail_ssl_conf_command_check(ngx_conf_t *cf, void *post, void *data) + return NGX_CONF_OK; + #endif + } ++ ++static char * ++ngx_conf_set_pass_phrase_dialog(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ++{ ++ ngx_mail_ssl_conf_t *sscf = conf; ++ ngx_str_t *value; ++ ++ if (sscf->pass_phrase_dialog.data){ ++ return "is duplicate"; ++ } ++ ++ value = cf->args->elts; ++ ++ sscf->pass_phrase_dialog = value[1]; ++ ++ if (sscf->pass_phrase_dialog.len == 0) { ++ return NGX_CONF_OK; ++ } else if (sscf->pass_phrase_dialog.len > NGX_SSL_PASS_PHRASE_ARG_MAX_LEN) { ++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0, ++ "ssl_pass_phrase_dialog argument length exceeded maximum possible length: %d", ++ NGX_SSL_PASS_PHRASE_ARG_MAX_LEN); ++ ++ return NGX_CONF_ERROR; ++ } ++ ++ return NGX_CONF_OK; ++} +diff --git a/src/mail/ngx_mail_ssl_module.h b/src/mail/ngx_mail_ssl_module.h +index c0eb6a38f834..02b4d4f8f72b 100644 +--- a/src/mail/ngx_mail_ssl_module.h ++++ b/src/mail/ngx_mail_ssl_module.h +@@ -56,6 +56,8 @@ typedef struct { + + u_char *file; + ngx_uint_t line; ++ ++ ngx_str_t pass_phrase_dialog; + } ngx_mail_ssl_conf_t; + + +diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c +index 6e51585f6e1f..3110b272952a 100644 +--- a/src/stream/ngx_stream_proxy_module.c ++++ b/src/stream/ngx_stream_proxy_module.c +@@ -2479,7 +2479,7 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, ngx_stream_proxy_srv_conf_t *pscf) + if (ngx_ssl_certificate(cf, pscf->ssl, + &pscf->ssl_certificate->value, + &pscf->ssl_certificate_key->value, +- pscf->ssl_passwords) ++ pscf->ssl_passwords, NULL) + != NGX_OK) + { + return NGX_ERROR; +diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c +index ea0b112b883c..63b49f1d56b9 100644 +--- a/src/stream/ngx_stream_ssl_module.c ++++ b/src/stream/ngx_stream_ssl_module.c +@@ -17,6 +17,8 @@ typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c, + #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" + #define NGX_DEFAULT_ECDH_CURVE "auto" + ++#define NGX_SSL_STREAM_NAME "NGX_STREAM_SSL_MODULE" ++static ngx_str_t ngx_ssl_stream_default_name = ngx_string(NGX_SSL_STREAM_NAME); + + static ngx_int_t ngx_stream_ssl_handler(ngx_stream_session_t *s); + static ngx_int_t ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, +@@ -61,6 +63,9 @@ static char *ngx_stream_ssl_alpn(ngx_conf_t *cf, ngx_command_t *cmd, + static char *ngx_stream_ssl_conf_command_check(ngx_conf_t *cf, void *post, + void *data); + ++static char *ngx_conf_set_pass_phrase_dialog(ngx_conf_t *cf, ngx_command_t *cmd, ++ void *conf); ++ + static ngx_int_t ngx_stream_ssl_init(ngx_conf_t *cf); + + +@@ -301,6 +306,13 @@ static ngx_command_t ngx_stream_ssl_commands[] = { + 0, + NULL }, + ++ { ngx_string("ssl_pass_phrase_dialog"), ++ NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1, ++ ngx_conf_set_pass_phrase_dialog, ++ NGX_STREAM_SRV_CONF_OFFSET, ++ offsetof(ngx_stream_ssl_srv_conf_t, pass_phrase_dialog), ++ NULL }, ++ + ngx_null_command + }; + +@@ -902,6 +914,7 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + { + ngx_stream_ssl_srv_conf_t *prev = parent; + ngx_stream_ssl_srv_conf_t *conf = child; ++ ngx_ssl_ppdialog_conf_t dlg; + + ngx_pool_cleanup_t *cln; + +@@ -947,6 +960,9 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + + ngx_conf_merge_ptr_value(conf->conf_commands, prev->conf_commands, NULL); + ++ ngx_conf_merge_str_value(conf->pass_phrase_dialog, prev->pass_phrase_dialog, ++ NGX_SSL_PASS_PHRASE_DEFAULT_VAL); ++ + ngx_conf_merge_uint_value(conf->ocsp, prev->ocsp, 0); + ngx_conf_merge_str_value(conf->ocsp_responder, prev->ocsp_responder, ""); + ngx_conf_merge_ptr_value(conf->ocsp_cache_zone, +@@ -990,6 +1006,22 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + cln->handler = ngx_ssl_cleanup_ctx; + cln->data = &conf->ssl; + ++ /** directive format: ssl_pass_phrase_dialog builtin|exec:filepath */ ++ if (ngx_strncasecmp(conf->pass_phrase_dialog.data, (u_char *)"exec:", 5) == 0){ ++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0, ++ "ssl_pass_phrase_dialog config directive SET: %s ", conf->pass_phrase_dialog.data); ++ } else if (ngx_strncasecmp(conf->pass_phrase_dialog.data, (u_char *)NGX_SSL_PASS_PHRASE_DEFAULT_VAL, ++ sizeof(NGX_SSL_PASS_PHRASE_DEFAULT_VAL)) != 0){ ++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0, ++ "ssl_pass_phrase_dialog config directive accepts only the following " ++ "values: %s | exec:filepath", NGX_SSL_PASS_PHRASE_DEFAULT_VAL); ++ ++ return NGX_CONF_ERROR; ++ } ++ ++ dlg.data = &conf->pass_phrase_dialog; ++ dlg.server = &ngx_ssl_stream_default_name; ++ + #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx, + ngx_stream_ssl_servername); +@@ -1034,7 +1066,7 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + /* configure certificates */ + + if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, +- conf->certificate_keys, conf->passwords) ++ conf->certificate_keys, conf->passwords, &dlg) + != NGX_OK) + { + return NGX_CONF_ERROR; +@@ -1716,3 +1748,30 @@ ngx_stream_ssl_init(ngx_conf_t *cf) + + return NGX_OK; + } ++ ++static char * ++ngx_conf_set_pass_phrase_dialog(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ++{ ++ ngx_stream_ssl_srv_conf_t *sscf = conf; ++ ngx_str_t *value; ++ ++ if (sscf->pass_phrase_dialog.data){ ++ return "is duplicate"; ++ } ++ ++ value = cf->args->elts; ++ ++ sscf->pass_phrase_dialog = value[1]; ++ ++ if (sscf->pass_phrase_dialog.len == 0) { ++ return NGX_CONF_OK; ++ } else if (sscf->pass_phrase_dialog.len > NGX_SSL_PASS_PHRASE_ARG_MAX_LEN) { ++ ngx_log_error(NGX_LOG_EMERG, cf->log, 0, ++ "ssl_pass_phrase_dialog argument length exceeded maximum possible length: %d", ++ NGX_SSL_PASS_PHRASE_ARG_MAX_LEN); ++ ++ return NGX_CONF_ERROR; ++ } ++ ++ return NGX_CONF_OK; ++} +diff --git a/src/stream/ngx_stream_ssl_module.h b/src/stream/ngx_stream_ssl_module.h +index ffa03a6f3439..3dbbca7dcce8 100644 +--- a/src/stream/ngx_stream_ssl_module.h ++++ b/src/stream/ngx_stream_ssl_module.h +@@ -56,6 +56,8 @@ typedef struct { + ngx_flag_t session_tickets; + ngx_array_t *session_ticket_keys; + ++ ngx_str_t pass_phrase_dialog; ++ + ngx_uint_t ocsp; + ngx_str_t ocsp_responder; + ngx_shm_zone_t *ocsp_cache_zone; +-- +2.52.0 diff --git a/SPECS/nginx/0004-Disable-ENGINE-support.patch b/SPECS/nginx/0004-Disable-ENGINE-support.patch new file mode 100644 index 00000000000..8c2dbf28d5e --- /dev/null +++ b/SPECS/nginx/0004-Disable-ENGINE-support.patch @@ -0,0 +1,99 @@ +From 0b9485b645b487d08ed3ab38e94d433112553d67 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= +Date: Tue, 2 Jul 2024 18:29:18 +0200 +Subject: [PATCH 4/5] Disable ENGINE support + +--- + auto/options | 3 +++ + configure | 4 ++++ + src/event/ngx_event_openssl.c | 4 ++-- + src/event/ngx_event_openssl.h | 2 +- + src/event/ngx_event_openssl_cache.c | 2 +- + 5 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/auto/options b/auto/options +index 6a6e990a0f6b..3cc983dc68a2 100644 +--- a/auto/options ++++ b/auto/options +@@ -45,6 +45,8 @@ USE_THREADS=NO + + NGX_FILE_AIO=NO + ++NGX_SSL_NO_ENGINE=NO ++ + QUIC_BPF=NO + + HTTP=YES +@@ -373,6 +375,7 @@ use the \"--with-mail_ssl_module\" option instead" + + --with-openssl=*) OPENSSL="$value" ;; + --with-openssl-opt=*) OPENSSL_OPT="$value" ;; ++ --without-engine) NGX_SSL_NO_ENGINE=YES ;; + + --with-md5=*) + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +diff --git a/configure b/configure +index 5b88ebb4cbe8..3a2129e499fc 100755 +--- a/configure ++++ b/configure +@@ -104,6 +104,10 @@ have=NGX_HTTP_UWSGI_TEMP_PATH value="\"$NGX_HTTP_UWSGI_TEMP_PATH\"" + have=NGX_HTTP_SCGI_TEMP_PATH value="\"$NGX_HTTP_SCGI_TEMP_PATH\"" + . auto/define + ++if [ $NGX_SSL_NO_ENGINE = YES ]; then ++ have=NGX_SSL_NO_ENGINE . auto/have ++fi ++ + . auto/make + . auto/lib/make + . auto/install +diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c +index fb6a5e950504..0b58d1383457 100644 +--- a/src/event/ngx_event_openssl.c ++++ b/src/event/ngx_event_openssl.c +@@ -5981,7 +5981,7 @@ ngx_openssl_create_conf(ngx_cycle_t *cycle) + static char * + ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) + { +-#ifndef OPENSSL_NO_ENGINE ++#if !defined(OPENSSL_NO_ENGINE) && !defined(NGX_SSL_NO_ENGINE) + + ngx_openssl_conf_t *oscf = conf; + +@@ -6032,7 +6032,7 @@ ngx_openssl_exit(ngx_cycle_t *cycle) + #if OPENSSL_VERSION_NUMBER < 0x10100003L + + EVP_cleanup(); +-#ifndef OPENSSL_NO_ENGINE ++#if !defined(OPENSSL_NO_ENGINE) && !defined(NGX_SSL_NO_ENGINE) + ENGINE_cleanup(); + #endif + +diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h +index 43bddc7be736..7ea2ad751e2b 100644 +--- a/src/event/ngx_event_openssl.h ++++ b/src/event/ngx_event_openssl.h +@@ -22,7 +22,7 @@ + #ifndef OPENSSL_NO_DH + #include + #endif +-#ifndef OPENSSL_NO_ENGINE ++#if !defined(OPENSSL_NO_ENGINE) && !defined(NGX_SSL_NO_ENGINE) + #include + #endif + #include +diff --git a/src/event/ngx_event_openssl_cache.c b/src/event/ngx_event_openssl_cache.c +index 83ddbbaeb97e..b2df0941f5c1 100644 +--- a/src/event/ngx_event_openssl_cache.c ++++ b/src/event/ngx_event_openssl_cache.c +@@ -694,7 +694,7 @@ ngx_ssl_cache_pkey_create(ngx_ssl_cache_key_t *id, char **err, void *data) + + if (id->type == NGX_SSL_CACHE_ENGINE) { + +-#ifndef OPENSSL_NO_ENGINE ++#if !defined(OPENSSL_NO_ENGINE) && !defined(NGX_SSL_NO_ENGINE) + + u_char *p, *last; + ENGINE *engine; +-- +2.52.0 diff --git a/SPECS/nginx/0005-Compile-perl-module-with-O2.patch b/SPECS/nginx/0005-Compile-perl-module-with-O2.patch new file mode 100644 index 00000000000..5b76595fb26 --- /dev/null +++ b/SPECS/nginx/0005-Compile-perl-module-with-O2.patch @@ -0,0 +1,25 @@ +From 8c38540d5ab78c856b07d799015cb0c94d2f9a55 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= +Date: Wed, 31 Jul 2024 17:47:10 +0200 +Subject: [PATCH 5/5] Compile perl module with O2 + +--- + src/http/modules/perl/Makefile.PL | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/http/modules/perl/Makefile.PL b/src/http/modules/perl/Makefile.PL +index 7edadcb3d53e..2ebb7c4c6eb4 100644 +--- a/src/http/modules/perl/Makefile.PL ++++ b/src/http/modules/perl/Makefile.PL +@@ -14,7 +14,7 @@ WriteMakefile( + AUTHOR => 'Igor Sysoev', + + CCFLAGS => "$ENV{NGX_PM_CFLAGS}", +- OPTIMIZE => '-O', ++ OPTIMIZE => '-O2', + + LDDLFLAGS => "$ENV{NGX_PM_LDFLAGS}", + +-- +2.52.0 + diff --git a/SPECS/nginx/CVE-2024-7347.patch b/SPECS/nginx/CVE-2024-7347.patch deleted file mode 100644 index bbfad40576a..00000000000 --- a/SPECS/nginx/CVE-2024-7347.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 7362d01658b61184108c21278443910da68f93b4 Mon Sep 17 00:00:00 2001 -From: Roman Arutyunyan -Date: Mon, 12 Aug 2024 18:20:43 +0400 -Subject: [PATCH] Mp4: fixed buffer underread while updating stsz atom. - -While cropping an stsc atom in ngx_http_mp4_crop_stsc_data(), a 32-bit integer -overflow could happen, which could result in incorrect seeking and a very large -value stored in "samples". This resulted in a large invalid value of -trak->end_chunk_samples. This value is further used to calculate the value of -trak->end_chunk_samples_size in ngx_http_mp4_update_stsz_atom(). While doing -this, a large invalid value of trak->end_chunk_samples could result in reading -memory before stsz atom start. This could potentially result in a segfault. ---- - src/http/modules/ngx_http_mp4_module.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c -index 03175dea21..1cd017c274 100644 ---- a/src/http/modules/ngx_http_mp4_module.c -+++ b/src/http/modules/ngx_http_mp4_module.c -@@ -3099,7 +3099,8 @@ static ngx_int_t - ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, - ngx_http_mp4_trak_t *trak, ngx_uint_t start) - { -- uint32_t start_sample, chunk, samples, id, next_chunk, n, -+ uint64_t n; -+ uint32_t start_sample, chunk, samples, id, next_chunk, - prev_samples; - ngx_buf_t *data, *buf; - ngx_uint_t entries, target_chunk, chunk_samples; -@@ -3160,7 +3161,7 @@ ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, - "samples:%uD, id:%uD", - start_sample, chunk, next_chunk - chunk, samples, id); - -- n = (next_chunk - chunk) * samples; -+ n = (uint64_t) (next_chunk - chunk) * samples; - - if (start_sample < n) { - goto found; -@@ -3182,7 +3183,7 @@ ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, - "sample:%uD, chunk:%uD, chunks:%uD, samples:%uD", - start_sample, chunk, next_chunk - chunk, samples); - -- n = (next_chunk - chunk) * samples; -+ n = (uint64_t) (next_chunk - chunk) * samples; - - if (start_sample > n) { - ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, -From 88955b1044ef38315b77ad1a509d63631a790a0f Mon Sep 17 00:00:00 2001 -From: Roman Arutyunyan -Date: Mon, 12 Aug 2024 18:20:45 +0400 -Subject: [PATCH] Mp4: rejecting unordered chunks in stsc atom. - -Unordered chunks could result in trak->end_chunk smaller than trak->start_chunk -in ngx_http_mp4_crop_stsc_data(). Later in ngx_http_mp4_update_stco_atom() -this caused buffer overread while trying to calculate trak->end_offset. ---- - src/http/modules/ngx_http_mp4_module.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c -index 1cd017c274..041ad263b5 100644 ---- a/src/http/modules/ngx_http_mp4_module.c -+++ b/src/http/modules/ngx_http_mp4_module.c -@@ -3156,6 +3156,13 @@ ngx_http_mp4_crop_stsc_data(ngx_http_mp4_file_t *mp4, - - next_chunk = ngx_mp4_get_32value(entry->chunk); - -+ if (next_chunk < chunk) { -+ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, -+ "unordered mp4 stsc chunks in \"%s\"", -+ mp4->file.name.data); -+ return NGX_ERROR; -+ } -+ - ngx_log_debug5(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, - "sample:%uD, chunk:%uD, chunks:%uD, " - "samples:%uD, id:%uD", diff --git a/SPECS/nginx/CVE-2025-23419.patch b/SPECS/nginx/CVE-2025-23419.patch deleted file mode 100644 index eac62698187..00000000000 --- a/SPECS/nginx/CVE-2025-23419.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 117654149dea3a5ff72eae8c9ff2484c35f77732 Mon Sep 17 00:00:00 2001 -From: Sergey Kandaurov -Date: Wed, 22 Jan 2025 18:55:44 +0400 -Subject: [PATCH] SNI: added restriction for TLSv1.3 cross-SNI session - resumption. - -In OpenSSL, session resumption always happens in the default SSL context, -prior to invoking the SNI callback. Further, unlike in TLSv1.2 and older -protocols, SSL_get_servername() returns values received in the resumption -handshake, which may be different from the value in the initial handshake. -Notably, this makes the restriction added in b720f650b insufficient for -sessions resumed with different SNI server name. - -Considering the example from b720f650b, previously, a client was able to -request example.org by presenting a certificate for example.org, then to -resume and request example.com. - -The fix is to reject handshakes resumed with a different server name, if -verification of client certificates is enabled in a corresponding server -configuration. ---- - src/http/ngx_http_request.c | 27 +++++++++++++++++++++++++-- - 1 file changed, 25 insertions(+), 2 deletions(-) - -diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c -index 3cca57c..9593b7f 100644 ---- a/src/http/ngx_http_request.c -+++ b/src/http/ngx_http_request.c -@@ -932,6 +932,31 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) - goto done; - } - -+ sscf = ngx_http_get_module_srv_conf(cscf->ctx, ngx_http_ssl_module); -+ -+#if (defined TLS1_3_VERSION \ -+ && !defined LIBRESSL_VERSION_NUMBER && !defined OPENSSL_IS_BORINGSSL) -+ -+ /* -+ * SSL_SESSION_get0_hostname() is only available in OpenSSL 1.1.1+, -+ * but servername being negotiated in every TLSv1.3 handshake -+ * is only returned in OpenSSL 1.1.1+ as well -+ */ -+ -+ if (sscf->verify) { -+ const char *hostname; -+ -+ hostname = SSL_SESSION_get0_hostname(SSL_get0_session(ssl_conn)); -+ -+ if (hostname != NULL && ngx_strcmp(hostname, servername) != 0) { -+ c->ssl->handshake_rejected = 1; -+ *ad = SSL_AD_ACCESS_DENIED; -+ return SSL_TLSEXT_ERR_ALERT_FATAL; -+ } -+ } -+ -+#endif -+ - hc->ssl_servername = ngx_palloc(c->pool, sizeof(ngx_str_t)); - if (hc->ssl_servername == NULL) { - goto error; -@@ -945,8 +970,6 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg) - - ngx_set_connection_log(c, clcf->error_log); - -- sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module); -- - c->ssl->buffer_size = sscf->buffer_size; - - if (sscf->ssl.ctx) { --- -2.34.1 - diff --git a/SPECS/nginx/CVE-2025-53859.patch b/SPECS/nginx/CVE-2025-53859.patch deleted file mode 100644 index 8f670b314eb..00000000000 --- a/SPECS/nginx/CVE-2025-53859.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 26aa1129e6d5920c7327991d693edda3aaa9abf3 Mon Sep 17 00:00:00 2001 -From: Azure Linux Security Servicing Account -Date: Tue, 19 Aug 2025 08:05:07 +0000 -Subject: [PATCH] CVE-2025-53859 - -Signed-off-by: Azure Linux Security Servicing Account -Upstream-reference: AI Backport of https://nginx.org/download/patch.2025.smtp.txt ---- - src/mail/ngx_mail_handler.c | 38 +++++++++++++++++++++---------------- - 1 file changed, 22 insertions(+), 16 deletions(-) - -diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c -index 1167df3..d3be7f3 100644 ---- a/src/mail/ngx_mail_handler.c -+++ b/src/mail/ngx_mail_handler.c -@@ -523,7 +523,7 @@ ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c) - 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 @@ ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n) - return NGX_MAIL_PARSE_INVALID_COMMAND; - } - -- s->login.data = p; -+ pos = p; - - while (p < last && *p) { p++; } - -@@ -565,7 +565,8 @@ ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n) - 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_int_t - 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_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c, - 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 @@ ngx_mail_auth_login_password(ngx_mail_session_t *s, ngx_connection_t *c) - "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_int_t - 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; - --- -2.45.4 - diff --git a/SPECS/nginx/nginx.signatures.json b/SPECS/nginx/nginx.signatures.json index fa4c0b10854..d3664c56162 100644 --- a/SPECS/nginx/nginx.signatures.json +++ b/SPECS/nginx/nginx.signatures.json @@ -1,8 +1,8 @@ { "Signatures": { - "nginx-1.25.4.tar.gz": "760729901acbaa517996e681ee6ea259032985e37c2768beef80df3a877deed9", - "nginx-njs-0.8.3.tar.gz": "5e1341ee8c1dfce420ea6456475dafa7d5f4b9aed310faca32597cf4d221cfe0", + "nginx-1.28.1.tar.gz": "40e7a0916d121e8905ef50f2a738b675599e42b2224a582dd938603fed15788e", + "nginx-njs-0.9.4.tar.gz": "7b3a9f14b0f09311d9031c2a252cb0e23c06baac2e586a7d12c75aa6cba4ca0e", "nginx-tests.tgz": "5847fdc454543df77e07026e7de737f9e7ff093c8ce4afcbc2093a64e570ff83", "nginx.service": "73a1321ae35eafc4e02614cde224fc0bf20ceba97f969b3373dd73c15c22a0e1" } -} \ No newline at end of file +} diff --git a/SPECS/nginx/nginx.spec b/SPECS/nginx/nginx.spec index 9c73c8fc85f..4ac4362d0ec 100644 --- a/SPECS/nginx/nginx.spec +++ b/SPECS/nginx/nginx.spec @@ -1,12 +1,12 @@ %global nginx_user nginx -%global njs_version 0.8.3 +%global njs_version 0.9.4 Summary: High-performance HTTP server and reverse proxy Name: nginx # Currently on "stable" version of nginx from https://nginx.org/en/download.html. # Note: Stable versions are even (1.20), mainline versions are odd (1.21) -Version: 1.25.4 -Release: 6%{?dist} +Version: 1.28.1 +Release: 1%{?dist} License: BSD-2-Clause Vendor: Microsoft Corporation Distribution: Azure Linux @@ -20,9 +20,11 @@ Source2: https://github.com/nginx/njs/archive/refs/tags/%{njs_version}.ta Source3: nginx-tests.tgz %endif -Patch0: CVE-2024-7347.patch -Patch1: CVE-2025-23419.patch -Patch2: CVE-2025-53859.patch +Patch1: 0001-remove-Werror-in-upstream-build-scripts.patch +Patch2: 0002-fix-PIDFile-handling.patch +Patch3: 0003-Add-SSL-passphrase-dialog.patch +Patch4: 0004-Disable-ENGINE-support.patch +Patch5: 0005-Compile-perl-module-with-O2.patch BuildRequires: libxml2-devel BuildRequires: libxslt-devel BuildRequires: openssl-devel @@ -165,6 +167,9 @@ rm -rf nginx-tests %dir %{_sysconfdir}/%{name} %changelog +* Thu Oct 23 2025 Sandeep Karambelkar - 1.28.0-1 +- Upgrade to 1.28.0 Upstream Stable Version + * Tue Sep 09 2025 Mayank Singh - 1.25.4-6 - Enable stream ssl preread module diff --git a/cgmanifest.json b/cgmanifest.json index 96f09b14c79..055ecde9e8d 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -14382,8 +14382,8 @@ "type": "other", "other": { "name": "nginx", - "version": "1.25.4", - "downloadUrl": "https://nginx.org/download/nginx-1.25.4.tar.gz" + "version": "1.28.1", + "downloadUrl": "https://nginx.org/download/nginx-1.28.1.tar.gz" } } },