diff --git a/nsd.conf.5.in b/nsd.conf.5.in index 8aad818c..b0df0bc2 100644 --- a/nsd.conf.5.in +++ b/nsd.conf.5.in @@ -1037,7 +1037,7 @@ SAN (Subject Alternative Name) DNS entry or CN (Common Name) entry equal to .BR auth-domain-name of the defined .BR tls-auth . -The certificate validify is also verified with +The certificate validity is also verified with .BR tls-cert-bundle . If authentication of the secondary, based on the specified tls-auth authentication information, fails the XFR zone transfer will be refused. If the connection is performed diff --git a/options.c b/options.c index 950a949e..a6005900 100644 --- a/options.c +++ b/options.c @@ -333,6 +333,9 @@ parse_options_file(struct nsd_options* opt, const char* file, tls_auth_options_find(opt, acl->tls_auth_name))) c_error("tls_auth %s in pattern %s could not be found", acl->tls_auth_name, pat->pname); + else if (!opt->tls_auth_port) + c_warning("provide-xfr has a tls-auth-name," + " but no tls-auth-port is configured"); } if(acl->nokey || acl->blocked) continue; @@ -959,10 +962,11 @@ zone_list_close(struct nsd_options* opt) } static void -c_error_va_list_pos(int showpos, const char* fmt, va_list args) +c_error_va_list_pos(int showpos, int is_error, const char* fmt, va_list args) { char* at = NULL; - cfg_parser->errors++; + if(is_error) + cfg_parser->errors++; if(showpos && c_text && c_text[0]!=0) { at = c_text; } @@ -975,7 +979,8 @@ c_error_va_list_pos(int showpos, const char* fmt, va_list args) snprintf(m, sizeof(m), "at '%s': ", at); (*cfg_parser->err)(cfg_parser->err_arg, m); } - (*cfg_parser->err)(cfg_parser->err_arg, "error: "); + (*cfg_parser->err)(cfg_parser->err_arg, + is_error ? "error: " : "warning: "); vsnprintf(m, sizeof(m), fmt, args); (*cfg_parser->err)(cfg_parser->err_arg, m); (*cfg_parser->err)(cfg_parser->err_arg, "\n"); @@ -983,7 +988,7 @@ c_error_va_list_pos(int showpos, const char* fmt, va_list args) } fprintf(stderr, "%s:%d: ", cfg_parser->filename, cfg_parser->line); if(at) fprintf(stderr, "at '%s': ", at); - fprintf(stderr, "error: "); + fprintf(stderr, is_error ? "error: " : "warning: "); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); } @@ -999,7 +1004,22 @@ c_error(const char *fmt, ...) } va_start(ap, fmt); - c_error_va_list_pos(showpos, fmt, ap); + c_error_va_list_pos(showpos, 1, fmt, ap); + va_end(ap); +} + +void +c_warning(const char *fmt, ...) +{ + va_list ap; + int showpos = 0; + + if (strcmp(fmt, "syntax error") == 0 || strcmp(fmt, "parse error") == 0) { + showpos = 1; + } + + va_start(ap, fmt); + c_error_va_list_pos(showpos, 0, fmt, ap); va_end(ap); } @@ -1993,6 +2013,16 @@ acl_check_incoming(struct acl_options* acl, struct query* q, DEBUG(DEBUG_XFRD,2, (LOG_INFO, "testing acl %s %s", acl->ip_address_spec, acl->nokey?"NOKEY": (acl->blocked?"BLOCKED":acl->key_name))); +#endif +#ifdef HAVE_SSL + if (acl->tls_auth_name && !q->tls_auth) { + /* the acl requires a TLS client cert with name, but + * the connection did not came over a "tls-auth-port:" + */ + number++; + acl = acl->next; + continue; + } #endif if(acl_addr_matches(acl, q) && acl_key_matches(acl, q)) { if(!match) @@ -2008,7 +2038,7 @@ acl_check_incoming(struct acl_options* acl, struct query* q, } #ifdef HAVE_SSL /* we are in a acl with tls_auth */ - if (acl->tls_auth_name && q->tls_auth) { + if (acl->tls_auth_name) { /* we have auth_domain_name in tls_auth */ if (acl->tls_auth_options && acl->tls_auth_options->auth_domain_name) { if (!acl_tls_hostname_matches(q->tls_auth, acl->tls_auth_options->auth_domain_name)) { diff --git a/options.h b/options.h index 5cd1cda5..eda716f2 100644 --- a/options.h +++ b/options.h @@ -641,6 +641,7 @@ const char* config_make_zonefile(struct zone_options* zone, struct nsd* nsd); /* parsing helpers */ void c_error(const char* msg, ...) ATTR_FORMAT(printf, 1,2); +void c_warning(const char* msg, ...) ATTR_FORMAT(printf, 1,2); int c_wrap(void); struct acl_options* parse_acl_info(region_type* region, char* ip, const char* key); diff --git a/rdata.c b/rdata.c index 69695d7e..a3be91a6 100644 --- a/rdata.c +++ b/rdata.c @@ -2560,7 +2560,10 @@ read_apl_rdata(struct domain_table *domains, uint16_t rdlength, return MALFORMED; while (rdlength - length >= 4) { uint8_t afdlength = rdata[length + 3] & APL_LENGTH_MASK; - if (rdlength - (length + 4) < afdlength) + uint16_t afam = read_uint16(rdata + length); + if (rdlength - (length + 4) < afdlength || + (afam == 1 && afdlength > 4) || + (afam == 2 && afdlength > 16)) return MALFORMED; length += 4 + afdlength; } @@ -2600,14 +2603,22 @@ print_apl(struct buffer *output, size_t rdlength, const uint8_t *rdata, af = -1; switch (address_family) { - case 1: af = AF_INET; break; - case 2: af = AF_INET6; break; + case 1: af = AF_INET; + if(length > 4) + return 0; + break; + case 2: af = AF_INET6; + if(length > 16) + return 0; + break; } if (af == -1 || size - 4 < length) return 0; memset(address, 0, sizeof(address)); + if(length > sizeof(address)) + return 0; memmove(address, rdata + *offset + 4, length); if (!inet_ntop(af, address, text_address, sizeof(text_address))) @@ -3282,7 +3293,7 @@ read_svcb_rdata(struct domain_table *domains, uint16_t rdlength, struct domain *domain; struct dname_buffer target; uint16_t length = 2, svcparams_length = 0; - uint16_t size; + size_t size; const size_t mark = buffer_position(packet); /* short + name + svc_params */ diff --git a/server.c b/server.c index ee67c035..eb276cc9 100644 --- a/server.c +++ b/server.c @@ -5409,7 +5409,6 @@ handle_tls_writing(int fd, short event, void* arg) data->shake_state = tls_hs_read_event; tcp_handler_setup_event(data, handle_tls_reading, fd, EV_PERSIST | EV_READ | EV_TIMEOUT); } else if(want != SSL_ERROR_WANT_WRITE) { - cleanup_tcp_handler(data); { char client_ip[128], e[188]; if(data->query) { @@ -5421,6 +5420,7 @@ handle_tls_writing(int fd, short event, void* arg) client_ip, "SSL_write error"); log_crypto_err(e); } + cleanup_tcp_handler(data); } return; }