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
8
* Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
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.
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.
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
26
* 2004-01-30: Added Socks5 proxy support, see RFC 1928
27
* (Christof Meerwald, http://cmeerw.org)
29
* 2010-10-10: Added Socks5 plain text authentication support (RFC 1929)
30
* (Pierre Bourdon <delroth@gmail.com>)
35
#elif defined(_MSC_VER)
36
#include "config-msvc.h"
53
#define UP_TYPE_SOCKS "SOCKS Proxy"
56
socks_adjust_frame_parameters (struct frame *frame, int proto)
58
if (proto == PROTO_UDPv4)
59
frame_add_to_extra_link (frame, 10);
62
struct socks_proxy_info *
63
socks_proxy_new (const char *server,
68
struct socks_proxy_info *p;
70
ALLOC_OBJ_CLEAR (p, struct socks_proxy_info);
73
ASSERT (legal_ipv4_port (port));
75
strncpynt (p->server, server, sizeof (p->server));
79
strncpynt (p->authfile, authfile, sizeof (p->authfile));
90
socks_proxy_close (struct socks_proxy_info *sp)
96
socks_username_password_auth (struct socks_proxy_info *p,
97
socket_descriptor_t sd,
98
volatile int *signal_received)
103
const int timeout_sec = 5;
104
struct user_pass creds;
108
get_user_pass (&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT);
110
if( !creds.username || (strlen(creds.username) > 255)
111
|| !creds.password || (strlen(creds.password) > 255) ) {
113
"SOCKS username and/or password exceeds 255 characters. "
114
"Authentication not possible.");
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);
121
if (size != strlen (to_send))
123
msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port write failed on send()");
137
tv.tv_sec = timeout_sec;
140
status = select (sd + 1, &reads, NULL, NULL, &tv);
142
get_signal (signal_received);
143
if (*signal_received)
149
msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read timeout expired");
156
msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on select()");
160
/* read single char */
161
size = recv(sd, &c, 1, MSG_NOSIGNAL);
166
msg (D_LINK_ERRORS | M_ERRNO, "socks_username_password_auth: TCP port read failed on recv()");
170
/* store char in buffer */
174
/* VER = 5, SUCCESS = 0 --> auth success */
175
if (buf[0] != 5 && buf[1] != 0)
177
msg (D_LINK_ERRORS, "socks_username_password_auth: server refused the authentication");
185
socks_handshake (struct socks_proxy_info *p,
186
socket_descriptor_t sd,
187
volatile int *signal_received)
191
const int timeout_sec = 5;
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);
197
msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port write failed on send()");
211
tv.tv_sec = timeout_sec;
214
status = select (sd + 1, &reads, NULL, NULL, &tv);
216
get_signal (signal_received);
217
if (*signal_received)
223
msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read timeout expired");
230
msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on select()");
234
/* read single char */
235
size = recv(sd, &c, 1, MSG_NOSIGNAL);
240
msg (D_LINK_ERRORS | M_ERRNO, "socks_handshake: TCP port read failed on recv()");
244
/* store char in buffer */
249
if (buf[0] != '\x05')
251
msg (D_LINK_ERRORS, "socks_handshake: Socks proxy returned bad status");
255
/* select the appropriate authentication method */
258
case 0: /* no authentication */
261
case 2: /* login/password */
264
msg(D_LINK_ERRORS, "socks_handshake: server asked for username/login auth but we were "
265
"not provided any credentials");
269
if (!socks_username_password_auth(p, sd, signal_received))
274
default: /* unknown auth method */
275
msg(D_LINK_ERRORS, "socks_handshake: unknown SOCKS auth method");
283
recv_socks_reply (socket_descriptor_t sd,
284
struct openvpn_sockaddr *addr,
285
volatile int *signal_received)
291
const int timeout_sec = 5;
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);
300
while (len < 4 + alen + 2)
310
tv.tv_sec = timeout_sec;
313
status = select (sd + 1, &reads, NULL, NULL, &tv);
315
get_signal (signal_received);
316
if (*signal_received)
322
msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read timeout expired");
329
msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on select()");
333
/* read single char */
334
size = recv(sd, &c, 1, MSG_NOSIGNAL);
339
msg (D_LINK_ERRORS | M_ERRNO, "recv_socks_reply: TCP port read failed on recv()");
350
case '\x01': /* IP V4 */
354
case '\x03': /* DOMAINNAME */
355
alen = (unsigned char) c;
358
case '\x04': /* IP V6 */
363
msg (D_LINK_ERRORS, "recv_socks_reply: Socks proxy returned bad address type");
368
/* store char in buffer */
369
if (len < (int)sizeof(buf))
374
/* VER == 5 && REP == 0 (succeeded) */
375
if (buf[0] != '\x05' || buf[1] != '\x00')
377
msg (D_LINK_ERRORS, "recv_socks_reply: Socks proxy returned bad reply");
381
/* ATYP == 1 (IP V4 address) */
382
if (atyp == '\x01' && addr != NULL)
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));
393
establish_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)
402
if (!socks_handshake (p, sd, signal_received))
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) */
412
len = (5 + len + 2 > sizeof(buf)) ? (sizeof(buf) - 5 - 2) : len;
415
memcpy(buf + 5, host, len);
417
buf[5 + len] = (char) (port >> 8);
418
buf[5 + len + 1] = (char) (port & 0xff);
421
const ssize_t size = send (sd, buf, 5 + len + 2, MSG_NOSIGNAL);
422
if ((int)size != 5 + (int)len + 2)
424
msg (D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()");
429
/* receive reply from Socks proxy and discard */
430
if (!recv_socks_reply (sd, NULL, signal_received))
436
/* on error, should we exit or restart? */
437
if (!*signal_received)
438
*signal_received = (p->retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- socks error */
443
establish_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)
449
if (!socks_handshake (p, ctrl_sd, signal_received))
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",
461
msg (D_LINK_ERRORS | M_ERRNO, "establish_socks_proxy_passthru: TCP port write failed on send()");
466
/* receive reply from Socks proxy */
468
if (!recv_socks_reply (ctrl_sd, relay_addr, signal_received))
474
/* on error, should we exit or restart? */
475
if (!*signal_received)
476
*signal_received = (p->retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- socks error */
481
* Remove the 10 byte socks5 header from an incoming
482
* UDP packet, setting *from to the source address.
484
* Run after UDP read.
487
socks_process_incoming_udp (struct buffer *buf,
488
struct link_socket_actual *from)
496
if (buf_read_u8 (buf) != 0)
499
atyp = buf_read_u8 (buf);
500
if (atyp != 1) /* ATYP == 1 (IP V4) */
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));
513
* Add a 10 byte socks header prior to UDP write.
514
* *to is the destination address.
516
* Run before UDP write.
517
* Returns the size of the header.
520
socks_process_outgoing_udp (struct buffer *buf,
521
const struct link_socket_actual *to)
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.
528
struct buffer head = buf_sub (buf, 10, true);
530
/* crash if not enough headroom in buf */
531
ASSERT (buf_defined (&head));
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));
543
static void dummy(void) {}
544
#endif /* ENABLE_SOCKS */