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