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 
40 struct 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  */
67 struct 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
79 static const char *
80 headc(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 
89 static inline void
90 close_socket_if_defined(const socket_descriptor_t sd)
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  */
108 static void
109 close_fds_except(int keep)
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  */
126 static void
127 set_signals(void)
128 {
129  signal(SIGTERM, SIG_DFL);
130 
131  signal(SIGINT, SIG_IGN);
132  signal(SIGHUP, SIG_IGN);
133  signal(SIGUSR1, SIG_IGN);
134  signal(SIGUSR2, SIG_IGN);
135  signal(SIGPIPE, SIG_IGN);
136 }
137 
138 /*
139  * Socket read/write functions.
140  */
141 
142 static 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 
157 static int
158 send_control(const socket_descriptor_t fd, int code)
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 
172 static int
173 cmsg_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  */
185 static void
186 port_share_sendmsg(const socket_descriptor_t sd,
187  const char command,
188  const struct buffer *head,
189  const socket_descriptor_t sd_send)
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 
255 static void
256 proxy_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  */
273 static void
274 proxy_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  */
301 static void
302 proxy_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  */
337 static void
338 journal_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.sa);
348  dlen = sizeof(to.addr.sa);
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);
356  check_malloc_return(jfn);
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  */
381 static void
382 proxy_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 
396 static inline void
397 proxy_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  */
414 static bool
415 proxy_entry_new(struct proxy_connection **list,
416  struct event_set *es,
417  const struct sockaddr_in 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(PF_INET, 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, (const struct sockaddr *) &server_addr, 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  */
491 static bool
492 control_message_from_parent(const socket_descriptor_t sd_control,
493  struct proxy_connection **list,
494  struct event_set *es,
495  const struct sockaddr_in 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 
577 static int
578 proxy_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 
598 static int
599 proxy_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 
640 static int
641 proxy_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  */
670 static bool
671 proxy_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  */
701 static int
702 proxy_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 
734 bad:
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  */
742 static void
743 port_share_proxy(const struct sockaddr_in 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 
806 done:
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  */
817 struct port_share *
818 port_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;
824  socket_descriptor_t fd[2];
825  struct sockaddr_in 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_INET, &ai);
840  ASSERT(status==0);
841  hostaddr = *((struct sockaddr_in *) ai->ai_addr);
842  freeaddrinfo(ai);
843 
844  /*
845  * Make a socket for foreground and background processes
846  * to communicate.
847  */
848  if (socketpair(PF_UNIX, SOCK_DGRAM, 0, fd) == -1)
849  {
850  msg(M_WARN, "PORT SHARE: socketpair call failed");
851  goto error;
852  }
853 
854  /*
855  * Fork off background proxy process.
856  */
857  pid = fork();
858 
859  if (pid)
860  {
861  int status;
862 
863  /*
864  * Foreground Process
865  */
866 
867  ps->background_pid = pid;
868 
869  /* close our copy of child's socket */
870  openvpn_close_socket(fd[1]);
871 
872  /* don't let future subprocesses inherit child socket */
873  set_cloexec(fd[0]);
874 
875  /* wait for background child process to initialize */
876  status = recv_control(fd[0]);
878  {
879  /* note that this will cause possible EAGAIN when writing to
880  * control socket if proxy process is backlogged */
881  set_nonblock(fd[0]);
882 
883  ps->foreground_fd = fd[0];
884  return ps;
885  }
886  else
887  {
888  msg(M_ERR, "PORT SHARE: unexpected init recv_control status=%d", status);
889  }
890  }
891  else
892  {
893  /*
894  * Background Process
895  */
896 
897  /* Ignore most signals (the parent will receive them) */
898  set_signals();
899 
900  /* Let msg know that we forked */
901  msg_forked();
902 
903 #ifdef ENABLE_MANAGEMENT
904  /* Don't interact with management interface */
905  management = NULL;
906 #endif
907 
908  /* close all parent fds except our socket back to parent */
909  close_fds_except(fd[1]);
910 
911  /* no blocking on control channel back to parent */
912  set_nonblock(fd[1]);
913 
914  /* execute the event loop */
915  port_share_proxy(hostaddr, fd[1], max_initial_buf, journal_dir);
916 
917  openvpn_close_socket(fd[1]);
918 
919  exit(0);
920  return NULL; /* NOTREACHED */
921  }
922 
923 error:
924  port_share_close(ps);
925  return NULL;
926 }
927 
928 void
929 port_share_close(struct port_share *ps)
930 {
931  if (ps)
932  {
933  if (ps->foreground_fd >= 0)
934  {
935  /* tell background process to exit */
936  port_share_sendmsg(ps->foreground_fd, COMMAND_EXIT, NULL, SOCKET_UNDEFINED);
937 
938  /* wait for background process to exit */
939  dmsg(D_PS_PROXY_DEBUG, "PORT SHARE: waiting for background process to exit");
940  if (ps->background_pid > 0)
941  {
942  waitpid(ps->background_pid, NULL, 0);
943  }
944  dmsg(D_PS_PROXY_DEBUG, "PORT SHARE: background process exited");
945 
946  openvpn_close_socket(ps->foreground_fd);
947  ps->foreground_fd = -1;
948  }
949 
950  free(ps);
951  }
952 }
953 
954 void
955 port_share_abort(struct port_share *ps)
956 {
957  if (ps)
958  {
959  /* tell background process to exit */
960  if (ps->foreground_fd >= 0)
961  {
962  send_control(ps->foreground_fd, COMMAND_EXIT);
963  openvpn_close_socket(ps->foreground_fd);
964  ps->foreground_fd = -1;
965  }
966  }
967 }
968 
969 /*
970  * Given either the first 2 or 3 bytes of an initial client -> server
971  * data payload, return true if the protocol is that of an OpenVPN
972  * client attempting to connect with an OpenVPN server.
973  */
974 bool
975 is_openvpn_protocol(const struct buffer *buf)
976 {
977  const unsigned char *p = (const unsigned char *) BSTR(buf);
978  const int len = BLEN(buf);
979  if (len >= 3)
980  {
981  int plen = (p[0] << 8) | p[1];
982 
984  {
985  /* WKc is at least 290 byte (not including metadata):
986  *
987  * 16 bit len + 256 bit HMAC + 2048 bit Kc = 2320 bit
988  *
989  * This is increased by the normal length of client handshake +
990  * tls-crypt overhead (32)
991  *
992  * For metadata tls-crypt-v2.txt does not explicitly specify
993  * an upper limit but we also have TLS_CRYPT_V2_MAX_WKC_LEN
994  * as 1024 bytes. We err on the safe side with 255 extra overhead
995  *
996  * We don't do the 2 byte check for tls-crypt-v2 because it is very
997  * unrealistic to have only 2 bytes available.
998  */
999  return (plen >= 336 && plen < (1024 + 255));
1000  }
1001  else
1002  {
1003  /* For non tls-crypt2 we assume the packet length to valid between
1004  * 14 and 255 */
1005  return plen >= 14 && plen <= 255
1007  }
1008  }
1009  else if (len >= 2)
1010  {
1011  int plen = (p[0] << 8) | p[1];
1012  return plen >= 14 && plen <= 255;
1013  }
1014  else
1015  {
1016  return true;
1017  }
1018 }
1019 
1020 /*
1021  * Called from the foreground process. Send a message to the background process that it
1022  * should proxy the TCP client on sd to the host/port defined in the initial port_share_open
1023  * call.
1024  */
1025 void
1026 port_share_redirect(struct port_share *ps, const struct buffer *head, socket_descriptor_t sd)
1027 {
1028  if (ps)
1029  {
1030  port_share_sendmsg(ps->foreground_fd, COMMAND_REDIRECT, head, sd);
1031  }
1032 }
1033 
1034 #endif /* if PORT_SHARE */
M_INFO
#define M_INFO
Definition: errlevel.h:55
gc_new
static struct gc_arena gc_new(void)
Definition: buffer.h:1030
M_ERRNO
#define M_ERRNO
Definition: error.h:94
buffer::len
int len
Length in bytes of the actual content within the allocated memory.
Definition: buffer.h:66
M_FATAL
#define M_FATAL
Definition: error.h:89
P_CONTROL_HARD_RESET_CLIENT_V2
#define P_CONTROL_HARD_RESET_CLIENT_V2
Definition: ssl_pkt.h:51
es
struct env_set * es
Definition: test_pkcs11.c:133
BSTR
#define BSTR(buf)
Definition: buffer.h:129
D_PS_PROXY_DEBUG
#define D_PS_PROXY_DEBUG
Definition: errlevel.h:145
dmsg
#define dmsg(flags,...)
Definition: error.h:148
fdmisc.h
openvpn_sockaddr
Definition: socket.h:65
EVENT_READ
#define EVENT_READ
Definition: event.h:39
COMMAND_EXIT
#define COMMAND_EXIT
Definition: auth-pam.c:59
P_OPCODE_SHIFT
#define P_OPCODE_SHIFT
Definition: ssl_pkt.h:39
openvpn_getaddrinfo
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:429
CLEAR
#define CLEAR(x)
Definition: basic.h:33
event_ctl
static void event_ctl(struct event_set *es, event_t event, unsigned int rwflags, void *arg)
Definition: event.h:160
event_del
static void event_del(struct event_set *es, event_t event)
Definition: event.h:154
P_CONTROL_HARD_RESET_CLIENT_V3
#define P_CONTROL_HARD_RESET_CLIENT_V3
Definition: ssl_pkt.h:55
ASSERT
#define ASSERT(x)
Definition: error.h:195
read
@ read
Definition: interactive.c:218
msg_forked
void msg_forked(void)
Definition: error.c:99
buf_advance
static bool buf_advance(struct buffer *buf, int size)
Definition: buffer.h:623
write
@ write
Definition: interactive.c:219
BLEN
#define BLEN(buf)
Definition: buffer.h:127
event_set_return::arg
void * arg
Definition: event.h:121
EVENT_UNDEF
#define EVENT_UNDEF
Definition: event.h:38
M_WARN
#define M_WARN
Definition: error.h:91
crypto.h
GETADDR_RESOLVE
#define GETADDR_RESOLVE
Definition: socket.h:504
M_ERR
#define M_ERR
Definition: error.h:105
D_PS_PROXY
#define D_PS_PROXY
Definition: errlevel.h:92
set_nonblock
void set_nonblock(socket_descriptor_t fd)
Definition: fdmisc.c:69
SIZE
#define SIZE(x)
Definition: basic.h:30
buffer
Wrapper structure for dynamically allocated memory.
Definition: buffer.h:60
event.h
socket_defined
static int socket_defined(const socket_descriptor_t sd)
Definition: syshead.h:437
ps.h
BCAP
#define BCAP(buf)
Definition: buffer.h:130
recv_control
static int recv_control(int fd)
Definition: auth-pam.c:138
syshead.h
BPTR
#define BPTR(buf)
Definition: buffer.h:124
send_control
static int send_control(int fd, int code)
Definition: auth-pam.c:154
gc_arena
Garbage collection arena used to keep track of dynamically allocated memory.
Definition: buffer.h:116
SOCKET_UNDEFINED
#define SOCKET_UNDEFINED
Definition: syshead.h:427
free_buf
void free_buf(struct buffer *buf)
Definition: buffer.c:183
socket_descriptor_t
SOCKET socket_descriptor_t
Definition: syshead.h:429
event_free
static void event_free(struct event_set *es)
Definition: event.h:139
set_cloexec
void set_cloexec(socket_descriptor_t fd)
Definition: fdmisc.c:79
event_set
Definition: event.h:124
status
static SERVICE_STATUS status
Definition: interactive.c:53
close_fds_except
static void close_fds_except(int keep)
Definition: auth-pam.c:251
management
Definition: manage.h:335
gc_free
static void gc_free(struct gc_arena *a)
Definition: buffer.h:1038
event_set_init
struct event_set * event_set_init(int *maxevents, unsigned int flags)
Definition: event.c:1186
event_set_return
Definition: event.h:118
socket.h
ALLOC_OBJ_CLEAR
#define ALLOC_OBJ_CLEAR(dptr, type)
Definition: buffer.h:1065
openvpn_close_socket
#define openvpn_close_socket(s)
Definition: socket.h:259
config.h
openvpn_connect
int openvpn_connect(socket_descriptor_t sd, const struct sockaddr *remote, int connect_timeout, volatile int *signal_received)
Definition: socket.c:1434
EVENT_WRITE
#define EVENT_WRITE
Definition: event.h:40
check_malloc_return
static void check_malloc_return(void *p)
Definition: buffer.h:1108
MSG_NOSIGNAL
#define MSG_NOSIGNAL
Definition: socket.h:254
platform_open
int platform_open(const char *path, int flags, int mode)
Definition: platform.c:527
event_set_return::rwflags
unsigned int rwflags
Definition: event.h:120
print_openvpn_sockaddr
static const char * print_openvpn_sockaddr(const struct openvpn_sockaddr *addr, struct gc_arena *gc)
Definition: socket.h:363
alloc_buf
struct buffer alloc_buf(size_t size)
Definition: buffer.c:62
memdbg.h
msg
#define msg(flags,...)
Definition: error.h:144
http-client.f
string f
Definition: http-client.py:6
event_wait
static int event_wait(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen)
Definition: event.h:166
set_signals
static void set_signals(void)
Definition: auth-pam.c:269
GETADDR_FATAL
#define GETADDR_FATAL
Definition: socket.h:505
RESPONSE_INIT_SUCCEEDED
#define RESPONSE_INIT_SUCCEEDED
Definition: auth-pam.c:62