aboutsummaryrefslogtreecommitdiff
path: root/contrib/unbound/util/net_help.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/unbound/util/net_help.c')
-rw-r--r--contrib/unbound/util/net_help.c92
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;
+}