Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.13.12 ]​[ nginx-1.12.2 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_stream.h>
0011 
0012 
0013 typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
0014     ngx_pool_t *pool, ngx_str_t *s);
0015 
0016 
0017 #define NGX_DEFAULT_CIPHERS     "HIGH:!aNULL:!MD5"
0018 #define NGX_DEFAULT_ECDH_CURVE  "auto"
0019 
0020 
0021 static ngx_int_t ngx_stream_ssl_handler(ngx_stream_session_t *s);
0022 static ngx_int_t ngx_stream_ssl_init_connection(ngx_ssl_t *ssl,
0023     ngx_connection_t *c);
0024 static void ngx_stream_ssl_handshake_handler(ngx_connection_t *c);
0025 static ngx_int_t ngx_stream_ssl_static_variable(ngx_stream_session_t *s,
0026     ngx_stream_variable_value_t *v, uintptr_t data);
0027 static ngx_int_t ngx_stream_ssl_variable(ngx_stream_session_t *s,
0028     ngx_stream_variable_value_t *v, uintptr_t data);
0029 
0030 static ngx_int_t ngx_stream_ssl_add_variables(ngx_conf_t *cf);
0031 static void *ngx_stream_ssl_create_conf(ngx_conf_t *cf);
0032 static char *ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent,
0033     void *child);
0034 
0035 static char *ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd,
0036     void *conf);
0037 static char *ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
0038     void *conf);
0039 static ngx_int_t ngx_stream_ssl_init(ngx_conf_t *cf);
0040 
0041 
0042 static ngx_conf_bitmask_t  ngx_stream_ssl_protocols[] = {
0043     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
0044     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
0045     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
0046     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
0047     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
0048     { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
0049     { ngx_null_string, 0 }
0050 };
0051 
0052 
0053 static ngx_conf_enum_t  ngx_stream_ssl_verify[] = {
0054     { ngx_string("off"), 0 },
0055     { ngx_string("on"), 1 },
0056     { ngx_string("optional"), 2 },
0057     { ngx_string("optional_no_ca"), 3 },
0058     { ngx_null_string, 0 }
0059 };
0060 
0061 
0062 static ngx_command_t  ngx_stream_ssl_commands[] = {
0063 
0064     { ngx_string("ssl_handshake_timeout"),
0065       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0066       ngx_conf_set_msec_slot,
0067       NGX_STREAM_SRV_CONF_OFFSET,
0068       offsetof(ngx_stream_ssl_conf_t, handshake_timeout),
0069       NULL },
0070 
0071     { ngx_string("ssl_certificate"),
0072       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0073       ngx_conf_set_str_array_slot,
0074       NGX_STREAM_SRV_CONF_OFFSET,
0075       offsetof(ngx_stream_ssl_conf_t, certificates),
0076       NULL },
0077 
0078     { ngx_string("ssl_certificate_key"),
0079       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0080       ngx_conf_set_str_array_slot,
0081       NGX_STREAM_SRV_CONF_OFFSET,
0082       offsetof(ngx_stream_ssl_conf_t, certificate_keys),
0083       NULL },
0084 
0085     { ngx_string("ssl_password_file"),
0086       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0087       ngx_stream_ssl_password_file,
0088       NGX_STREAM_SRV_CONF_OFFSET,
0089       0,
0090       NULL },
0091 
0092     { ngx_string("ssl_dhparam"),
0093       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0094       ngx_conf_set_str_slot,
0095       NGX_STREAM_SRV_CONF_OFFSET,
0096       offsetof(ngx_stream_ssl_conf_t, dhparam),
0097       NULL },
0098 
0099     { ngx_string("ssl_ecdh_curve"),
0100       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0101       ngx_conf_set_str_slot,
0102       NGX_STREAM_SRV_CONF_OFFSET,
0103       offsetof(ngx_stream_ssl_conf_t, ecdh_curve),
0104       NULL },
0105 
0106     { ngx_string("ssl_protocols"),
0107       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
0108       ngx_conf_set_bitmask_slot,
0109       NGX_STREAM_SRV_CONF_OFFSET,
0110       offsetof(ngx_stream_ssl_conf_t, protocols),
0111       &ngx_stream_ssl_protocols },
0112 
0113     { ngx_string("ssl_ciphers"),
0114       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0115       ngx_conf_set_str_slot,
0116       NGX_STREAM_SRV_CONF_OFFSET,
0117       offsetof(ngx_stream_ssl_conf_t, ciphers),
0118       NULL },
0119 
0120     { ngx_string("ssl_verify_client"),
0121       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0122       ngx_conf_set_enum_slot,
0123       NGX_STREAM_SRV_CONF_OFFSET,
0124       offsetof(ngx_stream_ssl_conf_t, verify),
0125       &ngx_stream_ssl_verify },
0126 
0127     { ngx_string("ssl_verify_depth"),
0128       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0129       ngx_conf_set_num_slot,
0130       NGX_STREAM_SRV_CONF_OFFSET,
0131       offsetof(ngx_stream_ssl_conf_t, verify_depth),
0132       NULL },
0133 
0134     { ngx_string("ssl_client_certificate"),
0135       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0136       ngx_conf_set_str_slot,
0137       NGX_STREAM_SRV_CONF_OFFSET,
0138       offsetof(ngx_stream_ssl_conf_t, client_certificate),
0139       NULL },
0140 
0141     { ngx_string("ssl_trusted_certificate"),
0142       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0143       ngx_conf_set_str_slot,
0144       NGX_STREAM_SRV_CONF_OFFSET,
0145       offsetof(ngx_stream_ssl_conf_t, trusted_certificate),
0146       NULL },
0147 
0148     { ngx_string("ssl_prefer_server_ciphers"),
0149       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0150       ngx_conf_set_flag_slot,
0151       NGX_STREAM_SRV_CONF_OFFSET,
0152       offsetof(ngx_stream_ssl_conf_t, prefer_server_ciphers),
0153       NULL },
0154 
0155     { ngx_string("ssl_session_cache"),
0156       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE12,
0157       ngx_stream_ssl_session_cache,
0158       NGX_STREAM_SRV_CONF_OFFSET,
0159       0,
0160       NULL },
0161 
0162     { ngx_string("ssl_session_tickets"),
0163       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
0164       ngx_conf_set_flag_slot,
0165       NGX_STREAM_SRV_CONF_OFFSET,
0166       offsetof(ngx_stream_ssl_conf_t, session_tickets),
0167       NULL },
0168 
0169     { ngx_string("ssl_session_ticket_key"),
0170       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0171       ngx_conf_set_str_array_slot,
0172       NGX_STREAM_SRV_CONF_OFFSET,
0173       offsetof(ngx_stream_ssl_conf_t, session_ticket_keys),
0174       NULL },
0175 
0176     { ngx_string("ssl_session_timeout"),
0177       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0178       ngx_conf_set_sec_slot,
0179       NGX_STREAM_SRV_CONF_OFFSET,
0180       offsetof(ngx_stream_ssl_conf_t, session_timeout),
0181       NULL },
0182 
0183     { ngx_string("ssl_crl"),
0184       NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
0185       ngx_conf_set_str_slot,
0186       NGX_STREAM_SRV_CONF_OFFSET,
0187       offsetof(ngx_stream_ssl_conf_t, crl),
0188       NULL },
0189 
0190       ngx_null_command
0191 };
0192 
0193 
0194 static ngx_stream_module_t  ngx_stream_ssl_module_ctx = {
0195     ngx_stream_ssl_add_variables,          /* preconfiguration */
0196     ngx_stream_ssl_init,                   /* postconfiguration */
0197 
0198     NULL,                                  /* create main configuration */
0199     NULL,                                  /* init main configuration */
0200 
0201     ngx_stream_ssl_create_conf,            /* create server configuration */
0202     ngx_stream_ssl_merge_conf              /* merge server configuration */
0203 };
0204 
0205 
0206 ngx_module_t  ngx_stream_ssl_module = {
0207     NGX_MODULE_V1,
0208     &ngx_stream_ssl_module_ctx,            /* module context */
0209     ngx_stream_ssl_commands,               /* module directives */
0210     NGX_STREAM_MODULE,                     /* module type */
0211     NULL,                                  /* init master */
0212     NULL,                                  /* init module */
0213     NULL,                                  /* init process */
0214     NULL,                                  /* init thread */
0215     NULL,                                  /* exit thread */
0216     NULL,                                  /* exit process */
0217     NULL,                                  /* exit master */
0218     NGX_MODULE_V1_PADDING
0219 };
0220 
0221 
0222 static ngx_stream_variable_t  ngx_stream_ssl_vars[] = {
0223 
0224     { ngx_string("ssl_protocol"), NULL, ngx_stream_ssl_static_variable,
0225       (uintptr_t) ngx_ssl_get_protocol, NGX_STREAM_VAR_CHANGEABLE, 0 },
0226 
0227     { ngx_string("ssl_cipher"), NULL, ngx_stream_ssl_static_variable,
0228       (uintptr_t) ngx_ssl_get_cipher_name, NGX_STREAM_VAR_CHANGEABLE, 0 },
0229 
0230     { ngx_string("ssl_ciphers"), NULL, ngx_stream_ssl_variable,
0231       (uintptr_t) ngx_ssl_get_ciphers, NGX_STREAM_VAR_CHANGEABLE, 0 },
0232 
0233     { ngx_string("ssl_curves"), NULL, ngx_stream_ssl_variable,
0234       (uintptr_t) ngx_ssl_get_curves, NGX_STREAM_VAR_CHANGEABLE, 0 },
0235 
0236     { ngx_string("ssl_session_id"), NULL, ngx_stream_ssl_variable,
0237       (uintptr_t) ngx_ssl_get_session_id, NGX_STREAM_VAR_CHANGEABLE, 0 },
0238 
0239     { ngx_string("ssl_session_reused"), NULL, ngx_stream_ssl_variable,
0240       (uintptr_t) ngx_ssl_get_session_reused, NGX_STREAM_VAR_CHANGEABLE, 0 },
0241 
0242     { ngx_string("ssl_server_name"), NULL, ngx_stream_ssl_variable,
0243       (uintptr_t) ngx_ssl_get_server_name, NGX_STREAM_VAR_CHANGEABLE, 0 },
0244 
0245     { ngx_string("ssl_client_cert"), NULL, ngx_stream_ssl_variable,
0246       (uintptr_t) ngx_ssl_get_certificate, NGX_STREAM_VAR_CHANGEABLE, 0 },
0247 
0248     { ngx_string("ssl_client_raw_cert"), NULL, ngx_stream_ssl_variable,
0249       (uintptr_t) ngx_ssl_get_raw_certificate,
0250       NGX_STREAM_VAR_CHANGEABLE, 0 },
0251 
0252     { ngx_string("ssl_client_escaped_cert"), NULL, ngx_stream_ssl_variable,
0253       (uintptr_t) ngx_ssl_get_escaped_certificate,
0254       NGX_STREAM_VAR_CHANGEABLE, 0 },
0255 
0256     { ngx_string("ssl_client_s_dn"), NULL, ngx_stream_ssl_variable,
0257       (uintptr_t) ngx_ssl_get_subject_dn, NGX_STREAM_VAR_CHANGEABLE, 0 },
0258 
0259     { ngx_string("ssl_client_i_dn"), NULL, ngx_stream_ssl_variable,
0260       (uintptr_t) ngx_ssl_get_issuer_dn, NGX_STREAM_VAR_CHANGEABLE, 0 },
0261 
0262     { ngx_string("ssl_client_serial"), NULL, ngx_stream_ssl_variable,
0263       (uintptr_t) ngx_ssl_get_serial_number, NGX_STREAM_VAR_CHANGEABLE, 0 },
0264 
0265     { ngx_string("ssl_client_fingerprint"), NULL, ngx_stream_ssl_variable,
0266       (uintptr_t) ngx_ssl_get_fingerprint, NGX_STREAM_VAR_CHANGEABLE, 0 },
0267 
0268     { ngx_string("ssl_client_verify"), NULL, ngx_stream_ssl_variable,
0269       (uintptr_t) ngx_ssl_get_client_verify, NGX_STREAM_VAR_CHANGEABLE, 0 },
0270 
0271     { ngx_string("ssl_client_v_start"), NULL, ngx_stream_ssl_variable,
0272       (uintptr_t) ngx_ssl_get_client_v_start, NGX_STREAM_VAR_CHANGEABLE, 0 },
0273 
0274     { ngx_string("ssl_client_v_end"), NULL, ngx_stream_ssl_variable,
0275       (uintptr_t) ngx_ssl_get_client_v_end, NGX_STREAM_VAR_CHANGEABLE, 0 },
0276 
0277     { ngx_string("ssl_client_v_remain"), NULL, ngx_stream_ssl_variable,
0278       (uintptr_t) ngx_ssl_get_client_v_remain, NGX_STREAM_VAR_CHANGEABLE, 0 },
0279 
0280       ngx_stream_null_variable
0281 };
0282 
0283 
0284 static ngx_str_t ngx_stream_ssl_sess_id_ctx = ngx_string("STREAM");
0285 
0286 
0287 static ngx_int_t
0288 ngx_stream_ssl_handler(ngx_stream_session_t *s)
0289 {
0290     long                    rc;
0291     X509                   *cert;
0292     ngx_int_t               rv;
0293     ngx_connection_t       *c;
0294     ngx_stream_ssl_conf_t  *sslcf;
0295 
0296     if (!s->ssl) {
0297         return NGX_OK;
0298     }
0299 
0300     c = s->connection;
0301 
0302     sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);
0303 
0304     if (c->ssl == NULL) {
0305         c->log->action = "SSL handshaking";
0306 
0307         if (sslcf->ssl.ctx == NULL) {
0308             ngx_log_error(NGX_LOG_ERR, c->log, 0,
0309                           "no \"ssl_certificate\" is defined "
0310                           "in server listening on SSL port");
0311             return NGX_ERROR;
0312         }
0313 
0314         rv = ngx_stream_ssl_init_connection(&sslcf->ssl, c);
0315 
0316         if (rv != NGX_OK) {
0317             return rv;
0318         }
0319     }
0320 
0321     if (sslcf->verify) {
0322         rc = SSL_get_verify_result(c->ssl->connection);
0323 
0324         if (rc != X509_V_OK
0325             && (sslcf->verify != 3 || !ngx_ssl_verify_error_optional(rc)))
0326         {
0327             ngx_log_error(NGX_LOG_INFO, c->log, 0,
0328                           "client SSL certificate verify error: (%l:%s)",
0329                           rc, X509_verify_cert_error_string(rc));
0330 
0331             ngx_ssl_remove_cached_session(c->ssl->session_ctx,
0332                                        (SSL_get0_session(c->ssl->connection)));
0333             return NGX_ERROR;
0334         }
0335 
0336         if (sslcf->verify == 1) {
0337             cert = SSL_get_peer_certificate(c->ssl->connection);
0338 
0339             if (cert == NULL) {
0340                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
0341                               "client sent no required SSL certificate");
0342 
0343                 ngx_ssl_remove_cached_session(c->ssl->session_ctx,
0344                                        (SSL_get0_session(c->ssl->connection)));
0345                 return NGX_ERROR;
0346             }
0347 
0348             X509_free(cert);
0349         }
0350     }
0351 
0352     return NGX_OK;
0353 }
0354 
0355 
0356 static ngx_int_t
0357 ngx_stream_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
0358 {
0359     ngx_int_t                    rc;
0360     ngx_stream_session_t        *s;
0361     ngx_stream_ssl_conf_t       *sslcf;
0362     ngx_stream_core_srv_conf_t  *cscf;
0363 
0364     s = c->data;
0365 
0366     cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
0367 
0368     if (cscf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
0369         return NGX_ERROR;
0370     }
0371 
0372     if (ngx_ssl_create_connection(ssl, c, 0) != NGX_OK) {
0373         return NGX_ERROR;
0374     }
0375 
0376     rc = ngx_ssl_handshake(c);
0377 
0378     if (rc == NGX_ERROR) {
0379         return NGX_ERROR;
0380     }
0381 
0382     if (rc == NGX_AGAIN) {
0383         sslcf = ngx_stream_get_module_srv_conf(s, ngx_stream_ssl_module);
0384 
0385         ngx_add_timer(c->read, sslcf->handshake_timeout);
0386 
0387         c->ssl->handler = ngx_stream_ssl_handshake_handler;
0388 
0389         return NGX_AGAIN;
0390     }
0391 
0392     /* rc == NGX_OK */
0393 
0394     return NGX_OK;
0395 }
0396 
0397 
0398 static void
0399 ngx_stream_ssl_handshake_handler(ngx_connection_t *c)
0400 {
0401     ngx_stream_session_t  *s;
0402 
0403     s = c->data;
0404 
0405     if (!c->ssl->handshaked) {
0406         ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
0407         return;
0408     }
0409 
0410     if (c->read->timer_set) {
0411         ngx_del_timer(c->read);
0412     }
0413 
0414     ngx_stream_core_run_phases(s);
0415 }
0416 
0417 
0418 static ngx_int_t
0419 ngx_stream_ssl_static_variable(ngx_stream_session_t *s,
0420     ngx_stream_variable_value_t *v, uintptr_t data)
0421 {
0422     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;
0423 
0424     size_t     len;
0425     ngx_str_t  str;
0426 
0427     if (s->connection->ssl) {
0428 
0429         (void) handler(s->connection, NULL, &str);
0430 
0431         v->data = str.data;
0432 
0433         for (len = 0; v->data[len]; len++) { /* void */ }
0434 
0435         v->len = len;
0436         v->valid = 1;
0437         v->no_cacheable = 0;
0438         v->not_found = 0;
0439 
0440         return NGX_OK;
0441     }
0442 
0443     v->not_found = 1;
0444 
0445     return NGX_OK;
0446 }
0447 
0448 
0449 static ngx_int_t
0450 ngx_stream_ssl_variable(ngx_stream_session_t *s,
0451     ngx_stream_variable_value_t *v, uintptr_t data)
0452 {
0453     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;
0454 
0455     ngx_str_t  str;
0456 
0457     if (s->connection->ssl) {
0458 
0459         if (handler(s->connection, s->connection->pool, &str) != NGX_OK) {
0460             return NGX_ERROR;
0461         }
0462 
0463         v->len = str.len;
0464         v->data = str.data;
0465 
0466         if (v->len) {
0467             v->valid = 1;
0468             v->no_cacheable = 0;
0469             v->not_found = 0;
0470 
0471             return NGX_OK;
0472         }
0473     }
0474 
0475     v->not_found = 1;
0476 
0477     return NGX_OK;
0478 }
0479 
0480 
0481 static ngx_int_t
0482 ngx_stream_ssl_add_variables(ngx_conf_t *cf)
0483 {
0484     ngx_stream_variable_t  *var, *v;
0485 
0486     for (v = ngx_stream_ssl_vars; v->name.len; v++) {
0487         var = ngx_stream_add_variable(cf, &v->name, v->flags);
0488         if (var == NULL) {
0489             return NGX_ERROR;
0490         }
0491 
0492         var->get_handler = v->get_handler;
0493         var->data = v->data;
0494     }
0495 
0496     return NGX_OK;
0497 }
0498 
0499 
0500 static void *
0501 ngx_stream_ssl_create_conf(ngx_conf_t *cf)
0502 {
0503     ngx_stream_ssl_conf_t  *scf;
0504 
0505     scf = ngx_pcalloc(cf->pool, sizeof(ngx_stream_ssl_conf_t));
0506     if (scf == NULL) {
0507         return NULL;
0508     }
0509 
0510     /*
0511      * set by ngx_pcalloc():
0512      *
0513      *     scf->protocols = 0;
0514      *     scf->dhparam = { 0, NULL };
0515      *     scf->ecdh_curve = { 0, NULL };
0516      *     scf->client_certificate = { 0, NULL };
0517      *     scf->trusted_certificate = { 0, NULL };
0518      *     scf->crl = { 0, NULL };
0519      *     scf->ciphers = { 0, NULL };
0520      *     scf->shm_zone = NULL;
0521      */
0522 
0523     scf->handshake_timeout = NGX_CONF_UNSET_MSEC;
0524     scf->certificates = NGX_CONF_UNSET_PTR;
0525     scf->certificate_keys = NGX_CONF_UNSET_PTR;
0526     scf->passwords = NGX_CONF_UNSET_PTR;
0527     scf->prefer_server_ciphers = NGX_CONF_UNSET;
0528     scf->verify = NGX_CONF_UNSET_UINT;
0529     scf->verify_depth = NGX_CONF_UNSET_UINT;
0530     scf->builtin_session_cache = NGX_CONF_UNSET;
0531     scf->session_timeout = NGX_CONF_UNSET;
0532     scf->session_tickets = NGX_CONF_UNSET;
0533     scf->session_ticket_keys = NGX_CONF_UNSET_PTR;
0534 
0535     return scf;
0536 }
0537 
0538 
0539 static char *
0540 ngx_stream_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
0541 {
0542     ngx_stream_ssl_conf_t *prev = parent;
0543     ngx_stream_ssl_conf_t *conf = child;
0544 
0545     ngx_pool_cleanup_t  *cln;
0546 
0547     ngx_conf_merge_msec_value(conf->handshake_timeout,
0548                          prev->handshake_timeout, 60000);
0549 
0550     ngx_conf_merge_value(conf->session_timeout,
0551                          prev->session_timeout, 300);
0552 
0553     ngx_conf_merge_value(conf->prefer_server_ciphers,
0554                          prev->prefer_server_ciphers, 0);
0555 
0556     ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
0557                          (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1
0558                           |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
0559 
0560     ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
0561     ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
0562 
0563     ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL);
0564     ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys,
0565                          NULL);
0566 
0567     ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL);
0568 
0569     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
0570 
0571     ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
0572                          "");
0573     ngx_conf_merge_str_value(conf->trusted_certificate,
0574                          prev->trusted_certificate, "");
0575     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
0576 
0577     ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
0578                          NGX_DEFAULT_ECDH_CURVE);
0579 
0580     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
0581 
0582 
0583     conf->ssl.log = cf->log;
0584 
0585     if (conf->certificates == NULL) {
0586         return NGX_CONF_OK;
0587     }
0588 
0589     if (conf->certificate_keys == NULL
0590         || conf->certificate_keys->nelts < conf->certificates->nelts)
0591     {
0592         ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0593                       "no \"ssl_certificate_key\" is defined "
0594                       "for certificate \"%V\"",
0595                       ((ngx_str_t *) conf->certificates->elts)
0596                       + conf->certificates->nelts - 1);
0597         return NGX_CONF_ERROR;
0598     }
0599 
0600     if (ngx_ssl_create(&conf->ssl, conf->protocols, NULL) != NGX_OK) {
0601         return NGX_CONF_ERROR;
0602     }
0603 
0604     cln = ngx_pool_cleanup_add(cf->pool, 0);
0605     if (cln == NULL) {
0606         return NGX_CONF_ERROR;
0607     }
0608 
0609     cln->handler = ngx_ssl_cleanup_ctx;
0610     cln->data = &conf->ssl;
0611 
0612     if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates,
0613                              conf->certificate_keys, conf->passwords)
0614         != NGX_OK)
0615     {
0616         return NGX_CONF_ERROR;
0617     }
0618 
0619     if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers,
0620                         conf->prefer_server_ciphers)
0621         != NGX_OK)
0622     {
0623         return NGX_CONF_ERROR;
0624     }
0625 
0626     if (conf->verify) {
0627 
0628         if (conf->client_certificate.len == 0 && conf->verify != 3) {
0629             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
0630                           "no ssl_client_certificate for ssl_client_verify");
0631             return NGX_CONF_ERROR;
0632         }
0633 
0634         if (ngx_ssl_client_certificate(cf, &conf->ssl,
0635                                        &conf->client_certificate,
0636                                        conf->verify_depth)
0637             != NGX_OK)
0638         {
0639             return NGX_CONF_ERROR;
0640         }
0641 
0642         if (ngx_ssl_trusted_certificate(cf, &conf->ssl,
0643                                         &conf->trusted_certificate,
0644                                         conf->verify_depth)
0645             != NGX_OK)
0646         {
0647             return NGX_CONF_ERROR;
0648         }
0649 
0650         if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
0651             return NGX_CONF_ERROR;
0652         }
0653     }
0654 
0655     if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
0656         return NGX_CONF_ERROR;
0657     }
0658 
0659     if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
0660         return NGX_CONF_ERROR;
0661     }
0662 
0663     ngx_conf_merge_value(conf->builtin_session_cache,
0664                          prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
0665 
0666     if (conf->shm_zone == NULL) {
0667         conf->shm_zone = prev->shm_zone;
0668     }
0669 
0670     if (ngx_ssl_session_cache(&conf->ssl, &ngx_stream_ssl_sess_id_ctx,
0671                               conf->builtin_session_cache,
0672                               conf->shm_zone, conf->session_timeout)
0673         != NGX_OK)
0674     {
0675         return NGX_CONF_ERROR;
0676     }
0677 
0678     ngx_conf_merge_value(conf->session_tickets,
0679                          prev->session_tickets, 1);
0680 
0681 #ifdef SSL_OP_NO_TICKET
0682     if (!conf->session_tickets) {
0683         SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET);
0684     }
0685 #endif
0686 
0687     ngx_conf_merge_ptr_value(conf->session_ticket_keys,
0688                          prev->session_ticket_keys, NULL);
0689 
0690     if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys)
0691         != NGX_OK)
0692     {
0693         return NGX_CONF_ERROR;
0694     }
0695 
0696     return NGX_CONF_OK;
0697 }
0698 
0699 
0700 static char *
0701 ngx_stream_ssl_password_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0702 {
0703     ngx_stream_ssl_conf_t  *scf = conf;
0704 
0705     ngx_str_t  *value;
0706 
0707     if (scf->passwords != NGX_CONF_UNSET_PTR) {
0708         return "is duplicate";
0709     }
0710 
0711     value = cf->args->elts;
0712 
0713     scf->passwords = ngx_ssl_read_password_file(cf, &value[1]);
0714 
0715     if (scf->passwords == NULL) {
0716         return NGX_CONF_ERROR;
0717     }
0718 
0719     return NGX_CONF_OK;
0720 }
0721 
0722 
0723 static char *
0724 ngx_stream_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0725 {
0726     ngx_stream_ssl_conf_t  *scf = conf;
0727 
0728     size_t       len;
0729     ngx_str_t   *value, name, size;
0730     ngx_int_t    n;
0731     ngx_uint_t   i, j;
0732 
0733     value = cf->args->elts;
0734 
0735     for (i = 1; i < cf->args->nelts; i++) {
0736 
0737         if (ngx_strcmp(value[i].data, "off") == 0) {
0738             scf->builtin_session_cache = NGX_SSL_NO_SCACHE;
0739             continue;
0740         }
0741 
0742         if (ngx_strcmp(value[i].data, "none") == 0) {
0743             scf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
0744             continue;
0745         }
0746 
0747         if (ngx_strcmp(value[i].data, "builtin") == 0) {
0748             scf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
0749             continue;
0750         }
0751 
0752         if (value[i].len > sizeof("builtin:") - 1
0753             && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
0754                == 0)
0755         {
0756             n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
0757                          value[i].len - (sizeof("builtin:") - 1));
0758 
0759             if (n == NGX_ERROR) {
0760                 goto invalid;
0761             }
0762 
0763             scf->builtin_session_cache = n;
0764 
0765             continue;
0766         }
0767 
0768         if (value[i].len > sizeof("shared:") - 1
0769             && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
0770                == 0)
0771         {
0772             len = 0;
0773 
0774             for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
0775                 if (value[i].data[j] == ':') {
0776                     break;
0777                 }
0778 
0779                 len++;
0780             }
0781 
0782             if (len == 0) {
0783                 goto invalid;
0784             }
0785 
0786             name.len = len;
0787             name.data = value[i].data + sizeof("shared:") - 1;
0788 
0789             size.len = value[i].len - j - 1;
0790             size.data = name.data + len + 1;
0791 
0792             n = ngx_parse_size(&size);
0793 
0794             if (n == NGX_ERROR) {
0795                 goto invalid;
0796             }
0797 
0798             if (n < (ngx_int_t) (8 * ngx_pagesize)) {
0799                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0800                                    "session cache \"%V\" is too small",
0801                                    &value[i]);
0802 
0803                 return NGX_CONF_ERROR;
0804             }
0805 
0806             scf->shm_zone = ngx_shared_memory_add(cf, &name, n,
0807                                                    &ngx_stream_ssl_module);
0808             if (scf->shm_zone == NULL) {
0809                 return NGX_CONF_ERROR;
0810             }
0811 
0812             scf->shm_zone->init = ngx_ssl_session_cache_init;
0813 
0814             continue;
0815         }
0816 
0817         goto invalid;
0818     }
0819 
0820     if (scf->shm_zone && scf->builtin_session_cache == NGX_CONF_UNSET) {
0821         scf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
0822     }
0823 
0824     return NGX_CONF_OK;
0825 
0826 invalid:
0827 
0828     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
0829                        "invalid session cache \"%V\"", &value[i]);
0830 
0831     return NGX_CONF_ERROR;
0832 }
0833 
0834 
0835 static ngx_int_t
0836 ngx_stream_ssl_init(ngx_conf_t *cf)
0837 {
0838     ngx_stream_handler_pt        *h;
0839     ngx_stream_core_main_conf_t  *cmcf;
0840 
0841     cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);
0842 
0843     h = ngx_array_push(&cmcf->phases[NGX_STREAM_SSL_PHASE].handlers);
0844     if (h == NULL) {
0845         return NGX_ERROR;
0846     }
0847 
0848     *h = ngx_stream_ssl_handler;
0849 
0850     return NGX_OK;
0851 }