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