forked from rpms/nginx
Compare commits
No commits in common. 'c9' and 'c9-beta-stream-1.22' have entirely different histories.
c9
...
c9-beta-st
@ -1,2 +1,2 @@
|
|||||||
SOURCES/nginx-1.20.1.tar.gz
|
SOURCES/nginx-1.22.1.tar.gz
|
||||||
SOURCES/nginx-logo.png
|
SOURCES/nginx-logo.png
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
6b4ab4eff3c617e133819f43fdfc14708e593a79 SOURCES/nginx-1.20.1.tar.gz
|
45a89797f7c789287c7f663811efbbd19e84f154 SOURCES/nginx-1.22.1.tar.gz
|
||||||
e28dd656984cc2894d8124c5278789c656f6a9cb SOURCES/nginx-logo.png
|
e28dd656984cc2894d8124c5278789c656f6a9cb SOURCES/nginx-logo.png
|
||||||
|
@ -1,96 +0,0 @@
|
|||||||
From ee8ea4f1c88a0393206769cd30a545dc3375f868 Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= <luhliari@redhat.com>
|
|
||||||
Date: Wed, 2 Feb 2022 20:14:55 +0100
|
|
||||||
Subject: [PATCH] Fix ALPACA security issue
|
|
||||||
|
|
||||||
---
|
|
||||||
src/mail/ngx_mail.h | 3 +++
|
|
||||||
src/mail/ngx_mail_core_module.c | 10 ++++++++++
|
|
||||||
src/mail/ngx_mail_handler.c | 15 ++++++++++++++-
|
|
||||||
3 files changed, 27 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h
|
|
||||||
index b865a3b..76cae37 100644
|
|
||||||
--- a/src/mail/ngx_mail.h
|
|
||||||
+++ b/src/mail/ngx_mail.h
|
|
||||||
@@ -115,6 +115,8 @@ typedef struct {
|
|
||||||
ngx_msec_t timeout;
|
|
||||||
ngx_msec_t resolver_timeout;
|
|
||||||
|
|
||||||
+ ngx_uint_t max_errors;
|
|
||||||
+
|
|
||||||
ngx_str_t server_name;
|
|
||||||
|
|
||||||
u_char *file_name;
|
|
||||||
@@ -231,6 +233,7 @@ typedef struct {
|
|
||||||
ngx_uint_t command;
|
|
||||||
ngx_array_t args;
|
|
||||||
|
|
||||||
+ ngx_uint_t errors;
|
|
||||||
ngx_uint_t login_attempt;
|
|
||||||
|
|
||||||
/* used to parse POP3/IMAP/SMTP command */
|
|
||||||
diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c
|
|
||||||
index 4083124..115671c 100644
|
|
||||||
--- a/src/mail/ngx_mail_core_module.c
|
|
||||||
+++ b/src/mail/ngx_mail_core_module.c
|
|
||||||
@@ -85,6 +85,13 @@ static ngx_command_t ngx_mail_core_commands[] = {
|
|
||||||
offsetof(ngx_mail_core_srv_conf_t, resolver_timeout),
|
|
||||||
NULL },
|
|
||||||
|
|
||||||
+ { ngx_string("max_errors"),
|
|
||||||
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
|
|
||||||
+ ngx_conf_set_num_slot,
|
|
||||||
+ NGX_MAIL_SRV_CONF_OFFSET,
|
|
||||||
+ offsetof(ngx_mail_core_srv_conf_t, max_errors),
|
|
||||||
+ NULL },
|
|
||||||
+
|
|
||||||
ngx_null_command
|
|
||||||
};
|
|
||||||
|
|
||||||
@@ -163,6 +170,8 @@ ngx_mail_core_create_srv_conf(ngx_conf_t *cf)
|
|
||||||
cscf->timeout = NGX_CONF_UNSET_MSEC;
|
|
||||||
cscf->resolver_timeout = NGX_CONF_UNSET_MSEC;
|
|
||||||
|
|
||||||
+ cscf->max_errors = NGX_CONF_UNSET_UINT;
|
|
||||||
+
|
|
||||||
cscf->resolver = NGX_CONF_UNSET_PTR;
|
|
||||||
|
|
||||||
cscf->file_name = cf->conf_file->file.name.data;
|
|
||||||
@@ -182,6 +191,7 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|
||||||
ngx_conf_merge_msec_value(conf->resolver_timeout, prev->resolver_timeout,
|
|
||||||
30000);
|
|
||||||
|
|
||||||
+ ngx_conf_merge_uint_value(conf->max_errors, prev->max_errors, 5);
|
|
||||||
|
|
||||||
ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
|
|
||||||
|
|
||||||
diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c
|
|
||||||
index 0aaa0e7..71b8151 100644
|
|
||||||
--- a/src/mail/ngx_mail_handler.c
|
|
||||||
+++ b/src/mail/ngx_mail_handler.c
|
|
||||||
@@ -871,7 +871,20 @@ ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c)
|
|
||||||
return NGX_MAIL_PARSE_INVALID_COMMAND;
|
|
||||||
}
|
|
||||||
|
|
||||||
- if (rc == NGX_IMAP_NEXT || rc == NGX_MAIL_PARSE_INVALID_COMMAND) {
|
|
||||||
+ if (rc == NGX_MAIL_PARSE_INVALID_COMMAND) {
|
|
||||||
+
|
|
||||||
+ s->errors++;
|
|
||||||
+
|
|
||||||
+ if (s->errors >= cscf->max_errors) {
|
|
||||||
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
|
||||||
+ "client sent too many invalid commands");
|
|
||||||
+ s->quit = 1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return rc;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (rc == NGX_IMAP_NEXT) {
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
|||||||
From b6aa9504cdfb6391d895dcbddc87b9260ea6968c Mon Sep 17 00:00:00 2001
|
|
||||||
From: =?UTF-8?q?Lubo=C5=A1=20Uhliarik?= <luhliari@redhat.com>
|
|
||||||
Date: Wed, 11 Oct 2023 09:59:23 +0200
|
|
||||||
Subject: [PATCH] CVE-2023-44487 - HTTP/2: per-iteration stream handling limit.
|
|
||||||
|
|
||||||
To ensure that attempts to flood servers with many streams are detected
|
|
||||||
early, a limit of no more than 2 * max_concurrent_streams new streams per one
|
|
||||||
event loop iteration was introduced. This limit is applied even if
|
|
||||||
max_concurrent_streams is not yet reached - for example, if corresponding
|
|
||||||
streams are handled synchronously or reset.
|
|
||||||
|
|
||||||
Further, refused streams are now limited to maximum of max_concurrent_streams
|
|
||||||
and 100, similarly to priority_limit initial value, providing some tolerance
|
|
||||||
to clients trying to open several streams at the connection start, yet
|
|
||||||
low tolerance to flooding attempts.
|
|
||||||
---
|
|
||||||
src/http/v2/ngx_http_v2.c | 15 +++++++++++++++
|
|
||||||
src/http/v2/ngx_http_v2.h | 2 ++
|
|
||||||
2 files changed, 17 insertions(+)
|
|
||||||
|
|
||||||
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
|
|
||||||
index 3611a2e..291677a 100644
|
|
||||||
--- a/src/http/v2/ngx_http_v2.c
|
|
||||||
+++ b/src/http/v2/ngx_http_v2.c
|
|
||||||
@@ -361,6 +361,7 @@ ngx_http_v2_read_handler(ngx_event_t *rev)
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 read handler");
|
|
||||||
|
|
||||||
h2c->blocked = 1;
|
|
||||||
+ h2c->new_streams = 0;
|
|
||||||
|
|
||||||
if (c->close) {
|
|
||||||
c->close = 0;
|
|
||||||
@@ -1320,6 +1321,14 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|
||||||
goto rst_stream;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ if (h2c->new_streams++ >= 2 * h2scf->concurrent_streams) {
|
|
||||||
+ ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
|
||||||
+ "client sent too many streams at once");
|
|
||||||
+
|
|
||||||
+ status = NGX_HTTP_V2_REFUSED_STREAM;
|
|
||||||
+ goto rst_stream;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (!h2c->settings_ack
|
|
||||||
&& !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG)
|
|
||||||
&& h2scf->preread_size < NGX_HTTP_V2_DEFAULT_WINDOW)
|
|
||||||
@@ -1385,6 +1394,12 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|
||||||
|
|
||||||
rst_stream:
|
|
||||||
|
|
||||||
+ if (h2c->refused_streams++ > ngx_max(h2scf->concurrent_streams, 100)) {
|
|
||||||
+ ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
|
||||||
+ "client sent too many refused streams");
|
|
||||||
+ return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_NO_ERROR);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, status) != NGX_OK) {
|
|
||||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
|
|
||||||
}
|
|
||||||
diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h
|
|
||||||
index 3492297..6a7aaa6 100644
|
|
||||||
--- a/src/http/v2/ngx_http_v2.h
|
|
||||||
+++ b/src/http/v2/ngx_http_v2.h
|
|
||||||
@@ -125,6 +125,8 @@ struct ngx_http_v2_connection_s {
|
|
||||||
ngx_uint_t processing;
|
|
||||||
ngx_uint_t frames;
|
|
||||||
ngx_uint_t idle;
|
|
||||||
+ ngx_uint_t new_streams;
|
|
||||||
+ ngx_uint_t refused_streams;
|
|
||||||
ngx_uint_t priority_limit;
|
|
||||||
|
|
||||||
ngx_uint_t pushing;
|
|
||||||
--
|
|
||||||
2.31.1
|
|
||||||
|
|
@ -0,0 +1,754 @@
|
|||||||
|
diff --git a/contrib/vim/syntax/nginx.vim b/contrib/vim/syntax/nginx.vim
|
||||||
|
index 7d587fc..15b21e2 100644
|
||||||
|
--- a/contrib/vim/syntax/nginx.vim
|
||||||
|
+++ b/contrib/vim/syntax/nginx.vim
|
||||||
|
@@ -617,6 +617,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 104e8da..8cf777e 100644
|
||||||
|
--- a/src/event/ngx_event_openssl.c
|
||||||
|
+++ b/src/event/ngx_event_openssl.c
|
||||||
|
@@ -9,9 +9,8 @@
|
||||||
|
#include <ngx_core.h>
|
||||||
|
#include <ngx_event.h>
|
||||||
|
|
||||||
|
-
|
||||||
|
#define NGX_SSL_PASSWORD_BUFFER_SIZE 4096
|
||||||
|
-
|
||||||
|
+#define NGX_PASS_PHRASE_ARG_MAX_LEN 255
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ngx_uint_t engine; /* unsigned engine:1; */
|
||||||
|
@@ -20,8 +19,8 @@ typedef struct {
|
||||||
|
|
||||||
|
static X509 *ngx_ssl_load_certificate(ngx_pool_t *pool, char **err,
|
||||||
|
ngx_str_t *cert, STACK_OF(X509) **chain);
|
||||||
|
-static EVP_PKEY *ngx_ssl_load_certificate_key(ngx_pool_t *pool, char **err,
|
||||||
|
- ngx_str_t *key, ngx_array_t *passwords);
|
||||||
|
+static EVP_PKEY *ngx_ssl_load_certificate_key(ngx_pool_t *pool,
|
||||||
|
+ char **err, ngx_str_t *key, ngx_array_t *passwords, ngx_ssl_ppdialog_conf_t *dlg);
|
||||||
|
static int ngx_ssl_password_callback(char *buf, int size, int rwflag,
|
||||||
|
void *userdata);
|
||||||
|
static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
|
||||||
|
@@ -88,6 +87,12 @@ static time_t ngx_ssl_parse_time(
|
||||||
|
#endif
|
||||||
|
ASN1_TIME *asn1time, ngx_log_t *log);
|
||||||
|
|
||||||
|
+static int ngx_ssl_read_pstream(const char *cmd, char *buf,
|
||||||
|
+ ngx_int_t bufsize);
|
||||||
|
+
|
||||||
|
+static int ngx_ssl_pass_phrase_callback(char *buf, int bufsize,
|
||||||
|
+ int rwflag, void *u);
|
||||||
|
+
|
||||||
|
static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
|
||||||
|
static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
|
||||||
|
static void ngx_openssl_exit(ngx_cycle_t *cycle);
|
||||||
|
@@ -398,7 +403,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;
|
||||||
|
@@ -408,7 +413,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;
|
||||||
|
@@ -421,12 +426,13 @@ 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;
|
||||||
|
EVP_PKEY *pkey;
|
||||||
|
STACK_OF(X509) *chain;
|
||||||
|
+ EVP_PKEY *pubkey;
|
||||||
|
|
||||||
|
x509 = ngx_ssl_load_certificate(cf->pool, &err, cert, &chain);
|
||||||
|
if (x509 == NULL) {
|
||||||
|
@@ -516,8 +522,19 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- pkey = ngx_ssl_load_certificate_key(cf->pool, &err, key, passwords);
|
||||||
|
- if (pkey == NULL) {
|
||||||
|
+ pubkey = X509_get_pubkey(x509);
|
||||||
|
+ if (!pubkey){
|
||||||
|
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
|
||||||
|
+ "X509_get_pubkey() failed");
|
||||||
|
+ return NGX_ERROR;
|
||||||
|
+ }
|
||||||
|
+ dlg->cryptosystem = EVP_PKEY_get_base_id(pubkey);
|
||||||
|
+ EVP_PKEY_free(pubkey);
|
||||||
|
+
|
||||||
|
+ pkey = ngx_ssl_load_certificate_key(cf->pool, &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",
|
||||||
|
@@ -587,7 +604,7 @@ ngx_ssl_connection_certificate(ngx_connection_t *c, ngx_pool_t *pool,
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- pkey = ngx_ssl_load_certificate_key(pool, &err, key, passwords);
|
||||||
|
+ pkey = ngx_ssl_load_certificate_key(pool, &err, key, passwords, NULL);
|
||||||
|
if (pkey == NULL) {
|
||||||
|
if (err != NULL) {
|
||||||
|
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
|
||||||
|
@@ -700,10 +717,81 @@ ngx_ssl_load_certificate(ngx_pool_t *pool, char **err, ngx_str_t *cert,
|
||||||
|
return x509;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+ngx_ssl_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_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_read_pstream((char *)cmd, buf, bufsize)) != 0){
|
||||||
|
+ return -1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return strlen(buf);
|
||||||
|
+}
|
||||||
|
|
||||||
|
static EVP_PKEY *
|
||||||
|
-ngx_ssl_load_certificate_key(ngx_pool_t *pool, char **err,
|
||||||
|
- ngx_str_t *key, ngx_array_t *passwords)
|
||||||
|
+ngx_ssl_load_certificate_key(ngx_pool_t *pool, char **err, ngx_str_t *key, ngx_array_t *passwords, ngx_ssl_ppdialog_conf_t *dlg)
|
||||||
|
{
|
||||||
|
BIO *bio;
|
||||||
|
EVP_PKEY *pkey;
|
||||||
|
@@ -791,11 +879,26 @@ ngx_ssl_load_certificate_key(ngx_pool_t *pool, char **err,
|
||||||
|
tries = 1;
|
||||||
|
pwd = NULL;
|
||||||
|
cb = NULL;
|
||||||
|
+
|
||||||
|
+ /** directive format: ssl_pass_phrase_dialog buildin|exec:filepath */
|
||||||
|
+ if (dlg && ngx_strncasecmp(dlg->data->data, (u_char *)"exec:", 5) == 0){
|
||||||
|
+ pwd = (void *)dlg;
|
||||||
|
+ cb = ngx_ssl_pass_phrase_callback;
|
||||||
|
+ } else {
|
||||||
|
+ pwd = NULL;
|
||||||
|
+ cb = NULL;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
- for ( ;; ) {
|
||||||
|
+ /* skip decrypting private keys in config test phase to avoid
|
||||||
|
+ asking for pass phase twice */
|
||||||
|
+ if (ngx_test_config){
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ for ( ;; ) {
|
||||||
|
pkey = PEM_read_bio_PrivateKey(bio, NULL, cb, pwd);
|
||||||
|
+
|
||||||
|
if (pkey != NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
|
||||||
|
index 860ea26..41f4501 100644
|
||||||
|
--- a/src/event/ngx_event_openssl.h
|
||||||
|
+++ b/src/event/ngx_event_openssl.h
|
||||||
|
@@ -74,9 +74,19 @@
|
||||||
|
#define ERR_peek_error_data(d, f) ERR_peek_error_line_data(NULL, NULL, d, f)
|
||||||
|
#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;
|
||||||
|
@@ -84,7 +94,6 @@ struct ngx_ssl_s {
|
||||||
|
size_t buffer_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
-
|
||||||
|
struct ngx_ssl_connection_s {
|
||||||
|
ngx_ssl_conn_t *connection;
|
||||||
|
SSL_CTX *session_ctx;
|
||||||
|
@@ -184,9 +193,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_array_t *passwords);
|
||||||
|
|
||||||
|
diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c
|
||||||
|
index dfe49c5..904263d 100644
|
||||||
|
--- a/src/http/modules/ngx_http_grpc_module.c
|
||||||
|
+++ b/src/http/modules/ngx_http_grpc_module.c
|
||||||
|
@@ -4983,7 +4983,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 9cc202c..2c938d7 100644
|
||||||
|
--- a/src/http/modules/ngx_http_proxy_module.c
|
||||||
|
+++ b/src/http/modules/ngx_http_proxy_module.c
|
||||||
|
@@ -5032,7 +5032,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 4c4a598..a147054 100644
|
||||||
|
--- a/src/http/modules/ngx_http_ssl_module.c
|
||||||
|
+++ b/src/http/modules/ngx_http_ssl_module.c
|
||||||
|
@@ -17,8 +17,9 @@ 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_HTTP_ALPN_PROTOS "\x08http/1.1\x08http/1.0\x08http/0.9"
|
||||||
|
+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"
|
||||||
|
|
||||||
|
#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation
|
||||||
|
static int ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn,
|
||||||
|
@@ -53,6 +54,9 @@ static char *ngx_http_ssl_conf_command_check(ngx_conf_t *cf, void *post,
|
||||||
|
|
||||||
|
static ngx_int_t ngx_http_ssl_init(ngx_conf_t *cf);
|
||||||
|
|
||||||
|
+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 },
|
||||||
|
@@ -296,6 +300,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
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -555,7 +566,7 @@ ngx_http_ssl_add_variables(ngx_conf_t *cf)
|
||||||
|
static void *
|
||||||
|
ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
|
||||||
|
{
|
||||||
|
- ngx_http_ssl_srv_conf_t *sscf;
|
||||||
|
+ ngx_http_ssl_srv_conf_t *sscf;
|
||||||
|
|
||||||
|
sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssl_srv_conf_t));
|
||||||
|
if (sscf == NULL) {
|
||||||
|
@@ -577,6 +588,8 @@ 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->enable = NGX_CONF_UNSET;
|
||||||
|
@@ -608,6 +621,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;
|
||||||
|
|
||||||
|
@@ -674,6 +689,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->enable) {
|
||||||
|
@@ -736,6 +754,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 buildin|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,
|
||||||
|
@@ -786,7 +828,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;
|
||||||
|
@@ -1335,3 +1377,31 @@ 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;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h
|
||||||
|
index 7ab0f7e..2f83d75 100644
|
||||||
|
--- a/src/http/modules/ngx_http_ssl_module.h
|
||||||
|
+++ b/src/http/modules/ngx_http_ssl_module.h
|
||||||
|
@@ -67,6 +67,8 @@ typedef struct {
|
||||||
|
|
||||||
|
u_char *file;
|
||||||
|
ngx_uint_t line;
|
||||||
|
+
|
||||||
|
+ 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 e4f721b..61efa99 100644
|
||||||
|
--- a/src/http/modules/ngx_http_uwsgi_module.c
|
||||||
|
+++ b/src/http/modules/ngx_http_uwsgi_module.c
|
||||||
|
@@ -2564,7 +2564,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 28737ac..728181d 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,
|
||||||
|
@@ -35,6 +36,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 },
|
||||||
|
@@ -216,6 +219,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
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -345,6 +355,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;
|
||||||
|
@@ -388,6 +400,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;
|
||||||
|
|
||||||
|
@@ -449,6 +463,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 buildin|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
|
||||||
|
@@ -461,7 +498,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;
|
||||||
|
@@ -745,3 +782,32 @@ 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 a0a6113..3d87d50 100644
|
||||||
|
--- a/src/mail/ngx_mail_ssl_module.h
|
||||||
|
+++ b/src/mail/ngx_mail_ssl_module.h
|
||||||
|
@@ -57,6 +57,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 ed275c0..1747aed 100644
|
||||||
|
--- a/src/stream/ngx_stream_proxy_module.c
|
||||||
|
+++ b/src/stream/ngx_stream_proxy_module.c
|
||||||
|
@@ -2305,7 +2305,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 1ba1825..ba70547 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,
|
||||||
|
@@ -57,6 +59,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);
|
||||||
|
|
||||||
|
|
||||||
|
@@ -226,6 +231,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_conf_t, pass_phrase_dialog),
|
||||||
|
+ NULL },
|
||||||
|
+
|
||||||
|
ngx_null_command
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -690,6 +702,7 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
|
{
|
||||||
|
ngx_stream_ssl_conf_t *prev = parent;
|
||||||
|
ngx_stream_ssl_conf_t *conf = child;
|
||||||
|
+ ngx_ssl_ppdialog_conf_t dlg;
|
||||||
|
|
||||||
|
ngx_pool_cleanup_t *cln;
|
||||||
|
|
||||||
|
@@ -732,6 +745,8 @@ ngx_stream_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;
|
||||||
|
|
||||||
|
@@ -779,6 +794,23 @@ ngx_stream_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 buildin|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);
|
||||||
|
@@ -823,7 +855,7 @@ ngx_stream_ssl_merge_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;
|
||||||
|
@@ -1209,3 +1241,31 @@ 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_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 e7c825e..d80daa4 100644
|
||||||
|
--- a/src/stream/ngx_stream_ssl_module.h
|
||||||
|
+++ b/src/stream/ngx_stream_ssl_module.h
|
||||||
|
@@ -56,6 +56,8 @@ typedef struct {
|
||||||
|
|
||||||
|
u_char *file;
|
||||||
|
ngx_uint_t line;
|
||||||
|
+
|
||||||
|
+ ngx_str_t pass_phrase_dialog;
|
||||||
|
} ngx_stream_ssl_conf_t;
|
||||||
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQEcBAABCAAGBQJgrPDQAAoJEFIKmZOhwFL4dlIH/RFvUn4wiazXVujdm1df2/Q5
|
|
||||||
b+NVlr+O9WZ2Mb35dooOshG/G2wVjI95Cd5NU6svulJ05uv6tGgHA0CUZP6PLqIm
|
|
||||||
4os5QcgbEbfdDbfQEw7wyc831DqiBPwzk/xt954vsqwzX3mkXvUNTEYpynguwN1J
|
|
||||||
2iMb/bFRSlLZkKGbKOmLMO7iav0r88qtpmQIzG1mFTDg3leH0q3hEMAJl7pIicYd
|
|
||||||
Of3+/EHnM8CXORtA1q6YTLbcHAzhSmjdrMyw+RQGQkxoPtdj9vwL4Z6Wk8+6dDK7
|
|
||||||
dVBaiKp80tDM/iJizPbkbrBVbnR/9W48+QBC7tmOJMuj2c1Q/kvwJg9CLyHlqCU=
|
|
||||||
=tPti
|
|
||||||
-----END PGP SIGNATURE-----
|
|
@ -0,0 +1,14 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQHEBAABCAAuFiEEE8gqY7YDV2FW4wpOoOqYG2aw2WcFAmNPwgkQHGsucGF2bG92
|
||||||
|
QGY1LmNvbQAKCRCg6pgbZrDZZ521C/9stdPkXnyO46ZOHEBK0UhPXPLcLaeUPOj3
|
||||||
|
LZz0mS1pLeQrWVJcSzjn4x1VA1Mo24wJ2PDHVLDlz+wrGDWj+YQh0Pzt81AV/VWl
|
||||||
|
gDfbJ9ROfaXNUBMPWwKH5fxlocYYyYM3SlN/nwx5EDR8uB0mnSUPS+TV8SxW+252
|
||||||
|
IfGv8xtX4diEowVCCpkvqDkbEwWy4GQia1KHd0krfvi6Aha3NNNRkjyPUNrf42A5
|
||||||
|
lmqxp1PwKnb6IYEkoYYtehKARuFjY9d5rsaQSXzNXYnRqQYOzSB42wcxJCu/Lw2S
|
||||||
|
MfzY0b5j6PdVziBXQr/Bk8ge7sVT30oKD+LnKKL/CWHnFveykOAuvuihsD4VS1iB
|
||||||
|
1Ns2Pjdofzw7+OzlVWJ4SBlm6HPCXBSfg15jkXinDdU/lKT6Gv0n4Y4i3GWkdFKe
|
||||||
|
JuuDcvhM2dAl8PV9YrlaVK/1InHNb7jsksKLZ0MxOEj05QSOWT5kOAbQCRfKAc8/
|
||||||
|
S8kd48v9BSgC+PZjS6AG3+sM2YjwQvo=
|
||||||
|
=Ww/y
|
||||||
|
-----END PGP SIGNATURE-----
|
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
exec /bin/systemd-ask-password "Enter TLS private key passphrase for $1 ($2) : "
|
@ -0,0 +1,147 @@
|
|||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
=t1B0
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
Loading…
Reference in new issue