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