Changelog
+Daniel S (2 Jan 2008)
+- 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.
+
Daniel S (1 Jan 2008)
- Mohun Biswas pointed out that --libcurl generated a source code with an int
function but without a return statement. While fixing that, I also took care
Curl and libcurl 7.17.2
Public curl releases: 103
- Command line options: 123
+ Command line options: 124
curl_easy_setopt() options: 148
Public functions in libcurl: 55
Public web site mirrors: 42
o --data-urlencode was added
o CURLOPT_PROXY_TRANSFER_MODE was added
o --no-keep-alive was added
+ o --socks4a added (proxy type CURLPROXY_SOCKS4A for libcurl)
This release includes the following bugfixes:
Robin Johnson, Michal Marek, Ates Goral, Andres Garcia, Rob Crittenden,
Emil Romanus, Alessandro Vesely, Ray Pekowski, Spacen Jasset, Andrew Moise,
Gilles Blanc, David Wright, Vikram Saxena, Mateusz Loskot, Gary Maxwell,
- Dmitry Kurochkin, Mohun Biswas
+ Dmitry Kurochkin, Mohun Biswas, Richard Atterer
Thanks! (and sorry if I forgot to mention someone)
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * 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
This option overrides any previous use of \fI-x/--proxy\fP, as they are
mutually exclusive.
+If this option is used several times, the last one will be used.
+.IP "--socks4a <host[:port]>"
+Use the specified SOCKS4a proxy. If the port number is not specified, it is
+assumed at port 1080. (Added in 7.17.2)
+
+This option overrides any previous use of \fI-x/--proxy\fP, as they are
+mutually exclusive.
+
If this option is used several times, the last one will be used.
.IP "--socks5 <host[:port]>"
Use the specified SOCKS5 proxy. If the port number is not specified, it is
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * 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
specified in the proxy string \fICURLOPT_PROXY\fP.
.IP CURLOPT_PROXYTYPE
Pass a long with this option to set type of the proxy. Available options for
-this are \fICURLPROXY_HTTP\fP, \fICURLPROXY_SOCKS4\fP (added in 7.15.2)
-\fICURLPROXY_SOCKS5\fP. The HTTP type is default. (Added in 7.10)
+this are \fICURLPROXY_HTTP\fP, \fICURLPROXY_SOCKS4\fP (added in 7.15.2),
+\fICURLPROXY_SOCKS5\fP and \fICURLPROXY_SOCKS4A\fP (added in 7.17.2). The HTTP
+type is default. (Added in 7.10)
.IP CURLOPT_HTTPPROXYTUNNEL
Set the parameter to non-zero to get the library to tunnel all operations
through a given HTTP proxy. There is a big difference between using a proxy
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
void *userptr);
typedef enum {
- CURLPROXY_HTTP = 0,
- CURLPROXY_SOCKS4 = 4,
- CURLPROXY_SOCKS5 = 5
-} curl_proxytype;
+ CURLPROXY_HTTP = 0, /* added in 7.10 */
+ CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
+ in 7.10 */
+ CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
+ CURLPROXY_SOCKS4A = 6 /* added in 7.17.2 */
+} curl_proxytype; /* this enum was added in 7.10 */
#define CURLAUTH_NONE 0 /* nothing */
#define CURLAUTH_BASIC (1<<0) /* Basic (default) */
CINIT(SHARE, OBJECTPOINT, 100),
/* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
- CURLPROXY_SOCKS4 and CURLPROXY_SOCKS5. */
+ CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
CINIT(PROXYTYPE, LONG, 101),
/* Set the Accept-Encoding string. Use this to tell a server you would like
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
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);
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);
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");
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
* 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];
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;
{
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 */
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,
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
***************************************************************************/
/*
- * 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
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * 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
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;
/* 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");
" -s/--silent Silent mode. Don't output anything",
" -S/--show-error Show error. With -s, make curl show errors when they occur",
" --socks4 <host[:port]> Use SOCKS4 proxy on given host + port",
+ " --socks4a <host[:port]> Use SOCKS4a proxy on given host + port",
" --socks5 <host[:port]> Use SOCKS5 proxy on given host + port",
" --stderr <file> Where to redirect stderr. - means stdout",
" -t/--telnet-option <OPT=val> Set telnet option",
{"$r", "ftp-method", TRUE},
{"$s", "local-port", TRUE},
{"$t", "socks4", TRUE},
+ {"$T", "socks4a", TRUE},
{"$u", "ftp-alternative-to-user", TRUE},
{"$v", "ftp-ssl-reqd", FALSE},
{"$w", "no-sessionid", FALSE},
GetStr(&config->socksproxy, nextarg);
config->socksver = CURLPROXY_SOCKS4;
break;
+ case 'T': /* --socks4a specifies a socks4a proxy to use */
+ GetStr(&config->socksproxy, nextarg);
+ config->socksver = CURLPROXY_SOCKS4A;
+ break;
case 'd': /* --tcp-nodelay option */
config->tcp_nodelay ^= TRUE;
break;