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 LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 /** 36 * \file 37 * Implementation of net_help.h. 38 */ 39 40 #include "config.h" 41 #include <ldns/ldns.h> 42 #include "util/net_help.h" 43 #include "util/log.h" 44 #include "util/data/dname.h" 45 #include "util/module.h" 46 #include "util/regional.h" 47 #include <fcntl.h> 48 #include <openssl/ssl.h> 49 #include <openssl/err.h> 50 51 /** max length of an IP address (the address portion) that we allow */ 52 #define MAX_ADDR_STRLEN 128 /* characters */ 53 /** default value for EDNS ADVERTISED size */ 54 uint16_t EDNS_ADVERTISED_SIZE = 4096; 55 56 /** minimal responses when positive answer: default is no */ 57 int MINIMAL_RESPONSES = 0; 58 59 /** rrset order roundrobin: default is no */ 60 int RRSET_ROUNDROBIN = 0; 61 62 /* returns true is string addr is an ip6 specced address */ 63 int 64 str_is_ip6(const char* str) 65 { 66 if(strchr(str, ':')) 67 return 1; 68 else return 0; 69 } 70 71 int 72 fd_set_nonblock(int s) 73 { 74 #ifdef HAVE_FCNTL 75 int flag; 76 if((flag = fcntl(s, F_GETFL)) == -1) { 77 log_err("can't fcntl F_GETFL: %s", strerror(errno)); 78 flag = 0; 79 } 80 flag |= O_NONBLOCK; 81 if(fcntl(s, F_SETFL, flag) == -1) { 82 log_err("can't fcntl F_SETFL: %s", strerror(errno)); 83 return 0; 84 } 85 #elif defined(HAVE_IOCTLSOCKET) 86 unsigned long on = 1; 87 if(ioctlsocket(s, FIONBIO, &on) != 0) { 88 log_err("can't ioctlsocket FIONBIO on: %s", 89 wsa_strerror(WSAGetLastError())); 90 } 91 #endif 92 return 1; 93 } 94 95 int 96 fd_set_block(int s) 97 { 98 #ifdef HAVE_FCNTL 99 int flag; 100 if((flag = fcntl(s, F_GETFL)) == -1) { 101 log_err("cannot fcntl F_GETFL: %s", strerror(errno)); 102 flag = 0; 103 } 104 flag &= ~O_NONBLOCK; 105 if(fcntl(s, F_SETFL, flag) == -1) { 106 log_err("cannot fcntl F_SETFL: %s", strerror(errno)); 107 return 0; 108 } 109 #elif defined(HAVE_IOCTLSOCKET) 110 unsigned long off = 0; 111 if(ioctlsocket(s, FIONBIO, &off) != 0) { 112 log_err("can't ioctlsocket FIONBIO off: %s", 113 wsa_strerror(WSAGetLastError())); 114 } 115 #endif 116 return 1; 117 } 118 119 int 120 is_pow2(size_t num) 121 { 122 if(num == 0) return 1; 123 return (num & (num-1)) == 0; 124 } 125 126 void* 127 memdup(void* data, size_t len) 128 { 129 void* d; 130 if(!data) return NULL; 131 if(len == 0) return NULL; 132 d = malloc(len); 133 if(!d) return NULL; 134 memcpy(d, data, len); 135 return d; 136 } 137 138 void 139 log_addr(enum verbosity_value v, const char* str, 140 struct sockaddr_storage* addr, socklen_t addrlen) 141 { 142 uint16_t port; 143 const char* family = "unknown"; 144 char dest[100]; 145 int af = (int)((struct sockaddr_in*)addr)->sin_family; 146 void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 147 if(verbosity < v) 148 return; 149 switch(af) { 150 case AF_INET: family="ip4"; break; 151 case AF_INET6: family="ip6"; 152 sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; 153 break; 154 case AF_UNIX: family="unix"; break; 155 default: break; 156 } 157 if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) { 158 strncpy(dest, "(inet_ntop error)", sizeof(dest)); 159 } 160 dest[sizeof(dest)-1] = 0; 161 port = ntohs(((struct sockaddr_in*)addr)->sin_port); 162 if(verbosity >= 4) 163 verbose(v, "%s %s %s port %d (len %d)", str, family, dest, 164 (int)port, (int)addrlen); 165 else verbose(v, "%s %s port %d", str, dest, (int)port); 166 } 167 168 int 169 extstrtoaddr(const char* str, struct sockaddr_storage* addr, 170 socklen_t* addrlen) 171 { 172 char* s; 173 int port = UNBOUND_DNS_PORT; 174 if((s=strchr(str, '@'))) { 175 char buf[MAX_ADDR_STRLEN]; 176 if(s-str >= MAX_ADDR_STRLEN) { 177 return 0; 178 } 179 strncpy(buf, str, MAX_ADDR_STRLEN); 180 buf[s-str] = 0; 181 port = atoi(s+1); 182 if(port == 0 && strcmp(s+1,"0")!=0) { 183 return 0; 184 } 185 return ipstrtoaddr(buf, port, addr, addrlen); 186 } 187 return ipstrtoaddr(str, port, addr, addrlen); 188 } 189 190 191 int 192 ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr, 193 socklen_t* addrlen) 194 { 195 uint16_t p; 196 if(!ip) return 0; 197 p = (uint16_t) port; 198 if(str_is_ip6(ip)) { 199 char buf[MAX_ADDR_STRLEN]; 200 char* s; 201 struct sockaddr_in6* sa = (struct sockaddr_in6*)addr; 202 *addrlen = (socklen_t)sizeof(struct sockaddr_in6); 203 memset(sa, 0, *addrlen); 204 sa->sin6_family = AF_INET6; 205 sa->sin6_port = (in_port_t)htons(p); 206 if((s=strchr(ip, '%'))) { /* ip6%interface, rfc 4007 */ 207 if(s-ip >= MAX_ADDR_STRLEN) 208 return 0; 209 strncpy(buf, ip, MAX_ADDR_STRLEN); 210 buf[s-ip]=0; 211 sa->sin6_scope_id = (uint32_t)atoi(s+1); 212 ip = buf; 213 } 214 if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) { 215 return 0; 216 } 217 } else { /* ip4 */ 218 struct sockaddr_in* sa = (struct sockaddr_in*)addr; 219 *addrlen = (socklen_t)sizeof(struct sockaddr_in); 220 memset(sa, 0, *addrlen); 221 sa->sin_family = AF_INET; 222 sa->sin_port = (in_port_t)htons(p); 223 if(inet_pton((int)sa->sin_family, ip, &sa->sin_addr) <= 0) { 224 return 0; 225 } 226 } 227 return 1; 228 } 229 230 int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr, 231 socklen_t* addrlen, int* net) 232 { 233 char* s = NULL; 234 *net = (str_is_ip6(str)?128:32); 235 if((s=strchr(str, '/'))) { 236 if(atoi(s+1) > *net) { 237 log_err("netblock too large: %s", str); 238 return 0; 239 } 240 *net = atoi(s+1); 241 if(*net == 0 && strcmp(s+1, "0") != 0) { 242 log_err("cannot parse netblock: '%s'", str); 243 return 0; 244 } 245 if(!(s = strdup(str))) { 246 log_err("out of memory"); 247 return 0; 248 } 249 *strchr(s, '/') = '\0'; 250 } 251 if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) { 252 free(s); 253 log_err("cannot parse ip address: '%s'", str); 254 return 0; 255 } 256 if(s) { 257 free(s); 258 addr_mask(addr, *addrlen, *net); 259 } 260 return 1; 261 } 262 263 void 264 log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, 265 uint16_t type, uint16_t dclass) 266 { 267 char buf[LDNS_MAX_DOMAINLEN+1]; 268 char t[12], c[12]; 269 const char *ts, *cs; 270 if(verbosity < v) 271 return; 272 dname_str(name, buf); 273 if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG"; 274 else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR"; 275 else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR"; 276 else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB"; 277 else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA"; 278 else if(type == LDNS_RR_TYPE_ANY) ts = "ANY"; 279 else if(ldns_rr_descript(type) && ldns_rr_descript(type)->_name) 280 ts = ldns_rr_descript(type)->_name; 281 else { 282 snprintf(t, sizeof(t), "TYPE%d", (int)type); 283 ts = t; 284 } 285 if(ldns_lookup_by_id(ldns_rr_classes, (int)dclass) && 286 ldns_lookup_by_id(ldns_rr_classes, (int)dclass)->name) 287 cs = ldns_lookup_by_id(ldns_rr_classes, (int)dclass)->name; 288 else { 289 snprintf(c, sizeof(c), "CLASS%d", (int)dclass); 290 cs = c; 291 } 292 log_info("%s %s %s %s", str, buf, ts, cs); 293 } 294 295 void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, 296 struct sockaddr_storage* addr, socklen_t addrlen) 297 { 298 uint16_t port; 299 const char* family = "unknown_family "; 300 char namebuf[LDNS_MAX_DOMAINLEN+1]; 301 char dest[100]; 302 int af = (int)((struct sockaddr_in*)addr)->sin_family; 303 void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 304 if(verbosity < v) 305 return; 306 switch(af) { 307 case AF_INET: family=""; break; 308 case AF_INET6: family=""; 309 sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; 310 break; 311 case AF_UNIX: family="unix_family "; break; 312 default: break; 313 } 314 if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) { 315 strncpy(dest, "(inet_ntop error)", sizeof(dest)); 316 } 317 dest[sizeof(dest)-1] = 0; 318 port = ntohs(((struct sockaddr_in*)addr)->sin_port); 319 dname_str(zone, namebuf); 320 if(af != AF_INET && af != AF_INET6) 321 verbose(v, "%s <%s> %s%s#%d (addrlen %d)", 322 str, namebuf, family, dest, (int)port, (int)addrlen); 323 else verbose(v, "%s <%s> %s%s#%d", 324 str, namebuf, family, dest, (int)port); 325 } 326 327 int 328 sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1, 329 struct sockaddr_storage* addr2, socklen_t len2) 330 { 331 struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1; 332 struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2; 333 struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1; 334 struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2; 335 if(len1 < len2) 336 return -1; 337 if(len1 > len2) 338 return 1; 339 log_assert(len1 == len2); 340 if( p1_in->sin_family < p2_in->sin_family) 341 return -1; 342 if( p1_in->sin_family > p2_in->sin_family) 343 return 1; 344 log_assert( p1_in->sin_family == p2_in->sin_family ); 345 /* compare ip4 */ 346 if( p1_in->sin_family == AF_INET ) { 347 /* just order it, ntohs not required */ 348 if(p1_in->sin_port < p2_in->sin_port) 349 return -1; 350 if(p1_in->sin_port > p2_in->sin_port) 351 return 1; 352 log_assert(p1_in->sin_port == p2_in->sin_port); 353 return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); 354 } else if (p1_in6->sin6_family == AF_INET6) { 355 /* just order it, ntohs not required */ 356 if(p1_in6->sin6_port < p2_in6->sin6_port) 357 return -1; 358 if(p1_in6->sin6_port > p2_in6->sin6_port) 359 return 1; 360 log_assert(p1_in6->sin6_port == p2_in6->sin6_port); 361 return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, 362 INET6_SIZE); 363 } else { 364 /* eek unknown type, perform this comparison for sanity. */ 365 return memcmp(addr1, addr2, len1); 366 } 367 } 368 369 int 370 sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1, 371 struct sockaddr_storage* addr2, socklen_t len2) 372 { 373 struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1; 374 struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2; 375 struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1; 376 struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2; 377 if(len1 < len2) 378 return -1; 379 if(len1 > len2) 380 return 1; 381 log_assert(len1 == len2); 382 if( p1_in->sin_family < p2_in->sin_family) 383 return -1; 384 if( p1_in->sin_family > p2_in->sin_family) 385 return 1; 386 log_assert( p1_in->sin_family == p2_in->sin_family ); 387 /* compare ip4 */ 388 if( p1_in->sin_family == AF_INET ) { 389 return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); 390 } else if (p1_in6->sin6_family == AF_INET6) { 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 addr_is_ip6(struct sockaddr_storage* addr, socklen_t len) 401 { 402 if(len == (socklen_t)sizeof(struct sockaddr_in6) && 403 ((struct sockaddr_in6*)addr)->sin6_family == AF_INET6) 404 return 1; 405 else return 0; 406 } 407 408 void 409 addr_mask(struct sockaddr_storage* addr, socklen_t len, int net) 410 { 411 uint8_t mask[8] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe}; 412 int i, max; 413 uint8_t* s; 414 if(addr_is_ip6(addr, len)) { 415 s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr; 416 max = 128; 417 } else { 418 s = (uint8_t*)&((struct sockaddr_in*)addr)->sin_addr; 419 max = 32; 420 } 421 if(net >= max) 422 return; 423 for(i=net/8+1; i<max/8; i++) { 424 s[i] = 0; 425 } 426 s[net/8] &= mask[net&0x7]; 427 } 428 429 int 430 addr_in_common(struct sockaddr_storage* addr1, int net1, 431 struct sockaddr_storage* addr2, int net2, socklen_t addrlen) 432 { 433 int min = (net1<net2)?net1:net2; 434 int i, to; 435 int match = 0; 436 uint8_t* s1, *s2; 437 if(addr_is_ip6(addr1, addrlen)) { 438 s1 = (uint8_t*)&((struct sockaddr_in6*)addr1)->sin6_addr; 439 s2 = (uint8_t*)&((struct sockaddr_in6*)addr2)->sin6_addr; 440 to = 16; 441 } else { 442 s1 = (uint8_t*)&((struct sockaddr_in*)addr1)->sin_addr; 443 s2 = (uint8_t*)&((struct sockaddr_in*)addr2)->sin_addr; 444 to = 4; 445 } 446 /* match = bits_in_common(s1, s2, to); */ 447 for(i=0; i<to; i++) { 448 if(s1[i] == s2[i]) { 449 match += 8; 450 } else { 451 uint8_t z = s1[i]^s2[i]; 452 log_assert(z); 453 while(!(z&0x80)) { 454 match++; 455 z<<=1; 456 } 457 break; 458 } 459 } 460 if(match > min) match = min; 461 return match; 462 } 463 464 void 465 addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen, 466 char* buf, size_t len) 467 { 468 int af = (int)((struct sockaddr_in*)addr)->sin_family; 469 void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 470 if(addr_is_ip6(addr, addrlen)) 471 sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr; 472 if(inet_ntop(af, sinaddr, buf, (socklen_t)len) == 0) { 473 snprintf(buf, len, "(inet_ntop_error)"); 474 } 475 } 476 477 int 478 addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen) 479 { 480 /* prefix for ipv4 into ipv6 mapping is ::ffff:x.x.x.x */ 481 const uint8_t map_prefix[16] = 482 {0,0,0,0, 0,0,0,0, 0,0,0xff,0xff, 0,0,0,0}; 483 uint8_t* s; 484 if(!addr_is_ip6(addr, addrlen)) 485 return 0; 486 /* s is 16 octet ipv6 address string */ 487 s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr; 488 return (memcmp(s, map_prefix, 12) == 0); 489 } 490 491 int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen) 492 { 493 int af = (int)((struct sockaddr_in*)addr)->sin_family; 494 void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 495 return af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in) 496 && memcmp(sinaddr, "\377\377\377\377", 4) == 0; 497 } 498 499 int addr_is_any(struct sockaddr_storage* addr, socklen_t addrlen) 500 { 501 int af = (int)((struct sockaddr_in*)addr)->sin_family; 502 void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; 503 void* sin6addr = &((struct sockaddr_in6*)addr)->sin6_addr; 504 if(af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in) 505 && memcmp(sinaddr, "\000\000\000\000", 4) == 0) 506 return 1; 507 else if(af==AF_INET6 && addrlen>=(socklen_t)sizeof(struct sockaddr_in6) 508 && memcmp(sin6addr, "\000\000\000\000\000\000\000\000" 509 "\000\000\000\000\000\000\000\000", 16) == 0) 510 return 1; 511 return 0; 512 } 513 514 void sock_list_insert(struct sock_list** list, struct sockaddr_storage* addr, 515 socklen_t len, struct regional* region) 516 { 517 struct sock_list* add = (struct sock_list*)regional_alloc(region, 518 sizeof(*add) - sizeof(add->addr) + (size_t)len); 519 if(!add) { 520 log_err("out of memory in socketlist insert"); 521 return; 522 } 523 log_assert(list); 524 add->next = *list; 525 add->len = len; 526 *list = add; 527 if(len) memmove(&add->addr, addr, len); 528 } 529 530 void sock_list_prepend(struct sock_list** list, struct sock_list* add) 531 { 532 struct sock_list* last = add; 533 if(!last) 534 return; 535 while(last->next) 536 last = last->next; 537 last->next = *list; 538 *list = add; 539 } 540 541 int sock_list_find(struct sock_list* list, struct sockaddr_storage* addr, 542 socklen_t len) 543 { 544 while(list) { 545 if(len == list->len) { 546 if(len == 0 || sockaddr_cmp_addr(addr, len, 547 &list->addr, list->len) == 0) 548 return 1; 549 } 550 list = list->next; 551 } 552 return 0; 553 } 554 555 void sock_list_merge(struct sock_list** list, struct regional* region, 556 struct sock_list* add) 557 { 558 struct sock_list* p; 559 for(p=add; p; p=p->next) { 560 if(!sock_list_find(*list, &p->addr, p->len)) 561 sock_list_insert(list, &p->addr, p->len, region); 562 } 563 } 564 565 void 566 log_crypto_err(const char* str) 567 { 568 /* error:[error code]:[library name]:[function name]:[reason string] */ 569 char buf[128]; 570 unsigned long e; 571 ERR_error_string_n(ERR_get_error(), buf, sizeof(buf)); 572 log_err("%s crypto %s", str, buf); 573 while( (e=ERR_get_error()) ) { 574 ERR_error_string_n(e, buf, sizeof(buf)); 575 log_err("and additionally crypto %s", buf); 576 } 577 } 578 579 void* listen_sslctx_create(char* key, char* pem, char* verifypem) 580 { 581 SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method()); 582 if(!ctx) { 583 log_crypto_err("could not SSL_CTX_new"); 584 return NULL; 585 } 586 /* no SSLv2 because has defects */ 587 if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)){ 588 log_crypto_err("could not set SSL_OP_NO_SSLv2"); 589 SSL_CTX_free(ctx); 590 return NULL; 591 } 592 if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) { 593 log_err("error for cert file: %s", pem); 594 log_crypto_err("error in SSL_CTX use_certificate_file"); 595 SSL_CTX_free(ctx); 596 return NULL; 597 } 598 if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) { 599 log_err("error for private key file: %s", key); 600 log_crypto_err("Error in SSL_CTX use_PrivateKey_file"); 601 SSL_CTX_free(ctx); 602 return NULL; 603 } 604 if(!SSL_CTX_check_private_key(ctx)) { 605 log_err("error for key file: %s", key); 606 log_crypto_err("Error in SSL_CTX check_private_key"); 607 SSL_CTX_free(ctx); 608 return NULL; 609 } 610 611 if(verifypem && verifypem[0]) { 612 if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { 613 log_crypto_err("Error in SSL_CTX verify locations"); 614 SSL_CTX_free(ctx); 615 return NULL; 616 } 617 SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file( 618 verifypem)); 619 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 620 } 621 return ctx; 622 } 623 624 void* connect_sslctx_create(char* key, char* pem, char* verifypem) 625 { 626 SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method()); 627 if(!ctx) { 628 log_crypto_err("could not allocate SSL_CTX pointer"); 629 return NULL; 630 } 631 if(!(SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)) { 632 log_crypto_err("could not set SSL_OP_NO_SSLv2"); 633 SSL_CTX_free(ctx); 634 return NULL; 635 } 636 if(key && key[0]) { 637 if(!SSL_CTX_use_certificate_file(ctx, pem, SSL_FILETYPE_PEM)) { 638 log_err("error in client certificate %s", pem); 639 log_crypto_err("error in certificate file"); 640 SSL_CTX_free(ctx); 641 return NULL; 642 } 643 if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) { 644 log_err("error in client private key %s", key); 645 log_crypto_err("error in key file"); 646 SSL_CTX_free(ctx); 647 return NULL; 648 } 649 if(!SSL_CTX_check_private_key(ctx)) { 650 log_err("error in client key %s", key); 651 log_crypto_err("error in SSL_CTX_check_private_key"); 652 SSL_CTX_free(ctx); 653 return NULL; 654 } 655 } 656 if(verifypem && verifypem[0]) { 657 if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL) != 1) { 658 log_crypto_err("error in SSL_CTX verify"); 659 SSL_CTX_free(ctx); 660 return NULL; 661 } 662 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 663 } 664 return ctx; 665 } 666 667 void* incoming_ssl_fd(void* sslctx, int fd) 668 { 669 SSL* ssl = SSL_new((SSL_CTX*)sslctx); 670 if(!ssl) { 671 log_crypto_err("could not SSL_new"); 672 return NULL; 673 } 674 SSL_set_accept_state(ssl); 675 (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); 676 if(!SSL_set_fd(ssl, fd)) { 677 log_crypto_err("could not SSL_set_fd"); 678 SSL_free(ssl); 679 return NULL; 680 } 681 return ssl; 682 } 683 684 void* outgoing_ssl_fd(void* sslctx, int fd) 685 { 686 SSL* ssl = SSL_new((SSL_CTX*)sslctx); 687 if(!ssl) { 688 log_crypto_err("could not SSL_new"); 689 return NULL; 690 } 691 SSL_set_connect_state(ssl); 692 (void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); 693 if(!SSL_set_fd(ssl, fd)) { 694 log_crypto_err("could not SSL_set_fd"); 695 SSL_free(ssl); 696 return NULL; 697 } 698 return ssl; 699 } 700