net.c revision 1.22
1/* $OpenBSD: net.c,v 1.22 2015/08/20 22:39:29 deraadt Exp $ */ 2 3/* 4 * Copyright (c) 2005 H�kan Olsson. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28/* 29 * This code was written under funding by Multicom Security AB. 30 */ 31 32#include <sys/types.h> 33#include <sys/socket.h> 34#include <sys/time.h> 35#include <netinet/in.h> 36#include <arpa/inet.h> 37#include <ifaddrs.h> 38#include <netdb.h> 39#include <signal.h> 40 41#include <openssl/aes.h> 42#include <openssl/sha.h> 43 44#include <errno.h> 45#include <stdio.h> 46#include <stdlib.h> 47#include <string.h> 48#include <unistd.h> 49 50#include "sasyncd.h" 51#include "net.h" 52 53struct msg { 54 u_int8_t *buf; 55 u_int32_t len; 56 int refcnt; 57}; 58 59struct qmsg { 60 SIMPLEQ_ENTRY(qmsg) next; 61 struct msg *msg; 62}; 63 64int *listeners; 65AES_KEY aes_key[2]; 66#define AES_IV_LEN AES_BLOCK_SIZE 67 68/* We never send (or expect to receive) messages smaller/larger than this. */ 69#define MSG_MINLEN 12 70#define MSG_MAXLEN 4096 71 72/* Local prototypes. */ 73static u_int8_t *net_read(struct syncpeer *, u_int32_t *, u_int32_t *); 74static int net_set_sa(struct sockaddr *, char *, in_port_t); 75static void net_check_peers(void *); 76 77/* Pretty-print a buffer. */ 78void 79dump_buf(int lvl, u_int8_t *b, u_int32_t len, char *title) 80{ 81 u_int32_t i, off, blen; 82 u_int8_t *buf; 83 const char def[] = "Buffer:"; 84 85 if (cfgstate.verboselevel < lvl) 86 return; 87 88 blen = 2 * (len + len / 36) + 3 + (title ? strlen(title) : sizeof def); 89 if (!(buf = calloc(1, blen))) 90 return; 91 92 snprintf(buf, blen, "%s\n ", title ? title : def); 93 off = strlen(buf); 94 for (i = 0; i < len; i++, off+=2) { 95 snprintf(buf + off, blen - off, "%02x", b[i]); 96 if ((i+1) % 36 == 0) { 97 off += 2; 98 snprintf(buf + off, blen - off, "\n "); 99 } 100 } 101 log_msg(lvl, "%s", buf); 102 free(buf); 103} 104 105/* Add a listening socket. */ 106static int 107net_add_listener(struct sockaddr *sa) 108{ 109 char host[NI_MAXHOST], port[NI_MAXSERV]; 110 int r, s; 111 112 s = socket(sa->sa_family, SOCK_STREAM, 0); 113 if (s < 0) { 114 perror("net_add_listener: socket()"); 115 close(s); 116 return -1; 117 } 118 119 r = 1; 120 if (setsockopt(s, SOL_SOCKET, 121 cfgstate.listen_on ? SO_REUSEADDR : SO_REUSEPORT, (void *)&r, 122 sizeof r)) { 123 perror("net_add_listener: setsockopt()"); 124 close(s); 125 return -1; 126 } 127 128 if (bind(s, sa, sa->sa_family == AF_INET ? sizeof(struct sockaddr_in) : 129 sizeof (struct sockaddr_in6))) { 130 perror("net_add_listener: bind()"); 131 close(s); 132 return -1; 133 } 134 135 if (listen(s, 3)) { 136 perror("net_add_listener: listen()"); 137 close(s); 138 return -1; 139 } 140 141 if (getnameinfo(sa, sa->sa_len, host, sizeof host, port, sizeof port, 142 NI_NUMERICHOST | NI_NUMERICSERV)) 143 log_msg(2, "listening on port %u fd %d", cfgstate.listen_port, 144 s); 145 else 146 log_msg(2, "listening on %s port %s fd %d", host, port, s); 147 148 return s; 149} 150 151/* Allocate and fill in listeners array. */ 152static int 153net_setup_listeners(void) 154{ 155 struct sockaddr_storage sa_storage; 156 struct sockaddr *sa = (struct sockaddr *)&sa_storage; 157 struct sockaddr_in *sin = (struct sockaddr_in *)sa; 158 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; 159 struct ifaddrs *ifap = 0, *ifa; 160 int i, count; 161 162 /* Setup listening sockets. */ 163 memset(&sa_storage, 0, sizeof sa_storage); 164 if (net_set_sa(sa, cfgstate.listen_on, cfgstate.listen_port) == 0) { 165 listeners = calloc(2, sizeof(int)); 166 if (!listeners) { 167 perror("net_setup_listeners: calloc()"); 168 goto errout; 169 } 170 listeners[1] = -1; 171 listeners[0] = net_add_listener(sa); 172 if (listeners[0] == -1) { 173 log_msg(0, "net_setup_listeners: could not find " 174 "listen address (%s)", cfgstate.listen_on); 175 goto errout; 176 } 177 return 0; 178 } 179 180 /* 181 * If net_set_sa() failed, cfgstate.listen_on is probably an 182 * interface name, so we should listen on all it's addresses. 183 */ 184 185 if (getifaddrs(&ifap) != 0) { 186 perror("net_setup_listeners: getifaddrs()"); 187 goto errout; 188 } 189 190 /* How many addresses matches? */ 191 for (count = 0, ifa = ifap; ifa; ifa = ifa->ifa_next) { 192 if (!ifa->ifa_name || !ifa->ifa_addr || 193 (ifa->ifa_addr->sa_family != AF_INET && 194 ifa->ifa_addr->sa_family != AF_INET6)) 195 continue; 196 if (cfgstate.listen_family && 197 cfgstate.listen_family != ifa->ifa_addr->sa_family) 198 continue; 199 if (strcmp(ifa->ifa_name, cfgstate.listen_on) != 0) 200 continue; 201 count++; 202 } 203 204 if (!count) { 205 log_msg(0, "net_setup_listeners: no listeners found for %s", 206 cfgstate.listen_on); 207 goto errout; 208 } 209 210 /* Allocate one extra slot and set to -1, marking end of array. */ 211 listeners = calloc(count + 1, sizeof(int)); 212 if (!listeners) { 213 perror("net_setup_listeners: calloc()"); 214 goto errout; 215 } 216 for (i = 0; i <= count; i++) 217 listeners[i] = -1; 218 219 /* Create listening sockets */ 220 for (count = 0, ifa = ifap; ifa; ifa = ifa->ifa_next) { 221 if (!ifa->ifa_name || !ifa->ifa_addr || 222 (ifa->ifa_addr->sa_family != AF_INET && 223 ifa->ifa_addr->sa_family != AF_INET6)) 224 continue; 225 if (cfgstate.listen_family && 226 cfgstate.listen_family != ifa->ifa_addr->sa_family) 227 continue; 228 if (strcmp(ifa->ifa_name, cfgstate.listen_on) != 0) 229 continue; 230 231 memset(&sa_storage, 0, sizeof sa_storage); 232 sa->sa_family = ifa->ifa_addr->sa_family; 233 switch (sa->sa_family) { 234 case AF_INET: 235 sin->sin_port = htons(cfgstate.listen_port); 236 sin->sin_len = sizeof *sin; 237 memcpy(&sin->sin_addr, 238 &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, 239 sizeof sin->sin_addr); 240 break; 241 case AF_INET6: 242 sin6->sin6_port = htons(cfgstate.listen_port); 243 sin6->sin6_len = sizeof *sin6; 244 memcpy(&sin6->sin6_addr, 245 &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr, 246 sizeof sin6->sin6_addr); 247 break; 248 } 249 250 listeners[count] = net_add_listener(sa); 251 if (listeners[count] == -1) { 252 log_msg(2, "net_setup_listeners(setup): failed to " 253 "add listener, count = %d", count); 254 goto errout; 255 } 256 count++; 257 } 258 freeifaddrs(ifap); 259 return 0; 260 261 errout: 262 if (ifap) 263 freeifaddrs(ifap); 264 if (listeners) { 265 for (i = 0; listeners[i] != -1; i++) 266 close(listeners[i]); 267 free(listeners); 268 } 269 return -1; 270} 271 272int 273net_init(void) 274{ 275 struct syncpeer *p; 276 277 if (AES_set_encrypt_key(cfgstate.sharedkey, cfgstate.sharedkey_len, 278 &aes_key[0]) || 279 AES_set_decrypt_key(cfgstate.sharedkey, cfgstate.sharedkey_len, 280 &aes_key[1])) { 281 fprintf(stderr, "Bad AES shared key\n"); 282 return -1; 283 } 284 285 if (net_setup_listeners()) 286 return -1; 287 288 for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) { 289 p->socket = -1; 290 SIMPLEQ_INIT(&p->msgs); 291 } 292 293 net_check_peers(0); 294 return 0; 295} 296 297static void 298net_enqueue(struct syncpeer *p, struct msg *m) 299{ 300 struct qmsg *qm; 301 302 if (p->socket < 0) 303 return; 304 305 qm = calloc(1, sizeof *qm); 306 if (!qm) { 307 log_err("net_enqueue: calloc()"); 308 return; 309 } 310 311 qm->msg = m; 312 m->refcnt++; 313 314 SIMPLEQ_INSERT_TAIL(&p->msgs, qm, next); 315 return; 316} 317 318/* 319 * Queue a message for transmission to a particular peer, 320 * or to all peers if no peer is specified. 321 */ 322int 323net_queue(struct syncpeer *p0, u_int32_t msgtype, u_int8_t *buf, u_int32_t len) 324{ 325 struct syncpeer *p = p0; 326 struct msg *m; 327 SHA_CTX ctx; 328 u_int8_t hash[SHA_DIGEST_LENGTH]; 329 u_int8_t iv[AES_IV_LEN], tmp_iv[AES_IV_LEN]; 330 u_int32_t v, padlen = 0; 331 int i, offset; 332 333 m = calloc(1, sizeof *m); 334 if (!m) { 335 log_err("net_queue: calloc()"); 336 free(buf); 337 return -1; 338 } 339 340 /* Generate hash */ 341 SHA1_Init(&ctx); 342 SHA1_Update(&ctx, buf, len); 343 SHA1_Final(hash, &ctx); 344 dump_buf(2, hash, sizeof hash, "net_queue: computed hash"); 345 346 /* Padding required? */ 347 i = len % AES_IV_LEN; 348 if (i) { 349 u_int8_t *pbuf; 350 i = AES_IV_LEN - i; 351 pbuf = realloc(buf, len + i); 352 if (!pbuf) { 353 log_err("net_queue: realloc()"); 354 free(buf); 355 free(m); 356 return -1; 357 } 358 padlen = i; 359 while (i > 0) 360 pbuf[len++] = (u_int8_t)i--; 361 buf = pbuf; 362 } 363 364 /* Get random IV */ 365 for (i = 0; (size_t)i <= sizeof iv - sizeof v; i += sizeof v) { 366 v = arc4random(); 367 memcpy(&iv[i], &v, sizeof v); 368 } 369 dump_buf(2, iv, sizeof iv, "net_queue: IV"); 370 memcpy(tmp_iv, iv, sizeof tmp_iv); 371 372 /* Encrypt */ 373 dump_buf(2, buf, len, "net_queue: pre encrypt"); 374 AES_cbc_encrypt(buf, buf, len, &aes_key[0], tmp_iv, AES_ENCRYPT); 375 dump_buf(2, buf, len, "net_queue: post encrypt"); 376 377 /* Allocate send buffer */ 378 m->len = len + sizeof iv + sizeof hash + 3 * sizeof(u_int32_t); 379 m->buf = malloc(m->len); 380 if (!m->buf) { 381 free(m); 382 free(buf); 383 log_err("net_queue: calloc()"); 384 return -1; 385 } 386 offset = 0; 387 388 /* Fill it (order must match parsing code in net_read()) */ 389 v = htonl(m->len - sizeof(u_int32_t)); 390 memcpy(m->buf + offset, &v, sizeof v); 391 offset += sizeof v; 392 v = htonl(msgtype); 393 memcpy(m->buf + offset, &v, sizeof v); 394 offset += sizeof v; 395 v = htonl(padlen); 396 memcpy(m->buf + offset, &v, sizeof v); 397 offset += sizeof v; 398 memcpy(m->buf + offset, hash, sizeof hash); 399 offset += sizeof hash; 400 memcpy(m->buf + offset, iv, sizeof iv); 401 offset += sizeof iv; 402 memcpy(m->buf + offset, buf, len); 403 free(buf); 404 405 if (p) 406 net_enqueue(p, m); 407 else 408 for (p = LIST_FIRST(&cfgstate.peerlist); p; 409 p = LIST_NEXT(p, link)) 410 net_enqueue(p, m); 411 412 if (!m->refcnt) { 413 free(m->buf); 414 free(m); 415 } 416 417 return 0; 418} 419 420/* Set all write pending filedescriptors. */ 421int 422net_set_pending_wfds(fd_set *fds) 423{ 424 struct syncpeer *p; 425 int max_fd = -1; 426 427 for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) 428 if (p->socket > -1 && SIMPLEQ_FIRST(&p->msgs)) { 429 FD_SET(p->socket, fds); 430 if (p->socket > max_fd) 431 max_fd = p->socket; 432 } 433 return max_fd + 1; 434} 435 436/* 437 * Set readable filedescriptors. They are basically the same as for write, 438 * plus the listening socket. 439 */ 440int 441net_set_rfds(fd_set *fds) 442{ 443 struct syncpeer *p; 444 int i, max_fd = -1; 445 446 for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) { 447 if (p->socket > -1) 448 FD_SET(p->socket, fds); 449 if (p->socket > max_fd) 450 max_fd = p->socket; 451 } 452 for (i = 0; listeners[i] != -1; i++) { 453 FD_SET(listeners[i], fds); 454 if (listeners[i] > max_fd) 455 max_fd = listeners[i]; 456 } 457 return max_fd + 1; 458} 459 460static void 461net_accept(int accept_socket) 462{ 463 struct sockaddr_storage sa_storage, sa_storage2; 464 struct sockaddr *sa = (struct sockaddr *)&sa_storage; 465 struct sockaddr *sa2 = (struct sockaddr *)&sa_storage2; 466 struct sockaddr_in *sin, *sin2; 467 struct sockaddr_in6 *sin6, *sin62; 468 struct syncpeer *p; 469 socklen_t socklen; 470 int s, found; 471 472 /* Accept a new incoming connection */ 473 socklen = sizeof sa_storage; 474 memset(&sa_storage, 0, socklen); 475 memset(&sa_storage2, 0, socklen); 476 s = accept(accept_socket, sa, &socklen); 477 if (s > -1) { 478 /* Setup the syncpeer structure */ 479 found = 0; 480 for (p = LIST_FIRST(&cfgstate.peerlist); p && !found; 481 p = LIST_NEXT(p, link)) { 482 483 /* Match? */ 484 if (net_set_sa(sa2, p->name, 0)) 485 continue; 486 if (sa->sa_family != sa2->sa_family) 487 continue; 488 if (sa->sa_family == AF_INET) { 489 sin = (struct sockaddr_in *)sa; 490 sin2 = (struct sockaddr_in *)sa2; 491 if (memcmp(&sin->sin_addr, &sin2->sin_addr, 492 sizeof(struct in_addr))) 493 continue; 494 } else { 495 sin6 = (struct sockaddr_in6 *)sa; 496 sin62 = (struct sockaddr_in6 *)sa2; 497 if (memcmp(&sin6->sin6_addr, &sin62->sin6_addr, 498 sizeof(struct in6_addr))) 499 continue; 500 } 501 /* Match! */ 502 found++; 503 p->socket = s; 504 log_msg(1, "net: peer \"%s\" connected", p->name); 505 if (cfgstate.runstate == MASTER) 506 timer_add("pfkey_snap", 2, pfkey_snapshot, p); 507 } 508 if (!found) { 509 log_msg(1, "net: found no matching peer for accepted " 510 "socket, closing."); 511 close(s); 512 } 513 } else if (errno != EWOULDBLOCK && errno != EINTR && 514 errno != ECONNABORTED) 515 log_err("net: accept()"); 516} 517 518void 519net_handle_messages(fd_set *fds) 520{ 521 struct syncpeer *p; 522 u_int8_t *msg; 523 u_int32_t msgtype, msglen; 524 int i; 525 526 for (i = 0; listeners[i] != -1; i++) 527 if (FD_ISSET(listeners[i], fds)) 528 net_accept(listeners[i]); 529 530 for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) { 531 if (p->socket < 0 || !FD_ISSET(p->socket, fds)) 532 continue; 533 msg = net_read(p, &msgtype, &msglen); 534 if (!msg) 535 continue; 536 537 log_msg(2, "net_handle_messages: got msg type %u len %u from " 538 "peer %s", msgtype, msglen, p->name); 539 540 switch (msgtype) { 541 case MSG_SYNCCTL: 542 net_ctl_handle_msg(p, msg, msglen); 543 free(msg); 544 break; 545 546 case MSG_PFKEYDATA: 547 if (p->runstate != MASTER || 548 cfgstate.runstate == MASTER) { 549 log_msg(1, "net: got PFKEY message from " 550 "non-MASTER peer"); 551 free(msg); 552 if (cfgstate.runstate == MASTER) 553 net_ctl_send_state(p); 554 else 555 net_ctl_send_error(p, 0); 556 } else if (pfkey_queue_message(msg, msglen)) 557 free(msg); 558 break; 559 560 default: 561 log_msg(0, "net: got unknown message type %u len %u " 562 "from peer %s", msgtype, msglen, p->name); 563 free(msg); 564 net_ctl_send_error(p, 0); 565 } 566 } 567} 568 569void 570net_send_messages(fd_set *fds) 571{ 572 struct syncpeer *p; 573 struct qmsg *qm; 574 struct msg *m; 575 ssize_t r; 576 577 for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) { 578 if (p->socket < 0 || !FD_ISSET(p->socket, fds)) 579 continue; 580 qm = SIMPLEQ_FIRST(&p->msgs); 581 if (!qm) { 582 /* XXX Log */ 583 continue; 584 } 585 m = qm->msg; 586 587 log_msg(2, "net_send_messages: msg %p len %u ref %d " 588 "to peer %s", m, m->len, m->refcnt, p->name); 589 590 /* write message */ 591 r = write(p->socket, m->buf, m->len); 592 if (r == -1) { 593 net_disconnect_peer(p); 594 log_msg(0, "net_send_messages: write() failed, " 595 "peer disconnected"); 596 } else if (r < (ssize_t)m->len) { 597 /* retransmit later */ 598 continue; 599 } 600 601 /* cleanup */ 602 SIMPLEQ_REMOVE_HEAD(&p->msgs, next); 603 free(qm); 604 605 if (--m->refcnt < 1) { 606 log_msg(2, "net_send_messages: freeing msg %p", m); 607 free(m->buf); 608 free(m); 609 } 610 } 611 return; 612} 613 614void 615net_disconnect_peer(struct syncpeer *p) 616{ 617 if (p->socket > -1) { 618 log_msg(1, "net_disconnect_peer: peer \"%s\" removed", 619 p->name); 620 close(p->socket); 621 } 622 p->socket = -1; 623} 624 625void 626net_shutdown(void) 627{ 628 struct syncpeer *p; 629 struct qmsg *qm; 630 struct msg *m; 631 int i; 632 633 while ((p = LIST_FIRST(&cfgstate.peerlist))) { 634 while ((qm = SIMPLEQ_FIRST(&p->msgs))) { 635 SIMPLEQ_REMOVE_HEAD(&p->msgs, next); 636 m = qm->msg; 637 if (--m->refcnt < 1) { 638 free(m->buf); 639 free(m); 640 } 641 free(qm); 642 } 643 net_disconnect_peer(p); 644 if (p->sa) 645 free(p->sa); 646 if (p->name) 647 free(p->name); 648 LIST_REMOVE(p, link); 649 cfgstate.peercnt--; 650 free(p); 651 } 652 653 if (listeners) { 654 for (i = 0; listeners[i] != -1; i++) 655 close(listeners[i]); 656 free(listeners); 657 listeners = 0; 658 } 659} 660 661/* 662 * Helper functions (local) below here. 663 */ 664 665static u_int8_t * 666net_read(struct syncpeer *p, u_int32_t *msgtype, u_int32_t *msglen) 667{ 668 u_int8_t *msg, *blob, *rhash, *iv, hash[SHA_DIGEST_LENGTH]; 669 u_int32_t v, blob_len, pos = 0; 670 int padlen = 0, offset = 0; 671 ssize_t r; 672 SHA_CTX ctx; 673 674 /* Read blob length */ 675 r = read(p->socket, &v, sizeof v); 676 if (r != (ssize_t)sizeof v) { 677 if (r < 1) 678 net_disconnect_peer(p); 679 return NULL; 680 } 681 682 blob_len = ntohl(v); 683 if (blob_len < sizeof hash + AES_IV_LEN + 2 * sizeof(u_int32_t)) 684 return NULL; 685 *msglen = blob_len - sizeof hash - AES_IV_LEN - 2 * sizeof(u_int32_t); 686 if (*msglen < MSG_MINLEN || *msglen > MSG_MAXLEN) 687 return NULL; 688 689 /* Read message blob */ 690 blob = malloc(blob_len); 691 if (!blob) { 692 log_err("net_read: malloc()"); 693 return NULL; 694 } 695 696 while (blob_len > pos) { 697 switch (r = read(p->socket, blob + pos, blob_len - pos)) { 698 case -1: 699 if (errno == EINTR || errno == EAGAIN) 700 continue; 701 /* FALLTHROUGH */ 702 case 0: 703 net_disconnect_peer(p); 704 free(blob); 705 return NULL; 706 /* NOTREACHED */ 707 default: 708 pos += r; 709 } 710 } 711 712 offset = 0; 713 memcpy(&v, blob + offset, sizeof v); 714 *msgtype = ntohl(v); 715 offset += sizeof v; 716 717 if (*msgtype > MSG_MAXTYPE) { 718 free(blob); 719 return NULL; 720 } 721 722 memcpy(&v, blob + offset, sizeof v); 723 padlen = ntohl(v); 724 offset += sizeof v; 725 726 rhash = blob + offset; 727 iv = rhash + sizeof hash; 728 msg = malloc(*msglen); 729 if (!msg) { 730 free(blob); 731 return NULL; 732 } 733 memcpy(msg, iv + AES_IV_LEN, *msglen); 734 735 dump_buf(2, rhash, sizeof hash, "net_read: got hash"); 736 dump_buf(2, iv, AES_IV_LEN, "net_read: got IV"); 737 dump_buf(2, msg, *msglen, "net_read: pre decrypt"); 738 AES_cbc_encrypt(msg, msg, *msglen, &aes_key[1], iv, AES_DECRYPT); 739 dump_buf(2, msg, *msglen, "net_read: post decrypt"); 740 *msglen -= padlen; 741 742 SHA1_Init(&ctx); 743 SHA1_Update(&ctx, msg, *msglen); 744 SHA1_Final(hash, &ctx); 745 dump_buf(2, hash, sizeof hash, "net_read: computed hash"); 746 747 if (memcmp(hash, rhash, sizeof hash) != 0) { 748 free(blob); 749 free(msg); 750 log_msg(0, "net_read: got bad message (typo in shared key?)"); 751 return NULL; 752 } 753 free(blob); 754 return msg; 755} 756 757static int 758net_set_sa(struct sockaddr *sa, char *name, in_port_t port) 759{ 760 struct sockaddr_in *sin = (struct sockaddr_in *)sa; 761 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; 762 763 if (!name) { 764 /* XXX Assume IPv4 */ 765 sa->sa_family = AF_INET; 766 sin->sin_port = htons(port); 767 sin->sin_len = sizeof *sin; 768 return 0; 769 } 770 771 if (inet_pton(AF_INET, name, &sin->sin_addr) == 1) { 772 sa->sa_family = AF_INET; 773 sin->sin_port = htons(port); 774 sin->sin_len = sizeof *sin; 775 return 0; 776 } 777 778 if (inet_pton(AF_INET6, name, &sin6->sin6_addr) == 1) { 779 sa->sa_family = AF_INET6; 780 sin6->sin6_port = htons(port); 781 sin6->sin6_len = sizeof *sin6; 782 return 0; 783 } 784 785 return -1; 786} 787 788static void 789got_sigalrm(int s) 790{ 791 return; 792} 793 794void 795net_connect(void) 796{ 797 struct itimerval iv; 798 struct syncpeer *p; 799 800 signal(SIGALRM, got_sigalrm); 801 memset(&iv, 0, sizeof iv); 802 iv.it_value.tv_sec = 5; 803 iv.it_interval.tv_sec = 5; 804 setitimer(ITIMER_REAL, &iv, NULL); 805 806 for (p = LIST_FIRST(&cfgstate.peerlist); p; p = LIST_NEXT(p, link)) { 807 if (p->socket > -1) 808 continue; 809 if (!p->sa) { 810 p->sa = calloc(1, sizeof(struct sockaddr_storage)); 811 if (!p->sa) 812 return; 813 if (net_set_sa(p->sa, p->name, cfgstate.listen_port)) 814 continue; 815 } 816 p->socket = socket(p->sa->sa_family, SOCK_STREAM, 0); 817 if (p->socket < 0) { 818 log_err("peer \"%s\": socket()", p->name); 819 continue; 820 } 821 if (connect(p->socket, p->sa, p->sa->sa_len)) { 822 log_msg(1, "net_connect: peer \"%s\" not ready yet", 823 p->name); 824 net_disconnect_peer(p); 825 continue; 826 } 827 if (net_ctl_send_state(p)) { 828 log_msg(0, "net_connect: peer \"%s\" failed", p->name); 829 net_disconnect_peer(p); 830 continue; 831 } 832 log_msg(1, "net_connect: peer \"%s\" connected, fd %d", 833 p->name, p->socket); 834 835 /* Schedule a pfkey sync to the newly connected peer. */ 836 if (cfgstate.runstate == MASTER) 837 timer_add("pfkey_snapshot", 2, pfkey_snapshot, p); 838 } 839 840 timerclear(&iv.it_value); 841 timerclear(&iv.it_interval); 842 setitimer(ITIMER_REAL, &iv, NULL); 843 signal(SIGALRM, SIG_IGN); 844 845 return; 846} 847 848static void 849net_check_peers(void *arg) 850{ 851 net_connect(); 852 (void)timer_add("peer recheck", 600, net_check_peers, 0); 853} 854