diff options
Diffstat (limited to 'contrib/unbound/util/net_help.c')
-rw-r--r-- | contrib/unbound/util/net_help.c | 92 |
1 files changed, 79 insertions, 13 deletions
diff --git a/contrib/unbound/util/net_help.c b/contrib/unbound/util/net_help.c index 8970247926d7..5cf702ef9bca 100644 --- a/contrib/unbound/util/net_help.c +++ b/contrib/unbound/util/net_help.c @@ -47,6 +47,7 @@ #ifdef HAVE_NETIOAPI_H #include <netioapi.h> #endif +#include <ctype.h> #include "util/net_help.h" #include "util/log.h" #include "util/data/dname.h" @@ -77,6 +78,8 @@ /** max length of an IP address (the address portion) that we allow */ #define MAX_ADDR_STRLEN 128 /* characters */ +/** max length of a hostname (with port and tls name) that we allow */ +#define MAX_HOST_STRLEN (LDNS_MAX_DOMAINLEN * 3) /* characters */ /** default value for EDNS ADVERTISED size */ uint16_t EDNS_ADVERTISED_SIZE = 4096; @@ -486,28 +489,38 @@ uint8_t* authextstrtodname(char* str, int* port, char** auth_name) *port = UNBOUND_DNS_PORT; *auth_name = NULL; if((s=strchr(str, '@'))) { + char buf[MAX_HOST_STRLEN]; + size_t len = (size_t)(s-str); char* hash = strchr(s+1, '#'); if(hash) { *auth_name = hash+1; } else { *auth_name = NULL; } + if(len >= MAX_HOST_STRLEN) { + return NULL; + } + (void)strlcpy(buf, str, sizeof(buf)); + buf[len] = 0; *port = atoi(s+1); if(*port == 0) { if(!hash && strcmp(s+1,"0")!=0) - return 0; + return NULL; if(hash && strncmp(s+1,"0#",2)!=0) - return 0; + return NULL; } - *s = 0; - dname = sldns_str2wire_dname(str, &dname_len); - *s = '@'; + dname = sldns_str2wire_dname(buf, &dname_len); } else if((s=strchr(str, '#'))) { + char buf[MAX_HOST_STRLEN]; + size_t len = (size_t)(s-str); + if(len >= MAX_HOST_STRLEN) { + return NULL; + } + (void)strlcpy(buf, str, sizeof(buf)); + buf[len] = 0; *port = UNBOUND_DNS_OVER_TLS_PORT; *auth_name = s+1; - *s = 0; - dname = sldns_str2wire_dname(str, &dname_len); - *s = '#'; + dname = sldns_str2wire_dname(buf, &dname_len); } else { dname = sldns_str2wire_dname(str, &dname_len); } @@ -850,6 +863,20 @@ addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen) return (memcmp(s, map_prefix, 12) == 0); } +int addr_is_ip6linklocal(struct sockaddr_storage* addr, socklen_t addrlen) +{ + const uint8_t prefix[2] = {0xfe, 0x80}; + int af = (int)((struct sockaddr_in6*)addr)->sin6_family; + void* sin6addr = &((struct sockaddr_in6*)addr)->sin6_addr; + uint8_t start[2]; + if(af != AF_INET6 || addrlen<(socklen_t)sizeof(struct sockaddr_in6)) + return 0; + /* Put the first 10 bits of sin6addr in start, match fe80::/10. */ + memmove(start, sin6addr, 2); + start[1] &= 0xc0; + return memcmp(start, prefix, 2) == 0; +} + int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen) { int af = (int)((struct sockaddr_in*)addr)->sin_family; @@ -1026,11 +1053,11 @@ static void log_crypto_err_io_code_arg(const char* str, int r, } else { if(print_errno) { if(errno == 0) - log_err("str: syscall error with errno %s", - strerror(errno)); - else log_err("str: %s", strerror(errno)); + log_err("%s: syscall error with errno %s", + str, strerror(errno)); + else log_err("%s: %s", str, strerror(errno)); } else { - log_err("str: %s", inf); + log_err("%s: %s", str, inf); } } } @@ -1194,7 +1221,7 @@ listen_sslctx_setup_2(void* ctxt) if(!SSL_CTX_set_ecdh_auto(ctx,1)) { log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE"); } -#elif defined(USE_ECDSA) +#elif defined(USE_ECDSA) && defined(HAVE_SSL_CTX_SET_TMP_ECDH) if(1) { EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1); if (!ecdh) { @@ -1845,3 +1872,42 @@ sock_close(int socket) closesocket(socket); } # endif /* USE_WINSOCK */ + +ssize_t +hex_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) +{ + static char hexdigits[] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' + }; + size_t i; + + if (targsize < srclength * 2 + 1) { + return -1; + } + + for (i = 0; i < srclength; ++i) { + *target++ = hexdigits[src[i] >> 4U]; + *target++ = hexdigits[src[i] & 0xfU]; + } + *target = '\0'; + return 2 * srclength; +} + +ssize_t +hex_pton(const char* src, uint8_t* target, size_t targsize) +{ + uint8_t *t = target; + if(strlen(src) % 2 != 0 || strlen(src)/2 > targsize) { + return -1; + } + while(*src) { + if(!isxdigit((unsigned char)src[0]) || + !isxdigit((unsigned char)src[1])) + return -1; + *t++ = sldns_hexdigit_to_int(src[0]) * 16 + + sldns_hexdigit_to_int(src[1]) ; + src += 2; + } + return t-target; +} |