1/* 2 * OpenVPN -- An application to securely tunnel IP networks 3 * over a single UDP port, with support for SSL/TLS-based 4 * session authentication and key exchange, 5 * packet encryption, packet authentication, and 6 * packet compression. 7 * 8 * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 12 * as published by the Free Software Foundation. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program (see the file COPYING included with this 21 * distribution); if not, write to the Free Software Foundation, Inc., 22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#elif defined(_MSC_VER) 28#include "config-msvc.h" 29#endif 30 31#include "syshead.h" 32 33#if PORT_SHARE 34 35#include "event.h" 36#include "socket.h" 37#include "fdmisc.h" 38#include "crypto.h" 39#include "ps.h" 40 41#include "memdbg.h" 42 43struct port_share *port_share = NULL; /* GLOBAL */ 44 45/* size of i/o buffers */ 46#define PROXY_CONNECTION_BUFFER_SIZE 1500 47 48/* Command codes for foreground -> background communication */ 49#define COMMAND_REDIRECT 10 50#define COMMAND_EXIT 11 51 52/* Response codes for background -> foreground communication */ 53#define RESPONSE_INIT_SUCCEEDED 20 54#define RESPONSE_INIT_FAILED 21 55 56/* 57 * Return values for proxy_connection_io functions 58 */ 59 60#define IOSTAT_EAGAIN_ON_READ 0 /* recv returned EAGAIN */ 61#define IOSTAT_EAGAIN_ON_WRITE 1 /* send returned EAGAIN */ 62#define IOSTAT_READ_ERROR 2 /* the other end of our read socket (pc) was closed */ 63#define IOSTAT_WRITE_ERROR 3 /* the other end of our write socket (pc->counterpart) was closed */ 64#define IOSTAT_GOOD 4 /* nothing to report */ 65 66/* 67 * A foreign (non-OpenVPN) connection we are proxying, 68 * usually HTTPS 69 */ 70struct proxy_connection { 71 bool defined; 72 struct proxy_connection *next; 73 struct proxy_connection *counterpart; 74 struct buffer buf; 75 bool buffer_initial; 76 int rwflags; 77 int sd; 78 char *jfn; 79}; 80 81#if 0 82static const char * 83headc (const struct buffer *buf) 84{ 85 static char foo[16]; 86 strncpy (foo, BSTR(buf), 15); 87 foo[15] = 0; 88 return foo; 89} 90#endif 91 92static inline void 93close_socket_if_defined (const socket_descriptor_t sd) 94{ 95 if (socket_defined (sd)) 96 openvpn_close_socket (sd); 97} 98 99/* 100 * Close most of parent's fds. 101 * Keep stdin/stdout/stderr, plus one 102 * other fd which is presumed to be 103 * our pipe back to parent. 104 * Admittedly, a bit of a kludge, 105 * but posix doesn't give us a kind 106 * of FD_CLOEXEC which will stop 107 * fds from crossing a fork(). 108 */ 109static void 110close_fds_except (int keep) 111{ 112 socket_descriptor_t i; 113 closelog (); 114 for (i = 3; i <= 100; ++i) 115 { 116 if (i != keep) 117 openvpn_close_socket (i); 118 } 119} 120 121/* 122 * Usually we ignore signals, because our parent will 123 * deal with them. 124 */ 125static void 126set_signals (void) 127{ 128 signal (SIGTERM, SIG_DFL); 129 130 signal (SIGINT, SIG_IGN); 131 signal (SIGHUP, SIG_IGN); 132 signal (SIGUSR1, SIG_IGN); 133 signal (SIGUSR2, SIG_IGN); 134 signal (SIGPIPE, SIG_IGN); 135} 136 137/* 138 * Socket read/write functions. 139 */ 140 141static int 142recv_control (const socket_descriptor_t fd) 143{ 144 unsigned char c; 145 const ssize_t size = read (fd, &c, sizeof (c)); 146 if (size == sizeof (c)) 147 return c; 148 else 149 { 150 return -1; 151 } 152} 153 154static int 155send_control (const socket_descriptor_t fd, int code) 156{ 157 unsigned char c = (unsigned char) code; 158 const ssize_t size = write (fd, &c, sizeof (c)); 159 if (size == sizeof (c)) 160 return (int) size; 161 else 162 return -1; 163} 164 165static int 166cmsg_size () 167{ 168 return CMSG_SPACE(sizeof(socket_descriptor_t)); 169} 170 171/* 172 * Send a command (char), data (head), and a file descriptor (sd_send) to a local process 173 * over unix socket sd. Unfortunately, there's no portable way to send file descriptors 174 * to other processes, so this code, as well as its analog (control_message_from_parent below), 175 * is Linux-specific. This function runs in the context of the main process and is used to 176 * send commands, data, and file descriptors to the background process. 177 */ 178static void 179port_share_sendmsg (const socket_descriptor_t sd, 180 const char command, 181 const struct buffer *head, 182 const socket_descriptor_t sd_send) 183{ 184 if (socket_defined (sd)) 185 { 186 struct msghdr mesg; 187 struct cmsghdr* h; 188 struct iovec iov[2]; 189 socket_descriptor_t sd_null[2] = { SOCKET_UNDEFINED, SOCKET_UNDEFINED }; 190 char cmd; 191 ssize_t status; 192 193 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE: sendmsg sd=%d len=%d", 194 (int)sd_send, 195 head ? BLEN(head) : -1); 196 197 CLEAR (mesg); 198 199 cmd = command; 200 201 iov[0].iov_base = &cmd; 202 iov[0].iov_len = sizeof (cmd); 203 mesg.msg_iovlen = 1; 204 205 if (head) 206 { 207 iov[1].iov_base = BPTR (head); 208 iov[1].iov_len = BLEN (head); 209 mesg.msg_iovlen = 2; 210 } 211 212 mesg.msg_iov = iov; 213 214 mesg.msg_controllen = cmsg_size (); 215 mesg.msg_control = (char *) malloc (mesg.msg_controllen); 216 check_malloc_return (mesg.msg_control); 217 mesg.msg_flags = 0; 218 219 h = CMSG_FIRSTHDR(&mesg); 220 h->cmsg_level = SOL_SOCKET; 221 h->cmsg_type = SCM_RIGHTS; 222 h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t)); 223 224 if (socket_defined (sd_send)) 225 { 226 *((socket_descriptor_t*)CMSG_DATA(h)) = sd_send; 227 } 228 else 229 { 230 socketpair (PF_UNIX, SOCK_DGRAM, 0, sd_null); 231 *((socket_descriptor_t*)CMSG_DATA(h)) = sd_null[0]; 232 } 233 234 status = sendmsg (sd, &mesg, MSG_NOSIGNAL); 235 if (status == -1) 236 msg (M_WARN|M_ERRNO, "PORT SHARE: sendmsg failed -- unable to communicate with background process (%d,%d,%d,%d)", 237 sd, sd_send, sd_null[0], sd_null[1] 238 ); 239 240 close_socket_if_defined (sd_null[0]); 241 close_socket_if_defined (sd_null[1]); 242 free (mesg.msg_control); 243 } 244} 245 246static void 247proxy_entry_close_sd (struct proxy_connection *pc, struct event_set *es) 248{ 249 if (pc->defined && socket_defined (pc->sd)) 250 { 251 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: delete sd=%d", (int)pc->sd); 252 if (es) 253 event_del (es, pc->sd); 254 openvpn_close_socket (pc->sd); 255 pc->sd = SOCKET_UNDEFINED; 256 } 257} 258 259/* 260 * Mark a proxy entry and its counterpart for close. 261 */ 262static void 263proxy_entry_mark_for_close (struct proxy_connection *pc, struct event_set *es) 264{ 265 if (pc->defined) 266 { 267 struct proxy_connection *cp = pc->counterpart; 268 proxy_entry_close_sd (pc, es); 269 free_buf (&pc->buf); 270 pc->buffer_initial = false; 271 pc->rwflags = 0; 272 pc->defined = false; 273 if (pc->jfn) 274 { 275 unlink (pc->jfn); 276 free (pc->jfn); 277 pc->jfn = NULL; 278 } 279 if (cp && cp->defined && cp->counterpart == pc) 280 proxy_entry_mark_for_close (cp, es); 281 } 282} 283 284/* 285 * Run through the proxy entry list and delete all entries marked 286 * for close. 287 */ 288static void 289proxy_list_housekeeping (struct proxy_connection **list) 290{ 291 if (list) 292 { 293 struct proxy_connection *prev = NULL; 294 struct proxy_connection *pc = *list; 295 296 while (pc) 297 { 298 struct proxy_connection *next = pc->next; 299 if (!pc->defined) 300 { 301 free (pc); 302 if (prev) 303 prev->next = next; 304 else 305 *list = next; 306 } 307 else 308 prev = pc; 309 pc = next; 310 } 311 } 312} 313 314/* 315 * Record IP/port of client in filesystem, so that server receiving 316 * the proxy can determine true client origin. 317 */ 318static void 319journal_add (const char *journal_dir, struct proxy_connection *pc, struct proxy_connection *cp) 320{ 321 struct gc_arena gc = gc_new (); 322 struct openvpn_sockaddr from, to; 323 socklen_t slen, dlen; 324 int fnlen; 325 char *jfn; 326 int fd; 327 328 slen = sizeof(from.addr.sa); 329 dlen = sizeof(to.addr.sa); 330 if (!getpeername (pc->sd, (struct sockaddr *) &from.addr.sa, &slen) 331 && !getsockname (cp->sd, (struct sockaddr *) &to.addr.sa, &dlen)) 332 { 333 const char *f = print_sockaddr_ex (&from, ":", PS_SHOW_PORT, &gc); 334 const char *t = print_sockaddr_ex (&to, ":", PS_SHOW_PORT, &gc); 335 fnlen = strlen(journal_dir) + strlen(t) + 2; 336 jfn = (char *) malloc(fnlen); 337 check_malloc_return (jfn); 338 openvpn_snprintf (jfn, fnlen, "%s/%s", journal_dir, t); 339 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: client origin %s -> %s", jfn, f); 340 fd = platform_open (jfn, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP); 341 if (fd != -1) 342 { 343 write(fd, f, strlen(f)); 344 close (fd); 345 cp->jfn = jfn; 346 } 347 else 348 { 349 msg (M_WARN|M_ERRNO, "PORT SHARE: unable to write journal file in %s", jfn); 350 free (jfn); 351 } 352 } 353 gc_free (&gc); 354} 355 356/* 357 * Cleanup function, on proxy process exit. 358 */ 359static void 360proxy_list_close (struct proxy_connection **list) 361{ 362 if (list) 363 { 364 struct proxy_connection *pc = *list; 365 while (pc) 366 { 367 proxy_entry_mark_for_close (pc, NULL); 368 pc = pc->next; 369 } 370 proxy_list_housekeeping (list); 371 } 372} 373 374static void 375sock_addr_set (struct openvpn_sockaddr *osaddr, 376 const in_addr_t addr, 377 const int port) 378{ 379 CLEAR (*osaddr); 380 osaddr->addr.in4.sin_family = AF_INET; 381 osaddr->addr.in4.sin_addr.s_addr = htonl (addr); 382 osaddr->addr.in4.sin_port = htons (port); 383} 384 385static inline void 386proxy_connection_io_requeue (struct proxy_connection *pc, const int rwflags_new, struct event_set *es) 387{ 388 if (socket_defined (pc->sd) && pc->rwflags != rwflags_new) 389 { 390 /*dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: requeue[%d] rwflags=%d", (int)pc->sd, rwflags_new);*/ 391 event_ctl (es, pc->sd, rwflags_new, (void*)pc); 392 pc->rwflags = rwflags_new; 393 } 394} 395 396/* 397 * Create a new pair of proxy_connection entries, one for each 398 * socket file descriptor involved in the proxy. We are given 399 * the client fd, and we should derive our own server fd by connecting 400 * to the server given by server_addr/server_port. Return true 401 * on success and false on failure to connect to server. 402 */ 403static bool 404proxy_entry_new (struct proxy_connection **list, 405 struct event_set *es, 406 const in_addr_t server_addr, 407 const int server_port, 408 const socket_descriptor_t sd_client, 409 struct buffer *initial_data, 410 const char *journal_dir) 411{ 412 struct openvpn_sockaddr osaddr; 413 socket_descriptor_t sd_server; 414 int status; 415 struct proxy_connection *pc; 416 struct proxy_connection *cp; 417 418 /* connect to port share server */ 419 sock_addr_set (&osaddr, server_addr, server_port); 420 if ((sd_server = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) 421 { 422 msg (M_WARN|M_ERRNO, "PORT SHARE PROXY: cannot create socket"); 423 return false; 424 } 425 status = openvpn_connect (sd_server, &osaddr, 5, NULL); 426 if (status) 427 { 428 msg (M_WARN, "PORT SHARE PROXY: connect to port-share server failed"); 429 openvpn_close_socket (sd_server); 430 return false; 431 } 432 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: connect to port-share server succeeded"); 433 434 set_nonblock (sd_client); 435 set_nonblock (sd_server); 436 437 /* allocate 2 new proxy_connection objects */ 438 ALLOC_OBJ_CLEAR (pc, struct proxy_connection); 439 ALLOC_OBJ_CLEAR (cp, struct proxy_connection); 440 441 /* client object */ 442 pc->defined = true; 443 pc->next = cp; 444 pc->counterpart = cp; 445 pc->buf = *initial_data; 446 pc->buffer_initial = true; 447 pc->rwflags = EVENT_UNDEF; 448 pc->sd = sd_client; 449 450 /* server object */ 451 cp->defined = true; 452 cp->next = *list; 453 cp->counterpart = pc; 454 cp->buf = alloc_buf (PROXY_CONNECTION_BUFFER_SIZE); 455 cp->buffer_initial = false; 456 cp->rwflags = EVENT_UNDEF; 457 cp->sd = sd_server; 458 459 /* add to list */ 460 *list = pc; 461 462 /* add journal entry */ 463 if (journal_dir) 464 journal_add (journal_dir, pc, cp); 465 466 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: NEW CONNECTION [c=%d s=%d]", (int)sd_client, (int)sd_server); 467 468 /* set initial i/o states */ 469 proxy_connection_io_requeue (pc, EVENT_READ, es); 470 proxy_connection_io_requeue (cp, EVENT_READ|EVENT_WRITE, es); 471 472 return true; 473} 474 475/* 476 * This function runs in the context of the background proxy process. 477 * Receive a control message from the parent (sent by the port_share_sendmsg 478 * function above) and act on it. Return false if the proxy process should 479 * exit, true otherwise. 480 */ 481static bool 482control_message_from_parent (const socket_descriptor_t sd_control, 483 struct proxy_connection **list, 484 struct event_set *es, 485 const in_addr_t server_addr, 486 const int server_port, 487 const int max_initial_buf, 488 const char *journal_dir) 489{ 490 /* this buffer needs to be large enough to handle the largest buffer 491 that might be returned by the link_socket_read call in read_incoming_link. */ 492 struct buffer buf = alloc_buf (max_initial_buf); 493 494 struct msghdr mesg; 495 struct cmsghdr* h; 496 struct iovec iov[2]; 497 char command = 0; 498 ssize_t status; 499 int ret = true; 500 501 CLEAR (mesg); 502 503 iov[0].iov_base = &command; 504 iov[0].iov_len = sizeof (command); 505 iov[1].iov_base = BPTR (&buf); 506 iov[1].iov_len = BCAP (&buf); 507 mesg.msg_iov = iov; 508 mesg.msg_iovlen = 2; 509 510 mesg.msg_controllen = cmsg_size (); 511 mesg.msg_control = (char *) malloc (mesg.msg_controllen); 512 check_malloc_return (mesg.msg_control); 513 mesg.msg_flags = 0; 514 515 h = CMSG_FIRSTHDR(&mesg); 516 h->cmsg_len = CMSG_LEN(sizeof(socket_descriptor_t)); 517 h->cmsg_level = SOL_SOCKET; 518 h->cmsg_type = SCM_RIGHTS; 519 *((socket_descriptor_t*)CMSG_DATA(h)) = SOCKET_UNDEFINED; 520 521 status = recvmsg (sd_control, &mesg, MSG_NOSIGNAL); 522 if (status != -1) 523 { 524 if ( h == NULL 525 || h->cmsg_len != CMSG_LEN(sizeof(socket_descriptor_t)) 526 || h->cmsg_level != SOL_SOCKET 527 || h->cmsg_type != SCM_RIGHTS ) 528 { 529 msg (M_WARN, "PORT SHARE PROXY: received unknown message"); 530 } 531 else 532 { 533 const socket_descriptor_t received_fd = *((socket_descriptor_t*)CMSG_DATA(h)); 534 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED sd=%d", (int)received_fd); 535 536 if (status >= 2 && command == COMMAND_REDIRECT) 537 { 538 buf.len = status - 1; 539 if (proxy_entry_new (list, 540 es, 541 server_addr, 542 server_port, 543 received_fd, 544 &buf, 545 journal_dir)) 546 { 547 CLEAR (buf); /* we gave the buffer to proxy_entry_new */ 548 } 549 else 550 { 551 openvpn_close_socket (received_fd); 552 } 553 } 554 else if (status >= 1 && command == COMMAND_EXIT) 555 { 556 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: RECEIVED COMMAND_EXIT"); 557 openvpn_close_socket (received_fd); /* null socket */ 558 ret = false; 559 } 560 } 561 } 562 free (mesg.msg_control); 563 free_buf (&buf); 564 return ret; 565} 566 567static int 568proxy_connection_io_recv (struct proxy_connection *pc) 569{ 570 /* recv data from socket */ 571 const int status = recv (pc->sd, BPTR(&pc->buf), BCAP(&pc->buf), MSG_NOSIGNAL); 572 if (status < 0) 573 { 574 return (errno == EAGAIN) ? IOSTAT_EAGAIN_ON_READ : IOSTAT_READ_ERROR; 575 } 576 else 577 { 578 if (!status) 579 return IOSTAT_READ_ERROR; 580 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: read[%d] %d", (int)pc->sd, status); 581 pc->buf.len = status; 582 } 583 return IOSTAT_GOOD; 584} 585 586static int 587proxy_connection_io_send (struct proxy_connection *pc, int *bytes_sent) 588{ 589 const socket_descriptor_t sd = pc->counterpart->sd; 590 const int status = send (sd, BPTR(&pc->buf), BLEN(&pc->buf), MSG_NOSIGNAL); 591 592 if (status < 0) 593 { 594 const int e = errno; 595 return (e == EAGAIN) ? IOSTAT_EAGAIN_ON_WRITE : IOSTAT_WRITE_ERROR; 596 } 597 else 598 { 599 *bytes_sent += status; 600 if (status != pc->buf.len) 601 { 602 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: partial write[%d], tried=%d got=%d", (int)sd, pc->buf.len, status); 603 buf_advance (&pc->buf, status); 604 return IOSTAT_EAGAIN_ON_WRITE; 605 } 606 else 607 { 608 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: wrote[%d] %d", (int)sd, status); 609 pc->buf.len = 0; 610 pc->buf.offset = 0; 611 } 612 } 613 614 /* realloc send buffer after initial send */ 615 if (pc->buffer_initial) 616 { 617 free_buf (&pc->buf); 618 pc->buf = alloc_buf (PROXY_CONNECTION_BUFFER_SIZE); 619 pc->buffer_initial = false; 620 } 621 return IOSTAT_GOOD; 622} 623 624/* 625 * Forward data from pc to pc->counterpart. 626 */ 627 628static int 629proxy_connection_io_xfer (struct proxy_connection *pc, const int max_transfer) 630{ 631 int transferred = 0; 632 while (transferred < max_transfer) 633 { 634 if (!BLEN (&pc->buf)) 635 { 636 const int status = proxy_connection_io_recv (pc); 637 if (status != IOSTAT_GOOD) 638 return status; 639 } 640 641 if (BLEN (&pc->buf)) 642 { 643 const int status = proxy_connection_io_send (pc, &transferred); 644 if (status != IOSTAT_GOOD) 645 return status; 646 } 647 } 648 return IOSTAT_EAGAIN_ON_READ; 649} 650 651/* 652 * Decide how the receipt of an EAGAIN status should affect our next IO queueing. 653 */ 654static bool 655proxy_connection_io_status (const int status, int *rwflags_pc, int *rwflags_cp) 656{ 657 switch (status) 658 { 659 case IOSTAT_EAGAIN_ON_READ: 660 *rwflags_pc |= EVENT_READ; 661 *rwflags_cp &= ~EVENT_WRITE; 662 return true; 663 case IOSTAT_EAGAIN_ON_WRITE: 664 *rwflags_pc &= ~EVENT_READ; 665 *rwflags_cp |= EVENT_WRITE; 666 return true; 667 case IOSTAT_READ_ERROR: 668 return false; 669 case IOSTAT_WRITE_ERROR: 670 return false; 671 default: 672 msg (M_FATAL, "PORT SHARE PROXY: unexpected status=%d", status); 673 } 674 return false; /* NOTREACHED */ 675} 676 677/* 678 * Dispatch function for forwarding data between the two socket fds involved 679 * in the proxied connection. 680 */ 681static int 682proxy_connection_io_dispatch (struct proxy_connection *pc, 683 const int rwflags, 684 struct event_set *es) 685{ 686 const int max_transfer_per_iteration = 10000; 687 struct proxy_connection *cp = pc->counterpart; 688 int rwflags_pc = pc->rwflags; 689 int rwflags_cp = cp->rwflags; 690 691 ASSERT(pc->defined && cp->defined && cp->counterpart == pc); 692 693 if (rwflags & EVENT_READ) 694 { 695 const int status = proxy_connection_io_xfer (pc, max_transfer_per_iteration); 696 if (!proxy_connection_io_status (status, &rwflags_pc, &rwflags_cp)) 697 goto bad; 698 } 699 if (rwflags & EVENT_WRITE) 700 { 701 const int status = proxy_connection_io_xfer (cp, max_transfer_per_iteration); 702 if (!proxy_connection_io_status (status, &rwflags_cp, &rwflags_pc)) 703 goto bad; 704 } 705 proxy_connection_io_requeue (pc, rwflags_pc, es); 706 proxy_connection_io_requeue (cp, rwflags_cp, es); 707 708 return true; 709 710 bad: 711 proxy_entry_mark_for_close (pc, es); 712 return false; 713} 714 715/* 716 * This is the main function for the port share proxy background process. 717 */ 718static void 719port_share_proxy (const in_addr_t hostaddr, 720 const int port, 721 const socket_descriptor_t sd_control, 722 const int max_initial_buf, 723 const char *journal_dir) 724{ 725 if (send_control (sd_control, RESPONSE_INIT_SUCCEEDED) >= 0) 726 { 727 void *sd_control_marker = (void *)1; 728 int maxevents = 256; 729 struct event_set *es; 730 struct event_set_return esr[64]; 731 struct proxy_connection *list = NULL; 732 time_t last_housekeeping = 0; 733 734 msg (D_PS_PROXY, "PORT SHARE PROXY: proxy starting"); 735 736 es = event_set_init (&maxevents, 0); 737 event_ctl (es, sd_control, EVENT_READ, sd_control_marker); 738 while (true) 739 { 740 int n_events; 741 struct timeval tv; 742 time_t current; 743 744 tv.tv_sec = 10; 745 tv.tv_usec = 0; 746 n_events = event_wait (es, &tv, esr, SIZE(esr)); 747 /*dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: event_wait returned %d", n_events);*/ 748 current = time(NULL); 749 if (n_events > 0) 750 { 751 int i; 752 for (i = 0; i < n_events; ++i) 753 { 754 const struct event_set_return *e = &esr[i]; 755 if (e->arg == sd_control_marker) 756 { 757 if (!control_message_from_parent (sd_control, &list, es, hostaddr, port, max_initial_buf, journal_dir)) 758 goto done; 759 } 760 else 761 { 762 struct proxy_connection *pc = (struct proxy_connection *)e->arg; 763 if (pc->defined) 764 proxy_connection_io_dispatch (pc, e->rwflags, es); 765 } 766 } 767 } 768 else if (n_events < 0) 769 { 770 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE PROXY: event_wait failed"); 771 } 772 if (current > last_housekeeping) 773 { 774 proxy_list_housekeeping (&list); 775 last_housekeeping = current; 776 } 777 } 778 779 done: 780 proxy_list_close (&list); 781 event_free (es); 782 } 783 msg (M_INFO, "PORT SHARE PROXY: proxy exiting"); 784} 785 786/* 787 * Called from the main OpenVPN process to enable the port 788 * share proxy. 789 */ 790struct port_share * 791port_share_open (const char *host, 792 const int port, 793 const int max_initial_buf, 794 const char *journal_dir) 795{ 796 pid_t pid; 797 socket_descriptor_t fd[2]; 798 in_addr_t hostaddr; 799 struct port_share *ps; 800 801 ALLOC_OBJ_CLEAR (ps, struct port_share); 802 ps->foreground_fd = -1; 803 ps->background_pid = -1; 804 805 /* 806 * Get host's IP address 807 */ 808 hostaddr = getaddr (GETADDR_RESOLVE|GETADDR_HOST_ORDER|GETADDR_FATAL, host, 0, NULL, NULL); 809 810 /* 811 * Make a socket for foreground and background processes 812 * to communicate. 813 */ 814 if (socketpair (PF_UNIX, SOCK_DGRAM, 0, fd) == -1) 815 { 816 msg (M_WARN, "PORT SHARE: socketpair call failed"); 817 goto error; 818 } 819 820 /* 821 * Fork off background proxy process. 822 */ 823 pid = fork (); 824 825 if (pid) 826 { 827 int status; 828 829 /* 830 * Foreground Process 831 */ 832 833 ps->background_pid = pid; 834 835 /* close our copy of child's socket */ 836 openvpn_close_socket (fd[1]); 837 838 /* don't let future subprocesses inherit child socket */ 839 set_cloexec (fd[0]); 840 841 /* wait for background child process to initialize */ 842 status = recv_control (fd[0]); 843 if (status == RESPONSE_INIT_SUCCEEDED) 844 { 845 /* note that this will cause possible EAGAIN when writing to 846 control socket if proxy process is backlogged */ 847 set_nonblock (fd[0]); 848 849 ps->foreground_fd = fd[0]; 850 return ps; 851 } 852 else 853 { 854 msg (M_ERR, "PORT SHARE: unexpected init recv_control status=%d", status); 855 } 856 } 857 else 858 { 859 /* 860 * Background Process 861 */ 862 863 /* Ignore most signals (the parent will receive them) */ 864 set_signals (); 865 866 /* Let msg know that we forked */ 867 msg_forked (); 868 869#ifdef ENABLE_MANAGEMENT 870 /* Don't interact with management interface */ 871 management = NULL; 872#endif 873 874 /* close all parent fds except our socket back to parent */ 875 close_fds_except (fd[1]); 876 877 /* no blocking on control channel back to parent */ 878 set_nonblock (fd[1]); 879 880 /* initialize prng */ 881 prng_init (NULL, 0); 882 883 /* execute the event loop */ 884 port_share_proxy (hostaddr, port, fd[1], max_initial_buf, journal_dir); 885 886 openvpn_close_socket (fd[1]); 887 888 exit (0); 889 return 0; /* NOTREACHED */ 890 } 891 892 error: 893 port_share_close (ps); 894 return NULL; 895} 896 897void 898port_share_close (struct port_share *ps) 899{ 900 if (ps) 901 { 902 if (ps->foreground_fd >= 0) 903 { 904 /* tell background process to exit */ 905 port_share_sendmsg (ps->foreground_fd, COMMAND_EXIT, NULL, SOCKET_UNDEFINED); 906 907 /* wait for background process to exit */ 908 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE: waiting for background process to exit"); 909 if (ps->background_pid > 0) 910 waitpid (ps->background_pid, NULL, 0); 911 dmsg (D_PS_PROXY_DEBUG, "PORT SHARE: background process exited"); 912 913 openvpn_close_socket (ps->foreground_fd); 914 ps->foreground_fd = -1; 915 } 916 917 free (ps); 918 } 919} 920 921void 922port_share_abort (struct port_share *ps) 923{ 924 if (ps) 925 { 926 /* tell background process to exit */ 927 if (ps->foreground_fd >= 0) 928 { 929 send_control (ps->foreground_fd, COMMAND_EXIT); 930 openvpn_close_socket (ps->foreground_fd); 931 ps->foreground_fd = -1; 932 } 933 } 934} 935 936/* 937 * Given either the first 2 or 3 bytes of an initial client -> server 938 * data payload, return true if the protocol is that of an OpenVPN 939 * client attempting to connect with an OpenVPN server. 940 */ 941bool 942is_openvpn_protocol (const struct buffer *buf) 943{ 944 const unsigned char *p = (const unsigned char *) BSTR (buf); 945 const int len = BLEN (buf); 946 if (len >= 3) 947 { 948 return p[0] == 0 949 && p[1] >= 14 950 && p[2] == (P_CONTROL_HARD_RESET_CLIENT_V2<<P_OPCODE_SHIFT); 951 } 952 else if (len >= 2) 953 { 954 return p[0] == 0 && p[1] >= 14; 955 } 956 else 957 return true; 958} 959 960/* 961 * Called from the foreground process. Send a message to the background process that it 962 * should proxy the TCP client on sd to the host/port defined in the initial port_share_open 963 * call. 964 */ 965void 966port_share_redirect (struct port_share *ps, const struct buffer *head, socket_descriptor_t sd) 967{ 968 if (ps) 969 { 970 port_share_sendmsg (ps->foreground_fd, COMMAND_REDIRECT, head, sd); 971 } 972} 973 974#endif 975