1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Support username/password authentication in SOCKS 5.

[originally from svn r1972]
This commit is contained in:
Simon Tatham 2002-09-21 16:07:43 +00:00
parent 442a360fb2
commit d33c200de1
2 changed files with 67 additions and 12 deletions

View File

@ -1,4 +1,4 @@
\versionid $Id: config.but,v 1.39 2002/09/21 14:03:05 simon Exp $
\versionid $Id: config.but,v 1.40 2002/09/21 16:07:43 simon Exp $
\C{config} Configuring PuTTY
@ -1433,15 +1433,14 @@ This excludes both of the above ranges at once.
If your proxy requires authentication, you can enter a username and
a password in the \q{Username} and \q{Password} boxes.
Authentication is not supported for all forms of proxy. Currently:
Authentication is not supported for all forms of proxy:
\b Username and password authentication is supported for HTTP proxies.
\b Username and password authentication is supported for HTTP
proxies and SOCKS 5 proxies.
\b SOCKS 4 can use the \q{Username} field, but does not support
passwords.
\b PuTTY does not support authentication in SOCKS 5 at all.
\b Authentication is meaningless in Telnet proxies.
\S{config-proxy-command} Specifying the Telnet proxy command

70
proxy.c
View File

@ -683,6 +683,7 @@ int proxy_socks4_negotiate (Proxy_Socket p, int change)
return 1;
}
bufchain_consume(&p->pending_input_data, 2);
/* we're done */
proxy_activate(p);
@ -713,13 +714,22 @@ int proxy_socks5_negotiate (Proxy_Socket p, int change)
* 0x03 = CHAP
*/
char command[3];
char command[4];
int len;
command[0] = 5; /* version 5 */
command[1] = 1; /* TODO: we don't currently support any auth methods */
command[2] = 0x00; /* no authentication */
if (cfg.proxy_username[0] || cfg.proxy_password[0]) {
command[1] = 2; /* two methods supported: */
command[2] = 0x00; /* no authentication */
command[3] = 0x02; /* username/password */
len = 4;
} else {
command[1] = 1; /* one methods supported: */
command[2] = 0x00; /* no authentication */
len = 3;
}
sk_write(p->sub_socket, command, 3);
sk_write(p->sub_socket, command, len);
p->state = 1;
return 0;
@ -795,6 +805,36 @@ int proxy_socks5_negotiate (Proxy_Socket p, int change)
PROXY_ERROR_GENERAL, 0);
return 1;
}
bufchain_consume(&p->pending_input_data, 2);
}
if (p->state == 7) {
/* password authentication reply format:
* version number (1 bytes) = 1
* reply code (1 byte)
* 0 = succeeded
* >0 = failed
*/
/* get the response */
bufchain_prefix(&p->pending_input_data, &data, &len);
if (data[0] != 1) {
plug_closing(p->plug, "Network error: Error while communicating with proxy",
PROXY_ERROR_GENERAL, 0);
return 1;
}
if (data[1] != 0) {
plug_closing(p->plug, "Network error: Proxy refused authentication",
PROXY_ERROR_GENERAL, 0);
return 1;
}
bufchain_consume(&p->pending_input_data, 2);
p->state = 2; /* now proceed as authenticated */
}
if (p->state == 2) {
@ -909,9 +949,24 @@ int proxy_socks5_negotiate (Proxy_Socket p, int change)
}
if (p->state == 5) {
/* TODO: Handle username/password authentication */
plug_closing(p->plug, "Network error: We don't support username/password "
"authentication",
if (cfg.proxy_username[0] || cfg.proxy_password[0]) {
char userpwbuf[514];
int ulen, plen;
ulen = strlen(cfg.proxy_username);
if (ulen > 255) ulen = 255; if (ulen < 1) ulen = 1;
plen = strlen(cfg.proxy_password);
if (plen > 255) plen = 255; if (plen < 1) plen = 1;
userpwbuf[0] = 1; /* version number of subnegotiation */
userpwbuf[1] = ulen;
memcpy(userpwbuf+2, cfg.proxy_username, ulen);
userpwbuf[ulen+2] = plen;
memcpy(userpwbuf+ulen+3, cfg.proxy_password, plen);
sk_write(p->sub_socket, userpwbuf, ulen + plen + 3);
p->state = 7;
} else
plug_closing(p->plug, "Network error: Server chose "
"username/password authentication but we "
"didn't offer it!",
PROXY_ERROR_GENERAL, 0);
return 1;
}
@ -922,6 +977,7 @@ int proxy_socks5_negotiate (Proxy_Socket p, int change)
PROXY_ERROR_GENERAL, 0);
return 1;
}
}
plug_closing(p->plug, "Network error: Unexpected proxy error",