]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
WiP 2
authorWitold Kręcicki <wpk@isc.org>
Sun, 4 Nov 2018 18:07:27 +0000 (18:07 +0000)
committerWitold Kręcicki <wpk@isc.org>
Wed, 7 Nov 2018 12:42:39 +0000 (12:42 +0000)
bin/named/server.c
lib/isc/include/isc/result.h
lib/isc/include/isc/socket.h
lib/isc/result.c
lib/isc/unix/socket.c
lib/isccfg/namedconf.c
lib/ns/include/ns/interfacemgr.h
lib/ns/include/ns/listenlist.h
lib/ns/interfacemgr.c
lib/ns/listenlist.c

index 4f14900f7fbe162324d4d6d2566a72214e485961..028cbfae5c9a0258bbadf777b5bdd1251502e854 100644 (file)
@@ -6423,7 +6423,8 @@ add_listenelt(isc_mem_t *mctx, ns_listenlist_t *list, isc_sockaddr_t *addr,
                        goto clean;
 
                result = ns_listenelt_create(mctx, isc_sockaddr_getport(addr),
-                                            dscp, src_acl, &lelt);
+                                            dscp, src_acl, NULL, NULL,
+                                            &lelt);
                if (result != ISC_R_SUCCESS)
                        goto clean;
                ISC_LIST_APPEND(list->elts, lelt, link);
@@ -10410,12 +10411,24 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
                        uint16_t family, ns_listenelt_t **target)
 {
        isc_result_t result;
-       const cfg_obj_t *portobj, *dscpobj;
+       const cfg_obj_t *portobj, *dscpobj, *keyobj, *certobj;
+       const char *cert = NULL, *key=NULL;
        in_port_t port;
        isc_dscp_t dscp = -1;
        ns_listenelt_t *delt = NULL;
        REQUIRE(target != NULL && *target == NULL);
 
+       keyobj = cfg_tuple_get(listener, "key");
+       if (cfg_obj_isstring(keyobj)) {
+               key = cfg_obj_asstring(keyobj);
+       }
+
+       certobj = cfg_tuple_get(listener, "cert");
+       if (cfg_obj_isstring(certobj)) {
+               cert = cfg_obj_asstring(certobj);
+       }
+
+
        portobj = cfg_tuple_get(listener, "port");
        if (!cfg_obj_isuint32(portobj)) {
                if (named_g_port != 0) {
@@ -10448,7 +10461,8 @@ ns_listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
                dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
        }
 
-       result = ns_listenelt_create(mctx, port, dscp, NULL, &delt);
+       printf("Cert %s key %s port %d\n", cert, key, port);
+       result = ns_listenelt_create(mctx, port, dscp, NULL, cert, key, &delt);
        if (result != ISC_R_SUCCESS)
                return (result);
 
index b54df56acf768ee47a2fd8420995fb90f0b67523..2231fa8694ae115ed8aed4dfe2b62b6b3d1c6e9f 100644 (file)
@@ -85,9 +85,9 @@
 #define ISC_R_WOULDBLOCK               63      /*%< would block */
 #define ISC_R_COMPLETE                 64      /*%< complete */
 #define ISC_R_CRYPTOFAILURE            65      /*%< cryptography library failure */
-
+#define ISC_R_TLSERROR                 66      /*%< TLS error */
 /*% Not a result code: the number of results. */
-#define ISC_R_NRESULTS                         66
+#define ISC_R_NRESULTS                         67
 
 ISC_LANG_BEGINDECLS
 
index 8a3c96b14d2a978fee1b04ada21b10def9574fee..23b7b2e1b13b7cac32c106bcae97d10a82bef75e 100644 (file)
@@ -1044,4 +1044,7 @@ ISC_LANG_ENDDECLS
 isc_result_t
 isc_socket_getsslhexdigest(isc_socket_t *sock0, char *dest, unsigned int len);
 
+isc_result_t
+isc_socket_maketls(isc_socket_t *sock0, const char* cert_path, const char* key_path);
+
 #endif /* ISC_SOCKET_H */
index 23ff2099ead062ecee982e87a59f1d91843ce92b..dd0a0dadcbcc9707ecc022bd60c3981d7ab7c71e 100644 (file)
@@ -100,6 +100,8 @@ static const char *description[ISC_R_NRESULTS] = {
        "multiple",                             /*%< 62 */
        "would block",                          /*%< 63 */
        "complete",                             /*%< 64 */
+       "cryptography library failure",         /*%< 65 */
+       "TLS error",                            /*%< 66 */
 };
 
 static const char *identifier[ISC_R_NRESULTS] = {
@@ -168,6 +170,8 @@ static const char *identifier[ISC_R_NRESULTS] = {
        "ISC_R_MULTIPLE",
        "ISC_R_WOULDBLOCK",
        "ISC_R_COMPLETE",
+       "ISC_R_CRYPTOFAILURE",
+       "ISC_R_TLSERROR"
 };
 
 #define ISC_RESULT_RESULTSET                   2
index 6d2d78f445156dd8e5d52cf5474933b2557ac960..402fa0cfd62122ff996b1ccecd2643e9c4b98ad5 100644 (file)
@@ -32,6 +32,7 @@
 #endif
 
 #include <openssl/ssl.h>
+#include <openssl/err.h>
 
 #include <errno.h>
 #include <fcntl.h>
@@ -346,6 +347,7 @@ typedef struct isc__socketthread isc__socketthread_t;
 #define TLSSTATE_RWW   0x0002  /* Read Wants to Write */
 #define TLSSTATE_WWR   0x0004  /* Write Wants to Read */
 #define TLSSTATE_WWW   0x0008  /* Write Wants to Write */
+#define TLSSTATE_DEAD  0x0010  /* Delayed error */
 
 
 struct isc__socket {
@@ -370,8 +372,6 @@ struct isc__socket {
        ISC_LIST(isc_socket_newconnev_t)        accept_list;
        ISC_LIST(isc_socket_connev_t)           connect_list;
 
-       SSL *                   ssl;
-
        isc_sockaddr_t          peer_address;      /* remote address */
 
        unsigned int            listener : 1,      /* listener socket */
@@ -380,10 +380,14 @@ struct isc__socket {
                                bound : 1,         /* bound to local addr */
                                dupped : 1,
                                active : 1,        /* currently active */
-                               pktdscp : 1,       /* per packet dscp */
-                               tlsconnecting : 1, /* waiting for TLS conn */
-                               tlsaccepting : 1;  /* waiting for TLS accept */
+                               pktdscp : 1;       /* per packet dscp */
 
+
+       SSL                     *ssl;
+       /* server ctx for accepting socket */
+       SSL_CTX                 *ssl_ctx;
+       unsigned int            tlsconnecting : 1, /* waiting for TLS conn */
+                               tlsaccepting : 1;  /* waiting for TLS accept */
        int                     tlsstate;
 
 #ifdef ISC_PLATFORM_RECVOVERFLOW
@@ -410,6 +414,9 @@ struct isc__socketmgr {
        int                     reserved;       /* unlocked */
        isc_condition_t         shutdown_ok;
        int                     maxudp;
+
+       /* client ctx for created sockets */
+       SSL_CTX                 *ssl_ctx;       /* XXXWPK TODO verify thread-safety of that (we're not modifying it, only creating clients) */
 };
 
 struct isc__socketthread {
@@ -2021,6 +2028,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
        sock->tlsaccepting = 0;
        sock->tlsstate = 0;
        sock->ssl = NULL;
+       sock->ssl_ctx = NULL;
 
        ISC_LINK_INIT(sock, link);
 
@@ -3230,11 +3238,27 @@ internal_accept(isc__socket_t *sock) {
        /*
         * Fill in the done event details and send it off.
         */
-       dev->result = result;
-       task = dev->ev_sender;
-       dev->ev_sender = sock;
-
-       isc_task_sendtoanddetach(&task, ISC_EVENT_PTR(&dev), sock->threadid);
+       printf("Accept done %d %p\n", result, sock->ssl_ctx);
+       if (result == ISC_R_SUCCESS && sock->ssl_ctx != NULL) {
+               /*
+                * This socket might be handled by different FD, we can't
+                * launch internal_accept directly
+                */
+               isc__socket_t *ns = NEWCONNSOCK(dev);
+               ns->ssl_ctx = sock->ssl_ctx;
+               ns->tlsstate = TLSSTATE_RWR;
+               ns->tlsaccepting = 1;
+               ns->type = isc_sockettype_tls;
+               printf("Pushing TLS ACCEPT to %p\n", ns);
+               ISC_LIST_APPEND(ns->accept_list, dev, ev_link);
+               select_poke(ns->manager, ns->threadid, ns->fd,
+                           SELECT_POKE_READ);
+       } else {
+               dev->result = result;
+               task = dev->ev_sender;
+               dev->ev_sender = sock;
+               isc_task_sendtoanddetach(&task, ISC_EVENT_PTR(&dev), sock->threadid);
+       }
        return;
 
  soft_error:
@@ -3245,8 +3269,6 @@ internal_accept(isc__socket_t *sock) {
        return;
 }
 
-static void internal_tls_accept(isc__socket_t *sock) { UNUSED(sock); abort(); };
-
 static void
 internal_recv(isc__socket_t *sock) {
        isc_socketevent_t *dev;
@@ -3493,7 +3515,7 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable,
 
        isc_refcount_increment(&sock->references);
 
-       printf("process_fd sock->type %d readable %d writeable %d connecting %d\n", sock->type, readable, writeable, sock->connecting);
+       printf("process_fd %d sock->type %d readable %d writeable %d connecting %d\n", sock->fd, sock->type, readable, writeable, sock->connecting);
        if (!sock->listener && !sock->connecting && sock->type == isc_sockettype_tls) {
                if (readable) {
                        if (sock->tlsstate & TLSSTATE_RWR) {
@@ -4230,6 +4252,11 @@ isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
                return (ISC_R_UNEXPECTED);
        }
 
+       const SSL_METHOD *meth;
+       SSL_load_error_strings();
+       OpenSSL_add_ssl_algorithms();
+       meth = TLS_client_method();
+       manager->ssl_ctx = SSL_CTX_new(meth);
 
        /*
         * Start up the select/poll thread.
@@ -4366,6 +4393,13 @@ socket_recv(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
 
        dev->ev_sender = task;
 
+       if ((sock->type == isc_sockettype_tls) && (sock->tlsstate & TLSSTATE_DEAD) == TLSSTATE_DEAD) {
+               dev->result = ISC_R_TLSERROR;
+               if ((flags & ISC_SOCKFLAG_IMMEDIATE) == 0)
+                       send_recvdone_event(sock, &dev);
+               return (ISC_R_SUCCESS);
+       }
+
        if (sock->type == isc_sockettype_udp) {
                io_state = doio_recv(sock, dev);
        } else {
@@ -4531,6 +4565,13 @@ socket_send(isc__socket_t *sock, isc_socketevent_t *dev, isc_task_t *task,
                }
        }
 
+       if ((sock->type == isc_sockettype_tls) && (sock->tlsstate & TLSSTATE_DEAD) == TLSSTATE_DEAD) {
+               dev->result = ISC_R_TLSERROR;
+               if ((flags & ISC_SOCKFLAG_IMMEDIATE) == 0)
+                       send_recvdone_event(sock, &dev);
+               return (ISC_R_SUCCESS);
+       }
+
        if (sock->type == isc_sockettype_udp) {
                io_state = doio_send(sock, dev);
        } else {
@@ -5446,14 +5487,12 @@ internal_tls_connect(isc__socket_t *sock) {
        bool wanted_write = sock->tlsstate & (TLSSTATE_RWW | TLSSTATE_WWW);
        sock->tlsstate &= ~(TLSSTATE_RWR | TLSSTATE_RWW);
 
+       /*
+        * internal_tls_connect can be called multiple times, if that's the
+        * first time we need to create SSL object
+        */
        if (sock->ssl == NULL) {
-               const SSL_METHOD *meth;
-               SSL_CTX* ctx;
-               SSL_load_error_strings();
-               OpenSSL_add_ssl_algorithms();
-               meth = TLS_client_method();
-               ctx = SSL_CTX_new(meth);
-               sock->ssl = SSL_new(ctx);
+               sock->ssl = SSL_new(sock->manager->ssl_ctx);
                SSL_set_fd(sock->ssl, sock->fd);
                SSL_set_connect_state(sock->ssl);
        }
@@ -5483,6 +5522,7 @@ internal_tls_connect(isc__socket_t *sock) {
                        goto finish;
                } else {
                        printf("Other SSL error in connect %d %d\n", cc, err);
+                       ERR_print_errors_fp(stderr);
                        result = ISC_R_CONNECTIONRESET;
                }
        } else {
@@ -5500,6 +5540,82 @@ internal_tls_connect(isc__socket_t *sock) {
        watch_unwatch(sock, wanted_read, wanted_write);
 }
 
+static void
+internal_tls_accept(isc__socket_t *sock) {
+       isc_socket_newconnev_t *dev;
+       isc_result_t result;
+       int threadid = sock->threadid;
+       sock->tlsaccepting = 1;
+       bool wanted_read = sock->tlsstate & (TLSSTATE_RWR | TLSSTATE_WWR);
+       bool wanted_write = sock->tlsstate & (TLSSTATE_RWW | TLSSTATE_WWW);
+       sock->tlsstate &= ~(TLSSTATE_WWR | TLSSTATE_WWW);
+
+       printf("TLS ACCEPT SOCK %p\n", sock);
+       dev = ISC_LIST_HEAD(sock->accept_list);
+       if (dev == NULL) {
+               abort();
+       }
+
+       /*
+        * internal_tls_accept can be called multiple times, if that's the
+        * first time we need to create SSL object
+        */
+       if (sock->ssl == NULL) {
+               sock->ssl = SSL_new(sock->ssl_ctx);
+               SSL_set_fd(sock->ssl, sock->fd);
+               SSL_set_accept_state(sock->ssl);
+//             SSL_set_connect_state(sock->ssl);
+       }
+       int cc = SSL_accept(sock->ssl);
+       printf("SSL_Accept returned %d\n", cc);
+       if (cc <= 0) {
+               int err = SSL_get_error(sock->ssl, cc);
+               if (err == SSL_ERROR_WANT_READ) {
+                       printf("Want read\n");
+                       if (!wanted_read) {
+                               watch_fd(&sock->manager->threads[sock->threadid], sock->fd,
+                                        SELECT_POKE_READ);
+                       }
+                       sock->tlsstate |= TLSSTATE_RWR;
+                       watch_unwatch(sock, wanted_read, wanted_write);
+                       return;
+               } else if (err == SSL_ERROR_WANT_WRITE) {
+                       printf("Want write\n");
+                       if (!wanted_write) {
+                               watch_fd(&sock->manager->threads[sock->threadid], sock->fd,
+                                        SELECT_POKE_WRITE);
+                       }
+                       sock->tlsstate |= TLSSTATE_RWW;
+                       watch_unwatch(sock, wanted_read, wanted_write);
+                       return;
+               } else {
+                       printf("Other SSL error in connect %d %d\n", cc, err);
+                       result = ISC_R_CONNECTIONRESET;
+
+               }
+       } else {
+               result = ISC_R_SUCCESS;
+       }
+       /*
+        * Since regular accept failures are odd, but SSL negotiation
+        * failures are quite common, we delay the error to first read/write
+        * happening on the socket - accept always return SUCCESS at this
+        * stage.
+        */
+       if (result != ISC_R_SUCCESS) {
+               sock->tlsstate |= TLSSTATE_DEAD;
+       }
+       dev->result = ISC_R_SUCCESS;
+       sock->tlsaccepting = 0;
+       isc_task_t *task = dev->ev_sender;
+       ISC_LIST_UNLINK(sock->accept_list, dev, ev_link);
+       watch_unwatch(sock, wanted_read, wanted_write);
+       dev->ev_sender = sock;
+       isc_task_sendtoanddetach(&task, ISC_EVENT_PTR(&dev), threadid);
+
+       INSIST(ISC_LIST_EMPTY(sock->accept_list));
+}
+
 isc_result_t
 isc_socket_getpeername(isc_socket_t *sock0, isc_sockaddr_t *addressp) {
        isc__socket_t *sock = (isc__socket_t *)sock0;
@@ -6121,22 +6237,22 @@ isc_socket_getsslhexdigest(isc_socket_t *sock0, char *dest, unsigned int len) {
        unsigned char digest[EVP_MAX_MD_SIZE];
        unsigned int dlen;
        X509* x509;
-       if (sock->ssl == NULL) { 
+       if (sock->ssl == NULL) {
                return (ISC_R_UNSET);
        }
        x509 = SSL_get_peer_certificate(sock->ssl);
        if (x509 == NULL) {
                return (ISC_R_UNEXPECTED);
        }
-       
-        if (X509_pubkey_digest(x509, EVP_sha256(), digest, &dlen) != 1) {
-               return (ISC_R_UNEXPECTED);
+
+       if (X509_pubkey_digest(x509, EVP_sha256(), digest, &dlen) != 1) {
+               return (ISC_R_UNEXPECTED);
        }
-       
+
        if (len < 2*dlen + 1) {
                return (ISC_R_NOSPACE);
        }
-       
+
        r.base = digest;
        r.length = dlen;
        isc_buffer_init(&buf, dest, len);
@@ -6147,4 +6263,35 @@ isc_socket_getsslhexdigest(isc_socket_t *sock0, char *dest, unsigned int len) {
        isc_buffer_putuint8(&buf, 0);
        return (ISC_R_SUCCESS);
 }
-       
+
+isc_result_t
+isc_socket_maketls(isc_socket_t *sock0, const char* cert_path, const char* key_path) {
+       printf("Maketls\n");
+       isc__socket_t *sock = (isc__socket_t*) sock0;
+       const SSL_METHOD *meth;
+
+       REQUIRE(VALID_SOCKET(sock));
+       REQUIRE(!sock->connected);
+       REQUIRE(sock->listener);
+
+       REQUIRE(sock->ssl == NULL);
+       REQUIRE(sock->ssl_ctx == NULL);
+
+       SSL_load_error_strings();
+       OpenSSL_add_ssl_algorithms();
+       meth = TLS_server_method();
+       INSIST(meth != NULL);
+       sock->ssl_ctx = SSL_CTX_new(meth);
+       INSIST(sock->ssl_ctx != NULL);
+//     SSL_set_msg_callback(sock->ssl_ctx,SSL_trace); SSL_set_msg_callback_arg(sock->ssl_ctx,BIO_new_fp(stdout,0));
+       if (SSL_CTX_use_certificate_file(sock->ssl_ctx, cert_path, SSL_FILETYPE_PEM) <= 0) {
+               abort();
+       }
+       if (SSL_CTX_use_PrivateKey_file(sock->ssl_ctx, key_path, SSL_FILETYPE_PEM) <= 0) {
+               abort();
+       }
+
+       sock->type = isc_sockettype_tls;
+
+       return (ISC_R_SUCCESS);
+}
index 5af0396034edac5b9b856bc7a7a364cf586e9235..c6ddba6fe3c248f3126b87c86b7c90b67beb43aa 100644 (file)
@@ -125,6 +125,8 @@ static cfg_type_t cfg_type_notifytype;
 static cfg_type_t cfg_type_optional_allow;
 static cfg_type_t cfg_type_optional_class;
 static cfg_type_t cfg_type_optional_dscp;
+static cfg_type_t cfg_type_optional_cert;
+static cfg_type_t cfg_type_optional_key;
 static cfg_type_t cfg_type_optional_facility;
 static cfg_type_t cfg_type_optional_keyref;
 static cfg_type_t cfg_type_optional_port;
@@ -168,6 +170,8 @@ static cfg_type_t cfg_type_tkey_dhkey = {
 static cfg_tuplefielddef_t listenon_fields[] = {
        { "port", &cfg_type_optional_port, 0 },
        { "dscp", &cfg_type_optional_dscp, 0 },
+       { "cert", &cfg_type_optional_cert, 0 },
+       { "key", &cfg_type_optional_key, 0 },
        { "acl", &cfg_type_bracketed_aml, 0 },
        { NULL, NULL, 0 }
 };
@@ -636,6 +640,20 @@ static cfg_type_t cfg_type_optional_port = {
        doc_optional_keyvalue, &cfg_rep_uint32, &port_kw
 };
 
+static keyword_type_t tlskey_kw = { "key", &cfg_type_qstring };
+
+static cfg_type_t cfg_type_optional_key = {
+       "optional_key", parse_optional_keyvalue, print_keyvalue,
+       doc_optional_keyvalue, &cfg_rep_string, &tlskey_kw
+};
+
+static keyword_type_t tlscert_kw = { "cert", &cfg_type_qstring };
+
+static cfg_type_t cfg_type_optional_cert = {
+       "optional_cert", parse_optional_keyvalue, print_keyvalue,
+       doc_optional_keyvalue, &cfg_rep_string, &tlscert_kw
+};
+
 /*% A list of keys, as in the "key" clause of the controls statement. */
 static cfg_type_t cfg_type_keylist = {
        "keylist", cfg_parse_bracketed_list, cfg_print_bracketed_list,
index 54846fdc27326c7ca077bb9648847d258beec9dc..4daeb75274489809c3a95b1bd9ff61907344882b 100644 (file)
@@ -81,6 +81,8 @@ struct ns_interface {
        int                     ntcpcurrent;    /*%< Current ditto, locked */
        int                     nudpdispatch;   /*%< Number of UDP dispatches */
        ns_clientmgr_t *        clientmgr;      /*%< Client manager. */
+       const char *            certpath;       /*%< TLS cert path. */
+       const char *            keypath;        /*%< TLS key path. */
        ISC_LINK(ns_interface_t) link;
 };
 
index f6f631988f6ff59764d632bcab630147849e21d3..c3f30cbbef45377864f0be04afefd1ac03510e30 100644 (file)
@@ -42,6 +42,8 @@ struct ns_listenelt {
        isc_mem_t *                     mctx;
        in_port_t                       port;
        isc_dscp_t                      dscp;  /* -1 = not set, 0..63 */
+       const char *                    certpath;
+       const char *                    keypath;
        dns_acl_t *                     acl;
        ISC_LINK(ns_listenelt_t)        link;
 };
@@ -58,7 +60,8 @@ struct ns_listenlist {
 
 isc_result_t
 ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
-                   dns_acl_t *acl, ns_listenelt_t **target);
+                   dns_acl_t *acl, const char *certpath,
+                   const char *keypath, ns_listenelt_t **target);
 /*%<
  * Create a listen-on list element.
  */
index adba622d096826d6ff62f1bc33b524a13674a051..c9ac22dc279451b37fc8d19566031cdefbf0364f 100644 (file)
@@ -385,7 +385,8 @@ ns_interfacemgr_shutdown(ns_interfacemgr_t *mgr) {
 
 static isc_result_t
 ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
-                   const char *name, ns_interface_t **ifpret)
+                   const char *name, const char *certpath,
+                   const char *keypath, ns_interface_t **ifpret)
 {
        ns_interface_t *ifp;
        isc_result_t result;
@@ -400,6 +401,8 @@ ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
        ifp->mgr = NULL;
        ifp->generation = mgr->generation;
        ifp->addr = *addr;
+       ifp->certpath = certpath;
+       ifp->keypath = keypath;
        ifp->flags = 0;
        strlcpy(ifp->name, name, sizeof(ifp->name));
        ifp->clientmgr = NULL;
@@ -559,7 +562,17 @@ ns_interface_accepttcp(ns_interface_t *ifp) {
                                 isc_result_totext(result));
                goto tcp_listen_failure;
        }
-
+       printf("XXX %s\n", ifp->certpath);
+       if (ifp->certpath != NULL) {
+               result = isc_socket_maketls(ifp->tcpsocket, ifp->certpath,
+                                           ifp->keypath);
+               if (result != ISC_R_SUCCESS) {
+                       isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
+                                     "setting TLS on TCP socket: %s",
+                                     isc_result_totext(result));
+                       goto tcp_listen_failure;
+               }
+       }
        /*
         * If/when there a multiple filters listen to the
         * result.
@@ -589,6 +602,7 @@ static isc_result_t
 ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
                   const char *name, ns_interface_t **ifpret,
                   bool accept_tcp, isc_dscp_t dscp,
+                  const char *certpath, const char *keypath,
                   bool *addr_in_use)
 {
        isc_result_t result;
@@ -596,17 +610,18 @@ ns_interface_setup(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
        REQUIRE(ifpret != NULL && *ifpret == NULL);
        REQUIRE(addr_in_use == NULL || *addr_in_use == false);
 
-       result = ns_interface_create(mgr, addr, name, &ifp);
+       result = ns_interface_create(mgr, addr, name, certpath, keypath, &ifp);
        if (result != ISC_R_SUCCESS)
                return (result);
 
        ifp->dscp = dscp;
-
-       result = ns_interface_listenudp(ifp);
-       if (result != ISC_R_SUCCESS) {
-               if ((result == ISC_R_ADDRINUSE) && (addr_in_use != NULL))
-                       *addr_in_use = true;
-               goto cleanup_interface;
+       if (certpath == NULL) {
+               result = ns_interface_listenudp(ifp);
+               if (result != ISC_R_SUCCESS) {
+                       if ((result == ISC_R_ADDRINUSE) && (addr_in_use != NULL))
+                               *addr_in_use = true;
+                       goto cleanup_interface;
+               }
        }
 
        if (((mgr->sctx->options & NS_SERVER_NOTCP) == 0) &&
@@ -932,6 +947,8 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
                                                            "<any>", &ifp,
                                                            true,
                                                            le->dscp,
+                                                           le->certpath,
+                                                           le->keypath,
                                                            NULL);
                                if (result == ISC_R_SUCCESS)
                                        ifp->flags |= NS_INTERFACEFLAG_ANYADDR;
@@ -1154,6 +1171,8 @@ do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
                                                    (adjusting == true) ?
                                                    false : true,
                                                    le->dscp,
+                                                   le->certpath,
+                                                   le->keypath,
                                                    &addr_in_use);
 
                                tried_listening = true;
index 21ae91bc9f6e9c1c90d21732e45d1420b8a5426a..a9b422672895e63bfa679a0ab2c3717ba34e7b21 100644 (file)
@@ -27,7 +27,8 @@ 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, ns_listenelt_t **target)
+                   dns_acl_t *acl, const char *certpath,
+                   const char *keypath, ns_listenelt_t **target)
 {
        ns_listenelt_t *elt = NULL;
        REQUIRE(target != NULL && *target == NULL);
@@ -39,6 +40,9 @@ ns_listenelt_create(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
        elt->port = port;
        elt->dscp = dscp;
        elt->acl = acl;
+       elt->certpath = certpath;
+       elt->keypath = keypath;
+       printf("LE create %d %s %s\n", port, certpath, keypath);
        *target = elt;
        return (ISC_R_SUCCESS);
 }
@@ -111,7 +115,7 @@ ns_listenlist_default(isc_mem_t *mctx, in_port_t port, isc_dscp_t dscp,
        if (result != ISC_R_SUCCESS)
                goto cleanup;
 
-       result = ns_listenelt_create(mctx, port, dscp, acl, &elt);
+       result = ns_listenelt_create(mctx, port, dscp, acl, NULL, NULL, &elt);
        if (result != ISC_R_SUCCESS)
                goto cleanup_acl;