]> git.kaiwu.me - nginx.git/commitdiff
SSL: passwords support for dynamic certificate loading.
authorMaxim Dounin <mdounin@mdounin.ru>
Mon, 25 Feb 2019 13:42:23 +0000 (16:42 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Mon, 25 Feb 2019 13:42:23 +0000 (16:42 +0300)
Passwords have to be copied to the configuration pool to be used
at runtime.  Also, to prevent blocking on stdin (with "daemon off;")
an empty password list is provided.

To make things simpler, password handling was modified to allow
an empty array (with 0 elements and elts set to NULL) as an equivalent
of an array with 1 empty password.

src/event/ngx_event_openssl.c
src/event/ngx_event_openssl.h
src/http/modules/ngx_http_ssl_module.c
src/http/ngx_http_request.c

index 1d1fa09d81806cbc91eb9c34494cc8713e7fdc19..c6eb65c64d1daf08bf15f46844f9a07b6b10e19f 100644 (file)
@@ -771,7 +771,7 @@ ngx_ssl_load_certificate_key(ngx_pool_t *pool, char **err,
             break;
         }
 
-        if (--tries) {
+        if (tries-- > 1) {
             ERR_clear_error();
             (void) BIO_reset(bio);
             pwd++;
@@ -800,6 +800,10 @@ ngx_ssl_password_callback(char *buf, int size, int rwflag, void *userdata)
         return 0;
     }
 
+    if (pwd == NULL) {
+        return 0;
+    }
+
     if (pwd->len > (size_t) size) {
         ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
                       "password is truncated to %d bytes", size);
@@ -1215,6 +1219,69 @@ cleanup:
 }
 
 
+ngx_array_t *
+ngx_ssl_preserve_passwords(ngx_conf_t *cf, ngx_array_t *passwords)
+{
+    ngx_str_t           *opwd, *pwd;
+    ngx_uint_t           i;
+    ngx_array_t         *pwds;
+    ngx_pool_cleanup_t  *cln;
+    static ngx_array_t   empty_passwords;
+
+    if (passwords == NULL) {
+
+        /*
+         * If there are no passwords, an empty array is used
+         * to make sure OpenSSL's default password callback
+         * won't block on reading from stdin.
+         */
+
+        return &empty_passwords;
+    }
+
+    /*
+     * Passwords are normally allocated from the temporary pool
+     * and cleared after parsing configuration.  To be used at
+     * runtime they have to be copied to the configuration pool.
+     */
+
+    pwds = ngx_array_create(cf->pool, passwords->nelts, sizeof(ngx_str_t));
+    if (pwds == NULL) {
+        return NULL;
+    }
+
+    cln = ngx_pool_cleanup_add(cf->pool, 0);
+    if (cln == NULL) {
+        return NULL;
+    }
+
+    cln->handler = ngx_ssl_passwords_cleanup;
+    cln->data = pwds;
+
+    opwd = passwords->elts;
+
+    for (i = 0; i < passwords->nelts; i++) {
+
+        pwd = ngx_array_push(pwds);
+        if (pwd == NULL) {
+            return NULL;
+        }
+
+        pwd->len = opwd[i].len;
+        pwd->data = ngx_pnalloc(cf->pool, pwd->len);
+
+        if (pwd->data == NULL) {
+            pwds->nelts--;
+            return NULL;
+        }
+
+        ngx_memcpy(pwd->data, opwd[i].data, opwd[i].len);
+    }
+
+    return pwds;
+}
+
+
 static void
 ngx_ssl_passwords_cleanup(void *data)
 {
index 3c91c848b39126e67e9c15787e67f33e419de892..21ed19e2dc59911b36da9ce13210fa9db06088f9 100644 (file)
@@ -183,6 +183,8 @@ ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
 RSA *ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
     int key_length);
 ngx_array_t *ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file);
+ngx_array_t *ngx_ssl_preserve_passwords(ngx_conf_t *cf,
+    ngx_array_t *passwords);
 ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
 ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name);
 ngx_int_t ngx_ssl_early_data(ngx_conf_t *cf, ngx_ssl_t *ssl,
index 759762c5a81e0e7f78eb90c6bc63009e1a70ec65..3134f0ec85eb1f9a607c41f303cc1df26d1f3968 100644 (file)
@@ -935,6 +935,11 @@ found:
         }
     }
 
+    conf->passwords = ngx_ssl_preserve_passwords(cf, conf->passwords);
+    if (conf->passwords == NULL) {
+        return NGX_ERROR;
+    }
+
     return NGX_OK;
 }
 
index 4e14d3b10cc23b56d850395207b82fc20cefdf3e..81d546a867f21b824df7af6dc2089eff766946f9 100644 (file)
@@ -995,7 +995,8 @@ ngx_http_ssl_certificate(ngx_ssl_conn_t *ssl_conn, void *arg)
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                        "ssl key: \"%s\"", key.data);
 
-        if (ngx_ssl_connection_certificate(c, r->pool, &cert, &key, NULL)
+        if (ngx_ssl_connection_certificate(c, r->pool, &cert, &key,
+                                           sscf->passwords)
             != NGX_OK)
         {
             goto failed;