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