diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ftp.c | 16 | ||||
-rw-r--r-- | lib/socks.c | 49 | ||||
-rw-r--r-- | lib/socks.h | 7 | ||||
-rw-r--r-- | lib/url.c | 12 |
4 files changed, 63 insertions, 21 deletions
@@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1726,8 +1726,9 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn, newport = (unsigned short)(num & 0xffff); if(conn->bits.tunnel_proxy || - data->set.proxytype == CURLPROXY_SOCKS5 || - data->set.proxytype == CURLPROXY_SOCKS4) + data->set.proxytype == CURLPROXY_SOCKS5 || + data->set.proxytype == CURLPROXY_SOCKS4 || + data->set.proxytype == CURLPROXY_SOCKS4A) /* proxy tunnel -> use other host info because ip_addr_str is the proxy address not the ftp host */ snprintf(newhost, sizeof(newhost), "%s", conn->host.name); @@ -1781,7 +1782,8 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn, conn->ip_addr_str); if(conn->bits.tunnel_proxy || data->set.proxytype == CURLPROXY_SOCKS5 || - data->set.proxytype == CURLPROXY_SOCKS4) + data->set.proxytype == CURLPROXY_SOCKS4 || + data->set.proxytype == CURLPROXY_SOCKS4A) /* proxy tunnel -> use other host info because ip_addr_str is the proxy address not the ftp host */ snprintf(newhost, sizeof(newhost), "%s", conn->host.name); @@ -1886,7 +1888,11 @@ static CURLcode ftp_state_pasv_resp(struct connectdata *conn, break; case CURLPROXY_SOCKS4: result = Curl_SOCKS4(conn->proxyuser, newhost, newport, - SECONDARYSOCKET, conn); + SECONDARYSOCKET, conn, false); + break; + case CURLPROXY_SOCKS4A: + result = Curl_SOCKS4(conn->proxyuser, newhost, newport, + SECONDARYSOCKET, conn, true); break; default: failf(data, "unknown proxytype option given"); diff --git a/lib/socks.c b/lib/socks.c index 2b3113ddf..5146b0dc4 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -118,16 +118,19 @@ static int blockread_all(struct connectdata *conn, /* connection data */ * http://socks.permeo.com/protocol/socks4.protocol * * Note : -* Nonsupport "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" +* Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" * Nonsupport "Identification Protocol (RFC1413)" */ CURLcode Curl_SOCKS4(const char *proxy_name, const char *hostname, int remote_port, int sockindex, - struct connectdata *conn) + struct connectdata *conn, + bool protocol4a) { - unsigned char socksreq[262]; /* room for SOCKS4 request incl. user id */ +#define SOCKS4REQLEN 262 + unsigned char socksreq[SOCKS4REQLEN]; /* room for SOCKS4 request incl. user + id */ int result; CURLcode code; curl_socket_t sock = conn->sock[sockindex]; @@ -165,8 +168,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name, socksreq[1] = 1; /* connect */ *((unsigned short*)&socksreq[2]) = htons((unsigned short)remote_port); - /* DNS resolve */ - { + /* DNS resolve only for SOCKS4, not SOCKS4a */ + if (!protocol4a) { struct Curl_dns_entry *dns; Curl_addrinfo *hp=NULL; int rc; @@ -225,15 +228,40 @@ CURLcode Curl_SOCKS4(const char *proxy_name, { ssize_t actualread; ssize_t written; + ssize_t hostnamelen = 0; int packetsize = 9 + (int)strlen((char*)socksreq + 8); /* size including NUL */ + /* If SOCKS4a, set special invalid IP address 0.0.0.x */ + if (protocol4a) { + socksreq[4] = 0; + socksreq[5] = 0; + socksreq[6] = 0; + socksreq[7] = 1; + /* If still enough room in buffer, also append hostname */ + hostnamelen = strlen(hostname) + 1; /* length including NUL */ + if (packetsize + hostnamelen <= SOCKS4REQLEN) + strcpy((char*)socksreq + packetsize, hostname); + else + hostnamelen = 0; /* Flag: hostname did not fit in buffer */ + } + /* Send request */ - code = Curl_write(conn, sock, (char *)socksreq, packetsize, &written); - if((code != CURLE_OK) || (written != packetsize)) { + code = Curl_write(conn, sock, (char *)socksreq, packetsize + hostnamelen, + &written); + if((code != CURLE_OK) || (written != packetsize + hostnamelen)) { failf(data, "Failed to send SOCKS4 connect request."); return CURLE_COULDNT_CONNECT; } + if (protocol4a && hostnamelen == 0) { + /* SOCKS4a with very long hostname - send that name separately */ + hostnamelen = strlen(hostname) + 1; + code = Curl_write(conn, sock, (char *)hostname, hostnamelen, &written); + if((code != CURLE_OK) || (written != hostnamelen)) { + failf(data, "Failed to send SOCKS4 connect request."); + return CURLE_COULDNT_CONNECT; + } + } packetsize = 8; /* receive data size */ @@ -275,7 +303,10 @@ CURLcode Curl_SOCKS4(const char *proxy_name, switch(socksreq[1]) { case 90: - infof(data, "SOCKS4 request granted.\n"); + if (protocol4a) + infof(data, "SOCKS4a request granted.\n"); + else + infof(data, "SOCKS4 request granted.\n"); break; case 91: failf(data, diff --git a/lib/socks.h b/lib/socks.h index 8da142fbd..756ecc3db 100644 --- a/lib/socks.h +++ b/lib/socks.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -24,14 +24,15 @@ ***************************************************************************/ /* - * This function logs in to a SOCKS4 proxy and sends the specifics to the + * This function logs in to a SOCKS4(a) proxy and sends the specifics to the * final destination server. */ CURLcode Curl_SOCKS4(const char *proxy_name, const char *hostname, int remote_port, int sockindex, - struct connectdata *conn); + struct connectdata *conn, + bool protocol4a); /* * This function logs in to a SOCKS5 proxy and sends the specifics to the @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2007, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -1868,7 +1868,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, case CURLOPT_PROXYTYPE: /* - * Set proxy type. HTTP/SOCKS4/SOCKS5 + * Set proxy type. HTTP/SOCKS4/SOCKS4a/SOCKS5 */ data->set.proxytype = (curl_proxytype)va_arg(param, long); break; @@ -2643,8 +2643,12 @@ static CURLcode ConnectPlease(struct SessionHandle *data, /* do nothing here. handled later. */ break; case CURLPROXY_SOCKS4: - result = Curl_SOCKS4(conn->proxyuser, conn->host.name, conn->remote_port, - FIRSTSOCKET, conn); + result = Curl_SOCKS4(conn->proxyuser, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn, false); + break; + case CURLPROXY_SOCKS4A: + result = Curl_SOCKS4(conn->proxyuser, conn->host.name, + conn->remote_port, FIRSTSOCKET, conn, true); break; default: failf(data, "unknown proxytype option given"); |