diff options
Diffstat (limited to 'Utilities/cmcurl/lib/socks.c')
-rw-r--r-- | Utilities/cmcurl/lib/socks.c | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/Utilities/cmcurl/lib/socks.c b/Utilities/cmcurl/lib/socks.c index 97a44b2..e64cb98 100644 --- a/Utilities/cmcurl/lib/socks.c +++ b/Utilities/cmcurl/lib/socks.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2017, 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 @@ -105,7 +105,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */ * Set protocol4a=true for "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)" * Nonsupport "Identification Protocol (RFC1413)" */ -CURLcode Curl_SOCKS4(const char *proxy_name, +CURLcode Curl_SOCKS4(const char *proxy_user, const char *hostname, int remote_port, int sockindex, @@ -154,7 +154,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name, /* DNS resolve only for SOCKS4, not SOCKS4a */ if(!protocol4a) { struct Curl_dns_entry *dns; - Curl_addrinfo *hp=NULL; + Curl_addrinfo *hp = NULL; int rc; rc = Curl_resolv(conn, hostname, remote_port, &dns); @@ -171,7 +171,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name, * returns a Curl_addrinfo pointer that may not always look the same. */ if(dns) - hp=dns->addr; + hp = dns->addr; if(hp) { char buf[64]; Curl_printable_address(hp, buf, sizeof(buf)); @@ -206,14 +206,14 @@ CURLcode Curl_SOCKS4(const char *proxy_name, * This is currently not supporting "Identification Protocol (RFC1413)". */ socksreq[8] = 0; /* ensure empty userid is NUL-terminated */ - if(proxy_name) { - size_t plen = strlen(proxy_name); + if(proxy_user) { + size_t plen = strlen(proxy_user); if(plen >= sizeof(socksreq) - 8) { failf(data, "Too long SOCKS proxy name, can't use!\n"); return CURLE_COULDNT_CONNECT; } /* copy the proxy name WITH trailing zero */ - memcpy(socksreq + 8, proxy_name, plen+1); + memcpy(socksreq + 8, proxy_user, plen + 1); } /* @@ -306,7 +306,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name, ", request rejected or failed.", (unsigned char)socksreq[4], (unsigned char)socksreq[5], (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]), + (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), (unsigned char)socksreq[1]); return CURLE_COULDNT_CONNECT; case 92: @@ -316,7 +316,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name, "identd on the client.", (unsigned char)socksreq[4], (unsigned char)socksreq[5], (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]), + (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), (unsigned char)socksreq[1]); return CURLE_COULDNT_CONNECT; case 93: @@ -326,7 +326,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name, "report different user-ids.", (unsigned char)socksreq[4], (unsigned char)socksreq[5], (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]), + (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), (unsigned char)socksreq[1]); return CURLE_COULDNT_CONNECT; default: @@ -335,7 +335,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name, ", Unknown.", (unsigned char)socksreq[4], (unsigned char)socksreq[5], (unsigned char)socksreq[6], (unsigned char)socksreq[7], - (((unsigned char)socksreq[8] << 8) | (unsigned char)socksreq[9]), + (((unsigned char)socksreq[2] << 8) | (unsigned char)socksreq[3]), (unsigned char)socksreq[1]); return CURLE_COULDNT_CONNECT; } @@ -350,7 +350,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name, * This function logs in to a SOCKS5 proxy and sends the specifics to the final * destination server. */ -CURLcode Curl_SOCKS5(const char *proxy_name, +CURLcode Curl_SOCKS5(const char *proxy_user, const char *proxy_password, const char *hostname, int remote_port, @@ -375,6 +375,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name, */ unsigned char socksreq[600]; /* room for large user/pw (255 max each) */ + int idx; ssize_t actualread; ssize_t written; int result; @@ -386,6 +387,8 @@ CURLcode Curl_SOCKS5(const char *proxy_name, (conn->socks_proxy.proxytype == CURLPROXY_SOCKS5) ? TRUE : FALSE; const size_t hostname_len = strlen(hostname); ssize_t len = 0; + const unsigned long auth = data->set.socks5auth; + bool allow_gssapi = FALSE; if(conn->bits.httpproxy) infof(conn->data, "SOCKS5: connecting to HTTP proxy %s port %d\n", @@ -426,18 +429,29 @@ CURLcode Curl_SOCKS5(const char *proxy_name, return CURLE_COULDNT_CONNECT; } - socksreq[0] = 5; /* version */ + if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) + infof(conn->data, + "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n", + auth); + if(!(auth & CURLAUTH_BASIC)) + /* disable username/password auth */ + proxy_user = NULL; #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - socksreq[1] = (char)(proxy_name ? 3 : 2); /* number of methods (below) */ - socksreq[2] = 0; /* no authentication */ - socksreq[3] = 1; /* GSS-API */ - socksreq[4] = 2; /* username/password */ -#else - socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */ - socksreq[2] = 0; /* no authentication */ - socksreq[3] = 2; /* username/password */ + if(auth & CURLAUTH_GSSAPI) + allow_gssapi = TRUE; #endif + idx = 0; + socksreq[idx++] = 5; /* version */ + idx++; /* reserve for the number of authentication methods */ + socksreq[idx++] = 0; /* no authentication */ + if(allow_gssapi) + socksreq[idx++] = 1; /* GSS-API */ + if(proxy_user) + socksreq[idx++] = 2; /* username/password */ + /* write the number of authentication methods */ + socksreq[1] = (unsigned char) (idx - 2); + (void)curlx_nonblock(sock, FALSE); infof(data, "SOCKS5 communication to %s:%d\n", hostname, remote_port); @@ -469,7 +483,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name, (void)curlx_nonblock(sock, FALSE); - result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread); + result = Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread); if(result || (actualread != 2)) { failf(data, "Unable to receive initial SOCKS5 response."); return CURLE_COULDNT_CONNECT; @@ -484,7 +498,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name, ; } #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - else if(socksreq[1] == 1) { + else if(allow_gssapi && (socksreq[1] == 1)) { code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn); if(code) { failf(data, "Unable to negotiate SOCKS5 GSS-API context."); @@ -494,13 +508,13 @@ CURLcode Curl_SOCKS5(const char *proxy_name, #endif else if(socksreq[1] == 2) { /* Needs user name and password */ - size_t proxy_name_len, proxy_password_len; - if(proxy_name && proxy_password) { - proxy_name_len = strlen(proxy_name); + size_t proxy_user_len, proxy_password_len; + if(proxy_user && proxy_password) { + proxy_user_len = strlen(proxy_user); proxy_password_len = strlen(proxy_password); } else { - proxy_name_len = 0; + proxy_user_len = 0; proxy_password_len = 0; } @@ -513,10 +527,10 @@ CURLcode Curl_SOCKS5(const char *proxy_name, */ len = 0; socksreq[len++] = 1; /* username/pw subnegotiation version */ - socksreq[len++] = (unsigned char) proxy_name_len; - if(proxy_name && proxy_name_len) - memcpy(socksreq + len, proxy_name, proxy_name_len); - len += proxy_name_len; + socksreq[len++] = (unsigned char) proxy_user_len; + if(proxy_user && proxy_user_len) + memcpy(socksreq + len, proxy_user, proxy_user_len); + len += proxy_user_len; socksreq[len++] = (unsigned char) proxy_password_len; if(proxy_password && proxy_password_len) memcpy(socksreq + len, proxy_password, proxy_password_len); @@ -528,7 +542,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name, return CURLE_COULDNT_CONNECT; } - result=Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread); + result = Curl_blockread_all(conn, sock, (char *)socksreq, 2, &actualread); if(result || (actualread != 2)) { failf(data, "Unable to receive SOCKS5 sub-negotiation response."); return CURLE_COULDNT_CONNECT; @@ -545,17 +559,13 @@ CURLcode Curl_SOCKS5(const char *proxy_name, } else { /* error */ -#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - if(socksreq[1] == 255) { -#else - if(socksreq[1] == 1) { + if(!allow_gssapi && (socksreq[1] == 1)) { failf(data, "SOCKS5 GSSAPI per-message authentication is not supported."); return CURLE_COULDNT_CONNECT; } if(socksreq[1] == 255) { -#endif - if(!proxy_name || !*proxy_name) { + if(!proxy_user || !*proxy_user) { failf(data, "No authentication method was acceptable. (It is quite likely" " that the SOCKS5 server wanted a username/password, since none" @@ -605,7 +615,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name, * returns a Curl_addrinfo pointer that may not always look the same. */ if(dns) - hp=dns->addr; + hp = dns->addr; if(hp) { int i; char buf[64]; |