Ticket #62: openvpn-socks-auth.patch
File openvpn-socks-auth.patch, 7.4 KB (added by , 12 years ago) |
---|
-
init.c
diff --git a/init.c b/init.c index a46fbde..f84fd35 100644
a b init_proxy_dowork (struct context *c) 417 417 { 418 418 c->c1.socks_proxy = socks_proxy_new (c->options.ce.socks_proxy_server, 419 419 c->options.ce.socks_proxy_port, 420 c->options.ce.socks_proxy_authfile, 420 421 c->options.ce.socks_proxy_retry, 421 422 c->options.auto_proxy_info); 422 423 if (c->c1.socks_proxy) -
options.c
diff --git a/options.c b/options.c index 5f1efc5..ae4eafb 100644
a b static const char usage_message[] = 120 120 " AGENT user-agent\n" 121 121 #endif 122 122 #ifdef ENABLE_SOCKS 123 "--socks-proxy s [p]: Connect to remote host through a Socks5 proxy at address\n" 124 " s and port p (default port = 1080).\n" 123 "--socks-proxy s [p] [up] : Connect to remote host through a Socks5 proxy at\n" 124 " address s and port p (default port = 1080).\n" 125 " If proxy authentication is required,\n" 126 " up is a file containing username/password on 2 lines, or\n" 127 " 'stdin' to prompt for console.\n" 125 128 "--socks-proxy-retry : Retry indefinitely on Socks proxy errors.\n" 126 129 #endif 127 130 "--resolv-retry n: If hostname resolve fails for --remote, retry\n" … … add_option (struct options *options, 4471 4474 options->ce.socks_proxy_port = 1080; 4472 4475 } 4473 4476 options->ce.socks_proxy_server = p[1]; 4477 options->ce.socks_proxy_authfile = p[3]; /* might be NULL */ 4474 4478 } 4475 4479 else if (streq (p[0], "socks-proxy-retry")) 4476 4480 { -
options.h
diff --git a/options.h b/options.h index fc5db58..c1e6d6d 100644
a b struct connection_entry 95 95 #ifdef ENABLE_SOCKS 96 96 const char *socks_proxy_server; 97 97 int socks_proxy_port; 98 const char *socks_proxy_authfile; 98 99 bool socks_proxy_retry; 99 100 #endif 100 101 -
socks.c
diff --git a/socks.c b/socks.c index 0c1bb3e..94fe1f9 100644
a b 38 38 #include "win32.h" 39 39 #include "socket.h" 40 40 #include "fdmisc.h" 41 #include "misc.h" 41 42 #include "proxy.h" 42 43 43 44 #include "memdbg.h" 44 45 46 #define UP_TYPE_SOCKS "SOCKS Proxy" 45 47 46 48 void 47 49 socks_adjust_frame_parameters (struct frame *frame, int proto) … … socks_adjust_frame_parameters (struct frame *frame, int proto) 53 55 struct socks_proxy_info * 54 56 socks_proxy_new (const char *server, 55 57 int port, 58 const char *authfile, 56 59 bool retry, 57 60 struct auto_proxy_info *auto_proxy_info) 58 61 { … … socks_proxy_new (const char *server, 77 80 78 81 strncpynt (p->server, server, sizeof (p->server)); 79 82 p->port = port; 83 84 if (authfile) 85 strncpynt (p->authfile, authfile, sizeof (p->authfile)); 86 else 87 p->authfile[0] = 0; 88 80 89 p->retry = retry; 81 90 p->defined = true; 82 91 … … socks_proxy_close (struct socks_proxy_info *sp) 90 99 } 91 100 92 101 static bool 93 socks_handshake (socket_descriptor_t sd, volatile int *signal_received) 102 socks_username_password_auth (struct socks_proxy_info *p, 103 socket_descriptor_t sd, 104 volatile int *signal_received) 105 { 106 char to_send[516]; 107 char buf[2]; 108 int len = 0; 109 const int timeout_sec = 5; 110 struct user_pass creds; 111 ssize_t size; 112 113 creds.defined = 0; 114 115 get_user_pass (&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT); 116 snprintf (to_send, sizeof (to_send), "\x01%c%s%c%s", strlen(creds.username), 117 creds.username, strlen(creds.password), creds.password); 118 size = send (sd, to_send, strlen(to_send), MSG_NOSIGNAL); 119 120 if (size != strlen (to_send)) 121 { 122 msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port write failed on send()"); 123 return false; 124 } 125 126 while (len < 2) 127 { 128 int status; 129 ssize_t size; 130 fd_set reads; 131 struct timeval tv; 132 char c; 133 134 FD_ZERO (&reads); 135 FD_SET (sd, &reads); 136 tv.tv_sec = timeout_sec; 137 tv.tv_usec = 0; 138 139 status = select (sd + 1, &reads, NULL, NULL, &tv); 140 141 get_signal (signal_received); 142 if (*signal_received) 143 return false; 144 145 /* timeout? */ 146 if (status == 0) 147 { 148 msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read timeout expired"); 149 return false; 150 } 151 152 /* error */ 153 if (status < 0) 154 { 155 msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on select()"); 156 return false; 157 } 158 159 /* read single char */ 160 size = recv(sd, &c, 1, MSG_NOSIGNAL); 161 162 /* error? */ 163 if (size != 1) 164 { 165 msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_username_password_auth: TCP port read failed on recv()"); 166 return false; 167 } 168 169 /* store char in buffer */ 170 buf[len++] = c; 171 } 172 173 if (buf[0] != 5 && buf[1] != 0) 174 { 175 msg (D_LINK_ERRORS, "socks_username_password_auth: server refused the authentication"); 176 return false; 177 } 178 179 return true; 180 } 181 182 static bool 183 socks_handshake (struct socks_proxy_info *p, 184 socket_descriptor_t sd, 185 volatile int *signal_received) 94 186 { 95 187 char buf[2]; 96 188 int len = 0; 97 189 const int timeout_sec = 5; 98 190 99 /* VER = 5, NMETHODS = 1, METHODS = [0] */100 const ssize_t size = send (sd, "\x05\x0 1\x00", 3, MSG_NOSIGNAL);101 if (size != 3)191 /* VER = 5, NMETHODS = 2, METHODS = [0 (no auth), 2 (plain login)] */ 192 const ssize_t size = send (sd, "\x05\x02\x00\x02", 4, MSG_NOSIGNAL); 193 if (size != 4) 102 194 { 103 195 msg (D_LINK_ERRORS | M_ERRNO_SOCK, "socks_handshake: TCP port write failed on send()"); 104 196 return false; … … socks_handshake (socket_descriptor_t sd, volatile int *signal_received) 151 243 buf[len++] = c; 152 244 } 153 245 154 /* VER == 5 && METHOD == 0*/155 if (buf[0] != '\x05' || buf[1] != '\x00')246 /* VER == 5 */ 247 if (buf[0] != '\x05') 156 248 { 157 249 msg (D_LINK_ERRORS, "socks_handshake: Socks proxy returned bad status"); 158 250 return false; 159 251 } 160 252 253 /* select the appropriate authentication method */ 254 switch (buf[1]) 255 { 256 case 0: /* no authentication */ 257 break; 258 259 case 2: /* login/password */ 260 if (!p->authfile[0]) 261 { 262 msg(D_LINK_ERRORS, "socks_handshake: server asked for username/login auth but we were " 263 "not provided any credentials"); 264 return false; 265 } 266 267 if (!socks_username_password_auth(p, sd, signal_received)) 268 return false; 269 270 break; 271 272 default: /* unknown auth method */ 273 msg(D_LINK_ERRORS, "socks_handshake: unknown SOCKS auth method"); 274 return false; 275 } 276 161 277 return true; 162 278 } 163 279 … … establish_socks_proxy_passthru (struct socks_proxy_info *p, 281 397 char buf[128]; 282 398 size_t len; 283 399 284 if (!socks_handshake ( sd, signal_received))400 if (!socks_handshake (p, sd, signal_received)) 285 401 goto error; 286 402 287 403 /* format Socks CONNECT message */ … … establish_socks_proxy_udpassoc (struct socks_proxy_info *p, 328 444 struct openvpn_sockaddr *relay_addr, 329 445 volatile int *signal_received) 330 446 { 331 if (!socks_handshake ( ctrl_sd, signal_received))447 if (!socks_handshake (p, ctrl_sd, signal_received)) 332 448 goto error; 333 449 334 450 { -
socks.h
diff --git a/socks.h b/socks.h index 702aa06..b748bb3 100644
a b struct socks_proxy_info { 43 43 44 44 char server[128]; 45 45 int port; 46 char authfile[256]; 46 47 }; 47 48 48 49 void socks_adjust_frame_parameters (struct frame *frame, int proto); 49 50 50 51 struct socks_proxy_info *socks_proxy_new (const char *server, 51 52 int port, 53 const char *authfile, 52 54 bool retry, 53 55 struct auto_proxy_info *auto_proxy_info); 54 56