OSDN Git Service

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