26
* 2004-01-30: Added Socks5 proxy support
26
* 2004-01-30: Added Socks5 proxy support, see RFC 1928
27
27
* (Christof Meerwald, http://cmeerw.org)
29
* see RFC 1928, only supports "no authentication"
29
* 2010-10-10: Added Socks5 plain text authentication support (RFC 1929)
30
* (Pierre Bourdon <delroth@gmail.com>)
32
33
#include "syshead.h"
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
socks_username_password_auth (struct socks_proxy_info *p,
104
socket_descriptor_t sd,
105
volatile int *signal_received)
110
const int timeout_sec = 5;
111
struct user_pass creds;
115
get_user_pass (&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT);
117
if( !creds.username || (strlen(creds.username) > 255)
118
|| !creds.password || (strlen(creds.password) > 255) ) {
120
"SOCKS username and/or password exceeds 255 characters. "
121
"Authentication not possible.");
124
openvpn_snprintf (to_send, sizeof (to_send), "\x01%c%s%c%s", (int) strlen(creds.username),
125
creds.username, (int) strlen(creds.password), creds.password);
126
size = send (sd, to_send, strlen(to_send), MSG_NOSIGNAL);
128
if (size != strlen (to_send))
130
msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port write failed on send()");
144
tv.tv_sec = timeout_sec;
147
status = select (sd + 1, &reads, NULL, NULL, &tv);
149
get_signal (signal_received);
150
if (*signal_received)
156
msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read timeout expired");
163
msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on select()");
167
/* read single char */
168
size = recv(sd, &c, 1, MSG_NOSIGNAL);
173
msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on recv()");
177
/* store char in buffer */
181
/* VER = 5, SUCCESS = 0 --> auth success */
182
if (buf[0] != 5 && buf[1] != 0)
184
msg (D_LINK_ERRORS, "socks_username_password_auth: server refused the authentication");
192
socks_handshake (struct socks_proxy_info *p,
193
socket_descriptor_t sd,
194
volatile int *signal_received)
198
const int timeout_sec = 5;
200
/* VER = 5, NMETHODS = 2, METHODS = [0 (no auth), 2 (plain login)] */
201
const ssize_t size = send (sd, "\x05\x02\x00\x02", 4, MSG_NOSIGNAL);
103
204
msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_handshake: TCP port write failed on send()");
154
/* VER == 5 && METHOD == 0 */
155
if (buf[0] != '\x05' || buf[1] != '\x00')
256
if (buf[0] != '\x05')
157
258
msg (D_LINK_ERRORS, "socks_handshake: Socks proxy returned bad status");
262
/* select the appropriate authentication method */
265
case 0: /* no authentication */
268
case 2: /* login/password */
271
msg(D_LINK_ERRORS, "socks_handshake: server asked for username/login auth but we were "
272
"not provided any credentials");
276
if (!socks_username_password_auth(p, sd, signal_received))
281
default: /* unknown auth method */
282
msg(D_LINK_ERRORS, "socks_handshake: unknown SOCKS auth method");