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