diff options
Diffstat (limited to 'usr.sbin/unbound/util')
-rw-r--r-- | usr.sbin/unbound/util/config_file.c | 43 | ||||
-rw-r--r-- | usr.sbin/unbound/util/config_file.h | 25 | ||||
-rw-r--r-- | usr.sbin/unbound/util/configlexer.lex | 76 | ||||
-rw-r--r-- | usr.sbin/unbound/util/configparser.y | 155 | ||||
-rw-r--r-- | usr.sbin/unbound/util/fptr_wlist.c | 57 | ||||
-rw-r--r-- | usr.sbin/unbound/util/iana_ports.inc | 3 | ||||
-rw-r--r-- | usr.sbin/unbound/util/log.h | 2 | ||||
-rw-r--r-- | usr.sbin/unbound/util/mini_event.h | 2 | ||||
-rw-r--r-- | usr.sbin/unbound/util/net_help.c | 159 | ||||
-rw-r--r-- | usr.sbin/unbound/util/net_help.h | 38 | ||||
-rw-r--r-- | usr.sbin/unbound/util/netevent.c | 45 | ||||
-rw-r--r-- | usr.sbin/unbound/util/netevent.h | 18 | ||||
-rw-r--r-- | usr.sbin/unbound/util/shm_side/shm_main.c | 4 | ||||
-rw-r--r-- | usr.sbin/unbound/util/ub_event.c | 4 |
14 files changed, 550 insertions, 81 deletions
diff --git a/usr.sbin/unbound/util/config_file.c b/usr.sbin/unbound/util/config_file.c index 5a8139d69c4..6139dfc2610 100644 --- a/usr.sbin/unbound/util/config_file.c +++ b/usr.sbin/unbound/util/config_file.c @@ -116,6 +116,7 @@ config_create(void) cfg->ssl_upstream = 0; cfg->tls_cert_bundle = NULL; cfg->tls_win_cert = 0; + cfg->tls_use_sni = 1; cfg->use_syslog = 1; cfg->log_identity = NULL; /* changed later with argv[0] */ cfg->log_time_ascii = 0; @@ -186,6 +187,7 @@ config_create(void) cfg->so_reuseport = REUSEPORT_DEFAULT; cfg->ip_transparent = 0; cfg->ip_freebind = 0; + cfg->ip_dscp = 0; cfg->num_ifs = 0; cfg->ifs = NULL; cfg->num_out_ifs = 0; @@ -266,13 +268,14 @@ config_create(void) cfg->unblock_lan_zones = 0; cfg->insecure_lan_zones = 0; cfg->python_script = NULL; + cfg->dynlib_file = NULL; cfg->remote_control_enable = 0; cfg->control_ifs.first = NULL; cfg->control_ifs.last = NULL; cfg->control_port = UNBOUND_CONTROL_PORT; cfg->control_use_cert = 1; cfg->minimal_responses = 1; - cfg->rrset_roundrobin = 0; + cfg->rrset_roundrobin = 1; cfg->unknown_server_time_limit = 376; cfg->max_udp_size = 4096; if(!(cfg->server_key_file = strdup(RUN_DIR"/unbound_server.key"))) @@ -295,6 +298,8 @@ config_create(void) if(!(cfg->dnstap_socket_path = strdup(DNSTAP_SOCKET_PATH))) goto error_exit; #endif + cfg->dnstap_bidirectional = 1; + cfg->dnstap_tls = 1; cfg->disable_dnssec_lame_check = 0; cfg->ip_ratelimit = 0; cfg->ratelimit = 0; @@ -335,6 +340,7 @@ config_create(void) if(!(cfg->redis_server_host = strdup("127.0.0.1"))) goto error_exit; cfg->redis_timeout = 100; cfg->redis_server_port = 6379; + cfg->redis_expire_records = 0; #endif /* USE_REDIS */ #endif /* USE_CACHEDB */ #ifdef USE_IPSET @@ -504,6 +510,7 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_STRLIST_APPEND("tls-session-ticket-keys:", tls_session_ticket_keys) else S_STR("tls-ciphers:", tls_ciphers) else S_STR("tls-ciphersuites:", tls_ciphersuites) + else S_YNO("tls-use-sni:", tls_use_sni) else S_YNO("interface-automatic:", if_automatic) else S_YNO("use-systemd:", use_systemd) else S_YNO("do-daemonize:", do_daemonize) @@ -523,6 +530,7 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_YNO("so-reuseport:", so_reuseport) else S_YNO("ip-transparent:", ip_transparent) else S_YNO("ip-freebind:", ip_freebind) + else S_NUMBER_OR_ZERO("ip-dscp:", ip_dscp) else S_MEMSIZE("rrset-cache-size:", rrset_cache_size) else S_POW2("rrset-cache-slabs:", rrset_cache_slabs) else S_YNO("prefetch:", prefetch) @@ -622,6 +630,7 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_STR("control-cert-file:", control_cert_file) else S_STR("module-config:", module_conf) else S_STRLIST("python-script:", python_script) + else S_STRLIST("dynlib-file:", dynlib_file) else S_YNO("disable-dnssec-lame-check:", disable_dnssec_lame_check) #ifdef CLIENT_SUBNET /* Can't set max subnet prefix here, since that value is used when @@ -631,7 +640,15 @@ int config_set_option(struct config_file* cfg, const char* opt, #endif #ifdef USE_DNSTAP else S_YNO("dnstap-enable:", dnstap) + else S_YNO("dnstap-bidirectional:", dnstap_bidirectional) else S_STR("dnstap-socket-path:", dnstap_socket_path) + else S_STR("dnstap-ip:", dnstap_ip) + else S_YNO("dnstap-tls:", dnstap_tls) + else S_STR("dnstap-tls-server-name:", dnstap_tls_server_name) + else S_STR("dnstap-tls-cert-bundle:", dnstap_tls_cert_bundle) + else S_STR("dnstap-tls-client-key-file:", dnstap_tls_client_key_file) + else S_STR("dnstap-tls-client-cert-file:", + dnstap_tls_client_cert_file) else S_YNO("dnstap-send-identity:", dnstap_send_identity) else S_YNO("dnstap-send-version:", dnstap_send_version) else S_STR("dnstap-identity:", dnstap_identity) @@ -915,6 +932,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_YNO(opt, "so-reuseport", so_reuseport) else O_YNO(opt, "ip-transparent", ip_transparent) else O_YNO(opt, "ip-freebind", ip_freebind) + else O_DEC(opt, "ip-dscp", ip_dscp) else O_MEM(opt, "rrset-cache-size", rrset_cache_size) else O_DEC(opt, "rrset-cache-slabs", rrset_cache_slabs) else O_YNO(opt, "prefetch-key", prefetch_key) @@ -949,6 +967,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_LST(opt, "tls-session-ticket-keys", tls_session_ticket_keys.first) else O_STR(opt, "tls-ciphers", tls_ciphers) else O_STR(opt, "tls-ciphersuites", tls_ciphersuites) + else O_YNO(opt, "tls-use-sni", tls_use_sni) else O_YNO(opt, "use-systemd", use_systemd) else O_YNO(opt, "do-daemonize", do_daemonize) else O_STR(opt, "chroot", chrootdir) @@ -1038,7 +1057,16 @@ config_get_option(struct config_file* cfg, const char* opt, #endif #ifdef USE_DNSTAP else O_YNO(opt, "dnstap-enable", dnstap) + else O_YNO(opt, "dnstap-bidirectional", dnstap_bidirectional) else O_STR(opt, "dnstap-socket-path", dnstap_socket_path) + else O_STR(opt, "dnstap-ip", dnstap_ip) + else O_YNO(opt, "dnstap-tls", dnstap_tls) + else O_STR(opt, "dnstap-tls-server-name", dnstap_tls_server_name) + else O_STR(opt, "dnstap-tls-cert-bundle", dnstap_tls_cert_bundle) + else O_STR(opt, "dnstap-tls-client-key-file", + dnstap_tls_client_key_file) + else O_STR(opt, "dnstap-tls-client-cert-file", + dnstap_tls_client_cert_file) else O_YNO(opt, "dnstap-send-identity", dnstap_send_identity) else O_YNO(opt, "dnstap-send-version", dnstap_send_version) else O_STR(opt, "dnstap-identity", dnstap_identity) @@ -1076,6 +1104,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones) else O_DEC(opt, "max-udp-size", max_udp_size) else O_LST(opt, "python-script", python_script) + else O_LST(opt, "dynlib-file", dynlib_file) else O_YNO(opt, "disable-dnssec-lame-check", disable_dnssec_lame_check) else O_DEC(opt, "ip-ratelimit", ip_ratelimit) else O_DEC(opt, "ratelimit", ratelimit) @@ -1116,6 +1145,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_STR(opt, "redis-server-host", redis_server_host) else O_DEC(opt, "redis-server-port", redis_server_port) else O_DEC(opt, "redis-timeout", redis_timeout) + else O_YNO(opt, "redis-expire-records", redis_expire_records) #endif /* USE_REDIS */ #endif /* USE_CACHEDB */ #ifdef USE_IPSET @@ -1458,11 +1488,17 @@ config_delete(struct config_file* cfg) free(cfg->dns64_prefix); config_delstrlist(cfg->dns64_ignore_aaaa); free(cfg->dnstap_socket_path); + free(cfg->dnstap_ip); + free(cfg->dnstap_tls_server_name); + free(cfg->dnstap_tls_cert_bundle); + free(cfg->dnstap_tls_client_key_file); + free(cfg->dnstap_tls_client_cert_file); free(cfg->dnstap_identity); free(cfg->dnstap_version); config_deldblstrlist(cfg->ratelimit_for_domain); config_deldblstrlist(cfg->ratelimit_below_domain); config_delstrlist(cfg->python_script); + config_delstrlist(cfg->dynlib_file); #ifdef USE_IPSECMOD free(cfg->ipsecmod_hook); config_delstrlist(cfg->ipsecmod_whitelist); @@ -1509,6 +1545,11 @@ int cfg_mark_ports(const char* str, int allow, int* avail, int num) { char* mid = strchr(str, '-'); +#ifdef DISABLE_EXPLICIT_PORT_RANDOMISATION + log_warn("Explicit port randomisation disabled, ignoring " + "outgoing-port-permit and outgoing-port-avoid configuration " + "options"); +#endif if(!mid) { int port = atoi(str); if(port == 0 && strcmp(str, "0") != 0) { diff --git a/usr.sbin/unbound/util/config_file.h b/usr.sbin/unbound/util/config_file.h index 8739ca2ae1e..66e5025d05b 100644 --- a/usr.sbin/unbound/util/config_file.h +++ b/usr.sbin/unbound/util/config_file.h @@ -85,6 +85,8 @@ struct config_file { int do_ip4; /** do ip6 query support. */ int do_ip6; + /** prefer ip4 upstream queries. */ + int prefer_ip4; /** prefer ip6 upstream queries. */ int prefer_ip6; /** do udp query support. */ @@ -126,6 +128,8 @@ struct config_file { char* tls_ciphers; /** TLS chiphersuites (TLSv1.3) */ char* tls_ciphersuites; + /** if SNI is to be used */ + int tls_use_sni; /** outgoing port range number of ports (per thread) */ int outgoing_num_ports; @@ -186,6 +190,8 @@ struct config_file { int ip_transparent; /** IP_FREEBIND socket option request on port 53 sockets */ int ip_freebind; + /** IP_TOS socket option requested on port 53 sockets */ + int ip_dscp; /** number of interfaces to open. If 0 default all interfaces. */ int num_ifs; @@ -444,6 +450,9 @@ struct config_file { /** Python script file */ struct config_strlist* python_script; + /** Dynamic library file */ + struct config_strlist* dynlib_file; + /** Use systemd socket activation. */ int use_systemd; @@ -472,8 +481,22 @@ struct config_file { /** true to enable dnstap support */ int dnstap; + /** using bidirectional frame streams if true */ + int dnstap_bidirectional; /** dnstap socket path */ char* dnstap_socket_path; + /** dnstap IP */ + char* dnstap_ip; + /** dnstap TLS enable */ + int dnstap_tls; + /** dnstap tls server authentication name */ + char* dnstap_tls_server_name; + /** dnstap server cert bundle */ + char* dnstap_tls_cert_bundle; + /** dnstap client key for client authentication */ + char* dnstap_tls_client_key_file; + /** dnstap client cert for client authentication */ + char* dnstap_tls_client_cert_file; /** true to send "identity" via dnstap */ int dnstap_send_identity; /** true to send "version" via dnstap */ @@ -582,6 +605,8 @@ struct config_file { int redis_server_port; /** timeout (in ms) for communication with the redis server */ int redis_timeout; + /** set timeout on redis records based on DNS response ttl */ + int redis_expire_records; #endif #endif diff --git a/usr.sbin/unbound/util/configlexer.lex b/usr.sbin/unbound/util/configlexer.lex index deedffa58da..83cea4b992f 100644 --- a/usr.sbin/unbound/util/configlexer.lex +++ b/usr.sbin/unbound/util/configlexer.lex @@ -45,11 +45,13 @@ struct inc_state { int line; YY_BUFFER_STATE buffer; struct inc_state* next; + int inc_toplevel; }; static struct inc_state* config_include_stack = NULL; static int inc_depth = 0; static int inc_prev = 0; static int num_args = 0; +static int inc_toplevel = 0; void init_cfg_parse(void) { @@ -57,14 +59,15 @@ void init_cfg_parse(void) inc_depth = 0; inc_prev = 0; num_args = 0; + inc_toplevel = 0; } -static void config_start_include(const char* filename) +static void config_start_include(const char* filename, int toplevel) { FILE *input; struct inc_state* s; char* nm; - if(inc_depth++ > 100000) { + if(inc_depth+1 > 100000) { ub_c_error_msg("too many include files"); return; } @@ -96,17 +99,20 @@ static void config_start_include(const char* filename) return; } LEXOUT(("switch_to_include_file(%s)\n", filename)); + inc_depth++; s->filename = cfg_parser->filename; s->line = cfg_parser->line; s->buffer = YY_CURRENT_BUFFER; + s->inc_toplevel = inc_toplevel; s->next = config_include_stack; config_include_stack = s; cfg_parser->filename = nm; cfg_parser->line = 1; + inc_toplevel = toplevel; yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE)); } -static void config_start_include_glob(const char* filename) +static void config_start_include_glob(const char* filename, int toplevel) { /* check for wildcards */ @@ -139,19 +145,19 @@ static void config_start_include_glob(const char* filename) globfree(&g); if(r == GLOB_NOMATCH) return; /* no matches for pattern */ - config_start_include(filename); /* let original deal with it */ + config_start_include(filename, toplevel); /* let original deal with it */ return; } /* process files found, if any */ for(i=(int)g.gl_pathc-1; i>=0; i--) { - config_start_include(g.gl_pathv[i]); + config_start_include(g.gl_pathv[i], toplevel); } globfree(&g); return; } #endif /* HAVE_GLOB */ - config_start_include(filename); + config_start_include(filename, toplevel); } static void config_end_include(void) @@ -165,6 +171,7 @@ static void config_end_include(void) yy_delete_buffer(YY_CURRENT_BUFFER); yy_switch_to_buffer(s->buffer); config_include_stack = s->next; + inc_toplevel = s->inc_toplevel; free(s); } @@ -199,7 +206,7 @@ COLON \: DQANY [^\"\n\r\\]|\\. SQANY [^\'\n\r\\]|\\. -%x quotedstring singlequotedstr include include_quoted val +%x quotedstring singlequotedstr include include_quoted val include_toplevel include_toplevel_quoted %% <INITIAL,val>{SPACE}* { @@ -220,6 +227,7 @@ outgoing-num-tcp{COLON} { YDVAR(1, VAR_OUTGOING_NUM_TCP) } incoming-num-tcp{COLON} { YDVAR(1, VAR_INCOMING_NUM_TCP) } do-ip4{COLON} { YDVAR(1, VAR_DO_IP4) } do-ip6{COLON} { YDVAR(1, VAR_DO_IP6) } +prefer-ip4{COLON} { YDVAR(1, VAR_PREFER_IP4) } prefer-ip6{COLON} { YDVAR(1, VAR_PREFER_IP6) } do-udp{COLON} { YDVAR(1, VAR_DO_UDP) } do-tcp{COLON} { YDVAR(1, VAR_DO_TCP) } @@ -247,6 +255,7 @@ tls-additional-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) } tls-session-ticket-keys{COLON} { YDVAR(1, VAR_TLS_SESSION_TICKET_KEYS) } tls-ciphers{COLON} { YDVAR(1, VAR_TLS_CIPHERS) } tls-ciphersuites{COLON} { YDVAR(1, VAR_TLS_CIPHERSUITES) } +tls-use-sni{COLON} { YDVAR(1, VAR_TLS_USE_SNI) } use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) } do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) } interface{COLON} { YDVAR(1, VAR_INTERFACE) } @@ -258,6 +267,7 @@ so-sndbuf{COLON} { YDVAR(1, VAR_SO_SNDBUF) } so-reuseport{COLON} { YDVAR(1, VAR_SO_REUSEPORT) } ip-transparent{COLON} { YDVAR(1, VAR_IP_TRANSPARENT) } ip-freebind{COLON} { YDVAR(1, VAR_IP_FREEBIND) } +ip-dscp{COLON} { YDVAR(1, VAR_IP_DSCP) } chroot{COLON} { YDVAR(1, VAR_CHROOT) } username{COLON} { YDVAR(1, VAR_USERNAME) } directory{COLON} { YDVAR(1, VAR_DIRECTORY) } @@ -412,6 +422,8 @@ control-key-file{COLON} { YDVAR(1, VAR_CONTROL_KEY_FILE) } control-cert-file{COLON} { YDVAR(1, VAR_CONTROL_CERT_FILE) } python-script{COLON} { YDVAR(1, VAR_PYTHON_SCRIPT) } python{COLON} { YDVAR(0, VAR_PYTHON) } +dynlib-file{COLON} { YDVAR(1, VAR_DYNLIB_FILE) } +dynlib{COLON} { YDVAR(0, VAR_DYNLIB) } domain-insecure{COLON} { YDVAR(1, VAR_DOMAIN_INSECURE) } minimal-responses{COLON} { YDVAR(1, VAR_MINIMAL_RESPONSES) } rrset-roundrobin{COLON} { YDVAR(1, VAR_RRSET_ROUNDROBIN) } @@ -429,7 +441,16 @@ access-control-view{COLON} { YDVAR(2, VAR_ACCESS_CONTROL_VIEW) } local-zone-override{COLON} { YDVAR(3, VAR_LOCAL_ZONE_OVERRIDE) } dnstap{COLON} { YDVAR(0, VAR_DNSTAP) } dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) } +dnstap-bidirectional{COLON} { YDVAR(1, VAR_DNSTAP_BIDIRECTIONAL) } dnstap-socket-path{COLON} { YDVAR(1, VAR_DNSTAP_SOCKET_PATH) } +dnstap-ip{COLON} { YDVAR(1, VAR_DNSTAP_IP) } +dnstap-tls{COLON} { YDVAR(1, VAR_DNSTAP_TLS) } +dnstap-tls-server-name{COLON} { YDVAR(1, VAR_DNSTAP_TLS_SERVER_NAME) } +dnstap-tls-cert-bundle{COLON} { YDVAR(1, VAR_DNSTAP_TLS_CERT_BUNDLE) } +dnstap-tls-client-key-file{COLON} { + YDVAR(1, VAR_DNSTAP_TLS_CLIENT_KEY_FILE) } +dnstap-tls-client-cert-file{COLON} { + YDVAR(1, VAR_DNSTAP_TLS_CLIENT_CERT_FILE) } dnstap-send-identity{COLON} { YDVAR(1, VAR_DNSTAP_SEND_IDENTITY) } dnstap-send-version{COLON} { YDVAR(1, VAR_DNSTAP_SEND_VERSION) } dnstap-identity{COLON} { YDVAR(1, VAR_DNSTAP_IDENTITY) } @@ -490,6 +511,7 @@ secret-seed{COLON} { YDVAR(1, VAR_CACHEDB_SECRETSEED) } redis-server-host{COLON} { YDVAR(1, VAR_CACHEDB_REDISHOST) } redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) } redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) } +redis-expire-records{COLON} { YDVAR(1, VAR_CACHEDB_REDISEXPIRERECORDS) } ipset{COLON} { YDVAR(0, VAR_IPSET) } name-v4{COLON} { YDVAR(1, VAR_IPSET_NAME_V4) } name-v6{COLON} { YDVAR(1, VAR_IPSET_NAME_V6) } @@ -551,7 +573,7 @@ tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) } <include>\" { LEXOUT(("IQS ")); BEGIN(include_quoted); } <include>{UNQUOTEDLETTER}* { LEXOUT(("Iunquotedstr(%s) ", yytext)); - config_start_include_glob(yytext); + config_start_include_glob(yytext, 0); BEGIN(inc_prev); } <include_quoted><<EOF>> { @@ -564,7 +586,7 @@ tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) } <include_quoted>\" { LEXOUT(("IQE ")); yytext[yyleng - 1] = '\0'; - config_start_include_glob(yytext); + config_start_include_glob(yytext, 0); BEGIN(inc_prev); } <INITIAL,val><<EOF>> { @@ -573,11 +595,47 @@ tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) } if (!config_include_stack) { yyterminate(); } else { + int prev_toplevel = inc_toplevel; fclose(yyin); config_end_include(); + if(prev_toplevel) return (VAR_FORCE_TOPLEVEL); } } + /* include-toplevel: directive */ +<INITIAL,val>include-toplevel{COLON} { + LEXOUT(("v(%s) ", yytext)); inc_prev = YYSTATE; BEGIN(include_toplevel); +} +<include_toplevel><<EOF>> { + yyerror("EOF inside include_toplevel directive"); + BEGIN(inc_prev); +} +<include_toplevel>{SPACE}* { LEXOUT(("ITSP ")); /* ignore */ } +<include_toplevel>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; } +<include_toplevel>\" { LEXOUT(("ITQS ")); BEGIN(include_toplevel_quoted); } +<include_toplevel>{UNQUOTEDLETTER}* { + LEXOUT(("ITunquotedstr(%s) ", yytext)); + config_start_include_glob(yytext, 1); + BEGIN(inc_prev); + return (VAR_FORCE_TOPLEVEL); +} +<include_toplevel_quoted><<EOF>> { + yyerror("EOF inside quoted string"); + BEGIN(inc_prev); +} +<include_toplevel_quoted>{DQANY}* { LEXOUT(("ITSTR(%s) ", yytext)); yymore(); } +<include_toplevel_quoted>{NEWLINE} { + yyerror("newline before \" in include name"); + cfg_parser->line++; BEGIN(inc_prev); +} +<include_toplevel_quoted>\" { + LEXOUT(("ITQE ")); + yytext[yyleng - 1] = '\0'; + config_start_include_glob(yytext, 1); + BEGIN(inc_prev); + return (VAR_FORCE_TOPLEVEL); +} + <val>{UNQUOTEDLETTER}* { LEXOUT(("unquotedstr(%s) ", yytext)); if(--num_args == 0) { BEGIN(INITIAL); } yylval.str = strdup(yytext); return STRING_ARG; } diff --git a/usr.sbin/unbound/util/configparser.y b/usr.sbin/unbound/util/configparser.y index 798f4a972fd..fe600a999d4 100644 --- a/usr.sbin/unbound/util/configparser.y +++ b/usr.sbin/unbound/util/configparser.y @@ -69,8 +69,9 @@ extern struct config_parser_state* cfg_parser; %token SPACE LETTER NEWLINE COMMENT COLON ANY ZONESTR %token <str> STRING_ARG +%token VAR_FORCE_TOPLEVEL %token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT -%token VAR_OUTGOING_RANGE VAR_INTERFACE +%token VAR_OUTGOING_RANGE VAR_INTERFACE VAR_PREFER_IP4 %token VAR_DO_IP4 VAR_DO_IP6 VAR_PREFER_IP6 VAR_DO_UDP VAR_DO_TCP %token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS VAR_TCP_IDLE_TIMEOUT %token VAR_EDNS_TCP_KEEPALIVE VAR_EDNS_TCP_KEEPALIVE_TIMEOUT @@ -116,8 +117,10 @@ extern struct config_parser_state* cfg_parser; %token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES %token VAR_INFRA_CACHE_MIN_RTT %token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL VAR_DNS64_IGNORE_AAAA -%token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH -%token VAR_DNSTAP_SEND_IDENTITY VAR_DNSTAP_SEND_VERSION +%token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH VAR_DNSTAP_IP +%token VAR_DNSTAP_TLS VAR_DNSTAP_TLS_SERVER_NAME VAR_DNSTAP_TLS_CERT_BUNDLE +%token VAR_DNSTAP_TLS_CLIENT_KEY_FILE VAR_DNSTAP_TLS_CLIENT_CERT_FILE +%token VAR_DNSTAP_SEND_IDENTITY VAR_DNSTAP_SEND_VERSION VAR_DNSTAP_BIDIRECTIONAL %token VAR_DNSTAP_IDENTITY VAR_DNSTAP_VERSION %token VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES %token VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES @@ -127,6 +130,7 @@ extern struct config_parser_state* cfg_parser; %token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES %token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA %token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT +%token VAR_IP_DSCP %token VAR_DISABLE_DNSSEC_LAME_CHECK %token VAR_IP_RATELIMIT VAR_IP_RATELIMIT_SLABS VAR_IP_RATELIMIT_SIZE %token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE @@ -159,6 +163,7 @@ extern struct config_parser_state* cfg_parser; %token VAR_IPSECMOD_MAX_TTL VAR_IPSECMOD_WHITELIST VAR_IPSECMOD_STRICT %token VAR_CACHEDB VAR_CACHEDB_BACKEND VAR_CACHEDB_SECRETSEED %token VAR_CACHEDB_REDISHOST VAR_CACHEDB_REDISPORT VAR_CACHEDB_REDISTIMEOUT +%token VAR_CACHEDB_REDISEXPIRERECORDS %token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM %token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM %token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL @@ -166,10 +171,11 @@ extern struct config_parser_state* cfg_parser; %token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT %token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY %token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY -%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES +%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES VAR_TLS_USE_SNI %token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6 %token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE %token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME +%token VAR_DYNLIB VAR_DYNLIB_FILE %% toplevelvars: /* empty */ | toplevelvars toplevelvar ; @@ -178,20 +184,25 @@ toplevelvar: serverstart contents_server | stubstart contents_stub | rcstart contents_rc | dtstart contents_dt | viewstart contents_view | dnscstart contents_dnsc | cachedbstart contents_cachedb | ipsetstart contents_ipset | authstart contents_auth | - rpzstart contents_rpz + rpzstart contents_rpz | dynlibstart contents_dl | + force_toplevel + ; +force_toplevel: VAR_FORCE_TOPLEVEL + { + OUTYY(("\nP(force-toplevel)\n")); + } ; - /* server: declaration */ serverstart: VAR_SERVER { - OUTYY(("\nP(server:)\n")); + OUTYY(("\nP(server:)\n")); } ; -contents_server: contents_server content_server +contents_server: contents_server content_server | ; content_server: server_num_threads | server_verbosity | server_port | server_outgoing_range | server_do_ip4 | - server_do_ip6 | server_prefer_ip6 | + server_do_ip6 | server_prefer_ip4 | server_prefer_ip6 | server_do_udp | server_do_tcp | server_tcp_mss | server_outgoing_tcp_mss | server_tcp_idle_timeout | server_tcp_keepalive | server_tcp_keepalive_timeout | @@ -239,6 +250,7 @@ content_server: server_num_threads | server_verbosity | server_port | server_dns64_prefix | server_dns64_synthall | server_dns64_ignore_aaaa | server_infra_cache_min_rtt | server_harden_algo_downgrade | server_ip_transparent | server_ip_ratelimit | server_ratelimit | + server_ip_dscp | server_ip_ratelimit_slabs | server_ratelimit_slabs | server_ip_ratelimit_size | server_ratelimit_size | server_ratelimit_for_domain | @@ -272,7 +284,8 @@ content_server: server_num_threads | server_verbosity | server_port | server_tcp_connection_limit | server_log_servfail | server_deny_any | server_unknown_server_time_limit | server_log_tag_queryreply | server_stream_wait_size | server_tls_ciphers | - server_tls_ciphersuites | server_tls_session_ticket_keys + server_tls_ciphersuites | server_tls_session_ticket_keys | + server_tls_use_sni ; stubstart: VAR_STUB_ZONE { @@ -780,6 +793,15 @@ server_do_tcp: VAR_DO_TCP STRING_ARG free($2); } ; +server_prefer_ip4: VAR_PREFER_IP4 STRING_ARG + { + OUTYY(("P(server_prefer_ip4:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->prefer_ip4 = (strcmp($2, "yes")==0); + free($2); + } + ; server_prefer_ip6: VAR_PREFER_IP6 STRING_ARG { OUTYY(("P(server_prefer_ip6:%s)\n", $2)); @@ -938,6 +960,15 @@ server_tls_session_ticket_keys: VAR_TLS_SESSION_TICKET_KEYS STRING_ARG yyerror("out of memory"); } ; +server_tls_use_sni: VAR_TLS_USE_SNI STRING_ARG + { + OUTYY(("P(server_tls_use_sni:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->tls_use_sni = (strcmp($2, "yes")==0); + free($2); + } + ; server_use_systemd: VAR_USE_SYSTEMD STRING_ARG { OUTYY(("P(server_use_systemd:%s)\n", $2)); @@ -1247,6 +1278,20 @@ server_ip_freebind: VAR_IP_FREEBIND STRING_ARG free($2); } ; +server_ip_dscp: VAR_IP_DSCP STRING_ARG + { + OUTYY(("P(server_ip_dscp:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else if (atoi($2) > 63) + yyerror("value too large (max 63)"); + else if (atoi($2) < 0) + yyerror("value too small (min 0)"); + else + cfg_parser->cfg->ip_dscp = atoi($2); + free($2); + } + ; server_stream_wait_size: VAR_STREAM_WAIT_SIZE STRING_ARG { OUTYY(("P(server_stream_wait_size:%s)\n", $2)); @@ -2719,7 +2764,10 @@ dtstart: VAR_DNSTAP ; contents_dt: contents_dt content_dt | ; -content_dt: dt_dnstap_enable | dt_dnstap_socket_path | +content_dt: dt_dnstap_enable | dt_dnstap_socket_path | dt_dnstap_bidirectional | + dt_dnstap_ip | dt_dnstap_tls | dt_dnstap_tls_server_name | + dt_dnstap_tls_cert_bundle | + dt_dnstap_tls_client_key_file | dt_dnstap_tls_client_cert_file | dt_dnstap_send_identity | dt_dnstap_send_version | dt_dnstap_identity | dt_dnstap_version | dt_dnstap_log_resolver_query_messages | @@ -2738,6 +2786,16 @@ dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING_ARG free($2); } ; +dt_dnstap_bidirectional: VAR_DNSTAP_BIDIRECTIONAL STRING_ARG + { + OUTYY(("P(dt_dnstap_bidirectional:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_bidirectional = + (strcmp($2, "yes")==0); + free($2); + } + ; dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG { OUTYY(("P(dt_dnstap_socket_path:%s)\n", $2)); @@ -2745,6 +2803,50 @@ dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG cfg_parser->cfg->dnstap_socket_path = $2; } ; +dt_dnstap_ip: VAR_DNSTAP_IP STRING_ARG + { + OUTYY(("P(dt_dnstap_ip:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_ip); + cfg_parser->cfg->dnstap_ip = $2; + } + ; +dt_dnstap_tls: VAR_DNSTAP_TLS STRING_ARG + { + OUTYY(("P(dt_dnstap_tls:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dnstap_tls = (strcmp($2, "yes")==0); + free($2); + } + ; +dt_dnstap_tls_server_name: VAR_DNSTAP_TLS_SERVER_NAME STRING_ARG + { + OUTYY(("P(dt_dnstap_tls_server_name:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_tls_server_name); + cfg_parser->cfg->dnstap_tls_server_name = $2; + } + ; +dt_dnstap_tls_cert_bundle: VAR_DNSTAP_TLS_CERT_BUNDLE STRING_ARG + { + OUTYY(("P(dt_dnstap_tls_cert_bundle:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_tls_cert_bundle); + cfg_parser->cfg->dnstap_tls_cert_bundle = $2; + } + ; +dt_dnstap_tls_client_key_file: VAR_DNSTAP_TLS_CLIENT_KEY_FILE STRING_ARG + { + OUTYY(("P(dt_dnstap_tls_client_key_file:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_tls_client_key_file); + cfg_parser->cfg->dnstap_tls_client_key_file = $2; + } + ; +dt_dnstap_tls_client_cert_file: VAR_DNSTAP_TLS_CLIENT_CERT_FILE STRING_ARG + { + OUTYY(("P(dt_dnstap_tls_client_cert_file:%s)\n", $2)); + free(cfg_parser->cfg->dnstap_tls_client_cert_file); + cfg_parser->cfg->dnstap_tls_client_cert_file = $2; + } + ; dt_dnstap_send_identity: VAR_DNSTAP_SEND_IDENTITY STRING_ARG { OUTYY(("P(dt_dnstap_send_identity:%s)\n", $2)); @@ -2852,6 +2954,21 @@ py_script: VAR_PYTHON_SCRIPT STRING_ARG if(!cfg_strlist_append_ex(&cfg_parser->cfg->python_script, $2)) yyerror("out of memory"); } +dynlibstart: VAR_DYNLIB + { + OUTYY(("\nP(dynlib:)\n")); + } + ; +contents_dl: contents_dl content_dl + | ; +content_dl: dl_file + ; +dl_file: VAR_DYNLIB_FILE STRING_ARG + { + OUTYY(("P(dynlib-file:%s)\n", $2)); + if(!cfg_strlist_append_ex(&cfg_parser->cfg->dynlib_file, $2)) + yyerror("out of memory"); + } server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG { OUTYY(("P(disable_dnssec_lame_check:%s)\n", $2)); @@ -3003,7 +3120,8 @@ cachedbstart: VAR_CACHEDB contents_cachedb: contents_cachedb content_cachedb | ; content_cachedb: cachedb_backend_name | cachedb_secret_seed | - redis_server_host | redis_server_port | redis_timeout + redis_server_host | redis_server_port | redis_timeout | + redis_expire_records ; cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG { @@ -3069,6 +3187,19 @@ redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG free($2); } ; +redis_expire_records: VAR_CACHEDB_REDISEXPIRERECORDS STRING_ARG + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_expire_records:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->redis_expire_records = (strcmp($2, "yes")==0); + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + #endif + free($2); + } + ; server_tcp_connection_limit: VAR_TCP_CONNECTION_LIMIT STRING_ARG STRING_ARG { OUTYY(("P(server_tcp_connection_limit:%s %s)\n", $2, $3)); diff --git a/usr.sbin/unbound/util/fptr_wlist.c b/usr.sbin/unbound/util/fptr_wlist.c index 84d41cc8464..aa275ed534b 100644 --- a/usr.sbin/unbound/util/fptr_wlist.c +++ b/usr.sbin/unbound/util/fptr_wlist.c @@ -81,6 +81,9 @@ #ifdef WITH_PYTHONMODULE #include "pythonmod/pythonmod.h" #endif +#ifdef WITH_DYNLIBMODULE +#include "dynlibmod/dynlibmod.h" +#endif #ifdef USE_CACHEDB #include "cachedb/cachedb.h" #endif @@ -93,6 +96,9 @@ #ifdef USE_IPSET #include "ipset/ipset.h" #endif +#ifdef USE_DNSTAP +#include "dnstap/dtstream.h" +#endif int fptr_whitelist_comm_point(comm_point_callback_type *fptr) @@ -168,6 +174,15 @@ fptr_whitelist_event(void (*fptr)(int, short, void *)) else if(fptr == &tube_handle_signal) return 1; else if(fptr == &comm_base_handle_slow_accept) return 1; else if(fptr == &comm_point_http_handle_callback) return 1; +#ifdef USE_DNSTAP + else if(fptr == &dtio_output_cb) return 1; + else if(fptr == &dtio_cmd_cb) return 1; + else if(fptr == &dtio_reconnect_timeout_cb) return 1; + else if(fptr == &dtio_stop_timer_cb) return 1; + else if(fptr == &dtio_stop_ev_cb) return 1; + else if(fptr == &dtio_tap_callback) return 1; + else if(fptr == &dtio_mainfdcallback) return 1; +#endif #ifdef UB_ON_WINDOWS else if(fptr == &worker_win_stop_cb) return 1; #endif @@ -380,6 +395,9 @@ fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id)) #ifdef WITH_PYTHONMODULE else if(fptr == &pythonmod_init) return 1; #endif +#ifdef WITH_DYNLIBMODULE + else if(fptr == &dynlibmod_init) return 1; +#endif #ifdef USE_CACHEDB else if(fptr == &cachedb_init) return 1; #endif @@ -405,6 +423,9 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id)) #ifdef WITH_PYTHONMODULE else if(fptr == &pythonmod_deinit) return 1; #endif +#ifdef WITH_DYNLIBMODULE + else if(fptr == &dynlibmod_deinit) return 1; +#endif #ifdef USE_CACHEDB else if(fptr == &cachedb_deinit) return 1; #endif @@ -431,6 +452,9 @@ fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate, #ifdef WITH_PYTHONMODULE else if(fptr == &pythonmod_operate) return 1; #endif +#ifdef WITH_DYNLIBMODULE + else if(fptr == &dynlibmod_operate) return 1; +#endif #ifdef USE_CACHEDB else if(fptr == &cachedb_operate) return 1; #endif @@ -457,6 +481,9 @@ fptr_whitelist_mod_inform_super(void (*fptr)( #ifdef WITH_PYTHONMODULE else if(fptr == &pythonmod_inform_super) return 1; #endif +#ifdef WITH_DYNLIBMODULE + else if(fptr == &dynlibmod_inform_super) return 1; +#endif #ifdef USE_CACHEDB else if(fptr == &cachedb_inform_super) return 1; #endif @@ -483,6 +510,9 @@ fptr_whitelist_mod_clear(void (*fptr)(struct module_qstate* qstate, #ifdef WITH_PYTHONMODULE else if(fptr == &pythonmod_clear) return 1; #endif +#ifdef WITH_DYNLIBMODULE + else if(fptr == &dynlibmod_clear) return 1; +#endif #ifdef USE_CACHEDB else if(fptr == &cachedb_clear) return 1; #endif @@ -508,6 +538,9 @@ fptr_whitelist_mod_get_mem(size_t (*fptr)(struct module_env* env, int id)) #ifdef WITH_PYTHONMODULE else if(fptr == &pythonmod_get_mem) return 1; #endif +#ifdef WITH_DYNLIBMODULE + else if(fptr == &dynlibmod_get_mem) return 1; +#endif #ifdef USE_CACHEDB else if(fptr == &cachedb_get_mem) return 1; #endif @@ -566,18 +599,30 @@ int fptr_whitelist_inplace_cb_reply_generic(inplace_cb_reply_func_type* fptr, #ifdef WITH_PYTHONMODULE if(fptr == &python_inplace_cb_reply_generic) return 1; #endif +#ifdef WITH_DYNLIBMODULE + if(fptr == &dynlib_inplace_cb_reply_generic) return 1; +#endif } else if(type == inplace_cb_reply_cache) { #ifdef WITH_PYTHONMODULE if(fptr == &python_inplace_cb_reply_generic) return 1; #endif +#ifdef WITH_DYNLIBMODULE + if(fptr == &dynlib_inplace_cb_reply_generic) return 1; +#endif } else if(type == inplace_cb_reply_local) { #ifdef WITH_PYTHONMODULE if(fptr == &python_inplace_cb_reply_generic) return 1; #endif +#ifdef WITH_DYNLIBMODULE + if(fptr == &dynlib_inplace_cb_reply_generic) return 1; +#endif } else if(type == inplace_cb_reply_servfail) { #ifdef WITH_PYTHONMODULE if(fptr == &python_inplace_cb_reply_generic) return 1; #endif +#ifdef WITH_DYNLIBMODULE + if(fptr == &dynlib_inplace_cb_reply_generic) return 1; +#endif } return 0; } @@ -592,6 +637,10 @@ int fptr_whitelist_inplace_cb_query(inplace_cb_query_func_type* fptr) if(fptr == &python_inplace_cb_query_generic) return 1; #endif +#ifdef WITH_DYNLIBMODULE + if(fptr == &dynlib_inplace_cb_query_generic) + return 1; +#endif (void)fptr; return 0; } @@ -605,6 +654,10 @@ int fptr_whitelist_inplace_cb_edns_back_parsed( #else (void)fptr; #endif +#ifdef WITH_DYNLIBMODULE + if(fptr == &dynlib_inplace_cb_edns_back_parsed) + return 1; +#endif return 0; } @@ -617,6 +670,10 @@ int fptr_whitelist_inplace_cb_query_response( #else (void)fptr; #endif +#ifdef WITH_DYNLIBMODULE + if(fptr == &dynlib_inplace_cb_query_response) + return 1; +#endif return 0; } diff --git a/usr.sbin/unbound/util/iana_ports.inc b/usr.sbin/unbound/util/iana_ports.inc index 3b8afe54e82..79488f49a2c 100644 --- a/usr.sbin/unbound/util/iana_ports.inc +++ b/usr.sbin/unbound/util/iana_ports.inc @@ -3771,6 +3771,7 @@ 4188, 4191, 4192, +4195, 4197, 4199, 4300, @@ -4539,6 +4540,7 @@ 6850, 6868, 6888, +6924, 6935, 6936, 6946, @@ -5229,6 +5231,7 @@ 18241, 18262, 18463, +18516, 18634, 18635, 18668, diff --git a/usr.sbin/unbound/util/log.h b/usr.sbin/unbound/util/log.h index 098a850a559..29a1ba38009 100644 --- a/usr.sbin/unbound/util/log.h +++ b/usr.sbin/unbound/util/log.h @@ -121,7 +121,7 @@ void log_ident_set_default(const char* id); /** * Revert identity to print, back to the recorded default value. */ -void log_ident_revert_to_default(); +void log_ident_revert_to_default(void); /** * Set identity to print if there is an identity, otherwise diff --git a/usr.sbin/unbound/util/mini_event.h b/usr.sbin/unbound/util/mini_event.h index 204894d97af..1734ca574c6 100644 --- a/usr.sbin/unbound/util/mini_event.h +++ b/usr.sbin/unbound/util/mini_event.h @@ -54,6 +54,8 @@ #if defined(USE_MINI_EVENT) && !defined(USE_WINSOCK) +#include <sys/time.h> + #ifndef HAVE_EVENT_BASE_FREE #define HAVE_EVENT_BASE_FREE #endif diff --git a/usr.sbin/unbound/util/net_help.c b/usr.sbin/unbound/util/net_help.c index 0869f91f954..f59a4d65370 100644 --- a/usr.sbin/unbound/util/net_help.c +++ b/usr.sbin/unbound/util/net_help.c @@ -55,6 +55,9 @@ #ifdef HAVE_OPENSSL_ERR_H #include <openssl/err.h> #endif +#ifdef HAVE_OPENSSL_CORE_NAMES_H +#include <openssl/core_names.h> +#endif #ifdef USE_WINSOCK #include <wincrypt.h> #endif @@ -67,8 +70,8 @@ uint16_t EDNS_ADVERTISED_SIZE = 4096; /** minimal responses when positive answer: default is no */ int MINIMAL_RESPONSES = 0; -/** rrset order roundrobin: default is no */ -int RRSET_ROUNDROBIN = 0; +/** rrset order roundrobin: default is yes */ +int RRSET_ROUNDROBIN = 1; /** log tag queries with name instead of 'info' for filtering */ int LOG_TAG_QUERYREPLY = 0; @@ -79,6 +82,32 @@ static struct tls_session_ticket_key { unsigned char *hmac_key; } *ticket_keys; +/** + * callback TLS session ticket encrypt and decrypt + * For use with SSL_CTX_set_tlsext_ticket_key_cb or + * SSL_CTX_set_tlsext_ticket_key_evp_cb + * @param s: the SSL_CTX to use (from connect_sslctx_create()) + * @param key_name: secret name, 16 bytes + * @param iv: up to EVP_MAX_IV_LENGTH. + * @param evp_ctx: the evp cipher context, function sets this. + * @param hmac_ctx: the hmac context, function sets this. + * with ..key_cb it is of type HMAC_CTX* + * with ..key_evp_cb it is of type EVP_MAC_CTX* + * @param enc: 1 is encrypt, 0 is decrypt + * @return 0 on no ticket, 1 for okay, and 2 for okay but renew the ticket + * (the ticket is decrypt only). and <0 for failures. + */ +#ifdef HAVE_SSL +int tls_session_ticket_key_cb(SSL *s, unsigned char* key_name, + unsigned char* iv, EVP_CIPHER_CTX *evp_ctx, +#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB + EVP_MAC_CTX *hmac_ctx, +#else + HMAC_CTX* hmac_ctx, +#endif + int enc); +#endif /* HAVE_SSL */ + /* returns true is string addr is an ip6 specced address */ int str_is_ip6(const char* str) @@ -829,6 +858,32 @@ void log_crypto_err_code(const char* str, unsigned long err) #endif /* HAVE_SSL */ } +#ifdef HAVE_SSL +/** log certificate details */ +void +log_cert(unsigned level, const char* str, void* cert) +{ + BIO* bio; + char nul = 0; + char* pp = NULL; + long len; + if(verbosity < level) return; + bio = BIO_new(BIO_s_mem()); + if(!bio) return; + X509_print_ex(bio, (X509*)cert, 0, (unsigned long)-1 + ^(X509_FLAG_NO_SUBJECT + |X509_FLAG_NO_ISSUER|X509_FLAG_NO_VALIDITY + |X509_FLAG_NO_EXTENSIONS|X509_FLAG_NO_AUX + |X509_FLAG_NO_ATTRIBUTES)); + BIO_write(bio, &nul, (int)sizeof(nul)); + len = BIO_get_mem_data(bio, &pp); + if(len != 0 && pp) { + verbose(level, "%s: \n%s", str, pp); + } + BIO_free(bio); +} +#endif /* HAVE_SSL */ + int listen_sslctx_setup(void* ctxt) { @@ -970,7 +1025,7 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem) } SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file( verifypem)); - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); } return ctx; #else @@ -1191,6 +1246,60 @@ void* outgoing_ssl_fd(void* sslctx, int fd) #endif } +int check_auth_name_for_ssl(char* auth_name) +{ + if(!auth_name) return 1; +#if defined(HAVE_SSL) && !defined(HAVE_SSL_SET1_HOST) && !defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) + log_err("the query has an auth_name %s, but libssl has no call to " + "perform TLS authentication. Remove that name from config " + "or upgrade the ssl crypto library.", auth_name); + return 0; +#else + return 1; +#endif +} + +/** set the authname on an SSL structure, SSL* ssl */ +int set_auth_name_on_ssl(void* ssl, char* auth_name, int use_sni) +{ + if(!auth_name) return 1; +#ifdef HAVE_SSL + if(use_sni) { + (void)SSL_set_tlsext_host_name(ssl, auth_name); + } +#else + (void)ssl; + (void)use_sni; +#endif +#ifdef HAVE_SSL_SET1_HOST + SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); + /* setting the hostname makes openssl verify the + * host name in the x509 certificate in the + * SSL connection*/ + if(!SSL_set1_host(ssl, auth_name)) { + log_err("SSL_set1_host failed"); + return 0; + } +#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) + /* openssl 1.0.2 has this function that can be used for + * set1_host like verification */ + if(auth_name) { + X509_VERIFY_PARAM* param = SSL_get0_param(ssl); +# ifdef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS + X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); +# endif + if(!X509_VERIFY_PARAM_set1_host(param, auth_name, strlen(auth_name))) { + log_err("X509_VERIFY_PARAM_set1_host failed"); + return 0; + } + SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); + } +#else + verbose(VERB_ALGO, "the query has an auth_name, but libssl has no call to perform TLS authentication"); +#endif /* HAVE_SSL_SET1_HOST */ + return 1; +} + #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L /** global lock list for openssl locks */ static lock_basic_type *ub_openssl_locks = NULL; @@ -1285,7 +1394,7 @@ int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_ses if(!data) return 0; - f = fopen(p->str, "r"); + f = fopen(p->str, "rb"); if(!f) { log_err("could not read tls-session-ticket-key %s: %s", p->str, strerror(errno)); free(data); @@ -1308,10 +1417,17 @@ int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_ses } /* terminate array with NULL key name entry */ keys->key_name = NULL; +# ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB + if(SSL_CTX_set_tlsext_ticket_key_evp_cb(sslctx, tls_session_ticket_key_cb) == 0) { + log_err("no support for TLS session ticket"); + return 0; + } +# else if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) { log_err("no support for TLS session ticket"); return 0; } +# endif return 1; #else (void)sslctx; @@ -1321,13 +1437,27 @@ int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_ses } -int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name, unsigned char* iv, void *evp_sctx, void *hmac_ctx, int enc) +#ifdef HAVE_SSL +int tls_session_ticket_key_cb(SSL *ATTR_UNUSED(sslctx), unsigned char* key_name, + unsigned char* iv, EVP_CIPHER_CTX *evp_sctx, +#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB + EVP_MAC_CTX *hmac_ctx, +#else + HMAC_CTX* hmac_ctx, +#endif + int enc) { #ifdef HAVE_SSL +# ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB + OSSL_PARAM params[3]; +# else const EVP_MD *digest; +# endif const EVP_CIPHER *cipher; int evp_cipher_length; +# ifndef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB digest = EVP_sha256(); +# endif cipher = EVP_aes_256_cbc(); evp_cipher_length = EVP_CIPHER_iv_length(cipher); if( enc == 1 ) { @@ -1342,7 +1472,14 @@ int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name verbose(VERB_CLIENT, "EVP_EncryptInit_ex failed"); return -1; } -#ifndef HMAC_INIT_EX_RETURNS_VOID +#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB + params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, + ticket_keys->hmac_key, 32); + params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + "sha256", 0); + params[2] = OSSL_PARAM_construct_end(); + EVP_MAC_set_ctx_params(hmac_ctx, params); +#elif !defined(HMAC_INIT_EX_RETURNS_VOID) if (HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL) != 1) { verbose(VERB_CLIENT, "HMAC_Init_ex failed"); return -1; @@ -1366,7 +1503,14 @@ int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name return 0; } -#ifndef HMAC_INIT_EX_RETURNS_VOID +#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB + params[0] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + key->hmac_key, 32); + params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + "sha256", 0); + params[2] = OSSL_PARAM_construct_end(); + EVP_MAC_set_ctx_params(hmac_ctx, params); +#elif !defined(HMAC_INIT_EX_RETURNS_VOID) if (HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL) != 1) { verbose(VERB_CLIENT, "HMAC_Init_ex failed"); return -1; @@ -1391,6 +1535,7 @@ int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name return 0; #endif } +#endif /* HAVE_SSL */ void listen_sslctx_delete_ticket_keys(void) diff --git a/usr.sbin/unbound/util/net_help.h b/usr.sbin/unbound/util/net_help.h index 7a33a72035d..29943ada090 100644 --- a/usr.sbin/unbound/util/net_help.h +++ b/usr.sbin/unbound/util/net_help.h @@ -386,6 +386,14 @@ void log_crypto_err(const char* str); void log_crypto_err_code(const char* str, unsigned long err); /** + * Log certificate details verbosity, string, of X509 cert + * @param level: verbosity level + * @param str: string to prefix on output + * @param cert: X509* structure. + */ +void log_cert(unsigned level, const char* str, void* cert); + +/** * Set SSL_OP_NOxxx options on SSL context to disable bad crypto * @param ctxt: SSL_CTX* * @return false on failure. @@ -435,6 +443,22 @@ void* incoming_ssl_fd(void* sslctx, int fd); void* outgoing_ssl_fd(void* sslctx, int fd); /** + * check if authname SSL functionality is available, false if not + * @param auth_name: the name for the remote server, used for error print. + * @return false if SSL functionality to check the SSL name is not available. + */ +int check_auth_name_for_ssl(char* auth_name); + +/** + * set auth name on SSL for verification + * @param ssl: SSL* to set + * @param auth_name: if NULL nothing happens, otherwise the name to check. + * @param use_sni: if SNI will be used. + * @return 1 on success or NULL auth_name, 0 on failure. + */ +int set_auth_name_on_ssl(void* ssl, char* auth_name, int use_sni); + +/** * Initialize openssl locking for thread safety * @return false on failure (alloc failure). */ @@ -454,20 +478,6 @@ void ub_openssl_lock_delete(void); int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_session_ticket_keys); -/** - * callback TLS session ticket encrypt and decrypt - * For use with SSL_CTX_set_tlsext_ticket_key_cb - * @param s: the SSL_CTX to use (from connect_sslctx_create()) - * @param key_name: secret name, 16 bytes - * @param iv: up to EVP_MAX_IV_LENGTH. - * @param evp_ctx: the evp cipher context, function sets this. - * @param hmac_ctx: the hmax context, function sets this. - * @param enc: 1 is encrypt, 0 is decrypt - * @return 0 on no ticket, 1 for okay, and 2 for okay but renew the ticket - * (the ticket is decrypt only). and <0 for failures. - */ -int tls_session_ticket_key_cb(void *s, unsigned char* key_name,unsigned char* iv, void *evp_ctx, void *hmac_ctx, int enc); - /** Free memory used for TLS session ticket keys */ void listen_sslctx_delete_ticket_keys(void); diff --git a/usr.sbin/unbound/util/netevent.c b/usr.sbin/unbound/util/netevent.c index dbc9f4cd8f3..3e7a433e502 100644 --- a/usr.sbin/unbound/util/netevent.c +++ b/usr.sbin/unbound/util/netevent.c @@ -470,7 +470,7 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, msg.msg_iovlen = 1; msg.msg_control = control.buf; #ifndef S_SPLINT_S - msg.msg_controllen = sizeof(control); + msg.msg_controllen = sizeof(control.buf); #endif /* S_SPLINT_S */ msg.msg_flags = 0; @@ -480,7 +480,7 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, #ifdef IP_PKTINFO void* cmsg_data; msg.msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo)); - log_assert(msg.msg_controllen <= sizeof(control)); + log_assert(msg.msg_controllen <= sizeof(control.buf)); cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_type = IP_PKTINFO; memmove(CMSG_DATA(cmsg), &r->pktinfo.v4info, @@ -491,7 +491,7 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); #elif defined(IP_SENDSRCADDR) msg.msg_controllen = CMSG_SPACE(sizeof(struct in_addr)); - log_assert(msg.msg_controllen <= sizeof(control)); + log_assert(msg.msg_controllen <= sizeof(control.buf)); cmsg->cmsg_level = IPPROTO_IP; cmsg->cmsg_type = IP_SENDSRCADDR; memmove(CMSG_DATA(cmsg), &r->pktinfo.v4addr, @@ -504,7 +504,7 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, } else if(r->srctype == 6) { void* cmsg_data; msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); - log_assert(msg.msg_controllen <= sizeof(control)); + log_assert(msg.msg_controllen <= sizeof(control.buf)); cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_PKTINFO; memmove(CMSG_DATA(cmsg), &r->pktinfo.v6info, @@ -516,7 +516,7 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, } else { /* try to pass all 0 to use default route */ msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo)); - log_assert(msg.msg_controllen <= sizeof(control)); + log_assert(msg.msg_controllen <= sizeof(control.buf)); cmsg->cmsg_level = IPPROTO_IPV6; cmsg->cmsg_type = IPV6_PKTINFO; memset(CMSG_DATA(cmsg), 0, sizeof(struct in6_pktinfo)); @@ -616,7 +616,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg) msg.msg_iovlen = 1; msg.msg_control = ancil.buf; #ifndef S_SPLINT_S - msg.msg_controllen = sizeof(ancil); + msg.msg_controllen = sizeof(ancil.buf); #endif /* S_SPLINT_S */ msg.msg_flags = 0; rcv = recvmsg(fd, &msg, 0); @@ -1033,34 +1033,8 @@ tcp_callback_reader(struct comm_point* c) } #ifdef HAVE_SSL -/** log certificate details */ -static void -log_cert(unsigned level, const char* str, X509* cert) -{ - BIO* bio; - char nul = 0; - char* pp = NULL; - long len; - if(verbosity < level) return; - bio = BIO_new(BIO_s_mem()); - if(!bio) return; - X509_print_ex(bio, cert, 0, (unsigned long)-1 - ^(X509_FLAG_NO_SUBJECT - |X509_FLAG_NO_ISSUER|X509_FLAG_NO_VALIDITY - |X509_FLAG_NO_EXTENSIONS|X509_FLAG_NO_AUX - |X509_FLAG_NO_ATTRIBUTES)); - BIO_write(bio, &nul, (int)sizeof(nul)); - len = BIO_get_mem_data(bio, &pp); - if(len != 0 && pp) { - verbose(level, "%s: \n%s", str, pp); - } - BIO_free(bio); -} -#endif /* HAVE_SSL */ - -#ifdef HAVE_SSL /** true if the ssl handshake error has to be squelched from the logs */ -static int +int squelch_err_ssl_handshake(unsigned long err) { if(verbosity >= VERB_QUERY) @@ -3189,7 +3163,10 @@ comm_point_send_reply(struct comm_reply *repinfo) if(repinfo->c->tcp_parent->dtenv != NULL && repinfo->c->tcp_parent->dtenv->log_client_response_messages) dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, - &repinfo->addr, repinfo->c->type, repinfo->c->buffer); + &repinfo->addr, repinfo->c->type, + ( repinfo->c->tcp_req_info + ? repinfo->c->tcp_req_info->spool_buffer + : repinfo->c->buffer )); #endif if(repinfo->c->tcp_req_info) { tcp_req_info_send_reply(repinfo->c->tcp_req_info); diff --git a/usr.sbin/unbound/util/netevent.h b/usr.sbin/unbound/util/netevent.h index d80c72b3343..bb2cd1e5373 100644 --- a/usr.sbin/unbound/util/netevent.h +++ b/usr.sbin/unbound/util/netevent.h @@ -783,7 +783,23 @@ void comm_base_handle_slow_accept(int fd, short event, void* arg); void comm_point_tcp_win_bio_cb(struct comm_point* c, void* ssl); #endif -/** see if errno for tcp connect has to be logged or not. This uses errno */ +/** + * See if errno for tcp connect has to be logged or not. This uses errno + * @param addr: apart from checking errno, the addr is checked for ip4mapped + * and broadcast type, hence passed. + * @param addrlen: length of the addr parameter. + * @return true if it needs to be logged. + */ int tcp_connect_errno_needs_log(struct sockaddr* addr, socklen_t addrlen); +#ifdef HAVE_SSL +/** + * True if the ssl handshake error has to be squelched from the logs + * @param err: the error returned by the openssl routine, ERR_get_error. + * This is a packed structure with elements that are examined. + * @return true if the error is squelched (not logged). + */ +int squelch_err_ssl_handshake(unsigned long err); +#endif + #endif /* NET_EVENT_H */ diff --git a/usr.sbin/unbound/util/shm_side/shm_main.c b/usr.sbin/unbound/util/shm_side/shm_main.c index 46a71510fea..af8c5bcf370 100644 --- a/usr.sbin/unbound/util/shm_side/shm_main.c +++ b/usr.sbin/unbound/util/shm_side/shm_main.c @@ -285,6 +285,10 @@ void shm_main_run(struct worker *worker) shm_stat->mem.ipsecmod = (long long)mod_get_mem(&worker->env, "ipsecmod"); #endif +#ifdef WITH_DYNLIBMODULE + shm_stat->mem.dynlib = (long long)mod_get_mem(&worker->env, + "dynlib"); +#endif } server_stats_add(stat_total, stat_info); diff --git a/usr.sbin/unbound/util/ub_event.c b/usr.sbin/unbound/util/ub_event.c index 9af476ad408..68f633bb0ef 100644 --- a/usr.sbin/unbound/util/ub_event.c +++ b/usr.sbin/unbound/util/ub_event.c @@ -148,7 +148,7 @@ const char* ub_event_get_version(void) return event_get_version(); } -#if (defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) && defined(EVBACKEND_SELECT) +#if (defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) && defined(EV_FEATURE_BACKENDS) static const char* ub_ev_backend2str(int b) { switch(b) { @@ -184,7 +184,7 @@ ub_get_event_sys(struct ub_event_base* base, const char** n, const char** s, *n = "libev"; if (!b) b = (struct event_base*)ev_default_loop(EVFLAG_AUTO); -# ifdef EVBACKEND_SELECT +# ifdef EV_FEATURE_BACKENDS *m = ub_ev_backend2str(ev_backend((struct ev_loop*)b)); # else *m = "not obtainable"; |