From 8924f58c370afa756fc4fd13916dfdea91d21b21 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Thu, 27 Apr 2017 15:18:49 +0200 Subject: CURLOPT_SOCKS5_AUTH: allowed methods for SOCKS5 proxy auth If libcurl was built with GSS-API support, it unconditionally advertised GSS-API authentication while connecting to a SOCKS5 proxy. This caused problems in environments with improperly configured Kerberos: a stock libcurl failed to connect, despite libcurl built without GSS-API connected fine using username and password. This commit introduces the CURLOPT_SOCKS5_AUTH option to control the allowed methods for SOCKS5 authentication at run time. Note that a new option was preferred over reusing CURLOPT_PROXYAUTH for compatibility reasons because the set of authentication methods allowed by default was different for HTTP and SOCKS5 proxies. Bug: https://curl.haxx.se/mail/lib-2017-01/0005.html Closes https://github.com/curl/curl/pull/1454 --- lib/socks.c | 27 ++++++++++++++++++--------- lib/url.c | 8 ++++++++ lib/urldata.h | 1 + 3 files changed, 27 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/socks.c b/lib/socks.c index 968b720b7..000cd9c2d 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -387,6 +387,8 @@ CURLcode Curl_SOCKS5(const char *proxy_user, (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", @@ -427,13 +429,24 @@ CURLcode Curl_SOCKS5(const char *proxy_user, return CURLE_COULDNT_CONNECT; } + 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) + 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 defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) - socksreq[idx++] = 1; /* GSS-API */ -#endif + if(allow_gssapi) + socksreq[idx++] = 1; /* GSS-API */ if(proxy_user) socksreq[idx++] = 2; /* username/password */ /* write the number of authentication methods */ @@ -485,7 +498,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user, ; } #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."); @@ -546,16 +559,12 @@ CURLcode Curl_SOCKS5(const char *proxy_user, } 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_user || !*proxy_user) { failf(data, "No authentication method was acceptable. (It is quite likely" diff --git a/lib/url.c b/lib/url.c index 3b3143ab8..07bdea129 100644 --- a/lib/url.c +++ b/lib/url.c @@ -545,6 +545,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) set->httpauth = CURLAUTH_BASIC; /* defaults to basic */ set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */ + /* SOCKS5 proxy auth defaults to username/password + GSS-API */ + set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI; + /* make libcurl quiet by default: */ set->hide_progress = TRUE; /* CURLOPT_NOPROGRESS changes these */ @@ -1541,6 +1544,11 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option, break; #endif /* CURL_DISABLE_PROXY */ + case CURLOPT_SOCKS5_AUTH: + data->set.socks5auth = va_arg(param, unsigned long); + if(data->set.socks5auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI)) + result = CURLE_NOT_BUILT_IN; + break; #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI) case CURLOPT_SOCKS5_GSSAPI_NEC: /* diff --git a/lib/urldata.h b/lib/urldata.h index 8c4a029fe..e89d1d706 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1615,6 +1615,7 @@ struct UserDefined { long use_port; /* which port to use (when not using default) */ unsigned long httpauth; /* kind of HTTP authentication to use (bitmask) */ unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */ + unsigned long socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */ long followlocation; /* as in HTTP Location: */ long maxredirs; /* maximum no. of http(s) redirects to follow, set to -1 for infinity */ -- cgit v1.2.3