summaryrefslogtreecommitdiffstats
path: root/lib/socks.c
diff options
context:
space:
mode:
authorCurl Upstream <curl-library@cool.haxx.se>2021-02-03 07:02:36 (GMT)
committerBrad King <brad.king@kitware.com>2021-02-03 16:49:32 (GMT)
commit076b3219f58ca16afa52fe095019a05537ade0f3 (patch)
treef9ea493f94ce5afb8792e1ab4a040cea7eba4aed /lib/socks.c
parent5aacc593a961fe9ee1427c03d18fba8947a9e33d (diff)
downloadCMake-076b3219f58ca16afa52fe095019a05537ade0f3.zip
CMake-076b3219f58ca16afa52fe095019a05537ade0f3.tar.gz
CMake-076b3219f58ca16afa52fe095019a05537ade0f3.tar.bz2
curl 2021-02-03 (2f33be81)
Code extracted from: https://github.com/curl/curl.git at commit 2f33be817cbce6ad7a36f27dd7ada9219f13584c (curl-7_75_0).
Diffstat (limited to 'lib/socks.c')
-rw-r--r--lib/socks.c134
1 files changed, 67 insertions, 67 deletions
diff --git a/lib/socks.c b/lib/socks.c
index a2d1e62..d1c2a2e 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2021, 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
@@ -51,7 +51,7 @@
*
* This is STUPID BLOCKING behavior. Only used by the SOCKS GSSAPI functions.
*/
-int Curl_blockread_all(struct connectdata *conn, /* connection data */
+int Curl_blockread_all(struct Curl_easy *data, /* transfer */
curl_socket_t sockfd, /* read from this socket */
char *buf, /* store read data here */
ssize_t buffersize, /* max amount to read */
@@ -62,7 +62,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
int result;
*n = 0;
for(;;) {
- timediff_t timeout_ms = Curl_timeleft(conn->data, NULL, TRUE);
+ timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
if(timeout_ms < 0) {
/* we already got the timeout */
result = CURLE_OPERATION_TIMEDOUT;
@@ -107,13 +107,14 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
/* always use this function to change state, to make debugging easier */
-static void socksstate(struct connectdata *conn,
+static void socksstate(struct Curl_easy *data,
enum connect_t state
#ifdef DEBUGBUILD
, int lineno
#endif
)
{
+ struct connectdata *conn = data->conn;
enum connect_t oldstate = conn->cnnct.state;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
/* synced with the state list in urldata.h */
@@ -146,7 +147,7 @@ static void socksstate(struct connectdata *conn,
conn->cnnct.state = state;
#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
- infof(conn->data,
+ infof(data,
"SXSTATE: %s => %s conn %p; line %d\n",
statename[oldstate], statename[conn->cnnct.state], conn,
lineno);
@@ -188,29 +189,32 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
const char *hostname,
int remote_port,
int sockindex,
- struct connectdata *conn,
+ struct Curl_easy *data,
bool *done)
{
+ struct connectdata *conn = data->conn;
const bool protocol4a =
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS4A) ? TRUE : FALSE;
- unsigned char *socksreq = &conn->cnnct.socksreq[0];
+ unsigned char *socksreq = (unsigned char *)data->state.buffer;
CURLcode result;
curl_socket_t sockfd = conn->sock[sockindex];
- struct Curl_easy *data = conn->data;
struct connstate *sx = &conn->cnnct;
struct Curl_dns_entry *dns = NULL;
ssize_t actualread;
ssize_t written;
+ /* make sure that the buffer is at least 600 bytes */
+ DEBUGASSERT(READBUFFER_MIN >= 600);
+
if(!SOCKS_STATE(sx->state) && !*done)
- sxstate(conn, CONNECT_SOCKS_INIT);
+ sxstate(data, CONNECT_SOCKS_INIT);
switch(sx->state) {
case CONNECT_SOCKS_INIT:
/* SOCKS4 can only do IPv4, insist! */
conn->ip_version = CURL_IPRESOLVE_V4;
if(conn->bits.httpproxy)
- infof(conn->data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
+ infof(data, "SOCKS4%s: connecting to HTTP proxy %s port %d\n",
protocol4a ? "a" : "", hostname, remote_port);
infof(data, "SOCKS4 communication to %s:%d\n", hostname, remote_port);
@@ -234,37 +238,37 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
/* DNS resolve only for SOCKS4, not SOCKS4a */
if(!protocol4a) {
enum resolve_t rc =
- Curl_resolv(conn, hostname, remote_port, FALSE, &dns);
+ Curl_resolv(data, hostname, remote_port, FALSE, &dns);
if(rc == CURLRESOLV_ERROR)
return CURLPX_RESOLVE_HOST;
else if(rc == CURLRESOLV_PENDING) {
- sxstate(conn, CONNECT_RESOLVING);
+ sxstate(data, CONNECT_RESOLVING);
infof(data, "SOCKS4 non-blocking resolve of %s\n", hostname);
return CURLPX_OK;
}
- sxstate(conn, CONNECT_RESOLVED);
+ sxstate(data, CONNECT_RESOLVED);
goto CONNECT_RESOLVED;
}
/* socks4a doesn't resolve anything locally */
- sxstate(conn, CONNECT_REQ_INIT);
+ sxstate(data, CONNECT_REQ_INIT);
goto CONNECT_REQ_INIT;
case CONNECT_RESOLVING:
/* check if we have the name resolved by now */
- dns = Curl_fetch_addr(conn, hostname, (int)conn->port);
+ dns = Curl_fetch_addr(data, hostname, (int)conn->port);
if(dns) {
#ifdef CURLRES_ASYNCH
- conn->async.dns = dns;
- conn->async.done = TRUE;
+ data->state.async.dns = dns;
+ data->state.async.done = TRUE;
#endif
infof(data, "Hostname '%s' was found\n", hostname);
- sxstate(conn, CONNECT_RESOLVED);
+ sxstate(data, CONNECT_RESOLVED);
}
else {
- result = Curl_resolv_check(data->conn, &dns);
+ result = Curl_resolv_check(data, &dns);
if(!dns) {
if(result)
return CURLPX_RESOLVE_HOST;
@@ -298,7 +302,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
}
else {
hp = NULL; /* fail! */
- failf(data, "SOCKS4 connection to %s not supported\n", buf);
+ failf(data, "SOCKS4 connection to %s not supported", buf);
}
Curl_resolv_unlock(data, dns); /* not used anymore from now on */
@@ -318,8 +322,8 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
if(proxy_user) {
size_t plen = strlen(proxy_user);
- if(plen >= sizeof(sx->socksreq) - 8) {
- failf(data, "Too long SOCKS proxy user name, can't use!\n");
+ if(plen >= (size_t)data->set.buffer_size - 8) {
+ failf(data, "Too long SOCKS proxy user name, can't use!");
return CURLPX_LONG_USER;
}
/* copy the proxy name WITH trailing zero */
@@ -352,12 +356,12 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
}
sx->outp = socksreq;
sx->outstanding = packetsize;
- sxstate(conn, CONNECT_REQ_SENDING);
+ sxstate(data, CONNECT_REQ_SENDING);
}
/* FALLTHROUGH */
case CONNECT_REQ_SENDING:
/* Send request */
- result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ result = Curl_write_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to send SOCKS4 connect request.");
@@ -373,7 +377,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
/* done sending! */
sx->outstanding = 8; /* receive data size */
sx->outp = socksreq;
- sxstate(conn, CONNECT_SOCKS_READ);
+ sxstate(data, CONNECT_SOCKS_READ);
/* FALLTHROUGH */
case CONNECT_SOCKS_READ:
@@ -396,7 +400,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
sx->outp += actualread;
return CURLPX_OK;
}
- sxstate(conn, CONNECT_DONE);
+ sxstate(data, CONNECT_DONE);
break;
default: /* lots of unused states in SOCKS4 */
break;
@@ -437,8 +441,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
failf(data,
"Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
", request rejected or failed.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+ socksreq[4], socksreq[5], socksreq[6], socksreq[7],
(((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
(unsigned char)socksreq[1]);
return CURLPX_REQUEST_FAILED;
@@ -447,8 +450,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
"Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
", request rejected because SOCKS server cannot connect to "
"identd on the client.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+ socksreq[4], socksreq[5], socksreq[6], socksreq[7],
(((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
(unsigned char)socksreq[1]);
return CURLPX_IDENTD;
@@ -457,8 +459,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
"Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
", request rejected because the client program and identd "
"report different user-ids.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+ socksreq[4], socksreq[5], socksreq[6], socksreq[7],
(((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
(unsigned char)socksreq[1]);
return CURLPX_IDENTD_DIFFER;
@@ -466,8 +467,7 @@ CURLproxycode Curl_SOCKS4(const char *proxy_user,
failf(data,
"Can't complete SOCKS4 connection to %d.%d.%d.%d:%d. (%d)"
", Unknown.",
- (unsigned char)socksreq[4], (unsigned char)socksreq[5],
- (unsigned char)socksreq[6], (unsigned char)socksreq[7],
+ socksreq[4], socksreq[5], socksreq[6], socksreq[7],
(((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]),
(unsigned char)socksreq[1]);
return CURLPX_UNKNOWN_FAIL;
@@ -486,7 +486,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
const char *hostname,
int remote_port,
int sockindex,
- struct connectdata *conn,
+ struct Curl_easy *data,
bool *done)
{
/*
@@ -505,14 +505,14 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
o REP Reply field:
o X'00' succeeded
*/
- unsigned char *socksreq = &conn->cnnct.socksreq[0];
+ struct connectdata *conn = data->conn;
+ unsigned char *socksreq = (unsigned char *)data->state.buffer;
char dest[256] = "unknown"; /* printable hostname:port */
int idx;
ssize_t actualread;
ssize_t written;
CURLcode result;
curl_socket_t sockfd = conn->sock[sockindex];
- struct Curl_easy *data = conn->data;
bool socks5_resolve_local =
(conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE;
const size_t hostname_len = strlen(hostname);
@@ -523,23 +523,23 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
struct Curl_dns_entry *dns = NULL;
if(!SOCKS_STATE(sx->state) && !*done)
- sxstate(conn, CONNECT_SOCKS_INIT);
+ sxstate(data, CONNECT_SOCKS_INIT);
switch(sx->state) {
case CONNECT_SOCKS_INIT:
if(conn->bits.httpproxy)
- infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
+ infof(data, "SOCKS5: connecting to HTTP proxy %s port %d\n",
hostname, remote_port);
/* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
if(!socks5_resolve_local && hostname_len > 255) {
- infof(conn->data, "SOCKS5: server resolving disabled for hostnames of "
+ infof(data, "SOCKS5: server resolving disabled for hostnames of "
"length > 255 [actual len=%zu]\n", hostname_len);
socks5_resolve_local = TRUE;
}
if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
- infof(conn->data,
+ infof(data,
"warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n",
auth);
if(!(auth & CURLAUTH_BASIC))
@@ -561,21 +561,21 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
/* write the number of authentication methods */
socksreq[1] = (unsigned char) (idx - 2);
- result = Curl_write_plain(conn, sockfd, (char *)socksreq, idx, &written);
+ result = Curl_write_plain(data, sockfd, (char *)socksreq, idx, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to send initial SOCKS5 request.");
return CURLPX_SEND_CONNECT;
}
if(written != idx) {
- sxstate(conn, CONNECT_SOCKS_SEND);
+ sxstate(data, CONNECT_SOCKS_SEND);
sx->outstanding = idx - written;
sx->outp = &socksreq[written];
return CURLPX_OK;
}
- sxstate(conn, CONNECT_SOCKS_READ);
+ sxstate(data, CONNECT_SOCKS_READ);
goto CONNECT_SOCKS_READ_INIT;
case CONNECT_SOCKS_SEND:
- result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ result = Curl_write_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Unable to send initial SOCKS5 request.");
@@ -617,18 +617,18 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
}
else if(socksreq[1] == 0) {
/* DONE! No authentication needed. Send request. */
- sxstate(conn, CONNECT_REQ_INIT);
+ sxstate(data, CONNECT_REQ_INIT);
goto CONNECT_REQ_INIT;
}
else if(socksreq[1] == 2) {
/* regular name + password authentication */
- sxstate(conn, CONNECT_AUTH_INIT);
+ sxstate(data, CONNECT_AUTH_INIT);
goto CONNECT_AUTH_INIT;
}
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
else if(allow_gssapi && (socksreq[1] == 1)) {
- sxstate(conn, CONNECT_GSSAPI_INIT);
- result = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
+ sxstate(data, CONNECT_GSSAPI_INIT);
+ result = Curl_SOCKS5_gssapi_negotiate(sockindex, data);
if(result) {
failf(data, "Unable to negotiate SOCKS5 GSS-API context.");
return CURLPX_GSSAPI;
@@ -701,13 +701,13 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
memcpy(socksreq + len, proxy_password, proxy_password_len);
}
len += proxy_password_len;
- sxstate(conn, CONNECT_AUTH_SEND);
+ sxstate(data, CONNECT_AUTH_SEND);
sx->outstanding = len;
sx->outp = socksreq;
}
/* FALLTHROUGH */
case CONNECT_AUTH_SEND:
- result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ result = Curl_write_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to send SOCKS5 sub-negotiation request.");
@@ -721,7 +721,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
}
sx->outp = socksreq;
sx->outstanding = 2;
- sxstate(conn, CONNECT_AUTH_READ);
+ sxstate(data, CONNECT_AUTH_READ);
/* FALLTHROUGH */
case CONNECT_AUTH_READ:
result = Curl_read_plain(sockfd, (char *)sx->outp,
@@ -749,40 +749,40 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
}
/* Everything is good so far, user was authenticated! */
- sxstate(conn, CONNECT_REQ_INIT);
+ sxstate(data, CONNECT_REQ_INIT);
/* FALLTHROUGH */
CONNECT_REQ_INIT:
case CONNECT_REQ_INIT:
if(socks5_resolve_local) {
- enum resolve_t rc = Curl_resolv(conn, hostname, remote_port,
+ enum resolve_t rc = Curl_resolv(data, hostname, remote_port,
FALSE, &dns);
if(rc == CURLRESOLV_ERROR)
return CURLPX_RESOLVE_HOST;
if(rc == CURLRESOLV_PENDING) {
- sxstate(conn, CONNECT_RESOLVING);
+ sxstate(data, CONNECT_RESOLVING);
return CURLPX_OK;
}
- sxstate(conn, CONNECT_RESOLVED);
+ sxstate(data, CONNECT_RESOLVED);
goto CONNECT_RESOLVED;
}
goto CONNECT_RESOLVE_REMOTE;
case CONNECT_RESOLVING:
/* check if we have the name resolved by now */
- dns = Curl_fetch_addr(conn, hostname, remote_port);
+ dns = Curl_fetch_addr(data, hostname, remote_port);
if(dns) {
#ifdef CURLRES_ASYNCH
- conn->async.dns = dns;
- conn->async.done = TRUE;
+ data->state.async.dns = dns;
+ data->state.async.done = TRUE;
#endif
infof(data, "SOCKS5: hostname '%s' found\n", hostname);
}
if(!dns) {
- result = Curl_resolv_check(data->conn, &dns);
+ result = Curl_resolv_check(data, &dns);
if(!dns) {
if(result)
return CURLPX_RESOLVE_HOST;
@@ -839,7 +839,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
#endif
else {
hp = NULL; /* fail! */
- failf(data, "SOCKS5 connection to %s not supported\n", dest);
+ failf(data, "SOCKS5 connection to %s not supported", dest);
}
Curl_resolv_unlock(data, dns); /* not used anymore from now on */
@@ -878,10 +878,10 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
#endif
sx->outp = socksreq;
sx->outstanding = len;
- sxstate(conn, CONNECT_REQ_SENDING);
+ sxstate(data, CONNECT_REQ_SENDING);
/* FALLTHROUGH */
case CONNECT_REQ_SENDING:
- result = Curl_write_plain(conn, sockfd, (char *)sx->outp,
+ result = Curl_write_plain(data, sockfd, (char *)sx->outp,
sx->outstanding, &written);
if(result && (CURLE_AGAIN != result)) {
failf(data, "Failed to send SOCKS5 connect request.");
@@ -901,7 +901,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
#endif
sx->outstanding = 10; /* minimum packet size is 10 */
sx->outp = socksreq;
- sxstate(conn, CONNECT_REQ_READ);
+ sxstate(data, CONNECT_REQ_READ);
/* FALLTHROUGH */
case CONNECT_REQ_READ:
result = Curl_read_plain(sockfd, (char *)sx->outp,
@@ -992,10 +992,10 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
if(len > 10) {
sx->outstanding = len - 10; /* get the rest */
sx->outp = &socksreq[10];
- sxstate(conn, CONNECT_REQ_READ_MORE);
+ sxstate(data, CONNECT_REQ_READ_MORE);
}
else {
- sxstate(conn, CONNECT_DONE);
+ sxstate(data, CONNECT_DONE);
break;
}
#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
@@ -1020,7 +1020,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
sx->outp += actualread;
return CURLPX_OK;
}
- sxstate(conn, CONNECT_DONE);
+ sxstate(data, CONNECT_DONE);
}
infof(data, "SOCKS5 request granted.\n");