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-2009 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
27 * (Christof Meerwald, http://cmeerw.org)
29 * see RFC 1928, only supports "no authentication"
47 socks_adjust_frame_parameters (struct frame
*frame
, int proto
)
49 if (proto
== PROTO_UDPv4
)
50 frame_add_to_extra_link (frame
, 10);
53 struct socks_proxy_info
*
54 socks_proxy_new (const char *server
,
57 struct auto_proxy_info
*auto_proxy_info
)
59 struct socks_proxy_info
*p
;
65 if (!auto_proxy_info
->socks
.server
)
68 server
= auto_proxy_info
->socks
.server
;
69 port
= auto_proxy_info
->socks
.port
;
73 ALLOC_OBJ_CLEAR (p
, struct socks_proxy_info
);
76 ASSERT (legal_ipv4_port (port
));
78 strncpynt (p
->server
, server
, sizeof (p
->server
));
87 socks_proxy_close (struct socks_proxy_info
*sp
)
93 socks_handshake (socket_descriptor_t sd
, volatile int *signal_received
)
97 const int timeout_sec
= 5;
99 /* VER = 5, NMETHODS = 1, METHODS = [0] */
100 const ssize_t size
= send (sd
, "\x05\x01\x00", 3, MSG_NOSIGNAL
);
103 msg (D_LINK_ERRORS
| M_ERRNO_SOCK
, "socks_handshake: TCP port write failed on send()");
117 tv
.tv_sec
= timeout_sec
;
120 status
= select (sd
+ 1, &reads
, NULL
, NULL
, &tv
);
122 get_signal (signal_received
);
123 if (*signal_received
)
129 msg (D_LINK_ERRORS
| M_ERRNO_SOCK
, "socks_handshake: TCP port read timeout expired");
136 msg (D_LINK_ERRORS
| M_ERRNO_SOCK
, "socks_handshake: TCP port read failed on select()");
140 /* read single char */
141 size
= recv(sd
, &c
, 1, MSG_NOSIGNAL
);
146 msg (D_LINK_ERRORS
| M_ERRNO_SOCK
, "socks_handshake: TCP port read failed on recv()");
150 /* store char in buffer */
154 /* VER == 5 && METHOD == 0 */
155 if (buf
[0] != '\x05' || buf
[1] != '\x00')
157 msg (D_LINK_ERRORS
, "socks_handshake: Socks proxy returned bad status");
165 recv_socks_reply (socket_descriptor_t sd
,
166 struct openvpn_sockaddr
*addr
,
167 volatile int *signal_received
)
173 const int timeout_sec
= 5;
177 addr
->sa
.sin_family
= AF_INET
;
178 addr
->sa
.sin_addr
.s_addr
= htonl (INADDR_ANY
);
179 addr
->sa
.sin_port
= htons (0);
182 while (len
< 4 + alen
+ 2)
192 tv
.tv_sec
= timeout_sec
;
195 status
= select (sd
+ 1, &reads
, NULL
, NULL
, &tv
);
197 get_signal (signal_received
);
198 if (*signal_received
)
204 msg (D_LINK_ERRORS
| M_ERRNO_SOCK
, "recv_socks_reply: TCP port read timeout expired");
211 msg (D_LINK_ERRORS
| M_ERRNO_SOCK
, "recv_socks_reply: TCP port read failed on select()");
215 /* read single char */
216 size
= recv(sd
, &c
, 1, MSG_NOSIGNAL
);
221 msg (D_LINK_ERRORS
| M_ERRNO_SOCK
, "recv_socks_reply: TCP port read failed on recv()");
232 case '\x01': /* IP V4 */
236 case '\x03': /* DOMAINNAME */
237 alen
= (unsigned char) c
;
240 case '\x04': /* IP V6 */
245 msg (D_LINK_ERRORS
, "recv_socks_reply: Socks proxy returned bad address type");
250 /* store char in buffer */
251 if (len
< (int)sizeof(buf
))
256 /* VER == 5 && REP == 0 (succeeded) */
257 if (buf
[0] != '\x05' || buf
[1] != '\x00')
259 msg (D_LINK_ERRORS
, "recv_socks_reply: Socks proxy returned bad reply");
263 /* ATYP == 1 (IP V4 address) */
264 if (atyp
== '\x01' && addr
!= NULL
)
266 memcpy (&addr
->sa
.sin_addr
, buf
+ 4, sizeof (addr
->sa
.sin_addr
));
267 memcpy (&addr
->sa
.sin_port
, buf
+ 8, sizeof (addr
->sa
.sin_port
));
275 establish_socks_proxy_passthru (struct socks_proxy_info
*p
,
276 socket_descriptor_t sd
, /* already open to proxy */
277 const char *host
, /* openvpn server remote */
278 const int port
, /* openvpn server port */
279 volatile int *signal_received
)
284 if (!socks_handshake (sd
, signal_received
))
287 /* format Socks CONNECT message */
288 buf
[0] = '\x05'; /* VER = 5 */
289 buf
[1] = '\x01'; /* CMD = 1 (CONNECT) */
290 buf
[2] = '\x00'; /* RSV */
291 buf
[3] = '\x03'; /* ATYP = 3 (DOMAINNAME) */
294 len
= (5 + len
+ 2 > sizeof(buf
)) ? (sizeof(buf
) - 5 - 2) : len
;
297 memcpy(buf
+ 5, host
, len
);
299 buf
[5 + len
] = (char) (port
>> 8);
300 buf
[5 + len
+ 1] = (char) (port
& 0xff);
303 const ssize_t size
= send (sd
, buf
, 5 + len
+ 2, MSG_NOSIGNAL
);
304 if ((int)size
!= 5 + (int)len
+ 2)
306 msg (D_LINK_ERRORS
| M_ERRNO_SOCK
, "establish_socks_proxy_passthru: TCP port write failed on send()");
311 /* receive reply from Socks proxy and discard */
312 if (!recv_socks_reply (sd
, NULL
, signal_received
))
318 /* on error, should we exit or restart? */
319 if (!*signal_received
)
320 *signal_received
= (p
->retry
? SIGUSR1
: SIGTERM
); /* SOFT-SIGUSR1 -- socks error */
325 establish_socks_proxy_udpassoc (struct socks_proxy_info
*p
,
326 socket_descriptor_t ctrl_sd
, /* already open to proxy */
327 socket_descriptor_t udp_sd
,
328 struct openvpn_sockaddr
*relay_addr
,
329 volatile int *signal_received
)
331 if (!socks_handshake (ctrl_sd
, signal_received
))
335 /* send Socks UDP ASSOCIATE message */
336 /* VER = 5, CMD = 3 (UDP ASSOCIATE), RSV = 0, ATYP = 1 (IP V4),
337 BND.ADDR = 0, BND.PORT = 0 */
338 const ssize_t size
= send (ctrl_sd
,
339 "\x05\x03\x00\x01\x00\x00\x00\x00\x00\x00",
343 msg (D_LINK_ERRORS
| M_ERRNO_SOCK
, "establish_socks_proxy_passthru: TCP port write failed on send()");
348 /* receive reply from Socks proxy */
350 if (!recv_socks_reply (ctrl_sd
, relay_addr
, signal_received
))
356 /* on error, should we exit or restart? */
357 if (!*signal_received
)
358 *signal_received
= (p
->retry
? SIGUSR1
: SIGTERM
); /* SOFT-SIGUSR1 -- socks error */
363 * Remove the 10 byte socks5 header from an incoming
364 * UDP packet, setting *from to the source address.
366 * Run after UDP read.
369 socks_process_incoming_udp (struct buffer
*buf
,
370 struct link_socket_actual
*from
)
378 if (buf_read_u8 (buf
) != 0)
381 atyp
= buf_read_u8 (buf
);
382 if (atyp
!= 1) /* ATYP == 1 (IP V4) */
385 buf_read (buf
, &from
->dest
.sa
.sin_addr
, sizeof (from
->dest
.sa
.sin_addr
));
386 buf_read (buf
, &from
->dest
.sa
.sin_port
, sizeof (from
->dest
.sa
.sin_port
));
395 * Add a 10 byte socks header prior to UDP write.
396 * *to is the destination address.
398 * Run before UDP write.
399 * Returns the size of the header.
402 socks_process_outgoing_udp (struct buffer
*buf
,
403 const struct link_socket_actual
*to
)
406 * Get a 10 byte subset buffer prepended to buf --
407 * we expect these bytes will be here because
408 * we allocated frame space in socks_adjust_frame_parameters.
410 struct buffer head
= buf_sub (buf
, 10, true);
412 /* crash if not enough headroom in buf */
413 ASSERT (buf_defined (&head
));
415 buf_write_u16 (&head
, 0); /* RSV = 0 */
416 buf_write_u8 (&head
, 0); /* FRAG = 0 */
417 buf_write_u8 (&head
, '\x01'); /* ATYP = 1 (IP V4) */
418 buf_write (&head
, &to
->dest
.sa
.sin_addr
, sizeof (to
->dest
.sa
.sin_addr
));
419 buf_write (&head
, &to
->dest
.sa
.sin_port
, sizeof (to
->dest
.sa
.sin_port
));
425 static void dummy(void) {}
426 #endif /* ENABLE_SOCKS */