1/*
2 *  OpenVPN -- An application to securely tunnel IP networks
3 *             over a single TCP/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-2010 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/*
26 * 2004-01-30: Added Socks5 proxy support, see RFC 1928
27 *   (Christof Meerwald, http://cmeerw.org)
28 *
29 * 2010-10-10: Added Socks5 plain text authentication support (RFC 1929)
30 *   (Pierre Bourdon <delroth@gmail.com>)
31 */
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#elif defined(_MSC_VER)
36#include "config-msvc.h"
37#endif
38
39#include "syshead.h"
40
41#ifdef ENABLE_SOCKS
42
43#include "common.h"
44#include "misc.h"
45#include "win32.h"
46#include "socket.h"
47#include "fdmisc.h"
48#include "misc.h"
49#include "proxy.h"
50
51#include "memdbg.h"
52
53#define UP_TYPE_SOCKS		"SOCKS Proxy"
54
55void
56socks_adjust_frame_parameters (struct frame *frame, int proto)
57{
58  if (proto == PROTO_UDPv4)
59    frame_add_to_extra_link (frame, 10);
60}
61
62struct socks_proxy_info *
63socks_proxy_new (const char *server,
64		 int port,
65		 const char *authfile,
66		 bool retry)
67{
68  struct socks_proxy_info *p;
69
70  ALLOC_OBJ_CLEAR (p, struct socks_proxy_info);
71
72  ASSERT (server);
73  ASSERT (legal_ipv4_port (port));
74
75  strncpynt (p->server, server, sizeof (p->server));
76  p->port = port;
77
78  if (authfile)
79    strncpynt (p->authfile, authfile, sizeof (p->authfile));
80  else
81    p->authfile[0] = 0;
82
83  p->retry = retry;
84  p->defined = true;
85
86  return p;
87}
88
89void
90socks_proxy_close (struct socks_proxy_info *sp)
91{
92  free (sp);
93}
94
95static bool
96socks_username_password_auth (struct socks_proxy_info *p,
97                              socket_descriptor_t sd,
98                              volatile int *signal_received)
99{
100  char to_send[516];
101  char buf[2];
102  int len = 0;
103  const int timeout_sec = 5;
104  struct user_pass creds;
105  ssize_t size;
106
107  creds.defined = 0;
108  get_user_pass (&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT);
109
110  if( !creds.username || (strlen(creds.username) > 255)
111      || !creds.password || (strlen(creds.password) > 255) ) {
112          msg (M_NONFATAL,
113               "SOCKS username and/or password exceeds 255 characters.  "
114               "Authentication not possible.");
115          return false;
116  }
117  openvpn_snprintf (to_send, sizeof (to_send), "\x01%c%s%c%s", (int) strlen(creds.username),
118            creds.username, (int) strlen(creds.password), creds.password);
119  size = send (sd, to_send, strlen(to_send), MSG_NOSIGNAL);
120
121  if (size != strlen (to_send))
122    {
123      msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port write failed on send()");
124      return false;
125    }
126
127  while (len < 2)
128    {
129      int status;
130      ssize_t size;
131      fd_set reads;
132      struct timeval tv;
133      char c;
134
135      FD_ZERO (&reads);
136      FD_SET (sd, &reads);
137      tv.tv_sec = timeout_sec;
138      tv.tv_usec = 0;
139
140      status = select (sd + 1, &reads, NULL, NULL, &tv);
141
142      get_signal (signal_received);
143      if (*signal_received)
144	return false;
145
146      /* timeout? */
147      if (status == 0)
148	{
149	  msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read timeout expired");
150	  return false;
151	}
152
153      /* error */
154      if (status < 0)
155	{
156	  msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on select()");
157	  return false;
158	}
159
160      /* read single char */
161      size = recv(sd, &c, 1, MSG_NOSIGNAL);
162
163      /* error? */
164      if (size != 1)
165	{
166	  msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on recv()");
167	  return false;
168	}
169
170      /* store char in buffer */
171      buf[len++] = c;
172    }
173
174  /* VER = 5, SUCCESS = 0 --> auth success */
175  if (buf[0] != 5 && buf[1] != 0)
176  {
177    msg (D_LINK_ERRORS, "socks_username_password_auth: server refused the authentication");
178    return false;
179  }
180
181  return true;
182}
183
184static bool
185socks_handshake (struct socks_proxy_info *p,
186                 socket_descriptor_t sd,
187                 volatile int *signal_received)
188{
189  char buf[2];
190  int len = 0;
191  const int timeout_sec = 5;
192
193  /* VER = 5, NMETHODS = 2, METHODS = [0 (no auth), 2 (plain login)] */
194  const ssize_t size = send (sd, "\x05\x02\x00\x02", 4, MSG_NOSIGNAL);
195  if (size != 4)
196    {
197      msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port write failed on send()");
198      return false;
199    }
200
201  while (len < 2)
202    {
203      int status;
204      ssize_t size;
205      fd_set reads;
206      struct timeval tv;
207      char c;
208
209      FD_ZERO (&reads);
210      FD_SET (sd, &reads);
211      tv.tv_sec = timeout_sec;
212      tv.tv_usec = 0;
213
214      status = select (sd + 1, &reads, NULL, NULL, &tv);
215
216      get_signal (signal_received);
217      if (*signal_received)
218	return false;
219
220      /* timeout? */
221      if (status == 0)
222	{
223	  msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read timeout expired");
224	  return false;
225	}
226
227      /* error */
228      if (status < 0)
229	{
230	  msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on select()");
231	  return false;
232	}
233
234      /* read single char */
235      size = recv(sd, &c, 1, MSG_NOSIGNAL);
236
237      /* error? */
238      if (size != 1)
239	{
240	  msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on recv()");
241	  return false;
242	}
243
244      /* store char in buffer */
245      buf[len++] = c;
246    }
247
248  /* VER == 5 */
249  if (buf[0] != '\x05')
250    {
251      msg (D_LINK_ERRORS, "socks_handshake: Socks proxy returned bad status");
252      return false;
253    }
254
255  /* select the appropriate authentication method */
256  switch (buf[1])
257    {
258    case 0: /* no authentication */
259      break;
260
261    case 2: /* login/password */
262      if (!p->authfile[0])
263      {
264	msg(D_LINK_ERRORS, "socks_handshake: server asked for username/login auth but we were "
265	                   "not provided any credentials");
266	return false;
267      }
268
269      if (!socks_username_password_auth(p, sd, signal_received))
270	return false;
271
272      break;
273
274    default: /* unknown auth method */
275      msg(D_LINK_ERRORS, "socks_handshake: unknown SOCKS auth method");
276      return false;
277    }
278
279  return true;
280}
281
282static bool
283recv_socks_reply (socket_descriptor_t sd,
284		  struct openvpn_sockaddr *addr,
285		  volatile int *signal_received)
286{
287  char atyp = '\0';
288  int alen = 0;
289  int len = 0;
290  char buf[22];
291  const int timeout_sec = 5;
292
293  if (addr != NULL)
294    {
295      addr->addr.in4.sin_family = AF_INET;
296      addr->addr.in4.sin_addr.s_addr = htonl (INADDR_ANY);
297      addr->addr.in4.sin_port = htons (0);
298    }
299
300  while (len < 4 + alen + 2)
301    {
302      int status;
303      ssize_t size;
304      fd_set reads;
305      struct timeval tv;
306      char c;
307
308      FD_ZERO (&reads);
309      FD_SET (sd, &reads);
310      tv.tv_sec = timeout_sec;
311      tv.tv_usec = 0;
312
313      status = select (sd + 1, &reads, NULL, NULL, &tv);
314
315      get_signal (signal_received);
316      if (*signal_received)
317	return false;
318
319      /* timeout? */
320      if (status == 0)
321	{
322	  msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read timeout expired");
323	  return false;
324	}
325
326      /* error */
327      if (status < 0)
328	{
329	  msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on select()");
330	  return false;
331	}
332
333      /* read single char */
334      size = recv(sd, &c, 1, MSG_NOSIGNAL);
335
336      /* error? */
337      if (size != 1)
338	{
339	  msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on recv()");
340	  return false;
341	}
342
343      if (len == 3)
344	atyp = c;
345
346      if (len == 4)
347	{
348	  switch (atyp)
349	    {
350	    case '\x01':	/* IP V4 */
351	      alen = 4;
352	      break;
353
354	    case '\x03':	/* DOMAINNAME */
355	      alen = (unsigned char) c;
356	      break;
357
358	    case '\x04':	/* IP V6 */
359	      alen = 16;
360	      break;
361
362	    default:
363	      msg (D_LINK_ERRORS, "recv_socks_reply: Socks proxy returned bad address type");
364	      return false;
365	    }
366	}
367
368      /* store char in buffer */
369      if (len < (int)sizeof(buf))
370	buf[len] = c;
371      ++len;
372    }
373
374  /* VER == 5 && REP == 0 (succeeded) */
375  if (buf[0] != '\x05' || buf[1] != '\x00')
376    {
377      msg (D_LINK_ERRORS, "recv_socks_reply: Socks proxy returned bad reply");
378      return false;
379    }
380
381  /* ATYP == 1 (IP V4 address) */
382  if (atyp == '\x01' && addr != NULL)
383    {
384      memcpy (&addr->addr.in4.sin_addr, buf + 4, sizeof (addr->addr.in4.sin_addr));
385      memcpy (&addr->addr.in4.sin_port, buf + 8, sizeof (addr->addr.in4.sin_port));
386    }
387
388
389  return true;
390}
391
392void
393establish_socks_proxy_passthru (struct socks_proxy_info *p,
394			        socket_descriptor_t sd, /* already open to proxy */
395			        const char *host,       /* openvpn server remote */
396			        const int port,         /* openvpn server port */
397			        volatile int *signal_received)
398{
399  char buf[128];
400  size_t len;
401
402  if (!socks_handshake (p, sd, signal_received))
403    goto error;
404
405  /* format Socks CONNECT message */
406  buf[0] = '\x05';		/* VER = 5 */
407  buf[1] = '\x01';		/* CMD = 1 (CONNECT) */
408  buf[2] = '\x00';		/* RSV */
409  buf[3] = '\x03';		/* ATYP = 3 (DOMAINNAME) */
410
411  len = strlen(host);
412  len = (5 + len + 2 > sizeof(buf)) ? (sizeof(buf) - 5 - 2) : len;
413
414  buf[4] = (char) len;
415  memcpy(buf + 5, host, len);
416
417  buf[5 + len] = (char) (port >> 8);
418  buf[5 + len + 1] = (char) (port & 0xff);
419
420  {
421    const ssize_t size = send (sd, buf, 5 + len + 2, MSG_NOSIGNAL);
422    if ((int)size != 5 + (int)len + 2)
423      {
424	msg (D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()");
425	goto error;
426      }
427  }
428
429  /* receive reply from Socks proxy and discard */
430  if (!recv_socks_reply (sd, NULL, signal_received))
431    goto error;
432
433  return;
434
435 error:
436  /* on error, should we exit or restart? */
437  if (!*signal_received)
438    *signal_received = (p->retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- socks error */
439  return;
440}
441
442void
443establish_socks_proxy_udpassoc (struct socks_proxy_info *p,
444			        socket_descriptor_t ctrl_sd, /* already open to proxy */
445				socket_descriptor_t udp_sd,
446				struct openvpn_sockaddr *relay_addr,
447			        volatile int *signal_received)
448{
449  if (!socks_handshake (p, ctrl_sd, signal_received))
450    goto error;
451
452  {
453    /* send Socks UDP ASSOCIATE message */
454    /* VER = 5, CMD = 3 (UDP ASSOCIATE), RSV = 0, ATYP = 1 (IP V4),
455       BND.ADDR = 0, BND.PORT = 0 */
456    const ssize_t size = send (ctrl_sd,
457			       "\x05\x03\x00\x01\x00\x00\x00\x00\x00\x00",
458			       10, MSG_NOSIGNAL);
459    if (size != 10)
460      {
461	msg (D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()");
462	goto error;
463      }
464  }
465
466  /* receive reply from Socks proxy */
467  CLEAR (*relay_addr);
468  if (!recv_socks_reply (ctrl_sd, relay_addr, signal_received))
469    goto error;
470
471  return;
472
473 error:
474  /* on error, should we exit or restart? */
475  if (!*signal_received)
476    *signal_received = (p->retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- socks error */
477  return;
478}
479
480/*
481 * Remove the 10 byte socks5 header from an incoming
482 * UDP packet, setting *from to the source address.
483 *
484 * Run after UDP read.
485 */
486void
487socks_process_incoming_udp (struct buffer *buf,
488			    struct link_socket_actual *from)
489{
490  int atyp;
491
492  if (BLEN (buf) < 10)
493    goto error;
494
495  buf_read_u16 (buf);
496  if (buf_read_u8 (buf) != 0)
497    goto error;
498
499  atyp = buf_read_u8 (buf);
500  if (atyp != 1)		/* ATYP == 1 (IP V4) */
501    goto error;
502
503  buf_read (buf, &from->dest.addr.in4.sin_addr, sizeof (from->dest.addr.in4.sin_addr));
504  buf_read (buf, &from->dest.addr.in4.sin_port, sizeof (from->dest.addr.in4.sin_port));
505
506  return;
507
508 error:
509  buf->len = 0;
510}
511
512/*
513 * Add a 10 byte socks header prior to UDP write.
514 * *to is the destination address.
515 *
516 * Run before UDP write.
517 * Returns the size of the header.
518 */
519int
520socks_process_outgoing_udp (struct buffer *buf,
521			    const struct link_socket_actual *to)
522{
523  /*
524   * Get a 10 byte subset buffer prepended to buf --
525   * we expect these bytes will be here because
526   * we allocated frame space in socks_adjust_frame_parameters.
527   */
528  struct buffer head = buf_sub (buf, 10, true);
529
530  /* crash if not enough headroom in buf */
531  ASSERT (buf_defined (&head));
532
533  buf_write_u16 (&head, 0);	/* RSV = 0 */
534  buf_write_u8 (&head, 0);	/* FRAG = 0 */
535  buf_write_u8 (&head, '\x01'); /* ATYP = 1 (IP V4) */
536  buf_write (&head, &to->dest.addr.in4.sin_addr, sizeof (to->dest.addr.in4.sin_addr));
537  buf_write (&head, &to->dest.addr.in4.sin_port, sizeof (to->dest.addr.in4.sin_port));
538
539  return 10;
540}
541
542#else
543static void dummy(void) {}
544#endif /* ENABLE_SOCKS */
545