Annotation of embedaddon/nginx/src/http/modules/ngx_http_ssl_module.c, revision 1.1

1.1     ! misho       1: 
        !             2: /*
        !             3:  * Copyright (C) Igor Sysoev
        !             4:  * Copyright (C) Nginx, Inc.
        !             5:  */
        !             6: 
        !             7: 
        !             8: #include <ngx_config.h>
        !             9: #include <ngx_core.h>
        !            10: #include <ngx_http.h>
        !            11: 
        !            12: 
        !            13: typedef ngx_int_t (*ngx_ssl_variable_handler_pt)(ngx_connection_t *c,
        !            14:     ngx_pool_t *pool, ngx_str_t *s);
        !            15: 
        !            16: 
        !            17: #define NGX_DEFAULT_CIPHERS     "HIGH:!aNULL:!MD5"
        !            18: #define NGX_DEFAULT_ECDH_CURVE  "prime256v1"
        !            19: 
        !            20: 
        !            21: #ifdef TLSEXT_TYPE_next_proto_neg
        !            22: static int ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
        !            23:     const unsigned char **out, unsigned int *outlen, void *arg);
        !            24: #endif
        !            25: 
        !            26: static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
        !            27:     ngx_http_variable_value_t *v, uintptr_t data);
        !            28: static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r,
        !            29:     ngx_http_variable_value_t *v, uintptr_t data);
        !            30: 
        !            31: static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf);
        !            32: static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf);
        !            33: static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf,
        !            34:     void *parent, void *child);
        !            35: 
        !            36: static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
        !            37:     void *conf);
        !            38: static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
        !            39:     void *conf);
        !            40: 
        !            41: static ngx_int_t ngx_http_ssl_init(ngx_conf_t *cf);
        !            42: 
        !            43: 
        !            44: static ngx_conf_bitmask_t  ngx_http_ssl_protocols[] = {
        !            45:     { ngx_string("SSLv2"), NGX_SSL_SSLv2 },
        !            46:     { ngx_string("SSLv3"), NGX_SSL_SSLv3 },
        !            47:     { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
        !            48:     { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
        !            49:     { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
        !            50:     { ngx_null_string, 0 }
        !            51: };
        !            52: 
        !            53: 
        !            54: static ngx_conf_enum_t  ngx_http_ssl_verify[] = {
        !            55:     { ngx_string("off"), 0 },
        !            56:     { ngx_string("on"), 1 },
        !            57:     { ngx_string("optional"), 2 },
        !            58:     { ngx_string("optional_no_ca"), 3 },
        !            59:     { ngx_null_string, 0 }
        !            60: };
        !            61: 
        !            62: 
        !            63: static ngx_command_t  ngx_http_ssl_commands[] = {
        !            64: 
        !            65:     { ngx_string("ssl"),
        !            66:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
        !            67:       ngx_http_ssl_enable,
        !            68:       NGX_HTTP_SRV_CONF_OFFSET,
        !            69:       offsetof(ngx_http_ssl_srv_conf_t, enable),
        !            70:       NULL },
        !            71: 
        !            72:     { ngx_string("ssl_certificate"),
        !            73:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !            74:       ngx_conf_set_str_slot,
        !            75:       NGX_HTTP_SRV_CONF_OFFSET,
        !            76:       offsetof(ngx_http_ssl_srv_conf_t, certificate),
        !            77:       NULL },
        !            78: 
        !            79:     { ngx_string("ssl_certificate_key"),
        !            80:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !            81:       ngx_conf_set_str_slot,
        !            82:       NGX_HTTP_SRV_CONF_OFFSET,
        !            83:       offsetof(ngx_http_ssl_srv_conf_t, certificate_key),
        !            84:       NULL },
        !            85: 
        !            86:     { ngx_string("ssl_dhparam"),
        !            87:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !            88:       ngx_conf_set_str_slot,
        !            89:       NGX_HTTP_SRV_CONF_OFFSET,
        !            90:       offsetof(ngx_http_ssl_srv_conf_t, dhparam),
        !            91:       NULL },
        !            92: 
        !            93:     { ngx_string("ssl_ecdh_curve"),
        !            94:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !            95:       ngx_conf_set_str_slot,
        !            96:       NGX_HTTP_SRV_CONF_OFFSET,
        !            97:       offsetof(ngx_http_ssl_srv_conf_t, ecdh_curve),
        !            98:       NULL },
        !            99: 
        !           100:     { ngx_string("ssl_protocols"),
        !           101:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
        !           102:       ngx_conf_set_bitmask_slot,
        !           103:       NGX_HTTP_SRV_CONF_OFFSET,
        !           104:       offsetof(ngx_http_ssl_srv_conf_t, protocols),
        !           105:       &ngx_http_ssl_protocols },
        !           106: 
        !           107:     { ngx_string("ssl_ciphers"),
        !           108:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !           109:       ngx_conf_set_str_slot,
        !           110:       NGX_HTTP_SRV_CONF_OFFSET,
        !           111:       offsetof(ngx_http_ssl_srv_conf_t, ciphers),
        !           112:       NULL },
        !           113: 
        !           114:     { ngx_string("ssl_verify_client"),
        !           115:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !           116:       ngx_conf_set_enum_slot,
        !           117:       NGX_HTTP_SRV_CONF_OFFSET,
        !           118:       offsetof(ngx_http_ssl_srv_conf_t, verify),
        !           119:       &ngx_http_ssl_verify },
        !           120: 
        !           121:     { ngx_string("ssl_verify_depth"),
        !           122:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_1MORE,
        !           123:       ngx_conf_set_num_slot,
        !           124:       NGX_HTTP_SRV_CONF_OFFSET,
        !           125:       offsetof(ngx_http_ssl_srv_conf_t, verify_depth),
        !           126:       NULL },
        !           127: 
        !           128:     { ngx_string("ssl_client_certificate"),
        !           129:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !           130:       ngx_conf_set_str_slot,
        !           131:       NGX_HTTP_SRV_CONF_OFFSET,
        !           132:       offsetof(ngx_http_ssl_srv_conf_t, client_certificate),
        !           133:       NULL },
        !           134: 
        !           135:     { ngx_string("ssl_trusted_certificate"),
        !           136:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !           137:       ngx_conf_set_str_slot,
        !           138:       NGX_HTTP_SRV_CONF_OFFSET,
        !           139:       offsetof(ngx_http_ssl_srv_conf_t, trusted_certificate),
        !           140:       NULL },
        !           141: 
        !           142:     { ngx_string("ssl_prefer_server_ciphers"),
        !           143:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
        !           144:       ngx_conf_set_flag_slot,
        !           145:       NGX_HTTP_SRV_CONF_OFFSET,
        !           146:       offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers),
        !           147:       NULL },
        !           148: 
        !           149:     { ngx_string("ssl_session_cache"),
        !           150:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12,
        !           151:       ngx_http_ssl_session_cache,
        !           152:       NGX_HTTP_SRV_CONF_OFFSET,
        !           153:       0,
        !           154:       NULL },
        !           155: 
        !           156:     { ngx_string("ssl_session_timeout"),
        !           157:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !           158:       ngx_conf_set_sec_slot,
        !           159:       NGX_HTTP_SRV_CONF_OFFSET,
        !           160:       offsetof(ngx_http_ssl_srv_conf_t, session_timeout),
        !           161:       NULL },
        !           162: 
        !           163:     { ngx_string("ssl_crl"),
        !           164:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !           165:       ngx_conf_set_str_slot,
        !           166:       NGX_HTTP_SRV_CONF_OFFSET,
        !           167:       offsetof(ngx_http_ssl_srv_conf_t, crl),
        !           168:       NULL },
        !           169: 
        !           170:     { ngx_string("ssl_stapling"),
        !           171:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
        !           172:       ngx_conf_set_flag_slot,
        !           173:       NGX_HTTP_SRV_CONF_OFFSET,
        !           174:       offsetof(ngx_http_ssl_srv_conf_t, stapling),
        !           175:       NULL },
        !           176: 
        !           177:     { ngx_string("ssl_stapling_file"),
        !           178:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !           179:       ngx_conf_set_str_slot,
        !           180:       NGX_HTTP_SRV_CONF_OFFSET,
        !           181:       offsetof(ngx_http_ssl_srv_conf_t, stapling_file),
        !           182:       NULL },
        !           183: 
        !           184:     { ngx_string("ssl_stapling_responder"),
        !           185:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
        !           186:       ngx_conf_set_str_slot,
        !           187:       NGX_HTTP_SRV_CONF_OFFSET,
        !           188:       offsetof(ngx_http_ssl_srv_conf_t, stapling_responder),
        !           189:       NULL },
        !           190: 
        !           191:     { ngx_string("ssl_stapling_verify"),
        !           192:       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
        !           193:       ngx_conf_set_flag_slot,
        !           194:       NGX_HTTP_SRV_CONF_OFFSET,
        !           195:       offsetof(ngx_http_ssl_srv_conf_t, stapling_verify),
        !           196:       NULL },
        !           197: 
        !           198:       ngx_null_command
        !           199: };
        !           200: 
        !           201: 
        !           202: static ngx_http_module_t  ngx_http_ssl_module_ctx = {
        !           203:     ngx_http_ssl_add_variables,            /* preconfiguration */
        !           204:     ngx_http_ssl_init,                     /* postconfiguration */
        !           205: 
        !           206:     NULL,                                  /* create main configuration */
        !           207:     NULL,                                  /* init main configuration */
        !           208: 
        !           209:     ngx_http_ssl_create_srv_conf,          /* create server configuration */
        !           210:     ngx_http_ssl_merge_srv_conf,           /* merge server configuration */
        !           211: 
        !           212:     NULL,                                  /* create location configuration */
        !           213:     NULL                                   /* merge location configuration */
        !           214: };
        !           215: 
        !           216: 
        !           217: ngx_module_t  ngx_http_ssl_module = {
        !           218:     NGX_MODULE_V1,
        !           219:     &ngx_http_ssl_module_ctx,              /* module context */
        !           220:     ngx_http_ssl_commands,                 /* module directives */
        !           221:     NGX_HTTP_MODULE,                       /* module type */
        !           222:     NULL,                                  /* init master */
        !           223:     NULL,                                  /* init module */
        !           224:     NULL,                                  /* init process */
        !           225:     NULL,                                  /* init thread */
        !           226:     NULL,                                  /* exit thread */
        !           227:     NULL,                                  /* exit process */
        !           228:     NULL,                                  /* exit master */
        !           229:     NGX_MODULE_V1_PADDING
        !           230: };
        !           231: 
        !           232: 
        !           233: static ngx_http_variable_t  ngx_http_ssl_vars[] = {
        !           234: 
        !           235:     { ngx_string("ssl_protocol"), NULL, ngx_http_ssl_static_variable,
        !           236:       (uintptr_t) ngx_ssl_get_protocol, NGX_HTTP_VAR_CHANGEABLE, 0 },
        !           237: 
        !           238:     { ngx_string("ssl_cipher"), NULL, ngx_http_ssl_static_variable,
        !           239:       (uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
        !           240: 
        !           241:     { ngx_string("ssl_session_id"), NULL, ngx_http_ssl_variable,
        !           242:       (uintptr_t) ngx_ssl_get_session_id, NGX_HTTP_VAR_CHANGEABLE, 0 },
        !           243: 
        !           244:     { ngx_string("ssl_client_cert"), NULL, ngx_http_ssl_variable,
        !           245:       (uintptr_t) ngx_ssl_get_certificate, NGX_HTTP_VAR_CHANGEABLE, 0 },
        !           246: 
        !           247:     { ngx_string("ssl_client_raw_cert"), NULL, ngx_http_ssl_variable,
        !           248:       (uintptr_t) ngx_ssl_get_raw_certificate,
        !           249:       NGX_HTTP_VAR_CHANGEABLE, 0 },
        !           250: 
        !           251:     { ngx_string("ssl_client_s_dn"), NULL, ngx_http_ssl_variable,
        !           252:       (uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
        !           253: 
        !           254:     { ngx_string("ssl_client_i_dn"), NULL, ngx_http_ssl_variable,
        !           255:       (uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
        !           256: 
        !           257:     { ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
        !           258:       (uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
        !           259: 
        !           260:     { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable,
        !           261:       (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 },
        !           262: 
        !           263:     { ngx_null_string, NULL, NULL, 0, 0, 0 }
        !           264: };
        !           265: 
        !           266: 
        !           267: static ngx_str_t ngx_http_ssl_sess_id_ctx = ngx_string("HTTP");
        !           268: 
        !           269: 
        !           270: #ifdef TLSEXT_TYPE_next_proto_neg
        !           271: 
        !           272: #define NGX_HTTP_NPN_ADVERTISE  "\x08http/1.1"
        !           273: 
        !           274: static int
        !           275: ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn,
        !           276:     const unsigned char **out, unsigned int *outlen, void *arg)
        !           277: {
        !           278: #if (NGX_HTTP_SPDY || NGX_DEBUG)
        !           279:     ngx_connection_t  *c;
        !           280: 
        !           281:     c = ngx_ssl_get_connection(ssl_conn);
        !           282:     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL NPN advertised");
        !           283: #endif
        !           284: 
        !           285: #if (NGX_HTTP_SPDY)
        !           286:     {
        !           287:     ngx_http_connection_t  *hc;
        !           288: 
        !           289:     hc = c->data;
        !           290: 
        !           291:     if (hc->addr_conf->spdy) {
        !           292:         *out = (unsigned char *) NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE;
        !           293:         *outlen = sizeof(NGX_SPDY_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1;
        !           294: 
        !           295:         return SSL_TLSEXT_ERR_OK;
        !           296:     }
        !           297:     }
        !           298: #endif
        !           299: 
        !           300:     *out = (unsigned char *) NGX_HTTP_NPN_ADVERTISE;
        !           301:     *outlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1;
        !           302: 
        !           303:     return SSL_TLSEXT_ERR_OK;
        !           304: }
        !           305: 
        !           306: #endif
        !           307: 
        !           308: 
        !           309: static ngx_int_t
        !           310: ngx_http_ssl_static_variable(ngx_http_request_t *r,
        !           311:     ngx_http_variable_value_t *v, uintptr_t data)
        !           312: {
        !           313:     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;
        !           314: 
        !           315:     size_t     len;
        !           316:     ngx_str_t  s;
        !           317: 
        !           318:     if (r->connection->ssl) {
        !           319: 
        !           320:         (void) handler(r->connection, NULL, &s);
        !           321: 
        !           322:         v->data = s.data;
        !           323: 
        !           324:         for (len = 0; v->data[len]; len++) { /* void */ }
        !           325: 
        !           326:         v->len = len;
        !           327:         v->valid = 1;
        !           328:         v->no_cacheable = 0;
        !           329:         v->not_found = 0;
        !           330: 
        !           331:         return NGX_OK;
        !           332:     }
        !           333: 
        !           334:     v->not_found = 1;
        !           335: 
        !           336:     return NGX_OK;
        !           337: }
        !           338: 
        !           339: 
        !           340: static ngx_int_t
        !           341: ngx_http_ssl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
        !           342:     uintptr_t data)
        !           343: {
        !           344:     ngx_ssl_variable_handler_pt  handler = (ngx_ssl_variable_handler_pt) data;
        !           345: 
        !           346:     ngx_str_t  s;
        !           347: 
        !           348:     if (r->connection->ssl) {
        !           349: 
        !           350:         if (handler(r->connection, r->pool, &s) != NGX_OK) {
        !           351:             return NGX_ERROR;
        !           352:         }
        !           353: 
        !           354:         v->len = s.len;
        !           355:         v->data = s.data;
        !           356: 
        !           357:         if (v->len) {
        !           358:             v->valid = 1;
        !           359:             v->no_cacheable = 0;
        !           360:             v->not_found = 0;
        !           361: 
        !           362:             return NGX_OK;
        !           363:         }
        !           364:     }
        !           365: 
        !           366:     v->not_found = 1;
        !           367: 
        !           368:     return NGX_OK;
        !           369: }
        !           370: 
        !           371: 
        !           372: static ngx_int_t
        !           373: ngx_http_ssl_add_variables(ngx_conf_t *cf)
        !           374: {
        !           375:     ngx_http_variable_t  *var, *v;
        !           376: 
        !           377:     for (v = ngx_http_ssl_vars; v->name.len; v++) {
        !           378:         var = ngx_http_add_variable(cf, &v->name, v->flags);
        !           379:         if (var == NULL) {
        !           380:             return NGX_ERROR;
        !           381:         }
        !           382: 
        !           383:         var->get_handler = v->get_handler;
        !           384:         var->data = v->data;
        !           385:     }
        !           386: 
        !           387:     return NGX_OK;
        !           388: }
        !           389: 
        !           390: 
        !           391: static void *
        !           392: ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
        !           393: {
        !           394:     ngx_http_ssl_srv_conf_t  *sscf;
        !           395: 
        !           396:     sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssl_srv_conf_t));
        !           397:     if (sscf == NULL) {
        !           398:         return NULL;
        !           399:     }
        !           400: 
        !           401:     /*
        !           402:      * set by ngx_pcalloc():
        !           403:      *
        !           404:      *     sscf->protocols = 0;
        !           405:      *     sscf->certificate = { 0, NULL };
        !           406:      *     sscf->certificate_key = { 0, NULL };
        !           407:      *     sscf->dhparam = { 0, NULL };
        !           408:      *     sscf->ecdh_curve = { 0, NULL };
        !           409:      *     sscf->client_certificate = { 0, NULL };
        !           410:      *     sscf->trusted_certificate = { 0, NULL };
        !           411:      *     sscf->crl = { 0, NULL };
        !           412:      *     sscf->ciphers = { 0, NULL };
        !           413:      *     sscf->shm_zone = NULL;
        !           414:      *     sscf->stapling_file = { 0, NULL };
        !           415:      *     sscf->stapling_responder = { 0, NULL };
        !           416:      */
        !           417: 
        !           418:     sscf->enable = NGX_CONF_UNSET;
        !           419:     sscf->prefer_server_ciphers = NGX_CONF_UNSET;
        !           420:     sscf->verify = NGX_CONF_UNSET_UINT;
        !           421:     sscf->verify_depth = NGX_CONF_UNSET_UINT;
        !           422:     sscf->builtin_session_cache = NGX_CONF_UNSET;
        !           423:     sscf->session_timeout = NGX_CONF_UNSET;
        !           424:     sscf->stapling = NGX_CONF_UNSET;
        !           425:     sscf->stapling_verify = NGX_CONF_UNSET;
        !           426: 
        !           427:     return sscf;
        !           428: }
        !           429: 
        !           430: 
        !           431: static char *
        !           432: ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
        !           433: {
        !           434:     ngx_http_ssl_srv_conf_t *prev = parent;
        !           435:     ngx_http_ssl_srv_conf_t *conf = child;
        !           436: 
        !           437:     ngx_pool_cleanup_t  *cln;
        !           438: 
        !           439:     if (conf->enable == NGX_CONF_UNSET) {
        !           440:         if (prev->enable == NGX_CONF_UNSET) {
        !           441:             conf->enable = 0;
        !           442: 
        !           443:         } else {
        !           444:             conf->enable = prev->enable;
        !           445:             conf->file = prev->file;
        !           446:             conf->line = prev->line;
        !           447:         }
        !           448:     }
        !           449: 
        !           450:     ngx_conf_merge_value(conf->session_timeout,
        !           451:                          prev->session_timeout, 300);
        !           452: 
        !           453:     ngx_conf_merge_value(conf->prefer_server_ciphers,
        !           454:                          prev->prefer_server_ciphers, 0);
        !           455: 
        !           456:     ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
        !           457:                          (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1
        !           458:                           |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2));
        !           459: 
        !           460:     ngx_conf_merge_uint_value(conf->verify, prev->verify, 0);
        !           461:     ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1);
        !           462: 
        !           463:     ngx_conf_merge_str_value(conf->certificate, prev->certificate, "");
        !           464:     ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, "");
        !           465: 
        !           466:     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
        !           467: 
        !           468:     ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
        !           469:                          "");
        !           470:     ngx_conf_merge_str_value(conf->trusted_certificate,
        !           471:                          prev->trusted_certificate, "");
        !           472:     ngx_conf_merge_str_value(conf->crl, prev->crl, "");
        !           473: 
        !           474:     ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve,
        !           475:                          NGX_DEFAULT_ECDH_CURVE);
        !           476: 
        !           477:     ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
        !           478: 
        !           479:     ngx_conf_merge_value(conf->stapling, prev->stapling, 0);
        !           480:     ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0);
        !           481:     ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, "");
        !           482:     ngx_conf_merge_str_value(conf->stapling_responder,
        !           483:                          prev->stapling_responder, "");
        !           484: 
        !           485:     conf->ssl.log = cf->log;
        !           486: 
        !           487:     if (conf->enable) {
        !           488: 
        !           489:         if (conf->certificate.len == 0) {
        !           490:             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
        !           491:                           "no \"ssl_certificate\" is defined for "
        !           492:                           "the \"ssl\" directive in %s:%ui",
        !           493:                           conf->file, conf->line);
        !           494:             return NGX_CONF_ERROR;
        !           495:         }
        !           496: 
        !           497:         if (conf->certificate_key.len == 0) {
        !           498:             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
        !           499:                           "no \"ssl_certificate_key\" is defined for "
        !           500:                           "the \"ssl\" directive in %s:%ui",
        !           501:                           conf->file, conf->line);
        !           502:             return NGX_CONF_ERROR;
        !           503:         }
        !           504: 
        !           505:     } else {
        !           506: 
        !           507:         if (conf->certificate.len == 0) {
        !           508:             return NGX_CONF_OK;
        !           509:         }
        !           510: 
        !           511:         if (conf->certificate_key.len == 0) {
        !           512:             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
        !           513:                           "no \"ssl_certificate_key\" is defined "
        !           514:                           "for certificate \"%V\"", &conf->certificate);
        !           515:             return NGX_CONF_ERROR;
        !           516:         }
        !           517:     }
        !           518: 
        !           519:     if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) {
        !           520:         return NGX_CONF_ERROR;
        !           521:     }
        !           522: 
        !           523: #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
        !           524: 
        !           525:     if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx,
        !           526:                                                ngx_http_ssl_servername)
        !           527:         == 0)
        !           528:     {
        !           529:         ngx_log_error(NGX_LOG_WARN, cf->log, 0,
        !           530:             "nginx was built with SNI support, however, now it is linked "
        !           531:             "dynamically to an OpenSSL library which has no tlsext support, "
        !           532:             "therefore SNI is not available");
        !           533:     }
        !           534: 
        !           535: #endif
        !           536: 
        !           537: #ifdef TLSEXT_TYPE_next_proto_neg
        !           538:     SSL_CTX_set_next_protos_advertised_cb(conf->ssl.ctx,
        !           539:                                           ngx_http_ssl_npn_advertised, NULL);
        !           540: #endif
        !           541: 
        !           542:     cln = ngx_pool_cleanup_add(cf->pool, 0);
        !           543:     if (cln == NULL) {
        !           544:         return NGX_CONF_ERROR;
        !           545:     }
        !           546: 
        !           547:     cln->handler = ngx_ssl_cleanup_ctx;
        !           548:     cln->data = &conf->ssl;
        !           549: 
        !           550:     if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate,
        !           551:                             &conf->certificate_key)
        !           552:         != NGX_OK)
        !           553:     {
        !           554:         return NGX_CONF_ERROR;
        !           555:     }
        !           556: 
        !           557:     if (SSL_CTX_set_cipher_list(conf->ssl.ctx,
        !           558:                                 (const char *) conf->ciphers.data)
        !           559:         == 0)
        !           560:     {
        !           561:         ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
        !           562:                       "SSL_CTX_set_cipher_list(\"%V\") failed",
        !           563:                       &conf->ciphers);
        !           564:     }
        !           565: 
        !           566:     if (conf->verify) {
        !           567: 
        !           568:         if (conf->client_certificate.len == 0 && conf->verify != 3) {
        !           569:             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
        !           570:                           "no ssl_client_certificate for ssl_client_verify");
        !           571:             return NGX_CONF_ERROR;
        !           572:         }
        !           573: 
        !           574:         if (ngx_ssl_client_certificate(cf, &conf->ssl,
        !           575:                                        &conf->client_certificate,
        !           576:                                        conf->verify_depth)
        !           577:             != NGX_OK)
        !           578:         {
        !           579:             return NGX_CONF_ERROR;
        !           580:         }
        !           581:     }
        !           582: 
        !           583:     if (ngx_ssl_trusted_certificate(cf, &conf->ssl,
        !           584:                                     &conf->trusted_certificate,
        !           585:                                     conf->verify_depth)
        !           586:         != NGX_OK)
        !           587:     {
        !           588:         return NGX_CONF_ERROR;
        !           589:     }
        !           590: 
        !           591:     if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
        !           592:         return NGX_CONF_ERROR;
        !           593:     }
        !           594: 
        !           595:     if (conf->prefer_server_ciphers) {
        !           596:         SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
        !           597:     }
        !           598: 
        !           599:     /* a temporary 512-bit RSA key is required for export versions of MSIE */
        !           600:     SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback);
        !           601: 
        !           602:     if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) {
        !           603:         return NGX_CONF_ERROR;
        !           604:     }
        !           605: 
        !           606:     if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) {
        !           607:         return NGX_CONF_ERROR;
        !           608:     }
        !           609: 
        !           610:     ngx_conf_merge_value(conf->builtin_session_cache,
        !           611:                          prev->builtin_session_cache, NGX_SSL_NONE_SCACHE);
        !           612: 
        !           613:     if (conf->shm_zone == NULL) {
        !           614:         conf->shm_zone = prev->shm_zone;
        !           615:     }
        !           616: 
        !           617:     if (ngx_ssl_session_cache(&conf->ssl, &ngx_http_ssl_sess_id_ctx,
        !           618:                               conf->builtin_session_cache,
        !           619:                               conf->shm_zone, conf->session_timeout)
        !           620:         != NGX_OK)
        !           621:     {
        !           622:         return NGX_CONF_ERROR;
        !           623:     }
        !           624: 
        !           625:     if (conf->stapling) {
        !           626: 
        !           627:         if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file,
        !           628:                              &conf->stapling_responder, conf->stapling_verify)
        !           629:             != NGX_OK)
        !           630:         {
        !           631:             return NGX_CONF_ERROR;
        !           632:         }
        !           633: 
        !           634:     }
        !           635: 
        !           636:     return NGX_CONF_OK;
        !           637: }
        !           638: 
        !           639: 
        !           640: static char *
        !           641: ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
        !           642: {
        !           643:     ngx_http_ssl_srv_conf_t *sscf = conf;
        !           644: 
        !           645:     char  *rv;
        !           646: 
        !           647:     rv = ngx_conf_set_flag_slot(cf, cmd, conf);
        !           648: 
        !           649:     if (rv != NGX_CONF_OK) {
        !           650:         return rv;
        !           651:     }
        !           652: 
        !           653:     sscf->file = cf->conf_file->file.name.data;
        !           654:     sscf->line = cf->conf_file->line;
        !           655: 
        !           656:     return NGX_CONF_OK;
        !           657: }
        !           658: 
        !           659: 
        !           660: static char *
        !           661: ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
        !           662: {
        !           663:     ngx_http_ssl_srv_conf_t *sscf = conf;
        !           664: 
        !           665:     size_t       len;
        !           666:     ngx_str_t   *value, name, size;
        !           667:     ngx_int_t    n;
        !           668:     ngx_uint_t   i, j;
        !           669: 
        !           670:     value = cf->args->elts;
        !           671: 
        !           672:     for (i = 1; i < cf->args->nelts; i++) {
        !           673: 
        !           674:         if (ngx_strcmp(value[i].data, "off") == 0) {
        !           675:             sscf->builtin_session_cache = NGX_SSL_NO_SCACHE;
        !           676:             continue;
        !           677:         }
        !           678: 
        !           679:         if (ngx_strcmp(value[i].data, "none") == 0) {
        !           680:             sscf->builtin_session_cache = NGX_SSL_NONE_SCACHE;
        !           681:             continue;
        !           682:         }
        !           683: 
        !           684:         if (ngx_strcmp(value[i].data, "builtin") == 0) {
        !           685:             sscf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE;
        !           686:             continue;
        !           687:         }
        !           688: 
        !           689:         if (value[i].len > sizeof("builtin:") - 1
        !           690:             && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1)
        !           691:                == 0)
        !           692:         {
        !           693:             n = ngx_atoi(value[i].data + sizeof("builtin:") - 1,
        !           694:                          value[i].len - (sizeof("builtin:") - 1));
        !           695: 
        !           696:             if (n == NGX_ERROR) {
        !           697:                 goto invalid;
        !           698:             }
        !           699: 
        !           700:             sscf->builtin_session_cache = n;
        !           701: 
        !           702:             continue;
        !           703:         }
        !           704: 
        !           705:         if (value[i].len > sizeof("shared:") - 1
        !           706:             && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1)
        !           707:                == 0)
        !           708:         {
        !           709:             len = 0;
        !           710: 
        !           711:             for (j = sizeof("shared:") - 1; j < value[i].len; j++) {
        !           712:                 if (value[i].data[j] == ':') {
        !           713:                     break;
        !           714:                 }
        !           715: 
        !           716:                 len++;
        !           717:             }
        !           718: 
        !           719:             if (len == 0) {
        !           720:                 goto invalid;
        !           721:             }
        !           722: 
        !           723:             name.len = len;
        !           724:             name.data = value[i].data + sizeof("shared:") - 1;
        !           725: 
        !           726:             size.len = value[i].len - j - 1;
        !           727:             size.data = name.data + len + 1;
        !           728: 
        !           729:             n = ngx_parse_size(&size);
        !           730: 
        !           731:             if (n == NGX_ERROR) {
        !           732:                 goto invalid;
        !           733:             }
        !           734: 
        !           735:             if (n < (ngx_int_t) (8 * ngx_pagesize)) {
        !           736:                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
        !           737:                                    "session cache \"%V\" is too small",
        !           738:                                    &value[i]);
        !           739: 
        !           740:                 return NGX_CONF_ERROR;
        !           741:             }
        !           742: 
        !           743:             sscf->shm_zone = ngx_shared_memory_add(cf, &name, n,
        !           744:                                                    &ngx_http_ssl_module);
        !           745:             if (sscf->shm_zone == NULL) {
        !           746:                 return NGX_CONF_ERROR;
        !           747:             }
        !           748: 
        !           749:             sscf->shm_zone->init = ngx_ssl_session_cache_init;
        !           750: 
        !           751:             continue;
        !           752:         }
        !           753: 
        !           754:         goto invalid;
        !           755:     }
        !           756: 
        !           757:     if (sscf->shm_zone && sscf->builtin_session_cache == NGX_CONF_UNSET) {
        !           758:         sscf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE;
        !           759:     }
        !           760: 
        !           761:     return NGX_CONF_OK;
        !           762: 
        !           763: invalid:
        !           764: 
        !           765:     ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
        !           766:                        "invalid session cache \"%V\"", &value[i]);
        !           767: 
        !           768:     return NGX_CONF_ERROR;
        !           769: }
        !           770: 
        !           771: 
        !           772: static ngx_int_t
        !           773: ngx_http_ssl_init(ngx_conf_t *cf)
        !           774: {
        !           775:     ngx_uint_t                   s;
        !           776:     ngx_http_ssl_srv_conf_t     *sscf;
        !           777:     ngx_http_core_loc_conf_t    *clcf;
        !           778:     ngx_http_core_srv_conf_t   **cscfp;
        !           779:     ngx_http_core_main_conf_t   *cmcf;
        !           780: 
        !           781:     cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
        !           782:     cscfp = cmcf->servers.elts;
        !           783: 
        !           784:     for (s = 0; s < cmcf->servers.nelts; s++) {
        !           785: 
        !           786:         sscf = cscfp[s]->ctx->srv_conf[ngx_http_ssl_module.ctx_index];
        !           787: 
        !           788:         if (sscf->ssl.ctx == NULL || !sscf->stapling) {
        !           789:             continue;
        !           790:         }
        !           791: 
        !           792:         clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
        !           793: 
        !           794:         if (ngx_ssl_stapling_resolver(cf, &sscf->ssl, clcf->resolver,
        !           795:                                       clcf->resolver_timeout)
        !           796:             != NGX_OK)
        !           797:         {
        !           798:             return NGX_ERROR;
        !           799:         }
        !           800:     }
        !           801: 
        !           802:     return NGX_OK;
        !           803: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>