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