2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-02 23:55:27 +00:00

Add "protocols" options to the "tls" clause

This commit adds the ability to specify allowed TLS protocols versions
within the "tls" clause. If an unsupported TLS protocol version is
specified in a file, the configuration file will not pass
verification.

Also, this commit adds strict checks for "tls" clauses verification,
in particular:

- it ensures that loading configuration files containing duplicated
"tls" clauses is not allowed;

- it ensures that loading configuration files containing "tls" clauses
missing "cert-file" or "key-file" is not allowed;

- it ensures that loading configuration files containing "tls" clauses
named as "ephemeral" or "none" is not allowed.
This commit is contained in:
Artem Boldariev
2021-09-13 15:39:36 +03:00
parent 9e039986cd
commit 992f815770
21 changed files with 571 additions and 35 deletions

View File

@@ -567,7 +567,7 @@ TLS
dh-param quoted_string; // experimental
hostname quoted_string;
key-file quoted_string;
protocols sslprotos; // experimental
protocols { string; ... };
};
TRUST-ANCHORS

View File

@@ -413,9 +413,9 @@ named_server_reload(isc_task_t *task, isc_event_t *event);
#ifdef HAVE_LIBNGHTTP2
static isc_result_t
listenelt_http(const cfg_obj_t *http, bool tls, const char *key,
const char *cert, in_port_t port, isc_mem_t *mctx,
ns_listenelt_t **target);
listenelt_http(const cfg_obj_t *http, bool tls,
const ns_listen_tls_params_t *tls_params, in_port_t port,
isc_mem_t *mctx, ns_listenelt_t **target);
#endif
static isc_result_t
@@ -11026,6 +11026,8 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
const char *key = NULL, *cert = NULL;
bool do_tls = false, no_tls = false, http = false;
ns_listenelt_t *delt = NULL;
uint32_t tls_protos = 0;
ns_listen_tls_params_t tls_params = { 0 };
REQUIRE(target != NULL && *target == NULL);
@@ -11043,6 +11045,7 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
} else {
const cfg_obj_t *keyobj = NULL, *certobj = NULL;
const cfg_obj_t *tlsmap = NULL;
const cfg_obj_t *tls_proto_list = NULL;
do_tls = true;
@@ -11059,8 +11062,34 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
CHECK(cfg_map_get(tlsmap, "cert-file", &certobj));
cert = cfg_obj_asstring(certobj);
if (cfg_map_get(tlsmap, "protocols", &tls_proto_list) ==
ISC_R_SUCCESS) {
const cfg_listelt_t *proto = NULL;
INSIST(tls_proto_list != NULL);
for (proto = cfg_list_first(tls_proto_list);
proto != 0; proto = cfg_list_next(proto))
{
const cfg_obj_t *tls_proto_obj =
cfg_listelt_value(proto);
const char *tls_sver =
cfg_obj_asstring(tls_proto_obj);
const isc_tls_protocol_version_t ver =
isc_tls_protocol_name_to_version(
tls_sver);
INSIST(ver !=
ISC_TLS_PROTO_VER_UNDEFINED);
INSIST(isc_tls_protocol_supported(ver));
tls_protos |= ver;
}
}
}
}
tls_params = (ns_listen_tls_params_t){ .key = key,
.cert = cert,
.protocols = tls_protos };
httpobj = cfg_tuple_get(ltup, "http");
if (httpobj != NULL && cfg_obj_isstring(httpobj)) {
@@ -11144,14 +11173,14 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
#ifdef HAVE_LIBNGHTTP2
if (http) {
CHECK(listenelt_http(http_server, do_tls, key, cert, port, mctx,
&delt));
CHECK(listenelt_http(http_server, do_tls, &tls_params, port,
mctx, &delt));
}
#endif /* HAVE_LIBNGHTTP2 */
if (!http) {
CHECK(ns_listenelt_create(mctx, port, dscp, NULL, do_tls, key,
cert, &delt));
CHECK(ns_listenelt_create(mctx, port, dscp, NULL, do_tls,
&tls_params, &delt));
}
result = cfg_acl_fromconfig2(cfg_tuple_get(listener, "acl"), config,
@@ -11169,9 +11198,9 @@ cleanup:
#ifdef HAVE_LIBNGHTTP2
static isc_result_t
listenelt_http(const cfg_obj_t *http, bool tls, const char *key,
const char *cert, in_port_t port, isc_mem_t *mctx,
ns_listenelt_t **target) {
listenelt_http(const cfg_obj_t *http, bool tls,
const ns_listen_tls_params_t *tls_params, in_port_t port,
isc_mem_t *mctx, ns_listenelt_t **target) {
isc_result_t result = ISC_R_SUCCESS;
ns_listenelt_t *delt = NULL;
char **endpoints = NULL;
@@ -11184,7 +11213,11 @@ listenelt_http(const cfg_obj_t *http, bool tls, const char *key,
isc_quota_t *quota = NULL;
REQUIRE(target != NULL && *target == NULL);
REQUIRE((key == NULL) == (cert == NULL));
if (tls) {
INSIST(tls_params != NULL);
INSIST((tls_params->key == NULL) == (tls_params->cert == NULL));
}
if (port == 0) {
port = tls ? named_g_httpsport : named_g_httpport;
@@ -11239,7 +11272,7 @@ listenelt_http(const cfg_obj_t *http, bool tls, const char *key,
isc_quota_init(quota, max_clients);
}
result = ns_listenelt_create_http(mctx, port, named_g_dscp, NULL, tls,
key, cert, endpoints, len, quota,
tls_params, endpoints, len, quota,
max_streams, &delt);
if (result != ISC_R_SUCCESS) {
goto error;

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
tls local-tls {
key-file "key.pem";
cert-file "cert.pem";
protocols { unknown; TLSv1.2; }; # bad TLS protocol version name
};
options {
listen-on port 853 tls local-tls { 10.53.0.1; };
};

View File

@@ -0,0 +1,24 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
tls local-tls {
key-file "key.pem";
cert-file "cert.pem";
};
tls local-tls {
key-file "key.pem";
cert-file "cert.pem";
};
options {
listen-on port 853 tls local-tls { 10.53.0.1; };
};

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
# ephemeral is reserved for internal use
tls ephemeral {
key-file "key.pem";
cert-file "cert.pem";
};
options {
listen-on port 853 tls ephemeral { 10.53.0.1; };
};

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
tls local-tls {
key-file "key.pem";
};
http local-http-server {
endpoints { "/dns-query"; };
listener-clients 100;
streams-per-connection 100;
};
options {
listen-on { 10.53.0.1; };
http-port 80;
https-port 443;
http-listener-clients 100;
http-streams-per-connection 100;
listen-on port 443 tls local-tls http local-http-server { 10.53.0.1; };
listen-on port 8080 tls none http local-http-server { 10.53.0.1; };
};

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
tls local-tls {
cert-file "cert.pem";
};
http local-http-server {
endpoints { "/dns-query"; };
listener-clients 100;
streams-per-connection 100;
};
options {
listen-on { 10.53.0.1; };
http-port 80;
https-port 443;
http-listener-clients 100;
http-streams-per-connection 100;
listen-on port 443 tls local-tls http local-http-server { 10.53.0.1; };
listen-on port 8080 tls none http local-http-server { 10.53.0.1; };
};

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
# none is reserved for internal use
tls none {
key-file "key.pem";
cert-file "cert.pem";
};
options {
listen-on port 853 tls none { 10.53.0.1; };
};

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
tls local-tls {
protocols { TLSv1.2; };
key-file "key.pem";
cert-file "cert.pem";
};
http local-http-server {
endpoints { "/dns-query"; };
listener-clients 100;
streams-per-connection 100;
};
options {
listen-on { 10.53.0.1; };
http-port 80;
https-port 443;
http-listener-clients 100;
http-streams-per-connection 100;
listen-on port 443 tls local-tls http local-http-server { 10.53.0.1; };
listen-on port 8080 tls none http local-http-server { 10.53.0.1; };
};

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
tls local-tls {
protocols { TLSv1.2; };
key-file "key.pem";
cert-file "cert.pem";
};
options {
listen-on port 853 tls local-tls { 10.53.0.1; };
};

View File

@@ -293,7 +293,7 @@ The following statements are supported:
Declares communication channels to get access to ``named`` statistics.
``tls``
Specifies configuration information for a TLS connection, including a ``key-file``, ``cert-file``, ``ca-file`` and ``hostname``.
Specifies configuration information for a TLS connection, including a ``key-file``, ``cert-file``, ``ca-file``, ``hostname``, and ``protocols``.
``http``
Specifies configuration information for an HTTP connection, including ``endponts``, ``listener-clients`` and ``streams-per-connection``.
@@ -4772,6 +4772,12 @@ The following options can be specified in a ``tls`` statement:
``hostname``
The hostname associated with the certificate.
``protocols``
Allowed versions of the TLS protocol. TLS version 1.2 and higher are
supported, depending on the cryptographic library in use. Multiple
versions might be specified (e.g.
``protocols { TLSv1.2; TLSv1.3; };``).
There are two built-in TLS connection configurations: ``ephemeral``,
uses a temporary key and certificate created for the current ``named``
session only, and ``none``, which can be used when setting up an HTTP

View File

@@ -658,7 +658,7 @@ tls string {
dh\-param quoted_string; // experimental
hostname quoted_string;
key\-file quoted_string;
protocols sslprotos; // experimental
protocols { string; ... };
};
.ft P
.fi

View File

@@ -463,7 +463,7 @@ tls <string> {
dh-param <quoted_string>; // experimental
hostname <quoted_string>;
key-file <quoted_string>;
protocols <sslprotos>; // experimental
protocols { <string>; ... };
}; // may occur multiple times
trust-anchors { <string> ( static-key |

View File

@@ -460,7 +460,7 @@ tls <string> {
dh-param <quoted_string>; // experimental
hostname <quoted_string>;
key-file <quoted_string>;
protocols <sslprotos>; // experimental
protocols { <string>; ... };
}; // may occur multiple times
trust-anchors { <string> ( static-key |

View File

@@ -7,5 +7,5 @@
dh-param <quoted_string>; // experimental
hostname <quoted_string>;
key-file <quoted_string>;
protocols <sslprotos>; // experimental
protocols { <string>; ... };
};

View File

@@ -16,6 +16,8 @@
#include <stdbool.h>
#include <stdlib.h>
#include <openssl/opensslv.h>
#ifdef HAVE_DNSTAP
#include <fstrm.h>
#endif
@@ -2116,6 +2118,149 @@ done:
}
#endif /* HAVE_LIBNGHTTP2 */
static isc_result_t
bind9_check_tls_defintion(const cfg_obj_t *tlsobj, const char *name,
isc_log_t *logctx, isc_symtab_t *symtab) {
isc_result_t result, tresult;
const cfg_obj_t *tls_proto_list = NULL, *tls_key = NULL,
*tls_cert = NULL;
uint32_t tls_protos = 0;
isc_symvalue_t symvalue;
if (strcasecmp(name, "ephemeral") == 0 || strcasecmp(name, "none") == 0)
{
cfg_obj_log(tlsobj, logctx, ISC_LOG_ERROR,
"tls clause name '%s' is reserved for internal use",
name);
result = ISC_R_FAILURE;
} else {
/* Check for duplicates */
symvalue.as_cpointer = tlsobj;
result = isc_symtab_define(symtab, name, 1, symvalue,
isc_symexists_reject);
if (result == ISC_R_EXISTS) {
const char *file = NULL;
unsigned int line;
tresult = isc_symtab_lookup(symtab, name, 1, &symvalue);
RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
line = cfg_obj_line(symvalue.as_cpointer);
file = cfg_obj_file(symvalue.as_cpointer);
if (file == NULL) {
file = "<unknown file>";
}
cfg_obj_log(tlsobj, logctx, ISC_LOG_ERROR,
"tls clause '%s' is duplicated: "
"also defined at %s:%u",
name, file, line);
}
}
if (cfg_map_get(tlsobj, "key-file", &tls_key) != ISC_R_SUCCESS) {
cfg_obj_log(tlsobj, logctx, ISC_LOG_ERROR,
"'key-file' is required in tls clause '%s'", name);
result = ISC_R_FAILURE;
}
if (cfg_map_get(tlsobj, "cert-file", &tls_cert) != ISC_R_SUCCESS) {
cfg_obj_log(tlsobj, logctx, ISC_LOG_ERROR,
"'cert-file' is required in tls clause '%s'", name);
result = ISC_R_FAILURE;
}
/* Check protocols are valid */
tresult = cfg_map_get(tlsobj, "protocols", &tls_proto_list);
if (tresult == ISC_R_SUCCESS) {
const cfg_listelt_t *proto = NULL;
INSIST(tls_proto_list != NULL);
for (proto = cfg_list_first(tls_proto_list); proto != 0;
proto = cfg_list_next(proto))
{
const cfg_obj_t *tls_proto_obj =
cfg_listelt_value(proto);
const char *tls_sver = cfg_obj_asstring(tls_proto_obj);
const isc_tls_protocol_version_t ver =
isc_tls_protocol_name_to_version(tls_sver);
if (ver == ISC_TLS_PROTO_VER_UNDEFINED) {
cfg_obj_log(tls_proto_obj, logctx,
ISC_LOG_ERROR,
"'%s' is not a valid "
"TLS protocol version",
tls_sver);
result = ISC_R_FAILURE;
continue;
} else if (!isc_tls_protocol_supported(ver)) {
cfg_obj_log(tls_proto_obj, logctx,
ISC_LOG_ERROR,
"'%s' is not "
"supported by the "
"cryptographic library version in "
"use (%s)",
tls_sver, OPENSSL_VERSION_TEXT);
result = ISC_R_FAILURE;
}
if ((tls_protos & ver) != 0) {
cfg_obj_log(tls_proto_obj, logctx,
ISC_LOG_WARNING,
"'%s' is specified more than once "
"in '%s'",
tls_sver, name);
result = ISC_R_FAILURE;
}
tls_protos |= ver;
}
if (tls_protos == 0) {
cfg_obj_log(tlsobj, logctx, ISC_LOG_ERROR,
"tls '%s' does not contain any valid "
"TLS protocol versions definitions",
name);
result = ISC_R_FAILURE;
}
}
return (result);
}
static isc_result_t
bind9_check_tls_definitions(const cfg_obj_t *config, isc_log_t *logctx,
isc_mem_t *mctx) {
isc_result_t result, tresult;
const cfg_obj_t *obj = NULL;
const cfg_listelt_t *elt = NULL;
isc_symtab_t *symtab = NULL;
result = cfg_map_get(config, "tls", &obj);
if (result != ISC_R_SUCCESS) {
result = ISC_R_SUCCESS;
return (result);
}
result = isc_symtab_create(mctx, 100, NULL, NULL, false, &symtab);
if (result != ISC_R_SUCCESS) {
return (result);
}
for (elt = cfg_list_first(obj); elt != NULL; elt = cfg_list_next(elt)) {
const char *name;
obj = cfg_listelt_value(elt);
name = cfg_obj_asstring(cfg_map_getname(obj));
tresult = bind9_check_tls_defintion(obj, name, logctx, symtab);
if (result == ISC_R_SUCCESS) {
result = tresult;
}
}
isc_symtab_destroy(&symtab);
return (result);
}
static isc_result_t
get_remotes(const cfg_obj_t *cctx, const char *list, const char *name,
const cfg_obj_t **ret) {
@@ -5494,6 +5639,11 @@ bind9_check_namedconf(const cfg_obj_t *config, bool check_plugins,
}
#endif /* HAVE_LIBNGHTTP2 */
if (bind9_check_tls_definitions(config, logctx, mctx) != ISC_R_SUCCESS)
{
result = ISC_R_FAILURE;
}
(void)cfg_map_get(config, "view", &views);
if (views != NULL && options != NULL) {

View File

@@ -50,6 +50,40 @@ isc_tlsctx_createclient(isc_tlsctx_t **ctxp);
*\li 'ctxp' != NULL and '*ctxp' == NULL.
*/
typedef enum isc_tls_protocol_version {
/* these must be the powers of two */
ISC_TLS_PROTO_VER_1_2 = 1 << 0,
ISC_TLS_PROTO_VER_1_3 = 1 << 1,
ISC_TLS_PROTO_VER_UNDEFINED,
} isc_tls_protocol_version_t;
void
isc_tlsctx_set_protocols(isc_tlsctx_t *ctx, const uint32_t tls_versions);
/*%<
* Sets the supported TLS protocol versions via the 'tls_versions' bit
* set argument (see `isc_tls_protocol_version_t` enum for the
* expected values).
*
* Requires:
*\li 'ctx' != NULL;
*\li 'tls_versions' != 0.
*/
bool
isc_tls_protocol_supported(const isc_tls_protocol_version_t tls_ver);
/*%<
* Check in runtime that the specified TLS protocol versions is supported.
*/
isc_tls_protocol_version_t
isc_tls_protocol_name_to_version(const char *name);
/*%<
* Convert the protocol version string into the version of
* 'isc_tls_protocol_version_t' type.
* Requires:
*\li 'name' != NULL.
*/
isc_tls_t *
isc_tls_create(isc_tlsctx_t *ctx);
/*%<

View File

@@ -10,6 +10,7 @@
*/
#include <inttypes.h>
#include <string.h>
#if HAVE_LIBNGHTTP2
#include <nghttp2/nghttp2.h>
#endif /* HAVE_LIBNGHTTP2 */
@@ -364,6 +365,101 @@ ssl_error:
return (ISC_R_TLSERROR);
}
static long
get_tls_version_disable_bit(const isc_tls_protocol_version_t tls_ver) {
long bit = 0;
switch (tls_ver) {
case ISC_TLS_PROTO_VER_1_2:
#ifdef SSL_OP_NO_TLSv1_2
bit = SSL_OP_NO_TLSv1_2;
#else
bit = 0;
#endif
break;
case ISC_TLS_PROTO_VER_1_3:
#ifdef SSL_OP_NO_TLSv1_3
bit = SSL_OP_NO_TLSv1_3;
#else
bit = 0;
#endif
break;
default:
INSIST(0);
ISC_UNREACHABLE();
break;
};
return (bit);
}
bool
isc_tls_protocol_supported(const isc_tls_protocol_version_t tls_ver) {
return (get_tls_version_disable_bit(tls_ver) != 0);
}
isc_tls_protocol_version_t
isc_tls_protocol_name_to_version(const char *name) {
REQUIRE(name != NULL);
if (strcasecmp(name, "TLSv1.2") == 0) {
return (ISC_TLS_PROTO_VER_1_2);
} else if (strcasecmp(name, "TLSv1.3") == 0) {
return (ISC_TLS_PROTO_VER_1_3);
}
return (ISC_TLS_PROTO_VER_UNDEFINED);
}
void
isc_tlsctx_set_protocols(isc_tlsctx_t *ctx, const uint32_t tls_versions) {
REQUIRE(ctx != NULL);
REQUIRE(tls_versions != 0);
long set_options = 0;
long clear_options = 0;
uint32_t versions = tls_versions;
/*
* The code below might be initially hard to follow because of the
* double negation that OpenSSL enforces.
*
* Taking into account that OpenSSL provides bits to *disable*
* specific protocol versions, like SSL_OP_NO_TLSv1_2,
* SSL_OP_NO_TLSv1_3, etc., the code has the following logic:
*
* If a protocol version is not specified in the bitmask, get the
* bit that disables it and add it to the set of TLS options to
* set ('set_options'). Otherwise, if a protocol version is set,
* add the bit to the set of options to clear ('clear_options').
*/
/* TLS protocol versions are defined as powers of two. */
for (uint32_t tls_ver = ISC_TLS_PROTO_VER_1_2;
tls_ver < ISC_TLS_PROTO_VER_UNDEFINED; tls_ver <<= 1)
{
/* Only supported versions should ever be passed to the
* function. The configuration file was not verified
* properly, if we are trying to enable an unsupported
* TLS version */
INSIST(isc_tls_protocol_supported(tls_ver));
if ((tls_versions & tls_ver) == 0) {
set_options |= get_tls_version_disable_bit(tls_ver);
} else {
clear_options |= get_tls_version_disable_bit(tls_ver);
}
versions &= ~(tls_ver);
}
/* All versions should be processed at this point, thus the value
* must equal zero. If it is not, then some garbage has been
* passed to the function; this situation is worth
* investigation. */
INSIST(versions == 0);
(void)SSL_CTX_set_options(ctx, set_options);
(void)SSL_CTX_clear_options(ctx, clear_options);
}
isc_tls_t *
isc_tls_create(isc_tlsctx_t *ctx) {
isc_tls_t *newctx = NULL;

View File

@@ -3875,10 +3875,12 @@ cfg_print_zonegrammar(const unsigned int zonetype, unsigned int flags,
/*%
* "tls" and related statement syntax.
*/
static cfg_type_t cfg_type_sslprotos = {
"sslprotos", cfg_parse_spacelist, cfg_print_spacelist,
cfg_doc_terminal, &cfg_rep_list, &cfg_type_astring
};
static cfg_type_t cfg_type_tlsprotos = { "tls_protocols",
cfg_parse_bracketed_list,
cfg_print_bracketed_list,
cfg_doc_bracketed_list,
&cfg_rep_list,
&cfg_type_astring };
static cfg_clausedef_t tls_clauses[] = {
{ "key-file", &cfg_type_qstring, 0 },
@@ -3886,7 +3888,7 @@ static cfg_clausedef_t tls_clauses[] = {
{ "ca-file", &cfg_type_qstring, 0 },
{ "hostname", &cfg_type_qstring, 0 },
{ "dh-param", &cfg_type_qstring, CFG_CLAUSEFLAG_EXPERIMENTAL },
{ "protocols", &cfg_type_sslprotos, CFG_CLAUSEFLAG_EXPERIMENTAL },
{ "protocols", &cfg_type_tlsprotos, 0 },
{ "ciphers", &cfg_type_astring, CFG_CLAUSEFLAG_EXPERIMENTAL },
{ NULL, NULL, 0 }
};

View File

@@ -59,22 +59,34 @@ struct ns_listenlist {
ISC_LIST(ns_listenelt_t) elts;
};
typedef struct ns_listen_tls_params {
const char *key;
const char *cert;
uint32_t protocols;
} ns_listen_tls_params_t;
/***
*** Functions
***/
isc_result_t
ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
dns_acl_t *acl, bool tls, const char *key, const char *cert,
ns_listenelt_t **target);
dns_acl_t *acl, bool tls,
const ns_listen_tls_params_t *tls_params,
ns_listenelt_t ** target);
/*%<
* Create a listen-on list element.
*
* Requires:
* \li 'targetp' is a valid pointer to a pointer containing 'NULL';
* \li 'tls_params' is a valid, non-'NULL' pointer if 'tls' equals 'true'.
*/
isc_result_t
ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, isc_dscp_t dscp,
dns_acl_t *acl, bool tls, const char *key,
const char *cert, char **endpoints, size_t nendpoints,
dns_acl_t *acl, bool tls,
const ns_listen_tls_params_t *tls_params,
char **endpoints, size_t nendpoints,
isc_quota_t *quota, const uint32_t max_streams,
ns_listenelt_t **target);
/*%<

View File

@@ -26,19 +26,26 @@ destroy(ns_listenlist_t *list);
isc_result_t
ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
dns_acl_t *acl, bool tls, const char *key, const char *cert,
dns_acl_t *acl, bool tls,
const ns_listen_tls_params_t *tls_params,
ns_listenelt_t **target) {
ns_listenelt_t *elt = NULL;
isc_result_t result = ISC_R_SUCCESS;
isc_tlsctx_t *sslctx = NULL;
REQUIRE(target != NULL && *target == NULL);
REQUIRE(!tls || tls_params != NULL);
if (tls) {
result = isc_tlsctx_createserver(key, cert, &sslctx);
result = isc_tlsctx_createserver(tls_params->key,
tls_params->cert, &sslctx);
if (result != ISC_R_SUCCESS) {
return (result);
}
if (tls_params->protocols != 0) {
isc_tlsctx_set_protocols(sslctx, tls_params->protocols);
}
}
elt = isc_mem_get(mctx, sizeof(*elt));
@@ -59,8 +66,9 @@ ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
isc_result_t
ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, isc_dscp_t dscp,
dns_acl_t *acl, bool tls, const char *key,
const char *cert, char **endpoints, size_t nendpoints,
dns_acl_t *acl, bool tls,
const ns_listen_tls_params_t *tls_params,
char **endpoints, size_t nendpoints,
isc_quota_t *quota, const uint32_t max_streams,
ns_listenelt_t **target) {
isc_result_t result;
@@ -69,8 +77,8 @@ ns_listenelt_create_http(isc_mem_t *mctx, in_port_t http_port, isc_dscp_t dscp,
REQUIRE(endpoints != NULL && *endpoints != NULL);
REQUIRE(nendpoints > 0);
result = ns_listenelt_create(mctx, http_port, dscp, acl, tls, key, cert,
target);
result = ns_listenelt_create(mctx, http_port, dscp, acl, tls,
tls_params, target);
if (result == ISC_R_SUCCESS) {
(*target)->is_http = true;
(*target)->http_endpoints = endpoints;
@@ -164,8 +172,7 @@ ns_listenlist_default(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
goto cleanup;
}
result = ns_listenelt_create(mctx, port, dscp, acl, false, NULL, NULL,
&elt);
result = ns_listenelt_create(mctx, port, dscp, acl, false, NULL, &elt);
if (result != ISC_R_SUCCESS) {
goto cleanup_acl;
}