summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_router.c
diff options
context:
space:
mode:
authorAndrey Suvorov <a.suvorov@f5.com>2021-03-24 13:19:36 -0700
committerAndrey Suvorov <a.suvorov@f5.com>2021-03-24 13:19:36 -0700
commitd2b0882d89f29fea84b457e0709b6980c8a30a57 (patch)
tree5bf41ab489a5866cfcb28ea35d36623110079d53 /src/nxt_router.c
parentd62192738f2db9e22e1357daa7b7dccdce3c783f (diff)
downloadunit-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 'src/nxt_router.c')
-rw-r--r--src/nxt_router.c123
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;