From: Wouter Wijngaards Date: Tue, 12 Jun 2018 07:43:52 +0000 (+0000) Subject: - #4102 for NSD, but for Unbound. Named unix pipes do not use X-Git-Tag: release-1.7.3rc1~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7fd32916e8d0c59be6887c164b69efcb337cf91d;p=thirdparty%2Funbound.git - #4102 for NSD, but for Unbound. Named unix pipes do not use certificate and key files, access can be restricted with file and directory permissions. The option control-use-cert is no longer used, and ignored if found in unbound.conf. git-svn-id: file:///svn/unbound/trunk@4718 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/daemon/cachedump.c b/daemon/cachedump.c index 81061870b..5a72e9d11 100644 --- a/daemon/cachedump.c +++ b/daemon/cachedump.c @@ -62,7 +62,7 @@ /** dump one rrset zonefile line */ static int -dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i) +dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i) { char s[65535]; if(!packed_rr_to_string(k, i, now, s, sizeof(s))) { @@ -73,7 +73,7 @@ dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i) /** dump rrset key and data info */ static int -dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k, +dump_rrset(RES* ssl, struct ub_packed_rrset_key* k, struct packed_rrset_data* d, time_t now) { size_t i; @@ -99,7 +99,7 @@ dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k, /** dump lruhash rrset cache */ static int -dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now) +dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now) { struct lruhash_entry* e; /* lruhash already locked by caller */ @@ -118,7 +118,7 @@ dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now) /** dump rrset cache */ static int -dump_rrset_cache(SSL* ssl, struct worker* worker) +dump_rrset_cache(RES* ssl, struct worker* worker) { struct rrset_cache* r = worker->env.rrset_cache; size_t slab; @@ -137,7 +137,7 @@ dump_rrset_cache(SSL* ssl, struct worker* worker) /** dump message to rrset reference */ static int -dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k) +dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k) { char* nm, *tp, *cl; nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len); @@ -164,7 +164,7 @@ dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k) /** dump message entry */ static int -dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d, +dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now) { size_t i; @@ -246,7 +246,7 @@ copy_msg(struct regional* region, struct lruhash_entry* e, /** dump lruhash msg cache */ static int -dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h) +dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h) { struct lruhash_entry* e; struct query_info* k; @@ -274,7 +274,7 @@ dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h) /** dump msg cache */ static int -dump_msg_cache(SSL* ssl, struct worker* worker) +dump_msg_cache(RES* ssl, struct worker* worker) { struct slabhash* sh = worker->env.msg_cache; size_t slab; @@ -291,7 +291,7 @@ dump_msg_cache(SSL* ssl, struct worker* worker) } int -dump_cache(SSL* ssl, struct worker* worker) +dump_cache(RES* ssl, struct worker* worker) { if(!dump_rrset_cache(ssl, worker)) return 0; @@ -302,7 +302,7 @@ dump_cache(SSL* ssl, struct worker* worker) /** read a line from ssl into buffer */ static int -ssl_read_buf(SSL* ssl, sldns_buffer* buf) +ssl_read_buf(RES* ssl, sldns_buffer* buf) { return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf), sldns_buffer_capacity(buf)); @@ -310,7 +310,7 @@ ssl_read_buf(SSL* ssl, sldns_buffer* buf) /** check fixed text on line */ static int -read_fixed(SSL* ssl, sldns_buffer* buf, const char* str) +read_fixed(RES* ssl, sldns_buffer* buf, const char* str) { if(!ssl_read_buf(ssl, buf)) return 0; return (strcmp((char*)sldns_buffer_begin(buf), str) == 0); @@ -318,7 +318,7 @@ read_fixed(SSL* ssl, sldns_buffer* buf, const char* str) /** load an RR into rrset */ static int -load_rr(SSL* ssl, sldns_buffer* buf, struct regional* region, +load_rr(RES* ssl, sldns_buffer* buf, struct regional* region, struct ub_packed_rrset_key* rk, struct packed_rrset_data* d, unsigned int i, int is_rrsig, int* go_on, time_t now) { @@ -435,7 +435,7 @@ move_into_cache(struct ub_packed_rrset_key* k, /** load an rrset entry */ static int -load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker) +load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker) { char* s = (char*)sldns_buffer_begin(buf); struct regional* region = worker->scratchpad; @@ -519,7 +519,7 @@ load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker) /** load rrset cache */ static int -load_rrset_cache(SSL* ssl, struct worker* worker) +load_rrset_cache(RES* ssl, struct worker* worker) { sldns_buffer* buf = worker->env.scratch_buffer; if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0; @@ -575,7 +575,7 @@ load_qinfo(char* str, struct query_info* qinfo, struct regional* region) /** load a msg rrset reference */ static int -load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker, +load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker, struct regional *region, struct ub_packed_rrset_key** rrset, int* go_on) { @@ -620,7 +620,7 @@ load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker, /** load a msg entry */ static int -load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker) +load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker) { struct regional* region = worker->scratchpad; struct query_info qinf; @@ -685,7 +685,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker) /** load msg cache */ static int -load_msg_cache(SSL* ssl, struct worker* worker) +load_msg_cache(RES* ssl, struct worker* worker) { sldns_buffer* buf = worker->env.scratch_buffer; if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0; @@ -698,7 +698,7 @@ load_msg_cache(SSL* ssl, struct worker* worker) } int -load_cache(SSL* ssl, struct worker* worker) +load_cache(RES* ssl, struct worker* worker) { if(!load_rrset_cache(ssl, worker)) return 0; @@ -709,7 +709,7 @@ load_cache(SSL* ssl, struct worker* worker) /** print details on a delegation point */ static void -print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp) +print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp) { char buf[257]; struct delegpt_addr* a; @@ -785,7 +785,7 @@ print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp) /** print main dp info */ static void -print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg) +print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg) { size_t i, n_ns, n_miss, n_addr, n_res, n_avail; @@ -813,7 +813,7 @@ print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg) return; } -int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm, +int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm, size_t nmlen, int ATTR_UNUSED(nmlabs)) { /* deep links into the iterator module */ diff --git a/daemon/cachedump.h b/daemon/cachedump.h index 0f2feabcb..72c172d44 100644 --- a/daemon/cachedump.h +++ b/daemon/cachedump.h @@ -72,6 +72,7 @@ #ifndef DAEMON_DUMPCACHE_H #define DAEMON_DUMPCACHE_H struct worker; +#include "daemon/remote.h" /** * Dump cache(s) to text @@ -80,7 +81,7 @@ struct worker; * ptrs to the caches. * @return false on ssl print error. */ -int dump_cache(SSL* ssl, struct worker* worker); +int dump_cache(RES* ssl, struct worker* worker); /** * Load cache(s) from text @@ -89,7 +90,7 @@ int dump_cache(SSL* ssl, struct worker* worker); * ptrs to the caches. * @return false on ssl error. */ -int load_cache(SSL* ssl, struct worker* worker); +int load_cache(RES* ssl, struct worker* worker); /** * Print the delegation used to lookup for this name. @@ -101,7 +102,7 @@ int load_cache(SSL* ssl, struct worker* worker); * @param nmlabs: labels in name. * @return false on ssl error. */ -int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm, +int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm, size_t nmlen, int nmlabs); #endif /* DAEMON_DUMPCACHE_H */ diff --git a/daemon/remote.c b/daemon/remote.c index cfc91eb98..663e242d4 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -142,130 +142,20 @@ timeval_divide(struct timeval* avg, const struct timeval* sum, long long d) #endif } -/* - * The following function was generated using the openssl utility, using - * the command : "openssl dhparam -C 2048" - * (some openssl versions reject DH that is 'too small', eg. 512). - */ -#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) -#ifndef S_SPLINT_S -static DH *get_dh2048(void) -{ - static unsigned char dh2048_p[]={ - 0xE7,0x36,0x28,0x3B,0xE4,0xC3,0x32,0x1C,0x01,0xC3,0x67,0xD6, - 0xF5,0xF3,0xDA,0xDC,0x71,0xC0,0x42,0x8B,0xE6,0xEB,0x8D,0x80, - 0x35,0x7F,0x09,0x45,0x30,0xE5,0xB2,0x92,0x81,0x3F,0x08,0xCD, - 0x36,0x5E,0x19,0x83,0x62,0xCC,0xAE,0x9B,0x81,0x66,0x24,0xEE, - 0x16,0x6F,0xA9,0x9E,0xF4,0x82,0x1B,0xDD,0x46,0xC7,0x33,0x5D, - 0xF4,0xCA,0xE6,0x8F,0xFC,0xD4,0xD8,0x58,0x94,0x24,0x5D,0xFF, - 0x0A,0xE8,0xEF,0x3D,0xCE,0xBB,0x50,0x94,0xE0,0x5F,0xE8,0x41, - 0xC3,0x35,0x30,0x37,0xD5,0xCB,0x8F,0x3D,0x95,0x15,0x1A,0x77, - 0x42,0xB2,0x06,0x86,0xF6,0x09,0x66,0x0E,0x9A,0x25,0x94,0x3E, - 0xD2,0x04,0x25,0x25,0x1D,0x23,0xEB,0xDC,0x4D,0x0C,0x83,0x28, - 0x2E,0x15,0x81,0x2D,0xC1,0xAF,0x8D,0x36,0x64,0xE3,0x9A,0x83, - 0x78,0xC2,0x8D,0xC0,0x9D,0xD9,0x3A,0x1C,0xC5,0x2B,0x50,0x68, - 0x07,0xA9,0x4B,0x8C,0x07,0x57,0xD6,0x15,0x03,0x4E,0x9E,0x01, - 0xF2,0x6F,0x35,0xAC,0x26,0x9C,0x92,0x68,0x61,0x13,0xFB,0x01, - 0xBA,0x22,0x36,0x01,0x55,0xB6,0x62,0xD9,0xB2,0x98,0xCE,0x5D, - 0x4B,0xA5,0x41,0xD6,0xE5,0x70,0x78,0x12,0x1F,0x64,0xB6,0x6F, - 0xB0,0x91,0x51,0x91,0x92,0xC0,0x94,0x3A,0xD1,0x28,0x4D,0x30, - 0x84,0x3E,0xE4,0xE4,0x7F,0x47,0x89,0xB1,0xB6,0x8C,0x8E,0x0E, - 0x26,0xDB,0xCD,0x17,0x07,0x2A,0x21,0x7A,0xCC,0x68,0xE8,0x57, - 0x94,0x9E,0x59,0x61,0xEC,0x20,0x34,0x26,0x0D,0x66,0x44,0xEB, - 0x6F,0x02,0x58,0xE2,0xED,0xF6,0xF3,0x1B,0xBF,0x9E,0x45,0x52, - 0x5A,0x49,0xA1,0x5B, - }; - static unsigned char dh2048_g[]={ - 0x02, - }; - DH *dh = NULL; - BIGNUM *p = NULL, *g = NULL; - - dh = DH_new(); - p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL); - g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL); - if (!dh || !p || !g) - goto err; - -#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) - dh->p = p; - dh->g = g; -#else - if (!DH_set0_pqg(dh, p, NULL, g)) - goto err; -#endif - return dh; -err: - if (p) - BN_free(p); - if (g) - BN_free(g); - if (dh) - DH_free(dh); - return NULL; -} -#endif /* SPLINT */ -#endif /* OPENSSL_VERSION_NUMBER < 0x10100000 */ - -struct daemon_remote* -daemon_remote_create(struct config_file* cfg) +static int +remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg) { char* s_cert; char* s_key; - struct daemon_remote* rc = (struct daemon_remote*)calloc(1, - sizeof(*rc)); - if(!rc) { - log_err("out of memory in daemon_remote_create"); - return NULL; - } - rc->max_active = 10; - - if(!cfg->remote_control_enable) { - rc->ctx = NULL; - return rc; - } rc->ctx = SSL_CTX_new(SSLv23_server_method()); if(!rc->ctx) { log_crypto_err("could not SSL_CTX_new"); - free(rc); - return NULL; + return 0; } if(!listen_sslctx_setup(rc->ctx)) { - daemon_remote_delete(rc); - return NULL; + return 0; } - if (cfg->remote_control_use_cert == 0) { - /* No certificates are requested */ -#if defined(SSL_OP_NO_TLSv1_3) - /* in openssl 1.1.1, negotiation code for tls 1.3 does - * not allow the unauthenticated aNULL and eNULL ciphers */ - SSL_CTX_set_options(rc->ctx, SSL_OP_NO_TLSv1_3); -#endif -#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL - SSL_CTX_set_security_level(rc->ctx, 0); -#endif - if(!SSL_CTX_set_cipher_list(rc->ctx, "aNULL:eNULL")) { - log_crypto_err("Failed to set aNULL cipher list"); - daemon_remote_delete(rc); - return NULL; - } - - /* in openssl 1.1, the securitylevel 0 allows eNULL, that - * does not need the DH */ -#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) - /* Since we have no certificates and hence no source of - * DH params, let's generate and set them - */ - if(!SSL_CTX_set_tmp_dh(rc->ctx,get_dh2048())) { - log_crypto_err("Wanted to set DH param, but failed"); - daemon_remote_delete(rc); - return NULL; - } -#endif - return rc; - } - rc->use_cert = 1; s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1); s_key = fname_after_chroot(cfg->server_key_file, cfg, 1); if(!s_cert || !s_key) { @@ -294,14 +184,40 @@ daemon_remote_create(struct config_file* cfg) setup_error: free(s_cert); free(s_key); - daemon_remote_delete(rc); - return NULL; + return 0; } SSL_CTX_set_client_CA_list(rc->ctx, SSL_load_client_CA_file(s_cert)); SSL_CTX_set_verify(rc->ctx, SSL_VERIFY_PEER, NULL); free(s_cert); free(s_key); + return 1; +} + +struct daemon_remote* +daemon_remote_create(struct config_file* cfg) +{ + struct daemon_remote* rc = (struct daemon_remote*)calloc(1, + sizeof(*rc)); + if(!rc) { + log_err("out of memory in daemon_remote_create"); + return NULL; + } + rc->max_active = 10; + if(!cfg->remote_control_enable) { + rc->ctx = NULL; + return rc; + } + if(options_remote_is_address(cfg)) { + if(!remote_setup_ctx(rc, cfg)) { + daemon_remote_delete(rc); + return NULL; + } + rc->use_cert = 1; + } else { + rc->ctx = NULL; + rc->use_cert = 0; + } return rc; } @@ -551,6 +467,7 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err, log_err("out of memory"); goto close_exit; } + n->fd = newfd; /* start in reading state */ n->c = comm_point_create_raw(rc->worker->base, newfd, 0, &remote_control_callback, n); @@ -565,22 +482,26 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err, comm_point_start_listening(n->c, -1, REMOTE_CONTROL_TCP_TIMEOUT); memcpy(&n->c->repinfo.addr, &addr, addrlen); n->c->repinfo.addrlen = addrlen; - n->shake_state = rc_hs_read; - n->ssl = SSL_new(rc->ctx); - if(!n->ssl) { - log_crypto_err("could not SSL_new"); - comm_point_delete(n->c); - free(n); - goto close_exit; - } - SSL_set_accept_state(n->ssl); - (void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY); - if(!SSL_set_fd(n->ssl, newfd)) { - log_crypto_err("could not SSL_set_fd"); - SSL_free(n->ssl); - comm_point_delete(n->c); - free(n); - goto close_exit; + if(rc->use_cert) { + n->shake_state = rc_hs_read; + n->ssl = SSL_new(rc->ctx); + if(!n->ssl) { + log_crypto_err("could not SSL_new"); + comm_point_delete(n->c); + free(n); + goto close_exit; + } + SSL_set_accept_state(n->ssl); + (void)SSL_set_mode(n->ssl, SSL_MODE_AUTO_RETRY); + if(!SSL_set_fd(n->ssl, newfd)) { + log_crypto_err("could not SSL_set_fd"); + SSL_free(n->ssl); + comm_point_delete(n->c); + free(n); + goto close_exit; + } + } else { + n->ssl = NULL; } n->rc = rc; @@ -622,27 +543,41 @@ clean_point(struct daemon_remote* rc, struct rc_state* s) } int -ssl_print_text(SSL* ssl, const char* text) +ssl_print_text(RES* res, const char* text) { int r; - if(!ssl) + if(!res) return 0; - ERR_clear_error(); - if((r=SSL_write(ssl, text, (int)strlen(text))) <= 0) { - if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) { - verbose(VERB_QUERY, "warning, in SSL_write, peer " - "closed connection"); + if(res->ssl) { + ERR_clear_error(); + if((r=SSL_write(res->ssl, text, (int)strlen(text))) <= 0) { + if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) { + verbose(VERB_QUERY, "warning, in SSL_write, peer " + "closed connection"); + return 0; + } + log_crypto_err("could not SSL_write"); return 0; } - log_crypto_err("could not SSL_write"); - return 0; + } else { + size_t at = 0; + while(at < strlen(text)) { + ssize_t r = write(res->fd, text+at, strlen(text)-at); + if(r == -1) { + if(errno == EAGAIN || errno == EINTR) + continue; + log_err("could not write: %s", strerror(errno)); + return 0; + } + at += r; + } } return 1; } /** print text over the ssl connection */ static int -ssl_print_vmsg(SSL* ssl, const char* format, va_list args) +ssl_print_vmsg(RES* ssl, const char* format, va_list args) { char msg[1024]; vsnprintf(msg, sizeof(msg), format, args); @@ -650,7 +585,7 @@ ssl_print_vmsg(SSL* ssl, const char* format, va_list args) } /** printf style printing to the ssl connection */ -int ssl_printf(SSL* ssl, const char* format, ...) +int ssl_printf(RES* ssl, const char* format, ...) { va_list args; int ret; @@ -661,21 +596,33 @@ int ssl_printf(SSL* ssl, const char* format, ...) } int -ssl_read_line(SSL* ssl, char* buf, size_t max) +ssl_read_line(RES* res, char* buf, size_t max) { int r; size_t len = 0; - if(!ssl) + if(!res) return 0; while(len < max) { - ERR_clear_error(); - if((r=SSL_read(ssl, buf+len, 1)) <= 0) { - if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) { - buf[len] = 0; - return 1; + if(res->ssl) { + ERR_clear_error(); + if((r=SSL_read(res->ssl, buf+len, 1)) <= 0) { + if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) { + buf[len] = 0; + return 1; + } + log_crypto_err("could not SSL_read"); + return 0; + } + } else { + ssize_t rr = read(res->fd, buf+len, 1); + if(rr <= 0) { + if(rr == 0) { + buf[len] = 0; + return 1; + } + log_err("could not read: %s", strerror(errno)); + return 0; } - log_crypto_err("could not SSL_read"); - return 0; } if(buf[len] == '\n') { /* return string without \n */ @@ -700,14 +647,14 @@ skipwhite(char* str) } /** send the OK to the control client */ -static void send_ok(SSL* ssl) +static void send_ok(RES* ssl) { (void)ssl_printf(ssl, "ok\n"); } /** do the stop command */ static void -do_stop(SSL* ssl, struct daemon_remote* rc) +do_stop(RES* ssl, struct daemon_remote* rc) { rc->worker->need_to_exit = 1; comm_base_exit(rc->worker->base); @@ -716,7 +663,7 @@ do_stop(SSL* ssl, struct daemon_remote* rc) /** do the reload command */ static void -do_reload(SSL* ssl, struct daemon_remote* rc) +do_reload(RES* ssl, struct daemon_remote* rc) { rc->worker->need_to_exit = 0; comm_base_exit(rc->worker->base); @@ -725,7 +672,7 @@ do_reload(SSL* ssl, struct daemon_remote* rc) /** do the verbosity command */ static void -do_verbosity(SSL* ssl, char* str) +do_verbosity(RES* ssl, char* str) { int val = atoi(str); if(val == 0 && strcmp(str, "0") != 0) { @@ -738,7 +685,7 @@ do_verbosity(SSL* ssl, char* str) /** print stats from statinfo */ static int -print_stats(SSL* ssl, const char* nm, struct ub_stats_info* s) +print_stats(RES* ssl, const char* nm, struct ub_stats_info* s) { struct timeval sumwait, avg; if(!ssl_printf(ssl, "%s.num.queries"SQ"%lu\n", nm, @@ -797,7 +744,7 @@ print_stats(SSL* ssl, const char* nm, struct ub_stats_info* s) /** print stats for one thread */ static int -print_thread_stats(SSL* ssl, int i, struct ub_stats_info* s) +print_thread_stats(RES* ssl, int i, struct ub_stats_info* s) { char nm[32]; snprintf(nm, sizeof(nm), "thread%d", i); @@ -807,7 +754,7 @@ print_thread_stats(SSL* ssl, int i, struct ub_stats_info* s) /** print long number */ static int -print_longnum(SSL* ssl, const char* desc, size_t x) +print_longnum(RES* ssl, const char* desc, size_t x) { if(x > 1024*1024*1024) { /* more than a Gb */ @@ -822,7 +769,7 @@ print_longnum(SSL* ssl, const char* desc, size_t x) /** print mem stats */ static int -print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon) +print_mem(RES* ssl, struct worker* worker, struct daemon* daemon) { size_t msg, rrset, val, iter, respip; #ifdef CLIENT_SUBNET @@ -885,7 +832,7 @@ print_mem(SSL* ssl, struct worker* worker, struct daemon* daemon) /** print uptime stats */ static int -print_uptime(SSL* ssl, struct worker* worker, int reset) +print_uptime(RES* ssl, struct worker* worker, int reset) { struct timeval now = *worker->env.now_tv; struct timeval up, dt; @@ -904,7 +851,7 @@ print_uptime(SSL* ssl, struct worker* worker, int reset) /** print extended histogram */ static int -print_hist(SSL* ssl, struct ub_stats_info* s) +print_hist(RES* ssl, struct ub_stats_info* s) { struct timehist* hist; size_t i; @@ -932,7 +879,7 @@ print_hist(SSL* ssl, struct ub_stats_info* s) /** print extended stats */ static int -print_ext(SSL* ssl, struct ub_stats_info* s) +print_ext(RES* ssl, struct ub_stats_info* s) { int i; char nm[16]; @@ -1089,7 +1036,7 @@ print_ext(SSL* ssl, struct ub_stats_info* s) /** do the stats command */ static void -do_stats(SSL* ssl, struct daemon_remote* rc, int reset) +do_stats(RES* ssl, struct daemon_remote* rc, int reset) { struct daemon* daemon = rc->worker->daemon; struct ub_stats_info total; @@ -1123,7 +1070,7 @@ do_stats(SSL* ssl, struct daemon_remote* rc, int reset) /** parse commandline argument domain name */ static int -parse_arg_name(SSL* ssl, char* str, uint8_t** res, size_t* len, int* labs) +parse_arg_name(RES* ssl, char* str, uint8_t** res, size_t* len, int* labs) { uint8_t nm[LDNS_MAX_DOMAINLEN+1]; size_t nmlen = sizeof(nm); @@ -1149,7 +1096,7 @@ parse_arg_name(SSL* ssl, char* str, uint8_t** res, size_t* len, int* labs) /** find second argument, modifies string */ static int -find_arg2(SSL* ssl, char* arg, char** arg2) +find_arg2(RES* ssl, char* arg, char** arg2) { char* as = strchr(arg, ' '); char* at = strchr(arg, '\t'); @@ -1174,7 +1121,7 @@ find_arg2(SSL* ssl, char* arg, char** arg2) /** Add a new zone */ static int -perform_zone_add(SSL* ssl, struct local_zones* zones, char* arg) +perform_zone_add(RES* ssl, struct local_zones* zones, char* arg) { uint8_t* nm; int nmlabs; @@ -1214,7 +1161,7 @@ perform_zone_add(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_zone command */ static void -do_zone_add(SSL* ssl, struct local_zones* zones, char* arg) +do_zone_add(RES* ssl, struct local_zones* zones, char* arg) { if(!perform_zone_add(ssl, zones, arg)) return; @@ -1223,7 +1170,7 @@ do_zone_add(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_zones command */ static void -do_zones_add(SSL* ssl, struct local_zones* zones) +do_zones_add(RES* ssl, struct local_zones* zones) { char buf[2048]; int num = 0; @@ -1242,7 +1189,7 @@ do_zones_add(SSL* ssl, struct local_zones* zones) /** Remove a zone */ static int -perform_zone_remove(SSL* ssl, struct local_zones* zones, char* arg) +perform_zone_remove(RES* ssl, struct local_zones* zones, char* arg) { uint8_t* nm; int nmlabs; @@ -1263,7 +1210,7 @@ perform_zone_remove(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_zone_remove command */ static void -do_zone_remove(SSL* ssl, struct local_zones* zones, char* arg) +do_zone_remove(RES* ssl, struct local_zones* zones, char* arg) { if(!perform_zone_remove(ssl, zones, arg)) return; @@ -1272,7 +1219,7 @@ do_zone_remove(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_zones_remove command */ static void -do_zones_remove(SSL* ssl, struct local_zones* zones) +do_zones_remove(RES* ssl, struct local_zones* zones) { char buf[2048]; int num = 0; @@ -1291,7 +1238,7 @@ do_zones_remove(SSL* ssl, struct local_zones* zones) /** Add new RR data */ static int -perform_data_add(SSL* ssl, struct local_zones* zones, char* arg) +perform_data_add(RES* ssl, struct local_zones* zones, char* arg) { if(!local_zones_add_RR(zones, arg)) { ssl_printf(ssl,"error in syntax or out of memory, %s\n", arg); @@ -1302,7 +1249,7 @@ perform_data_add(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_data command */ static void -do_data_add(SSL* ssl, struct local_zones* zones, char* arg) +do_data_add(RES* ssl, struct local_zones* zones, char* arg) { if(!perform_data_add(ssl, zones, arg)) return; @@ -1311,7 +1258,7 @@ do_data_add(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_datas command */ static void -do_datas_add(SSL* ssl, struct local_zones* zones) +do_datas_add(RES* ssl, struct local_zones* zones) { char buf[2048]; int num = 0; @@ -1330,7 +1277,7 @@ do_datas_add(SSL* ssl, struct local_zones* zones) /** Remove RR data */ static int -perform_data_remove(SSL* ssl, struct local_zones* zones, char* arg) +perform_data_remove(RES* ssl, struct local_zones* zones, char* arg) { uint8_t* nm; int nmlabs; @@ -1345,7 +1292,7 @@ perform_data_remove(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_data_remove command */ static void -do_data_remove(SSL* ssl, struct local_zones* zones, char* arg) +do_data_remove(RES* ssl, struct local_zones* zones, char* arg) { if(!perform_data_remove(ssl, zones, arg)) return; @@ -1354,7 +1301,7 @@ do_data_remove(SSL* ssl, struct local_zones* zones, char* arg) /** Do the local_datas_remove command */ static void -do_datas_remove(SSL* ssl, struct local_zones* zones) +do_datas_remove(RES* ssl, struct local_zones* zones) { char buf[2048]; int num = 0; @@ -1373,7 +1320,7 @@ do_datas_remove(SSL* ssl, struct local_zones* zones) /** Add a new zone to view */ static void -do_view_zone_add(SSL* ssl, struct worker* worker, char* arg) +do_view_zone_add(RES* ssl, struct worker* worker, char* arg) { char* arg2; struct view* v; @@ -1406,7 +1353,7 @@ do_view_zone_add(SSL* ssl, struct worker* worker, char* arg) /** Remove a zone from view */ static void -do_view_zone_remove(SSL* ssl, struct worker* worker, char* arg) +do_view_zone_remove(RES* ssl, struct worker* worker, char* arg) { char* arg2; struct view* v; @@ -1429,7 +1376,7 @@ do_view_zone_remove(SSL* ssl, struct worker* worker, char* arg) /** Add new RR data to view */ static void -do_view_data_add(SSL* ssl, struct worker* worker, char* arg) +do_view_data_add(RES* ssl, struct worker* worker, char* arg) { char* arg2; struct view* v; @@ -1454,7 +1401,7 @@ do_view_data_add(SSL* ssl, struct worker* worker, char* arg) /** Remove RR data from view */ static void -do_view_data_remove(SSL* ssl, struct worker* worker, char* arg) +do_view_data_remove(RES* ssl, struct worker* worker, char* arg) { char* arg2; struct view* v; @@ -1477,7 +1424,7 @@ do_view_data_remove(SSL* ssl, struct worker* worker, char* arg) /** cache lookup of nameservers */ static void -do_lookup(SSL* ssl, struct worker* worker, char* arg) +do_lookup(RES* ssl, struct worker* worker, char* arg) { uint8_t* nm; int nmlabs; @@ -1515,7 +1462,7 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen, /** flush a type */ static void -do_flush_type(SSL* ssl, struct worker* worker, char* arg) +do_flush_type(RES* ssl, struct worker* worker, char* arg) { uint8_t* nm; int nmlabs; @@ -1535,7 +1482,7 @@ do_flush_type(SSL* ssl, struct worker* worker, char* arg) /** flush statistics */ static void -do_flush_stats(SSL* ssl, struct worker* worker) +do_flush_stats(RES* ssl, struct worker* worker) { worker_stats_clear(worker); send_ok(ssl); @@ -1590,7 +1537,7 @@ infra_del_host(struct lruhash_entry* e, void* arg) /** flush infra cache */ static void -do_flush_infra(SSL* ssl, struct worker* worker, char* arg) +do_flush_infra(RES* ssl, struct worker* worker, char* arg) { struct sockaddr_storage addr; socklen_t len; @@ -1624,7 +1571,7 @@ do_flush_infra(SSL* ssl, struct worker* worker, char* arg) /** flush requestlist */ static void -do_flush_requestlist(SSL* ssl, struct worker* worker) +do_flush_requestlist(RES* ssl, struct worker* worker) { mesh_delete_all(worker->env.mesh); send_ok(ssl); @@ -1682,7 +1629,7 @@ zone_del_kcache(struct lruhash_entry* e, void* arg) /** remove all rrsets and keys from zone from cache */ static void -do_flush_zone(SSL* ssl, struct worker* worker, char* arg) +do_flush_zone(RES* ssl, struct worker* worker, char* arg) { uint8_t* nm; int nmlabs; @@ -1760,7 +1707,7 @@ bogus_del_kcache(struct lruhash_entry* e, void* arg) /** remove all bogus rrsets, msgs and keys from cache */ static void -do_flush_bogus(SSL* ssl, struct worker* worker) +do_flush_bogus(RES* ssl, struct worker* worker) { struct del_info inf; /* what we do is to set them all expired */ @@ -1835,7 +1782,7 @@ negative_del_kcache(struct lruhash_entry* e, void* arg) /** remove all negative(NODATA,NXDOMAIN), and servfail messages from cache */ static void -do_flush_negative(SSL* ssl, struct worker* worker) +do_flush_negative(RES* ssl, struct worker* worker) { struct del_info inf; /* what we do is to set them all expired */ @@ -1863,7 +1810,7 @@ do_flush_negative(SSL* ssl, struct worker* worker) /** remove name rrset from cache */ static void -do_flush_name(SSL* ssl, struct worker* w, char* arg) +do_flush_name(RES* ssl, struct worker* w, char* arg) { uint8_t* nm; int nmlabs; @@ -1887,7 +1834,7 @@ do_flush_name(SSL* ssl, struct worker* w, char* arg) /** printout a delegation point info */ static int -ssl_print_name_dp(SSL* ssl, const char* str, uint8_t* nm, uint16_t dclass, +ssl_print_name_dp(RES* ssl, const char* str, uint8_t* nm, uint16_t dclass, struct delegpt* dp) { char buf[257]; @@ -1921,7 +1868,7 @@ ssl_print_name_dp(SSL* ssl, const char* str, uint8_t* nm, uint16_t dclass, /** print root forwards */ static int -print_root_fwds(SSL* ssl, struct iter_forwards* fwds, uint8_t* root) +print_root_fwds(RES* ssl, struct iter_forwards* fwds, uint8_t* root) { struct delegpt* dp; dp = forwards_lookup(fwds, root, LDNS_RR_CLASS_IN); @@ -1934,7 +1881,7 @@ print_root_fwds(SSL* ssl, struct iter_forwards* fwds, uint8_t* root) /** parse args into delegpt */ static struct delegpt* -parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names) +parse_delegpt(RES* ssl, char* args, uint8_t* nm, int allow_names) { /* parse args and add in */ char* p = args; @@ -1997,7 +1944,7 @@ parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names) /** do the status command */ static void -do_forward(SSL* ssl, struct worker* worker, char* args) +do_forward(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; uint8_t* root = (uint8_t*)"\000"; @@ -2028,7 +1975,7 @@ do_forward(SSL* ssl, struct worker* worker, char* args) } static int -parse_fs_args(SSL* ssl, char* args, uint8_t** nm, struct delegpt** dp, +parse_fs_args(RES* ssl, char* args, uint8_t** nm, struct delegpt** dp, int* insecure, int* prime) { char* zonename; @@ -2073,7 +2020,7 @@ parse_fs_args(SSL* ssl, char* args, uint8_t** nm, struct delegpt** dp, /** do the forward_add command */ static void -do_forward_add(SSL* ssl, struct worker* worker, char* args) +do_forward_add(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0; @@ -2101,7 +2048,7 @@ do_forward_add(SSL* ssl, struct worker* worker, char* args) /** do the forward_remove command */ static void -do_forward_remove(SSL* ssl, struct worker* worker, char* args) +do_forward_remove(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0; @@ -2118,7 +2065,7 @@ do_forward_remove(SSL* ssl, struct worker* worker, char* args) /** do the stub_add command */ static void -do_stub_add(SSL* ssl, struct worker* worker, char* args) +do_stub_add(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0, prime = 0; @@ -2159,7 +2106,7 @@ do_stub_add(SSL* ssl, struct worker* worker, char* args) /** do the stub_remove command */ static void -do_stub_remove(SSL* ssl, struct worker* worker, char* args) +do_stub_remove(RES* ssl, struct worker* worker, char* args) { struct iter_forwards* fwd = worker->env.fwds; int insecure = 0; @@ -2177,7 +2124,7 @@ do_stub_remove(SSL* ssl, struct worker* worker, char* args) /** do the insecure_add command */ static void -do_insecure_add(SSL* ssl, struct worker* worker, char* arg) +do_insecure_add(RES* ssl, struct worker* worker, char* arg) { size_t nmlen; int nmlabs; @@ -2198,7 +2145,7 @@ do_insecure_add(SSL* ssl, struct worker* worker, char* arg) /** do the insecure_remove command */ static void -do_insecure_remove(SSL* ssl, struct worker* worker, char* arg) +do_insecure_remove(RES* ssl, struct worker* worker, char* arg) { size_t nmlen; int nmlabs; @@ -2213,7 +2160,7 @@ do_insecure_remove(SSL* ssl, struct worker* worker, char* arg) } static void -do_insecure_list(SSL* ssl, struct worker* worker) +do_insecure_list(RES* ssl, struct worker* worker) { char buf[257]; struct trust_anchor* a; @@ -2229,7 +2176,7 @@ do_insecure_list(SSL* ssl, struct worker* worker) /** do the status command */ static void -do_status(SSL* ssl, struct worker* worker) +do_status(RES* ssl, struct worker* worker) { int i; time_t uptime; @@ -2334,7 +2281,7 @@ get_mesh_status(struct mesh_area* mesh, struct mesh_state* m, /** do the dump_requestlist command */ static void -do_dump_requestlist(SSL* ssl, struct worker* worker) +do_dump_requestlist(RES* ssl, struct worker* worker) { struct mesh_area* mesh; struct mesh_state* m; @@ -2373,7 +2320,7 @@ struct infra_arg { /** the infra cache */ struct infra_cache* infra; /** the SSL connection */ - SSL* ssl; + RES* ssl; /** the time now */ time_t now; /** ssl failure? stop writing and skip the rest. If the tcp @@ -2428,7 +2375,7 @@ dump_infra_host(struct lruhash_entry* e, void* arg) /** do the dump_infra command */ static void -do_dump_infra(SSL* ssl, struct worker* worker) +do_dump_infra(RES* ssl, struct worker* worker) { struct infra_arg arg; arg.infra = worker->env.infra_cache; @@ -2440,7 +2387,7 @@ do_dump_infra(SSL* ssl, struct worker* worker) /** do the log_reopen command */ static void -do_log_reopen(SSL* ssl, struct worker* worker) +do_log_reopen(RES* ssl, struct worker* worker) { struct config_file* cfg = worker->env.cfg; send_ok(ssl); @@ -2449,7 +2396,7 @@ do_log_reopen(SSL* ssl, struct worker* worker) /** do the set_option command */ static void -do_set_option(SSL* ssl, struct worker* worker, char* arg) +do_set_option(RES* ssl, struct worker* worker, char* arg) { char* arg2; if(!find_arg2(ssl, arg, &arg2)) @@ -2472,13 +2419,13 @@ do_set_option(SSL* ssl, struct worker* worker, char* arg) /* routine to printout option values over SSL */ void remote_get_opt_ssl(char* line, void* arg) { - SSL* ssl = (SSL*)arg; + RES* ssl = (RES*)arg; (void)ssl_printf(ssl, "%s\n", line); } /** do the get_option command */ static void -do_get_option(SSL* ssl, struct worker* worker, char* arg) +do_get_option(RES* ssl, struct worker* worker, char* arg) { int r; r = config_get_option(worker->env.cfg, arg, remote_get_opt_ssl, ssl); @@ -2490,7 +2437,7 @@ do_get_option(SSL* ssl, struct worker* worker, char* arg) /** do the list_forwards command */ static void -do_list_forwards(SSL* ssl, struct worker* worker) +do_list_forwards(RES* ssl, struct worker* worker) { /* since its a per-worker structure no locks needed */ struct iter_forwards* fwds = worker->env.fwds; @@ -2518,7 +2465,7 @@ do_list_forwards(SSL* ssl, struct worker* worker) /** do the list_stubs command */ static void -do_list_stubs(SSL* ssl, struct worker* worker) +do_list_stubs(RES* ssl, struct worker* worker) { struct iter_hints_stub* z; struct trust_anchor* a; @@ -2546,7 +2493,7 @@ do_list_stubs(SSL* ssl, struct worker* worker) /** do the list_auth_zones command */ static void -do_list_auth_zones(SSL* ssl, struct auth_zones* az) +do_list_auth_zones(RES* ssl, struct auth_zones* az) { struct auth_zone* z; char buf[257], buf2[256]; @@ -2576,7 +2523,7 @@ do_list_auth_zones(SSL* ssl, struct auth_zones* az) /** do the list_local_zones command */ static void -do_list_local_zones(SSL* ssl, struct local_zones* zones) +do_list_local_zones(RES* ssl, struct local_zones* zones) { struct local_zone* z; char buf[257]; @@ -2598,7 +2545,7 @@ do_list_local_zones(SSL* ssl, struct local_zones* zones) /** do the list_local_data command */ static void -do_list_local_data(SSL* ssl, struct worker* worker, struct local_zones* zones) +do_list_local_data(RES* ssl, struct worker* worker, struct local_zones* zones) { struct local_zone* z; struct local_data* d; @@ -2637,7 +2584,7 @@ do_list_local_data(SSL* ssl, struct worker* worker, struct local_zones* zones) /** do the view_list_local_zones command */ static void -do_view_list_local_zones(SSL* ssl, struct worker* worker, char* arg) +do_view_list_local_zones(RES* ssl, struct worker* worker, char* arg) { struct view* v = views_find_view(worker->daemon->views, arg, 0 /* get read lock*/); @@ -2653,7 +2600,7 @@ do_view_list_local_zones(SSL* ssl, struct worker* worker, char* arg) /** do the view_list_local_data command */ static void -do_view_list_local_data(SSL* ssl, struct worker* worker, char* arg) +do_view_list_local_data(RES* ssl, struct worker* worker, char* arg) { struct view* v = views_find_view(worker->daemon->views, arg, 0 /* get read lock*/); @@ -2672,7 +2619,7 @@ struct ratelimit_list_arg { /** the infra cache */ struct infra_cache* infra; /** the SSL to print to */ - SSL* ssl; + RES* ssl; /** all or only ratelimited */ int all; /** current time */ @@ -2719,7 +2666,7 @@ ip_rate_list(struct lruhash_entry* e, void* arg) /** do the ratelimit_list command */ static void -do_ratelimit_list(SSL* ssl, struct worker* worker, char* arg) +do_ratelimit_list(RES* ssl, struct worker* worker, char* arg) { struct ratelimit_list_arg a; a.all = 0; @@ -2737,7 +2684,7 @@ do_ratelimit_list(SSL* ssl, struct worker* worker, char* arg) /** do the ip_ratelimit_list command */ static void -do_ip_ratelimit_list(SSL* ssl, struct worker* worker, char* arg) +do_ip_ratelimit_list(RES* ssl, struct worker* worker, char* arg) { struct ip_ratelimit_list_arg a; a.all = 0; @@ -2755,7 +2702,7 @@ do_ip_ratelimit_list(SSL* ssl, struct worker* worker, char* arg) /** tell other processes to execute the command */ static void -distribute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd) +distribute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd) { int i; if(!cmd || !ssl) @@ -2781,7 +2728,7 @@ cmdcmp(char* p, const char* cmd, size_t len) /** execute a remote control command */ static void -execute_cmd(struct daemon_remote* rc, SSL* ssl, char* cmd, +execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd, struct worker* worker) { char* p = skipwhite(cmd); @@ -2965,7 +2912,7 @@ daemon_remote_exec(struct worker* worker) /** handle remote control request */ static void -handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl) +handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res) { int r; char pre[10]; @@ -2979,12 +2926,22 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl) fd_set_block(s->c->fd); /* try to read magic UBCT[version]_space_ string */ - ERR_clear_error(); - if((r=SSL_read(ssl, magic, (int)sizeof(magic)-1)) <= 0) { - if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) + if(res->ssl) { + ERR_clear_error(); + if((r=SSL_read(res->ssl, magic, (int)sizeof(magic)-1)) <= 0) { + if(SSL_get_error(res->ssl, r) == SSL_ERROR_ZERO_RETURN) + return; + log_crypto_err("could not SSL_read"); return; - log_crypto_err("could not SSL_read"); - return; + } + } else { + ssize_t rr = read(res->fd, magic, sizeof(magic)-1); + if(rr < (ssize_t)sizeof(magic)-1) { + if(rr == 0) return; + log_err("could not read: %s", strerror(errno)); + return; + } + r = (int)rr; } magic[6] = 0; if( r != 6 || strncmp(magic, "UBCT", 4) != 0) { @@ -2994,25 +2951,58 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, SSL* ssl) } /* read the command line */ - if(!ssl_read_line(ssl, buf, sizeof(buf))) { + if(!ssl_read_line(res, buf, sizeof(buf))) { return; } snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION); if(strcmp(magic, pre) != 0) { verbose(VERB_QUERY, "control connection had bad " "version %s, cmd: %s", magic, buf); - ssl_printf(ssl, "error version mismatch\n"); + ssl_printf(res, "error version mismatch\n"); return; } verbose(VERB_DETAIL, "control cmd: %s", buf); /* figure out what to do */ - execute_cmd(rc, ssl, buf, rc->worker); + execute_cmd(rc, res, buf, rc->worker); +} + +/** handle SSL_do_handshake changes to the file descriptor to wait for later */ +static int +remote_handshake_later(struct daemon_remote* rc, struct rc_state* s, + struct comm_point* c, int r, int r2) +{ + if(r2 == SSL_ERROR_WANT_READ) { + if(s->shake_state == rc_hs_read) { + /* try again later */ + return 0; + } + s->shake_state = rc_hs_read; + comm_point_listen_for_rw(c, 1, 0); + return 0; + } else if(r2 == SSL_ERROR_WANT_WRITE) { + if(s->shake_state == rc_hs_write) { + /* try again later */ + return 0; + } + s->shake_state = rc_hs_write; + comm_point_listen_for_rw(c, 0, 1); + return 0; + } else { + if(r == 0) + log_err("remote control connection closed prematurely"); + log_addr(1, "failed connection from", + &s->c->repinfo.addr, s->c->repinfo.addrlen); + log_crypto_err("remote control failed ssl"); + clean_point(rc, s); + return 0; + } } int remote_control_callback(struct comm_point* c, void* arg, int err, struct comm_reply* ATTR_UNUSED(rep)) { + RES res; struct rc_state* s = (struct rc_state*)arg; struct daemon_remote* rc = s->rc; int r; @@ -3022,38 +3012,16 @@ int remote_control_callback(struct comm_point* c, void* arg, int err, clean_point(rc, s); return 0; } - /* (continue to) setup the SSL connection */ - ERR_clear_error(); - r = SSL_do_handshake(s->ssl); - if(r != 1) { - int r2 = SSL_get_error(s->ssl, r); - if(r2 == SSL_ERROR_WANT_READ) { - if(s->shake_state == rc_hs_read) { - /* try again later */ - return 0; - } - s->shake_state = rc_hs_read; - comm_point_listen_for_rw(c, 1, 0); - return 0; - } else if(r2 == SSL_ERROR_WANT_WRITE) { - if(s->shake_state == rc_hs_write) { - /* try again later */ - return 0; - } - s->shake_state = rc_hs_write; - comm_point_listen_for_rw(c, 0, 1); - return 0; - } else { - if(r == 0) - log_err("remote control connection closed prematurely"); - log_addr(1, "failed connection from", - &s->c->repinfo.addr, s->c->repinfo.addrlen); - log_crypto_err("remote control failed ssl"); - clean_point(rc, s); - return 0; + if(s->ssl) { + /* (continue to) setup the SSL connection */ + ERR_clear_error(); + r = SSL_do_handshake(s->ssl); + if(r != 1) { + int r2 = SSL_get_error(s->ssl, r); + return remote_handshake_later(rc, s, c, r, r2); } + s->shake_state = rc_none; } - s->shake_state = rc_none; /* once handshake has completed, check authentication */ if (!rc->use_cert) { @@ -3076,7 +3044,9 @@ int remote_control_callback(struct comm_point* c, void* arg, int err, } /* if OK start to actually handle the request */ - handle_req(rc, s, s->ssl); + res.ssl = s->ssl; + res.fd = c->fd; + handle_req(rc, s, &res); verbose(VERB_ALGO, "remote control operation completed"); clean_point(rc, s); diff --git a/daemon/remote.h b/daemon/remote.h index 190286d47..ec62e82fe 100644 --- a/daemon/remote.h +++ b/daemon/remote.h @@ -73,6 +73,8 @@ struct rc_state { /** the ssl state */ SSL* ssl; #endif + /** file descriptor */ + int fd; /** the rc this is part of */ struct daemon_remote* rc; }; @@ -103,6 +105,17 @@ struct daemon_remote { #endif }; +/** + * Connection to print to, either SSL or plain over fd + */ +struct remote_stream { + /** SSL structure, nonNULL if using SSL */ + SSL* ssl; + /** file descriptor for plain transfer */ + int fd; +}; +typedef struct remote_stream RES; + /** * Create new remote control state for the daemon. * @param cfg: config file with key file settings. @@ -166,26 +179,26 @@ void daemon_remote_exec(struct worker* worker); * @param text: the text. * @return false on connection failure. */ -int ssl_print_text(SSL* ssl, const char* text); +int ssl_print_text(RES* ssl, const char* text); /** * printf style printing to the ssl connection - * @param ssl: the SSL connection to print to. Blocking. + * @param ssl: the RES connection to print to. Blocking. * @param format: printf style format string. * @return success or false on a network failure. */ -int ssl_printf(SSL* ssl, const char* format, ...) +int ssl_printf(RES* ssl, const char* format, ...) ATTR_FORMAT(printf, 2, 3); /** * Read until \n is encountered - * If SSL signals EOF, the string up to then is returned (without \n). - * @param ssl: the SSL connection to read from. blocking. + * If stream signals EOF, the string up to then is returned (without \n). + * @param ssl: the RES connection to read from. blocking. * @param buf: buffer to read to. * @param max: size of buffer. * @return false on connection failure. */ -int ssl_read_line(SSL* ssl, char* buf, size_t max); +int ssl_read_line(RES* ssl, char* buf, size_t max); #endif /* HAVE_SSL */ #endif /* DAEMON_REMOTE_H */ diff --git a/doc/Changelog b/doc/Changelog index 80f4a6041..da6a63a9d 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,9 @@ +12 June 2018: Wouter + - #4102 for NSD, but for Unbound. Named unix pipes do not use + certificate and key files, access can be restricted with file and + directory permissions. The option control-use-cert is no longer + used, and ignored if found in unbound.conf. + 6 June 2018: Wouter - Patch to fix openwrt for mac os build darwin detection in configure. diff --git a/doc/example.conf.in b/doc/example.conf.in index c8bb0b3ca..e53105307 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -774,12 +774,10 @@ remote-control: # set up the keys and certificates with unbound-control-setup. # control-enable: no - # Set to no and use an absolute path as control-interface to use - # a unix local named pipe for unbound-control. - # control-use-cert: yes - # what interfaces are listened to for remote control. # give 0.0.0.0 and ::0 to listen to all interfaces. + # set to an absolute path to use a unix local name pipe, certificates + # are not used for that, so key and cert files need not be present. # control-interface: 127.0.0.1 # control-interface: ::1 diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 8f494d210..6210cc09d 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -1369,6 +1369,14 @@ By default localhost (127.0.0.1 and ::1) is listened to. Use 0.0.0.0 and ::0 to listen to all interfaces. If you change this and permissions have been dropped, you must restart the server for the change to take effect. +.IP +If you set it to an absolute path, a local socket is used. The local socket +does not use the certificates and keys, so those files need not be present. +To restrict access, unbound sets permissions on the file to the user and +group that is configured, the access bits are set to allow the group members +to access the control socket file. Put users that need to access the socket +in the that group. To restrict access further, create a directory to put +the control socket in and restrict access to that directory. .TP 5 .B control\-port: \fI The port number to listen on for IPv4 or IPv6 control interfaces, @@ -1376,13 +1384,6 @@ default is 8953. If you change this and permissions have been dropped, you must restart the server for the change to take effect. .TP 5 -.B control\-use\-cert: \fI -Whether to require certificate authentication of control connections. -The default is "yes". -This should not be changed unless there are other mechanisms in place -to prevent untrusted users from accessing the remote control -interface. -.TP 5 .B server\-key\-file: \fI Path to the server private key, by default unbound_server.key. This file is generated by the \fIunbound\-control\-setup\fR utility. diff --git a/smallapp/unbound-checkconf.c b/smallapp/unbound-checkconf.c index e205c3e9c..a1a3fc62a 100644 --- a/smallapp/unbound-checkconf.c +++ b/smallapp/unbound-checkconf.c @@ -542,7 +542,7 @@ morechecks(struct config_file* cfg, const char* fname) # endif } #endif - if(cfg->remote_control_enable && cfg->remote_control_use_cert) { + if(cfg->remote_control_enable && options_remote_is_address(cfg)) { check_chroot_string("server-key-file", &cfg->server_key_file, cfg->chrootdir, cfg); check_chroot_string("server-cert-file", &cfg->server_cert_file, diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index 2337e7a73..ade245292 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -451,47 +451,33 @@ setup_ctx(struct config_file* cfg) char* s_cert=NULL, *c_key=NULL, *c_cert=NULL; SSL_CTX* ctx; - if(cfg->remote_control_use_cert) { - s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1); - c_key = fname_after_chroot(cfg->control_key_file, cfg, 1); - c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1); - if(!s_cert || !c_key || !c_cert) - fatal_exit("out of memory"); - } + if(!options_remote_is_address(cfg)) + return NULL; + s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1); + c_key = fname_after_chroot(cfg->control_key_file, cfg, 1); + c_cert = fname_after_chroot(cfg->control_cert_file, cfg, 1); + if(!s_cert || !c_key || !c_cert) + fatal_exit("out of memory"); ctx = SSL_CTX_new(SSLv23_client_method()); if(!ctx) ssl_err("could not allocate SSL_CTX pointer"); if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) != SSL_OP_NO_SSLv2) ssl_err("could not set SSL_OP_NO_SSLv2"); - if(cfg->remote_control_use_cert) { - if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) - != SSL_OP_NO_SSLv3) - ssl_err("could not set SSL_OP_NO_SSLv3"); - if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert) || - !SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM) - || !SSL_CTX_check_private_key(ctx)) - ssl_err("Error setting up SSL_CTX client key and cert"); - if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1) - ssl_err("Error setting up SSL_CTX verify, server cert"); - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); - - free(s_cert); - free(c_key); - free(c_cert); - } else { - /* Use ciphers that don't require authentication */ -#if defined(SSL_OP_NO_TLSv1_3) - /* in openssl 1.1.1, negotiation code for tls 1.3 does - * not allow the unauthenticated aNULL and eNULL ciphers */ - SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3); -#endif -#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL - SSL_CTX_set_security_level(ctx, 0); -#endif - if(!SSL_CTX_set_cipher_list(ctx, "aNULL:eNULL")) - ssl_err("Error setting NULL cipher!"); - } + if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) + != SSL_OP_NO_SSLv3) + ssl_err("could not set SSL_OP_NO_SSLv3"); + if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert) || + !SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM) + || !SSL_CTX_check_private_key(ctx)) + ssl_err("Error setting up SSL_CTX client key and cert"); + if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1) + ssl_err("Error setting up SSL_CTX verify, server cert"); + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); + + free(s_cert); + free(c_key); + free(c_cert); return ctx; } @@ -571,12 +557,13 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd) /** setup SSL on the connection */ static SSL* -setup_ssl(SSL_CTX* ctx, int fd, struct config_file* cfg) +setup_ssl(SSL_CTX* ctx, int fd) { SSL* ssl; X509* x; int r; + if(!ctx) return NULL; ssl = SSL_new(ctx); if(!ssl) ssl_err("could not SSL_new"); @@ -597,78 +584,106 @@ setup_ssl(SSL_CTX* ctx, int fd, struct config_file* cfg) /* check authenticity of server */ if(SSL_get_verify_result(ssl) != X509_V_OK) ssl_err("SSL verification failed"); - if(cfg->remote_control_use_cert) { - x = SSL_get_peer_certificate(ssl); - if(!x) - ssl_err("Server presented no peer certificate"); - X509_free(x); - } + x = SSL_get_peer_certificate(ssl); + if(!x) + ssl_err("Server presented no peer certificate"); + X509_free(x); return ssl; } +/** read from ssl or fd, fatalexit on error, 0 EOF, 1 success */ +static int +remote_read(SSL* ssl, int fd, char* buf, size_t len) +{ + if(ssl) { + int r; + ERR_clear_error(); + if((r = SSL_read(ssl, buf, (int)len-1)) <= 0) { + if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) { + /* EOF */ + return 0; + } + ssl_err("could not SSL_read"); + } + buf[r] = 0; + } else { + ssize_t rr = read(fd, buf, len-1); + if(rr <= 0) { + if(rr == 0) { + /* EOF */ + return 0; + } + fatal_exit("could not read: %s", strerror(errno)); + } + buf[rr] = 0; + } + return 1; +} + +/** write to ssl or fd, fatalexit on error */ +static void +remote_write(SSL* ssl, int fd, const char* buf, size_t len) +{ + if(ssl) { + if(SSL_write(ssl, buf, (int)len) <= 0) + ssl_err("could not SSL_write"); + } else { + if(write(fd, buf, len) < (ssize_t)len) + fatal_exit("could not write: %s", strerror(errno)); + } +} + /** send stdin to server */ static void -send_file(SSL* ssl, FILE* in, char* buf, size_t sz) +send_file(SSL* ssl, int fd, FILE* in, char* buf, size_t sz) { while(fgets(buf, (int)sz, in)) { - if(SSL_write(ssl, buf, (int)strlen(buf)) <= 0) - ssl_err("could not SSL_write contents"); + remote_write(ssl, fd, buf, strlen(buf)); } } /** send end-of-file marker to server */ static void -send_eof(SSL* ssl) +send_eof(SSL* ssl, int fd) { char e[] = {0x04, 0x0a}; - if(SSL_write(ssl, e, (int)sizeof(e)) <= 0) - ssl_err("could not SSL_write end-of-file marker"); + remote_write(ssl, fd, e, sizeof(e)); } /** send command and display result */ static int -go_cmd(SSL* ssl, int quiet, int argc, char* argv[]) +go_cmd(SSL* ssl, int fd, int quiet, int argc, char* argv[]) { char pre[10]; const char* space=" "; const char* newline="\n"; int was_error = 0, first_line = 1; - int r, i; + int i; char buf[1024]; snprintf(pre, sizeof(pre), "UBCT%d ", UNBOUND_CONTROL_VERSION); - if(SSL_write(ssl, pre, (int)strlen(pre)) <= 0) - ssl_err("could not SSL_write"); + remote_write(ssl, fd, pre, strlen(pre)); for(i=0; i0&&strcmp(argv[0],"status")==0); - ssl = setup_ssl(ctx, fd, cfg); + ssl = setup_ssl(ctx, fd); /* send command */ - ret = go_cmd(ssl, quiet, argc, argv); + ret = go_cmd(ssl, fd, quiet, argc, argv); - SSL_free(ssl); + if(ssl) SSL_free(ssl); #ifndef USE_WINSOCK close(fd); #else closesocket(fd); #endif - SSL_CTX_free(ctx); + if(ctx) SSL_CTX_free(ctx); config_delete(cfg); return ret; } diff --git a/util/config_file.c b/util/config_file.c index b76ed56fc..b43eb2ae2 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -246,7 +246,6 @@ config_create(void) cfg->remote_control_enable = 0; cfg->control_ifs = NULL; cfg->control_port = UNBOUND_CONTROL_PORT; - cfg->remote_control_use_cert = 1; cfg->minimal_responses = 0; cfg->rrset_roundrobin = 0; cfg->max_udp_size = 4096; @@ -2264,3 +2263,12 @@ void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname) snprintf(b, sizeof(b), "%s %s", str, buf); errinf(qstate, b); } + +int options_remote_is_address(struct config_file* cfg) +{ + if(!cfg->remote_control_enable) return 0; + if(!cfg->control_ifs) return 1; + if(!cfg->control_ifs->str) return 1; + if(cfg->control_ifs->str[0] == 0) return 1; + return (cfg->control_ifs->str[0] != '/'); +} diff --git a/util/config_file.h b/util/config_file.h index 548cc33e9..9eb809faa 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -377,8 +377,6 @@ struct config_file { struct config_strlist* control_ifs; /** port number for the control port */ int control_port; - /** use certificates for remote control */ - int remote_control_use_cert; /** private key file for server */ char* server_key_file; /** certificate file for server */ @@ -894,6 +892,10 @@ void config_delview(struct config_view* p); */ void config_delviews(struct config_view* list); +/** check if config turns on IP-address interface with certificates or a + * named pipe without certificates. */ +int options_remote_is_address(struct config_file* cfg); + /** * Convert 14digit to time value * @param str: string of 14 digits diff --git a/util/configparser.c b/util/configparser.c index acb7cf438..161653d7f 100644 --- a/util/configparser.c +++ b/util/configparser.c @@ -999,15 +999,15 @@ static const yytype_uint16 yyrline[] = 2025, 2034, 2044, 2054, 2064, 2071, 2078, 2087, 2097, 2107, 2114, 2121, 2128, 2136, 2146, 2156, 2166, 2176, 2206, 2216, 2224, 2233, 2248, 2257, 2262, 2263, 2264, 2264, 2264, 2265, - 2265, 2265, 2266, 2266, 2268, 2278, 2287, 2294, 2304, 2311, - 2318, 2325, 2332, 2337, 2338, 2339, 2339, 2340, 2340, 2341, - 2341, 2342, 2343, 2344, 2345, 2346, 2347, 2349, 2357, 2364, - 2372, 2380, 2387, 2394, 2403, 2412, 2421, 2430, 2439, 2448, - 2453, 2454, 2455, 2457, 2463, 2473, 2480, 2489, 2497, 2503, - 2504, 2506, 2506, 2506, 2507, 2507, 2508, 2509, 2510, 2511, - 2512, 2514, 2524, 2534, 2541, 2550, 2557, 2566, 2574, 2587, - 2595, 2608, 2613, 2614, 2615, 2615, 2616, 2616, 2616, 2618, - 2632, 2647, 2659, 2674 + 2265, 2265, 2266, 2266, 2268, 2278, 2287, 2294, 2301, 2308, + 2315, 2322, 2329, 2334, 2335, 2336, 2336, 2337, 2337, 2338, + 2338, 2339, 2340, 2341, 2342, 2343, 2344, 2346, 2354, 2361, + 2369, 2377, 2384, 2391, 2400, 2409, 2418, 2427, 2436, 2445, + 2450, 2451, 2452, 2454, 2460, 2470, 2477, 2486, 2494, 2500, + 2501, 2503, 2503, 2503, 2504, 2504, 2505, 2506, 2507, 2508, + 2509, 2511, 2521, 2531, 2538, 2547, 2554, 2563, 2571, 2584, + 2592, 2605, 2610, 2611, 2612, 2612, 2613, 2613, 2613, 2615, + 2629, 2644, 2656, 2671 }; #endif @@ -5082,128 +5082,125 @@ yyreduce: #line 2295 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(control_use_cert:%s)\n", (yyvsp[0].str))); - if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->cfg->remote_control_use_cert = - (strcmp((yyvsp[0].str), "yes")==0); + /* ignored */ free((yyvsp[0].str)); } -#line 5092 "util/configparser.c" /* yacc.c:1646 */ +#line 5089 "util/configparser.c" /* yacc.c:1646 */ break; case 428: -#line 2305 "./util/configparser.y" /* yacc.c:1646 */ +#line 2302 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(rc_server_key_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->server_key_file); cfg_parser->cfg->server_key_file = (yyvsp[0].str); } -#line 5102 "util/configparser.c" /* yacc.c:1646 */ +#line 5099 "util/configparser.c" /* yacc.c:1646 */ break; case 429: -#line 2312 "./util/configparser.y" /* yacc.c:1646 */ +#line 2309 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(rc_server_cert_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->server_cert_file); cfg_parser->cfg->server_cert_file = (yyvsp[0].str); } -#line 5112 "util/configparser.c" /* yacc.c:1646 */ +#line 5109 "util/configparser.c" /* yacc.c:1646 */ break; case 430: -#line 2319 "./util/configparser.y" /* yacc.c:1646 */ +#line 2316 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(rc_control_key_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->control_key_file); cfg_parser->cfg->control_key_file = (yyvsp[0].str); } -#line 5122 "util/configparser.c" /* yacc.c:1646 */ +#line 5119 "util/configparser.c" /* yacc.c:1646 */ break; case 431: -#line 2326 "./util/configparser.y" /* yacc.c:1646 */ +#line 2323 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(rc_control_cert_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->control_cert_file); cfg_parser->cfg->control_cert_file = (yyvsp[0].str); } -#line 5132 "util/configparser.c" /* yacc.c:1646 */ +#line 5129 "util/configparser.c" /* yacc.c:1646 */ break; case 432: -#line 2333 "./util/configparser.y" /* yacc.c:1646 */ +#line 2330 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("\nP(dnstap:)\n")); } -#line 5140 "util/configparser.c" /* yacc.c:1646 */ +#line 5137 "util/configparser.c" /* yacc.c:1646 */ break; case 447: -#line 2350 "./util/configparser.y" /* yacc.c:1646 */ +#line 2347 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_enable:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap = (strcmp((yyvsp[0].str), "yes")==0); } -#line 5151 "util/configparser.c" /* yacc.c:1646 */ +#line 5148 "util/configparser.c" /* yacc.c:1646 */ break; case 448: -#line 2358 "./util/configparser.y" /* yacc.c:1646 */ +#line 2355 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_socket_path:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_socket_path); cfg_parser->cfg->dnstap_socket_path = (yyvsp[0].str); } -#line 5161 "util/configparser.c" /* yacc.c:1646 */ +#line 5158 "util/configparser.c" /* yacc.c:1646 */ break; case 449: -#line 2365 "./util/configparser.y" /* yacc.c:1646 */ +#line 2362 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_send_identity:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap_send_identity = (strcmp((yyvsp[0].str), "yes")==0); } -#line 5172 "util/configparser.c" /* yacc.c:1646 */ +#line 5169 "util/configparser.c" /* yacc.c:1646 */ break; case 450: -#line 2373 "./util/configparser.y" /* yacc.c:1646 */ +#line 2370 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_send_version:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) yyerror("expected yes or no."); else cfg_parser->cfg->dnstap_send_version = (strcmp((yyvsp[0].str), "yes")==0); } -#line 5183 "util/configparser.c" /* yacc.c:1646 */ +#line 5180 "util/configparser.c" /* yacc.c:1646 */ break; case 451: -#line 2381 "./util/configparser.y" /* yacc.c:1646 */ +#line 2378 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_identity:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_identity); cfg_parser->cfg->dnstap_identity = (yyvsp[0].str); } -#line 5193 "util/configparser.c" /* yacc.c:1646 */ +#line 5190 "util/configparser.c" /* yacc.c:1646 */ break; case 452: -#line 2388 "./util/configparser.y" /* yacc.c:1646 */ +#line 2385 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_version:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_version); cfg_parser->cfg->dnstap_version = (yyvsp[0].str); } -#line 5203 "util/configparser.c" /* yacc.c:1646 */ +#line 5200 "util/configparser.c" /* yacc.c:1646 */ break; case 453: -#line 2395 "./util/configparser.y" /* yacc.c:1646 */ +#line 2392 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_log_resolver_query_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5211,11 +5208,11 @@ yyreduce: else cfg_parser->cfg->dnstap_log_resolver_query_messages = (strcmp((yyvsp[0].str), "yes")==0); } -#line 5215 "util/configparser.c" /* yacc.c:1646 */ +#line 5212 "util/configparser.c" /* yacc.c:1646 */ break; case 454: -#line 2404 "./util/configparser.y" /* yacc.c:1646 */ +#line 2401 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_log_resolver_response_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5223,11 +5220,11 @@ yyreduce: else cfg_parser->cfg->dnstap_log_resolver_response_messages = (strcmp((yyvsp[0].str), "yes")==0); } -#line 5227 "util/configparser.c" /* yacc.c:1646 */ +#line 5224 "util/configparser.c" /* yacc.c:1646 */ break; case 455: -#line 2413 "./util/configparser.y" /* yacc.c:1646 */ +#line 2410 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_log_client_query_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5235,11 +5232,11 @@ yyreduce: else cfg_parser->cfg->dnstap_log_client_query_messages = (strcmp((yyvsp[0].str), "yes")==0); } -#line 5239 "util/configparser.c" /* yacc.c:1646 */ +#line 5236 "util/configparser.c" /* yacc.c:1646 */ break; case 456: -#line 2422 "./util/configparser.y" /* yacc.c:1646 */ +#line 2419 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_log_client_response_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5247,11 +5244,11 @@ yyreduce: else cfg_parser->cfg->dnstap_log_client_response_messages = (strcmp((yyvsp[0].str), "yes")==0); } -#line 5251 "util/configparser.c" /* yacc.c:1646 */ +#line 5248 "util/configparser.c" /* yacc.c:1646 */ break; case 457: -#line 2431 "./util/configparser.y" /* yacc.c:1646 */ +#line 2428 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_log_forwarder_query_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5259,11 +5256,11 @@ yyreduce: else cfg_parser->cfg->dnstap_log_forwarder_query_messages = (strcmp((yyvsp[0].str), "yes")==0); } -#line 5263 "util/configparser.c" /* yacc.c:1646 */ +#line 5260 "util/configparser.c" /* yacc.c:1646 */ break; case 458: -#line 2440 "./util/configparser.y" /* yacc.c:1646 */ +#line 2437 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dt_dnstap_log_forwarder_response_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5271,29 +5268,29 @@ yyreduce: else cfg_parser->cfg->dnstap_log_forwarder_response_messages = (strcmp((yyvsp[0].str), "yes")==0); } -#line 5275 "util/configparser.c" /* yacc.c:1646 */ +#line 5272 "util/configparser.c" /* yacc.c:1646 */ break; case 459: -#line 2449 "./util/configparser.y" /* yacc.c:1646 */ +#line 2446 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("\nP(python:)\n")); } -#line 5283 "util/configparser.c" /* yacc.c:1646 */ +#line 5280 "util/configparser.c" /* yacc.c:1646 */ break; case 463: -#line 2458 "./util/configparser.y" /* yacc.c:1646 */ +#line 2455 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(python-script:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->python_script); cfg_parser->cfg->python_script = (yyvsp[0].str); } -#line 5293 "util/configparser.c" /* yacc.c:1646 */ +#line 5290 "util/configparser.c" /* yacc.c:1646 */ break; case 464: -#line 2464 "./util/configparser.y" /* yacc.c:1646 */ +#line 2461 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(disable_dnssec_lame_check:%s)\n", (yyvsp[0].str))); if (strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5302,21 +5299,21 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5306 "util/configparser.c" /* yacc.c:1646 */ +#line 5303 "util/configparser.c" /* yacc.c:1646 */ break; case 465: -#line 2474 "./util/configparser.y" /* yacc.c:1646 */ +#line 2471 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(server_log_identity:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->log_identity); cfg_parser->cfg->log_identity = (yyvsp[0].str); } -#line 5316 "util/configparser.c" /* yacc.c:1646 */ +#line 5313 "util/configparser.c" /* yacc.c:1646 */ break; case 466: -#line 2481 "./util/configparser.y" /* yacc.c:1646 */ +#line 2478 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(server_response_ip:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); validate_respip_action((yyvsp[0].str)); @@ -5324,31 +5321,31 @@ yyreduce: (yyvsp[-1].str), (yyvsp[0].str))) fatal_exit("out of memory adding response-ip"); } -#line 5328 "util/configparser.c" /* yacc.c:1646 */ +#line 5325 "util/configparser.c" /* yacc.c:1646 */ break; case 467: -#line 2490 "./util/configparser.y" /* yacc.c:1646 */ +#line 2487 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(server_response_ip_data:%s)\n", (yyvsp[-1].str))); if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data, (yyvsp[-1].str), (yyvsp[0].str))) fatal_exit("out of memory adding response-ip-data"); } -#line 5339 "util/configparser.c" /* yacc.c:1646 */ +#line 5336 "util/configparser.c" /* yacc.c:1646 */ break; case 468: -#line 2498 "./util/configparser.y" /* yacc.c:1646 */ +#line 2495 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("\nP(dnscrypt:)\n")); OUTYY(("\nP(dnscrypt:)\n")); } -#line 5348 "util/configparser.c" /* yacc.c:1646 */ +#line 5345 "util/configparser.c" /* yacc.c:1646 */ break; case 481: -#line 2515 "./util/configparser.y" /* yacc.c:1646 */ +#line 2512 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dnsc_dnscrypt_enable:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5356,11 +5353,11 @@ yyreduce: else cfg_parser->cfg->dnscrypt = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5360 "util/configparser.c" /* yacc.c:1646 */ +#line 5357 "util/configparser.c" /* yacc.c:1646 */ break; case 482: -#line 2525 "./util/configparser.y" /* yacc.c:1646 */ +#line 2522 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dnsc_dnscrypt_port:%s)\n", (yyvsp[0].str))); @@ -5369,21 +5366,21 @@ yyreduce: else cfg_parser->cfg->dnscrypt_port = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5373 "util/configparser.c" /* yacc.c:1646 */ +#line 5370 "util/configparser.c" /* yacc.c:1646 */ break; case 483: -#line 2535 "./util/configparser.y" /* yacc.c:1646 */ +#line 2532 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dnsc_dnscrypt_provider:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnscrypt_provider); cfg_parser->cfg->dnscrypt_provider = (yyvsp[0].str); } -#line 5383 "util/configparser.c" /* yacc.c:1646 */ +#line 5380 "util/configparser.c" /* yacc.c:1646 */ break; case 484: -#line 2542 "./util/configparser.y" /* yacc.c:1646 */ +#line 2539 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dnsc_dnscrypt_provider_cert:%s)\n", (yyvsp[0].str))); if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_provider_cert, (yyvsp[0].str))) @@ -5391,21 +5388,21 @@ yyreduce: if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert, (yyvsp[0].str))) fatal_exit("out of memory adding dnscrypt-provider-cert"); } -#line 5395 "util/configparser.c" /* yacc.c:1646 */ +#line 5392 "util/configparser.c" /* yacc.c:1646 */ break; case 485: -#line 2551 "./util/configparser.y" /* yacc.c:1646 */ +#line 2548 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dnsc_dnscrypt_provider_cert_rotated:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert_rotated, (yyvsp[0].str))) fatal_exit("out of memory adding dnscrypt-provider-cert-rotated"); } -#line 5405 "util/configparser.c" /* yacc.c:1646 */ +#line 5402 "util/configparser.c" /* yacc.c:1646 */ break; case 486: -#line 2558 "./util/configparser.y" /* yacc.c:1646 */ +#line 2555 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dnsc_dnscrypt_secret_key:%s)\n", (yyvsp[0].str))); if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_secret_key, (yyvsp[0].str))) @@ -5413,22 +5410,22 @@ yyreduce: if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_secret_key, (yyvsp[0].str))) fatal_exit("out of memory adding dnscrypt-secret-key"); } -#line 5417 "util/configparser.c" /* yacc.c:1646 */ +#line 5414 "util/configparser.c" /* yacc.c:1646 */ break; case 487: -#line 2567 "./util/configparser.y" /* yacc.c:1646 */ +#line 2564 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dnscrypt_shared_secret_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->dnscrypt_shared_secret_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 5428 "util/configparser.c" /* yacc.c:1646 */ +#line 5425 "util/configparser.c" /* yacc.c:1646 */ break; case 488: -#line 2575 "./util/configparser.y" /* yacc.c:1646 */ +#line 2572 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dnscrypt_shared_secret_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -5440,22 +5437,22 @@ yyreduce: } free((yyvsp[0].str)); } -#line 5444 "util/configparser.c" /* yacc.c:1646 */ +#line 5441 "util/configparser.c" /* yacc.c:1646 */ break; case 489: -#line 2588 "./util/configparser.y" /* yacc.c:1646 */ +#line 2585 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dnscrypt_nonce_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->dnscrypt_nonce_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 5455 "util/configparser.c" /* yacc.c:1646 */ +#line 5452 "util/configparser.c" /* yacc.c:1646 */ break; case 490: -#line 2596 "./util/configparser.y" /* yacc.c:1646 */ +#line 2593 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("P(dnscrypt_nonce_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -5467,19 +5464,19 @@ yyreduce: } free((yyvsp[0].str)); } -#line 5471 "util/configparser.c" /* yacc.c:1646 */ +#line 5468 "util/configparser.c" /* yacc.c:1646 */ break; case 491: -#line 2609 "./util/configparser.y" /* yacc.c:1646 */ +#line 2606 "./util/configparser.y" /* yacc.c:1646 */ { OUTYY(("\nP(cachedb:)\n")); } -#line 5479 "util/configparser.c" /* yacc.c:1646 */ +#line 5476 "util/configparser.c" /* yacc.c:1646 */ break; case 499: -#line 2619 "./util/configparser.y" /* yacc.c:1646 */ +#line 2616 "./util/configparser.y" /* yacc.c:1646 */ { #ifdef USE_CACHEDB OUTYY(("P(backend:%s)\n", (yyvsp[0].str))); @@ -5492,11 +5489,11 @@ yyreduce: OUTYY(("P(Compiled without cachedb, ignoring)\n")); #endif } -#line 5496 "util/configparser.c" /* yacc.c:1646 */ +#line 5493 "util/configparser.c" /* yacc.c:1646 */ break; case 500: -#line 2633 "./util/configparser.y" /* yacc.c:1646 */ +#line 2630 "./util/configparser.y" /* yacc.c:1646 */ { #ifdef USE_CACHEDB OUTYY(("P(secret-seed:%s)\n", (yyvsp[0].str))); @@ -5510,11 +5507,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 5514 "util/configparser.c" /* yacc.c:1646 */ +#line 5511 "util/configparser.c" /* yacc.c:1646 */ break; case 501: -#line 2648 "./util/configparser.y" /* yacc.c:1646 */ +#line 2645 "./util/configparser.y" /* yacc.c:1646 */ { #if defined(USE_CACHEDB) && defined(USE_REDIS) OUTYY(("P(redis_server_host:%s)\n", (yyvsp[0].str))); @@ -5525,11 +5522,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 5529 "util/configparser.c" /* yacc.c:1646 */ +#line 5526 "util/configparser.c" /* yacc.c:1646 */ break; case 502: -#line 2660 "./util/configparser.y" /* yacc.c:1646 */ +#line 2657 "./util/configparser.y" /* yacc.c:1646 */ { #if defined(USE_CACHEDB) && defined(USE_REDIS) int port; @@ -5543,11 +5540,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 5547 "util/configparser.c" /* yacc.c:1646 */ +#line 5544 "util/configparser.c" /* yacc.c:1646 */ break; case 503: -#line 2675 "./util/configparser.y" /* yacc.c:1646 */ +#line 2672 "./util/configparser.y" /* yacc.c:1646 */ { #if defined(USE_CACHEDB) && defined(USE_REDIS) OUTYY(("P(redis_timeout:%s)\n", (yyvsp[0].str))); @@ -5559,11 +5556,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 5563 "util/configparser.c" /* yacc.c:1646 */ +#line 5560 "util/configparser.c" /* yacc.c:1646 */ break; -#line 5567 "util/configparser.c" /* yacc.c:1646 */ +#line 5564 "util/configparser.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -5791,7 +5788,7 @@ yyreturn: #endif return yyresult; } -#line 2687 "./util/configparser.y" /* yacc.c:1906 */ +#line 2684 "./util/configparser.y" /* yacc.c:1906 */ /* parse helper routines could be here */ diff --git a/util/configparser.y b/util/configparser.y index 3f8a2df6e..00678169b 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -2294,10 +2294,7 @@ rc_control_interface: VAR_CONTROL_INTERFACE STRING_ARG rc_control_use_cert: VAR_CONTROL_USE_CERT STRING_ARG { OUTYY(("P(control_use_cert:%s)\n", $2)); - if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) - yyerror("expected yes or no."); - else cfg_parser->cfg->remote_control_use_cert = - (strcmp($2, "yes")==0); + /* ignored */ free($2); } ;