diff options
author | Curl Upstream <curl-library@cool.haxx.se> | 2021-02-03 07:02:36 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2021-02-03 16:49:32 (GMT) |
commit | 076b3219f58ca16afa52fe095019a05537ade0f3 (patch) | |
tree | f9ea493f94ce5afb8792e1ab4a040cea7eba4aed /lib/socks.c | |
parent | 5aacc593a961fe9ee1427c03d18fba8947a9e33d (diff) | |
download | CMake-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.c | 134 |
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"); |