mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 23:58:49 -05:00
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
This commit is contained in:
parent
cd1c9f0807
commit
8924f58c37
@ -173,6 +173,8 @@ Filter out hosts from proxy use. \fICURLOPT_NOPROXY(3)\fP
|
||||
Tunnel through the HTTP proxy. \fICURLOPT_HTTPPROXYTUNNEL(3)\fP
|
||||
.IP CURLOPT_CONNECT_TO
|
||||
Connect to a specific host and port. See \fICURLOPT_CONNECT_TO(3)\fP
|
||||
.IP CURLOPT_SOCKS5_AUTH
|
||||
Socks5 authentication methods. See \fICURLOPT_SOCKS5_AUTH(3)\fP
|
||||
.IP CURLOPT_SOCKS5_GSSAPI_SERVICE
|
||||
Socks5 GSSAPI service name. \fICURLOPT_SOCKS5_GSSAPI_SERVICE(3)\fP
|
||||
.IP CURLOPT_SOCKS5_GSSAPI_NEC
|
||||
|
63
docs/libcurl/opts/CURLOPT_SOCKS5_AUTH.3
Normal file
63
docs/libcurl/opts/CURLOPT_SOCKS5_AUTH.3
Normal file
@ -0,0 +1,63 @@
|
||||
.\" **************************************************************************
|
||||
.\" * _ _ ____ _
|
||||
.\" * Project ___| | | | _ \| |
|
||||
.\" * / __| | | | |_) | |
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
.\" * 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
|
||||
.\" * are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
.\" *
|
||||
.\" * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
.\" * copies of the Software, and permit persons to whom the Software is
|
||||
.\" * furnished to do so, under the terms of the COPYING file.
|
||||
.\" *
|
||||
.\" * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
.\" * KIND, either express or implied.
|
||||
.\" *
|
||||
.\" **************************************************************************
|
||||
.\"
|
||||
.TH CURLOPT_SOCKS5_AUTH 3 "27 April 2017" "libcurl 7.55.0" "curl_easy_setopt options"
|
||||
.SH NAME
|
||||
CURLOPT_SOCKS5_AUTH \- set allowed methods for SOCKS5 proxy authentication
|
||||
.SH SYNOPSIS
|
||||
#include <curl/curl.h>
|
||||
|
||||
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SOCKS5_AUTH, long bitmask);
|
||||
.SH DESCRIPTION
|
||||
Pass a long as parameter, which is set to a bitmask, to tell libcurl which
|
||||
authentication method(s) are allowed for SOCKS5 proxy authentication. The only
|
||||
supported flags are \fICURLAUTH_BASIC\fP, which allows username/password
|
||||
authentication, \fICURLAUTH_GSSAPI\fP, which allows GSS-API authentication, and
|
||||
\fICURLAUTH_NONE\fP, which allows no authentication. Set the actual user name
|
||||
and password with the \fICURLOPT_PROXYUSERPWD(3)\fP option.
|
||||
.SH DEFAULT
|
||||
CURLAUTH_BASIC|CURLAUTH_GSSAPI
|
||||
.SH PROTOCOLS
|
||||
All
|
||||
.SH EXAMPLE
|
||||
.nf
|
||||
CURL *curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||
|
||||
/* request to use a SOCKS5 proxy */
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, "socks5://user:pass@myproxy.com");
|
||||
|
||||
/* enable username/password authentication only */
|
||||
curl_easy_setopt(curl, CURLOPT_SOCKS5_AUTH, CURLAUTH_BASIC);
|
||||
|
||||
/* Perform the request */
|
||||
curl_easy_perform(curl);
|
||||
}
|
||||
.fi
|
||||
.SH AVAILABILITY
|
||||
Added in 7.55.0
|
||||
.SH RETURN VALUE
|
||||
Returns CURLE_OK if the option is supported, CURLE_UNKNOWN_OPTION if not, or
|
||||
CURLE_NOT_BUILT_IN if the bitmask contains unsupported flags.
|
||||
.SH "SEE ALSO"
|
||||
.BR CURLOPT_PROXY "(3), " CURLOPT_PROXYTYPE "(3)"
|
@ -17,6 +17,7 @@ CURLAUTH_ANYSAFE 7.10.6
|
||||
CURLAUTH_BASIC 7.10.6
|
||||
CURLAUTH_DIGEST 7.10.6
|
||||
CURLAUTH_DIGEST_IE 7.19.3
|
||||
CURLAUTH_GSSAPI 7.55.0
|
||||
CURLAUTH_GSSNEGOTIATE 7.10.6 7.38.0
|
||||
CURLAUTH_NEGOTIATE 7.38.0
|
||||
CURLAUTH_NONE 7.10.6
|
||||
@ -527,6 +528,7 @@ CURLOPT_SERVICE_NAME 7.43.0
|
||||
CURLOPT_SHARE 7.10
|
||||
CURLOPT_SOCKOPTDATA 7.16.0
|
||||
CURLOPT_SOCKOPTFUNCTION 7.16.0
|
||||
CURLOPT_SOCKS5_AUTH 7.55.0
|
||||
CURLOPT_SOCKS5_GSSAPI_NEC 7.19.4
|
||||
CURLOPT_SOCKS5_GSSAPI_SERVICE 7.19.4 7.49.0
|
||||
CURLOPT_SOURCE_HOST 7.12.1 - 7.15.5
|
||||
|
@ -677,6 +677,8 @@ typedef enum {
|
||||
#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2)
|
||||
/* Deprecated since the advent of CURLAUTH_NEGOTIATE */
|
||||
#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE
|
||||
/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */
|
||||
#define CURLAUTH_GSSAPI CURLAUTH_NEGOTIATE
|
||||
#define CURLAUTH_NTLM (((unsigned long)1)<<3)
|
||||
#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
|
||||
#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
|
||||
@ -1783,6 +1785,9 @@ typedef enum {
|
||||
/* The request target, instead of extracted from the URL */
|
||||
CINIT(REQUEST_TARGET, STRINGPOINT, 266),
|
||||
|
||||
/* bitmask of allowed auth methods for connections to SOCKS5 proxies */
|
||||
CINIT(SOCKS5_AUTH, LONG, 267),
|
||||
|
||||
CURLOPT_LASTENTRY /* the last unused */
|
||||
} CURLoption;
|
||||
|
||||
|
27
lib/socks.c
27
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"
|
||||
|
@ -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:
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user