summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
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");