1 /* 2 * util/net_help.c - implementation of the network helper code 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * Neither the name of the NLNET LABS nor the names of its contributors may 20 * be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 /** 36 * \file 37 * Implementation of net_help.h. 38 */ 39 40 #include "config.h" 41 #include "util/net_help.h" 42 #include "util/log.h" 43 #include "util/data/dname.h" 44 #include "util/module.h" 45 #include "util/regional.h" 46 #include "sldns/parseutil.h" 47 #include "sldns/wire2str.h" 48 #include <fcntl.h> 49 #ifdef HAVE_OPENSSL_SSL_H 50 #include <openssl/ssl.h> 51 #endif 52 #ifdef HAVE_OPENSSL_ERR_H 53 #include <openssl/err.h> 54 #endif 55 56 /** max length of an IP address (the address portion) that we allow */ 57 #define MAX_ADDR_STRLEN 128 /* characters */ 58 /** default value for EDNS ADVERTISED size */ 59 uint16_t EDNS_ADVERTISED_SIZE = 4096; 60 61 /** minimal responses when positive answer: default is no */ 62 int MINIMAL_RESPONSES = 0; 63 64 /** rrset order roundrobin: default is no */ 65 int RRSET_ROUNDROBIN = 0; 66 67 /* returns true is string addr is an ip6 specced address */ 68 int 69 str_is_ip6(const char* str) 70 { 71 if(strchr(str, ':')) 72 return 1; 73 else return 0; 74 } 75 76 int 77 fd_set_nonblock(int s) 78 { 79 #ifdef HAVE_FCNTL 80 int flag; 81 if((flag = fcntl(s, F_GETFL)) == -1) { 82 log_err("can't fcntl F_GETFL: %s", strerror(errno)); 83 flag = 0; 84 } 85 flag |= O_NONBLOCK; 86 if(fcntl(s, F_SETFL, flag) == -1) { 87 log_err("can't fcntl F_SETFL: %s", strerror(errno)); 88 return 0; 89 } 90 #elif defined(HAVE_IOCTLSOCKET) 91 unsigned long on = 1; 92 if(ioctlsocket(s, FIONBIO, &on) != 0) { 93 log_err("can't ioctlsocket FIONBIO on: %s", 94 wsa_strerror(WSAGetLastError())); 95 } 96 #endif 97 return 1; 98 } 99 100 int 101 fd_set_block(int s) 102 { 103 #ifdef HAVE_FCNTL 104 int flag; 105 if((flag = fcntl(s, F_GETFL)) == -1) { 106 log_err("cannot fcntl F_GETFL: %s", strerror(errno)); 107 flag = 0; 108 } 109 flag &= ~O_NONBLOCK; 110 if(fcntl(s, F_SETFL, flag) == -1) { 111 log_err("cannot fcntl F_SETFL: %s", strerror(errno)); 112 return 0; 113 } 114 #elif defined(HAVE_IOCTLSOCKET) 115 unsigned long off = 0; 116 if(ioctlsocket(s, FIONBIO, &off) != 0) { 117 log_err("can't ioctlsocket FIONBIO off: %s", 118 wsa_strerror(WSAGetLastError())); 119 } 120 #endif 121 return 1; 122 } 123 124 int 125 is_pow2(size_t num) 126 { 127 if(num == 0) return 1; 128 return (num & (num-1)) == 0; 129 } 130 131 void* 132 memdup(void* data, size_t len) 133 { 134 void* d; 135 if(!data) return NULL; 136 if(len == 0) return NULL; 137 d = malloc(len); 138 if(!d) return NULL; 139 memcpy(d, data, len); 140 return d; 141 } 142 143 void 144 log_addr(enum verbosity_value v, const char* str, 145 struct sockaddr_storage* addr, socklen_t addrlen) 146 { 147 uint16_t port; 148 const char* family = "unknown"; 149 char dest[100]; 150 int af = (int)((struct sockaddr_in*)addr)->sin_family; 151 void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 152 if(verbosity < v) 153 return; 154 switch(af) { 155 case AF_INET: family="ip4"; break; 156 case AF_INET6: family="ip6"; 157 sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; 158 break; 159 case AF_LOCAL: 160 dest[0]=0; 161 (void)inet_ntop(af, sinaddr, dest, 162 (socklen_t)sizeof(dest)); 163 verbose(v, "%s local %s", str, dest); 164 return; /* do not continue and try to get port */ 165 default: break; 166 } 167 if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) { 168 (void)strlcpy(dest, "(inet_ntop error)", sizeof(dest)); 169 } 170 dest[sizeof(dest)-1] = 0; 171 port = ntohs(((struct sockaddr_in*)addr)->sin_port); 172 if(verbosity >= 4) 173 verbose(v, "%s %s %s port %d (len %d)", str, family, dest, 174 (int)port, (int)addrlen); 175 else verbose(v, "%s %s port %d", str, dest, (int)port); 176 } 177 178 int 179 extstrtoaddr(const char* str, struct sockaddr_storage* addr, 180 socklen_t* addrlen) 181 { 182 char* s; 183 int port = UNBOUND_DNS_PORT; 184 if((s=strchr(str, '@'))) { 185 char buf[MAX_ADDR_STRLEN]; 186 if(s-str >= MAX_ADDR_STRLEN) { 187 return 0; 188 } 189 (void)strlcpy(buf, str, sizeof(buf)); 190 buf[s-str] = 0; 191 port = atoi(s+1); 192 if(port == 0 && strcmp(s+1,"0")!=0) { 193 return 0; 194 } 195 return ipstrtoaddr(buf, port, addr, addrlen); 196 } 197 return ipstrtoaddr(str, port, addr, addrlen); 198 } 199 200 201 int 202 ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr, 203 socklen_t* addrlen) 204 { 205 uint16_t p; 206 if(!ip) return 0; 207 p = (uint16_t) port; 208 if(str_is_ip6(ip)) { 209 char buf[MAX_ADDR_STRLEN]; 210 char* s; 211 struct sockaddr_in6* sa = (struct sockaddr_in6*)addr; 212 *addrlen = (socklen_t)sizeof(struct sockaddr_in6); 213 memset(sa, 0, *addrlen); 214 sa->sin6_family = AF_INET6; 215 sa->sin6_port = (in_port_t)htons(p); 216 if((s=strchr(ip, '%'))) { /* ip6%interface, rfc 4007 */ 217 if(s-ip >= MAX_ADDR_STRLEN) 218 return 0; 219 (void)strlcpy(buf, ip, sizeof(buf)); 220 buf[s-ip]=0; 221 sa->sin6_scope_id = (uint32_t)atoi(s+1); 222 ip = buf; 223 } 224 if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) { 225 return 0; 226 } 227 } else { /* ip4 */ 228 struct sockaddr_in* sa = (struct sockaddr_in*)addr; 229 *addrlen = (socklen_t)sizeof(struct sockaddr_in); 230 memset(sa, 0, *addrlen); 231 sa->sin_family = AF_INET; 232 sa->sin_port = (in_port_t)htons(p); 233 if(inet_pton((int)sa->sin_family, ip, &sa->sin_addr) <= 0) { 234 return 0; 235 } 236 } 237 return 1; 238 } 239 240 int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr, 241 socklen_t* addrlen, int* net) 242 { 243 char* s = NULL; 244 *net = (str_is_ip6(str)?128:32); 245 if((s=strchr(str, '/'))) { 246 if(atoi(s+1) > *net) { 247 log_err("netblock too large: %s", str); 248 return 0; 249 } 250 *net = atoi(s+1); 251 if(*net == 0 && strcmp(s+1, "0") != 0) { 252 log_err("cannot parse netblock: '%s'", str); 253 return 0; 254 } 255 if(!(s = strdup(str))) { 256 log_err("out of memory"); 257 return 0; 258 } 259 *strchr(s, '/') = '\0'; 260 } 261 if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) { 262 free(s); 263 log_err("cannot parse ip address: '%s'", str); 264 return 0; 265 } 266 if(s) { 267 free(s); 268 addr_mask(addr, *addrlen, *net); 269 } 270 return 1; 271 } 272 273 void 274 log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, 275 uint16_t type, uint16_t dclass) 276 { 277 char buf[LDNS_MAX_DOMAINLEN+1]; 278 char t[12], c[12]; 279 const char *ts, *cs; 280 if(verbosity < v) 281 return; 282 dname_str(name, buf); 283 if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG"; 284 else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR"; 285 else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR"; 286 else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB"; 287 else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA"; 288 else if(type == LDNS_RR_TYPE_ANY) ts = "ANY"; 289 else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name) 290 ts = sldns_rr_descript(type)->_name; 291 else { 292 snprintf(t, sizeof(t), "TYPE%d", (int)type); 293 ts = t; 294 } 295 if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) && 296 sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name) 297 cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name; 298 else { 299 snprintf(c, sizeof(c), "CLASS%d", (int)dclass); 300 cs = c; 301 } 302 log_info("%s %s %s %s", str, buf, ts, cs); 303 } 304 305 void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, 306 struct sockaddr_storage* addr, socklen_t addrlen) 307 { 308 uint16_t port; 309 const char* family = "unknown_family "; 310 char namebuf[LDNS_MAX_DOMAINLEN+1]; 311 char dest[100]; 312 int af = (int)((struct sockaddr_in*)addr)->sin_family; 313 void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 314 if(verbosity < v) 315 return; 316 switch(af) { 317 case AF_INET: family=""; break; 318 case AF_INET6: family=""; 319 sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; 320 break; 321 case AF_LOCAL: family="local "; break; 322 default: break; 323 } 324 if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) { 325 (void)strlcpy(dest, "(inet_ntop error)", sizeof(dest)); 326 } 327 dest[sizeof(dest)-1] = 0; 328 port = ntohs(((struct sockaddr_in*)addr)->sin_port); 329 dname_str(zone, namebuf); 330 if(af != AF_INET && af != AF_INET6) 331 verbose(v, "%s <%s> %s%s#%d (addrlen %d)", 332 str, namebuf, family, dest, (int)port, (int)addrlen); 333 else verbose(v, "%s <%s> %s%s#%d", 334 str, namebuf, family, dest, (int)port); 335 } 336 337 void log_err_addr(const char* str, const char* err, 338 struct sockaddr_storage* addr, socklen_t addrlen) 339 { 340 uint16_t port; 341 char dest[100]; 342 int af = (int)((struct sockaddr_in*)addr)->sin_family; 343 void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 344 if(af == AF_INET6) 345 sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; 346 if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) { 347 (void)strlcpy(dest, "(inet_ntop error)", sizeof(dest)); 348 } 349 dest[sizeof(dest)-1] = 0; 350 port = ntohs(((struct sockaddr_in*)addr)->sin_port); 351 if(verbosity >= 4) 352 log_err("%s: %s for %s port %d (len %d)", str, err, dest, 353 (int)port, (int)addrlen); 354 else log_err("%s: %s for %s", str, err, dest); 355 } 356 357 int 358 sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1, 359 struct sockaddr_storage* addr2, socklen_t len2) 360 { 361 struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1; 362 struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2; 363 struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1; 364 struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2; 365 if(len1 < len2) 366 return -1; 367 if(len1 > len2) 368 return 1; 369 log_assert(len1 == len2); 370 if( p1_in->sin_family < p2_in->sin_family) 371 return -1; 372 if( p1_in->sin_family > p2_in->sin_family) 373 return 1; 374 log_assert( p1_in->sin_family == p2_in->sin_family ); 375 /* compare ip4 */ 376 if( p1_in->sin_family == AF_INET ) { 377 /* just order it, ntohs not required */ 378 if(p1_in->sin_port < p2_in->sin_port) 379 return -1; 380 if(p1_in->sin_port > p2_in->sin_port) 381 return 1; 382 log_assert(p1_in->sin_port == p2_in->sin_port); 383 return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); 384 } else if (p1_in6->sin6_family == AF_INET6) { 385 /* just order it, ntohs not required */ 386 if(p1_in6->sin6_port < p2_in6->sin6_port) 387 return -1; 388 if(p1_in6->sin6_port > p2_in6->sin6_port) 389 return 1; 390 log_assert(p1_in6->sin6_port == p2_in6->sin6_port); 391 return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, 392 INET6_SIZE); 393 } else { 394 /* eek unknown type, perform this comparison for sanity. */ 395 return memcmp(addr1, addr2, len1); 396 } 397 } 398 399 int 400 sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1, 401 struct sockaddr_storage* addr2, socklen_t len2) 402 { 403 struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1; 404 struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2; 405 struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1; 406 struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2; 407 if(len1 < len2) 408 return -1; 409 if(len1 > len2) 410 return 1; 411 log_assert(len1 == len2); 412 if( p1_in->sin_family < p2_in->sin_family) 413 return -1; 414 if( p1_in->sin_family > p2_in->sin_family) 415 return 1; 416 log_assert( p1_in->sin_family == p2_in->sin_family ); 417 /* compare ip4 */ 418 if( p1_in->sin_family == AF_INET ) { 419 return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); 420 } else if (p1_in6->sin6_family == AF_INET6) { 421 return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, 422 INET6_SIZE); 423 } else { 424 /* eek unknown type, perform this comparison for sanity. */ 425 return memcmp(addr1, addr2, len1); 426 } 427 } 428 429 int 430 addr_is_ip6(struct sockaddr_storage* addr, socklen_t len) 431 { 432 if(len == (socklen_t)sizeof(struct sockaddr_in6) && 433 ((struct sockaddr_in6*)addr)->sin6_family == AF_INET6) 434 return 1; 435 else return 0; 436 } 437 438 void 439 addr_mask(struct sockaddr_storage* addr, socklen_t len, int net) 440 { 441 uint8_t mask[8] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe}; 442 int i, max; 443 uint8_t* s; 444 if(addr_is_ip6(addr, len)) { 445 s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr; 446 max = 128; 447 } else { 448 s = (uint8_t*)&((struct sockaddr_in*)addr)->sin_addr; 449 max = 32; 450 } 451 if(net >= max) 452 return; 453 for(i=net/8+1; i<max/8; i++) { 454 s[i] = 0; 455 } 456 s[net/8] &= mask[net&0x7]; 457 } 458 459 int 460 addr_in_common(struct sockaddr_storage* addr1, int net1, 461 struct sockaddr_storage* addr2, int net2, socklen_t addrlen) 462 { 463 int min = (net1<net2)?net1:net2; 464 int i, to; 465 int match = 0; 466 uint8_t* s1, *s2; 467 if(addr_is_ip6(addr1, addrlen)) { 468 s1 = (uint8_t*)&((struct sockaddr_in6*)addr1)->sin6_addr; 469 s2 = (uint8_t*)&((struct sockaddr_in6*)addr2)->sin6_addr; 470 to = 16; 471 } else { 472 s1 = (uint8_t*)&((struct sockaddr_in*)addr1)->sin_addr; 473 s2 = (uint8_t*)&((struct sockaddr_in*)addr2)->sin_addr; 474 to = 4; 475 } 476 /* match = bits_in_common(s1, s2, to); */ 477 for(i=0; i<to; i++) { 478 if(s1[i] == s2[i]) { 479 match += 8; 480 } else { 481 uint8_t z = s1[i]^s2[i]; 482 log_assert(z); 483 while(!(z&0x80)) { 484 match++; 485 z<<=1; 486 } 487 break; 488 } 489 } 490 if(match > min) match = min; 491 return match; 492 } 493 494 void 495 addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen, 496 char* buf, size_t len) 497 { 498 int af = (int)((struct sockaddr_in*)addr)->sin_family; 499 void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 500 if(addr_is_ip6(addr, addrlen)) 501 sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; 502 if(inet_ntop(af, sinaddr, buf, (socklen_t)len) == 0) { 503 snprintf(buf, len, "(inet_ntop_error)"); 504 } 505 } 506 507 int 508 addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen) 509 { 510 /* prefix for ipv4 into ipv6 mapping is ::ffff:x.x.x.x */ 511 const uint8_t map_prefix[16] = 512 {0,0,0,0, 0,0,0,0, 0,0,0xff,0xff, 0,0,0,0}; 513 uint8_t* s; 514 if(!addr_is_ip6(addr, addrlen)) 515 return 0; 516 /* s is 16 octet ipv6 address string */ 517 s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr; 518 return (memcmp(s, map_prefix, 12) == 0); 519 } 520 521 int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen) 522 { 523 int af = (int)((struct sockaddr_in*)addr)->sin_family; 524 void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 525 return af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in) 526 && memcmp(sinaddr, "\377\377\377\377", 4) == 0; 527 } 528 529 int addr_is_any(struct sockaddr_storage* addr, socklen_t addrlen) 530 { 531 int af = (int)((struct sockaddr_in*)addr)->sin_family; 532 void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 533 void* sin6addr = &((struct sockaddr_in6*)addr)->sin6_addr; 534 if(af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in) 535 && memcmp(sinaddr, "\000\000\000\000", 4) == 0) 536 return 1; 537 else if(af==AF_INET6 && addrlen>=(socklen_t)sizeof(struct sockaddr_in6) 538 && memcmp(sin6addr, "\000\000\000\000\000\000\000\000" 539 "\000\000\000\000\000\000\000\000", 16) == 0) 540 return 1; 541 return 0; 542 } 543 544 void sock_list_insert(struct sock_list** list, struct sockaddr_storage* addr, 545 socklen_t len, struct regional* region) 546 { 547 struct sock_list* add = (struct sock_list*)regional_alloc(region, 548 sizeof(*add) - sizeof(add->addr) + (size_t)len); 549 if(!add) { 550 log_err("out of memory in socketlist insert"); 551 return; 552 } 553 log_assert(list); 554 add->next = *list; 555 add->len = len; 556 *list = add; 557 if(len) memmove(&add->addr, addr, len); 558 } 559 560 void sock_list_prepend(struct sock_list** list, struct sock_list* add) 561 { 562 struct sock_list* last = add; 563 if(!last) 564 return; 565 while(last->next) 566 last = last->next; 567 last->next = *list; 568 *list = add; 569 } 570 571 int sock_list_find(struct sock_list* list, struct sockaddr_storage* addr, 572 socklen_t len) 573 { 574 while(list) { 575 if(len == list->len) { 576 if(len == 0 || sockaddr_cmp_addr(addr, len, 577 &list->addr, list->len) == 0) 578 return 1; 579 } 580 list = list->next; 581 } 582 return 0; 583 } 584 585 void sock_list_merge(struct sock_list** list, struct regional* region, 586 struct sock_list* add) 587 { 588 struct sock_list* p; 589 for(p=add; p; p=p->next) { 590 if(!sock_list_find(*list, &p->addr, p->len)) 591 sock_list_insert(list, &p->addr, p->len, region); 592 } 593 } 594 595 void 596 log_crypto_err(const char* str) 597 { 598 #ifdef HAVE_SSL 599 /* error:[error code]:[library name]:[function name]:[reason string] */ 600 char buf[128]; 601 unsigned long e; 602 ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); 603 log_err("%s crypto %s", str, buf); 604 while( (e=ERR_get_error()) ) { 605 ERR_error_string_n(e, buf, sizeof(buf)); 606 log_err("and additionally crypto %s", buf); 607 } 608 #else 609 (void)str; 610 #endif /* HAVE_SSL */ 611 } 612 613 void* listen_sslctx_create(char* key, char* pem, char* verifypem) 614 { 615 #ifdef HAVE_SSL 616 SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method()); 617 if(!ctx) { 618 log_crypto_err("could not SSL_CTX_new"); 619 return NULL; 620 } 621 /* no SSLv2, SSLv3 because has defects */ 622 if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) 623 != SSL_OP_NO_SSLv2){ 624 log_crypto_err("could not set SSL_OP_NO_SSLv2"); 625 SSL_CTX_free(ctx); 626 return NULL; 627 } 628 if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) 629 != SSL_OP_NO_SSLv3){ 630 log_crypto_err("could not set SSL_OP_NO_SSLv3"); 631 SSL_CTX_free(ctx); 632 return NULL; 633 } 634 if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) { 635 log_err("error for cert file: %s", pem); 636 log_crypto_err("error in SSL_CTX use_certificate_chain_file"); 637 SSL_CTX_free(ctx); 638 return NULL; 639 } 640 if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) { 641 log_err("error for private key file: %s", key); 642 log_crypto_err("Error in SSL_CTX use_PrivateKey_file"); 643 SSL_CTX_free(ctx); 644 return NULL; 645 } 646 if(!SSL_CTX_check_private_key(ctx)) { 647 log_err("error for key file: %s", key); 648 log_crypto_err("Error in SSL_CTX check_private_key"); 649 SSL_CTX_free(ctx); 650 return NULL; 651 } 652 #if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO 653 if(!SSL_CTX_set_ecdh_auto(ctx,1)) { 654 log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE"); 655 } 656 #elif defined(USE_ECDSA) 657 if(1) { 658 EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1); 659 if (!ecdh) { 660 log_crypto_err("could not find p256, not enabling ECDHE"); 661 } else { 662 if (1 != SSL_CTX_set_tmp_ecdh (ctx, ecdh)) { 663 log_crypto_err("Error in SSL_CTX_set_tmp_ecdh, not enabling ECDHE"); 664 } 665 EC_KEY_free (ecdh); 666 } 667 } 668 #endif 669 670 if(verifypem && verifypem[0]) { 671 if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { 672 log_crypto_err("Error in SSL_CTX verify locations"); 673 SSL_CTX_free(ctx); 674 return NULL; 675 } 676 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file( 677 verifypem)); 678 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 679 } 680 return ctx; 681 #else 682 (void)key; (void)pem; (void)verifypem; 683 return NULL; 684 #endif 685 } 686 687 void* connect_sslctx_create(char* key, char* pem, char* verifypem) 688 { 689 #ifdef HAVE_SSL 690 SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method()); 691 if(!ctx) { 692 log_crypto_err("could not allocate SSL_CTX pointer"); 693 return NULL; 694 } 695 if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) 696 != SSL_OP_NO_SSLv2) { 697 log_crypto_err("could not set SSL_OP_NO_SSLv2"); 698 SSL_CTX_free(ctx); 699 return NULL; 700 } 701 if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) 702 != SSL_OP_NO_SSLv3) { 703 log_crypto_err("could not set SSL_OP_NO_SSLv3"); 704 SSL_CTX_free(ctx); 705 return NULL; 706 } 707 if(key && key[0]) { 708 if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) { 709 log_err("error in client certificate %s", pem); 710 log_crypto_err("error in certificate file"); 711 SSL_CTX_free(ctx); 712 return NULL; 713 } 714 if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) { 715 log_err("error in client private key %s", key); 716 log_crypto_err("error in key file"); 717 SSL_CTX_free(ctx); 718 return NULL; 719 } 720 if(!SSL_CTX_check_private_key(ctx)) { 721 log_err("error in client key %s", key); 722 log_crypto_err("error in SSL_CTX_check_private_key"); 723 SSL_CTX_free(ctx); 724 return NULL; 725 } 726 } 727 if(verifypem && verifypem[0]) { 728 if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { 729 log_crypto_err("error in SSL_CTX verify"); 730 SSL_CTX_free(ctx); 731 return NULL; 732 } 733 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 734 } 735 return ctx; 736 #else 737 (void)key; (void)pem; (void)verifypem; 738 return NULL; 739 #endif 740 } 741 742 void* incoming_ssl_fd(void* sslctx, int fd) 743 { 744 #ifdef HAVE_SSL 745 SSL* ssl = SSL_new((SSL_CTX*)sslctx); 746 if(!ssl) { 747 log_crypto_err("could not SSL_new"); 748 return NULL; 749 } 750 SSL_set_accept_state(ssl); 751 (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); 752 if(!SSL_set_fd(ssl, fd)) { 753 log_crypto_err("could not SSL_set_fd"); 754 SSL_free(ssl); 755 return NULL; 756 } 757 return ssl; 758 #else 759 (void)sslctx; (void)fd; 760 return NULL; 761 #endif 762 } 763 764 void* outgoing_ssl_fd(void* sslctx, int fd) 765 { 766 #ifdef HAVE_SSL 767 SSL* ssl = SSL_new((SSL_CTX*)sslctx); 768 if(!ssl) { 769 log_crypto_err("could not SSL_new"); 770 return NULL; 771 } 772 SSL_set_connect_state(ssl); 773 (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); 774 if(!SSL_set_fd(ssl, fd)) { 775 log_crypto_err("could not SSL_set_fd"); 776 SSL_free(ssl); 777 return NULL; 778 } 779 return ssl; 780 #else 781 (void)sslctx; (void)fd; 782 return NULL; 783 #endif 784 } 785 786 #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L 787 /** global lock list for openssl locks */ 788 static lock_basic_t *ub_openssl_locks = NULL; 789 790 /** callback that gets thread id for openssl */ 791 static unsigned long 792 ub_crypto_id_cb(void) 793 { 794 return (unsigned long)log_thread_get(); 795 } 796 797 static void 798 ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file), 799 int ATTR_UNUSED(line)) 800 { 801 if((mode&CRYPTO_LOCK)) { 802 lock_basic_lock(&ub_openssl_locks[type]); 803 } else { 804 lock_basic_unlock(&ub_openssl_locks[type]); 805 } 806 } 807 #endif /* OPENSSL_THREADS */ 808 809 int ub_openssl_lock_init(void) 810 { 811 #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L 812 int i; 813 ub_openssl_locks = (lock_basic_t*)reallocarray( 814 NULL, (size_t)CRYPTO_num_locks(), sizeof(lock_basic_t)); 815 if(!ub_openssl_locks) 816 return 0; 817 for(i=0; i<CRYPTO_num_locks(); i++) { 818 lock_basic_init(&ub_openssl_locks[i]); 819 } 820 CRYPTO_set_id_callback(&ub_crypto_id_cb); 821 CRYPTO_set_locking_callback(&ub_crypto_lock_cb); 822 #endif /* OPENSSL_THREADS */ 823 return 1; 824 } 825 826 void ub_openssl_lock_delete(void) 827 { 828 #if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L 829 int i; 830 if(!ub_openssl_locks) 831 return; 832 CRYPTO_set_id_callback(NULL); 833 CRYPTO_set_locking_callback(NULL); 834 for(i=0; i<CRYPTO_num_locks(); i++) { 835 lock_basic_destroy(&ub_openssl_locks[i]); 836 } 837 free(ub_openssl_locks); 838 #endif /* OPENSSL_THREADS */ 839 } 840 841