|
|
34bc20 |
From 295124c256ed25f097192cfa9a67e460f7bb587f Mon Sep 17 00:00:00 2001
|
|
|
34bc20 |
From: nao <naost3rn@gmail.com>
|
|
|
34bc20 |
Date: Tue, 21 Jan 2020 10:30:37 +0100
|
|
|
34bc20 |
Subject: [PATCH 1/2] http: move "oauth_bearer" from connectdata to Curl_easy
|
|
|
34bc20 |
|
|
|
34bc20 |
Fixes the bug where oauth_bearer gets deallocated when we re-use a
|
|
|
34bc20 |
connection.
|
|
|
34bc20 |
|
|
|
34bc20 |
Closes #4824
|
|
|
34bc20 |
|
|
|
34bc20 |
Upstream-commit: dea17b519dc1d83265ca6aa9a484a2cf242db3b9
|
|
|
34bc20 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
34bc20 |
---
|
|
|
34bc20 |
lib/curl_sasl.c | 14 ++++++++------
|
|
|
34bc20 |
lib/http.c | 12 +++++-------
|
|
|
34bc20 |
lib/url.c | 9 ---------
|
|
|
34bc20 |
lib/urldata.h | 2 --
|
|
|
34bc20 |
4 files changed, 13 insertions(+), 24 deletions(-)
|
|
|
34bc20 |
|
|
|
34bc20 |
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
|
|
|
34bc20 |
index 354bc54..c767bef 100644
|
|
|
34bc20 |
--- a/lib/curl_sasl.c
|
|
|
34bc20 |
+++ b/lib/curl_sasl.c
|
|
|
34bc20 |
@@ -269,6 +269,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
|
|
34bc20 |
data->set.str[STRING_SERVICE_NAME] :
|
|
|
34bc20 |
sasl->params->service;
|
|
|
34bc20 |
#endif
|
|
|
34bc20 |
+ const char *oauth_bearer = data->set.str[STRING_BEARER];
|
|
|
34bc20 |
|
|
|
34bc20 |
sasl->force_ir = force_ir; /* Latch for future use */
|
|
|
34bc20 |
sasl->authused = 0; /* No mechanism used yet */
|
|
|
34bc20 |
@@ -339,7 +340,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
|
|
34bc20 |
}
|
|
|
34bc20 |
else
|
|
|
34bc20 |
#endif
|
|
|
34bc20 |
- if((enabledmechs & SASL_MECH_OAUTHBEARER) && conn->oauth_bearer) {
|
|
|
34bc20 |
+ if((enabledmechs & SASL_MECH_OAUTHBEARER) && oauth_bearer) {
|
|
|
34bc20 |
mech = SASL_MECH_STRING_OAUTHBEARER;
|
|
|
34bc20 |
state1 = SASL_OAUTH2;
|
|
|
34bc20 |
state2 = SASL_OAUTH2_RESP;
|
|
|
34bc20 |
@@ -349,10 +350,10 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
|
|
34bc20 |
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
|
|
|
34bc20 |
hostname,
|
|
|
34bc20 |
port,
|
|
|
34bc20 |
- conn->oauth_bearer,
|
|
|
34bc20 |
+ oauth_bearer,
|
|
|
34bc20 |
&resp, &len;;
|
|
|
34bc20 |
}
|
|
|
34bc20 |
- else if((enabledmechs & SASL_MECH_XOAUTH2) && conn->oauth_bearer) {
|
|
|
34bc20 |
+ else if((enabledmechs & SASL_MECH_XOAUTH2) && oauth_bearer) {
|
|
|
34bc20 |
mech = SASL_MECH_STRING_XOAUTH2;
|
|
|
34bc20 |
state1 = SASL_OAUTH2;
|
|
|
34bc20 |
sasl->authused = SASL_MECH_XOAUTH2;
|
|
|
34bc20 |
@@ -360,7 +361,7 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn,
|
|
|
34bc20 |
if(force_ir || data->set.sasl_ir)
|
|
|
34bc20 |
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
|
|
|
34bc20 |
NULL, 0,
|
|
|
34bc20 |
- conn->oauth_bearer,
|
|
|
34bc20 |
+ oauth_bearer,
|
|
|
34bc20 |
&resp, &len;;
|
|
|
34bc20 |
}
|
|
|
34bc20 |
else if(enabledmechs & SASL_MECH_PLAIN) {
|
|
|
34bc20 |
@@ -429,6 +430,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
|
|
34bc20 |
char *serverdata;
|
|
|
34bc20 |
#endif
|
|
|
34bc20 |
size_t len = 0;
|
|
|
34bc20 |
+ const char *oauth_bearer = data->set.str[STRING_BEARER];
|
|
|
34bc20 |
|
|
|
34bc20 |
*progress = SASL_INPROGRESS;
|
|
|
34bc20 |
|
|
|
34bc20 |
@@ -556,7 +558,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
|
|
34bc20 |
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
|
|
|
34bc20 |
hostname,
|
|
|
34bc20 |
port,
|
|
|
34bc20 |
- conn->oauth_bearer,
|
|
|
34bc20 |
+ oauth_bearer,
|
|
|
34bc20 |
&resp, &len;;
|
|
|
34bc20 |
|
|
|
34bc20 |
/* Failures maybe sent by the server as continuations for OAUTHBEARER */
|
|
|
34bc20 |
@@ -565,7 +567,7 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn,
|
|
|
34bc20 |
else
|
|
|
34bc20 |
result = Curl_auth_create_oauth_bearer_message(data, conn->user,
|
|
|
34bc20 |
NULL, 0,
|
|
|
34bc20 |
- conn->oauth_bearer,
|
|
|
34bc20 |
+ oauth_bearer,
|
|
|
34bc20 |
&resp, &len;;
|
|
|
34bc20 |
break;
|
|
|
34bc20 |
|
|
|
34bc20 |
diff --git a/lib/http.c b/lib/http.c
|
|
|
34bc20 |
index 26eb52d..bf19077 100644
|
|
|
34bc20 |
--- a/lib/http.c
|
|
|
34bc20 |
+++ b/lib/http.c
|
|
|
34bc20 |
@@ -326,7 +326,7 @@ static CURLcode http_output_bearer(struct connectdata *conn)
|
|
|
34bc20 |
userp = &conn->allocptr.userpwd;
|
|
|
34bc20 |
free(*userp);
|
|
|
34bc20 |
*userp = aprintf("Authorization: Bearer %s\r\n",
|
|
|
34bc20 |
- conn->oauth_bearer);
|
|
|
34bc20 |
+ conn->data->set.str[STRING_BEARER]);
|
|
|
34bc20 |
|
|
|
34bc20 |
if(!*userp) {
|
|
|
34bc20 |
result = CURLE_OUT_OF_MEMORY;
|
|
|
34bc20 |
@@ -510,7 +510,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
|
|
34bc20 |
CURLcode result = CURLE_OK;
|
|
|
34bc20 |
unsigned long authmask = ~0ul;
|
|
|
34bc20 |
|
|
|
34bc20 |
- if(!conn->oauth_bearer)
|
|
|
34bc20 |
+ if(!data->set.str[STRING_BEARER])
|
|
|
34bc20 |
authmask &= (unsigned long)~CURLAUTH_BEARER;
|
|
|
34bc20 |
|
|
|
34bc20 |
if(100 <= data->req.httpcode && 199 >= data->req.httpcode)
|
|
|
34bc20 |
@@ -520,7 +520,7 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
|
|
|
34bc20 |
if(data->state.authproblem)
|
|
|
34bc20 |
return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
|
|
|
34bc20 |
|
|
|
34bc20 |
- if((conn->bits.user_passwd || conn->oauth_bearer) &&
|
|
|
34bc20 |
+ if((conn->bits.user_passwd || data->set.str[STRING_BEARER]) &&
|
|
|
34bc20 |
((data->req.httpcode == 401) ||
|
|
|
34bc20 |
(conn->bits.authneg && data->req.httpcode < 300))) {
|
|
|
34bc20 |
pickhost = pickoneauth(&data->state.authhost, authmask);
|
|
|
34bc20 |
@@ -590,9 +590,7 @@ output_auth_headers(struct connectdata *conn,
|
|
|
34bc20 |
{
|
|
|
34bc20 |
const char *auth = NULL;
|
|
|
34bc20 |
CURLcode result = CURLE_OK;
|
|
|
34bc20 |
-#if !defined(CURL_DISABLE_VERBOSE_STRINGS) || defined(USE_SPNEGO)
|
|
|
34bc20 |
struct Curl_easy *data = conn->data;
|
|
|
34bc20 |
-#endif
|
|
|
34bc20 |
#ifdef USE_SPNEGO
|
|
|
34bc20 |
struct negotiatedata *negdata = proxy ?
|
|
|
34bc20 |
&data->state.proxyneg : &data->state.negotiate;
|
|
|
34bc20 |
@@ -664,7 +662,7 @@ output_auth_headers(struct connectdata *conn,
|
|
|
34bc20 |
}
|
|
|
34bc20 |
if(authstatus->picked == CURLAUTH_BEARER) {
|
|
|
34bc20 |
/* Bearer */
|
|
|
34bc20 |
- if((!proxy && conn->oauth_bearer &&
|
|
|
34bc20 |
+ if((!proxy && data->set.str[STRING_BEARER] &&
|
|
|
34bc20 |
!Curl_checkheaders(conn, "Authorization:"))) {
|
|
|
34bc20 |
auth = "Bearer";
|
|
|
34bc20 |
result = http_output_bearer(conn);
|
|
|
34bc20 |
@@ -722,7 +720,7 @@ Curl_http_output_auth(struct connectdata *conn,
|
|
|
34bc20 |
authproxy = &data->state.authproxy;
|
|
|
34bc20 |
|
|
|
34bc20 |
if((conn->bits.httpproxy && conn->bits.proxy_user_passwd) ||
|
|
|
34bc20 |
- conn->bits.user_passwd || conn->oauth_bearer)
|
|
|
34bc20 |
+ conn->bits.user_passwd || data->set.str[STRING_BEARER])
|
|
|
34bc20 |
/* continue please */;
|
|
|
34bc20 |
else {
|
|
|
34bc20 |
authhost->done = TRUE;
|
|
|
34bc20 |
diff --git a/lib/url.c b/lib/url.c
|
|
|
34bc20 |
index 4803653..fca0855 100644
|
|
|
34bc20 |
--- a/lib/url.c
|
|
|
34bc20 |
+++ b/lib/url.c
|
|
|
34bc20 |
@@ -686,7 +686,6 @@ static void conn_free(struct connectdata *conn)
|
|
|
34bc20 |
|
|
|
34bc20 |
Curl_safefree(conn->user);
|
|
|
34bc20 |
Curl_safefree(conn->passwd);
|
|
|
34bc20 |
- Curl_safefree(conn->oauth_bearer);
|
|
|
34bc20 |
Curl_safefree(conn->options);
|
|
|
34bc20 |
Curl_safefree(conn->http_proxy.user);
|
|
|
34bc20 |
Curl_safefree(conn->socks_proxy.user);
|
|
|
34bc20 |
@@ -4161,14 +4160,6 @@ static CURLcode create_conn(struct Curl_easy *data,
|
|
|
34bc20 |
}
|
|
|
34bc20 |
}
|
|
|
34bc20 |
|
|
|
34bc20 |
- if(data->set.str[STRING_BEARER]) {
|
|
|
34bc20 |
- conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
|
|
|
34bc20 |
- if(!conn->oauth_bearer) {
|
|
|
34bc20 |
- result = CURLE_OUT_OF_MEMORY;
|
|
|
34bc20 |
- goto out;
|
|
|
34bc20 |
- }
|
|
|
34bc20 |
- }
|
|
|
34bc20 |
-
|
|
|
34bc20 |
#ifdef USE_UNIX_SOCKETS
|
|
|
34bc20 |
if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
|
|
|
34bc20 |
conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
|
|
|
34bc20 |
diff --git a/lib/urldata.h b/lib/urldata.h
|
|
|
34bc20 |
index 72a36fb..73a185c 100644
|
|
|
34bc20 |
--- a/lib/urldata.h
|
|
|
34bc20 |
+++ b/lib/urldata.h
|
|
|
34bc20 |
@@ -850,8 +850,6 @@ struct connectdata {
|
|
|
34bc20 |
char *passwd; /* password string, allocated */
|
|
|
34bc20 |
char *options; /* options string, allocated */
|
|
|
34bc20 |
|
|
|
34bc20 |
- char *oauth_bearer; /* bearer token for OAuth 2.0, allocated */
|
|
|
34bc20 |
-
|
|
|
34bc20 |
int httpversion; /* the HTTP version*10 reported by the server */
|
|
|
34bc20 |
int rtspversion; /* the RTSP version*10 reported by the server */
|
|
|
34bc20 |
|
|
|
34bc20 |
--
|
|
|
34bc20 |
2.34.1
|
|
|
34bc20 |
|
|
|
34bc20 |
|
|
|
34bc20 |
From 85d1103c2fc0c9b1bdfae470dbafd45758e1c2f0 Mon Sep 17 00:00:00 2001
|
|
|
34bc20 |
From: Patrick Monnerat <patrick@monnerat.net>
|
|
|
34bc20 |
Date: Mon, 25 Apr 2022 11:44:05 +0200
|
|
|
34bc20 |
Subject: [PATCH 2/2] url: check sasl additional parameters for connection
|
|
|
34bc20 |
reuse.
|
|
|
34bc20 |
|
|
|
34bc20 |
Also move static function safecmp() as non-static Curl_safecmp() since
|
|
|
34bc20 |
its purpose is needed at several places.
|
|
|
34bc20 |
|
|
|
34bc20 |
Bug: https://curl.se/docs/CVE-2022-22576.html
|
|
|
34bc20 |
|
|
|
34bc20 |
CVE-2022-22576
|
|
|
34bc20 |
|
|
|
34bc20 |
Closes #8746
|
|
|
34bc20 |
|
|
|
34bc20 |
Upstream-commit: 852aa5ad351ea53e5f01d2f44b5b4370c2bf5425
|
|
|
34bc20 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
34bc20 |
---
|
|
|
34bc20 |
lib/strcase.c | 10 ++++++++++
|
|
|
34bc20 |
lib/strcase.h | 2 ++
|
|
|
34bc20 |
lib/url.c | 12 +++++++++++-
|
|
|
34bc20 |
lib/urldata.h | 2 ++
|
|
|
34bc20 |
lib/vtls/vtls.c | 19 +++++--------------
|
|
|
34bc20 |
5 files changed, 30 insertions(+), 15 deletions(-)
|
|
|
34bc20 |
|
|
|
34bc20 |
diff --git a/lib/strcase.c b/lib/strcase.c
|
|
|
34bc20 |
index dd46ca1..692a3f1 100644
|
|
|
34bc20 |
--- a/lib/strcase.c
|
|
|
34bc20 |
+++ b/lib/strcase.c
|
|
|
34bc20 |
@@ -165,6 +165,16 @@ void Curl_strntoupper(char *dest, const char *src, size_t n)
|
|
|
34bc20 |
} while(*src++ && --n);
|
|
|
34bc20 |
}
|
|
|
34bc20 |
|
|
|
34bc20 |
+/* Compare case-sensitive NUL-terminated strings, taking care of possible
|
|
|
34bc20 |
+ * null pointers. Return true if arguments match.
|
|
|
34bc20 |
+ */
|
|
|
34bc20 |
+bool Curl_safecmp(char *a, char *b)
|
|
|
34bc20 |
+{
|
|
|
34bc20 |
+ if(a && b)
|
|
|
34bc20 |
+ return !strcmp(a, b);
|
|
|
34bc20 |
+ return !a && !b;
|
|
|
34bc20 |
+}
|
|
|
34bc20 |
+
|
|
|
34bc20 |
/* --- public functions --- */
|
|
|
34bc20 |
|
|
|
34bc20 |
int curl_strequal(const char *first, const char *second)
|
|
|
34bc20 |
diff --git a/lib/strcase.h b/lib/strcase.h
|
|
|
34bc20 |
index b628656..382b80a 100644
|
|
|
34bc20 |
--- a/lib/strcase.h
|
|
|
34bc20 |
+++ b/lib/strcase.h
|
|
|
34bc20 |
@@ -47,4 +47,6 @@ char Curl_raw_toupper(char in);
|
|
|
34bc20 |
|
|
|
34bc20 |
void Curl_strntoupper(char *dest, const char *src, size_t n);
|
|
|
34bc20 |
|
|
|
34bc20 |
+bool Curl_safecmp(char *a, char *b);
|
|
|
34bc20 |
+
|
|
|
34bc20 |
#endif /* HEADER_CURL_STRCASE_H */
|
|
|
34bc20 |
diff --git a/lib/url.c b/lib/url.c
|
|
|
34bc20 |
index adef2cd..94e3406 100644
|
|
|
34bc20 |
--- a/lib/url.c
|
|
|
34bc20 |
+++ b/lib/url.c
|
|
|
34bc20 |
@@ -701,6 +701,7 @@ static void conn_free(struct connectdata *conn)
|
|
|
34bc20 |
Curl_safefree(conn->allocptr.host);
|
|
|
34bc20 |
Curl_safefree(conn->allocptr.cookiehost);
|
|
|
34bc20 |
Curl_safefree(conn->allocptr.rtsp_transport);
|
|
|
34bc20 |
+ Curl_safefree(conn->oauth_bearer);
|
|
|
34bc20 |
Curl_safefree(conn->trailer);
|
|
|
34bc20 |
Curl_safefree(conn->host.rawalloc); /* host name buffer */
|
|
|
34bc20 |
Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
|
|
|
34bc20 |
@@ -1291,7 +1292,8 @@ ConnectionExists(struct Curl_easy *data,
|
|
|
34bc20 |
/* This protocol requires credentials per connection,
|
|
|
34bc20 |
so verify that we're using the same name and password as well */
|
|
|
34bc20 |
if(strcmp(needle->user, check->user) ||
|
|
|
34bc20 |
- strcmp(needle->passwd, check->passwd)) {
|
|
|
34bc20 |
+ strcmp(needle->passwd, check->passwd) ||
|
|
|
34bc20 |
+ !Curl_safecmp(needle->oauth_bearer, check->oauth_bearer)) {
|
|
|
34bc20 |
/* one of them was different */
|
|
|
34bc20 |
continue;
|
|
|
34bc20 |
}
|
|
|
34bc20 |
@@ -4160,6 +4162,14 @@ static CURLcode create_conn(struct Curl_easy *data,
|
|
|
34bc20 |
}
|
|
|
34bc20 |
}
|
|
|
34bc20 |
|
|
|
34bc20 |
+ if(data->set.str[STRING_BEARER]) {
|
|
|
34bc20 |
+ conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
|
|
|
34bc20 |
+ if(!conn->oauth_bearer) {
|
|
|
34bc20 |
+ result = CURLE_OUT_OF_MEMORY;
|
|
|
34bc20 |
+ goto out;
|
|
|
34bc20 |
+ }
|
|
|
34bc20 |
+ }
|
|
|
34bc20 |
+
|
|
|
34bc20 |
#ifdef USE_UNIX_SOCKETS
|
|
|
34bc20 |
if(data->set.str[STRING_UNIX_SOCKET_PATH]) {
|
|
|
34bc20 |
conn->unix_domain_socket = strdup(data->set.str[STRING_UNIX_SOCKET_PATH]);
|
|
|
34bc20 |
diff --git a/lib/urldata.h b/lib/urldata.h
|
|
|
34bc20 |
index cc8a600..03da59a 100644
|
|
|
34bc20 |
--- a/lib/urldata.h
|
|
|
34bc20 |
+++ b/lib/urldata.h
|
|
|
34bc20 |
@@ -850,6 +850,8 @@ struct connectdata {
|
|
|
34bc20 |
char *passwd; /* password string, allocated */
|
|
|
34bc20 |
char *options; /* options string, allocated */
|
|
|
34bc20 |
|
|
|
34bc20 |
+ char *oauth_bearer; /* OAUTH2 bearer, allocated */
|
|
|
34bc20 |
+
|
|
|
34bc20 |
int httpversion; /* the HTTP version*10 reported by the server */
|
|
|
34bc20 |
int rtspversion; /* the RTSP version*10 reported by the server */
|
|
|
34bc20 |
|
|
|
34bc20 |
diff --git a/lib/vtls/vtls.c b/lib/vtls/vtls.c
|
|
|
34bc20 |
index 03b85ba..a40ac06 100644
|
|
|
34bc20 |
--- a/lib/vtls/vtls.c
|
|
|
34bc20 |
+++ b/lib/vtls/vtls.c
|
|
|
34bc20 |
@@ -82,15 +82,6 @@
|
|
|
34bc20 |
else \
|
|
|
34bc20 |
dest->var = NULL;
|
|
|
34bc20 |
|
|
|
34bc20 |
-static bool safecmp(char *a, char *b)
|
|
|
34bc20 |
-{
|
|
|
34bc20 |
- if(a && b)
|
|
|
34bc20 |
- return !strcmp(a, b);
|
|
|
34bc20 |
- else if(!a && !b)
|
|
|
34bc20 |
- return TRUE; /* match */
|
|
|
34bc20 |
- return FALSE; /* no match */
|
|
|
34bc20 |
-}
|
|
|
34bc20 |
-
|
|
|
34bc20 |
bool
|
|
|
34bc20 |
Curl_ssl_config_matches(struct ssl_primary_config* data,
|
|
|
34bc20 |
struct ssl_primary_config* needle)
|
|
|
34bc20 |
@@ -100,11 +91,11 @@ Curl_ssl_config_matches(struct ssl_primary_config* data,
|
|
|
34bc20 |
(data->verifypeer == needle->verifypeer) &&
|
|
|
34bc20 |
(data->verifyhost == needle->verifyhost) &&
|
|
|
34bc20 |
(data->verifystatus == needle->verifystatus) &&
|
|
|
34bc20 |
- safecmp(data->CApath, needle->CApath) &&
|
|
|
34bc20 |
- safecmp(data->CAfile, needle->CAfile) &&
|
|
|
34bc20 |
- safecmp(data->clientcert, needle->clientcert) &&
|
|
|
34bc20 |
- safecmp(data->random_file, needle->random_file) &&
|
|
|
34bc20 |
- safecmp(data->egdsocket, needle->egdsocket) &&
|
|
|
34bc20 |
+ Curl_safecmp(data->CApath, needle->CApath) &&
|
|
|
34bc20 |
+ Curl_safecmp(data->CAfile, needle->CAfile) &&
|
|
|
34bc20 |
+ Curl_safecmp(data->clientcert, needle->clientcert) &&
|
|
|
34bc20 |
+ Curl_safecmp(data->random_file, needle->random_file) &&
|
|
|
34bc20 |
+ Curl_safecmp(data->egdsocket, needle->egdsocket) &&
|
|
|
34bc20 |
Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
|
|
|
34bc20 |
Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13))
|
|
|
34bc20 |
return TRUE;
|
|
|
34bc20 |
--
|
|
|
34bc20 |
2.34.1
|
|
|
34bc20 |
|