/** 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))) {
/** 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;
/** 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 */
/** 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;
/** 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);
/** 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;
/** 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;
/** 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;
}
int
-dump_cache(SSL* ssl, struct worker* worker)
+dump_cache(RES* ssl, struct worker* worker)
{
if(!dump_rrset_cache(ssl, worker))
return 0;
/** 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));
/** 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);
/** 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)
{
/** 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;
/** 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;
/** 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)
{
/** 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;
/** 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;
}
int
-load_cache(SSL* ssl, struct worker* worker)
+load_cache(RES* ssl, struct worker* worker)
{
if(!load_rrset_cache(ssl, worker))
return 0;
/** 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;
/** 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;
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 */
#ifndef DAEMON_DUMPCACHE_H
#define DAEMON_DUMPCACHE_H
struct worker;
+#include "daemon/remote.h"
/**
* Dump cache(s) to text
* 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
* 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.
* @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 */
#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) {
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;
}
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);
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;
}
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);
}
/** 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;
}
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 */
}
/** 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);
/** 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);
/** 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) {
/** 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,
/** 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);
/** 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 */
/** 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
/** 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;
/** 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;
/** 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];
/** 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;
/** 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);
/** 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');
/** 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;
/** 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;
/** 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;
/** 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;
/** 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;
/** 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;
/** 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);
/** 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;
/** 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;
/** 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;
/** 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;
/** 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;
/** 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;
/** 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;
/** 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;
/** 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;
/** 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;
/** 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;
/** 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);
/** 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;
/** 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);
/** 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;
/** 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 */
/** 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 */
/** 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;
/** 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];
/** 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);
/** 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;
/** 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";
}
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;
/** 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;
/** 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;
/** 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;
/** 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;
/** 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;
/** 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;
}
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;
/** 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;
/** 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;
/** 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
/** 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;
/** 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);
/** 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))
/* 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);
/** 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;
/** 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;
/** 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];
/** 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];
/** 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;
/** 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*/);
/** 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*/);
/** the infra cache */
struct infra_cache* infra;
/** the SSL to print to */
- SSL* ssl;
+ RES* ssl;
/** all or only ratelimited */
int all;
/** current time */
/** 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;
/** 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;
/** 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)
/** 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);
/** 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];
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) {
}
/* 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;
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) {
}
/* 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);
/** the ssl state */
SSL* ssl;
#endif
+ /** file descriptor */
+ int fd;
/** the rc this is part of */
struct daemon_remote* rc;
};
#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.
* @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 */
+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.
# 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
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<port number>
The port number to listen on for IPv4 or IPv6 control interfaces,
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<yes or no>
-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<private key file>
Path to the server private key, by default unbound_server.key.
This file is generated by the \fIunbound\-control\-setup\fR utility.
# 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,
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;
}
/** 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");
/* 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; i<argc; i++) {
- if(SSL_write(ssl, space, (int)strlen(space)) <= 0)
- ssl_err("could not SSL_write");
- if(SSL_write(ssl, argv[i], (int)strlen(argv[i])) <= 0)
- ssl_err("could not SSL_write");
+ remote_write(ssl, fd, space, strlen(space));
+ remote_write(ssl, fd, argv[i], strlen(argv[i]));
}
- if(SSL_write(ssl, newline, (int)strlen(newline)) <= 0)
- ssl_err("could not SSL_write");
+ remote_write(ssl, fd, newline, strlen(newline));
if(argc == 1 && strcmp(argv[0], "load_cache") == 0) {
- send_file(ssl, stdin, buf, sizeof(buf));
+ send_file(ssl, fd, stdin, buf, sizeof(buf));
}
else if(argc == 1 && (strcmp(argv[0], "local_zones") == 0 ||
strcmp(argv[0], "local_zones_remove") == 0 ||
strcmp(argv[0], "local_datas") == 0 ||
strcmp(argv[0], "local_datas_remove") == 0)) {
- send_file(ssl, stdin, buf, sizeof(buf));
- send_eof(ssl);
+ send_file(ssl, fd, stdin, buf, sizeof(buf));
+ send_eof(ssl, fd);
}
while(1) {
- ERR_clear_error();
- if((r = SSL_read(ssl, buf, (int)sizeof(buf)-1)) <= 0) {
- if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
- /* EOF */
- break;
- }
- ssl_err("could not SSL_read");
+ if(remote_read(ssl, fd, buf, sizeof(buf)) == 0) {
+ break; /* EOF */
}
- buf[r] = 0;
if(first_line && strncmp(buf, "error", 5) == 0) {
printf("%s", buf);
was_error = 1;
/* contact server */
fd = contact_server(svr, cfg, argc>0&&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;
}
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;
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] != '/');
+}
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 */
*/
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
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
#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)
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)
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)
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)
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)
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)
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)
(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));
(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)
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)));
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)))
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)))
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)
}
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)
}
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)));
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)));
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)));
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;
#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)));
#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
#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 */
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);
}
;