Controller: certificates storage interface.
This commit is contained in:
parent
2dfd8ffc2f
commit
8d844bc2aa
16 changed files with 2111 additions and 52 deletions
|
@ -106,7 +106,7 @@ NXT_LIB_UNIT_SRCS="src/nxt_unit.c"
|
|||
|
||||
|
||||
NXT_LIB_TLS_DEPS="src/nxt_tls.h"
|
||||
NXT_LIB_TLS_SRCS=
|
||||
NXT_LIB_TLS_SRCS="src/nxt_cert.c"
|
||||
NXT_LIB_OPENSSL_SRCS="src/nxt_openssl.c"
|
||||
NXT_LIB_GNUTLS_SRCS="src/nxt_gnutls.c"
|
||||
NXT_LIB_CYASSL_SRCS="src/nxt_cyassl.c"
|
||||
|
|
1204
src/nxt_cert.c
Normal file
1204
src/nxt_cert.c
Normal file
File diff suppressed because it is too large
Load diff
32
src/nxt_cert.h
Normal file
32
src/nxt_cert.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) Valentin V. Bartenev
|
||||
* Copyright (C) NGINX, Inc.
|
||||
*/
|
||||
|
||||
#ifndef _NXT_CERT_INCLUDED_
|
||||
#define _NXT_CERT_INCLUDED_
|
||||
|
||||
|
||||
typedef struct nxt_cert_s nxt_cert_t;
|
||||
|
||||
nxt_cert_t *nxt_cert_mem(nxt_task_t *task, nxt_buf_mem_t *mbuf);
|
||||
void nxt_cert_destroy(nxt_cert_t *cert);
|
||||
|
||||
void nxt_cert_info_init(nxt_task_t *task, nxt_array_t *certs);
|
||||
nxt_int_t nxt_cert_info_save(nxt_str_t *name, nxt_cert_t *cert);
|
||||
nxt_conf_value_t *nxt_cert_info_get(nxt_str_t *name);
|
||||
nxt_conf_value_t *nxt_cert_info_get_all(nxt_mp_t *mp);
|
||||
nxt_int_t nxt_cert_info_delete(nxt_str_t *name);
|
||||
|
||||
nxt_array_t *nxt_cert_store_load(nxt_task_t *task);
|
||||
void nxt_cert_store_release(nxt_array_t *certs);
|
||||
|
||||
void nxt_cert_store_get(nxt_task_t *task, nxt_str_t *name, nxt_mp_t *mp,
|
||||
nxt_port_rpc_handler_t handler, void *ctx);
|
||||
void nxt_cert_store_delete(nxt_task_t *task, nxt_str_t *name, nxt_mp_t *mp);
|
||||
|
||||
void nxt_cert_store_get_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg);
|
||||
void nxt_cert_store_delete_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg);
|
||||
|
||||
#endif /* _NXT_CERT_INCLUDED_ */
|
|
@ -180,6 +180,33 @@ nxt_conf_set_string(nxt_conf_value_t *value, nxt_str_t *str)
|
|||
}
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_conf_set_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp, nxt_str_t *str)
|
||||
{
|
||||
nxt_str_t tmp, *ptr;
|
||||
|
||||
if (str->length > NXT_CONF_MAX_SHORT_STRING) {
|
||||
value->type = NXT_CONF_VALUE_STRING;
|
||||
|
||||
ptr = nxt_str_dup(mp, &tmp, str);
|
||||
if (nxt_slow_path(ptr == NULL)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
value->u.string.length = tmp.length;
|
||||
value->u.string.start = tmp.start;
|
||||
|
||||
} else {
|
||||
value->type = NXT_CONF_VALUE_SHORT_STRING;
|
||||
value->u.str.length = str->length;
|
||||
|
||||
nxt_memcpy(value->u.str.start, str->start, str->length);
|
||||
}
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
||||
int64_t
|
||||
nxt_conf_get_integer(nxt_conf_value_t *value)
|
||||
{
|
||||
|
@ -246,6 +273,20 @@ nxt_conf_set_member_string(nxt_conf_value_t *object, nxt_str_t *name,
|
|||
}
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_conf_set_member_string_dup(nxt_conf_value_t *object, nxt_mp_t *mp,
|
||||
nxt_str_t *name, nxt_str_t *value, uint32_t index)
|
||||
{
|
||||
nxt_conf_object_member_t *member;
|
||||
|
||||
member = &object->u.object->members[index];
|
||||
|
||||
nxt_conf_set_string(&member->name, name);
|
||||
|
||||
return nxt_conf_set_string_dup(&member->value, mp, value);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nxt_conf_set_member_integer(nxt_conf_value_t *object, nxt_str_t *name,
|
||||
int64_t value, uint32_t index)
|
||||
|
@ -261,6 +302,64 @@ nxt_conf_set_member_integer(nxt_conf_value_t *object, nxt_str_t *name,
|
|||
}
|
||||
|
||||
|
||||
void
|
||||
nxt_conf_set_member_null(nxt_conf_value_t *object, nxt_str_t *name,
|
||||
uint32_t index)
|
||||
{
|
||||
nxt_conf_object_member_t *member;
|
||||
|
||||
member = &object->u.object->members[index];
|
||||
|
||||
nxt_conf_set_string(&member->name, name);
|
||||
|
||||
member->value.type = NXT_CONF_VALUE_NULL;
|
||||
}
|
||||
|
||||
|
||||
nxt_conf_value_t *
|
||||
nxt_conf_create_array(nxt_mp_t *mp, nxt_uint_t count)
|
||||
{
|
||||
size_t size;
|
||||
nxt_conf_value_t *value;
|
||||
|
||||
size = sizeof(nxt_conf_value_t)
|
||||
+ sizeof(nxt_conf_array_t)
|
||||
+ count * sizeof(nxt_conf_value_t);
|
||||
|
||||
value = nxt_mp_get(mp, size);
|
||||
if (nxt_slow_path(value == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
value->u.array = nxt_pointer_to(value, sizeof(nxt_conf_value_t));
|
||||
value->u.array->count = count;
|
||||
|
||||
value->type = NXT_CONF_VALUE_ARRAY;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nxt_conf_set_element(nxt_conf_value_t *array, nxt_uint_t index,
|
||||
nxt_conf_value_t *value)
|
||||
{
|
||||
array->u.array->elements[index] = *value;
|
||||
}
|
||||
|
||||
|
||||
nxt_int_t
|
||||
nxt_conf_set_element_string_dup(nxt_conf_value_t *array, nxt_mp_t *mp,
|
||||
nxt_uint_t index, nxt_str_t *value)
|
||||
{
|
||||
nxt_conf_value_t *element;
|
||||
|
||||
element = &array->u.array->elements[index];
|
||||
|
||||
return nxt_conf_set_string_dup(element, mp, value);
|
||||
}
|
||||
|
||||
|
||||
nxt_uint_t
|
||||
nxt_conf_type(nxt_conf_value_t *value)
|
||||
{
|
||||
|
|
|
@ -102,6 +102,8 @@ nxt_int_t nxt_conf_validate(nxt_conf_validation_t *vldt);
|
|||
|
||||
NXT_EXPORT void nxt_conf_get_string(nxt_conf_value_t *value, nxt_str_t *str);
|
||||
NXT_EXPORT void nxt_conf_set_string(nxt_conf_value_t *value, nxt_str_t *str);
|
||||
NXT_EXPORT nxt_int_t nxt_conf_set_string_dup(nxt_conf_value_t *value,
|
||||
nxt_mp_t *mp, nxt_str_t *str);
|
||||
NXT_EXPORT int64_t nxt_conf_get_integer(nxt_conf_value_t *value);
|
||||
|
||||
// FIXME reimplement and reorder functions below
|
||||
|
@ -111,8 +113,18 @@ void nxt_conf_set_member(nxt_conf_value_t *object, nxt_str_t *name,
|
|||
nxt_conf_value_t *value, uint32_t index);
|
||||
void nxt_conf_set_member_string(nxt_conf_value_t *object, nxt_str_t *name,
|
||||
nxt_str_t *value, uint32_t index);
|
||||
nxt_int_t nxt_conf_set_member_string_dup(nxt_conf_value_t *object, nxt_mp_t *mp,
|
||||
nxt_str_t *name, nxt_str_t *value, uint32_t index);
|
||||
void nxt_conf_set_member_integer(nxt_conf_value_t *object, nxt_str_t *name,
|
||||
int64_t value, uint32_t index);
|
||||
void nxt_conf_set_member_null(nxt_conf_value_t *object, nxt_str_t *name,
|
||||
uint32_t index);
|
||||
|
||||
nxt_conf_value_t *nxt_conf_create_array(nxt_mp_t *mp, nxt_uint_t count);
|
||||
void nxt_conf_set_element(nxt_conf_value_t *array, nxt_uint_t index,
|
||||
nxt_conf_value_t *value);
|
||||
nxt_int_t nxt_conf_set_element_string_dup(nxt_conf_value_t *array, nxt_mp_t *mp,
|
||||
nxt_uint_t index, nxt_str_t *value);
|
||||
|
||||
|
||||
#endif /* _NXT_CONF_INCLUDED_ */
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <nxt_main.h>
|
||||
#include <nxt_conf.h>
|
||||
#include <nxt_cert.h>
|
||||
#include <nxt_router.h>
|
||||
|
||||
|
||||
|
@ -49,6 +50,10 @@ static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt,
|
|||
|
||||
static nxt_int_t nxt_conf_vldt_listener(nxt_conf_validation_t *vldt,
|
||||
nxt_str_t *name, nxt_conf_value_t *value);
|
||||
#if (NXT_TLS)
|
||||
static nxt_int_t nxt_conf_vldt_certificate(nxt_conf_validation_t *vldt,
|
||||
nxt_conf_value_t *value, void *data);
|
||||
#endif
|
||||
static nxt_int_t nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt,
|
||||
nxt_conf_value_t *value, void *data);
|
||||
static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt,
|
||||
|
@ -138,12 +143,35 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_root_members[] = {
|
|||
};
|
||||
|
||||
|
||||
#if (NXT_TLS)
|
||||
|
||||
static nxt_conf_vldt_object_t nxt_conf_vldt_tls_members[] = {
|
||||
{ nxt_string("certificate"),
|
||||
NXT_CONF_VLDT_STRING,
|
||||
&nxt_conf_vldt_certificate,
|
||||
NULL },
|
||||
|
||||
NXT_CONF_VLDT_END
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = {
|
||||
{ nxt_string("application"),
|
||||
NXT_CONF_VLDT_STRING,
|
||||
&nxt_conf_vldt_app_name,
|
||||
NULL },
|
||||
|
||||
#if (NXT_TLS)
|
||||
|
||||
{ nxt_string("tls"),
|
||||
NXT_CONF_VLDT_OBJECT,
|
||||
&nxt_conf_vldt_object,
|
||||
(void *) &nxt_conf_vldt_tls_members },
|
||||
|
||||
#endif
|
||||
|
||||
NXT_CONF_VLDT_END
|
||||
};
|
||||
|
||||
|
@ -467,6 +495,30 @@ nxt_conf_vldt_listener(nxt_conf_validation_t *vldt, nxt_str_t *name,
|
|||
}
|
||||
|
||||
|
||||
#if (NXT_TLS)
|
||||
|
||||
static nxt_int_t
|
||||
nxt_conf_vldt_certificate(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
||||
void *data)
|
||||
{
|
||||
nxt_str_t name;
|
||||
nxt_conf_value_t *cert;
|
||||
|
||||
nxt_conf_get_string(value, &name);
|
||||
|
||||
cert = nxt_cert_info_get(&name);
|
||||
|
||||
if (cert == NULL) {
|
||||
return nxt_conf_vldt_error(vldt, "Certificate \"%V\" is not found.",
|
||||
&name);
|
||||
}
|
||||
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static nxt_int_t
|
||||
nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
|
||||
void *data)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <nxt_runtime.h>
|
||||
#include <nxt_main_process.h>
|
||||
#include <nxt_conf.h>
|
||||
#include <nxt_cert.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -72,6 +73,15 @@ static nxt_int_t nxt_controller_request_content_length(void *ctx,
|
|||
|
||||
static void nxt_controller_process_request(nxt_task_t *task,
|
||||
nxt_controller_request_t *req);
|
||||
static void nxt_controller_process_config(nxt_task_t *task,
|
||||
nxt_controller_request_t *req, nxt_str_t *path);
|
||||
#if (NXT_TLS)
|
||||
static void nxt_controller_process_cert(nxt_task_t *task,
|
||||
nxt_controller_request_t *req, nxt_str_t *path);
|
||||
static void nxt_controller_process_cert_save(nxt_task_t *task,
|
||||
nxt_port_recv_msg_t *msg, void *data);
|
||||
static nxt_bool_t nxt_controller_cert_in_use(nxt_str_t *name);
|
||||
#endif
|
||||
static void nxt_controller_conf_handler(nxt_task_t *task,
|
||||
nxt_port_recv_msg_t *msg, void *data);
|
||||
static void nxt_controller_conf_store(nxt_task_t *task,
|
||||
|
@ -124,6 +134,7 @@ nxt_controller_start(nxt_task_t *task, void *data)
|
|||
nxt_conf_value_t *conf;
|
||||
nxt_event_engine_t *engine;
|
||||
nxt_conf_validation_t vldt;
|
||||
nxt_controller_init_t *init;
|
||||
|
||||
rt = task->thread->runtime;
|
||||
|
||||
|
@ -144,9 +155,20 @@ nxt_controller_start(nxt_task_t *task, void *data)
|
|||
|
||||
nxt_queue_init(&nxt_controller_waiting_requests);
|
||||
|
||||
json = data;
|
||||
init = data;
|
||||
|
||||
if (json->length == 0) {
|
||||
#if (NXT_TLS)
|
||||
|
||||
if (init->certs != NULL) {
|
||||
nxt_cert_info_init(task, init->certs);
|
||||
nxt_cert_store_release(init->certs);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
json = &init->conf;
|
||||
|
||||
if (json->start == NULL) {
|
||||
return NXT_OK;
|
||||
}
|
||||
|
||||
|
@ -789,10 +811,131 @@ nxt_controller_request_content_length(void *ctx, nxt_http_field_t *field,
|
|||
|
||||
static void
|
||||
nxt_controller_process_request(nxt_task_t *task, nxt_controller_request_t *req)
|
||||
{
|
||||
uint32_t i, count;
|
||||
nxt_str_t path;
|
||||
nxt_conn_t *c;
|
||||
nxt_conf_value_t *value;
|
||||
nxt_controller_response_t resp;
|
||||
#if (NXT_TLS)
|
||||
nxt_conf_value_t *certs;
|
||||
|
||||
static nxt_str_t certificates = nxt_string("certificates");
|
||||
#endif
|
||||
static nxt_str_t config = nxt_string("config");
|
||||
|
||||
c = req->conn;
|
||||
path = req->parser.path;
|
||||
|
||||
if (path.length > 1 && path.start[path.length - 1] == '/') {
|
||||
path.length--;
|
||||
}
|
||||
|
||||
if (nxt_str_start(&path, "/config", 7)
|
||||
&& (path.length == 7 || path.start[7] == '/'))
|
||||
{
|
||||
if (path.length == 7) {
|
||||
path.length = 1;
|
||||
|
||||
} else {
|
||||
path.length -= 7;
|
||||
path.start += 7;
|
||||
}
|
||||
|
||||
nxt_controller_process_config(task, req, &path);
|
||||
return;
|
||||
}
|
||||
|
||||
#if (NXT_TLS)
|
||||
|
||||
if (nxt_str_start(&path, "/certificates", 13)
|
||||
&& (path.length == 13 || path.start[13] == '/'))
|
||||
{
|
||||
if (path.length == 13) {
|
||||
path.length = 1;
|
||||
|
||||
} else {
|
||||
path.length -= 13;
|
||||
path.start += 13;
|
||||
}
|
||||
|
||||
nxt_controller_process_cert(task, req, &path);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
nxt_memzero(&resp, sizeof(nxt_controller_response_t));
|
||||
|
||||
if (path.length == 1 && path.start[0] == '/') {
|
||||
|
||||
if (!nxt_str_eq(&req->parser.method, "GET", 3)) {
|
||||
goto invalid_method;
|
||||
}
|
||||
|
||||
count = 1;
|
||||
#if (NXT_TLS)
|
||||
count++;
|
||||
#endif
|
||||
|
||||
value = nxt_conf_create_object(c->mem_pool, count);
|
||||
if (nxt_slow_path(value == NULL)) {
|
||||
goto alloc_fail;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
#if (NXT_TLS)
|
||||
certs = nxt_cert_info_get_all(c->mem_pool);
|
||||
if (nxt_slow_path(certs == NULL)) {
|
||||
goto alloc_fail;
|
||||
}
|
||||
|
||||
nxt_conf_set_member(value, &certificates, certs, i++);
|
||||
#endif
|
||||
|
||||
nxt_conf_set_member(value, &config, nxt_controller_conf.root, i);
|
||||
|
||||
resp.status = 200;
|
||||
resp.conf = value;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
}
|
||||
|
||||
resp.status = 404;
|
||||
resp.title = (u_char *) "Value doesn't exist.";
|
||||
resp.offset = -1;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
|
||||
invalid_method:
|
||||
|
||||
resp.status = 405;
|
||||
resp.title = (u_char *) "Invalid method.";
|
||||
resp.offset = -1;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
|
||||
alloc_fail:
|
||||
|
||||
resp.status = 500;
|
||||
resp.title = (u_char *) "Memory allocation failed.";
|
||||
resp.offset = -1;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req,
|
||||
nxt_str_t *path)
|
||||
{
|
||||
nxt_mp_t *mp;
|
||||
nxt_int_t rc;
|
||||
nxt_str_t path;
|
||||
nxt_conn_t *c;
|
||||
nxt_buf_mem_t *mbuf;
|
||||
nxt_conf_op_t *ops;
|
||||
|
@ -803,29 +946,13 @@ nxt_controller_process_request(nxt_task_t *task, nxt_controller_request_t *req)
|
|||
|
||||
static const nxt_str_t empty_obj = nxt_string("{}");
|
||||
|
||||
c = req->conn;
|
||||
path = req->parser.path;
|
||||
|
||||
if (nxt_str_start(&path, "/config", 7)) {
|
||||
|
||||
if (path.length == 7) {
|
||||
path.length = 1;
|
||||
|
||||
} else if (path.start[7] == '/') {
|
||||
path.length -= 7;
|
||||
path.start += 7;
|
||||
}
|
||||
}
|
||||
|
||||
if (path.length > 1 && path.start[path.length - 1] == '/') {
|
||||
path.length--;
|
||||
}
|
||||
|
||||
nxt_memzero(&resp, sizeof(nxt_controller_response_t));
|
||||
|
||||
c = req->conn;
|
||||
|
||||
if (nxt_str_eq(&req->parser.method, "GET", 3)) {
|
||||
|
||||
value = nxt_conf_get_path(nxt_controller_conf.root, &path);
|
||||
value = nxt_conf_get_path(nxt_controller_conf.root, path);
|
||||
|
||||
if (value == NULL) {
|
||||
goto not_found;
|
||||
|
@ -877,10 +1004,10 @@ nxt_controller_process_request(nxt_task_t *task, nxt_controller_request_t *req)
|
|||
return;
|
||||
}
|
||||
|
||||
if (path.length != 1) {
|
||||
if (path->length != 1) {
|
||||
rc = nxt_conf_op_compile(c->mem_pool, &ops,
|
||||
nxt_controller_conf.root,
|
||||
&path, value);
|
||||
path, value);
|
||||
|
||||
if (rc != NXT_OK) {
|
||||
nxt_mp_destroy(mp);
|
||||
|
@ -948,7 +1075,7 @@ nxt_controller_process_request(nxt_task_t *task, nxt_controller_request_t *req)
|
|||
return;
|
||||
}
|
||||
|
||||
if (path.length == 1) {
|
||||
if (path->length == 1) {
|
||||
mp = nxt_mp_create(1024, 128, 256, 32);
|
||||
|
||||
if (nxt_slow_path(mp == NULL)) {
|
||||
|
@ -960,7 +1087,7 @@ nxt_controller_process_request(nxt_task_t *task, nxt_controller_request_t *req)
|
|||
} else {
|
||||
rc = nxt_conf_op_compile(c->mem_pool, &ops,
|
||||
nxt_controller_conf.root,
|
||||
&path, NULL);
|
||||
path, NULL);
|
||||
|
||||
if (rc != NXT_OK) {
|
||||
if (rc == NXT_DECLINED) {
|
||||
|
@ -1070,6 +1197,265 @@ nxt_controller_process_request(nxt_task_t *task, nxt_controller_request_t *req)
|
|||
}
|
||||
|
||||
|
||||
#if (NXT_TLS)
|
||||
|
||||
static void
|
||||
nxt_controller_process_cert(nxt_task_t *task,
|
||||
nxt_controller_request_t *req, nxt_str_t *path)
|
||||
{
|
||||
u_char *p;
|
||||
nxt_str_t name;
|
||||
nxt_int_t ret;
|
||||
nxt_conn_t *c;
|
||||
nxt_cert_t *cert;
|
||||
nxt_conf_value_t *value;
|
||||
nxt_controller_response_t resp;
|
||||
|
||||
name.length = path->length - 1;
|
||||
name.start = path->start + 1;
|
||||
|
||||
p = nxt_memchr(name.start, '/', name.length);
|
||||
|
||||
if (p != NULL) {
|
||||
name.length = p - name.start;
|
||||
|
||||
path->length -= p - path->start;
|
||||
path->start = p;
|
||||
|
||||
} else {
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
nxt_memzero(&resp, sizeof(nxt_controller_response_t));
|
||||
|
||||
c = req->conn;
|
||||
|
||||
if (nxt_str_eq(&req->parser.method, "GET", 3)) {
|
||||
|
||||
if (name.length != 0) {
|
||||
value = nxt_cert_info_get(&name);
|
||||
if (value == NULL) {
|
||||
goto cert_not_found;
|
||||
}
|
||||
|
||||
if (path != NULL) {
|
||||
value = nxt_conf_get_path(value, path);
|
||||
if (value == NULL) {
|
||||
goto not_found;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
value = nxt_cert_info_get_all(c->mem_pool);
|
||||
if (value == NULL) {
|
||||
goto alloc_fail;
|
||||
}
|
||||
}
|
||||
|
||||
resp.status = 200;
|
||||
resp.conf = value;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (name.length == 0 || path != NULL) {
|
||||
goto invalid_name;
|
||||
}
|
||||
|
||||
if (nxt_str_eq(&req->parser.method, "PUT", 3)) {
|
||||
value = nxt_cert_info_get(&name);
|
||||
if (value != NULL) {
|
||||
goto exists_cert;
|
||||
}
|
||||
|
||||
cert = nxt_cert_mem(task, &c->read->mem);
|
||||
if (cert == NULL) {
|
||||
goto invalid_cert;
|
||||
}
|
||||
|
||||
ret = nxt_cert_info_save(&name, cert);
|
||||
|
||||
nxt_cert_destroy(cert);
|
||||
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
goto alloc_fail;
|
||||
}
|
||||
|
||||
nxt_cert_store_get(task, &name, c->mem_pool,
|
||||
nxt_controller_process_cert_save, req);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nxt_str_eq(&req->parser.method, "DELETE", 6)) {
|
||||
|
||||
if (nxt_controller_cert_in_use(&name)) {
|
||||
goto cert_in_use;
|
||||
}
|
||||
|
||||
if (nxt_cert_info_delete(&name) != NXT_OK) {
|
||||
goto cert_not_found;
|
||||
}
|
||||
|
||||
nxt_cert_store_delete(task, &name, c->mem_pool);
|
||||
|
||||
resp.status = 200;
|
||||
resp.title = (u_char *) "Certificate deleted.";
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
}
|
||||
|
||||
resp.status = 405;
|
||||
resp.title = (u_char *) "Invalid method.";
|
||||
resp.offset = -1;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
|
||||
invalid_name:
|
||||
|
||||
resp.status = 400;
|
||||
resp.title = (u_char *) "Invalid certificate name.";
|
||||
resp.offset = -1;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
|
||||
invalid_cert:
|
||||
|
||||
resp.status = 400;
|
||||
resp.title = (u_char *) "Invalid certificate.";
|
||||
resp.offset = -1;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
|
||||
exists_cert:
|
||||
|
||||
resp.status = 400;
|
||||
resp.title = (u_char *) "Certificate already exists.";
|
||||
resp.offset = -1;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
|
||||
cert_in_use:
|
||||
|
||||
resp.status = 400;
|
||||
resp.title = (u_char *) "Certificate is used in the configuration.";
|
||||
resp.offset = -1;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
|
||||
cert_not_found:
|
||||
|
||||
resp.status = 404;
|
||||
resp.title = (u_char *) "Certificate doesn't exist.";
|
||||
resp.offset = -1;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
|
||||
not_found:
|
||||
|
||||
resp.status = 404;
|
||||
resp.title = (u_char *) "Invalid path.";
|
||||
resp.offset = -1;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
|
||||
alloc_fail:
|
||||
|
||||
resp.status = 500;
|
||||
resp.title = (u_char *) "Memory allocation failed.";
|
||||
resp.offset = -1;
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nxt_controller_process_cert_save(nxt_task_t *task, nxt_port_recv_msg_t *msg,
|
||||
void *data)
|
||||
{
|
||||
nxt_conn_t *c;
|
||||
nxt_buf_mem_t *mbuf;
|
||||
nxt_controller_request_t *req;
|
||||
nxt_controller_response_t resp;
|
||||
|
||||
req = data;
|
||||
|
||||
nxt_memzero(&resp, sizeof(nxt_controller_response_t));
|
||||
|
||||
if (msg == NULL || msg->port_msg.type == _NXT_PORT_MSG_RPC_ERROR) {
|
||||
resp.status = 500;
|
||||
resp.title = (u_char *) "Failed to store certificate.";
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
return;
|
||||
}
|
||||
|
||||
c = req->conn;
|
||||
|
||||
mbuf = &c->read->mem;
|
||||
|
||||
nxt_fd_write(msg->fd, mbuf->pos, nxt_buf_mem_used_size(mbuf));
|
||||
|
||||
nxt_fd_close(msg->fd);
|
||||
|
||||
nxt_memzero(&resp, sizeof(nxt_controller_response_t));
|
||||
|
||||
resp.status = 200;
|
||||
resp.title = (u_char *) "Certificate chain uploaded.";
|
||||
|
||||
nxt_controller_response(task, req, &resp);
|
||||
}
|
||||
|
||||
|
||||
static nxt_bool_t
|
||||
nxt_controller_cert_in_use(nxt_str_t *name)
|
||||
{
|
||||
uint32_t next;
|
||||
nxt_str_t str;
|
||||
nxt_conf_value_t *listeners, *listener, *value;
|
||||
|
||||
static nxt_str_t listeners_path = nxt_string("/listeners");
|
||||
static nxt_str_t certificate_path = nxt_string("/tls/certificate");
|
||||
|
||||
listeners = nxt_conf_get_path(nxt_controller_conf.root, &listeners_path);
|
||||
|
||||
if (listeners != NULL) {
|
||||
next = 0;
|
||||
|
||||
for ( ;; ) {
|
||||
listener = nxt_conf_next_object_member(listeners, &str, &next);
|
||||
if (listener == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
value = nxt_conf_get_path(listener, &certificate_path);
|
||||
if (value == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nxt_conf_get_string(value, &str);
|
||||
|
||||
if (nxt_strstr_eq(&str, name)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
nxt_controller_conf_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg,
|
||||
void *data)
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#include <nxt_main_process.h>
|
||||
#include <nxt_conf.h>
|
||||
#include <nxt_router.h>
|
||||
#if (NXT_TLS)
|
||||
#include <nxt_cert.h>
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -336,6 +339,10 @@ static nxt_port_handlers_t nxt_main_process_port_handlers = {
|
|||
.socket = nxt_main_port_socket_handler,
|
||||
.modules = nxt_main_port_modules_handler,
|
||||
.conf_store = nxt_main_port_conf_store_handler,
|
||||
#if (NXT_TLS)
|
||||
.cert_get = nxt_cert_store_get_handler,
|
||||
.cert_delete = nxt_cert_store_delete_handler,
|
||||
#endif
|
||||
.access_log = nxt_main_port_access_log_handler,
|
||||
.rpc_ready = nxt_port_rpc_handler,
|
||||
.rpc_error = nxt_port_rpc_handler,
|
||||
|
@ -439,13 +446,16 @@ static nxt_int_t
|
|||
nxt_main_create_controller_process(nxt_task_t *task, nxt_runtime_t *rt,
|
||||
nxt_process_init_t *init)
|
||||
{
|
||||
ssize_t n;
|
||||
nxt_int_t ret;
|
||||
nxt_str_t conf;
|
||||
nxt_file_t file;
|
||||
nxt_file_info_t fi;
|
||||
ssize_t n;
|
||||
nxt_int_t ret;
|
||||
nxt_str_t *conf;
|
||||
nxt_file_t file;
|
||||
nxt_file_info_t fi;
|
||||
nxt_controller_init_t ctrl_init;
|
||||
|
||||
conf.length = 0;
|
||||
nxt_memzero(&ctrl_init, sizeof(nxt_controller_init_t));
|
||||
|
||||
conf = &ctrl_init.conf;
|
||||
|
||||
nxt_memzero(&file, sizeof(nxt_file_t));
|
||||
|
||||
|
@ -457,19 +467,19 @@ nxt_main_create_controller_process(nxt_task_t *task, nxt_runtime_t *rt,
|
|||
ret = nxt_file_info(&file, &fi);
|
||||
|
||||
if (nxt_fast_path(ret == NXT_OK && nxt_is_file(&fi))) {
|
||||
conf.length = nxt_file_size(&fi);
|
||||
conf.start = nxt_malloc(conf.length);
|
||||
conf->length = nxt_file_size(&fi);
|
||||
conf->start = nxt_malloc(conf->length);
|
||||
|
||||
if (nxt_slow_path(conf.start == NULL)) {
|
||||
if (nxt_slow_path(conf->start == NULL)) {
|
||||
nxt_file_close(task, &file);
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
n = nxt_file_read(&file, conf.start, conf.length, 0);
|
||||
n = nxt_file_read(&file, conf->start, conf->length, 0);
|
||||
|
||||
if (nxt_slow_path(n != (ssize_t) conf.length)) {
|
||||
conf.length = 0;
|
||||
nxt_free(conf.start);
|
||||
if (nxt_slow_path(n != (ssize_t) conf->length)) {
|
||||
nxt_free(conf->start);
|
||||
conf->start = NULL;
|
||||
|
||||
nxt_alert(task, "failed to restore previous configuration: "
|
||||
"cannot read the file");
|
||||
|
@ -479,12 +489,24 @@ nxt_main_create_controller_process(nxt_task_t *task, nxt_runtime_t *rt,
|
|||
nxt_file_close(task, &file);
|
||||
}
|
||||
|
||||
init->data = &conf;
|
||||
#if (NXT_TLS)
|
||||
ctrl_init.certs = nxt_cert_store_load(task);
|
||||
#endif
|
||||
|
||||
init->data = &ctrl_init;
|
||||
|
||||
ret = nxt_main_create_worker_process(task, rt, init);
|
||||
|
||||
if (ret == NXT_OK && conf.length != 0) {
|
||||
nxt_free(conf.start);
|
||||
if (ret == NXT_OK) {
|
||||
if (conf->start != NULL) {
|
||||
nxt_free(conf->start);
|
||||
}
|
||||
|
||||
#if (NXT_TLS)
|
||||
if (ctrl_init.certs != NULL) {
|
||||
nxt_cert_store_release(ctrl_init.certs);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -19,6 +19,14 @@ typedef enum {
|
|||
} nxt_socket_error_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
nxt_str_t conf;
|
||||
#if (NXT_TLS)
|
||||
nxt_array_t *certs;
|
||||
#endif
|
||||
} nxt_controller_init_t;
|
||||
|
||||
|
||||
nxt_int_t nxt_main_process_start(nxt_thread_t *thr, nxt_task_t *task,
|
||||
nxt_runtime_t *runtime);
|
||||
void nxt_main_stop_all_processes(nxt_task_t *task, nxt_runtime_t *runtime);
|
||||
|
|
|
@ -40,6 +40,7 @@ static void nxt_openssl_locks_free(void);
|
|||
#endif
|
||||
static nxt_int_t nxt_openssl_server_init(nxt_task_t *task,
|
||||
nxt_tls_conf_t *conf);
|
||||
static nxt_uint_t nxt_openssl_chain_file(SSL_CTX *ctx, nxt_fd_t fd);
|
||||
static void nxt_openssl_server_free(nxt_task_t *task, nxt_tls_conf_t *conf);
|
||||
static void nxt_openssl_conn_init(nxt_task_t *task, nxt_tls_conf_t *conf,
|
||||
nxt_conn_t *c);
|
||||
|
@ -246,7 +247,8 @@ static nxt_int_t
|
|||
nxt_openssl_server_init(nxt_task_t *task, nxt_tls_conf_t *conf)
|
||||
{
|
||||
SSL_CTX *ctx;
|
||||
const char *certificate, *key, *ciphers, *ca_certificate;
|
||||
nxt_fd_t fd;
|
||||
const char *ciphers, *ca_certificate;
|
||||
STACK_OF(X509_NAME) *list;
|
||||
|
||||
ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
|
@ -284,15 +286,14 @@ nxt_openssl_server_init(nxt_task_t *task, nxt_tls_conf_t *conf)
|
|||
|
||||
#endif
|
||||
|
||||
certificate = conf->certificate;
|
||||
fd = conf->chain_file;
|
||||
|
||||
if (SSL_CTX_use_certificate_chain_file(ctx, certificate) == 0) {
|
||||
if (nxt_openssl_chain_file(ctx, fd) != NXT_OK) {
|
||||
nxt_openssl_log_error(task, NXT_LOG_ALERT,
|
||||
"SSL_CTX_use_certificate_file(\"%s\") failed",
|
||||
certificate);
|
||||
"nxt_openssl_chain_file() failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
key = conf->certificate_key;
|
||||
|
||||
if (SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM) == 0) {
|
||||
|
@ -301,7 +302,7 @@ nxt_openssl_server_init(nxt_task_t *task, nxt_tls_conf_t *conf)
|
|||
key);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*/
|
||||
ciphers = (conf->ciphers != NULL) ? conf->ciphers : "HIGH:!aNULL:!MD5";
|
||||
|
||||
if (SSL_CTX_set_cipher_list(ctx, ciphers) == 0) {
|
||||
|
@ -358,6 +359,85 @@ nxt_openssl_server_init(nxt_task_t *task, nxt_tls_conf_t *conf)
|
|||
}
|
||||
|
||||
|
||||
static nxt_uint_t
|
||||
nxt_openssl_chain_file(SSL_CTX *ctx, nxt_fd_t fd)
|
||||
{
|
||||
BIO *bio;
|
||||
X509 *cert, *ca;
|
||||
long reason;
|
||||
EVP_PKEY *key;
|
||||
nxt_uint_t ret;
|
||||
|
||||
bio = BIO_new(BIO_s_fd());
|
||||
if (bio == NULL) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
BIO_set_fd(bio, fd, BIO_CLOSE);
|
||||
|
||||
ret = NXT_ERROR;
|
||||
|
||||
cert = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
|
||||
if (cert == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_certificate(ctx, cert) != 1) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
for ( ;; ) {
|
||||
ca = PEM_read_bio_X509(bio, NULL, NULL, NULL);
|
||||
|
||||
if (ca == NULL) {
|
||||
reason = ERR_GET_REASON(ERR_peek_last_error());
|
||||
if (reason != PEM_R_NO_START_LINE) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that ca isn't freed if it was successfully added to the chain,
|
||||
* while the main certificate needs a X509_free() call, since
|
||||
* its reference count is increased by SSL_CTX_use_certificate().
|
||||
*/
|
||||
#if OPENSSL_VERSION_NUMBER > 0x10002000L
|
||||
if (SSL_CTX_add0_chain_cert(ctx, ca) != 1) {
|
||||
#else
|
||||
if (SSL_CTX_add_extra_chain_cert(ctx, ca) != 1) {
|
||||
#endif
|
||||
X509_free(ca);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (BIO_reset(bio) != 0) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
key = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
|
||||
if (key == NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (SSL_CTX_use_PrivateKey(ctx, key) == 1) {
|
||||
ret = NXT_OK;
|
||||
}
|
||||
|
||||
EVP_PKEY_free(key);
|
||||
|
||||
end:
|
||||
|
||||
X509_free(cert);
|
||||
BIO_free(bio);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nxt_openssl_server_free(nxt_task_t *task, nxt_tls_conf_t *conf)
|
||||
{
|
||||
|
|
|
@ -18,6 +18,8 @@ struct nxt_port_handlers_s {
|
|||
nxt_port_handler_t socket;
|
||||
nxt_port_handler_t modules;
|
||||
nxt_port_handler_t conf_store;
|
||||
nxt_port_handler_t cert_get;
|
||||
nxt_port_handler_t cert_delete;
|
||||
nxt_port_handler_t access_log;
|
||||
|
||||
/* File descriptor exchange. */
|
||||
|
@ -57,6 +59,8 @@ typedef enum {
|
|||
_NXT_PORT_MSG_SOCKET = nxt_port_handler_idx(socket),
|
||||
_NXT_PORT_MSG_MODULES = nxt_port_handler_idx(modules),
|
||||
_NXT_PORT_MSG_CONF_STORE = nxt_port_handler_idx(conf_store),
|
||||
_NXT_PORT_MSG_CERT_GET = nxt_port_handler_idx(cert_get),
|
||||
_NXT_PORT_MSG_CERT_DELETE = nxt_port_handler_idx(cert_delete),
|
||||
_NXT_PORT_MSG_ACCESS_LOG = nxt_port_handler_idx(access_log),
|
||||
|
||||
_NXT_PORT_MSG_CHANGE_FILE = nxt_port_handler_idx(change_file),
|
||||
|
@ -81,6 +85,8 @@ typedef enum {
|
|||
NXT_PORT_MSG_SOCKET = _NXT_PORT_MSG_SOCKET | NXT_PORT_MSG_LAST,
|
||||
NXT_PORT_MSG_MODULES = _NXT_PORT_MSG_MODULES | NXT_PORT_MSG_LAST,
|
||||
NXT_PORT_MSG_CONF_STORE = _NXT_PORT_MSG_CONF_STORE | NXT_PORT_MSG_LAST,
|
||||
NXT_PORT_MSG_CERT_GET = _NXT_PORT_MSG_CERT_GET | NXT_PORT_MSG_LAST,
|
||||
NXT_PORT_MSG_CERT_DELETE = _NXT_PORT_MSG_CERT_DELETE | NXT_PORT_MSG_LAST,
|
||||
NXT_PORT_MSG_ACCESS_LOG = _NXT_PORT_MSG_ACCESS_LOG | NXT_PORT_MSG_LAST,
|
||||
|
||||
NXT_PORT_MSG_CHANGE_FILE = _NXT_PORT_MSG_CHANGE_FILE | NXT_PORT_MSG_LAST,
|
||||
|
|
136
src/nxt_router.c
136
src/nxt_router.c
|
@ -7,6 +7,9 @@
|
|||
|
||||
#include <nxt_router.h>
|
||||
#include <nxt_conf.h>
|
||||
#if (NXT_TLS)
|
||||
#include <nxt_cert.h>
|
||||
#endif
|
||||
#include <nxt_http.h>
|
||||
#include <nxt_port_memory_int.h>
|
||||
#include <nxt_unit_request.h>
|
||||
|
@ -32,6 +35,18 @@ typedef struct {
|
|||
} nxt_router_listener_conf_t;
|
||||
|
||||
|
||||
#if (NXT_TLS)
|
||||
|
||||
typedef struct {
|
||||
nxt_str_t name;
|
||||
nxt_socket_conf_t *conf;
|
||||
|
||||
nxt_queue_link_t link; /* for nxt_socket_conf_t.tls */
|
||||
} nxt_router_tlssock_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct nxt_msg_info_s {
|
||||
nxt_buf_t *buf;
|
||||
nxt_port_mmap_tracking_t tracking;
|
||||
|
@ -156,6 +171,12 @@ static void nxt_router_listen_socket_ready(nxt_task_t *task,
|
|||
nxt_port_recv_msg_t *msg, void *data);
|
||||
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);
|
||||
static void nxt_router_tls_rpc_handler(nxt_task_t *task,
|
||||
nxt_port_recv_msg_t *msg, void *data);
|
||||
#endif
|
||||
static void nxt_router_app_rpc_create(nxt_task_t *task,
|
||||
nxt_router_temp_conf_t *tmcf, nxt_app_t *app);
|
||||
static void nxt_router_app_prefork_ready(nxt_task_t *task,
|
||||
|
@ -957,6 +978,10 @@ nxt_router_temp_conf(nxt_task_t *task)
|
|||
nxt_queue_init(&tmcf->pending);
|
||||
nxt_queue_init(&tmcf->creating);
|
||||
|
||||
#if (NXT_TLS)
|
||||
nxt_queue_init(&tmcf->tls);
|
||||
#endif
|
||||
|
||||
nxt_queue_init(&tmcf->apps);
|
||||
nxt_queue_init(&tmcf->previous);
|
||||
|
||||
|
@ -1002,6 +1027,9 @@ nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data)
|
|||
nxt_router_conf_t *rtcf;
|
||||
nxt_router_temp_conf_t *tmcf;
|
||||
const nxt_event_interface_t *interface;
|
||||
#if (NXT_TLS)
|
||||
nxt_router_tlssock_t *tls;
|
||||
#endif
|
||||
|
||||
tmcf = obj;
|
||||
|
||||
|
@ -1018,6 +1046,19 @@ nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data)
|
|||
return;
|
||||
}
|
||||
|
||||
#if (NXT_TLS)
|
||||
qlk = nxt_queue_first(&tmcf->tls);
|
||||
|
||||
if (qlk != nxt_queue_tail(&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);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
nxt_queue_each(app, &tmcf->apps, nxt_app_t, link) {
|
||||
|
||||
if (nxt_router_app_need_start(app)) {
|
||||
|
@ -1332,11 +1373,17 @@ 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");
|
||||
static nxt_str_t listeners_path = nxt_string("/listeners");
|
||||
static nxt_str_t access_log_path = nxt_string("/access_log");
|
||||
#if (NXT_TLS)
|
||||
static nxt_str_t certificate_path = nxt_string("/tls/certificate");
|
||||
#endif
|
||||
|
||||
conf = nxt_conf_json_parse(tmcf->mem_pool, start, end, NULL);
|
||||
if (conf == NULL) {
|
||||
|
@ -1588,6 +1635,26 @@ 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);
|
||||
|
||||
if (value != NULL) {
|
||||
nxt_conf_get_string(value, &name);
|
||||
|
||||
tls = nxt_mp_get(mp, sizeof(nxt_router_tlssock_t));
|
||||
if (nxt_slow_path(tls == NULL)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
tls->name = name;
|
||||
tls->conf = skcf;
|
||||
|
||||
nxt_queue_insert_tail(&tmcf->tls, &tls->link);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
skcf->listen->handler = nxt_http_conn_init;
|
||||
skcf->router_conf = tmcf->router_conf;
|
||||
skcf->router_conf->count++;
|
||||
|
@ -1956,6 +2023,75 @@ nxt_router_listen_socket_error(nxt_task_t *task, nxt_port_recv_msg_t *msg,
|
|||
}
|
||||
|
||||
|
||||
#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_socket_rpc_t *rpc;
|
||||
|
||||
rpc = nxt_mp_alloc(tmcf->mem_pool, sizeof(nxt_socket_rpc_t));
|
||||
if (rpc == NULL) {
|
||||
nxt_router_conf_error(task, tmcf);
|
||||
return;
|
||||
}
|
||||
|
||||
rpc->socket_conf = tls->conf;
|
||||
rpc->temp_conf = tmcf;
|
||||
|
||||
nxt_cert_store_get(task, &tls->name, tmcf->mem_pool,
|
||||
nxt_router_tls_rpc_handler, rpc);
|
||||
}
|
||||
|
||||
|
||||
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_debug(task, "tls rpc handler");
|
||||
|
||||
rpc = data;
|
||||
tmcf = rpc->temp_conf;
|
||||
|
||||
if (msg == NULL || msg->port_msg.type == _NXT_PORT_MSG_RPC_ERROR) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
mp = tmcf->router_conf->mem_pool;
|
||||
|
||||
tlscf = nxt_mp_zget(mp, sizeof(nxt_tls_conf_t));
|
||||
if (nxt_slow_path(tlscf == NULL)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
tlscf->chain_file = msg->fd;
|
||||
|
||||
ret = task->thread->runtime->tls->server_init(task, tlscf);
|
||||
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;
|
||||
|
||||
fail:
|
||||
|
||||
nxt_router_conf_error(task, tmcf);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
nxt_router_app_rpc_create(nxt_task_t *task,
|
||||
nxt_router_temp_conf_t *tmcf, nxt_app_t *app)
|
||||
|
|
|
@ -59,6 +59,10 @@ typedef struct {
|
|||
nxt_queue_t keeping; /* of nxt_socket_conf_t */
|
||||
nxt_queue_t deleting; /* of nxt_socket_conf_t */
|
||||
|
||||
#if (NXT_TLS)
|
||||
nxt_queue_t tls; /* of nxt_router_tlssock_t */
|
||||
#endif
|
||||
|
||||
nxt_queue_t apps; /* of nxt_app_t */
|
||||
nxt_queue_t previous; /* of nxt_app_t */
|
||||
|
||||
|
|
|
@ -762,6 +762,23 @@ nxt_runtime_conf_init(nxt_task_t *task, nxt_runtime_t *rt)
|
|||
|
||||
rt->conf_tmp = (char *) file_name.start;
|
||||
|
||||
ret = nxt_file_name_create(rt->mem_pool, &file_name, "%s%scerts/%Z",
|
||||
rt->state, slash);
|
||||
if (nxt_slow_path(ret != NXT_OK)) {
|
||||
return NXT_ERROR;
|
||||
}
|
||||
|
||||
ret = mkdir((char *) file_name.start, S_IRWXU);
|
||||
|
||||
if (nxt_fast_path(ret == 0 || nxt_errno == EEXIST)) {
|
||||
rt->certs.length = file_name.len;
|
||||
rt->certs.start = file_name.start;
|
||||
|
||||
} else {
|
||||
nxt_alert(task, "Unable to create certificates storage directory: "
|
||||
"mkdir(%s) failed %E", file_name.start, nxt_errno);
|
||||
}
|
||||
|
||||
control.length = nxt_strlen(rt->control);
|
||||
control.start = (u_char *) rt->control;
|
||||
|
||||
|
|
|
@ -68,6 +68,8 @@ struct nxt_runtime_s {
|
|||
const char *conf_tmp;
|
||||
const char *control;
|
||||
|
||||
nxt_str_t certs;
|
||||
|
||||
nxt_queue_t engines; /* of nxt_event_engine_t */
|
||||
|
||||
nxt_sockaddr_t *controller_listen;
|
||||
|
|
|
@ -44,8 +44,7 @@ struct nxt_tls_conf_s {
|
|||
|
||||
const nxt_tls_lib_t *lib;
|
||||
|
||||
char *certificate;
|
||||
char *certificate_key;
|
||||
nxt_fd_t chain_file;
|
||||
char *ciphers;
|
||||
|
||||
char *ca_certificate;
|
||||
|
|
Loading…
Reference in a new issue