In SOCKS5 dynamic forwarding, we were echoing back DST.{ADDR,PORT} as

BND.{ADDR,PORT}. Besides being clearly wrong, correspondence with
Sascha Schwarz suggests that this can confuse some SOCKS5 clients
(Aventail and sockscap32) which seem to assume that the reply must
have ATYP=1 (IPv4 literal) and so get the length wrong.

Now all replies have ATYP=1 with BND.{ADDR,PORT} = 0.0.0.0:0 -- this
apparently follows practice in OpenSSH. (We don't have enough info to
fill these fields in correctly.)

[originally from svn r3496]
This commit is contained in:
Jacob Nevins 2003-10-10 21:20:01 +00:00
Родитель c8a6df1e1c
Коммит 4de860abcf
1 изменённых файлов: 26 добавлений и 9 удалений

Просмотреть файл

@ -108,6 +108,7 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
if (pr->dynamic) {
while (len--) {
if (pr->port >= lenof(pr->hostname)) {
/* Request too long. */
if ((pr->dynamic >> 12) == 4) {
/* Send back a SOCKS 4 error before closing. */
char data[8];
@ -220,7 +221,23 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
}
if (pr->dynamic == 0x5001) {
/*
* We're receiving a SOCKS request.
*/
unsigned char reply[10]; /* SOCKS5 atyp=1 reply */
int atype, alen = 0;
/*
* Pre-fill reply packet.
* In all cases, we set BND.{HOST,ADDR} to 0.0.0.0:0
* (atyp=1) in the reply; if we succeed, we don't know
* the right answers, and if we fail, they should be
* ignored.
*/
memset(reply, 0, lenof(reply));
reply[0] = 5; /* VER */
reply[3] = 1; /* ATYP = 1 (IPv4, 0.0.0.0:0) */
if (pr->port < 6) continue;
atype = (unsigned char)pr->hostname[3];
if (atype == 1) /* IPv4 address */
@ -231,9 +248,9 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
alen = 1 + (unsigned char)pr->hostname[4];
if (pr->port < 6 + alen) continue;
if (pr->hostname[1] != 1 || pr->hostname[2] != 0) {
pr->hostname[1] = 1; /* generic failure */
pr->hostname[2] = 0; /* reserved */
sk_write(pr->s, pr->hostname, pr->port);
/* Not CONNECT or reserved field nonzero - error */
reply[1] = 1; /* generic failure */
sk_write(pr->s, reply, lenof(reply));
pfd_close(pr->s);
return 1;
}
@ -243,8 +260,8 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
*/
pr->port = GET_16BIT_MSB_FIRST(pr->hostname+4+alen);
if (atype == 1) {
pr->hostname[1] = 0; /* succeeded */
sk_write(pr->s, pr->hostname, alen + 6);
/* REP=0 (success) already */
sk_write(pr->s, reply, lenof(reply));
sprintf(pr->hostname, "%d.%d.%d.%d",
(unsigned char)pr->hostname[4],
(unsigned char)pr->hostname[5],
@ -252,8 +269,8 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
(unsigned char)pr->hostname[7]);
goto connect;
} else if (atype == 3) {
pr->hostname[1] = 0; /* succeeded */
sk_write(pr->s, pr->hostname, alen + 6);
/* REP=0 (success) already */
sk_write(pr->s, reply, lenof(reply));
memmove(pr->hostname, pr->hostname + 5, alen-1);
pr->hostname[alen-1] = '\0';
goto connect;
@ -261,8 +278,8 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
/*
* Unknown address type. (FIXME: support IPv6!)
*/
pr->hostname[1] = 8; /* atype not supported */
sk_write(pr->s, pr->hostname, pr->port);
reply[1] = 8; /* atype not supported */
sk_write(pr->s, reply, lenof(reply));
pfd_close(pr->s);
return 1;
}