comparison 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
comparison
equal deleted inserted replaced
7462:be2af41d3620 7463:180df83473a4
769 pkey = PEM_read_bio_PrivateKey(bio, NULL, cb, pwd); 769 pkey = PEM_read_bio_PrivateKey(bio, NULL, cb, pwd);
770 if (pkey != NULL) { 770 if (pkey != NULL) {
771 break; 771 break;
772 } 772 }
773 773
774 if (--tries) { 774 if (tries-- > 1) {
775 ERR_clear_error(); 775 ERR_clear_error();
776 (void) BIO_reset(bio); 776 (void) BIO_reset(bio);
777 pwd++; 777 pwd++;
778 continue; 778 continue;
779 } 779 }
795 ngx_str_t *pwd = userdata; 795 ngx_str_t *pwd = userdata;
796 796
797 if (rwflag) { 797 if (rwflag) {
798 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, 798 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
799 "ngx_ssl_password_callback() is called for encryption"); 799 "ngx_ssl_password_callback() is called for encryption");
800 return 0;
801 }
802
803 if (pwd == NULL) {
800 return 0; 804 return 0;
801 } 805 }
802 806
803 if (pwd->len > (size_t) size) { 807 if (pwd->len > (size_t) size) {
804 ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, 808 ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
1210 } 1214 }
1211 1215
1212 ngx_explicit_memzero(buf, NGX_SSL_PASSWORD_BUFFER_SIZE); 1216 ngx_explicit_memzero(buf, NGX_SSL_PASSWORD_BUFFER_SIZE);
1213 1217
1214 return passwords; 1218 return passwords;
1219 }
1220
1221
1222 ngx_array_t *
1223 ngx_ssl_preserve_passwords(ngx_conf_t *cf, ngx_array_t *passwords)
1224 {
1225 ngx_str_t *opwd, *pwd;
1226 ngx_uint_t i;
1227 ngx_array_t *pwds;
1228 ngx_pool_cleanup_t *cln;
1229 static ngx_array_t empty_passwords;
1230
1231 if (passwords == NULL) {
1232
1233 /*
1234 * If there are no passwords, an empty array is used
1235 * to make sure OpenSSL's default password callback
1236 * won't block on reading from stdin.
1237 */
1238
1239 return &empty_passwords;
1240 }
1241
1242 /*
1243 * Passwords are normally allocated from the temporary pool
1244 * and cleared after parsing configuration. To be used at
1245 * runtime they have to be copied to the configuration pool.
1246 */
1247
1248 pwds = ngx_array_create(cf->pool, passwords->nelts, sizeof(ngx_str_t));
1249 if (pwds == NULL) {
1250 return NULL;
1251 }
1252
1253 cln = ngx_pool_cleanup_add(cf->pool, 0);
1254 if (cln == NULL) {
1255 return NULL;
1256 }
1257
1258 cln->handler = ngx_ssl_passwords_cleanup;
1259 cln->data = pwds;
1260
1261 opwd = passwords->elts;
1262
1263 for (i = 0; i < passwords->nelts; i++) {
1264
1265 pwd = ngx_array_push(pwds);
1266 if (pwd == NULL) {
1267 return NULL;
1268 }
1269
1270 pwd->len = opwd[i].len;
1271 pwd->data = ngx_pnalloc(cf->pool, pwd->len);
1272
1273 if (pwd->data == NULL) {
1274 pwds->nelts--;
1275 return NULL;
1276 }
1277
1278 ngx_memcpy(pwd->data, opwd[i].data, opwd[i].len);
1279 }
1280
1281 return pwds;
1215 } 1282 }
1216 1283
1217 1284
1218 static void 1285 static void
1219 ngx_ssl_passwords_cleanup(void *data) 1286 ngx_ssl_passwords_cleanup(void *data)