]> granicus.if.org Git - curl/commitdiff
vauth/oauth2: Fix OAUTHBEARER token generation
authorMert Yazıcıoğlu <mert@mertyazicioglu.com>
Sun, 16 Dec 2018 12:45:40 +0000 (15:45 +0300)
committerJay Satiro <raysatiro@yahoo.com>
Tue, 2 Apr 2019 19:52:12 +0000 (15:52 -0400)
OAUTHBEARER tokens were incorrectly generated in a format similar to
XOAUTH2 tokens. These changes make OAUTHBEARER tokens conform to the
RFC7628.

Fixes: #2487
Reported-by: Paolo Mossino
Closes https://github.com/curl/curl/pull/3377

15 files changed:
lib/curl_sasl.c
lib/vauth/oauth2.c
lib/vauth/vauth.h
tests/data/test842
tests/data/test843
tests/data/test844
tests/data/test845
tests/data/test887
tests/data/test888
tests/data/test889
tests/data/test890
tests/data/test946
tests/data/test947
tests/data/test948
tests/data/test949

index 9e1a72e5e4d8a9f318fcdfe8b1a0d2a7ec14858c..456e08325a72d78df4269c46d6f0360aa6dd8bca 100644 (file)
@@ -357,10 +357,9 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
       sasl->authused = SASL_MECH_XOAUTH2;
 
       if(force_ir || data->set.sasl_ir)
-        result = Curl_auth_create_oauth_bearer_message(data, conn->user,
-                                                       NULL, 0,
-                                                       conn->oauth_bearer,
-                                                       &resp, &len);
+        result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
+                                                        conn->oauth_bearer,
+                                                        &resp, &len);
     }
     else if(enabledmechs & SASL_MECH_PLAIN) {
       mech = SASL_MECH_STRING_PLAIN;
@@ -562,10 +561,9 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
       newstate = SASL_OAUTH2_RESP;
     }
     else
-      result = Curl_auth_create_oauth_bearer_message(data, conn->user,
-                                                     NULL, 0,
-                                                     conn->oauth_bearer,
-                                                     &resp, &len);
+      result = Curl_auth_create_xoauth_bearer_message(data, conn->user,
+                                                      conn->oauth_bearer,
+                                                      &resp, &len);
     break;
 
   case SASL_OAUTH2_RESP:
index 6288f89a388b04bbc2d0a25efe4b83ce48c0b2ea..bedc6e3e6a9e71c03bd809ba3f2f5e180bc1cde4 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, 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
@@ -46,8 +46,8 @@
  *
  * data[in]         - The session handle.
  * user[in]         - The user name.
- * host[in]         - The host name(for OAUTHBEARER).
- * port[in]         - The port(for OAUTHBEARER when not Port 80).
+ * host[in]         - The host name.
+ * port[in]         - The port(when not Port 80).
  * bearer[in]       - The bearer token.
  * outptr[in / out] - The address where a pointer to newly allocated memory
  *                    holding the result will be stored upon completion.
@@ -66,13 +66,11 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
   char *oauth = NULL;
 
   /* Generate the message */
-  if(host == NULL && (port == 0 || port == 80))
-    oauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
-  else if(port == 0 || port == 80)
-    oauth = aprintf("user=%s\1host=%s\1auth=Bearer %s\1\1", user, host,
+  if(port == 0 || port == 80)
+    oauth = aprintf("n,a=%s,\1host=%s\1auth=Bearer %s\1\1", user, host,
                     bearer);
   else
-    oauth = aprintf("user=%s\1host=%s\1port=%ld\1auth=Bearer %s\1\1", user,
+    oauth = aprintf("n,a=%s,\1host=%s\1port=%ld\1auth=Bearer %s\1\1", user,
                     host, port, bearer);
   if(!oauth)
     return CURLE_OUT_OF_MEMORY;
@@ -84,3 +82,40 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
 
   return result;
 }
+
+/*
+ * Curl_auth_create_xoauth_bearer_message()
+ *
+ * This is used to generate an already encoded XOAuth 2.0 message ready for
+ * sending to the recipient.
+ *
+ * Parameters:
+ *
+ * data[in]         - The session handle.
+ * user[in]         - The user name.
+ * bearer[in]       - The bearer token.
+ * outptr[in / out] - The address where a pointer to newly allocated memory
+ *                    holding the result will be stored upon completion.
+ * outlen[out]      - The length of the output message.
+ *
+ * Returns CURLE_OK on success.
+ */
+CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data,
+                                               const char *user,
+                                               const char *bearer,
+                                               char **outptr, size_t *outlen)
+{
+  CURLcode result = CURLE_OK;
+
+  /* Generate the message */
+  char *xoauth = aprintf("user=%s\1auth=Bearer %s\1\1", user, bearer);
+  if(!xoauth)
+    return CURLE_OUT_OF_MEMORY;
+
+  /* Base64 encode the reply */
+  result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen);
+
+  free(xoauth);
+
+  return result;
+}
index f43064211f49bf84007259febaaa067aa030632e..13ddc41f76a4b84f7ac912bb8886daa47646e9f0 100644 (file)
@@ -151,6 +151,13 @@ CURLcode Curl_auth_create_oauth_bearer_message(struct Curl_easy *data,
                                                const long port,
                                                const char *bearer,
                                                char **outptr, size_t *outlen);
+
+/* This is used to generate a base64 encoded XOAuth 2.0 message */
+CURLcode Curl_auth_create_xoauth_bearer_message(struct Curl_easy *data,
+                                                const char *user,
+                                                const char *bearer,
+                                                char **outptr, size_t *outlen);
+
 #if defined(USE_KERBEROS5)
 /* This is used to evaluate if GSSAPI (Kerberos V5) is supported */
 bool Curl_auth_is_gssapi_supported(void);
index e86abd430faaddd9d63fa88734e4e350cd42fca7..1d9181e175c10c5d002a6b935cf9994e85b2e7a3 100644 (file)
@@ -15,7 +15,7 @@ RFC7628
 <servercmd>
 AUTH OAUTHBEARER
 REPLY AUTHENTICATE +
-REPLY dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== A002 OK AUTHENTICATE completed
+REPLY bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== A002 OK AUTHENTICATE completed
 </servercmd>
 <data>
 From: me@somewhere\r
@@ -53,7 +53,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 <protocol>
 A001 CAPABILITY\r
 A002 AUTHENTICATE OAUTHBEARER\r
-dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 A003 SELECT 842\r
 A004 FETCH 1 BODY[]\r
 A005 LOGOUT\r
index e286fd93fc5f88ad8a44702d55a9151cb2c17ac8..bd39dd907153d118e00a153ae8511dca92275fbf 100644 (file)
@@ -53,7 +53,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 <verify>
 <protocol>
 A001 CAPABILITY\r
-A002 AUTHENTICATE OAUTHBEARER dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+A002 AUTHENTICATE OAUTHBEARER bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 A003 SELECT 843\r
 A004 FETCH 1 BODY[]\r
 A005 LOGOUT\r
index 2cdb265fa3fc50237137eb2722df5880445b198a..c5093d2b8cbf899dd32567d83b9e156d9f5b5af2 100644 (file)
@@ -15,7 +15,8 @@ RFC7628
 <servercmd>
 AUTH OAUTHBEARER
 REPLY AUTHENTICATE +
-REPLY dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== + eyJzdGF0dXMiOiJpbnZhbGlkX3Rva2VuIiwic2NvcGUiOiJleGFtcGxlX3Njb3BlIiwib3BlbmlkLWNvbmZpZ3VyYXRpb24iOiJodHRwczovL2V4YW1wbGUuY29tLy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uIn0=
+REPLY bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== +
+eyJzdGF0dXMiOiJpbnZhbGlkX3Rva2VuIiwic2NvcGUiOiJleGFtcGxlX3Njb3BlIiwib3BlbmlkLWNvbmZpZ3VyYXRpb24iOiJodHRwczovL2V4YW1wbGUuY29tLy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uIn0=
 REPLY AQ== A002 NO Authentication failed
 </servercmd>
 </reply>
@@ -52,7 +53,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 <protocol>
 A001 CAPABILITY\r
 A002 AUTHENTICATE OAUTHBEARER\r
-dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 AQ==\r
 </protocol>
 </verify>
index d8b55748853644c07ab4e0917651963a2efe4be5..70562c7ab33281a881e4abc14d4f6caf27655298 100644 (file)
@@ -52,7 +52,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 # transfer and such a connection will not get a "LOGOUT"
 <protocol>
 A001 CAPABILITY\r
-A002 AUTHENTICATE OAUTHBEARER dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+A002 AUTHENTICATE OAUTHBEARER bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMwFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 AQ==\r
 </protocol>
 </verify>
index fed4e3d92dd97fbdb78259f90b26723d19476ada..35419b5027827741635724a0552377e92f4733c4 100644 (file)
@@ -17,7 +17,7 @@ RFC7628
 <servercmd>
 AUTH OAUTHBEARER
 REPLY AUTH +
-REPLY dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== +OK Login successful
+REPLY bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== +OK Login successful
 </servercmd>
 <data>
 From: me@somewhere\r
@@ -55,7 +55,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 <protocol>
 CAPA\r
 AUTH OAUTHBEARER\r
-dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 RETR 887\r
 QUIT\r
 </protocol>
index c52974f1996fd71444f14ff6bbe1df9fade741db..78463feaa8518a7ee89a9e36ff85933dfb5ea8ba 100644 (file)
@@ -54,7 +54,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 <verify>
 <protocol>
 CAPA\r
-AUTH OAUTHBEARER dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+AUTH OAUTHBEARER bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 RETR 888\r
 QUIT\r
 </protocol>
index da26a3729d9120bdcfa26fdf1fdf2a28e9f9e4df..2edb371e956fe3c0da2510fd3949031e5f9041e2 100644 (file)
@@ -17,7 +17,7 @@ RFC7628
 <servercmd>
 AUTH OAUTHBEARER
 REPLY AUTH +
-REPLY dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== + eyJzdGF0dXMiOiJpbnZhbGlkX3Rva2VuIiwic2NvcGUiOiJleGFtcGxlX3Njb3BlIiwib3BlbmlkLWNvbmZpZ3VyYXRpb24iOiJodHRwczovL2V4YW1wbGUuY29tLy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uIn0
+REPLY bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== + eyJzdGF0dXMiOiJpbnZhbGlkX3Rva2VuIiwic2NvcGUiOiJleGFtcGxlX3Njb3BlIiwib3BlbmlkLWNvbmZpZ3VyYXRpb24iOiJodHRwczovL2V4YW1wbGUuY29tLy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uIn0
 REPLY AQ== -ERR Authentication failed
 </servercmd>
 </reply>
@@ -54,7 +54,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 <protocol>
 CAPA\r
 AUTH OAUTHBEARER\r
-dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 AQ==\r
 </protocol>
 </verify>
index 30aa0b23239a300f1f2976f8c21dfd9c84dd1aa0..ca0ccc7b5e0da87807663b85a7f22cca798969ba 100644 (file)
@@ -53,7 +53,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 # transfer and such a connection will not get a "QUIT"
 <protocol>
 CAPA\r
-AUTH OAUTHBEARER dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+AUTH OAUTHBEARER bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwMQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 AQ==\r
 </protocol>
 </verify>
index da4b924f9d56aed04f9fadb48f70f9ac34c03d2c..c6753dc1e1afe065ddab7a1ce10d645515aa057e 100644 (file)
@@ -16,7 +16,7 @@ RFC7628
 <servercmd>
 AUTH OAUTHBEARER
 REPLY AUTH 334 OAUTHBEARER supported
-REPLY dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== 235 Authenticated
+REPLY bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== 235 Authenticated
 </servercmd>
 </reply>
 
@@ -48,7 +48,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 <protocol>
 EHLO 946\r
 AUTH OAUTHBEARER\r
-dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 MAIL FROM:<sender@example.com>\r
 RCPT TO:<recipient@example.com>\r
 DATA\r
index d33a55931e018d6863271fec200524237f1af673..03c3fbe37d8e5f20f5b15484015b119804d682cf 100644 (file)
@@ -47,7 +47,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 <verify>
 <protocol>
 EHLO 947\r
-AUTH OAUTHBEARER dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+AUTH OAUTHBEARER bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 MAIL FROM:<sender@example.com>\r
 RCPT TO:<recipient@example.com>\r
 DATA\r
index 9c1e31deb2500af39cf67d4ce36a7e07cfe2af10..8385f0cd27f3a99d3142ab4fee7240427d215231 100644 (file)
@@ -16,7 +16,7 @@ RFC7628
 <servercmd>
 AUTH OAUTHBEARER
 REPLY AUTH 334 OAUTHBEARER supported
-REPLY dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== 334 eyJzdGF0dXMiOiJpbnZhbGlkX3Rva2VuIiwic2NvcGUiOiJleGFtcGxlX3Njb3BlIiwib3BlbmlkLWNvbmZpZ3VyYXRpb24iOiJodHRwczovL2V4YW1wbGUuY29tLy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uIn0
+REPLY bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ== 334 eyJzdGF0dXMiOiJpbnZhbGlkX3Rva2VuIiwic2NvcGUiOiJleGFtcGxlX3Njb3BlIiwib3BlbmlkLWNvbmZpZ3VyYXRpb24iOiJodHRwczovL2V4YW1wbGUuY29tLy53ZWxsLWtub3duL29wZW5pZC1jb25maWd1cmF0aW9uIn0
 REPLY AQ== 535 Username and Password not accepted. Learn more at\r\n535 http://support.example.com/mail/oauth
 </servercmd>
 </reply>
@@ -56,7 +56,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 <protocol>
 EHLO 948\r
 AUTH OAUTHBEARER\r
-dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 AQ==\r
 </protocol>
 </verify>
index 9145d61e9e752d3e52d579d787f8475bfc1cf67b..345940077029dfc907f8a6d081e4c2b789869e58 100644 (file)
@@ -55,7 +55,7 @@ perl -e "print 'Test requires default test server host and port' if ( '%HOSTIP'
 # transfer and such a connection will not get a "QUIT"
 <protocol>
 EHLO 949\r
-AUTH OAUTHBEARER dXNlcj11c2VyAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
+AUTH OAUTHBEARER bixhPXVzZXIsAWhvc3Q9MTI3LjAuMC4xAXBvcnQ9OTAwNQFhdXRoPUJlYXJlciBtRl85LkI1Zi00LjFKcU0BAQ==\r
 AQ==\r
 </protocol>
 </verify>