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