Mercurial > hg > nginx
diff src/event/ngx_event_openssl.c @ 7463:180df83473a4
SSL: passwords support for dynamic certificate loading.
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.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 25 Feb 2019 16:42:23 +0300 |
parents | a68799465b19 |
children | 6708bec13757 |
line wrap: on
line diff
--- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -771,7 +771,7 @@ ngx_ssl_load_certificate_key(ngx_pool_t 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 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) {