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-2026 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, see <https://www.gnu.org/licenses/>.
21 */
22
23/*
24 * 2004-01-30: Added Socks5 proxy support, see RFC 1928
25 * (Christof Meerwald, https://cmeerw.org)
26 *
27 * 2010-10-10: Added Socks5 plain text authentication support (RFC 1929)
28 * (Pierre Bourdon <delroth@gmail.com>)
29 */
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include "syshead.h"
36
37#include "socks.h"
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 *
52socks_proxy_new(const char *server, const char *port, const char *authfile)
53{
54 struct socks_proxy_info *p;
55
57
59 ASSERT(port);
60
61 strlcpy(p->server, server, sizeof(p->server));
62 p->port = port;
63
64 if (authfile)
65 {
66 strlcpy(p->authfile, authfile, sizeof(p->authfile));
67 }
68 else
69 {
70 p->authfile[0] = 0;
71 }
72
73 p->defined = true;
74
75 return p;
76}
77
78void
80{
81 free(sp);
82}
83
84static bool
85socks_proxy_recv_char(uint8_t *c, const char *name, socket_descriptor_t sd,
86 const struct event_timeout *server_poll_timeout,
87 volatile int *signal_received)
88{
89 struct timeval tv;
90 tv.tv_sec = get_server_poll_remaining_time(server_poll_timeout);
91 tv.tv_usec = 0;
92
93 return proxy_recv_char(c, name, sd, &tv, signal_received);
94}
95
96static bool
98 const struct event_timeout *server_poll_timeout,
99 volatile int *signal_received)
100{
101 char to_send[516];
102 struct user_pass creds;
103 bool ret = false;
104
105 CLEAR(creds);
107 {
108 msg(M_NONFATAL, "SOCKS failed to get username/password.");
109 goto cleanup;
110 }
111
112 if ((strlen(creds.username) > 255) || (strlen(creds.password) > 255))
113 {
114 msg(M_NONFATAL, "SOCKS username and/or password exceeds 255 characters. "
115 "Authentication not possible.");
116 goto cleanup;
117 }
118
119 ASSERT(checked_snprintf(to_send, sizeof(to_send), "\x01%c%s%c%s",
120 (int)strlen(creds.username), creds.username,
121 (int)strlen(creds.password), creds.password));
122 if (!proxy_send(sd, to_send, strlen(to_send)))
123 {
124 goto cleanup;
125 }
126
127 int len = 0;
128 uint8_t buf[2];
129 while (len < 2)
130 {
131 uint8_t c;
132
133 if (!socks_proxy_recv_char(&c, __func__, sd, server_poll_timeout, signal_received))
134 {
135 goto cleanup;
136 }
137 /* store char in buffer */
138 buf[len++] = c;
139 }
140
141 /* VER = 5, SUCCESS = 0 --> auth success */
142 if (buf[0] != 5 || buf[1] != 0)
143 {
144 msg(D_LINK_ERRORS, "socks_username_password_auth: server refused the authentication");
145 goto cleanup;
146 }
147
148 ret = true;
149cleanup:
150 secure_memzero(&creds, sizeof(creds));
151 secure_memzero(to_send, sizeof(to_send));
152 return ret;
153}
154
155static bool
157 const struct event_timeout *server_poll_timeout, volatile int *signal_received)
158{
159 uint8_t buf[2];
160 int len = 0;
161
162 /* VER = 5, NMETHODS = 1, METHODS = [0 (no auth)] */
163 uint8_t method_sel[3] = { 0x05, 0x01, 0x00 };
164 if (p->authfile[0])
165 {
166 method_sel[2] = 0x02; /* METHODS = [2 (plain login)] */
167 }
168 if (!proxy_send(sd, method_sel, sizeof(method_sel)))
169 {
170 return false;
171 }
172
173 while (len < 2)
174 {
175 uint8_t c;
176
177 if (!socks_proxy_recv_char(&c, __func__, sd, server_poll_timeout, signal_received))
178 {
179 return false;
180 }
181 /* store char in buffer */
182 buf[len++] = c;
183 }
184
185 /* VER == 5 */
186 if (buf[0] != 5)
187 {
188 msg(D_LINK_ERRORS, "socks_handshake: Socks proxy returned bad status");
189 return false;
190 }
191
192 /* validate that the auth method returned is the one sent */
193 if (buf[1] != method_sel[2])
194 {
195 msg(D_LINK_ERRORS, "socks_handshake: Socks proxy returned unexpected auth");
196 return false;
197 }
198
199 /* select the appropriate authentication method */
200 switch (buf[1])
201 {
202 case 0: /* no authentication */
203 break;
204
205 case 2: /* login/password */
206 if (!p->authfile[0])
207 {
209 "socks_handshake: server asked for username/login auth but we were "
210 "not provided any credentials");
211 return false;
212 }
213
214 if (!socks_username_password_auth(p, sd, server_poll_timeout, signal_received))
215 {
216 return false;
217 }
218
219 break;
220
221 default: /* unknown auth method */
222 msg(D_LINK_ERRORS, "socks_handshake: unknown SOCKS auth method");
223 return false;
224 }
225
226 return true;
227}
228
229static bool
231 const struct event_timeout *server_poll_timeout, volatile int *signal_received)
232{
233 uint8_t atyp = 0;
234 int alen = 0;
235 int len = 0;
236 char buf[270]; /* 4 + alen(max 256) + 2 */
237
238 if (addr != NULL)
239 {
240 addr->addr.in4.sin_family = AF_INET;
241 addr->addr.in4.sin_addr.s_addr = htonl(INADDR_ANY);
242 addr->addr.in4.sin_port = htons(0);
243 }
244
245 while (len < 4 + alen + 2)
246 {
247 uint8_t c;
248
249 if (!socks_proxy_recv_char(&c, __func__, sd, server_poll_timeout, signal_received))
250 {
251 return false;
252 }
253
254 if (len == 3)
255 {
256 atyp = c;
257 }
258
259 if (len == 4)
260 {
261 switch (atyp)
262 {
263 case 1: /* IP V4 */
264 alen = 4;
265 break;
266
267 case 3: /* DOMAINNAME */
268 /* RFC 1928, section 5: 1 byte length, <n> bytes name,
269 * so the total "address length" is (length+1)
270 */
271 alen = c + 1;
272 break;
273
274 case 4: /* IP V6 */
275 alen = 16;
276 break;
277
278 default:
279 msg(D_LINK_ERRORS, "recv_socks_reply: Socks proxy returned bad address type");
280 return false;
281 }
282 }
283
284 /* store char in buffer */
285 if (len < (int)sizeof(buf))
286 {
287 buf[len] = c;
288 }
289 ++len;
290 }
291
292 /* VER == 5 && REP == 0 (succeeded) */
293 if (buf[0] != 5 || buf[1] != 0)
294 {
295 msg(D_LINK_ERRORS, "recv_socks_reply: Socks proxy returned bad reply");
296 return false;
297 }
298
299 /* ATYP == 1 (IP V4 address) */
300 if (atyp == 1 && addr != NULL)
301 {
302 memcpy(&addr->addr.in4.sin_addr, buf + 4, sizeof(addr->addr.in4.sin_addr));
303 memcpy(&addr->addr.in4.sin_port, buf + 8, sizeof(addr->addr.in4.sin_port));
304 struct gc_arena gc = gc_new();
305 msg(M_INFO, "SOCKS proxy wants us to send UDP to %s", print_openvpn_sockaddr(addr, &gc));
306 gc_free(&gc);
307 }
308
309
310 return true;
311}
312
313static int
314port_from_servname(const char *servname)
315{
316 int port = 0;
317 port = atoi(servname);
318 if (port > 0 && port < 65536)
319 {
320 return port;
321 }
322
323 const struct servent *service = getservbyname(servname, NULL);
324 if (service)
325 {
326 return service->s_port;
327 }
328
329 return 0;
330}
331
332void
334 socket_descriptor_t sd, /* already open to proxy */
335 const char *host, /* openvpn server remote */
336 const char *servname, /* openvpn server port */
337 const struct event_timeout *server_poll_timeout,
338 struct signal_info *sig_info)
339{
340 char buf[270];
341 size_t len;
342
343 if (!socks_handshake(p, sd, server_poll_timeout, &sig_info->signal_received))
344 {
345 goto error;
346 }
347
348 /* format Socks CONNECT message */
349 buf[0] = '\x05'; /* VER = 5 */
350 buf[1] = '\x01'; /* CMD = 1 (CONNECT) */
351 buf[2] = '\x00'; /* RSV */
352 buf[3] = '\x03'; /* ATYP = 3 (DOMAINNAME) */
353
354 len = strlen(host);
355 len = (5 + len + 2 > sizeof(buf)) ? (sizeof(buf) - 5 - 2) : len;
356
357 buf[4] = (char)len;
358 memcpy(buf + 5, host, len);
359
360 int port = port_from_servname(servname);
361 if (port == 0)
362 {
363 msg(D_LINK_ERRORS, "establish_socks_proxy_passthrough: Cannot convert %s to port number",
364 servname);
365 goto error;
366 }
367
368 buf[5 + len] = (char)(port >> 8);
369 buf[5 + len + 1] = (char)(port & 0xff);
370
371 if (!proxy_send(sd, buf, 5 + len + 2))
372 {
373 goto error;
374 }
375
376 /* receive reply from Socks proxy and discard */
377 if (!recv_socks_reply(sd, NULL, server_poll_timeout, &sig_info->signal_received))
378 {
379 goto error;
380 }
381
382 return;
383
384error:
385 /* SOFT-SIGUSR1 -- socks error */
386 register_signal(sig_info, SIGUSR1, "socks-error");
387 return;
388}
389
390void
392 socket_descriptor_t ctrl_sd, /* already open to proxy */
393 struct openvpn_sockaddr *relay_addr,
394 const struct event_timeout *server_poll_timeout,
395 struct signal_info *sig_info)
396{
397 if (!socks_handshake(p, ctrl_sd, server_poll_timeout, &sig_info->signal_received))
398 {
399 goto error;
400 }
401
402 {
403 /* send Socks UDP ASSOCIATE message */
404 /* VER = 5, CMD = 3 (UDP ASSOCIATE), RSV = 0, ATYP = 1 (IP V4),
405 * BND.ADDR = 0, BND.PORT = 0 */
406 const ssize_t size =
407 send(ctrl_sd, "\x05\x03\x00\x01\x00\x00\x00\x00\x00\x00", 10, MSG_NOSIGNAL);
408 if (size != 10)
409 {
410 msg(D_LINK_ERRORS | M_ERRNO, "%s: TCP port write failed on send()", __func__);
411 goto error;
412 }
413 }
414
415 /* receive reply from Socks proxy */
416 CLEAR(*relay_addr);
417 if (!recv_socks_reply(ctrl_sd, relay_addr, server_poll_timeout, &sig_info->signal_received))
418 {
419 goto error;
420 }
421 if (!relay_addr->addr.in4.sin_addr.s_addr)
422 {
423 msg(D_LINK_ERRORS, "%s: Socks proxy did not answer with IPv4 address", __func__);
424 goto error;
425 }
426
427 return;
428
429error:
430 /* SOFT-SIGUSR1 -- socks error */
431 register_signal(sig_info, SIGUSR1, "socks-error");
432 return;
433}
434
435/*
436 * Remove the socks5 header from an incoming
437 * UDP packet, setting *from to the source address.
438 *
439 * Run after UDP read.
440 */
441void
443{
444 int atyp;
445
446 if (BLEN(buf) < SOCKS_UDPv4_HEADROOM)
447 {
448 goto error;
449 }
450
451 buf_read_u16(buf);
452 if (buf_read_u8(buf) != 0)
453 {
454 goto error;
455 }
456
457 atyp = buf_read_u8(buf);
458 if (atyp != 1) /* ATYP == 1 (IP V4) */
459 {
460 goto error;
461 }
462
463 buf_read(buf, &from->dest.addr.in4.sin_addr, sizeof(from->dest.addr.in4.sin_addr));
464 buf_read(buf, &from->dest.addr.in4.sin_port, sizeof(from->dest.addr.in4.sin_port));
465
466 return;
467
468error:
469 buf->len = 0;
470}
471
472/*
473 * Add a socks header prior to UDP write.
474 * *to is the destination address.
475 *
476 * Run before UDP write.
477 * Returns the size of the header.
478 */
479int
481{
482 /*
483 * Get a subset buffer prepended to buf --
484 * we expect these bytes will be here because
485 * we always allocate space for these bytes
486 */
487 struct buffer head = buf_sub(buf, SOCKS_UDPv4_HEADROOM, true);
488
489 /* crash if not enough headroom in buf */
490 ASSERT(buf_defined(&head));
491
492 buf_write_u16(&head, 0); /* RSV = 0 */
493 buf_write_u8(&head, 0); /* FRAG = 0 */
494 buf_write_u8(&head, '\x01'); /* ATYP = 1 (IP V4) */
495 buf_write(&head, &to->dest.addr.in4.sin_addr, sizeof(to->dest.addr.in4.sin_addr));
496 buf_write(&head, &to->dest.addr.in4.sin_port, sizeof(to->dest.addr.in4.sin_port));
497
499}
struct buffer buf_sub(struct buffer *buf, int size, bool prepend)
Return a sub-buffer of another buffer.
Definition buffer.c:207
bool checked_snprintf(char *str, size_t size, const char *format,...)
Like snprintf() but returns an boolean.
Definition buffer.c:1115
static bool buf_write_u16(struct buffer *dest, uint16_t data)
Append a uint16_t to a buffer in network byte order.
Definition buffer.h:1297
static int buf_read_u16(struct buffer *buf)
Read and consume a uint16_t from the front of a buffer.
Definition buffer.h:1511
static bool buf_read(struct buffer *src, void *dest, int size)
Read bytes from the front of a buffer into a caller-supplied destination.
Definition buffer.h:1451
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
Definition buffer.h:748
static bool buf_write(struct buffer *dest, const void *src, size_t size)
Append data to a buffer.
Definition buffer.h:1239
static bool buf_write_u8(struct buffer *dest, uint8_t data)
Append a uint8_t to a buffer.
Definition buffer.h:1283
static int buf_read_u8(struct buffer *buf)
Read and consume a uint8_t from the front of a buffer.
Definition buffer.h:1490
#define BLEN(buf)
Return the length of the buffer content in bytes.
Definition buffer.h:151
static void gc_free(struct gc_arena *a)
Free all allocations in a garbage collection arena.
Definition buffer.h:1965
#define ALLOC_OBJ_CLEAR(dptr, type)
Allocate and zero-initialise memory for a single object of the given type.
Definition buffer.h:2027
static bool buf_defined(const struct buffer *buf)
Return true iff buf has a non-NULL data pointer.
Definition buffer.h:399
static struct gc_arena gc_new(void)
Allocate and return a new, empty garbage collection arena.
Definition buffer.h:1949
size_t strlcpy(char *dest, const char *src, size_t maxlen)
#define M_INFO
Definition errlevel.h:54
#define D_LINK_ERRORS
Definition errlevel.h:56
int get_server_poll_remaining_time(const struct event_timeout *server_poll_timeout)
Definition forward.c:515
Interface functions to the internal and external multiplexers.
static SERVICE_STATUS_HANDLE service
Definition interactive.c:51
#define GET_USER_PASS_MANAGEMENT
Definition misc.h:113
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:155
#define SOCKS_UDPv4_HEADROOM
Definition mtu.h:106
#define CLEAR(x)
Definition basic.h:32
#define M_NONFATAL
Definition error.h:91
#define msg(flags,...)
Definition error.h:152
#define ASSERT(x)
Definition error.h:221
#define M_ERRNO
Definition error.h:95
bool proxy_recv_char(uint8_t *c, const char *name, socket_descriptor_t sd, struct timeval *timeout, volatile int *signal_received)
Definition proxy.c:60
bool proxy_send(socket_descriptor_t sd, const void *buf, size_t len)
Definition proxy.c:187
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:228
#define MSG_NOSIGNAL
Definition socket.h:251
static const char * print_openvpn_sockaddr(const struct openvpn_sockaddr *addr, struct gc_arena *gc)
Definition socket_util.h:71
static int port_from_servname(const char *servname)
Definition socks.c:314
void establish_socks_proxy_passthru(const struct socks_proxy_info *p, socket_descriptor_t sd, const char *host, const char *servname, const struct event_timeout *server_poll_timeout, struct signal_info *sig_info)
Definition socks.c:333
static bool socks_proxy_recv_char(uint8_t *c, const char *name, socket_descriptor_t sd, const struct event_timeout *server_poll_timeout, volatile int *signal_received)
Definition socks.c:85
static bool socks_username_password_auth(const struct socks_proxy_info *p, socket_descriptor_t sd, const struct event_timeout *server_poll_timeout, volatile int *signal_received)
Definition socks.c:97
static bool recv_socks_reply(socket_descriptor_t sd, struct openvpn_sockaddr *addr, const struct event_timeout *server_poll_timeout, volatile int *signal_received)
Definition socks.c:230
static bool socks_handshake(const struct socks_proxy_info *p, socket_descriptor_t sd, const struct event_timeout *server_poll_timeout, volatile int *signal_received)
Definition socks.c:156
int socks_process_outgoing_udp(struct buffer *buf, const struct link_socket_actual *to)
Definition socks.c:480
void establish_socks_proxy_udpassoc(const struct socks_proxy_info *p, socket_descriptor_t ctrl_sd, struct openvpn_sockaddr *relay_addr, const struct event_timeout *server_poll_timeout, struct signal_info *sig_info)
Definition socks.c:391
#define UP_TYPE_SOCKS
Definition socks.c:49
void socks_process_incoming_udp(struct buffer *buf, struct link_socket_actual *from)
Definition socks.c:442
struct socks_proxy_info * socks_proxy_new(const char *server, const char *port, const char *authfile)
Definition socks.c:52
void socks_proxy_close(struct socks_proxy_info *sp)
Definition socks.c:79
Wrapper structure for dynamically allocated memory.
Definition buffer.h:71
int len
Length in bytes of the actual content within the allocated memory.
Definition buffer.h:76
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:127
union openvpn_sockaddr::@27 addr
struct sockaddr_in in4
Definition socket_util.h:43
volatile int signal_received
Definition sig.h:42
char authfile[256]
Definition socks.h:44
char server[128]
Definition socks.h:42
const char * port
Definition socks.h:43
char password[USER_PASS_LEN]
Definition misc.h:71
char username[USER_PASS_LEN]
Definition misc.h:70
SOCKET socket_descriptor_t
Definition syshead.h:445
#define SIGUSR1
Definition syshead.h:57
static int cleanup(void **state)
struct gc_arena gc
Definition test_ssl.c:138