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