diff options
author | Andrey Suvorov <a.suvorov@f5.com> | 2021-03-24 13:19:36 -0700 |
---|---|---|
committer | Andrey Suvorov <a.suvorov@f5.com> | 2021-03-24 13:19:36 -0700 |
commit | d2b0882d89f29fea84b457e0709b6980c8a30a57 (patch) | |
tree | 5bf41ab489a5866cfcb28ea35d36623110079d53 /src/nxt_router.c | |
parent | d62192738f2db9e22e1357daa7b7dccdce3c783f (diff) | |
download | unit-d2b0882d89f29fea84b457e0709b6980c8a30a57.tar.gz unit-d2b0882d89f29fea84b457e0709b6980c8a30a57.tar.bz2 |
Added ability to configure multiple certificates on a listener.
The certificate is selected by matching the arriving SNI to the common name and
the alternatives names. If no certificate matches the name, the first bundle in
the array is chosen.
Diffstat (limited to '')
-rw-r--r-- | src/nxt_router.c | 123 |
1 files changed, 93 insertions, 30 deletions
diff --git a/src/nxt_router.c b/src/nxt_router.c index 4be4197a..0ecaefa1 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -51,8 +51,10 @@ typedef struct { typedef struct { + nxt_str_t *name; nxt_socket_conf_t *socket_conf; nxt_router_temp_conf_t *temp_conf; + nxt_bool_t last; } nxt_socket_rpc_t; @@ -116,9 +118,11 @@ static void nxt_router_listen_socket_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); #if (NXT_TLS) static void nxt_router_tls_rpc_create(nxt_task_t *task, - nxt_router_temp_conf_t *tmcf, nxt_router_tlssock_t *tls); + nxt_router_temp_conf_t *tmcf, nxt_router_tlssock_t *tls, nxt_bool_t last); static void nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); +static nxt_int_t nxt_router_conf_tls_insert(nxt_router_temp_conf_t *tmcf, + nxt_conf_value_t *value, nxt_socket_conf_t *skcf); #endif static void nxt_router_app_rpc_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_app_t *app); @@ -944,14 +948,15 @@ nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data) } #if (NXT_TLS) - qlk = nxt_queue_first(&tmcf->tls); + qlk = nxt_queue_last(&tmcf->tls); - if (qlk != nxt_queue_tail(&tmcf->tls)) { + if (qlk != nxt_queue_head(&tmcf->tls)) { nxt_queue_remove(qlk); tls = nxt_queue_link_data(qlk, nxt_router_tlssock_t, link); - nxt_router_tls_rpc_create(task, tmcf, tls); + nxt_router_tls_rpc_create(task, tmcf, tls, + nxt_queue_is_empty(&tmcf->tls)); return; } #endif @@ -990,7 +995,7 @@ nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data) nxt_router_apps_sort(task, router, tmcf); - nxt_router_apps_hash_use(task, rtcf, 1); + nxt_router_apps_hash_use(task, rtcf, 1); nxt_router_engines_post(router, tmcf); @@ -1332,6 +1337,9 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_port_t *port; nxt_router_t *router; nxt_app_joint_t *app_joint; +#if (NXT_TLS) + nxt_conf_value_t *certificate; +#endif nxt_conf_value_t *conf, *http, *value, *websocket; nxt_conf_value_t *applications, *application; nxt_conf_value_t *listeners, *listener; @@ -1343,9 +1351,6 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_router_app_conf_t apcf; nxt_router_access_log_t *access_log; nxt_router_listener_conf_t lscf; -#if (NXT_TLS) - nxt_router_tlssock_t *tls; -#endif static nxt_str_t http_path = nxt_string("/settings/http"); static nxt_str_t applications_path = nxt_string("/applications"); @@ -1729,20 +1734,30 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, } #if (NXT_TLS) - value = nxt_conf_get_path(listener, &certificate_path); + certificate = nxt_conf_get_path(listener, &certificate_path); - if (value != NULL) { - nxt_conf_get_string(value, &name); + if (certificate != NULL) { + if (nxt_conf_type(certificate) == NXT_CONF_ARRAY) { + n = nxt_conf_array_elements_count(certificate); - tls = nxt_mp_get(mp, sizeof(nxt_router_tlssock_t)); - if (nxt_slow_path(tls == NULL)) { - goto fail; - } + for (i = 0; i < n; i++) { + value = nxt_conf_get_array_element(certificate, i); - tls->name = name; - tls->conf = skcf; + nxt_assert(value != NULL); - nxt_queue_insert_tail(&tmcf->tls, &tls->link); + ret = nxt_router_conf_tls_insert(tmcf, value, skcf); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } + } + + } else { + /* NXT_CONF_STRING */ + ret = nxt_router_conf_tls_insert(tmcf, certificate, skcf); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } + } } #endif @@ -1828,6 +1843,38 @@ fail: } +#if (NXT_TLS) + +static nxt_int_t +nxt_router_conf_tls_insert(nxt_router_temp_conf_t *tmcf, + nxt_conf_value_t *value, nxt_socket_conf_t *skcf) +{ + nxt_mp_t *mp; + nxt_str_t str; + nxt_router_tlssock_t *tls; + + mp = tmcf->router_conf->mem_pool; + + tls = nxt_mp_get(mp, sizeof(nxt_router_tlssock_t)); + if (nxt_slow_path(tls == NULL)) { + return NXT_ERROR; + } + + tls->conf = skcf; + nxt_conf_get_string(value, &str); + + if (nxt_slow_path(nxt_str_dup(mp, &tls->name, &str) == NULL)) { + return NXT_ERROR; + } + + nxt_queue_insert_tail(&tmcf->tls, &tls->link); + + return NXT_OK; +} + +#endif + + static nxt_int_t nxt_router_conf_process_static(nxt_task_t *task, nxt_router_conf_t *rtcf, nxt_conf_value_t *conf) @@ -2383,7 +2430,7 @@ nxt_router_listen_socket_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, static void nxt_router_tls_rpc_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, - nxt_router_tlssock_t *tls) + nxt_router_tlssock_t *tls, nxt_bool_t last) { nxt_socket_rpc_t *rpc; @@ -2393,8 +2440,10 @@ nxt_router_tls_rpc_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, return; } + rpc->name = &tls->name; rpc->socket_conf = tls->conf; rpc->temp_conf = tmcf; + rpc->last = last; nxt_cert_store_get(task, &tls->name, tmcf->mem_pool, nxt_router_tls_rpc_handler, rpc); @@ -2405,11 +2454,12 @@ static void nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data) { - nxt_mp_t *mp; - nxt_int_t ret; - nxt_tls_conf_t *tlscf; - nxt_socket_rpc_t *rpc; - nxt_router_temp_conf_t *tmcf; + nxt_mp_t *mp; + nxt_int_t ret; + nxt_tls_conf_t *tlscf; + nxt_socket_rpc_t *rpc; + nxt_tls_bundle_conf_t *bundle; + nxt_router_temp_conf_t *tmcf; nxt_debug(task, "tls rpc handler"); @@ -2422,20 +2472,33 @@ nxt_router_tls_rpc_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, mp = tmcf->router_conf->mem_pool; - tlscf = nxt_mp_zget(mp, sizeof(nxt_tls_conf_t)); - if (nxt_slow_path(tlscf == NULL)) { + if (rpc->socket_conf->tls == NULL){ + tlscf = nxt_mp_zget(mp, sizeof(nxt_tls_conf_t)); + if (nxt_slow_path(tlscf == NULL)) { + goto fail; + } + + rpc->socket_conf->tls = tlscf; + + } else { + tlscf = rpc->socket_conf->tls; + } + + bundle = nxt_mp_get(mp, sizeof(nxt_tls_bundle_conf_t)); + if (nxt_slow_path(bundle == NULL)) { goto fail; } - tlscf->chain_file = msg->fd[0]; + bundle->name = rpc->name; + bundle->chain_file = msg->fd[0]; + bundle->next = tlscf->bundle; + tlscf->bundle = bundle; - ret = task->thread->runtime->tls->server_init(task, tlscf); + ret = task->thread->runtime->tls->server_init(task, tlscf, mp, rpc->last); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } - rpc->socket_conf->tls = tlscf; - nxt_work_queue_add(&task->thread->engine->fast_work_queue, nxt_router_conf_apply, task, tmcf, NULL); return; |