File curl-CVE-2022-27782.patch of Package curl.37304
From c3f8e4e2b4a334697e7ce3168495f20a46b398bd Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 3 May 2022 09:31:11 +0200
Subject: [PATCH 1/2] tls: check more TLS details for connection reuse
CVE-2022-27782
Reported-by: Harry Sintonen
Bug: https://curl.se/docs/CVE-2022-27782.html
---
lib/setopt.c | 29 +++++++++++++++++------------
lib/url.c | 23 ++++++++++++++++-------
lib/urldata.h | 13 +++++++------
lib/vtls/gtls.c | 32 +++++++++++++++++---------------
lib/vtls/openssl.c | 10 +++++-----
lib/vtls/vtls.c | 20 ++++++++++++++++++++
6 files changed, 82 insertions(+), 45 deletions(-)
Index: curl-7.37.0/lib/url.c
===================================================================
--- curl-7.37.0.orig/lib/url.c
+++ curl-7.37.0/lib/url.c
@@ -150,6 +150,7 @@ static CURLcode parse_url_login(struct S
CURLcode parse_login_details(const char *login, const size_t len,
char **userptr, char **passwdptr,
char **optionsptr);
+static unsigned int get_protocol_family(unsigned int protocol);
/*
* Protocol table.
@@ -2133,6 +2134,7 @@ CURLcode Curl_setopt(struct SessionHandl
case CURLOPT_SSL_OPTIONS:
arg = va_arg(param, long);
+ data->set.ssl.ssl_options = (unsigned char)(arg & 0xff);
data->set.ssl_enable_beast = arg&CURLSSLOPT_ALLOW_BEAST?TRUE:FALSE;
break;
@@ -2922,6 +2924,17 @@ find_oldest_idle_connection_in_bundle(st
return conn_candidate;
}
+static bool ssh_config_matches(struct connectdata *one,
+ struct connectdata *two)
+{
+#ifdef USE_LIBSSH2
+ return (Curl_safecmp(one->proto.sshc.rsa, two->proto.sshc.rsa) &&
+ Curl_safecmp(one->proto.sshc.rsa_pub, two->proto.sshc.rsa_pub));
+#else
+ return TRUE;
+#endif
+}
+
/*
* Given one filled in connection struct (named needle), this function should
* detect if there already is one that has all the significant details
@@ -3062,6 +3075,12 @@ ConnectionExists(struct SessionHandle *d
}
}
+ if(get_protocol_family(needle->handler) == CURLPROTO_SFTP ||
+ get_protocol_family(needle->handler) == CURLPROTO_SCP ) {
+ if(!ssh_config_matches(needle, check))
+ continue;
+ }
+
if((needle->handler->flags&PROTOPT_SSL) !=
(check->handler->flags&PROTOPT_SSL))
/* don't do mixed SSL and non-SSL connections */
@@ -3673,6 +3692,8 @@ static struct connectdata *allocate_conn
conn->verifypeer = data->set.ssl.verifypeer;
conn->verifyhost = data->set.ssl.verifyhost;
+ conn->ssl_config.ssl_options = data->set.ssl.ssl_options;
+
conn->ip_version = data->set.ipver;
#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
@@ -6042,3 +6063,112 @@ CURLcode Curl_do_more(struct connectdata
return result;
}
+/*
+* get_protocol_family()
+*
+* This is used to return the protocol family for a given protocol.
+*
+* Parameters:
+*
+* protocol [in] - A single bit protocol identifier such as HTTP or HTTPS.
+*
+* Returns the family as a single bit protocol identifier.
+*/
+
+static unsigned int get_protocol_family(unsigned int protocol)
+{
+ unsigned int family;
+
+ switch(protocol) {
+ case CURLPROTO_HTTP:
+ case CURLPROTO_HTTPS:
+ family = CURLPROTO_HTTP;
+ break;
+
+ case CURLPROTO_FTP:
+ case CURLPROTO_FTPS:
+ family = CURLPROTO_FTP;
+ break;
+
+ case CURLPROTO_SCP:
+ family = CURLPROTO_SCP;
+ break;
+
+ case CURLPROTO_SFTP:
+ family = CURLPROTO_SFTP;
+ break;
+
+ case CURLPROTO_TELNET:
+ family = CURLPROTO_TELNET;
+ break;
+
+ case CURLPROTO_LDAP:
+ case CURLPROTO_LDAPS:
+ family = CURLPROTO_LDAP;
+ break;
+
+ case CURLPROTO_DICT:
+ family = CURLPROTO_DICT;
+ break;
+
+ case CURLPROTO_FILE:
+ family = CURLPROTO_FILE;
+ break;
+
+ case CURLPROTO_TFTP:
+ family = CURLPROTO_TFTP;
+ break;
+
+ case CURLPROTO_IMAP:
+ case CURLPROTO_IMAPS:
+ family = CURLPROTO_IMAP;
+ break;
+
+ case CURLPROTO_POP3:
+ case CURLPROTO_POP3S:
+ family = CURLPROTO_POP3;
+ break;
+
+ case CURLPROTO_SMTP:
+ case CURLPROTO_SMTPS:
+ family = CURLPROTO_SMTP;
+ break;
+
+ case CURLPROTO_RTSP:
+ family = CURLPROTO_RTSP;
+ break;
+
+ case CURLPROTO_RTMP:
+ case CURLPROTO_RTMPS:
+ family = CURLPROTO_RTMP;
+ break;
+
+ case CURLPROTO_RTMPT:
+ case CURLPROTO_RTMPTS:
+ family = CURLPROTO_RTMPT;
+ break;
+
+ case CURLPROTO_RTMPE:
+ family = CURLPROTO_RTMPE;
+ break;
+
+ case CURLPROTO_RTMPTE:
+ family = CURLPROTO_RTMPTE;
+ break;
+
+ case CURLPROTO_GOPHER:
+ family = CURLPROTO_GOPHER;
+ break;
+
+ // case CURLPROTO_SMB:
+ // case CURLPROTO_SMBS:
+ // family = CURLPROTO_SMB;
+ // break;
+
+ default:
+ family = 0;
+ break;
+ }
+
+ return family;
+}
\ No newline at end of file
Index: curl-7.37.0/lib/urldata.h
===================================================================
--- curl-7.37.0.orig/lib/urldata.h
+++ curl-7.37.0/lib/urldata.h
@@ -370,6 +370,7 @@ struct ssl_config_data {
char *CAfile; /* certificate to verify peer against */
const char *CRLfile; /* CRL to check certificate revocation */
const char *issuercert;/* optional issuer certificate filename */
+ unsigned char ssl_options; /* the CURLOPT_SSL_OPTIONS bitmask */
char *clientcert;
char *random_file; /* path to file containing "random" data */
char *egdsocket; /* path to file containing the EGD daemon socket */
Index: curl-7.37.0/lib/vtls/vtls.c
===================================================================
--- curl-7.37.0.orig/lib/vtls/vtls.c
+++ curl-7.37.0/lib/vtls/vtls.c
@@ -105,6 +105,7 @@ Curl_ssl_config_matches(struct ssl_confi
struct ssl_config_data* needle)
{
if((data->version == needle->version) &&
+ (data->ssl_options == needle->ssl_options) &&
(data->verifypeer == needle->verifypeer) &&
(data->verifyhost == needle->verifyhost) &&
Curl_safecmp(data->CApath, needle->CApath) &&
@@ -113,6 +114,12 @@ Curl_ssl_config_matches(struct ssl_confi
Curl_safecmp(data->clientcert, needle->clientcert) &&
Curl_safecmp(data->random_file, needle->random_file) &&
Curl_safecmp(data->egdsocket, needle->egdsocket) &&
+#ifdef USE_TLS_SRP
+ Curl_safecmp(data->username, needle->username) &&
+ Curl_safecmp(data->password, needle->password) &&
+ (data->authtype == needle->authtype) &&
+#endif
+ Curl_safecmp(data->CRLfile, needle->CRLfile) &&
safe_strequal(data->cipher_list, needle->cipher_list))
return TRUE;
@@ -127,6 +134,10 @@ Curl_clone_ssl_config(struct ssl_config_
dest->verifyhost = source->verifyhost;
dest->verifypeer = source->verifypeer;
dest->version = source->version;
+ dest->ssl_options = source->ssl_options;
+#ifdef USE_TLS_SRP
+ dest->authtype = source->authtype;
+#endif
if(source->CAfile) {
dest->CAfile = strdup(source->CAfile);
@@ -185,6 +196,32 @@ Curl_clone_ssl_config(struct ssl_config_
else
dest->clientcert = NULL;
+ if(source->CRLfile) {
+ dest->CRLfile = strdup(source->CRLfile);
+ if(!dest->CRLfile)
+ return FALSE;
+ }
+ else
+ dest->CRLfile = NULL;
+
+#ifdef USE_TLS_SRP
+ if(source->username) {
+ dest->username = strdup(source->username);
+ if(!dest->username)
+ return FALSE;
+ }
+ else
+ dest->username = NULL;
+
+ if(source->password) {
+ dest->password = strdup(source->password);
+ if(!dest->password)
+ return FALSE;
+ }
+ else
+ dest->password = NULL;
+#endif
+
return TRUE;
}
@@ -197,6 +234,12 @@ void Curl_free_ssl_config(struct ssl_con
Curl_safefree(sslc->egdsocket);
Curl_safefree(sslc->random_file);
Curl_safefree(sslc->clientcert);
+
+ Curl_safefree(sslc->CRLfile);
+#ifdef USE_TLS_SRP
+ Curl_safefree(sslc->username);
+ Curl_safefree(sslc->password);
+#endif
}
Index: curl-7.37.0/lib/ssh.h
===================================================================
--- curl-7.37.0.orig/lib/ssh.h
+++ curl-7.37.0/lib/ssh.h
@@ -108,8 +108,8 @@ struct ssh_conn {
const char *authlist; /* List of auth. methods, managed by libssh2 */
#ifdef USE_LIBSSH2
const char *passphrase; /* pass-phrase to use */
- char *rsa_pub; /* path name */
- char *rsa; /* path name */
+ char *rsa_pub; /* strdup'ed public key file */
+ char *rsa; /* strdup'ed private key file */
bool authed; /* the connection has been authenticated fine */
sshstate state; /* always use ssh.c:state() to change state! */
sshstate nextstate; /* the state to goto after stopping */