summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2008-01-02 21:40:11 +0000
committerDaniel Stenberg <daniel@haxx.se>2008-01-02 21:40:11 +0000
commita46b40b7fdf567250451b984b977f5e03c716d5e (patch)
treed5df5ab441077f295ec172ed2e94beed44622927 /lib
parent0b9b8acb08aa1a1c1c7668710d01eea8f27039b4 (diff)
downloadcurl-a46b40b7fdf567250451b984b977f5e03c716d5e.tar.gz
Richard Atterer brought a patch that added support for SOCKS4a proxies, which
is an inofficial PROXY4 variant that sends the hostname to the proxy instead of the resolved address (which is already supported by SOCKS5). --socks4a is the curl command line option for it and CURLOPT_PROXYTYPE can now be set to CURLPROXY_SOCKS4A as well.
Diffstat (limited to 'lib')
-rw-r--r--lib/ftp.c16
-rw-r--r--lib/socks.c49
-rw-r--r--lib/socks.h7
-rw-r--r--lib/url.c12
4 files changed, 63 insertions, 21 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index 3b1f3f70f..588cd5bce 100644
--- a/lib/ftp.c
+++ b/lib/ftp.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
@@ -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
diff --git a/lib/url.c b/lib/url.c
index ee8b916e4..a205f9a7b 100644
--- a/lib/url.c
+++ b/lib/url.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
@@ -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");