diff options
Diffstat (limited to 'libs/libcurl/src/socks.c')
-rw-r--r-- | libs/libcurl/src/socks.c | 79 |
1 files changed, 46 insertions, 33 deletions
diff --git a/libs/libcurl/src/socks.c b/libs/libcurl/src/socks.c index 2a8f106510..ea733d9e98 100644 --- a/libs/libcurl/src/socks.c +++ b/libs/libcurl/src/socks.c @@ -71,9 +71,18 @@ enum connect_t { CONNECT_DONE /* 17 connected fine to the remote or the SOCKS proxy */
};
+#define CURL_SOCKS_BUF_SIZE 600
+
+/* make sure we configure it not too low */
+#if CURL_SOCKS_BUF_SIZE < 600
+#error CURL_SOCKS_BUF_SIZE must be at least 600
+#endif
+
+
struct socks_state {
enum connect_t state;
ssize_t outstanding; /* send this many bytes more */
+ unsigned char buffer[CURL_SOCKS_BUF_SIZE];
unsigned char *outp; /* send from this pointer */
const char *hostname;
@@ -249,7 +258,7 @@ static CURLproxycode socks_state_recv(struct Curl_cfilter *cf, failf(data, "connection to proxy closed");
return CURLPX_CLOSED;
}
- failf(data, "SOCKS4: Failed receiving %s: %s", description,
+ failf(data, "SOCKS: Failed receiving %s: %s", description,
curl_easy_strerror(result));
return failcode;
}
@@ -278,14 +287,11 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, struct connectdata *conn = cf->conn;
const bool protocol4a =
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
- unsigned char *socksreq = (unsigned char *)data->state.buffer;
+ unsigned char *socksreq = sx->buffer;
CURLcode result;
CURLproxycode presult;
struct Curl_dns_entry *dns = NULL;
- /* make sure that the buffer is at least 600 bytes */
- DEBUGASSERT(READBUFFER_MIN >= 600);
-
switch(sx->state) {
case CONNECT_SOCKS_INIT:
/* SOCKS4 can only do IPv4, insist! */
@@ -339,8 +345,8 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, if(dns) {
#ifdef CURLRES_ASYNCH
- conn->resolve_async.dns = dns;
- conn->resolve_async.done = TRUE;
+ data->state.async.dns = dns;
+ data->state.async.done = TRUE;
#endif
infof(data, "Hostname '%s' was found", sx->hostname);
sxstate(sx, data, CONNECT_RESOLVED);
@@ -353,9 +359,10 @@ static CURLproxycode do_SOCKS4(struct Curl_cfilter *cf, return CURLPX_OK;
}
}
- /* FALLTHROUGH */
+ FALLTHROUGH();
+ case CONNECT_RESOLVED:
CONNECT_RESOLVED:
- case CONNECT_RESOLVED: {
+ {
struct Curl_addrinfo *hp = NULL;
/*
* We cannot use 'hostent' as a struct that Curl_resolv() returns. It
@@ -393,9 +400,9 @@ CONNECT_RESOLVED: if(!hp)
return CURLPX_RESOLVE_HOST;
}
- /* FALLTHROUGH */
-CONNECT_REQ_INIT:
+ FALLTHROUGH();
case CONNECT_REQ_INIT:
+CONNECT_REQ_INIT:
/*
* This is currently not supporting "Identification Protocol (RFC1413)".
*/
@@ -430,7 +437,7 @@ CONNECT_REQ_INIT: /* append hostname */
hostnamelen = strlen(sx->hostname) + 1; /* length including NUL */
if((hostnamelen <= 255) &&
- (packetsize + hostnamelen < data->set.buffer_size))
+ (packetsize + hostnamelen < sizeof(sx->buffer)))
strcpy((char *)socksreq + packetsize, sx->hostname);
else {
failf(data, "SOCKS4: too long host name");
@@ -439,10 +446,11 @@ CONNECT_REQ_INIT: packetsize += hostnamelen;
}
sx->outp = socksreq;
+ DEBUGASSERT(packetsize <= sizeof(sx->buffer));
sx->outstanding = packetsize;
sxstate(sx, data, CONNECT_REQ_SENDING);
}
- /* FALLTHROUGH */
+ FALLTHROUGH();
case CONNECT_REQ_SENDING:
/* Send request */
presult = socks_state_send(cf, sx, data, CURLPX_SEND_CONNECT,
@@ -458,7 +466,7 @@ CONNECT_REQ_INIT: sx->outp = socksreq;
sxstate(sx, data, CONNECT_SOCKS_READ);
- /* FALLTHROUGH */
+ FALLTHROUGH();
case CONNECT_SOCKS_READ:
/* Receive response */
presult = socks_state_recv(cf, sx, data, CURLPX_RECV_CONNECT,
@@ -570,14 +578,14 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, o X'00' succeeded
*/
struct connectdata *conn = cf->conn;
- unsigned char *socksreq = (unsigned char *)data->state.buffer;
- int idx;
+ unsigned char *socksreq = sx->buffer;
+ size_t idx;
CURLcode result;
CURLproxycode presult;
bool socks5_resolve_local =
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE;
const size_t hostname_len = strlen(sx->hostname);
- ssize_t len = 0;
+ size_t len = 0;
const unsigned char auth = data->set.socks5auth;
bool allow_gssapi = FALSE;
struct Curl_dns_entry *dns = NULL;
@@ -620,6 +628,7 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, socksreq[1] = (unsigned char) (idx - 2);
sx->outp = socksreq;
+ DEBUGASSERT(idx <= sizeof(sx->buffer));
sx->outstanding = idx;
presult = socks_state_send(cf, sx, data, CURLPX_SEND_CONNECT,
"initial SOCKS5 request");
@@ -640,12 +649,12 @@ static CURLproxycode do_SOCKS5(struct Curl_cfilter *cf, /* remain in sending state */
return CURLPX_OK;
}
- /* FALLTHROUGH */
-CONNECT_SOCKS_READ_INIT:
+ FALLTHROUGH();
case CONNECT_SOCKS_READ_INIT:
+CONNECT_SOCKS_READ_INIT:
sx->outstanding = 2; /* expect two bytes */
sx->outp = socksreq; /* store it here */
- /* FALLTHROUGH */
+ FALLTHROUGH();
case CONNECT_SOCKS_READ:
presult = socks_state_recv(cf, sx, data, CURLPX_RECV_CONNECT,
"initial SOCKS5 response");
@@ -746,10 +755,11 @@ CONNECT_AUTH_INIT: }
len += proxy_password_len;
sxstate(sx, data, CONNECT_AUTH_SEND);
+ DEBUGASSERT(len <= sizeof(sx->buffer));
sx->outstanding = len;
sx->outp = socksreq;
}
- /* FALLTHROUGH */
+ FALLTHROUGH();
case CONNECT_AUTH_SEND:
presult = socks_state_send(cf, sx, data, CURLPX_SEND_AUTH,
"SOCKS5 sub-negotiation request");
@@ -762,7 +772,7 @@ CONNECT_AUTH_INIT: sx->outp = socksreq;
sx->outstanding = 2;
sxstate(sx, data, CONNECT_AUTH_READ);
- /* FALLTHROUGH */
+ FALLTHROUGH();
case CONNECT_AUTH_READ:
presult = socks_state_recv(cf, sx, data, CURLPX_RECV_AUTH,
"SOCKS5 sub-negotiation response");
@@ -781,9 +791,9 @@ CONNECT_AUTH_INIT: /* Everything is good so far, user was authenticated! */
sxstate(sx, data, CONNECT_REQ_INIT);
- /* FALLTHROUGH */
-CONNECT_REQ_INIT:
+ FALLTHROUGH();
case CONNECT_REQ_INIT:
+CONNECT_REQ_INIT:
if(socks5_resolve_local) {
enum resolve_t rc = Curl_resolv(data, sx->hostname, sx->remote_port,
TRUE, &dns);
@@ -806,8 +816,8 @@ CONNECT_REQ_INIT: if(dns) {
#ifdef CURLRES_ASYNCH
- conn->resolve_async.dns = dns;
- conn->resolve_async.done = TRUE;
+ data->state.async.dns = dns;
+ data->state.async.done = TRUE;
#endif
infof(data, "SOCKS5: hostname '%s' found", sx->hostname);
}
@@ -820,9 +830,10 @@ CONNECT_REQ_INIT: return CURLPX_OK;
}
}
- /* FALLTHROUGH */
+ FALLTHROUGH();
+ case CONNECT_RESOLVED:
CONNECT_RESOLVED:
- case CONNECT_RESOLVED: {
+ {
char dest[MAX_IPADR_LEN]; /* printable address */
struct Curl_addrinfo *hp = NULL;
if(dns)
@@ -923,10 +934,10 @@ CONNECT_RESOLVE_REMOTE: infof(data, "SOCKS5 connect to %s:%d (remotely resolved)",
sx->hostname, sx->remote_port);
}
- /* FALLTHROUGH */
+ FALLTHROUGH();
-CONNECT_REQ_SEND:
case CONNECT_REQ_SEND:
+CONNECT_REQ_SEND:
/* PORT MSB */
socksreq[len++] = (unsigned char)((sx->remote_port >> 8) & 0xff);
/* PORT LSB */
@@ -939,9 +950,10 @@ CONNECT_REQ_SEND: }
#endif
sx->outp = socksreq;
+ DEBUGASSERT(len <= sizeof(sx->buffer));
sx->outstanding = len;
sxstate(sx, data, CONNECT_REQ_SENDING);
- /* FALLTHROUGH */
+ FALLTHROUGH();
case CONNECT_REQ_SENDING:
presult = socks_state_send(cf, sx, data, CURLPX_SEND_REQUEST,
"SOCKS5 connect request");
@@ -960,7 +972,7 @@ CONNECT_REQ_SEND: sx->outstanding = 10; /* minimum packet size is 10 */
sx->outp = socksreq;
sxstate(sx, data, CONNECT_REQ_READ);
- /* FALLTHROUGH */
+ FALLTHROUGH();
case CONNECT_REQ_READ:
presult = socks_state_recv(cf, sx, data, CURLPX_RECV_REQACK,
"SOCKS5 connect request ack");
@@ -1038,6 +1050,7 @@ CONNECT_REQ_SEND: /* decrypt_gssapi_blockread already read the whole packet */
#endif
if(len > 10) {
+ DEBUGASSERT(len <= sizeof(sx->buffer));
sx->outstanding = len - 10; /* get the rest */
sx->outp = &socksreq[10];
sxstate(sx, data, CONNECT_REQ_READ_MORE);
@@ -1049,7 +1062,7 @@ CONNECT_REQ_SEND: #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
}
#endif
- /* FALLTHROUGH */
+ FALLTHROUGH();
case CONNECT_REQ_READ_MORE:
presult = socks_state_recv(cf, sx, data, CURLPX_RECV_ADDRESS,
"SOCKS5 connect request address");
|