]> granicus.if.org Git - curl/commitdiff
sasl: Implement SASL authorisation identity via CURLOPT_SASL_AUTHZID
authorSteve Holme <steve_holme@hotmail.com>
Wed, 17 Apr 2019 22:47:51 +0000 (23:47 +0100)
committerJay Satiro <raysatiro@yahoo.com>
Tue, 6 Aug 2019 15:38:20 +0000 (11:38 -0400)
Added the ability for the calling program to specify the authorisation
identity (authzid), the identity to act as, in addition to the
authentication identity (authcid) and password when using SASL PLAIN
authentication.

Fixes #3653
Closes #3790

NOTE: This commit was cherry-picked and is part of a series of commits
that added the authzid feature for upcoming 7.66.0. The series was
temporarily reverted in db8ec1f so that it would not ship in a 7.65.x
patch release.

Closes https://github.com/curl/curl/pull/4186

12 files changed:
docs/libcurl/curl_easy_setopt.3
docs/libcurl/opts/CURLOPT_SASL_AUTHZID.3 [new file with mode: 0644]
docs/libcurl/opts/Makefile.inc
docs/libcurl/symbols-in-versions
include/curl/curl.h
include/curl/typecheck-gcc.h
lib/curl_sasl.c
lib/setopt.c
lib/url.c
lib/urldata.h
packages/OS400/ccsidcurl.c
packages/OS400/curl.inc.in

index cb5c418fbb5dc9b277cf6842ed0820f0dd57cdc6..2d052f0a4c449f536a2aac52ccde197bdb83219d 100644 (file)
@@ -256,6 +256,8 @@ TLS authentication methods. See \fICURLOPT_TLSAUTH_TYPE(3)\fP
 Proxy TLS authentication methods. See \fICURLOPT_PROXY_TLSAUTH_TYPE(3)\fP
 .IP CURLOPT_PROXYAUTH
 HTTP proxy authentication methods. See \fICURLOPT_PROXYAUTH(3)\fP
+.IP CURLOPT_SASL_AUTHZID
+SASL authorisation identity (identity to act as). See \fICURLOPT_SASL_AUTHZID(3)\fP
 .IP CURLOPT_SASL_IR
 Enable SASL initial response. See \fICURLOPT_SASL_IR(3)\fP
 .IP CURLOPT_XOAUTH2_BEARER
diff --git a/docs/libcurl/opts/CURLOPT_SASL_AUTHZID.3 b/docs/libcurl/opts/CURLOPT_SASL_AUTHZID.3
new file mode 100644 (file)
index 0000000..6544547
--- /dev/null
@@ -0,0 +1,64 @@
+.\" **************************************************************************
+.\" *                                  _   _ ____  _
+.\" *  Project                     ___| | | |  _ \| |
+.\" *                             / __| | | | |_) | |
+.\" *                            | (__| |_| |  _ <| |___
+.\" *                             \___|\___/|_| \_\_____|
+.\" *
+.\" * Copyright (C) 1998 - 2019, 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_SASL_AUTHZID 3 "11 Sep 2019" "libcurl 7.66.0" "curl_easy_setopt options"
+.SH NAME
+CURLOPT_SASL_AUTHZID \- authorisation identity (identity to act as)
+.SH SYNOPSIS
+#include <curl/curl.h>
+
+CURLcode curl_easy_setopt(CURL *handle, CURLOPT_SASL_AUTHZID, char *authzid);
+.SH DESCRIPTION
+Pass a char * as parameter, which should be pointing to the zero terminated
+authorisation identity (authzid) for the transfer. Only applicable to the PLAIN
+SASL authentication mechanism where it is optional.
+
+When not specified only the authentication identity (authcid) as specified by
+the username will be sent to the server, along with the password. The server
+will derive a authzid from the authcid when not provided, which it will then
+uses internally.
+
+When the authzid is specified, the use of which is server dependent, it can be
+used to access another user's inbox, that the user has been granted access to,
+or a shared mailbox for example.
+.SH DEFAULT
+blank
+.SH PROTOCOLS
+IMAP, POP3 and SMTP
+.SH EXAMPLE
+.nf
+CURL *curl = curl_easy_init();
+if(curl) {
+  curl_easy_setopt(curl, CURLOPT_URL, "imap://example.com/");
+  curl_easy_setopt(curl, CURLOPT_USERNAME, "Kurt");
+  curl_easy_setopt(curl, CURLOPT_PASSWORD, "xipj3plmq");
+  curl_easy_setopt(curl, CURLOPT_SASL_AUTHZID, "Ursel");
+  ret = curl_easy_perform(curl);
+  curl_easy_cleanup(curl);
+}
+.fi
+.SH AVAILABILITY
+Added in 7.66.0
+.SH RETURN VALUE
+Returns CURLE_OK if the option is supported, and CURLE_UNKNOWN_OPTION if not.
+.SH "SEE ALSO"
+.BR CURLOPT_USERNAME "(3), " CURLOPT_PASSWORD "(3), ".BR CURLOPT_USERPWD "(3)"
index 5460b2a57f4b8bb6618500644e726aeda3079a5a..094c58f427ebeea9cd9c9025dc20e8f84258a8c2 100644 (file)
@@ -273,6 +273,7 @@ man_MANS =                                      \
   CURLOPT_RTSP_SESSION_ID.3                     \
   CURLOPT_RTSP_STREAM_URI.3                     \
   CURLOPT_RTSP_TRANSPORT.3                      \
+  CURLOPT_SASL_AUTHZID.3                        \
   CURLOPT_SASL_IR.3                             \
   CURLOPT_SEEKDATA.3                            \
   CURLOPT_SEEKFUNCTION.3                        \
index 1b452d2458faedb4e4722c417a072e6a41a6de44..1afe73b533a331abcccad6916cc8b3e37d2616e0 100644 (file)
@@ -556,6 +556,7 @@ CURLOPT_RTSP_SERVER_CSEQ        7.20.0
 CURLOPT_RTSP_SESSION_ID         7.20.0
 CURLOPT_RTSP_STREAM_URI         7.20.0
 CURLOPT_RTSP_TRANSPORT          7.20.0
+CURLOPT_SASL_AUTHZID            7.66.0
 CURLOPT_SASL_IR                 7.31.0
 CURLOPT_SEEKDATA                7.18.0
 CURLOPT_SEEKFUNCTION            7.18.0
index a3cdd8395e7d222a4a52a790eb71c2c3c66f25df..33aa047a703ca673b892b7fb78dc742eaef97b97 100644 (file)
@@ -1929,6 +1929,9 @@ typedef enum {
   /* Bitmask to control HTTP/3 behavior. See CURLH3_* */
   CINIT(H3, LONG, 289),
 
+  /* SASL authorisation identity */
+  CINIT(SASL_AUTHZID, STRINGPOINT, 290),
+
   CURLOPT_LASTENTRY /* the last unused */
 } CURLoption;
 
index eeb36abc09b7373d0b57da2ba568cddcd5e487f4..dfd48b8a3f81ac153076e4e4beef012401ee727b 100644 (file)
@@ -311,6 +311,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_off_t,
    (option) == CURLOPT_RTSP_SESSION_ID ||                                     \
    (option) == CURLOPT_RTSP_STREAM_URI ||                                     \
    (option) == CURLOPT_RTSP_TRANSPORT ||                                      \
+   (option) == CURLOPT_SASL_AUTHZID ||                                        \
    (option) == CURLOPT_SERVICE_NAME ||                                        \
    (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE ||                               \
    (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 ||                             \
index 018e4228b3c23254896dc348beeb8f4d121f28ed..0aa1f5bb7a64726ae232c1c59df16d56a8a03e3b 100644 (file)
@@ -370,8 +370,9 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
       sasl->authused = SASL_MECH_PLAIN;
 
       if(force_ir || data->set.sasl_ir)
-        result = Curl_auth_create_plain_message(data, NULL, conn->user,
-                                                conn->passwd, &resp, &len);
+        result = Curl_auth_create_plain_message(data, conn->sasl_authzid,
+                                                conn->user, conn->passwd,
+                                                &resp, &len);
     }
     else if(enabledmechs & SASL_MECH_LOGIN) {
       mech = SASL_MECH_STRING_LOGIN;
@@ -453,8 +454,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
     *progress = SASL_DONE;
     return result;
   case SASL_PLAIN:
-    result = Curl_auth_create_plain_message(data, NULL, conn->user,
-                                            conn->passwd, &resp, &len);
+    result = Curl_auth_create_plain_message(data, conn->sasl_authzid,
+                                            conn->user, conn->passwd,
+                                            &resp, &len);
     break;
   case SASL_LOGIN:
     result = Curl_auth_create_login_message(data, conn->user, &resp, &len);
index 64a6b010d726ffc6993f469bdd088f593e2abfac..91251bd7b2d8ea803a4416da71e1a96fdab2a2f9 100644 (file)
@@ -2402,6 +2402,12 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
     break;
 #endif
 
+  case CURLOPT_SASL_AUTHZID:
+    /* Authorisation identity (identity to act as) */
+    result = Curl_setstropt(&data->set.str[STRING_SASL_AUTHZID],
+                            va_arg(param, char *));
+    break;
+
   case CURLOPT_SASL_IR:
     /* Enable/disable SASL initial response */
     data->set.sasl_ir = (0 != va_arg(param, long)) ? TRUE : FALSE;
index 05fc0e50e58ba42845e15c734aad0a9d5868db84..c61319b3bb845d4e463c5b43f0e57e2226c326bf 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -715,6 +715,7 @@ static void conn_free(struct connectdata *conn)
   Curl_safefree(conn->user);
   Curl_safefree(conn->passwd);
   Curl_safefree(conn->oauth_bearer);
+  Curl_safefree(conn->sasl_authzid);
   Curl_safefree(conn->options);
   Curl_safefree(conn->http_proxy.user);
   Curl_safefree(conn->socks_proxy.user);
@@ -3492,6 +3493,14 @@ static CURLcode create_conn(struct Curl_easy *data,
     }
   }
 
+  if(data->set.str[STRING_SASL_AUTHZID]) {
+    conn->sasl_authzid = strdup(data->set.str[STRING_SASL_AUTHZID]);
+    if(!conn->sasl_authzid) {
+      result = CURLE_OUT_OF_MEMORY;
+      goto out;
+    }
+  }
+
 #ifdef USE_UNIX_SOCKETS
   if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
     conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
index b9daf12deba16b851ea3a9a74f8c3148852b5bac..b3b1263c60f62b62f1b4d8811a3d6096ffe389e3 100644 (file)
@@ -875,7 +875,8 @@ struct connectdata {
   char *passwd;  /* password string, allocated */
   char *options; /* options string, allocated */
 
-  char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */
+  char *oauth_bearer;     /* bearer token for OAuth 2.0, allocated */
+  char *sasl_authzid;     /* authorisation identity string, allocated */
 
   int httpversion;        /* the HTTP version*10 reported by the server */
   int rtspversion;        /* the RTSP version*10 reported by the server */
@@ -1498,6 +1499,7 @@ enum dupstring {
 #ifdef USE_ALTSVC
   STRING_ALTSVC,                /* CURLOPT_ALTSVC */
 #endif
+  STRING_SASL_AUTHZID,          /* CURLOPT_SASL_AUTHZID */
   /* -- end of zero-terminated strings -- */
 
   STRING_LASTZEROTERMINATED,
index 4b462a273a595bdcc9b8afd686a4714e735373e1..a55cd5e10195367424ab78080d5a768c70ffd3e0 100644 (file)
@@ -1213,6 +1213,7 @@ curl_easy_setopt_ccsid(CURL *curl, CURLoption tag, ...)
   case CURLOPT_RTSP_SESSION_ID:
   case CURLOPT_RTSP_STREAM_URI:
   case CURLOPT_RTSP_TRANSPORT:
+  case CURLOPT_SASL_AUTHZID:
   case CURLOPT_SERVICE_NAME:
   case CURLOPT_SOCKS5_GSSAPI_SERVICE:
   case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
index 21da014e144ab69cf57982079facbd7bc1c844c9..c9c046831d2b303e6d5a4fffef5636de787559b9 100644 (file)
      d                 c                   00288
      d  CURLOPT_H3...
      d                 c                   00289
+     d  CURLOPT_SASL_AUTHZID...
+     d                 c                   10290
       *
       /if not defined(CURL_NO_OLDIES)
      d  CURLOPT_FILE   c                   10001