url: check sasl additional parameters for connection reuse.

Also move static function safecmp() as non-static Curl_safecmp() since
its purpose is needed at several places.

Bug: https://curl.se/docs/CVE-2022-22576.html

CVE-2022-22576

Closes #8746
This commit is contained in:
Patrick Monnerat 2022-04-25 11:44:05 +02:00 committed by Daniel Stenberg
parent ff2f3e8367
commit 852aa5ad35
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
5 changed files with 31 additions and 16 deletions

View File

@ -131,6 +131,16 @@ void Curl_strntolower(char *dest, const char *src, size_t n)
} while(*src++ && --n);
}
/* Compare case-sensitive NUL-terminated strings, taking care of possible
* null pointers. Return true if arguments match.
*/
bool Curl_safecmp(char *a, char *b)
{
if(a && b)
return !strcmp(a, b);
return !a && !b;
}
/* --- public functions --- */
int curl_strequal(const char *first, const char *second)

View File

@ -49,4 +49,6 @@ char Curl_raw_toupper(char in);
void Curl_strntoupper(char *dest, const char *src, size_t n);
void Curl_strntolower(char *dest, const char *src, size_t n);
bool Curl_safecmp(char *a, char *b);
#endif /* HEADER_CURL_STRCASE_H */

View File

@ -781,6 +781,7 @@ static void conn_free(struct connectdata *conn)
Curl_safefree(conn->passwd);
Curl_safefree(conn->sasl_authzid);
Curl_safefree(conn->options);
Curl_safefree(conn->oauth_bearer);
Curl_dyn_free(&conn->trailer);
Curl_safefree(conn->host.rawalloc); /* host name buffer */
Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */
@ -1342,7 +1343,9 @@ ConnectionExists(struct Curl_easy *data,
/* This protocol requires credentials per connection,
so verify that we're using the same name and password as well */
if(strcmp(needle->user, check->user) ||
strcmp(needle->passwd, check->passwd)) {
strcmp(needle->passwd, check->passwd) ||
!Curl_safecmp(needle->sasl_authzid, check->sasl_authzid) ||
!Curl_safecmp(needle->oauth_bearer, check->oauth_bearer)) {
/* one of them was different */
continue;
}
@ -3637,6 +3640,14 @@ static CURLcode create_conn(struct Curl_easy *data,
}
}
if(data->set.str[STRING_BEARER]) {
conn->oauth_bearer = strdup(data->set.str[STRING_BEARER]);
if(!conn->oauth_bearer) {
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]);

View File

@ -984,6 +984,7 @@ struct connectdata {
char *passwd; /* password string, allocated */
char *options; /* options string, allocated */
char *sasl_authzid; /* authorization identity string, allocated */
char *oauth_bearer; /* OAUTH2 bearer, allocated */
unsigned char httpversion; /* the HTTP version*10 reported by the server */
struct curltime now; /* "current" time */
struct curltime created; /* creation time */

View File

@ -125,15 +125,6 @@ static bool blobcmp(struct curl_blob *first, struct curl_blob *second)
return !memcmp(first->data, second->data, first->len); /* same data */
}
static bool safecmp(char *a, char *b)
{
if(a && b)
return !strcmp(a, b);
else if(!a && !b)
return TRUE; /* match */
return FALSE; /* no match */
}
bool
Curl_ssl_config_matches(struct ssl_primary_config *data,
@ -147,12 +138,12 @@ Curl_ssl_config_matches(struct ssl_primary_config *data,
blobcmp(data->cert_blob, needle->cert_blob) &&
blobcmp(data->ca_info_blob, needle->ca_info_blob) &&
blobcmp(data->issuercert_blob, needle->issuercert_blob) &&
safecmp(data->CApath, needle->CApath) &&
safecmp(data->CAfile, needle->CAfile) &&
safecmp(data->issuercert, needle->issuercert) &&
safecmp(data->clientcert, needle->clientcert) &&
safecmp(data->random_file, needle->random_file) &&
safecmp(data->egdsocket, needle->egdsocket) &&
Curl_safecmp(data->CApath, needle->CApath) &&
Curl_safecmp(data->CAfile, needle->CAfile) &&
Curl_safecmp(data->issuercert, needle->issuercert) &&
Curl_safecmp(data->clientcert, needle->clientcert) &&
Curl_safecmp(data->random_file, needle->random_file) &&
Curl_safecmp(data->egdsocket, needle->egdsocket) &&
Curl_safe_strcasecompare(data->cipher_list, needle->cipher_list) &&
Curl_safe_strcasecompare(data->cipher_list13, needle->cipher_list13) &&
Curl_safe_strcasecompare(data->curves, needle->curves) &&