X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=gateway.c;h=f1d160edf375d0c0ba518810dc6e8a94eb6d471e;hp=d007c00affbf32429bc72a1e364b3a5f9db8a8f9;hb=5947c5c37ce440d26761aec3cdb9f25ae297be01;hpb=1749113749e4ce6b1d62f17ef630e348063ba66a diff --git a/gateway.c b/gateway.c index d007c00a..f1d160ed 100644 --- a/gateway.c +++ b/gateway.c @@ -1,4 +1,4 @@ -const char gateway_rcs[] = "$Id: gateway.c,v 1.22 2008/02/03 13:46:15 fabiankeil Exp $"; +const char gateway_rcs[] = "$Id: gateway.c,v 1.25 2008/02/07 18:09:46 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/gateway.c,v $ @@ -34,6 +34,22 @@ const char gateway_rcs[] = "$Id: gateway.c,v 1.22 2008/02/03 13:46:15 fabiankeil * * Revisions : * $Log: gateway.c,v $ + * Revision 1.25 2008/02/07 18:09:46 fabiankeil + * In socks5_connect: + * - make the buffers quite a bit smaller. + * - properly report "socks5 server unreachable" failures. + * - let strncpy() use the whole buffer. Using a length of 0xffu wasn't actually + * wrong, but requires too much thinking as it doesn't depend on the buffer size. + * - log a message if the socks5 server sends more data than expected. + * - add some assertions and comments. + * + * Revision 1.24 2008/02/04 14:56:29 fabiankeil + * - Fix a compiler warning. + * - Stop assuming that htonl(INADDR_NONE) equals INADDR_NONE. + * + * Revision 1.23 2008/02/04 13:11:35 fabiankeil + * Remember the cause of the SOCKS5 error for the CGI message. + * * Revision 1.22 2008/02/03 13:46:15 fabiankeil * Add SOCKS5 support. Patch #1862863 by Eric M. Hopper with minor changes. * @@ -195,7 +211,7 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, #define SOCKS5_REQUEST_DENIED 2 #define SOCKS5_REQUEST_NETWORK_UNREACHABLE 3 #define SOCKS5_REQUEST_HOST_UNREACHABLE 4 -#define SOCKS5_REQUEST_CONNECTION_REFUSEDD 5 +#define SOCKS5_REQUEST_CONNECTION_REFUSED 5 #define SOCKS5_REQUEST_TTL_EXPIRED 6 #define SOCKS5_REQUEST_PROTOCOL_ERROR 7 #define SOCKS5_REQUEST_BAD_ADDRESS_TYPE 8 @@ -308,7 +324,7 @@ static jb_socket socks4_connect(const struct forward_spec * fwd, int target_port, struct client_state *csp) { - int web_server_addr; + unsigned int web_server_addr; char buf[BUFFER_SIZE]; struct socks_op *c = (struct socks_op *)buf; struct socks_reply *s = (struct socks_reply *)buf; @@ -348,13 +364,17 @@ static jb_socket socks4_connect(const struct forward_spec * fwd, switch (fwd->type) { case SOCKS_4: - web_server_addr = htonl(resolve_hostname_to_ip(target_host)); + web_server_addr = resolve_hostname_to_ip(target_host); if (web_server_addr == INADDR_NONE) { errstr = "could not resolve target host"; log_error(LOG_LEVEL_CONNECT, "socks4_connect: %s %s", errstr, target_host); err = 1; } + else + { + web_server_addr = htonl(web_server_addr); + } break; case SOCKS_4A: web_server_addr = 0x00000001; @@ -499,7 +519,7 @@ static const char *translate_socks5_error(int socks_error) return "SOCKS5 network unreachable"; case SOCKS5_REQUEST_HOST_UNREACHABLE: return "SOCKS5 host unreachable"; - case SOCKS5_REQUEST_CONNECTION_REFUSEDD: + case SOCKS5_REQUEST_CONNECTION_REFUSED: return "SOCKS5 connection refused"; case SOCKS5_REQUEST_TTL_EXPIRED: return "SOCKS5 TTL expired"; @@ -539,14 +559,15 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, struct client_state *csp) { int err = 0; - char cbuf[BUFFER_SIZE]; - char sbuf[BUFFER_SIZE]; + char cbuf[300]; + char sbuf[30]; size_t client_pos = 0; int server_size = 0; size_t hostlen = 0; jb_socket sfd; const char *errstr = NULL; + assert(fwd->gateway_host); if ((fwd->gateway_host == NULL) || (*fwd->gateway_host == '\0')) { errstr = "NULL gateway host specified"; @@ -555,6 +576,11 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, if (fwd->gateway_port <= 0) { + /* + * XXX: currently this can't happen because in + * case of invalid gateway ports we use the defaults. + * Of course we really shouldn't do that. + */ errstr = "invalid gateway port specified"; err = 1; } @@ -588,6 +614,9 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, if (sfd == JB_INVALID_SOCKET) { + errstr = "socks5 server unreachable"; + log_error(LOG_LEVEL_CONNECT, "socks5_connect: %s", errstr); + csp->error_message = strdup(errstr); return(JB_INVALID_SOCKET); } @@ -645,7 +674,9 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, cbuf[client_pos++] = '\x00'; /* Reserved, must be 0x00 */ cbuf[client_pos++] = '\x03'; /* Address is domain name */ cbuf[client_pos++] = (char)(hostlen & 0xffu); - strncpy(cbuf + client_pos, target_host, 0xffu); + assert(sizeof(cbuf) - client_pos > 255); + /* Using strncpy because we really want the nul byte padding. */ + strncpy(cbuf + client_pos, target_host, sizeof(cbuf) - client_pos); client_pos += (hostlen & 0xffu); cbuf[client_pos++] = (char)((target_port >> 8) & 0xffu); cbuf[client_pos++] = (char)((target_port ) & 0xffu); @@ -666,6 +697,13 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, errstr = "SOCKS5 negotiation read failed"; err = 1; } + else if (server_size > 20) + { + /* This is somewhat unexpected but doesn't realy matter. */ + log_error(LOG_LEVEL_CONNECT, "socks5_connect: read %d bytes " + "from socks server. Would have accepted up to %d.", + server_size, sizeof(sbuf)); + } if (!err && (sbuf[0] != '\x05')) { @@ -694,7 +732,9 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, log_error(LOG_LEVEL_CONNECT, "socks5_connect: %s", errstr); close_socket(sfd); errno = EINVAL; + return(JB_INVALID_SOCKET); + } /*