4604e0
From 5285b2518773185c049b0c2af980654a0b1c6871 Mon Sep 17 00:00:00 2001
4604e0
From: Kamil Dudka <kdudka@redhat.com>
4604e0
Date: Wed, 8 Mar 2017 12:21:09 +0100
4604e0
Subject: [PATCH 1/4] socks: use proxy_user instead of proxy_name
4604e0
4604e0
... to make it obvious what the data is used for
4604e0
4604e0
Upstream-commit: 641072b919b1a52c58664cd18619f8dd1c4c0cee
4604e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
4604e0
---
4604e0
 lib/socks.c | 30 +++++++++++++++---------------
4604e0
 1 file changed, 15 insertions(+), 15 deletions(-)
4604e0
4604e0
diff --git a/lib/socks.c b/lib/socks.c
4604e0
index 0cf397c..9aac9ca 100644
4604e0
--- a/lib/socks.c
4604e0
+++ b/lib/socks.c
4604e0
@@ -106,7 +106,7 @@ int Curl_blockread_all(struct connectdata *conn, /* connection data */
4604e0
 *   Set protocol4a=true for  "SOCKS 4A (Simple Extension to SOCKS 4 Protocol)"
4604e0
 *   Nonsupport "Identification Protocol (RFC1413)"
4604e0
 */
4604e0
-CURLcode Curl_SOCKS4(const char *proxy_name,
4604e0
+CURLcode Curl_SOCKS4(const char *proxy_user,
4604e0
                      const char *hostname,
4604e0
                      int remote_port,
4604e0
                      int sockindex,
4604e0
@@ -200,8 +200,8 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
4604e0
    * This is currently not supporting "Identification Protocol (RFC1413)".
4604e0
    */
4604e0
   socksreq[8] = 0; /* ensure empty userid is NUL-terminated */
4604e0
-  if(proxy_name)
4604e0
-    strlcat((char*)socksreq + 8, proxy_name, sizeof(socksreq) - 8);
4604e0
+  if(proxy_user)
4604e0
+    strlcat((char*)socksreq + 8, proxy_user, sizeof(socksreq) - 8);
4604e0
 
4604e0
   /*
4604e0
    * Make connection
4604e0
@@ -337,7 +337,7 @@ CURLcode Curl_SOCKS4(const char *proxy_name,
4604e0
  * This function logs in to a SOCKS5 proxy and sends the specifics to the final
4604e0
  * destination server.
4604e0
  */
4604e0
-CURLcode Curl_SOCKS5(const char *proxy_name,
4604e0
+CURLcode Curl_SOCKS5(const char *proxy_user,
4604e0
                      const char *proxy_password,
4604e0
                      const char *hostname,
4604e0
                      int remote_port,
4604e0
@@ -410,12 +410,12 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
4604e0
 
4604e0
   socksreq[0] = 5; /* version */
4604e0
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
4604e0
-  socksreq[1] = (char)(proxy_name ? 3 : 2); /* number of methods (below) */
4604e0
+  socksreq[1] = (char)(proxy_user ? 3 : 2); /* number of methods (below) */
4604e0
   socksreq[2] = 0; /* no authentication */
4604e0
   socksreq[3] = 1; /* gssapi */
4604e0
   socksreq[4] = 2; /* username/password */
4604e0
 #else
4604e0
-  socksreq[1] = (char)(proxy_name ? 2 : 1); /* number of methods (below) */
4604e0
+  socksreq[1] = (char)(proxy_user ? 2 : 1); /* number of methods (below) */
4604e0
   socksreq[2] = 0; /* no authentication */
4604e0
   socksreq[3] = 2; /* username/password */
4604e0
 #endif
4604e0
@@ -474,13 +474,13 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
4604e0
 #endif
4604e0
   else if(socksreq[1] == 2) {
4604e0
     /* Needs user name and password */
4604e0
-    size_t proxy_name_len, proxy_password_len;
4604e0
-    if(proxy_name && proxy_password) {
4604e0
-      proxy_name_len = strlen(proxy_name);
4604e0
+    size_t proxy_user_len, proxy_password_len;
4604e0
+    if(proxy_user && proxy_password) {
4604e0
+      proxy_user_len = strlen(proxy_user);
4604e0
       proxy_password_len = strlen(proxy_password);
4604e0
     }
4604e0
     else {
4604e0
-      proxy_name_len = 0;
4604e0
+      proxy_user_len = 0;
4604e0
       proxy_password_len = 0;
4604e0
     }
4604e0
 
4604e0
@@ -493,10 +493,10 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
4604e0
      */
4604e0
     len = 0;
4604e0
     socksreq[len++] = 1;    /* username/pw subnegotiation version */
4604e0
-    socksreq[len++] = (unsigned char) proxy_name_len;
4604e0
-    if(proxy_name && proxy_name_len)
4604e0
-      memcpy(socksreq + len, proxy_name, proxy_name_len);
4604e0
-    len += proxy_name_len;
4604e0
+    socksreq[len++] = (unsigned char) proxy_user_len;
4604e0
+    if(proxy_user && proxy_user_len)
4604e0
+      memcpy(socksreq + len, proxy_user, proxy_user_len);
4604e0
+    len += proxy_user_len;
4604e0
     socksreq[len++] = (unsigned char) proxy_password_len;
4604e0
     if(proxy_password && proxy_password_len)
4604e0
       memcpy(socksreq + len, proxy_password, proxy_password_len);
4604e0
@@ -535,7 +535,7 @@ CURLcode Curl_SOCKS5(const char *proxy_name,
4604e0
     }
4604e0
     else if(socksreq[1] == 255) {
4604e0
 #endif
4604e0
-      if(!proxy_name || !*proxy_name) {
4604e0
+      if(!proxy_user || !*proxy_user) {
4604e0
         failf(data,
4604e0
               "No authentication method was acceptable. (It is quite likely"
4604e0
               " that the SOCKS5 server wanted a username/password, since none"
4604e0
-- 
4604e0
2.13.5
4604e0
4604e0
4604e0
From 3676c3fab628e848270e2169398f912a1449c31b Mon Sep 17 00:00:00 2001
4604e0
From: Kamil Dudka <kdudka@redhat.com>
4604e0
Date: Wed, 8 Mar 2017 12:16:01 +0100
4604e0
Subject: [PATCH 2/4] socks: deduplicate the code for auth request
4604e0
4604e0
Upstream-commit: cd1c9f08078d4a8566ed10f6df9ae9a729f3290b
4604e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
4604e0
---
4604e0
 lib/socks.c | 19 ++++++++++---------
4604e0
 1 file changed, 10 insertions(+), 9 deletions(-)
4604e0
4604e0
diff --git a/lib/socks.c b/lib/socks.c
4604e0
index 9aac9ca..398e0ac 100644
4604e0
--- a/lib/socks.c
4604e0
+++ b/lib/socks.c
4604e0
@@ -362,6 +362,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
4604e0
   */
4604e0
 
4604e0
   unsigned char socksreq[600]; /* room for large user/pw (255 max each) */
4604e0
+  int idx;
4604e0
   ssize_t actualread;
4604e0
   ssize_t written;
4604e0
   int result;
4604e0
@@ -408,17 +409,17 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
4604e0
     return CURLE_COULDNT_CONNECT;
4604e0
   }
4604e0
 
4604e0
-  socksreq[0] = 5; /* version */
4604e0
+  idx = 0;
4604e0
+  socksreq[idx++] = 5;   /* version */
4604e0
+  idx++;                 /* reserve for the number of authentication methods */
4604e0
+  socksreq[idx++] = 0;   /* no authentication */
4604e0
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
4604e0
-  socksreq[1] = (char)(proxy_user ? 3 : 2); /* number of methods (below) */
4604e0
-  socksreq[2] = 0; /* no authentication */
4604e0
-  socksreq[3] = 1; /* gssapi */
4604e0
-  socksreq[4] = 2; /* username/password */
4604e0
-#else
4604e0
-  socksreq[1] = (char)(proxy_user ? 2 : 1); /* number of methods (below) */
4604e0
-  socksreq[2] = 0; /* no authentication */
4604e0
-  socksreq[3] = 2; /* username/password */
4604e0
+  socksreq[idx++] = 1;   /* GSS-API */
4604e0
 #endif
4604e0
+  if(proxy_user)
4604e0
+    socksreq[idx++] = 2; /* username/password */
4604e0
+  /* write the number of authentication methods */
4604e0
+  socksreq[1] = (unsigned char) (idx - 2);
4604e0
 
4604e0
   curlx_nonblock(sock, FALSE);
4604e0
 
4604e0
-- 
4604e0
2.13.5
4604e0
4604e0
4604e0
From a76468431c030fc832aed7a5fa5b4b3f9acfe2ae Mon Sep 17 00:00:00 2001
4604e0
From: Kamil Dudka <kdudka@redhat.com>
4604e0
Date: Thu, 27 Apr 2017 15:18:49 +0200
4604e0
Subject: [PATCH 3/4] CURLOPT_SOCKS5_AUTH: allowed methods for SOCKS5 proxy
4604e0
 auth
4604e0
4604e0
If libcurl was built with GSS-API support, it unconditionally advertised
4604e0
GSS-API authentication while connecting to a SOCKS5 proxy.  This caused
4604e0
problems in environments with improperly configured Kerberos: a stock
4604e0
libcurl failed to connect, despite libcurl built without GSS-API
4604e0
connected fine using username and password.
4604e0
4604e0
This commit introduces the CURLOPT_SOCKS5_AUTH option to control the
4604e0
allowed methods for SOCKS5 authentication at run time.
4604e0
4604e0
Note that a new option was preferred over reusing CURLOPT_PROXYAUTH
4604e0
for compatibility reasons because the set of authentication methods
4604e0
allowed by default was different for HTTP and SOCKS5 proxies.
4604e0
4604e0
Bug: https://curl.haxx.se/mail/lib-2017-01/0005.html
4604e0
Closes https://github.com/curl/curl/pull/1454
4604e0
4604e0
Upstream-commit: 8924f58c370afa756fc4fd13916dfdea91d21b21
4604e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
4604e0
---
4604e0
 docs/libcurl/curl_easy_setopt.3  |  8 ++++++++
4604e0
 docs/libcurl/symbols-in-versions |  2 ++
4604e0
 include/curl/curl.h              |  6 ++++++
4604e0
 lib/socks.c                      | 27 ++++++++++++++++++---------
4604e0
 lib/url.c                        |  8 ++++++++
4604e0
 lib/urldata.h                    |  1 +
4604e0
 6 files changed, 43 insertions(+), 9 deletions(-)
4604e0
4604e0
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
4604e0
index 0a9375e..4ce8207 100644
4604e0
--- a/docs/libcurl/curl_easy_setopt.3
4604e0
+++ b/docs/libcurl/curl_easy_setopt.3
4604e0
@@ -862,6 +862,14 @@ Set the parameter to 1 to make the library tunnel all operations through a
4604e0
 given HTTP proxy. There is a big difference between using a proxy and to
4604e0
 tunnel through it. If you don't know what this means, you probably don't want
4604e0
 this tunneling option.
4604e0
+.IP CURLOPT_SOCKS5_AUTH
4604e0
+Pass a long as parameter, which is set to a bitmask, to tell libcurl which
4604e0
+authentication method(s) are allowed for SOCKS5 proxy authentication.  The only
4604e0
+supported flags are \fICURLAUTH_BASIC\fP, which allows username/password
4604e0
+authentication, \fICURLAUTH_GSSAPI\fP, which allows GSS-API authentication, and
4604e0
+\fICURLAUTH_NONE\fP, which allows no authentication.  Set the actual user name
4604e0
+and password with the \fICURLOPT_PROXYUSERPWD(3)\fP option.  Defaults to
4604e0
+\fICURLAUTH_BASIC|CURLAUTH_GSSAPI\fP.  (Added in 7.55.0)
4604e0
 .IP CURLOPT_SOCKS5_GSSAPI_SERVICE
4604e0
 Pass a char * as parameter to a string holding the name of the service. The
4604e0
 default service name for a SOCKS5 server is rcmd/server-fqdn. This option
4604e0
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
4604e0
index 0f7469d..b0b6232 100644
4604e0
--- a/docs/libcurl/symbols-in-versions
4604e0
+++ b/docs/libcurl/symbols-in-versions
4604e0
@@ -17,6 +17,7 @@ CURLAUTH_ANYSAFE                7.10.6
4604e0
 CURLAUTH_BASIC                  7.10.6
4604e0
 CURLAUTH_DIGEST                 7.10.6
4604e0
 CURLAUTH_DIGEST_IE              7.19.3
4604e0
+CURLAUTH_GSSAPI                 7.55.0
4604e0
 CURLAUTH_GSSNEGOTIATE           7.10.6
4604e0
 CURLAUTH_NONE                   7.10.6
4604e0
 CURLAUTH_NTLM                   7.10.6
4604e0
@@ -454,6 +455,7 @@ CURLOPT_SERVER_RESPONSE_TIMEOUT 7.20.0
4604e0
 CURLOPT_SHARE                   7.10
4604e0
 CURLOPT_SOCKOPTDATA             7.16.0
4604e0
 CURLOPT_SOCKOPTFUNCTION         7.16.0
4604e0
+CURLOPT_SOCKS5_AUTH             7.55.0
4604e0
 CURLOPT_SOCKS5_GSSAPI_NEC       7.19.4
4604e0
 CURLOPT_SOCKS5_GSSAPI_SERVICE   7.19.4
4604e0
 CURLOPT_SOURCE_HOST             7.12.1        -           7.15.5
4604e0
diff --git a/include/curl/curl.h b/include/curl/curl.h
4604e0
index 14f6fd7..0375a64 100644
4604e0
--- a/include/curl/curl.h
4604e0
+++ b/include/curl/curl.h
4604e0
@@ -626,6 +626,9 @@ typedef enum {
4604e0
 #define CURLAUTH_ANY          (~CURLAUTH_DIGEST_IE)
4604e0
 #define CURLAUTH_ANYSAFE      (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
4604e0
 
4604e0
+/* Used for CURLOPT_SOCKS5_AUTH to stay terminologically correct */
4604e0
+#define CURLAUTH_GSSAPI CURLAUTH_GSSNEGOTIATE
4604e0
+
4604e0
 #define CURLSSH_AUTH_ANY       ~0     /* all types supported by the server */
4604e0
 #define CURLSSH_AUTH_NONE      0      /* none allowed, silly but complete */
4604e0
 #define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
4604e0
@@ -1539,6 +1542,9 @@ typedef enum {
4604e0
   /* Path to UNIX domain socket */
4604e0
   CINIT(UNIX_SOCKET_PATH, OBJECTPOINT, 231),
4604e0
 
4604e0
+  /* bitmask of allowed auth methods for connections to SOCKS5 proxies */
4604e0
+  CINIT(SOCKS5_AUTH, LONG, 267),
4604e0
+
4604e0
   CURLOPT_LASTENTRY /* the last unused */
4604e0
 } CURLoption;
4604e0
 
4604e0
diff --git a/lib/socks.c b/lib/socks.c
4604e0
index 398e0ac..5900063 100644
4604e0
--- a/lib/socks.c
4604e0
+++ b/lib/socks.c
4604e0
@@ -373,6 +373,8 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
4604e0
   bool socks5_resolve_local = (conn->proxytype == CURLPROXY_SOCKS5)?TRUE:FALSE;
4604e0
   const size_t hostname_len = strlen(hostname);
4604e0
   ssize_t len = 0;
4604e0
+  const unsigned long auth = data->set.socks5auth;
4604e0
+  bool allow_gssapi = FALSE;
4604e0
 
4604e0
   /* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
4604e0
   if(!socks5_resolve_local && hostname_len > 255) {
4604e0
@@ -409,13 +411,24 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
4604e0
     return CURLE_COULDNT_CONNECT;
4604e0
   }
4604e0
 
4604e0
+  if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
4604e0
+    infof(conn->data,
4604e0
+        "warning: unsupported value passed to CURLOPT_SOCKS5_AUTH: %lu\n",
4604e0
+        auth);
4604e0
+  if(!(auth & CURLAUTH_BASIC))
4604e0
+    /* disable username/password auth */
4604e0
+    proxy_user = NULL;
4604e0
+#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
4604e0
+  if(auth & CURLAUTH_GSSAPI)
4604e0
+    allow_gssapi = TRUE;
4604e0
+#endif
4604e0
+
4604e0
   idx = 0;
4604e0
   socksreq[idx++] = 5;   /* version */
4604e0
   idx++;                 /* reserve for the number of authentication methods */
4604e0
   socksreq[idx++] = 0;   /* no authentication */
4604e0
-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
4604e0
-  socksreq[idx++] = 1;   /* GSS-API */
4604e0
-#endif
4604e0
+  if(allow_gssapi)
4604e0
+    socksreq[idx++] = 1; /* GSS-API */
4604e0
   if(proxy_user)
4604e0
     socksreq[idx++] = 2; /* username/password */
4604e0
   /* write the number of authentication methods */
4604e0
@@ -465,7 +478,7 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
4604e0
     ;
4604e0
   }
4604e0
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
4604e0
-  else if(socksreq[1] == 1) {
4604e0
+  else if(allow_gssapi && (socksreq[1] == 1)) {
4604e0
     code = Curl_SOCKS5_gssapi_negotiate(sockindex, conn);
4604e0
     if(code != CURLE_OK) {
4604e0
       failf(data, "Unable to negotiate SOCKS5 gssapi context.");
4604e0
@@ -526,16 +539,12 @@ CURLcode Curl_SOCKS5(const char *proxy_user,
4604e0
   }
4604e0
   else {
4604e0
     /* error */
4604e0
-#if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
4604e0
-    if(socksreq[1] == 255) {
4604e0
-#else
4604e0
-    if(socksreq[1] == 1) {
4604e0
+    if(!allow_gssapi && (socksreq[1] == 1)) {
4604e0
       failf(data,
4604e0
             "SOCKS5 GSSAPI per-message authentication is not supported.");
4604e0
       return CURLE_COULDNT_CONNECT;
4604e0
     }
4604e0
     else if(socksreq[1] == 255) {
4604e0
-#endif
4604e0
       if(!proxy_user || !*proxy_user) {
4604e0
         failf(data,
4604e0
               "No authentication method was acceptable. (It is quite likely"
4604e0
diff --git a/lib/url.c b/lib/url.c
4604e0
index 19a40c7..d632813 100644
4604e0
--- a/lib/url.c
4604e0
+++ b/lib/url.c
4604e0
@@ -516,6 +516,9 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
4604e0
   set->httpauth = CURLAUTH_BASIC;  /* defaults to basic */
4604e0
   set->proxyauth = CURLAUTH_BASIC; /* defaults to basic */
4604e0
 
4604e0
+  /* SOCKS5 proxy auth defaults to username/password + GSS-API */
4604e0
+  set->socks5auth = CURLAUTH_BASIC | CURLAUTH_GSSAPI;
4604e0
+
4604e0
   /* make libcurl quiet by default: */
4604e0
   set->hide_progress = TRUE;  /* CURLOPT_NOPROGRESS changes these */
4604e0
 
4604e0
@@ -1380,6 +1383,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
4604e0
     break;
4604e0
 #endif   /* CURL_DISABLE_PROXY */
4604e0
 
4604e0
+  case CURLOPT_SOCKS5_AUTH:
4604e0
+    data->set.socks5auth = va_arg(param, unsigned long);
4604e0
+    if(data->set.socks5auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
4604e0
+      result = CURLE_NOT_BUILT_IN;
4604e0
+    break;
4604e0
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
4604e0
   case CURLOPT_SOCKS5_GSSAPI_SERVICE:
4604e0
     /*
4604e0
diff --git a/lib/urldata.h b/lib/urldata.h
4604e0
index f4c6222..3e6ace5 100644
4604e0
--- a/lib/urldata.h
4604e0
+++ b/lib/urldata.h
4604e0
@@ -1406,6 +1406,7 @@ struct UserDefined {
4604e0
   long use_port;     /* which port to use (when not using default) */
4604e0
   unsigned long httpauth;  /* kind of HTTP authentication to use (bitmask) */
4604e0
   unsigned long proxyauth; /* kind of proxy authentication to use (bitmask) */
4604e0
+  unsigned long socks5auth;/* kind of SOCKS5 authentication to use (bitmask) */
4604e0
   long followlocation; /* as in HTTP Location: */
4604e0
   long maxredirs;    /* maximum no. of http(s) redirects to follow, set to -1
4604e0
                         for infinity */
4604e0
-- 
4604e0
2.13.5
4604e0
4604e0
4604e0
From 08f6dc218afe2d7e74f87996965f0770a566f185 Mon Sep 17 00:00:00 2001
4604e0
From: Kamil Dudka <kdudka@redhat.com>
4604e0
Date: Fri, 19 May 2017 18:11:47 +0200
4604e0
Subject: [PATCH 4/4] curl --socks5-{basic,gssapi}: control socks5 auth
4604e0
4604e0
Closes https://github.com/curl/curl/pull/1454
4604e0
4604e0
Upstream-commit: ce2c3ebda20919fe636e675f219ae387e386f508
4604e0
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
4604e0
---
4604e0
 docs/curl.1         | 10 ++++++++++
4604e0
 src/tool_cfgable.h  |  1 +
4604e0
 src/tool_getparam.c | 16 ++++++++++++++++
4604e0
 src/tool_help.c     |  2 ++
4604e0
 src/tool_operate.c  |  5 +++++
4604e0
 src/tool_setopt.c   |  1 +
4604e0
 src/tool_setopt.h   |  1 +
4604e0
 7 files changed, 36 insertions(+)
4604e0
4604e0
diff --git a/docs/curl.1 b/docs/curl.1
4604e0
index c9bb336..7906f1f 100644
4604e0
--- a/docs/curl.1
4604e0
+++ b/docs/curl.1
4604e0
@@ -1343,6 +1343,16 @@ Since 7.21.7, this option is superfluous since you can specify a socks4a proxy
4604e0
 with \fI-x, --proxy\fP using a socks4a:// protocol prefix.
4604e0
 
4604e0
 If this option is used several times, the last one will be used.
4604e0
+.IP "--socks5-basic"
4604e0
+Tells curl to use username/password authentication when connecting to a SOCKS5
4604e0
+proxy.  The username/password authentication is enabled by default.  Use
4604e0
+\fI--socks5-gssapi\fP to force GSS-API authentication to SOCKS5 proxies.
4604e0
+(Added in 7.55.0)
4604e0
+.IP "--socks5-gssapi"
4604e0
+Tells curl to use GSS-API authentication when connecting to a SOCKS5 proxy.
4604e0
+The GSS-API authentication is enabled by default (if curl is compiled with
4604e0
+GSS-API support).  Use \fI--socks5-basic\fP to force username/password
4604e0
+authentication to SOCKS5 proxies.  (Added in 7.55.0)
4604e0
 .IP "--socks5-hostname <host[:port]>"
4604e0
 Use the specified SOCKS5 proxy (and let the proxy resolve the host name). If
4604e0
 the port number is not specified, it is assumed at port 1080. (Added in
4604e0
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
4604e0
index a9b033b..68d0297 100644
4604e0
--- a/src/tool_cfgable.h
4604e0
+++ b/src/tool_cfgable.h
4604e0
@@ -172,6 +172,7 @@ struct Configurable {
4604e0
                                  * default rcmd */
4604e0
   int socks5_gssapi_nec ;   /* The NEC reference server does not protect
4604e0
                              * the encryption type exchange */
4604e0
+  unsigned long socks5_auth;/* auth bitmask for socks5 proxies */
4604e0
 
4604e0
   bool tcp_nodelay;
4604e0
   long req_retry;           /* number of retries */
4604e0
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
4604e0
index 33db742..32fc68b 100644
4604e0
--- a/src/tool_getparam.c
4604e0
+++ b/src/tool_getparam.c
4604e0
@@ -210,6 +210,8 @@ static const struct LongShort aliases[]= {
4604e0
   {"El", "tlspassword",              TRUE},
4604e0
   {"Em", "tlsauthtype",              TRUE},
4604e0
   {"En", "ssl-allow-beast",          FALSE},
4604e0
+  {"EA", "socks5-basic",             FALSE},
4604e0
+  {"EB", "socks5-gssapi",            FALSE},
4604e0
   {"f",  "fail",                     FALSE},
4604e0
   {"F",  "form",                     TRUE},
4604e0
   {"Fs", "form-string",              TRUE},
4604e0
@@ -1324,6 +1326,20 @@ ParameterError getparameter(char *flag,    /* f or -long-flag */
4604e0
         if(curlinfo->features & CURL_VERSION_SSL)
4604e0
           config->ssl_allow_beast = toggle;
4604e0
         break;
4604e0
+      case 'A':
4604e0
+        /* --socks5-basic */
4604e0
+        if(toggle)
4604e0
+          config->socks5_auth |= CURLAUTH_BASIC;
4604e0
+        else
4604e0
+          config->socks5_auth &= ~CURLAUTH_BASIC;
4604e0
+        break;
4604e0
+      case 'B':
4604e0
+        /* --socks5-gssapi */
4604e0
+        if(toggle)
4604e0
+          config->socks5_auth |= CURLAUTH_GSSAPI;
4604e0
+        else
4604e0
+          config->socks5_auth &= ~CURLAUTH_GSSAPI;
4604e0
+        break;
4604e0
       default: /* certificate file */
4604e0
       {
4604e0
         char *certname, *passphrase;
4604e0
diff --git a/src/tool_help.c b/src/tool_help.c
4604e0
index 3a64e35..c2883eb 100644
4604e0
--- a/src/tool_help.c
4604e0
+++ b/src/tool_help.c
4604e0
@@ -179,6 +179,8 @@ static const char *const helptext[] = {
4604e0
   "     --socks4 HOST[:PORT]  SOCKS4 proxy on given host + port",
4604e0
   "     --socks4a HOST[:PORT]  SOCKS4a proxy on given host + port",
4604e0
   "     --socks5 HOST[:PORT]  SOCKS5 proxy on given host + port",
4604e0
+  "     --socks5-basic  Enable username/password auth for SOCKS5 proxies",
4604e0
+  "     --socks5-gssapi Enable GSS-API auth for SOCKS5 proxies",
4604e0
   "     --socks5-hostname HOST[:PORT] "
4604e0
   "SOCKS5 proxy, pass host name to proxy",
4604e0
 #if defined(HAVE_GSSAPI) || defined(USE_WINDOWS_SSPI)
4604e0
diff --git a/src/tool_operate.c b/src/tool_operate.c
4604e0
index 41b0e6b..185f9c6 100644
4604e0
--- a/src/tool_operate.c
4604e0
+++ b/src/tool_operate.c
4604e0
@@ -1208,6 +1208,11 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
4604e0
           if(config->socks5_gssapi_nec)
4604e0
             my_setopt_str(curl, CURLOPT_SOCKS5_GSSAPI_NEC,
4604e0
                           config->socks5_gssapi_nec);
4604e0
+
4604e0
+          /* new in curl 7.55.0 */
4604e0
+          if(config->socks5_auth)
4604e0
+            my_setopt_bitmask(curl, CURLOPT_SOCKS5_AUTH,
4604e0
+                              (long)config->socks5_auth);
4604e0
         }
4604e0
 #endif
4604e0
         /* curl 7.13.0 */
4604e0
diff --git a/src/tool_setopt.c b/src/tool_setopt.c
4604e0
index 9860117..5ae32cd 100644
4604e0
--- a/src/tool_setopt.c
4604e0
+++ b/src/tool_setopt.c
4604e0
@@ -130,6 +130,7 @@ const NameValue setopt_nv_CURLPROTO[] = {
4604e0
 static const NameValue setopt_nv_CURLNONZERODEFAULTS[] = {
4604e0
   NV1(CURLOPT_SSL_VERIFYPEER, 1),
4604e0
   NV1(CURLOPT_SSL_VERIFYHOST, 1),
4604e0
+  NV1(CURLOPT_SOCKS5_AUTH, 1),
4604e0
   NVEND
4604e0
 };
4604e0
 
4604e0
diff --git a/src/tool_setopt.h b/src/tool_setopt.h
4604e0
index d107756..60e614c 100644
4604e0
--- a/src/tool_setopt.h
4604e0
+++ b/src/tool_setopt.h
4604e0
@@ -64,6 +64,7 @@ extern const NameValueUnsigned setopt_nv_CURLAUTH[];
4604e0
 #define setopt_nv_CURLOPT_REDIR_PROTOCOLS setopt_nv_CURLPROTO
4604e0
 #define setopt_nv_CURLOPT_PROXYTYPE setopt_nv_CURLPROXY
4604e0
 #define setopt_nv_CURLOPT_PROXYAUTH setopt_nv_CURLAUTH
4604e0
+#define setopt_nv_CURLOPT_SOCKS5_AUTH setopt_nv_CURLAUTH
4604e0
 
4604e0
 /* Intercept setopt calls for --libcurl */
4604e0
 
4604e0
-- 
4604e0
2.13.5
4604e0