1933707f3Ssthen /* 2933707f3Ssthen * util/net_help.c - implementation of the network helper code 3933707f3Ssthen * 4933707f3Ssthen * Copyright (c) 2007, NLnet Labs. All rights reserved. 5933707f3Ssthen * 6933707f3Ssthen * This software is open source. 7933707f3Ssthen * 8933707f3Ssthen * Redistribution and use in source and binary forms, with or without 9933707f3Ssthen * modification, are permitted provided that the following conditions 10933707f3Ssthen * are met: 11933707f3Ssthen * 12933707f3Ssthen * Redistributions of source code must retain the above copyright notice, 13933707f3Ssthen * this list of conditions and the following disclaimer. 14933707f3Ssthen * 15933707f3Ssthen * Redistributions in binary form must reproduce the above copyright notice, 16933707f3Ssthen * this list of conditions and the following disclaimer in the documentation 17933707f3Ssthen * and/or other materials provided with the distribution. 18933707f3Ssthen * 19933707f3Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may 20933707f3Ssthen * be used to endorse or promote products derived from this software without 21933707f3Ssthen * specific prior written permission. 22933707f3Ssthen * 23933707f3Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 245d76a658Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 255d76a658Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 265d76a658Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 275d76a658Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 285d76a658Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 295d76a658Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 305d76a658Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 315d76a658Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 325d76a658Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 335d76a658Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34933707f3Ssthen */ 35933707f3Ssthen /** 36933707f3Ssthen * \file 37933707f3Ssthen * Implementation of net_help.h. 38933707f3Ssthen */ 39933707f3Ssthen 40933707f3Ssthen #include "config.h" 416eb11800Sflorian #ifdef HAVE_SYS_TYPES_H 426eb11800Sflorian # include <sys/types.h> 436eb11800Sflorian #endif 446eb11800Sflorian #ifdef HAVE_NET_IF_H 456eb11800Sflorian #include <net/if.h> 466eb11800Sflorian #endif 47e21c60efSsthen #ifdef HAVE_NETIOAPI_H 48e21c60efSsthen #include <netioapi.h> 49e21c60efSsthen #endif 50*98bc733bSsthen #include <ctype.h> 51933707f3Ssthen #include "util/net_help.h" 52933707f3Ssthen #include "util/log.h" 53933707f3Ssthen #include "util/data/dname.h" 54933707f3Ssthen #include "util/module.h" 55933707f3Ssthen #include "util/regional.h" 56f6b99bafSsthen #include "util/config_file.h" 57a58bff56Ssthen #include "sldns/parseutil.h" 58a58bff56Ssthen #include "sldns/wire2str.h" 59e21c60efSsthen #include "sldns/str2wire.h" 60933707f3Ssthen #include <fcntl.h> 613dcb24b8Ssthen #ifdef HAVE_OPENSSL_SSL_H 62933707f3Ssthen #include <openssl/ssl.h> 63f6b99bafSsthen #include <openssl/evp.h> 64f6b99bafSsthen #include <openssl/rand.h> 653dcb24b8Ssthen #endif 663dcb24b8Ssthen #ifdef HAVE_OPENSSL_ERR_H 67933707f3Ssthen #include <openssl/err.h> 683dcb24b8Ssthen #endif 69a3167c07Ssthen #ifdef HAVE_OPENSSL_CORE_NAMES_H 70a3167c07Ssthen #include <openssl/core_names.h> 71a3167c07Ssthen #endif 7220237c55Ssthen #ifdef USE_WINSOCK 7320237c55Ssthen #include <wincrypt.h> 7420237c55Ssthen #endif 752c144df0Ssthen #ifdef HAVE_NGHTTP2_NGHTTP2_H 762c144df0Ssthen #include <nghttp2/nghttp2.h> 772c144df0Ssthen #endif 78933707f3Ssthen 79933707f3Ssthen /** max length of an IP address (the address portion) that we allow */ 80933707f3Ssthen #define MAX_ADDR_STRLEN 128 /* characters */ 812bdc0ed1Ssthen /** max length of a hostname (with port and tls name) that we allow */ 822bdc0ed1Ssthen #define MAX_HOST_STRLEN (LDNS_MAX_DOMAINLEN * 3) /* characters */ 83933707f3Ssthen /** default value for EDNS ADVERTISED size */ 84933707f3Ssthen uint16_t EDNS_ADVERTISED_SIZE = 4096; 85933707f3Ssthen 86d8d14d0cSsthen /** minimal responses when positive answer: default is no */ 87d8d14d0cSsthen int MINIMAL_RESPONSES = 0; 88d8d14d0cSsthen 89a3167c07Ssthen /** rrset order roundrobin: default is yes */ 90a3167c07Ssthen int RRSET_ROUNDROBIN = 1; 91d8d14d0cSsthen 92f6b99bafSsthen /** log tag queries with name instead of 'info' for filtering */ 93f6b99bafSsthen int LOG_TAG_QUERYREPLY = 0; 94f6b99bafSsthen 95f6b99bafSsthen static struct tls_session_ticket_key { 96f6b99bafSsthen unsigned char *key_name; 97f6b99bafSsthen unsigned char *aes_key; 98f6b99bafSsthen unsigned char *hmac_key; 99f6b99bafSsthen } *ticket_keys; 100f6b99bafSsthen 1012c144df0Ssthen #ifdef HAVE_SSL 102a3167c07Ssthen /** 103a3167c07Ssthen * callback TLS session ticket encrypt and decrypt 104a3167c07Ssthen * For use with SSL_CTX_set_tlsext_ticket_key_cb or 105a3167c07Ssthen * SSL_CTX_set_tlsext_ticket_key_evp_cb 106a3167c07Ssthen * @param s: the SSL_CTX to use (from connect_sslctx_create()) 107a3167c07Ssthen * @param key_name: secret name, 16 bytes 108a3167c07Ssthen * @param iv: up to EVP_MAX_IV_LENGTH. 109a3167c07Ssthen * @param evp_ctx: the evp cipher context, function sets this. 110a3167c07Ssthen * @param hmac_ctx: the hmac context, function sets this. 111a3167c07Ssthen * with ..key_cb it is of type HMAC_CTX* 112a3167c07Ssthen * with ..key_evp_cb it is of type EVP_MAC_CTX* 113a3167c07Ssthen * @param enc: 1 is encrypt, 0 is decrypt 114a3167c07Ssthen * @return 0 on no ticket, 1 for okay, and 2 for okay but renew the ticket 115a3167c07Ssthen * (the ticket is decrypt only). and <0 for failures. 116a3167c07Ssthen */ 117a3167c07Ssthen int tls_session_ticket_key_cb(SSL *s, unsigned char* key_name, 118a3167c07Ssthen unsigned char* iv, EVP_CIPHER_CTX *evp_ctx, 119a3167c07Ssthen #ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB 120a3167c07Ssthen EVP_MAC_CTX *hmac_ctx, 121a3167c07Ssthen #else 122a3167c07Ssthen HMAC_CTX* hmac_ctx, 123a3167c07Ssthen #endif 124a3167c07Ssthen int enc); 125a3167c07Ssthen #endif /* HAVE_SSL */ 126a3167c07Ssthen 127933707f3Ssthen /* returns true is string addr is an ip6 specced address */ 128933707f3Ssthen int 129933707f3Ssthen str_is_ip6(const char* str) 130933707f3Ssthen { 131933707f3Ssthen if(strchr(str, ':')) 132933707f3Ssthen return 1; 133933707f3Ssthen else return 0; 134933707f3Ssthen } 135933707f3Ssthen 136933707f3Ssthen int 137933707f3Ssthen fd_set_nonblock(int s) 138933707f3Ssthen { 139933707f3Ssthen #ifdef HAVE_FCNTL 140933707f3Ssthen int flag; 141933707f3Ssthen if((flag = fcntl(s, F_GETFL)) == -1) { 142933707f3Ssthen log_err("can't fcntl F_GETFL: %s", strerror(errno)); 143933707f3Ssthen flag = 0; 144933707f3Ssthen } 145933707f3Ssthen flag |= O_NONBLOCK; 146933707f3Ssthen if(fcntl(s, F_SETFL, flag) == -1) { 147933707f3Ssthen log_err("can't fcntl F_SETFL: %s", strerror(errno)); 148933707f3Ssthen return 0; 149933707f3Ssthen } 150933707f3Ssthen #elif defined(HAVE_IOCTLSOCKET) 151933707f3Ssthen unsigned long on = 1; 152933707f3Ssthen if(ioctlsocket(s, FIONBIO, &on) != 0) { 153933707f3Ssthen log_err("can't ioctlsocket FIONBIO on: %s", 154933707f3Ssthen wsa_strerror(WSAGetLastError())); 155933707f3Ssthen } 156933707f3Ssthen #endif 157933707f3Ssthen return 1; 158933707f3Ssthen } 159933707f3Ssthen 160933707f3Ssthen int 161933707f3Ssthen fd_set_block(int s) 162933707f3Ssthen { 163933707f3Ssthen #ifdef HAVE_FCNTL 164933707f3Ssthen int flag; 165933707f3Ssthen if((flag = fcntl(s, F_GETFL)) == -1) { 166933707f3Ssthen log_err("cannot fcntl F_GETFL: %s", strerror(errno)); 167933707f3Ssthen flag = 0; 168933707f3Ssthen } 169933707f3Ssthen flag &= ~O_NONBLOCK; 170933707f3Ssthen if(fcntl(s, F_SETFL, flag) == -1) { 171933707f3Ssthen log_err("cannot fcntl F_SETFL: %s", strerror(errno)); 172933707f3Ssthen return 0; 173933707f3Ssthen } 174933707f3Ssthen #elif defined(HAVE_IOCTLSOCKET) 175933707f3Ssthen unsigned long off = 0; 176933707f3Ssthen if(ioctlsocket(s, FIONBIO, &off) != 0) { 1777191de28Ssthen if(WSAGetLastError() != WSAEINVAL || verbosity >= 4) 178933707f3Ssthen log_err("can't ioctlsocket FIONBIO off: %s", 179933707f3Ssthen wsa_strerror(WSAGetLastError())); 180933707f3Ssthen } 181933707f3Ssthen #endif 182933707f3Ssthen return 1; 183933707f3Ssthen } 184933707f3Ssthen 185933707f3Ssthen int 186933707f3Ssthen is_pow2(size_t num) 187933707f3Ssthen { 188933707f3Ssthen if(num == 0) return 1; 189933707f3Ssthen return (num & (num-1)) == 0; 190933707f3Ssthen } 191933707f3Ssthen 192933707f3Ssthen void* 193933707f3Ssthen memdup(void* data, size_t len) 194933707f3Ssthen { 195933707f3Ssthen void* d; 196933707f3Ssthen if(!data) return NULL; 197933707f3Ssthen if(len == 0) return NULL; 198933707f3Ssthen d = malloc(len); 199933707f3Ssthen if(!d) return NULL; 200933707f3Ssthen memcpy(d, data, len); 201933707f3Ssthen return d; 202933707f3Ssthen } 203933707f3Ssthen 204933707f3Ssthen void 205933707f3Ssthen log_addr(enum verbosity_value v, const char* str, 206933707f3Ssthen struct sockaddr_storage* addr, socklen_t addrlen) 207933707f3Ssthen { 208933707f3Ssthen uint16_t port; 209933707f3Ssthen const char* family = "unknown"; 210933707f3Ssthen char dest[100]; 211933707f3Ssthen int af = (int)((struct sockaddr_in*)addr)->sin_family; 212933707f3Ssthen void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 213933707f3Ssthen if(verbosity < v) 214933707f3Ssthen return; 215933707f3Ssthen switch(af) { 216933707f3Ssthen case AF_INET: family="ip4"; break; 217933707f3Ssthen case AF_INET6: family="ip6"; 218933707f3Ssthen sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; 219933707f3Ssthen break; 22031f127bbSsthen case AF_LOCAL: 22131f127bbSsthen dest[0]=0; 22231f127bbSsthen (void)inet_ntop(af, sinaddr, dest, 22331f127bbSsthen (socklen_t)sizeof(dest)); 22431f127bbSsthen verbose(v, "%s local %s", str, dest); 22531f127bbSsthen return; /* do not continue and try to get port */ 226933707f3Ssthen default: break; 227933707f3Ssthen } 228933707f3Ssthen if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) { 2295d76a658Ssthen (void)strlcpy(dest, "(inet_ntop error)", sizeof(dest)); 230933707f3Ssthen } 231933707f3Ssthen dest[sizeof(dest)-1] = 0; 232933707f3Ssthen port = ntohs(((struct sockaddr_in*)addr)->sin_port); 233933707f3Ssthen if(verbosity >= 4) 234933707f3Ssthen verbose(v, "%s %s %s port %d (len %d)", str, family, dest, 235933707f3Ssthen (int)port, (int)addrlen); 236933707f3Ssthen else verbose(v, "%s %s port %d", str, dest, (int)port); 237933707f3Ssthen } 238933707f3Ssthen 239933707f3Ssthen int 240933707f3Ssthen extstrtoaddr(const char* str, struct sockaddr_storage* addr, 24145872187Ssthen socklen_t* addrlen, int port) 242933707f3Ssthen { 243933707f3Ssthen char* s; 244933707f3Ssthen if((s=strchr(str, '@'))) { 245933707f3Ssthen char buf[MAX_ADDR_STRLEN]; 246933707f3Ssthen if(s-str >= MAX_ADDR_STRLEN) { 247933707f3Ssthen return 0; 248933707f3Ssthen } 2495d76a658Ssthen (void)strlcpy(buf, str, sizeof(buf)); 250933707f3Ssthen buf[s-str] = 0; 251933707f3Ssthen port = atoi(s+1); 252933707f3Ssthen if(port == 0 && strcmp(s+1,"0")!=0) { 253933707f3Ssthen return 0; 254933707f3Ssthen } 255933707f3Ssthen return ipstrtoaddr(buf, port, addr, addrlen); 256933707f3Ssthen } 257933707f3Ssthen return ipstrtoaddr(str, port, addr, addrlen); 258933707f3Ssthen } 259933707f3Ssthen 260933707f3Ssthen int 261933707f3Ssthen ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr, 262933707f3Ssthen socklen_t* addrlen) 263933707f3Ssthen { 264933707f3Ssthen uint16_t p; 265933707f3Ssthen if(!ip) return 0; 266933707f3Ssthen p = (uint16_t) port; 267933707f3Ssthen if(str_is_ip6(ip)) { 268933707f3Ssthen char buf[MAX_ADDR_STRLEN]; 269933707f3Ssthen char* s; 270933707f3Ssthen struct sockaddr_in6* sa = (struct sockaddr_in6*)addr; 271933707f3Ssthen *addrlen = (socklen_t)sizeof(struct sockaddr_in6); 272933707f3Ssthen memset(sa, 0, *addrlen); 273933707f3Ssthen sa->sin6_family = AF_INET6; 274933707f3Ssthen sa->sin6_port = (in_port_t)htons(p); 275933707f3Ssthen if((s=strchr(ip, '%'))) { /* ip6%interface, rfc 4007 */ 276933707f3Ssthen if(s-ip >= MAX_ADDR_STRLEN) 277933707f3Ssthen return 0; 2785d76a658Ssthen (void)strlcpy(buf, ip, sizeof(buf)); 279933707f3Ssthen buf[s-ip]=0; 2806eb11800Sflorian #ifdef HAVE_IF_NAMETOINDEX 2816eb11800Sflorian if (!(sa->sin6_scope_id = if_nametoindex(s+1))) 2826eb11800Sflorian #endif /* HAVE_IF_NAMETOINDEX */ 283933707f3Ssthen sa->sin6_scope_id = (uint32_t)atoi(s+1); 284933707f3Ssthen ip = buf; 285933707f3Ssthen } 286933707f3Ssthen if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) { 287933707f3Ssthen return 0; 288933707f3Ssthen } 289933707f3Ssthen } else { /* ip4 */ 290933707f3Ssthen struct sockaddr_in* sa = (struct sockaddr_in*)addr; 291933707f3Ssthen *addrlen = (socklen_t)sizeof(struct sockaddr_in); 292933707f3Ssthen memset(sa, 0, *addrlen); 293933707f3Ssthen sa->sin_family = AF_INET; 294933707f3Ssthen sa->sin_port = (in_port_t)htons(p); 295933707f3Ssthen if(inet_pton((int)sa->sin_family, ip, &sa->sin_addr) <= 0) { 296933707f3Ssthen return 0; 297933707f3Ssthen } 298933707f3Ssthen } 299933707f3Ssthen return 1; 300933707f3Ssthen } 301933707f3Ssthen 302933707f3Ssthen int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr, 303933707f3Ssthen socklen_t* addrlen, int* net) 304933707f3Ssthen { 30520237c55Ssthen char buf[64]; 30620237c55Ssthen char* s; 307933707f3Ssthen *net = (str_is_ip6(str)?128:32); 308933707f3Ssthen if((s=strchr(str, '/'))) { 309933707f3Ssthen if(atoi(s+1) > *net) { 310933707f3Ssthen log_err("netblock too large: %s", str); 311933707f3Ssthen return 0; 312933707f3Ssthen } 313933707f3Ssthen *net = atoi(s+1); 314933707f3Ssthen if(*net == 0 && strcmp(s+1, "0") != 0) { 315933707f3Ssthen log_err("cannot parse netblock: '%s'", str); 316933707f3Ssthen return 0; 317933707f3Ssthen } 31820237c55Ssthen strlcpy(buf, str, sizeof(buf)); 31920237c55Ssthen s = strchr(buf, '/'); 32020237c55Ssthen if(s) *s = 0; 32120237c55Ssthen s = buf; 322933707f3Ssthen } 323933707f3Ssthen if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) { 324933707f3Ssthen log_err("cannot parse ip address: '%s'", str); 325933707f3Ssthen return 0; 326933707f3Ssthen } 327933707f3Ssthen if(s) { 328933707f3Ssthen addr_mask(addr, *addrlen, *net); 329933707f3Ssthen } 330933707f3Ssthen return 1; 331933707f3Ssthen } 332933707f3Ssthen 333eaf2578eSsthen /* RPZ format address dname to network byte order address */ 334eaf2578eSsthen static int ipdnametoaddr(uint8_t* dname, size_t dnamelen, 335eaf2578eSsthen struct sockaddr_storage* addr, socklen_t* addrlen, int* af) 336eaf2578eSsthen { 337eaf2578eSsthen uint8_t* ia; 3389982a05dSsthen int dnamelabs = dname_count_labels(dname); 339eaf2578eSsthen uint8_t lablen; 340eaf2578eSsthen char* e = NULL; 341eaf2578eSsthen int z = 0; 342eaf2578eSsthen size_t len = 0; 343eaf2578eSsthen int i; 344eaf2578eSsthen *af = AF_INET; 345eaf2578eSsthen 346eaf2578eSsthen /* need 1 byte for label length */ 347eaf2578eSsthen if(dnamelen < 1) 348eaf2578eSsthen return 0; 349eaf2578eSsthen 350eaf2578eSsthen if(dnamelabs > 6 || 351eaf2578eSsthen dname_has_label(dname, dnamelen, (uint8_t*)"\002zz")) { 352eaf2578eSsthen *af = AF_INET6; 353eaf2578eSsthen } 354eaf2578eSsthen len = *dname; 355eaf2578eSsthen lablen = *dname++; 356eaf2578eSsthen i = (*af == AF_INET) ? 3 : 15; 357eaf2578eSsthen if(*af == AF_INET6) { 358eaf2578eSsthen struct sockaddr_in6* sa = (struct sockaddr_in6*)addr; 359eaf2578eSsthen *addrlen = (socklen_t)sizeof(struct sockaddr_in6); 360eaf2578eSsthen memset(sa, 0, *addrlen); 361eaf2578eSsthen sa->sin6_family = AF_INET6; 362eaf2578eSsthen ia = (uint8_t*)&sa->sin6_addr; 363eaf2578eSsthen } else { /* ip4 */ 364eaf2578eSsthen struct sockaddr_in* sa = (struct sockaddr_in*)addr; 365eaf2578eSsthen *addrlen = (socklen_t)sizeof(struct sockaddr_in); 366eaf2578eSsthen memset(sa, 0, *addrlen); 367eaf2578eSsthen sa->sin_family = AF_INET; 368eaf2578eSsthen ia = (uint8_t*)&sa->sin_addr; 369eaf2578eSsthen } 370eaf2578eSsthen while(lablen && i >= 0 && len <= dnamelen) { 371eaf2578eSsthen char buff[LDNS_MAX_LABELLEN+1]; 372eaf2578eSsthen uint16_t chunk; /* big enough to not overflow on IPv6 hextet */ 373eaf2578eSsthen if((*af == AF_INET && (lablen > 3 || dnamelabs > 6)) || 374eaf2578eSsthen (*af == AF_INET6 && (lablen > 4 || dnamelabs > 10))) { 375eaf2578eSsthen return 0; 376eaf2578eSsthen } 377eaf2578eSsthen if(memcmp(dname, "zz", 2) == 0 && *af == AF_INET6) { 378eaf2578eSsthen /* Add one or more 0 labels. Address is initialised at 379eaf2578eSsthen * 0, so just skip the zero part. */ 380eaf2578eSsthen int zl = 11 - dnamelabs; 381eaf2578eSsthen if(z || zl < 0) 382eaf2578eSsthen return 0; 383eaf2578eSsthen z = 1; 384eaf2578eSsthen i -= (zl*2); 385eaf2578eSsthen } else { 386eaf2578eSsthen memcpy(buff, dname, lablen); 387eaf2578eSsthen buff[lablen] = '\0'; 388eaf2578eSsthen chunk = strtol(buff, &e, (*af == AF_INET) ? 10 : 16); 389eaf2578eSsthen if(!e || *e != '\0' || (*af == AF_INET && chunk > 255)) 390eaf2578eSsthen return 0; 391eaf2578eSsthen if(*af == AF_INET) { 392eaf2578eSsthen log_assert(i < 4 && i >= 0); 393eaf2578eSsthen ia[i] = (uint8_t)chunk; 394eaf2578eSsthen i--; 395eaf2578eSsthen } else { 396eaf2578eSsthen log_assert(i < 16 && i >= 1); 397eaf2578eSsthen /* ia in network byte order */ 398eaf2578eSsthen ia[i-1] = (uint8_t)(chunk >> 8); 399eaf2578eSsthen ia[i] = (uint8_t)(chunk & 0x00FF); 400eaf2578eSsthen i -= 2; 401eaf2578eSsthen } 402eaf2578eSsthen } 403eaf2578eSsthen dname += lablen; 404eaf2578eSsthen lablen = *dname++; 405eaf2578eSsthen len += lablen; 406eaf2578eSsthen } 407eaf2578eSsthen if(i != -1) 408eaf2578eSsthen /* input too short */ 409eaf2578eSsthen return 0; 410eaf2578eSsthen return 1; 411eaf2578eSsthen } 412eaf2578eSsthen 413eaf2578eSsthen int netblockdnametoaddr(uint8_t* dname, size_t dnamelen, 414eaf2578eSsthen struct sockaddr_storage* addr, socklen_t* addrlen, int* net, int* af) 415eaf2578eSsthen { 416eaf2578eSsthen char buff[3 /* 3 digit netblock */ + 1]; 417eaf2578eSsthen size_t nlablen; 418eaf2578eSsthen if(dnamelen < 1 || *dname > 3) 419eaf2578eSsthen /* netblock invalid */ 420eaf2578eSsthen return 0; 421eaf2578eSsthen nlablen = *dname; 422eaf2578eSsthen 423eaf2578eSsthen if(dnamelen < 1 + nlablen) 424eaf2578eSsthen return 0; 425eaf2578eSsthen 426eaf2578eSsthen memcpy(buff, dname+1, nlablen); 427eaf2578eSsthen buff[nlablen] = '\0'; 428eaf2578eSsthen *net = atoi(buff); 429eaf2578eSsthen if(*net == 0 && strcmp(buff, "0") != 0) 430eaf2578eSsthen return 0; 431eaf2578eSsthen dname += nlablen; 432eaf2578eSsthen dname++; 433eaf2578eSsthen if(!ipdnametoaddr(dname, dnamelen-1-nlablen, addr, addrlen, af)) 434eaf2578eSsthen return 0; 435eaf2578eSsthen if((*af == AF_INET6 && *net > 128) || (*af == AF_INET && *net > 32)) 436eaf2578eSsthen return 0; 437eaf2578eSsthen return 1; 438eaf2578eSsthen } 439eaf2578eSsthen 44020237c55Ssthen int authextstrtoaddr(char* str, struct sockaddr_storage* addr, 44120237c55Ssthen socklen_t* addrlen, char** auth_name) 44220237c55Ssthen { 44320237c55Ssthen char* s; 44420237c55Ssthen int port = UNBOUND_DNS_PORT; 44520237c55Ssthen if((s=strchr(str, '@'))) { 44620237c55Ssthen char buf[MAX_ADDR_STRLEN]; 44720237c55Ssthen size_t len = (size_t)(s-str); 44820237c55Ssthen char* hash = strchr(s+1, '#'); 44920237c55Ssthen if(hash) { 45020237c55Ssthen *auth_name = hash+1; 45120237c55Ssthen } else { 45220237c55Ssthen *auth_name = NULL; 45320237c55Ssthen } 45420237c55Ssthen if(len >= MAX_ADDR_STRLEN) { 45520237c55Ssthen return 0; 45620237c55Ssthen } 45720237c55Ssthen (void)strlcpy(buf, str, sizeof(buf)); 45820237c55Ssthen buf[len] = 0; 45920237c55Ssthen port = atoi(s+1); 46020237c55Ssthen if(port == 0) { 46120237c55Ssthen if(!hash && strcmp(s+1,"0")!=0) 46220237c55Ssthen return 0; 46320237c55Ssthen if(hash && strncmp(s+1,"0#",2)!=0) 46420237c55Ssthen return 0; 46520237c55Ssthen } 46620237c55Ssthen return ipstrtoaddr(buf, port, addr, addrlen); 46720237c55Ssthen } 46820237c55Ssthen if((s=strchr(str, '#'))) { 46920237c55Ssthen char buf[MAX_ADDR_STRLEN]; 47020237c55Ssthen size_t len = (size_t)(s-str); 47120237c55Ssthen if(len >= MAX_ADDR_STRLEN) { 47220237c55Ssthen return 0; 47320237c55Ssthen } 47420237c55Ssthen (void)strlcpy(buf, str, sizeof(buf)); 47520237c55Ssthen buf[len] = 0; 47620237c55Ssthen port = UNBOUND_DNS_OVER_TLS_PORT; 47720237c55Ssthen *auth_name = s+1; 47820237c55Ssthen return ipstrtoaddr(buf, port, addr, addrlen); 47920237c55Ssthen } 48020237c55Ssthen *auth_name = NULL; 48120237c55Ssthen return ipstrtoaddr(str, port, addr, addrlen); 48220237c55Ssthen } 48320237c55Ssthen 484e21c60efSsthen uint8_t* authextstrtodname(char* str, int* port, char** auth_name) 485e21c60efSsthen { 486e21c60efSsthen char* s; 487e21c60efSsthen uint8_t* dname; 488e21c60efSsthen size_t dname_len; 489e21c60efSsthen *port = UNBOUND_DNS_PORT; 490e21c60efSsthen *auth_name = NULL; 491e21c60efSsthen if((s=strchr(str, '@'))) { 4922bdc0ed1Ssthen char buf[MAX_HOST_STRLEN]; 4932bdc0ed1Ssthen size_t len = (size_t)(s-str); 494e21c60efSsthen char* hash = strchr(s+1, '#'); 495e21c60efSsthen if(hash) { 496e21c60efSsthen *auth_name = hash+1; 497e21c60efSsthen } else { 498e21c60efSsthen *auth_name = NULL; 499e21c60efSsthen } 5002bdc0ed1Ssthen if(len >= MAX_HOST_STRLEN) { 5012bdc0ed1Ssthen return NULL; 5022bdc0ed1Ssthen } 5032bdc0ed1Ssthen (void)strlcpy(buf, str, sizeof(buf)); 5042bdc0ed1Ssthen buf[len] = 0; 505e21c60efSsthen *port = atoi(s+1); 506e21c60efSsthen if(*port == 0) { 507e21c60efSsthen if(!hash && strcmp(s+1,"0")!=0) 5082bdc0ed1Ssthen return NULL; 509e21c60efSsthen if(hash && strncmp(s+1,"0#",2)!=0) 5102bdc0ed1Ssthen return NULL; 511e21c60efSsthen } 5122bdc0ed1Ssthen dname = sldns_str2wire_dname(buf, &dname_len); 513e21c60efSsthen } else if((s=strchr(str, '#'))) { 5142bdc0ed1Ssthen char buf[MAX_HOST_STRLEN]; 5152bdc0ed1Ssthen size_t len = (size_t)(s-str); 5162bdc0ed1Ssthen if(len >= MAX_HOST_STRLEN) { 5172bdc0ed1Ssthen return NULL; 5182bdc0ed1Ssthen } 5192bdc0ed1Ssthen (void)strlcpy(buf, str, sizeof(buf)); 5202bdc0ed1Ssthen buf[len] = 0; 521e21c60efSsthen *port = UNBOUND_DNS_OVER_TLS_PORT; 522e21c60efSsthen *auth_name = s+1; 5232bdc0ed1Ssthen dname = sldns_str2wire_dname(buf, &dname_len); 524e21c60efSsthen } else { 525e21c60efSsthen dname = sldns_str2wire_dname(str, &dname_len); 526e21c60efSsthen } 527e21c60efSsthen return dname; 528e21c60efSsthen } 529e21c60efSsthen 530938a3a5eSflorian /** store port number into sockaddr structure */ 531938a3a5eSflorian void 532938a3a5eSflorian sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen, int port) 533938a3a5eSflorian { 534938a3a5eSflorian if(addr_is_ip6(addr, addrlen)) { 535938a3a5eSflorian struct sockaddr_in6* sa = (struct sockaddr_in6*)addr; 536938a3a5eSflorian sa->sin6_port = (in_port_t)htons((uint16_t)port); 537938a3a5eSflorian } else { 538938a3a5eSflorian struct sockaddr_in* sa = (struct sockaddr_in*)addr; 539938a3a5eSflorian sa->sin_port = (in_port_t)htons((uint16_t)port); 540938a3a5eSflorian } 541938a3a5eSflorian } 542938a3a5eSflorian 543933707f3Ssthen void 544933707f3Ssthen log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, 545933707f3Ssthen uint16_t type, uint16_t dclass) 546933707f3Ssthen { 547933707f3Ssthen char buf[LDNS_MAX_DOMAINLEN+1]; 548933707f3Ssthen char t[12], c[12]; 549933707f3Ssthen const char *ts, *cs; 550933707f3Ssthen if(verbosity < v) 551933707f3Ssthen return; 552933707f3Ssthen dname_str(name, buf); 553933707f3Ssthen if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG"; 554933707f3Ssthen else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR"; 555933707f3Ssthen else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR"; 556933707f3Ssthen else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB"; 557933707f3Ssthen else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA"; 558933707f3Ssthen else if(type == LDNS_RR_TYPE_ANY) ts = "ANY"; 5595d76a658Ssthen else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name) 5605d76a658Ssthen ts = sldns_rr_descript(type)->_name; 561933707f3Ssthen else { 562933707f3Ssthen snprintf(t, sizeof(t), "TYPE%d", (int)type); 563933707f3Ssthen ts = t; 564933707f3Ssthen } 5655d76a658Ssthen if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) && 5665d76a658Ssthen sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name) 5675d76a658Ssthen cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name; 568933707f3Ssthen else { 569933707f3Ssthen snprintf(c, sizeof(c), "CLASS%d", (int)dclass); 570933707f3Ssthen cs = c; 571933707f3Ssthen } 572933707f3Ssthen log_info("%s %s %s %s", str, buf, ts, cs); 573933707f3Ssthen } 574933707f3Ssthen 575f6b99bafSsthen void 576f6b99bafSsthen log_query_in(const char* str, uint8_t* name, uint16_t type, uint16_t dclass) 577f6b99bafSsthen { 578f6b99bafSsthen char buf[LDNS_MAX_DOMAINLEN+1]; 579f6b99bafSsthen char t[12], c[12]; 580f6b99bafSsthen const char *ts, *cs; 581f6b99bafSsthen dname_str(name, buf); 582f6b99bafSsthen if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG"; 583f6b99bafSsthen else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR"; 584f6b99bafSsthen else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR"; 585f6b99bafSsthen else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB"; 586f6b99bafSsthen else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA"; 587f6b99bafSsthen else if(type == LDNS_RR_TYPE_ANY) ts = "ANY"; 588f6b99bafSsthen else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name) 589f6b99bafSsthen ts = sldns_rr_descript(type)->_name; 590f6b99bafSsthen else { 591f6b99bafSsthen snprintf(t, sizeof(t), "TYPE%d", (int)type); 592f6b99bafSsthen ts = t; 593f6b99bafSsthen } 594f6b99bafSsthen if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) && 595f6b99bafSsthen sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name) 596f6b99bafSsthen cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name; 597f6b99bafSsthen else { 598f6b99bafSsthen snprintf(c, sizeof(c), "CLASS%d", (int)dclass); 599f6b99bafSsthen cs = c; 600f6b99bafSsthen } 601f6b99bafSsthen if(LOG_TAG_QUERYREPLY) 602f6b99bafSsthen log_query("%s %s %s %s", str, buf, ts, cs); 603f6b99bafSsthen else log_info("%s %s %s %s", str, buf, ts, cs); 604f6b99bafSsthen } 605f6b99bafSsthen 606933707f3Ssthen void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, 607933707f3Ssthen struct sockaddr_storage* addr, socklen_t addrlen) 608933707f3Ssthen { 609933707f3Ssthen uint16_t port; 610933707f3Ssthen const char* family = "unknown_family "; 611933707f3Ssthen char namebuf[LDNS_MAX_DOMAINLEN+1]; 612933707f3Ssthen char dest[100]; 613933707f3Ssthen int af = (int)((struct sockaddr_in*)addr)->sin_family; 614933707f3Ssthen void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 615933707f3Ssthen if(verbosity < v) 616933707f3Ssthen return; 617933707f3Ssthen switch(af) { 618933707f3Ssthen case AF_INET: family=""; break; 619933707f3Ssthen case AF_INET6: family=""; 620933707f3Ssthen sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; 621933707f3Ssthen break; 62231f127bbSsthen case AF_LOCAL: family="local "; break; 623933707f3Ssthen default: break; 624933707f3Ssthen } 625933707f3Ssthen if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) { 6265d76a658Ssthen (void)strlcpy(dest, "(inet_ntop error)", sizeof(dest)); 627933707f3Ssthen } 628933707f3Ssthen dest[sizeof(dest)-1] = 0; 629933707f3Ssthen port = ntohs(((struct sockaddr_in*)addr)->sin_port); 630933707f3Ssthen dname_str(zone, namebuf); 631933707f3Ssthen if(af != AF_INET && af != AF_INET6) 632933707f3Ssthen verbose(v, "%s <%s> %s%s#%d (addrlen %d)", 633933707f3Ssthen str, namebuf, family, dest, (int)port, (int)addrlen); 634933707f3Ssthen else verbose(v, "%s <%s> %s%s#%d", 635933707f3Ssthen str, namebuf, family, dest, (int)port); 636933707f3Ssthen } 637933707f3Ssthen 63898f3ca02Sbrad void log_err_addr(const char* str, const char* err, 63998f3ca02Sbrad struct sockaddr_storage* addr, socklen_t addrlen) 64098f3ca02Sbrad { 64198f3ca02Sbrad uint16_t port; 64298f3ca02Sbrad char dest[100]; 64398f3ca02Sbrad int af = (int)((struct sockaddr_in*)addr)->sin_family; 64498f3ca02Sbrad void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 64598f3ca02Sbrad if(af == AF_INET6) 64698f3ca02Sbrad sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; 64798f3ca02Sbrad if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) { 64898f3ca02Sbrad (void)strlcpy(dest, "(inet_ntop error)", sizeof(dest)); 64998f3ca02Sbrad } 65098f3ca02Sbrad dest[sizeof(dest)-1] = 0; 65198f3ca02Sbrad port = ntohs(((struct sockaddr_in*)addr)->sin_port); 65298f3ca02Sbrad if(verbosity >= 4) 65398f3ca02Sbrad log_err("%s: %s for %s port %d (len %d)", str, err, dest, 65498f3ca02Sbrad (int)port, (int)addrlen); 6552308e98cSsthen else log_err("%s: %s for %s port %d", str, err, dest, (int)port); 65698f3ca02Sbrad } 65798f3ca02Sbrad 658933707f3Ssthen int 659933707f3Ssthen sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1, 660933707f3Ssthen struct sockaddr_storage* addr2, socklen_t len2) 661933707f3Ssthen { 662933707f3Ssthen struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1; 663933707f3Ssthen struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2; 664933707f3Ssthen struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1; 665933707f3Ssthen struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2; 666933707f3Ssthen if(len1 < len2) 667933707f3Ssthen return -1; 668933707f3Ssthen if(len1 > len2) 669933707f3Ssthen return 1; 670933707f3Ssthen log_assert(len1 == len2); 671933707f3Ssthen if( p1_in->sin_family < p2_in->sin_family) 672933707f3Ssthen return -1; 673933707f3Ssthen if( p1_in->sin_family > p2_in->sin_family) 674933707f3Ssthen return 1; 675933707f3Ssthen log_assert( p1_in->sin_family == p2_in->sin_family ); 676933707f3Ssthen /* compare ip4 */ 677933707f3Ssthen if( p1_in->sin_family == AF_INET ) { 678933707f3Ssthen /* just order it, ntohs not required */ 679933707f3Ssthen if(p1_in->sin_port < p2_in->sin_port) 680933707f3Ssthen return -1; 681933707f3Ssthen if(p1_in->sin_port > p2_in->sin_port) 682933707f3Ssthen return 1; 683933707f3Ssthen log_assert(p1_in->sin_port == p2_in->sin_port); 684933707f3Ssthen return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); 685933707f3Ssthen } else if (p1_in6->sin6_family == AF_INET6) { 686933707f3Ssthen /* just order it, ntohs not required */ 687933707f3Ssthen if(p1_in6->sin6_port < p2_in6->sin6_port) 688933707f3Ssthen return -1; 689933707f3Ssthen if(p1_in6->sin6_port > p2_in6->sin6_port) 690933707f3Ssthen return 1; 691933707f3Ssthen log_assert(p1_in6->sin6_port == p2_in6->sin6_port); 692933707f3Ssthen return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, 693933707f3Ssthen INET6_SIZE); 694933707f3Ssthen } else { 695933707f3Ssthen /* eek unknown type, perform this comparison for sanity. */ 696933707f3Ssthen return memcmp(addr1, addr2, len1); 697933707f3Ssthen } 698933707f3Ssthen } 699933707f3Ssthen 700933707f3Ssthen int 701933707f3Ssthen sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1, 702933707f3Ssthen struct sockaddr_storage* addr2, socklen_t len2) 703933707f3Ssthen { 704933707f3Ssthen struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1; 705933707f3Ssthen struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2; 706933707f3Ssthen struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1; 707933707f3Ssthen struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2; 708933707f3Ssthen if(len1 < len2) 709933707f3Ssthen return -1; 710933707f3Ssthen if(len1 > len2) 711933707f3Ssthen return 1; 712933707f3Ssthen log_assert(len1 == len2); 713933707f3Ssthen if( p1_in->sin_family < p2_in->sin_family) 714933707f3Ssthen return -1; 715933707f3Ssthen if( p1_in->sin_family > p2_in->sin_family) 716933707f3Ssthen return 1; 717933707f3Ssthen log_assert( p1_in->sin_family == p2_in->sin_family ); 718933707f3Ssthen /* compare ip4 */ 719933707f3Ssthen if( p1_in->sin_family == AF_INET ) { 720933707f3Ssthen return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); 721933707f3Ssthen } else if (p1_in6->sin6_family == AF_INET6) { 722933707f3Ssthen return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, 723933707f3Ssthen INET6_SIZE); 724933707f3Ssthen } else { 725933707f3Ssthen /* eek unknown type, perform this comparison for sanity. */ 726933707f3Ssthen return memcmp(addr1, addr2, len1); 727933707f3Ssthen } 728933707f3Ssthen } 729933707f3Ssthen 730933707f3Ssthen int 731933707f3Ssthen addr_is_ip6(struct sockaddr_storage* addr, socklen_t len) 732933707f3Ssthen { 733933707f3Ssthen if(len == (socklen_t)sizeof(struct sockaddr_in6) && 734933707f3Ssthen ((struct sockaddr_in6*)addr)->sin6_family == AF_INET6) 735933707f3Ssthen return 1; 736933707f3Ssthen else return 0; 737933707f3Ssthen } 738933707f3Ssthen 739933707f3Ssthen void 740933707f3Ssthen addr_mask(struct sockaddr_storage* addr, socklen_t len, int net) 741933707f3Ssthen { 742933707f3Ssthen uint8_t mask[8] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe}; 743933707f3Ssthen int i, max; 744933707f3Ssthen uint8_t* s; 745933707f3Ssthen if(addr_is_ip6(addr, len)) { 746933707f3Ssthen s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr; 747933707f3Ssthen max = 128; 748933707f3Ssthen } else { 749933707f3Ssthen s = (uint8_t*)&((struct sockaddr_in*)addr)->sin_addr; 750933707f3Ssthen max = 32; 751933707f3Ssthen } 752933707f3Ssthen if(net >= max) 753933707f3Ssthen return; 754933707f3Ssthen for(i=net/8+1; i<max/8; i++) { 755933707f3Ssthen s[i] = 0; 756933707f3Ssthen } 757933707f3Ssthen s[net/8] &= mask[net&0x7]; 758933707f3Ssthen } 759933707f3Ssthen 760933707f3Ssthen int 761933707f3Ssthen addr_in_common(struct sockaddr_storage* addr1, int net1, 762933707f3Ssthen struct sockaddr_storage* addr2, int net2, socklen_t addrlen) 763933707f3Ssthen { 764933707f3Ssthen int min = (net1<net2)?net1:net2; 765933707f3Ssthen int i, to; 766933707f3Ssthen int match = 0; 767933707f3Ssthen uint8_t* s1, *s2; 768933707f3Ssthen if(addr_is_ip6(addr1, addrlen)) { 769933707f3Ssthen s1 = (uint8_t*)&((struct sockaddr_in6*)addr1)->sin6_addr; 770933707f3Ssthen s2 = (uint8_t*)&((struct sockaddr_in6*)addr2)->sin6_addr; 771933707f3Ssthen to = 16; 772933707f3Ssthen } else { 773933707f3Ssthen s1 = (uint8_t*)&((struct sockaddr_in*)addr1)->sin_addr; 774933707f3Ssthen s2 = (uint8_t*)&((struct sockaddr_in*)addr2)->sin_addr; 775933707f3Ssthen to = 4; 776933707f3Ssthen } 777933707f3Ssthen /* match = bits_in_common(s1, s2, to); */ 778933707f3Ssthen for(i=0; i<to; i++) { 779933707f3Ssthen if(s1[i] == s2[i]) { 780933707f3Ssthen match += 8; 781933707f3Ssthen } else { 782933707f3Ssthen uint8_t z = s1[i]^s2[i]; 783933707f3Ssthen log_assert(z); 784933707f3Ssthen while(!(z&0x80)) { 785933707f3Ssthen match++; 786933707f3Ssthen z<<=1; 787933707f3Ssthen } 788933707f3Ssthen break; 789933707f3Ssthen } 790933707f3Ssthen } 791933707f3Ssthen if(match > min) match = min; 792933707f3Ssthen return match; 793933707f3Ssthen } 794933707f3Ssthen 795933707f3Ssthen void 796933707f3Ssthen addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen, 797933707f3Ssthen char* buf, size_t len) 798933707f3Ssthen { 799933707f3Ssthen int af = (int)((struct sockaddr_in*)addr)->sin_family; 800933707f3Ssthen void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 801933707f3Ssthen if(addr_is_ip6(addr, addrlen)) 802933707f3Ssthen sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; 803933707f3Ssthen if(inet_ntop(af, sinaddr, buf, (socklen_t)len) == 0) { 804933707f3Ssthen snprintf(buf, len, "(inet_ntop_error)"); 805933707f3Ssthen } 806933707f3Ssthen } 807933707f3Ssthen 808933707f3Ssthen int 8098b7325afSsthen prefixnet_is_nat64(int prefixnet) 8108b7325afSsthen { 8118b7325afSsthen return (prefixnet == 32 || prefixnet == 40 || 8128b7325afSsthen prefixnet == 48 || prefixnet == 56 || 8138b7325afSsthen prefixnet == 64 || prefixnet == 96); 8148b7325afSsthen } 8158b7325afSsthen 8168b7325afSsthen void 8178b7325afSsthen addr_to_nat64(const struct sockaddr_storage* addr, 8188b7325afSsthen const struct sockaddr_storage* nat64_prefix, 8198b7325afSsthen socklen_t nat64_prefixlen, int nat64_prefixnet, 8208b7325afSsthen struct sockaddr_storage* nat64_addr, socklen_t* nat64_addrlen) 8218b7325afSsthen { 8228b7325afSsthen struct sockaddr_in *sin = (struct sockaddr_in *)addr; 8238b7325afSsthen struct sockaddr_in6 *sin6; 8248b7325afSsthen uint8_t *v4_byte; 8253a958a18Sderaadt int i; 8268b7325afSsthen 8278b7325afSsthen /* This needs to be checked by the caller */ 8288b7325afSsthen log_assert(addr->ss_family == AF_INET); 8298b7325afSsthen /* Current usage is only from config values; prefix lengths enforced 8308b7325afSsthen * during config validation */ 8318b7325afSsthen log_assert(prefixnet_is_nat64(nat64_prefixnet)); 8328b7325afSsthen 8338b7325afSsthen *nat64_addr = *nat64_prefix; 8348b7325afSsthen *nat64_addrlen = nat64_prefixlen; 8358b7325afSsthen 8368b7325afSsthen sin6 = (struct sockaddr_in6 *)nat64_addr; 8378b7325afSsthen sin6->sin6_flowinfo = 0; 8388b7325afSsthen sin6->sin6_port = sin->sin_port; 8398b7325afSsthen 8408b7325afSsthen nat64_prefixnet = nat64_prefixnet / 8; 8418b7325afSsthen 8428b7325afSsthen v4_byte = (uint8_t *)&sin->sin_addr.s_addr; 8433a958a18Sderaadt for(i = 0; i < 4; i++) { 8448b7325afSsthen if(nat64_prefixnet == 8) { 8458b7325afSsthen /* bits 64...71 are MBZ */ 8468b7325afSsthen sin6->sin6_addr.s6_addr[nat64_prefixnet++] = 0; 8478b7325afSsthen } 8488b7325afSsthen sin6->sin6_addr.s6_addr[nat64_prefixnet++] = *v4_byte++; 8498b7325afSsthen } 8508b7325afSsthen } 8518b7325afSsthen 8528b7325afSsthen int 853933707f3Ssthen addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen) 854933707f3Ssthen { 855933707f3Ssthen /* prefix for ipv4 into ipv6 mapping is ::ffff:x.x.x.x */ 856933707f3Ssthen const uint8_t map_prefix[16] = 857933707f3Ssthen {0,0,0,0, 0,0,0,0, 0,0,0xff,0xff, 0,0,0,0}; 858933707f3Ssthen uint8_t* s; 859933707f3Ssthen if(!addr_is_ip6(addr, addrlen)) 860933707f3Ssthen return 0; 861933707f3Ssthen /* s is 16 octet ipv6 address string */ 862933707f3Ssthen s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr; 863933707f3Ssthen return (memcmp(s, map_prefix, 12) == 0); 864933707f3Ssthen } 865933707f3Ssthen 866*98bc733bSsthen int addr_is_ip6linklocal(struct sockaddr_storage* addr, socklen_t addrlen) 867*98bc733bSsthen { 868*98bc733bSsthen const uint8_t prefix[2] = {0xfe, 0x80}; 869*98bc733bSsthen int af = (int)((struct sockaddr_in6*)addr)->sin6_family; 870*98bc733bSsthen void* sin6addr = &((struct sockaddr_in6*)addr)->sin6_addr; 871*98bc733bSsthen uint8_t start[2]; 872*98bc733bSsthen if(af != AF_INET6 || addrlen<(socklen_t)sizeof(struct sockaddr_in6)) 873*98bc733bSsthen return 0; 874*98bc733bSsthen /* Put the first 10 bits of sin6addr in start, match fe80::/10. */ 875*98bc733bSsthen memmove(start, sin6addr, 2); 876*98bc733bSsthen start[1] &= 0xc0; 877*98bc733bSsthen return memcmp(start, prefix, 2) == 0; 878*98bc733bSsthen } 879*98bc733bSsthen 880933707f3Ssthen int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen) 881933707f3Ssthen { 882933707f3Ssthen int af = (int)((struct sockaddr_in*)addr)->sin_family; 883933707f3Ssthen void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 884933707f3Ssthen return af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in) 885933707f3Ssthen && memcmp(sinaddr, "\377\377\377\377", 4) == 0; 886933707f3Ssthen } 887933707f3Ssthen 888933707f3Ssthen int addr_is_any(struct sockaddr_storage* addr, socklen_t addrlen) 889933707f3Ssthen { 890933707f3Ssthen int af = (int)((struct sockaddr_in*)addr)->sin_family; 891933707f3Ssthen void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 892933707f3Ssthen void* sin6addr = &((struct sockaddr_in6*)addr)->sin6_addr; 893933707f3Ssthen if(af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in) 894933707f3Ssthen && memcmp(sinaddr, "\000\000\000\000", 4) == 0) 895933707f3Ssthen return 1; 896933707f3Ssthen else if(af==AF_INET6 && addrlen>=(socklen_t)sizeof(struct sockaddr_in6) 897933707f3Ssthen && memcmp(sin6addr, "\000\000\000\000\000\000\000\000" 898933707f3Ssthen "\000\000\000\000\000\000\000\000", 16) == 0) 899933707f3Ssthen return 1; 900933707f3Ssthen return 0; 901933707f3Ssthen } 902933707f3Ssthen 903933707f3Ssthen void sock_list_insert(struct sock_list** list, struct sockaddr_storage* addr, 904933707f3Ssthen socklen_t len, struct regional* region) 905933707f3Ssthen { 906933707f3Ssthen struct sock_list* add = (struct sock_list*)regional_alloc(region, 907933707f3Ssthen sizeof(*add) - sizeof(add->addr) + (size_t)len); 908933707f3Ssthen if(!add) { 909933707f3Ssthen log_err("out of memory in socketlist insert"); 910933707f3Ssthen return; 911933707f3Ssthen } 912933707f3Ssthen log_assert(list); 913933707f3Ssthen add->next = *list; 914933707f3Ssthen add->len = len; 915933707f3Ssthen *list = add; 916933707f3Ssthen if(len) memmove(&add->addr, addr, len); 917933707f3Ssthen } 918933707f3Ssthen 919933707f3Ssthen void sock_list_prepend(struct sock_list** list, struct sock_list* add) 920933707f3Ssthen { 921933707f3Ssthen struct sock_list* last = add; 922933707f3Ssthen if(!last) 923933707f3Ssthen return; 924933707f3Ssthen while(last->next) 925933707f3Ssthen last = last->next; 926933707f3Ssthen last->next = *list; 927933707f3Ssthen *list = add; 928933707f3Ssthen } 929933707f3Ssthen 930933707f3Ssthen int sock_list_find(struct sock_list* list, struct sockaddr_storage* addr, 931933707f3Ssthen socklen_t len) 932933707f3Ssthen { 933933707f3Ssthen while(list) { 934933707f3Ssthen if(len == list->len) { 935933707f3Ssthen if(len == 0 || sockaddr_cmp_addr(addr, len, 936933707f3Ssthen &list->addr, list->len) == 0) 937933707f3Ssthen return 1; 938933707f3Ssthen } 939933707f3Ssthen list = list->next; 940933707f3Ssthen } 941933707f3Ssthen return 0; 942933707f3Ssthen } 943933707f3Ssthen 944933707f3Ssthen void sock_list_merge(struct sock_list** list, struct regional* region, 945933707f3Ssthen struct sock_list* add) 946933707f3Ssthen { 947933707f3Ssthen struct sock_list* p; 948933707f3Ssthen for(p=add; p; p=p->next) { 949933707f3Ssthen if(!sock_list_find(*list, &p->addr, p->len)) 950933707f3Ssthen sock_list_insert(list, &p->addr, p->len, region); 951933707f3Ssthen } 952933707f3Ssthen } 953933707f3Ssthen 954933707f3Ssthen void 955933707f3Ssthen log_crypto_err(const char* str) 956933707f3Ssthen { 9573dcb24b8Ssthen #ifdef HAVE_SSL 958ebf5bb73Ssthen log_crypto_err_code(str, ERR_get_error()); 959ebf5bb73Ssthen #else 960ebf5bb73Ssthen (void)str; 961ebf5bb73Ssthen #endif /* HAVE_SSL */ 962ebf5bb73Ssthen } 963ebf5bb73Ssthen 964ebf5bb73Ssthen void log_crypto_err_code(const char* str, unsigned long err) 965ebf5bb73Ssthen { 966ebf5bb73Ssthen #ifdef HAVE_SSL 967933707f3Ssthen /* error:[error code]:[library name]:[function name]:[reason string] */ 968933707f3Ssthen char buf[128]; 969933707f3Ssthen unsigned long e; 970ebf5bb73Ssthen ERR_error_string_n(err, buf, sizeof(buf)); 971933707f3Ssthen log_err("%s crypto %s", str, buf); 972933707f3Ssthen while( (e=ERR_get_error()) ) { 973933707f3Ssthen ERR_error_string_n(e, buf, sizeof(buf)); 974933707f3Ssthen log_err("and additionally crypto %s", buf); 975933707f3Ssthen } 9763dcb24b8Ssthen #else 9773dcb24b8Ssthen (void)str; 978ebf5bb73Ssthen (void)err; 9793dcb24b8Ssthen #endif /* HAVE_SSL */ 980933707f3Ssthen } 981933707f3Ssthen 982a3167c07Ssthen #ifdef HAVE_SSL 983d896b962Ssthen /** Print crypt erro with SSL_get_error want code and err_get_error code */ 984d896b962Ssthen static void log_crypto_err_io_code_arg(const char* str, int r, 985d896b962Ssthen unsigned long err, int err_present) 986d896b962Ssthen { 987d896b962Ssthen int print_errno = 0, print_crypto_err = 0; 988d896b962Ssthen const char* inf = NULL; 989d896b962Ssthen 990d896b962Ssthen switch(r) { 991d896b962Ssthen case SSL_ERROR_NONE: 992d896b962Ssthen inf = "no error"; 993d896b962Ssthen break; 994d896b962Ssthen case SSL_ERROR_ZERO_RETURN: 995d896b962Ssthen inf = "channel closed"; 996d896b962Ssthen break; 997d896b962Ssthen case SSL_ERROR_WANT_READ: 998d896b962Ssthen inf = "want read"; 999d896b962Ssthen break; 1000d896b962Ssthen case SSL_ERROR_WANT_WRITE: 1001d896b962Ssthen inf = "want write"; 1002d896b962Ssthen break; 1003d896b962Ssthen case SSL_ERROR_WANT_CONNECT: 1004d896b962Ssthen inf = "want connect"; 1005d896b962Ssthen break; 1006d896b962Ssthen case SSL_ERROR_WANT_ACCEPT: 1007d896b962Ssthen inf = "want accept"; 1008d896b962Ssthen break; 1009d896b962Ssthen case SSL_ERROR_WANT_X509_LOOKUP: 1010d896b962Ssthen inf = "want X509 lookup"; 1011d896b962Ssthen break; 1012d896b962Ssthen #ifdef SSL_ERROR_WANT_ASYNC 1013d896b962Ssthen case SSL_ERROR_WANT_ASYNC: 1014d896b962Ssthen inf = "want async"; 1015d896b962Ssthen break; 1016d896b962Ssthen #endif 1017d896b962Ssthen #ifdef SSL_ERROR_WANT_ASYNC_JOB 1018d896b962Ssthen case SSL_ERROR_WANT_ASYNC_JOB: 1019d896b962Ssthen inf = "want async job"; 1020d896b962Ssthen break; 1021d896b962Ssthen #endif 1022d896b962Ssthen #ifdef SSL_ERROR_WANT_CLIENT_HELLO_CB 1023d896b962Ssthen case SSL_ERROR_WANT_CLIENT_HELLO_CB: 1024d896b962Ssthen inf = "want client hello cb"; 1025d896b962Ssthen break; 1026d896b962Ssthen #endif 1027d896b962Ssthen case SSL_ERROR_SYSCALL: 1028d896b962Ssthen print_errno = 1; 1029d896b962Ssthen inf = "syscall"; 1030d896b962Ssthen break; 1031d896b962Ssthen case SSL_ERROR_SSL: 1032d896b962Ssthen print_crypto_err = 1; 1033d896b962Ssthen inf = "SSL, usually protocol, error"; 1034d896b962Ssthen break; 1035d896b962Ssthen default: 1036d896b962Ssthen inf = "unknown SSL_get_error result code"; 1037d896b962Ssthen print_errno = 1; 1038d896b962Ssthen print_crypto_err = 1; 1039d896b962Ssthen } 1040d896b962Ssthen if(print_crypto_err) { 1041d896b962Ssthen if(print_errno) { 1042d896b962Ssthen char buf[1024]; 1043d896b962Ssthen snprintf(buf, sizeof(buf), "%s with errno %s", 1044d896b962Ssthen str, strerror(errno)); 1045d896b962Ssthen if(err_present) 1046d896b962Ssthen log_crypto_err_code(buf, err); 1047d896b962Ssthen else log_crypto_err(buf); 1048d896b962Ssthen } else { 1049d896b962Ssthen if(err_present) 1050d896b962Ssthen log_crypto_err_code(str, err); 1051d896b962Ssthen else log_crypto_err(str); 1052d896b962Ssthen } 1053d896b962Ssthen } else { 1054d896b962Ssthen if(print_errno) { 1055d896b962Ssthen if(errno == 0) 10562bdc0ed1Ssthen log_err("%s: syscall error with errno %s", 10572bdc0ed1Ssthen str, strerror(errno)); 10582bdc0ed1Ssthen else log_err("%s: %s", str, strerror(errno)); 1059d896b962Ssthen } else { 10602bdc0ed1Ssthen log_err("%s: %s", str, inf); 1061d896b962Ssthen } 1062d896b962Ssthen } 1063d896b962Ssthen } 1064d896b962Ssthen #endif /* HAVE_SSL */ 1065d896b962Ssthen 1066d896b962Ssthen void log_crypto_err_io(const char* str, int r) 1067d896b962Ssthen { 1068d896b962Ssthen #ifdef HAVE_SSL 1069d896b962Ssthen log_crypto_err_io_code_arg(str, r, 0, 0); 1070d896b962Ssthen #else 1071d896b962Ssthen (void)str; 1072d896b962Ssthen (void)r; 1073d896b962Ssthen #endif /* HAVE_SSL */ 1074d896b962Ssthen } 1075d896b962Ssthen 1076d896b962Ssthen void log_crypto_err_io_code(const char* str, int r, unsigned long err) 1077d896b962Ssthen { 1078d896b962Ssthen #ifdef HAVE_SSL 1079d896b962Ssthen log_crypto_err_io_code_arg(str, r, err, 1); 1080d896b962Ssthen #else 1081d896b962Ssthen (void)str; 1082d896b962Ssthen (void)r; 1083d896b962Ssthen (void)err; 1084d896b962Ssthen #endif /* HAVE_SSL */ 1085d896b962Ssthen } 1086d896b962Ssthen 1087d896b962Ssthen #ifdef HAVE_SSL 1088a3167c07Ssthen /** log certificate details */ 1089a3167c07Ssthen void 1090a3167c07Ssthen log_cert(unsigned level, const char* str, void* cert) 1091a3167c07Ssthen { 1092a3167c07Ssthen BIO* bio; 1093a3167c07Ssthen char nul = 0; 1094a3167c07Ssthen char* pp = NULL; 1095a3167c07Ssthen long len; 1096a3167c07Ssthen if(verbosity < level) return; 1097a3167c07Ssthen bio = BIO_new(BIO_s_mem()); 1098a3167c07Ssthen if(!bio) return; 1099a3167c07Ssthen X509_print_ex(bio, (X509*)cert, 0, (unsigned long)-1 1100a3167c07Ssthen ^(X509_FLAG_NO_SUBJECT 1101a3167c07Ssthen |X509_FLAG_NO_ISSUER|X509_FLAG_NO_VALIDITY 1102a3167c07Ssthen |X509_FLAG_NO_EXTENSIONS|X509_FLAG_NO_AUX 1103a3167c07Ssthen |X509_FLAG_NO_ATTRIBUTES)); 1104a3167c07Ssthen BIO_write(bio, &nul, (int)sizeof(nul)); 1105a3167c07Ssthen len = BIO_get_mem_data(bio, &pp); 1106a3167c07Ssthen if(len != 0 && pp) { 1107e21c60efSsthen /* reduce size of cert printout */ 1108e21c60efSsthen char* s; 1109e21c60efSsthen while((s=strstr(pp, " "))!=NULL) 1110e21c60efSsthen memmove(s, s+1, strlen(s+1)+1); 1111e21c60efSsthen while((s=strstr(pp, "\t\t"))!=NULL) 1112e21c60efSsthen memmove(s, s+1, strlen(s+1)+1); 1113a3167c07Ssthen verbose(level, "%s: \n%s", str, pp); 1114a3167c07Ssthen } 1115a3167c07Ssthen BIO_free(bio); 1116a3167c07Ssthen } 1117a3167c07Ssthen #endif /* HAVE_SSL */ 1118a3167c07Ssthen 1119191f22c6Ssthen #if defined(HAVE_SSL) && defined(HAVE_NGHTTP2) && defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) 11202c144df0Ssthen static int alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out, 11212c144df0Ssthen unsigned char* outlen, const unsigned char* in, unsigned int inlen, 11222c144df0Ssthen void* ATTR_UNUSED(arg)) 11232c144df0Ssthen { 11242c144df0Ssthen int rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in, 11252c144df0Ssthen inlen); 11262c144df0Ssthen if(rv == -1) { 11272c144df0Ssthen return SSL_TLSEXT_ERR_NOACK; 11282c144df0Ssthen } 11292c144df0Ssthen /* either http/1.1 or h2 selected */ 11302c144df0Ssthen return SSL_TLSEXT_ERR_OK; 11312c144df0Ssthen } 11322c144df0Ssthen #endif 11332c144df0Ssthen 11347191de28Ssthen int 11357191de28Ssthen listen_sslctx_setup(void* ctxt) 11367191de28Ssthen { 11377191de28Ssthen #ifdef HAVE_SSL 11387191de28Ssthen SSL_CTX* ctx = (SSL_CTX*)ctxt; 11397191de28Ssthen /* no SSLv2, SSLv3 because has defects */ 1140eaf2578eSsthen #if SSL_OP_NO_SSLv2 != 0 11417191de28Ssthen if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) 11427191de28Ssthen != SSL_OP_NO_SSLv2){ 11437191de28Ssthen log_crypto_err("could not set SSL_OP_NO_SSLv2"); 11447191de28Ssthen return 0; 11457191de28Ssthen } 1146eaf2578eSsthen #endif 11477191de28Ssthen if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) 11487191de28Ssthen != SSL_OP_NO_SSLv3){ 11497191de28Ssthen log_crypto_err("could not set SSL_OP_NO_SSLv3"); 11507191de28Ssthen return 0; 11517191de28Ssthen } 11527191de28Ssthen #if defined(SSL_OP_NO_TLSv1) && defined(SSL_OP_NO_TLSv1_1) 11537191de28Ssthen /* if we have tls 1.1 disable 1.0 */ 11547191de28Ssthen if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1) & SSL_OP_NO_TLSv1) 11557191de28Ssthen != SSL_OP_NO_TLSv1){ 11567191de28Ssthen log_crypto_err("could not set SSL_OP_NO_TLSv1"); 11577191de28Ssthen return 0; 11587191de28Ssthen } 11597191de28Ssthen #endif 11607191de28Ssthen #if defined(SSL_OP_NO_TLSv1_1) && defined(SSL_OP_NO_TLSv1_2) 11617191de28Ssthen /* if we have tls 1.2 disable 1.1 */ 11627191de28Ssthen if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_1) & SSL_OP_NO_TLSv1_1) 11637191de28Ssthen != SSL_OP_NO_TLSv1_1){ 11647191de28Ssthen log_crypto_err("could not set SSL_OP_NO_TLSv1_1"); 11657191de28Ssthen return 0; 11667191de28Ssthen } 11677191de28Ssthen #endif 11688240c1b9Ssthen #if defined(SSL_OP_NO_RENEGOTIATION) 11698240c1b9Ssthen /* disable client renegotiation */ 11708240c1b9Ssthen if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) & 11718240c1b9Ssthen SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION) { 11728240c1b9Ssthen log_crypto_err("could not set SSL_OP_NO_RENEGOTIATION"); 11738240c1b9Ssthen return 0; 11748240c1b9Ssthen } 11758240c1b9Ssthen #endif 11767191de28Ssthen #if defined(SHA256_DIGEST_LENGTH) && defined(USE_ECDSA) 1177e21c60efSsthen /* if we detect system-wide crypto policies, use those */ 1178e21c60efSsthen if (access( "/etc/crypto-policies/config", F_OK ) != 0 ) { 11797191de28Ssthen /* if we have sha256, set the cipher list to have no known vulns */ 1180bdfc4d55Sflorian if(!SSL_CTX_set_cipher_list(ctx, "TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256")) 11817191de28Ssthen log_crypto_err("could not set cipher list with SSL_CTX_set_cipher_list"); 1182e21c60efSsthen } 11837191de28Ssthen #endif 11848b7325afSsthen #if defined(SSL_OP_IGNORE_UNEXPECTED_EOF) 11858b7325afSsthen /* ignore errors when peers do not send the mandatory close_notify 11868b7325afSsthen * alert on shutdown. 11878b7325afSsthen * Relevant for openssl >= 3 */ 11888b7325afSsthen if((SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF) & 11898b7325afSsthen SSL_OP_IGNORE_UNEXPECTED_EOF) != SSL_OP_IGNORE_UNEXPECTED_EOF) { 11908b7325afSsthen log_crypto_err("could not set SSL_OP_IGNORE_UNEXPECTED_EOF"); 11918b7325afSsthen return 0; 11928b7325afSsthen } 11938b7325afSsthen #endif 11947191de28Ssthen 11957191de28Ssthen if((SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE) & 11967191de28Ssthen SSL_OP_CIPHER_SERVER_PREFERENCE) != 11977191de28Ssthen SSL_OP_CIPHER_SERVER_PREFERENCE) { 11987191de28Ssthen log_crypto_err("could not set SSL_OP_CIPHER_SERVER_PREFERENCE"); 11997191de28Ssthen return 0; 12007191de28Ssthen } 12017191de28Ssthen 12027191de28Ssthen #ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL 12037191de28Ssthen SSL_CTX_set_security_level(ctx, 0); 12047191de28Ssthen #endif 12052c144df0Ssthen #if defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) && defined(HAVE_NGHTTP2) 12062c144df0Ssthen SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb, NULL); 12072c144df0Ssthen #endif 12087191de28Ssthen #else 12097191de28Ssthen (void)ctxt; 12107191de28Ssthen #endif /* HAVE_SSL */ 12117191de28Ssthen return 1; 12127191de28Ssthen } 12137191de28Ssthen 12147191de28Ssthen void 12157191de28Ssthen listen_sslctx_setup_2(void* ctxt) 12167191de28Ssthen { 12177191de28Ssthen #ifdef HAVE_SSL 12187191de28Ssthen SSL_CTX* ctx = (SSL_CTX*)ctxt; 12197191de28Ssthen (void)ctx; 12207191de28Ssthen #if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO 12217191de28Ssthen if(!SSL_CTX_set_ecdh_auto(ctx,1)) { 12227191de28Ssthen log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE"); 12237191de28Ssthen } 1224*98bc733bSsthen #elif defined(USE_ECDSA) && defined(HAVE_SSL_CTX_SET_TMP_ECDH) 12257191de28Ssthen if(1) { 12267191de28Ssthen EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1); 12277191de28Ssthen if (!ecdh) { 12287191de28Ssthen log_crypto_err("could not find p256, not enabling ECDHE"); 12297191de28Ssthen } else { 12307191de28Ssthen if (1 != SSL_CTX_set_tmp_ecdh (ctx, ecdh)) { 12317191de28Ssthen log_crypto_err("Error in SSL_CTX_set_tmp_ecdh, not enabling ECDHE"); 12327191de28Ssthen } 12337191de28Ssthen EC_KEY_free (ecdh); 12347191de28Ssthen } 12357191de28Ssthen } 12367191de28Ssthen #endif 12377191de28Ssthen #else 12387191de28Ssthen (void)ctxt; 12397191de28Ssthen #endif /* HAVE_SSL */ 12407191de28Ssthen } 12417191de28Ssthen 1242933707f3Ssthen void* listen_sslctx_create(char* key, char* pem, char* verifypem) 1243933707f3Ssthen { 12443dcb24b8Ssthen #ifdef HAVE_SSL 1245933707f3Ssthen SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method()); 1246933707f3Ssthen if(!ctx) { 1247933707f3Ssthen log_crypto_err("could not SSL_CTX_new"); 1248933707f3Ssthen return NULL; 1249933707f3Ssthen } 1250550cf4a9Ssthen if(!key || key[0] == 0) { 1251550cf4a9Ssthen log_err("error: no tls-service-key file specified"); 1252550cf4a9Ssthen SSL_CTX_free(ctx); 1253550cf4a9Ssthen return NULL; 1254550cf4a9Ssthen } 1255550cf4a9Ssthen if(!pem || pem[0] == 0) { 1256550cf4a9Ssthen log_err("error: no tls-service-pem file specified"); 1257550cf4a9Ssthen SSL_CTX_free(ctx); 1258550cf4a9Ssthen return NULL; 1259550cf4a9Ssthen } 12607191de28Ssthen if(!listen_sslctx_setup(ctx)) { 126198f3ca02Sbrad SSL_CTX_free(ctx); 126298f3ca02Sbrad return NULL; 126398f3ca02Sbrad } 1264a961b961Ssthen if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) { 1265933707f3Ssthen log_err("error for cert file: %s", pem); 1266a961b961Ssthen log_crypto_err("error in SSL_CTX use_certificate_chain_file"); 1267933707f3Ssthen SSL_CTX_free(ctx); 1268933707f3Ssthen return NULL; 1269933707f3Ssthen } 1270933707f3Ssthen if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) { 1271933707f3Ssthen log_err("error for private key file: %s", key); 1272933707f3Ssthen log_crypto_err("Error in SSL_CTX use_PrivateKey_file"); 1273933707f3Ssthen SSL_CTX_free(ctx); 1274933707f3Ssthen return NULL; 1275933707f3Ssthen } 1276933707f3Ssthen if(!SSL_CTX_check_private_key(ctx)) { 1277933707f3Ssthen log_err("error for key file: %s", key); 1278933707f3Ssthen log_crypto_err("Error in SSL_CTX check_private_key"); 1279933707f3Ssthen SSL_CTX_free(ctx); 1280933707f3Ssthen return NULL; 1281933707f3Ssthen } 12827191de28Ssthen listen_sslctx_setup_2(ctx); 1283933707f3Ssthen if(verifypem && verifypem[0]) { 1284933707f3Ssthen if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { 1285933707f3Ssthen log_crypto_err("Error in SSL_CTX verify locations"); 1286933707f3Ssthen SSL_CTX_free(ctx); 1287933707f3Ssthen return NULL; 1288933707f3Ssthen } 1289933707f3Ssthen SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file( 1290933707f3Ssthen verifypem)); 1291a3167c07Ssthen SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); 1292933707f3Ssthen } 1293933707f3Ssthen return ctx; 12943dcb24b8Ssthen #else 12953dcb24b8Ssthen (void)key; (void)pem; (void)verifypem; 12963dcb24b8Ssthen return NULL; 12973dcb24b8Ssthen #endif 1298933707f3Ssthen } 1299933707f3Ssthen 130020237c55Ssthen #ifdef USE_WINSOCK 130120237c55Ssthen /* For windows, the CA trust store is not read by openssl. 130220237c55Ssthen Add code to open the trust store using wincrypt API and add 130320237c55Ssthen the root certs into openssl trust store */ 130420237c55Ssthen static int 130520237c55Ssthen add_WIN_cacerts_to_openssl_store(SSL_CTX* tls_ctx) 130620237c55Ssthen { 130720237c55Ssthen HCERTSTORE hSystemStore; 130820237c55Ssthen PCCERT_CONTEXT pTargetCert = NULL; 130920237c55Ssthen X509_STORE* store; 131020237c55Ssthen 131120237c55Ssthen verbose(VERB_ALGO, "Adding Windows certificates from system root store to CA store"); 131220237c55Ssthen 131320237c55Ssthen /* load just once per context lifetime for this version 131420237c55Ssthen TODO: dynamically update CA trust changes as they are available */ 131520237c55Ssthen if (!tls_ctx) 131620237c55Ssthen return 0; 131720237c55Ssthen 131820237c55Ssthen /* Call wincrypt's CertOpenStore to open the CA root store. */ 131920237c55Ssthen 132020237c55Ssthen if ((hSystemStore = CertOpenStore( 132120237c55Ssthen CERT_STORE_PROV_SYSTEM, 132220237c55Ssthen 0, 132320237c55Ssthen 0, 132420237c55Ssthen /* NOTE: mingw does not have this const: replace with 1 << 16 from code 132520237c55Ssthen CERT_SYSTEM_STORE_CURRENT_USER, */ 132620237c55Ssthen 1 << 16, 132720237c55Ssthen L"root")) == 0) 132820237c55Ssthen { 132920237c55Ssthen return 0; 133020237c55Ssthen } 133120237c55Ssthen 133220237c55Ssthen store = SSL_CTX_get_cert_store(tls_ctx); 133320237c55Ssthen if (!store) 133420237c55Ssthen return 0; 133520237c55Ssthen 133620237c55Ssthen /* failure if the CA store is empty or the call fails */ 133720237c55Ssthen if ((pTargetCert = CertEnumCertificatesInStore( 133820237c55Ssthen hSystemStore, pTargetCert)) == 0) { 133920237c55Ssthen verbose(VERB_ALGO, "CA certificate store for Windows is empty."); 134020237c55Ssthen return 0; 134120237c55Ssthen } 134220237c55Ssthen /* iterate over the windows cert store and add to openssl store */ 134320237c55Ssthen do 134420237c55Ssthen { 134520237c55Ssthen X509 *cert1 = d2i_X509(NULL, 134620237c55Ssthen (const unsigned char **)&pTargetCert->pbCertEncoded, 134720237c55Ssthen pTargetCert->cbCertEncoded); 134820237c55Ssthen if (!cert1) { 1349d1e2768aSsthen unsigned long error = ERR_get_error(); 135020237c55Ssthen /* return error if a cert fails */ 135120237c55Ssthen verbose(VERB_ALGO, "%s %d:%s", 135220237c55Ssthen "Unable to parse certificate in memory", 1353d1e2768aSsthen (int)error, ERR_error_string(error, NULL)); 135420237c55Ssthen return 0; 135520237c55Ssthen } 135620237c55Ssthen else { 135720237c55Ssthen /* return error if a cert add to store fails */ 135820237c55Ssthen if (X509_STORE_add_cert(store, cert1) == 0) { 135920237c55Ssthen unsigned long error = ERR_peek_last_error(); 136020237c55Ssthen 136120237c55Ssthen /* Ignore error X509_R_CERT_ALREADY_IN_HASH_TABLE which means the 136220237c55Ssthen * certificate is already in the store. */ 136320237c55Ssthen if(ERR_GET_LIB(error) != ERR_LIB_X509 || 136420237c55Ssthen ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) { 1365d1e2768aSsthen error = ERR_get_error(); 136620237c55Ssthen verbose(VERB_ALGO, "%s %d:%s\n", 1367d1e2768aSsthen "Error adding certificate", (int)error, 1368d1e2768aSsthen ERR_error_string(error, NULL)); 136920237c55Ssthen X509_free(cert1); 137020237c55Ssthen return 0; 137120237c55Ssthen } 137220237c55Ssthen } 137320237c55Ssthen X509_free(cert1); 137420237c55Ssthen } 137520237c55Ssthen } while ((pTargetCert = CertEnumCertificatesInStore( 137620237c55Ssthen hSystemStore, pTargetCert)) != 0); 137720237c55Ssthen 137820237c55Ssthen /* Clean up memory and quit. */ 137920237c55Ssthen if (pTargetCert) 138020237c55Ssthen CertFreeCertificateContext(pTargetCert); 138120237c55Ssthen if (hSystemStore) 138220237c55Ssthen { 138320237c55Ssthen if (!CertCloseStore( 138420237c55Ssthen hSystemStore, 0)) 138520237c55Ssthen return 0; 138620237c55Ssthen } 138720237c55Ssthen verbose(VERB_ALGO, "Completed adding Windows certificates to CA store successfully"); 138820237c55Ssthen return 1; 138920237c55Ssthen } 139020237c55Ssthen #endif /* USE_WINSOCK */ 139120237c55Ssthen 139220237c55Ssthen void* connect_sslctx_create(char* key, char* pem, char* verifypem, int wincert) 1393933707f3Ssthen { 13943dcb24b8Ssthen #ifdef HAVE_SSL 1395933707f3Ssthen SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method()); 1396933707f3Ssthen if(!ctx) { 1397933707f3Ssthen log_crypto_err("could not allocate SSL_CTX pointer"); 1398933707f3Ssthen return NULL; 1399933707f3Ssthen } 1400eaf2578eSsthen #if SSL_OP_NO_SSLv2 != 0 14013c667526Sdoug if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) 14023c667526Sdoug != SSL_OP_NO_SSLv2) { 1403933707f3Ssthen log_crypto_err("could not set SSL_OP_NO_SSLv2"); 1404933707f3Ssthen SSL_CTX_free(ctx); 1405933707f3Ssthen return NULL; 1406933707f3Ssthen } 1407eaf2578eSsthen #endif 14083c667526Sdoug if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) 14093c667526Sdoug != SSL_OP_NO_SSLv3) { 141098f3ca02Sbrad log_crypto_err("could not set SSL_OP_NO_SSLv3"); 141198f3ca02Sbrad SSL_CTX_free(ctx); 141298f3ca02Sbrad return NULL; 141398f3ca02Sbrad } 14148240c1b9Ssthen #if defined(SSL_OP_NO_RENEGOTIATION) 14158240c1b9Ssthen /* disable client renegotiation */ 14168240c1b9Ssthen if((SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION) & 14178240c1b9Ssthen SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION) { 14188240c1b9Ssthen log_crypto_err("could not set SSL_OP_NO_RENEGOTIATION"); 1419e21c60efSsthen SSL_CTX_free(ctx); 14208240c1b9Ssthen return 0; 14218240c1b9Ssthen } 14228240c1b9Ssthen #endif 14238b7325afSsthen #if defined(SSL_OP_IGNORE_UNEXPECTED_EOF) 14248b7325afSsthen /* ignore errors when peers do not send the mandatory close_notify 14258b7325afSsthen * alert on shutdown. 14268b7325afSsthen * Relevant for openssl >= 3 */ 14278b7325afSsthen if((SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF) & 14288b7325afSsthen SSL_OP_IGNORE_UNEXPECTED_EOF) != SSL_OP_IGNORE_UNEXPECTED_EOF) { 14298b7325afSsthen log_crypto_err("could not set SSL_OP_IGNORE_UNEXPECTED_EOF"); 14308b7325afSsthen SSL_CTX_free(ctx); 14318b7325afSsthen return 0; 14328b7325afSsthen } 14338b7325afSsthen #endif 1434933707f3Ssthen if(key && key[0]) { 1435a961b961Ssthen if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) { 1436933707f3Ssthen log_err("error in client certificate %s", pem); 1437933707f3Ssthen log_crypto_err("error in certificate file"); 1438933707f3Ssthen SSL_CTX_free(ctx); 1439933707f3Ssthen return NULL; 1440933707f3Ssthen } 1441933707f3Ssthen if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) { 1442933707f3Ssthen log_err("error in client private key %s", key); 1443933707f3Ssthen log_crypto_err("error in key file"); 1444933707f3Ssthen SSL_CTX_free(ctx); 1445933707f3Ssthen return NULL; 1446933707f3Ssthen } 1447933707f3Ssthen if(!SSL_CTX_check_private_key(ctx)) { 1448933707f3Ssthen log_err("error in client key %s", key); 1449933707f3Ssthen log_crypto_err("error in SSL_CTX_check_private_key"); 1450933707f3Ssthen SSL_CTX_free(ctx); 1451933707f3Ssthen return NULL; 1452933707f3Ssthen } 1453933707f3Ssthen } 145420237c55Ssthen if((verifypem && verifypem[0]) || wincert) { 1455933707f3Ssthen if(verifypem && verifypem[0]) { 145657dceb2aSbrad if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { 1457933707f3Ssthen log_crypto_err("error in SSL_CTX verify"); 1458933707f3Ssthen SSL_CTX_free(ctx); 1459933707f3Ssthen return NULL; 1460933707f3Ssthen } 146120237c55Ssthen } 146220237c55Ssthen #ifdef USE_WINSOCK 146320237c55Ssthen if(wincert) { 146420237c55Ssthen if(!add_WIN_cacerts_to_openssl_store(ctx)) { 146520237c55Ssthen log_crypto_err("error in add_WIN_cacerts_to_openssl_store"); 146620237c55Ssthen SSL_CTX_free(ctx); 146720237c55Ssthen return NULL; 146820237c55Ssthen } 146920237c55Ssthen } 147020237c55Ssthen #else 14710bdb4f62Ssthen if(wincert) { 14720bdb4f62Ssthen if(!SSL_CTX_set_default_verify_paths(ctx)) { 14730bdb4f62Ssthen log_crypto_err("error in default_verify_paths"); 14740bdb4f62Ssthen SSL_CTX_free(ctx); 14750bdb4f62Ssthen return NULL; 14760bdb4f62Ssthen } 14770bdb4f62Ssthen } 147820237c55Ssthen #endif 1479933707f3Ssthen SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 1480933707f3Ssthen } 1481933707f3Ssthen return ctx; 14823dcb24b8Ssthen #else 148320237c55Ssthen (void)key; (void)pem; (void)verifypem; (void)wincert; 14843dcb24b8Ssthen return NULL; 14853dcb24b8Ssthen #endif 1486933707f3Ssthen } 1487933707f3Ssthen 1488933707f3Ssthen void* incoming_ssl_fd(void* sslctx, int fd) 1489933707f3Ssthen { 14903dcb24b8Ssthen #ifdef HAVE_SSL 1491933707f3Ssthen SSL* ssl = SSL_new((SSL_CTX*)sslctx); 1492933707f3Ssthen if(!ssl) { 1493933707f3Ssthen log_crypto_err("could not SSL_new"); 1494933707f3Ssthen return NULL; 1495933707f3Ssthen } 1496933707f3Ssthen SSL_set_accept_state(ssl); 1497ebf5bb73Ssthen (void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY); 1498933707f3Ssthen if(!SSL_set_fd(ssl, fd)) { 1499933707f3Ssthen log_crypto_err("could not SSL_set_fd"); 1500933707f3Ssthen SSL_free(ssl); 1501933707f3Ssthen return NULL; 1502933707f3Ssthen } 1503933707f3Ssthen return ssl; 15043dcb24b8Ssthen #else 15053dcb24b8Ssthen (void)sslctx; (void)fd; 15063dcb24b8Ssthen return NULL; 15073dcb24b8Ssthen #endif 1508933707f3Ssthen } 1509933707f3Ssthen 1510933707f3Ssthen void* outgoing_ssl_fd(void* sslctx, int fd) 1511933707f3Ssthen { 15123dcb24b8Ssthen #ifdef HAVE_SSL 1513933707f3Ssthen SSL* ssl = SSL_new((SSL_CTX*)sslctx); 1514933707f3Ssthen if(!ssl) { 1515933707f3Ssthen log_crypto_err("could not SSL_new"); 1516933707f3Ssthen return NULL; 1517933707f3Ssthen } 1518933707f3Ssthen SSL_set_connect_state(ssl); 1519ebf5bb73Ssthen (void)SSL_set_mode(ssl, (long)SSL_MODE_AUTO_RETRY); 1520933707f3Ssthen if(!SSL_set_fd(ssl, fd)) { 1521933707f3Ssthen log_crypto_err("could not SSL_set_fd"); 1522933707f3Ssthen SSL_free(ssl); 1523933707f3Ssthen return NULL; 1524933707f3Ssthen } 1525933707f3Ssthen return ssl; 15263dcb24b8Ssthen #else 15273dcb24b8Ssthen (void)sslctx; (void)fd; 15283dcb24b8Ssthen return NULL; 15293dcb24b8Ssthen #endif 1530933707f3Ssthen } 1531229e174cSsthen 1532a3167c07Ssthen int check_auth_name_for_ssl(char* auth_name) 1533a3167c07Ssthen { 1534a3167c07Ssthen if(!auth_name) return 1; 1535a3167c07Ssthen #if defined(HAVE_SSL) && !defined(HAVE_SSL_SET1_HOST) && !defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) 1536a3167c07Ssthen log_err("the query has an auth_name %s, but libssl has no call to " 1537a3167c07Ssthen "perform TLS authentication. Remove that name from config " 1538a3167c07Ssthen "or upgrade the ssl crypto library.", auth_name); 1539a3167c07Ssthen return 0; 1540a3167c07Ssthen #else 1541a3167c07Ssthen return 1; 1542a3167c07Ssthen #endif 1543a3167c07Ssthen } 1544a3167c07Ssthen 1545a3167c07Ssthen /** set the authname on an SSL structure, SSL* ssl */ 1546a3167c07Ssthen int set_auth_name_on_ssl(void* ssl, char* auth_name, int use_sni) 1547a3167c07Ssthen { 1548a3167c07Ssthen if(!auth_name) return 1; 1549a3167c07Ssthen #ifdef HAVE_SSL 1550a3167c07Ssthen if(use_sni) { 1551a3167c07Ssthen (void)SSL_set_tlsext_host_name(ssl, auth_name); 1552a3167c07Ssthen } 1553a3167c07Ssthen #else 1554a3167c07Ssthen (void)ssl; 1555a3167c07Ssthen (void)use_sni; 1556a3167c07Ssthen #endif 1557a3167c07Ssthen #ifdef HAVE_SSL_SET1_HOST 1558a3167c07Ssthen SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); 1559a3167c07Ssthen /* setting the hostname makes openssl verify the 1560a3167c07Ssthen * host name in the x509 certificate in the 1561a3167c07Ssthen * SSL connection*/ 1562a3167c07Ssthen if(!SSL_set1_host(ssl, auth_name)) { 1563a3167c07Ssthen log_err("SSL_set1_host failed"); 1564a3167c07Ssthen return 0; 1565a3167c07Ssthen } 1566a3167c07Ssthen #elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) 1567a3167c07Ssthen /* openssl 1.0.2 has this function that can be used for 1568a3167c07Ssthen * set1_host like verification */ 1569a3167c07Ssthen if(auth_name) { 1570a3167c07Ssthen X509_VERIFY_PARAM* param = SSL_get0_param(ssl); 1571a3167c07Ssthen # ifdef X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 1572a3167c07Ssthen X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); 1573a3167c07Ssthen # endif 1574a3167c07Ssthen if(!X509_VERIFY_PARAM_set1_host(param, auth_name, strlen(auth_name))) { 1575a3167c07Ssthen log_err("X509_VERIFY_PARAM_set1_host failed"); 1576a3167c07Ssthen return 0; 1577a3167c07Ssthen } 1578a3167c07Ssthen SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); 1579a3167c07Ssthen } 1580a3167c07Ssthen #else 1581a3167c07Ssthen verbose(VERB_ALGO, "the query has an auth_name, but libssl has no call to perform TLS authentication"); 1582a3167c07Ssthen #endif /* HAVE_SSL_SET1_HOST */ 1583a3167c07Ssthen return 1; 1584a3167c07Ssthen } 1585a3167c07Ssthen 158677079be7Ssthen #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L 1587229e174cSsthen /** global lock list for openssl locks */ 158877079be7Ssthen static lock_basic_type *ub_openssl_locks = NULL; 1589229e174cSsthen 1590229e174cSsthen /** callback that gets thread id for openssl */ 1591c3b38330Ssthen #ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK 1592c3b38330Ssthen static void 1593c3b38330Ssthen ub_crypto_id_cb(CRYPTO_THREADID *id) 1594c3b38330Ssthen { 1595c3b38330Ssthen CRYPTO_THREADID_set_numeric(id, (unsigned long)log_thread_get()); 1596c3b38330Ssthen } 1597c3b38330Ssthen #else 1598229e174cSsthen static unsigned long 1599229e174cSsthen ub_crypto_id_cb(void) 1600229e174cSsthen { 1601a58bff56Ssthen return (unsigned long)log_thread_get(); 1602229e174cSsthen } 1603c3b38330Ssthen #endif 1604229e174cSsthen 1605229e174cSsthen static void 1606229e174cSsthen ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file), 1607229e174cSsthen int ATTR_UNUSED(line)) 1608229e174cSsthen { 1609229e174cSsthen if((mode&CRYPTO_LOCK)) { 1610229e174cSsthen lock_basic_lock(&ub_openssl_locks[type]); 1611229e174cSsthen } else { 1612229e174cSsthen lock_basic_unlock(&ub_openssl_locks[type]); 1613229e174cSsthen } 1614229e174cSsthen } 1615229e174cSsthen #endif /* OPENSSL_THREADS */ 1616229e174cSsthen 1617229e174cSsthen int ub_openssl_lock_init(void) 1618229e174cSsthen { 161977079be7Ssthen #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L 1620229e174cSsthen int i; 162177079be7Ssthen ub_openssl_locks = (lock_basic_type*)reallocarray( 162277079be7Ssthen NULL, (size_t)CRYPTO_num_locks(), sizeof(lock_basic_type)); 1623229e174cSsthen if(!ub_openssl_locks) 1624229e174cSsthen return 0; 1625229e174cSsthen for(i=0; i<CRYPTO_num_locks(); i++) { 1626229e174cSsthen lock_basic_init(&ub_openssl_locks[i]); 1627229e174cSsthen } 1628c3b38330Ssthen # ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK 1629c3b38330Ssthen CRYPTO_THREADID_set_callback(&ub_crypto_id_cb); 1630c3b38330Ssthen # else 1631229e174cSsthen CRYPTO_set_id_callback(&ub_crypto_id_cb); 1632c3b38330Ssthen # endif 1633229e174cSsthen CRYPTO_set_locking_callback(&ub_crypto_lock_cb); 1634229e174cSsthen #endif /* OPENSSL_THREADS */ 1635229e174cSsthen return 1; 1636229e174cSsthen } 1637229e174cSsthen 1638229e174cSsthen void ub_openssl_lock_delete(void) 1639229e174cSsthen { 164077079be7Ssthen #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L 1641229e174cSsthen int i; 1642229e174cSsthen if(!ub_openssl_locks) 1643229e174cSsthen return; 1644c3b38330Ssthen # ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK 1645c3b38330Ssthen CRYPTO_THREADID_set_callback(NULL); 1646c3b38330Ssthen # else 1647229e174cSsthen CRYPTO_set_id_callback(NULL); 1648c3b38330Ssthen # endif 1649229e174cSsthen CRYPTO_set_locking_callback(NULL); 1650229e174cSsthen for(i=0; i<CRYPTO_num_locks(); i++) { 1651229e174cSsthen lock_basic_destroy(&ub_openssl_locks[i]); 1652229e174cSsthen } 1653229e174cSsthen free(ub_openssl_locks); 1654229e174cSsthen #endif /* OPENSSL_THREADS */ 1655229e174cSsthen } 1656229e174cSsthen 1657f6b99bafSsthen int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_session_ticket_keys) { 1658f6b99bafSsthen #ifdef HAVE_SSL 1659f6b99bafSsthen size_t s = 1; 1660f6b99bafSsthen struct config_strlist* p; 1661f6b99bafSsthen struct tls_session_ticket_key *keys; 1662f6b99bafSsthen for(p = tls_session_ticket_keys; p; p = p->next) { 1663f6b99bafSsthen s++; 1664f6b99bafSsthen } 1665f6b99bafSsthen keys = calloc(s, sizeof(struct tls_session_ticket_key)); 1666eaf2578eSsthen if(!keys) 1667eaf2578eSsthen return 0; 1668f6b99bafSsthen memset(keys, 0, s*sizeof(*keys)); 1669f6b99bafSsthen ticket_keys = keys; 1670f6b99bafSsthen 1671f6b99bafSsthen for(p = tls_session_ticket_keys; p; p = p->next) { 1672f6b99bafSsthen size_t n; 1673eaf2578eSsthen unsigned char *data; 1674eaf2578eSsthen FILE *f; 1675eaf2578eSsthen 1676eaf2578eSsthen data = (unsigned char *)malloc(80); 1677eaf2578eSsthen if(!data) 1678eaf2578eSsthen return 0; 1679eaf2578eSsthen 1680a3167c07Ssthen f = fopen(p->str, "rb"); 1681f6b99bafSsthen if(!f) { 1682f6b99bafSsthen log_err("could not read tls-session-ticket-key %s: %s", p->str, strerror(errno)); 1683f6b99bafSsthen free(data); 1684f6b99bafSsthen return 0; 1685f6b99bafSsthen } 1686f6b99bafSsthen n = fread(data, 1, 80, f); 1687f6b99bafSsthen fclose(f); 1688f6b99bafSsthen 1689f6b99bafSsthen if(n != 80) { 1690f6b99bafSsthen log_err("tls-session-ticket-key %s is %d bytes, must be 80 bytes", p->str, (int)n); 1691f6b99bafSsthen free(data); 1692f6b99bafSsthen return 0; 1693f6b99bafSsthen } 1694f6b99bafSsthen verbose(VERB_OPS, "read tls-session-ticket-key: %s", p->str); 1695f6b99bafSsthen 1696f6b99bafSsthen keys->key_name = data; 1697f6b99bafSsthen keys->aes_key = data + 16; 1698f6b99bafSsthen keys->hmac_key = data + 48; 1699f6b99bafSsthen keys++; 1700f6b99bafSsthen } 1701f6b99bafSsthen /* terminate array with NULL key name entry */ 1702f6b99bafSsthen keys->key_name = NULL; 1703a3167c07Ssthen # ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB 1704a3167c07Ssthen if(SSL_CTX_set_tlsext_ticket_key_evp_cb(sslctx, tls_session_ticket_key_cb) == 0) { 1705a3167c07Ssthen log_err("no support for TLS session ticket"); 1706a3167c07Ssthen return 0; 1707a3167c07Ssthen } 1708a3167c07Ssthen # else 1709f6b99bafSsthen if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) { 1710f6b99bafSsthen log_err("no support for TLS session ticket"); 1711f6b99bafSsthen return 0; 1712f6b99bafSsthen } 1713a3167c07Ssthen # endif 1714f6b99bafSsthen return 1; 1715f6b99bafSsthen #else 1716f6b99bafSsthen (void)sslctx; 1717f6b99bafSsthen (void)tls_session_ticket_keys; 1718f6b99bafSsthen return 0; 1719f6b99bafSsthen #endif 1720f6b99bafSsthen 1721f6b99bafSsthen } 1722f6b99bafSsthen 1723a3167c07Ssthen #ifdef HAVE_SSL 1724a3167c07Ssthen int tls_session_ticket_key_cb(SSL *ATTR_UNUSED(sslctx), unsigned char* key_name, 1725a3167c07Ssthen unsigned char* iv, EVP_CIPHER_CTX *evp_sctx, 1726a3167c07Ssthen #ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB 1727a3167c07Ssthen EVP_MAC_CTX *hmac_ctx, 1728a3167c07Ssthen #else 1729a3167c07Ssthen HMAC_CTX* hmac_ctx, 1730a3167c07Ssthen #endif 1731a3167c07Ssthen int enc) 1732f6b99bafSsthen { 1733f6b99bafSsthen #ifdef HAVE_SSL 1734a3167c07Ssthen # ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB 1735a3167c07Ssthen OSSL_PARAM params[3]; 1736a3167c07Ssthen # else 1737f6b99bafSsthen const EVP_MD *digest; 1738a3167c07Ssthen # endif 1739f6b99bafSsthen const EVP_CIPHER *cipher; 1740f6b99bafSsthen int evp_cipher_length; 1741a3167c07Ssthen # ifndef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB 1742f6b99bafSsthen digest = EVP_sha256(); 1743a3167c07Ssthen # endif 1744f6b99bafSsthen cipher = EVP_aes_256_cbc(); 1745f6b99bafSsthen evp_cipher_length = EVP_CIPHER_iv_length(cipher); 1746f6b99bafSsthen if( enc == 1 ) { 1747f6b99bafSsthen /* encrypt */ 1748f6b99bafSsthen verbose(VERB_CLIENT, "start session encrypt"); 1749f6b99bafSsthen memcpy(key_name, ticket_keys->key_name, 16); 1750f6b99bafSsthen if (RAND_bytes(iv, evp_cipher_length) != 1) { 1751f6b99bafSsthen verbose(VERB_CLIENT, "RAND_bytes failed"); 1752f6b99bafSsthen return -1; 1753f6b99bafSsthen } 1754f6b99bafSsthen if (EVP_EncryptInit_ex(evp_sctx, cipher, NULL, ticket_keys->aes_key, iv) != 1) { 1755f6b99bafSsthen verbose(VERB_CLIENT, "EVP_EncryptInit_ex failed"); 1756f6b99bafSsthen return -1; 1757f6b99bafSsthen } 1758a3167c07Ssthen #ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB 1759a3167c07Ssthen params[0] = OSSL_PARAM_construct_octet_string(OSSL_MAC_PARAM_KEY, 1760a3167c07Ssthen ticket_keys->hmac_key, 32); 1761a3167c07Ssthen params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, 1762a3167c07Ssthen "sha256", 0); 1763a3167c07Ssthen params[2] = OSSL_PARAM_construct_end(); 17642c144df0Ssthen #ifdef HAVE_EVP_MAC_CTX_SET_PARAMS 17652c144df0Ssthen EVP_MAC_CTX_set_params(hmac_ctx, params); 17662c144df0Ssthen #else 1767a3167c07Ssthen EVP_MAC_set_ctx_params(hmac_ctx, params); 17682c144df0Ssthen #endif 1769a3167c07Ssthen #elif !defined(HMAC_INIT_EX_RETURNS_VOID) 1770f6b99bafSsthen if (HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL) != 1) { 1771f6b99bafSsthen verbose(VERB_CLIENT, "HMAC_Init_ex failed"); 1772f6b99bafSsthen return -1; 1773f6b99bafSsthen } 1774ebf5bb73Ssthen #else 1775ebf5bb73Ssthen HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL); 1776ebf5bb73Ssthen #endif 1777f6b99bafSsthen return 1; 1778f6b99bafSsthen } else if (enc == 0) { 1779f6b99bafSsthen /* decrypt */ 1780f6b99bafSsthen struct tls_session_ticket_key *key; 1781f6b99bafSsthen verbose(VERB_CLIENT, "start session decrypt"); 1782f6b99bafSsthen for(key = ticket_keys; key->key_name != NULL; key++) { 1783f6b99bafSsthen if (!memcmp(key_name, key->key_name, 16)) { 1784f6b99bafSsthen verbose(VERB_CLIENT, "Found session_key"); 1785f6b99bafSsthen break; 1786f6b99bafSsthen } 1787f6b99bafSsthen } 1788f6b99bafSsthen if(key->key_name == NULL) { 1789f6b99bafSsthen verbose(VERB_CLIENT, "Not found session_key"); 1790f6b99bafSsthen return 0; 1791f6b99bafSsthen } 1792f6b99bafSsthen 1793a3167c07Ssthen #ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB 1794a3167c07Ssthen params[0] = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, 1795a3167c07Ssthen key->hmac_key, 32); 1796a3167c07Ssthen params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, 1797a3167c07Ssthen "sha256", 0); 1798a3167c07Ssthen params[2] = OSSL_PARAM_construct_end(); 17992c144df0Ssthen #ifdef HAVE_EVP_MAC_CTX_SET_PARAMS 18002c144df0Ssthen EVP_MAC_CTX_set_params(hmac_ctx, params); 18012c144df0Ssthen #else 1802a3167c07Ssthen EVP_MAC_set_ctx_params(hmac_ctx, params); 18032c144df0Ssthen #endif 1804a3167c07Ssthen #elif !defined(HMAC_INIT_EX_RETURNS_VOID) 1805f6b99bafSsthen if (HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL) != 1) { 1806f6b99bafSsthen verbose(VERB_CLIENT, "HMAC_Init_ex failed"); 1807f6b99bafSsthen return -1; 1808f6b99bafSsthen } 1809ebf5bb73Ssthen #else 1810ebf5bb73Ssthen HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL); 1811ebf5bb73Ssthen #endif 1812f6b99bafSsthen if (EVP_DecryptInit_ex(evp_sctx, cipher, NULL, key->aes_key, iv) != 1) { 1813f6b99bafSsthen log_err("EVP_DecryptInit_ex failed"); 1814f6b99bafSsthen return -1; 1815f6b99bafSsthen } 1816f6b99bafSsthen 1817f6b99bafSsthen return (key == ticket_keys) ? 1 : 2; 1818f6b99bafSsthen } 1819f6b99bafSsthen return -1; 1820f6b99bafSsthen #else 1821f6b99bafSsthen (void)key_name; 1822f6b99bafSsthen (void)iv; 1823f6b99bafSsthen (void)evp_sctx; 1824f6b99bafSsthen (void)hmac_ctx; 1825f6b99bafSsthen (void)enc; 1826f6b99bafSsthen return 0; 1827f6b99bafSsthen #endif 1828f6b99bafSsthen } 1829a3167c07Ssthen #endif /* HAVE_SSL */ 1830f6b99bafSsthen 1831f6b99bafSsthen void 1832f6b99bafSsthen listen_sslctx_delete_ticket_keys(void) 1833f6b99bafSsthen { 1834f6b99bafSsthen struct tls_session_ticket_key *key; 1835f6b99bafSsthen if(!ticket_keys) return; 1836f6b99bafSsthen for(key = ticket_keys; key->key_name != NULL; key++) { 1837550cf4a9Ssthen /* wipe key data from memory*/ 1838550cf4a9Ssthen #ifdef HAVE_EXPLICIT_BZERO 1839550cf4a9Ssthen explicit_bzero(key->key_name, 80); 1840550cf4a9Ssthen #else 1841550cf4a9Ssthen memset(key->key_name, 0xdd, 80); 1842550cf4a9Ssthen #endif 1843f6b99bafSsthen free(key->key_name); 1844f6b99bafSsthen } 1845f6b99bafSsthen free(ticket_keys); 1846f6b99bafSsthen ticket_keys = NULL; 1847f6b99bafSsthen } 18482c144df0Ssthen 18492c144df0Ssthen # ifndef USE_WINSOCK 18502c144df0Ssthen char* 18512c144df0Ssthen sock_strerror(int errn) 18522c144df0Ssthen { 18532c144df0Ssthen return strerror(errn); 18542c144df0Ssthen } 18552c144df0Ssthen 18562c144df0Ssthen void 18572c144df0Ssthen sock_close(int socket) 18582c144df0Ssthen { 18592c144df0Ssthen close(socket); 18602c144df0Ssthen } 18612c144df0Ssthen 18622c144df0Ssthen # else 18632c144df0Ssthen char* 18642c144df0Ssthen sock_strerror(int ATTR_UNUSED(errn)) 18652c144df0Ssthen { 18662c144df0Ssthen return wsa_strerror(WSAGetLastError()); 18672c144df0Ssthen } 18682c144df0Ssthen 18692c144df0Ssthen void 18702c144df0Ssthen sock_close(int socket) 18712c144df0Ssthen { 18722c144df0Ssthen closesocket(socket); 18732c144df0Ssthen } 18742c144df0Ssthen # endif /* USE_WINSOCK */ 1875*98bc733bSsthen 1876*98bc733bSsthen ssize_t 1877*98bc733bSsthen hex_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) 1878*98bc733bSsthen { 1879*98bc733bSsthen static char hexdigits[] = { 1880*98bc733bSsthen '0', '1', '2', '3', '4', '5', '6', '7', 1881*98bc733bSsthen '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' 1882*98bc733bSsthen }; 1883*98bc733bSsthen size_t i; 1884*98bc733bSsthen 1885*98bc733bSsthen if (targsize < srclength * 2 + 1) { 1886*98bc733bSsthen return -1; 1887*98bc733bSsthen } 1888*98bc733bSsthen 1889*98bc733bSsthen for (i = 0; i < srclength; ++i) { 1890*98bc733bSsthen *target++ = hexdigits[src[i] >> 4U]; 1891*98bc733bSsthen *target++ = hexdigits[src[i] & 0xfU]; 1892*98bc733bSsthen } 1893*98bc733bSsthen *target = '\0'; 1894*98bc733bSsthen return 2 * srclength; 1895*98bc733bSsthen } 1896*98bc733bSsthen 1897*98bc733bSsthen ssize_t 1898*98bc733bSsthen hex_pton(const char* src, uint8_t* target, size_t targsize) 1899*98bc733bSsthen { 1900*98bc733bSsthen uint8_t *t = target; 1901*98bc733bSsthen if(strlen(src) % 2 != 0 || strlen(src)/2 > targsize) { 1902*98bc733bSsthen return -1; 1903*98bc733bSsthen } 1904*98bc733bSsthen while(*src) { 1905*98bc733bSsthen if(!isxdigit((unsigned char)src[0]) || 1906*98bc733bSsthen !isxdigit((unsigned char)src[1])) 1907*98bc733bSsthen return -1; 1908*98bc733bSsthen *t++ = sldns_hexdigit_to_int(src[0]) * 16 + 1909*98bc733bSsthen sldns_hexdigit_to_int(src[1]) ; 1910*98bc733bSsthen src += 2; 1911*98bc733bSsthen } 1912*98bc733bSsthen return t-target; 1913*98bc733bSsthen } 1914