mirror of
https://github.com/moparisthebest/curl
synced 2024-12-23 16:48:49 -05:00
parent
49fe65ccd8
commit
239a7061f8
@ -56,6 +56,10 @@ defined in RFC2617 and is a more secure way to do authentication over public
|
|||||||
networks than the regular old-fashioned Basic method. The IE flavor is simply
|
networks than the regular old-fashioned Basic method. The IE flavor is simply
|
||||||
that libcurl will use a special "quirk" that IE is known to have used before
|
that libcurl will use a special "quirk" that IE is known to have used before
|
||||||
version 7 and that some servers require the client to use.
|
version 7 and that some servers require the client to use.
|
||||||
|
.IP CURLAUTH_BEARER
|
||||||
|
HTTP Bearer token authentication, used primarily in OAuth 2.0 protocol.
|
||||||
|
|
||||||
|
You can set the Bearer token to use with \fICURLOPT_XOAUTH2_BEARER(3)\fP.
|
||||||
.IP CURLAUTH_NEGOTIATE
|
.IP CURLAUTH_NEGOTIATE
|
||||||
HTTP Negotiate (SPNEGO) authentication. Negotiate authentication is defined
|
HTTP Negotiate (SPNEGO) authentication. Negotiate authentication is defined
|
||||||
in RFC 4559 and is the most secure way to perform authentication over HTTP.
|
in RFC 4559 and is the most secure way to perform authentication over HTTP.
|
||||||
|
@ -29,11 +29,11 @@ CURLOPT_XOAUTH2_BEARER \- specify OAuth 2.0 access token
|
|||||||
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_XOAUTH2_BEARER, char *token);
|
CURLcode curl_easy_setopt(CURL *handle, CURLOPT_XOAUTH2_BEARER, char *token);
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
Pass a char * as parameter, which should point to the zero terminated OAuth
|
Pass a char * as parameter, which should point to the zero terminated OAuth
|
||||||
2.0 Bearer Access Token for use with IMAP, POP3 and SMTP servers that support
|
2.0 Bearer Access Token for use with HTTP, IMAP, POP3 and SMTP servers
|
||||||
the OAuth 2.0 Authorization Framework.
|
that support the OAuth 2.0 Authorization Framework.
|
||||||
|
|
||||||
Note: The user name used to generate the Bearer Token should be supplied via
|
Note: For IMAP, POP3 and SMTP, the user name used to generate the Bearer Token
|
||||||
the \fICURLOPT_USERNAME(3)\fP option.
|
should be supplied via the \fICURLOPT_USERNAME(3)\fP option.
|
||||||
|
|
||||||
The application does not have to keep the string around after setting this
|
The application does not have to keep the string around after setting this
|
||||||
option.
|
option.
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
CURLAUTH_ANY 7.10.6
|
CURLAUTH_ANY 7.10.6
|
||||||
CURLAUTH_ANYSAFE 7.10.6
|
CURLAUTH_ANYSAFE 7.10.6
|
||||||
CURLAUTH_BASIC 7.10.6
|
CURLAUTH_BASIC 7.10.6
|
||||||
|
CURLAUTH_BEARER 7.61.0
|
||||||
CURLAUTH_DIGEST 7.10.6
|
CURLAUTH_DIGEST 7.10.6
|
||||||
CURLAUTH_DIGEST_IE 7.19.3
|
CURLAUTH_DIGEST_IE 7.19.3
|
||||||
CURLAUTH_GSSAPI 7.55.0
|
CURLAUTH_GSSAPI 7.55.0
|
||||||
|
@ -691,6 +691,7 @@ typedef enum {
|
|||||||
* CURLAUTH_NTLM - HTTP NTLM authentication
|
* CURLAUTH_NTLM - HTTP NTLM authentication
|
||||||
* CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour
|
* CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour
|
||||||
* CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper
|
* CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper
|
||||||
|
* CURLAUTH_BEARER - HTTP Bearer token authentication
|
||||||
* CURLAUTH_ONLY - Use together with a single other type to force no
|
* CURLAUTH_ONLY - Use together with a single other type to force no
|
||||||
* authentication or just that single type
|
* authentication or just that single type
|
||||||
* CURLAUTH_ANY - All fine types set
|
* CURLAUTH_ANY - All fine types set
|
||||||
@ -708,6 +709,7 @@ typedef enum {
|
|||||||
#define CURLAUTH_NTLM (((unsigned long)1)<<3)
|
#define CURLAUTH_NTLM (((unsigned long)1)<<3)
|
||||||
#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
|
#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4)
|
||||||
#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
|
#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5)
|
||||||
|
#define CURLAUTH_BEARER (((unsigned long)1)<<6)
|
||||||
#define CURLAUTH_ONLY (((unsigned long)1)<<31)
|
#define CURLAUTH_ONLY (((unsigned long)1)<<31)
|
||||||
#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
|
#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE)
|
||||||
#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
|
#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))
|
||||||
|
55
lib/http.c
55
lib/http.c
@ -310,6 +310,31 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* http_output_bearer() sets up an Authorization: header
|
||||||
|
* for HTTP Bearer authentication.
|
||||||
|
*
|
||||||
|
* Returns CURLcode.
|
||||||
|
*/
|
||||||
|
static CURLcode http_output_bearer(struct connectdata *conn)
|
||||||
|
{
|
||||||
|
char **userp;
|
||||||
|
CURLcode result = CURLE_OK;
|
||||||
|
|
||||||
|
userp = &conn->allocptr.userpwd;
|
||||||
|
free(*userp);
|
||||||
|
*userp = aprintf("Authorization: Bearer %s\r\n",
|
||||||
|
conn->oauth_bearer);
|
||||||
|
|
||||||
|
if(!*userp) {
|
||||||
|
result = CURLE_OUT_OF_MEMORY;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/* pickoneauth() selects the most favourable authentication method from the
|
/* pickoneauth() selects the most favourable authentication method from the
|
||||||
* ones available and the ones we want.
|
* ones available and the ones we want.
|
||||||
*
|
*
|
||||||
@ -326,6 +351,8 @@ static bool pickoneauth(struct auth *pick)
|
|||||||
of preference in case of the existence of multiple accepted types. */
|
of preference in case of the existence of multiple accepted types. */
|
||||||
if(avail & CURLAUTH_NEGOTIATE)
|
if(avail & CURLAUTH_NEGOTIATE)
|
||||||
pick->picked = CURLAUTH_NEGOTIATE;
|
pick->picked = CURLAUTH_NEGOTIATE;
|
||||||
|
else if(avail & CURLAUTH_BEARER)
|
||||||
|
pick->picked = CURLAUTH_BEARER;
|
||||||
else if(avail & CURLAUTH_DIGEST)
|
else if(avail & CURLAUTH_DIGEST)
|
||||||
pick->picked = CURLAUTH_DIGEST;
|
pick->picked = CURLAUTH_DIGEST;
|
||||||
else if(avail & CURLAUTH_NTLM)
|
else if(avail & CURLAUTH_NTLM)
|
||||||
@ -628,6 +655,20 @@ output_auth_headers(struct connectdata *conn,
|
|||||||
functions work that way */
|
functions work that way */
|
||||||
authstatus->done = TRUE;
|
authstatus->done = TRUE;
|
||||||
}
|
}
|
||||||
|
if(authstatus->picked == CURLAUTH_BEARER) {
|
||||||
|
/* Bearer */
|
||||||
|
if((!proxy && conn->oauth_bearer &&
|
||||||
|
!Curl_checkheaders(conn, "Authorization:"))) {
|
||||||
|
auth = "Bearer";
|
||||||
|
result = http_output_bearer(conn);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOTE: this function should set 'done' TRUE, as the other auth
|
||||||
|
functions work that way */
|
||||||
|
authstatus->done = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if(auth) {
|
if(auth) {
|
||||||
infof(data, "%s auth using %s with user '%s'\n",
|
infof(data, "%s auth using %s with user '%s'\n",
|
||||||
@ -674,7 +715,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
|||||||
authproxy = &data->state.authproxy;
|
authproxy = &data->state.authproxy;
|
||||||
|
|
||||||
if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
|
if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
|
||||||
conn->bits.user_passwd)
|
conn->bits.user_passwd || conn->oauth_bearer)
|
||||||
/* continue please */;
|
/* continue please */;
|
||||||
else {
|
else {
|
||||||
authhost->done = TRUE;
|
authhost->done = TRUE;
|
||||||
@ -883,6 +924,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
|||||||
data->state.authproblem = TRUE;
|
data->state.authproblem = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if(checkprefix("Bearer", auth)) {
|
||||||
|
*availp |= CURLAUTH_BEARER;
|
||||||
|
authp->avail |= CURLAUTH_BEARER;
|
||||||
|
if(authp->picked == CURLAUTH_BEARER) {
|
||||||
|
/* We asked for Bearer authentication but got a 40X back
|
||||||
|
anyway, which basically means our token isn't valid. */
|
||||||
|
authp->avail = CURLAUTH_NONE;
|
||||||
|
infof(data, "Authentication problem. Ignoring this.\n");
|
||||||
|
data->state.authproblem = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* there may be multiple methods on one line, so keep reading */
|
/* there may be multiple methods on one line, so keep reading */
|
||||||
while(*auth && *auth != ',') /* read up to the next comma */
|
while(*auth && *auth != ',') /* read up to the next comma */
|
||||||
|
@ -601,6 +601,7 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
|
|||||||
break;
|
break;
|
||||||
case 'B': /* OAuth 2.0 bearer token */
|
case 'B': /* OAuth 2.0 bearer token */
|
||||||
GetStr(&config->oauth_bearer, nextarg);
|
GetStr(&config->oauth_bearer, nextarg);
|
||||||
|
config->authtype |= CURLAUTH_BEARER;
|
||||||
break;
|
break;
|
||||||
case 'c': /* connect-timeout */
|
case 'c': /* connect-timeout */
|
||||||
err = str2udouble(&config->connecttimeout, nextarg,
|
err = str2udouble(&config->connecttimeout, nextarg,
|
||||||
|
@ -196,5 +196,6 @@ test2056 test2057 test2058 test2059 test2060 test2061 test2062 test2063 \
|
|||||||
test2064 test2065 test2066 test2067 test2068 test2069 \
|
test2064 test2065 test2066 test2067 test2068 test2069 \
|
||||||
\
|
\
|
||||||
test2070 test2071 test2072 test2073 \
|
test2070 test2071 test2072 test2073 \
|
||||||
|
test2074 \
|
||||||
\
|
\
|
||||||
test3000 test3001
|
test3000 test3001
|
||||||
|
57
tests/data/test2074
Normal file
57
tests/data/test2074
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<testcase>
|
||||||
|
<info>
|
||||||
|
<keywords>
|
||||||
|
HTTP
|
||||||
|
HTTP GET
|
||||||
|
AUTH OAUTHBEARER
|
||||||
|
</keywords>
|
||||||
|
</info>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Server-side
|
||||||
|
<reply>
|
||||||
|
<data>
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Date: Thu, 09 Nov 2010 14:49:00 GMT
|
||||||
|
Server: test-server/fake
|
||||||
|
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||||
|
ETag: "21025-dc7-39462498"
|
||||||
|
Accept-Ranges: bytes
|
||||||
|
Content-Length: 6
|
||||||
|
Connection: close
|
||||||
|
Content-Type: text/html
|
||||||
|
Funny-head: yesyes
|
||||||
|
|
||||||
|
-foo-
|
||||||
|
</data>
|
||||||
|
</reply>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Client-side
|
||||||
|
<client>
|
||||||
|
<server>
|
||||||
|
http
|
||||||
|
</server>
|
||||||
|
<name>
|
||||||
|
HTTP GET
|
||||||
|
</name>
|
||||||
|
<command>
|
||||||
|
http://%HOSTIP:%HTTPPORT/2074 --oauth2-bearer mF_9.B5f-4.1JqM
|
||||||
|
</command>
|
||||||
|
</client>
|
||||||
|
|
||||||
|
#
|
||||||
|
# Verify data after the test has been "shot"
|
||||||
|
<verify>
|
||||||
|
<strip>
|
||||||
|
^User-Agent:.*
|
||||||
|
</strip>
|
||||||
|
<protocol>
|
||||||
|
GET /2074 HTTP/1.1
|
||||||
|
Host: %HOSTIP:%HTTPPORT
|
||||||
|
Authorization: Bearer mF_9.B5f-4.1JqM
|
||||||
|
Accept: */*
|
||||||
|
|
||||||
|
</protocol>
|
||||||
|
</verify>
|
||||||
|
</testcase>
|
Loading…
Reference in New Issue
Block a user