diff options
Diffstat (limited to 'libs/libcurl/src/socks.c')
-rw-r--r-- | libs/libcurl/src/socks.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c index 487f26d2c4..2a8f106510 100644 --- a/libs/libcurl/src/socks.c +++ b/libs/libcurl/src/socks.c @@ -339,8 +339,8 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, if(dns) {
#ifdef CURLRES_ASYNCH
- data->state.async.dns = dns;
- data->state.async.done = TRUE;
+ conn->resolve_async.dns = dns;
+ conn->resolve_async.done = TRUE;
#endif
infof(data, "Hostname '%s' was found", sx->hostname);
sxstate(sx, data, CONNECT_RESOLVED);
@@ -402,8 +402,11 @@ CONNECT_REQ_INIT: socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
if(sx->proxy_user) {
size_t plen = strlen(sx->proxy_user);
- if(plen >= (size_t)data->set.buffer_size - 8) {
- failf(data, "Too long SOCKS proxy user name, can't use");
+ if(plen > 255) {
+ /* there is no real size limit to this field in the protocol, but
+ SOCKS5 limits the proxy user field to 255 bytes and it seems likely
+ that a longer field is either a mistake or malicious input */
+ failf(data, "Too long SOCKS proxy user name");
return CURLPX_LONG_USER;
}
/* copy the proxy name WITH trailing zero */
@@ -426,7 +429,8 @@ CONNECT_REQ_INIT: socksreq[7] = 1;
/* append hostname */
hostnamelen = strlen(sx->hostname) + 1; /* length including NUL */
- if(hostnamelen <= 255)
+ if((hostnamelen <= 255) &&
+ (packetsize + hostnamelen < data->set.buffer_size))
strcpy((char *)socksreq + packetsize, sx->hostname);
else {
failf(data, "SOCKS4: too long host name");
@@ -802,8 +806,8 @@ CONNECT_REQ_INIT: if(dns) {
#ifdef CURLRES_ASYNCH
- data->state.async.dns = dns;
- data->state.async.done = TRUE;
+ conn->resolve_async.dns = dns;
+ conn->resolve_async.done = TRUE;
#endif
infof(data, "SOCKS5: hostname '%s' found", sx->hostname);
}
@@ -819,10 +823,19 @@ CONNECT_REQ_INIT: /* FALLTHROUGH */
CONNECT_RESOLVED:
case CONNECT_RESOLVED: {
- char dest[MAX_IPADR_LEN] = "unknown"; /* printable address */
+ char dest[MAX_IPADR_LEN]; /* printable address */
struct Curl_addrinfo *hp = NULL;
if(dns)
hp = dns->addr;
+#ifdef ENABLE_IPV6
+ if(data->set.ipver != CURL_IPRESOLVE_WHATEVER) {
+ int wanted_family = data->set.ipver == CURL_IPRESOLVE_V4 ?
+ AF_INET : AF_INET6;
+ /* scan for the first proper address */
+ while(hp && (hp->ai_family != wanted_family))
+ hp = hp->ai_next;
+ }
+#endif
if(!hp) {
failf(data, "Failed to resolve \"%s\" for SOCKS5 connect.",
sx->hostname);
@@ -1119,7 +1132,7 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf, return result;
if(!sx) {
- sx = calloc(sizeof(*sx), 1);
+ sx = calloc(1, sizeof(*sx));
if(!sx)
return CURLE_OUT_OF_MEMORY;
cf->ctx = sx;
@@ -1157,32 +1170,29 @@ static CURLcode socks_proxy_cf_connect(struct Curl_cfilter *cf, return result;
}
-static int socks_cf_get_select_socks(struct Curl_cfilter *cf,
+static void socks_cf_adjust_pollset(struct Curl_cfilter *cf,
struct Curl_easy *data,
- curl_socket_t *socks)
+ struct easy_pollset *ps)
{
struct socks_state *sx = cf->ctx;
- int fds;
- fds = cf->next->cft->get_select_socks(cf->next, data, socks);
- if(!fds && cf->next->connected && !cf->connected && sx) {
+ if(!cf->connected && sx) {
/* If we are not connected, the filter below is and has nothing
* to wait on, we determine what to wait for. */
- socks[0] = Curl_conn_cf_get_socket(cf, data);
+ curl_socket_t sock = Curl_conn_cf_get_socket(cf, data);
switch(sx->state) {
case CONNECT_RESOLVING:
case CONNECT_SOCKS_READ:
case CONNECT_AUTH_READ:
case CONNECT_REQ_READ:
case CONNECT_REQ_READ_MORE:
- fds = GETSOCK_READSOCK(0);
+ Curl_pollset_set_in_only(data, ps, sock);
break;
default:
- fds = GETSOCK_WRITESOCK(0);
+ Curl_pollset_set_out_only(data, ps, sock);
break;
}
}
- return fds;
}
static void socks_proxy_cf_close(struct Curl_cfilter *cf,
@@ -1227,7 +1237,7 @@ struct Curl_cftype Curl_cft_socks_proxy = { socks_proxy_cf_connect,
socks_proxy_cf_close,
socks_cf_get_host,
- socks_cf_get_select_socks,
+ socks_cf_adjust_pollset,
Curl_cf_def_data_pending,
Curl_cf_def_send,
Curl_cf_def_recv,
|