From 25b445e4796bcbf9f842de686a8c384b30f6c2a2 Mon Sep 17 00:00:00 2001 From: Stefan Eissing Date: Fri, 17 Jan 2025 11:57:00 +0100 Subject: [PATCH] TLS: check connection for SSL use, not handler Protocol handler option PROTOPT_SSL is used to setup a connection filters. Once that is done, used `Curl_conn_is_ssl()` to check if a connection uses SSL. There may be other reasons to add SSL to a connection, e.g. starttls. Closes #16034 --- lib/cf-socket.c | 2 +- lib/ftp.c | 2 +- lib/http.c | 8 ++++---- lib/http_negotiate.c | 3 ++- lib/imap.c | 2 +- lib/ldap.c | 3 ++- lib/openldap.c | 2 +- lib/pop3.c | 2 +- lib/smb.c | 2 +- lib/smtp.c | 2 +- lib/url.c | 12 ++++++------ 11 files changed, 21 insertions(+), 19 deletions(-) diff --git a/lib/cf-socket.c b/lib/cf-socket.c index cbbe80fd1c..edda34868d 100644 --- a/lib/cf-socket.c +++ b/lib/cf-socket.c @@ -1298,7 +1298,7 @@ static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data, rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen); #elif defined(MSG_FASTOPEN) /* old Linux */ - if(cf->conn->given->flags & PROTOPT_SSL) + if(Curl_conn_is_ssl(cf->conn, cf->sockindex)) rc = connect(ctx->sock, &ctx->addr.curl_sa_addr, ctx->addr.addrlen); else rc = 0; /* Do nothing */ diff --git a/lib/ftp.c b/lib/ftp.c index ffa9043eae..5afa67a2ea 100644 --- a/lib/ftp.c +++ b/lib/ftp.c @@ -3163,7 +3163,7 @@ static CURLcode ftp_connect(struct Curl_easy *data, PINGPONG_SETUP(pp, ftp_statemachine, ftp_endofresp); - if(conn->handler->flags & PROTOPT_SSL) { + if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) { /* BLOCKING */ result = Curl_conn_connect(data, FIRSTSOCKET, TRUE, done); if(result) diff --git a/lib/http.c b/lib/http.c index 59ee15b7f6..f3bacd290a 100644 --- a/lib/http.c +++ b/lib/http.c @@ -2526,7 +2526,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done) goto fail; } - if(!(conn->handler->flags&PROTOPT_SSL) && + if(!Curl_conn_is_ssl(conn, FIRSTSOCKET) && conn->httpversion < 20 && (data->state.httpwant == CURL_HTTP_VERSION_2)) { /* append HTTP2 upgrade magic stuff to the HTTP request if it is not done @@ -2670,7 +2670,7 @@ static CURLcode http_header(struct Curl_easy *data, case 'A': #ifndef CURL_DISABLE_ALTSVC v = (data->asi && - ((data->conn->handler->flags & PROTOPT_SSL) || + (Curl_conn_is_ssl(data->conn, FIRSTSOCKET) || #ifdef DEBUGBUILD /* allow debug builds to circumvent the HTTPS restriction */ getenv("CURL_ALTSVC_HTTP") @@ -2944,7 +2944,7 @@ static CURLcode http_header(struct Curl_easy *data, #ifndef CURL_DISABLE_HSTS /* If enabled, the header is incoming and this is over HTTPS */ v = (data->hsts && - ((conn->handler->flags & PROTOPT_SSL) || + (Curl_conn_is_ssl(conn, FIRSTSOCKET) || #ifdef DEBUGBUILD /* allow debug builds to circumvent the HTTPS restriction */ getenv("CURL_HSTS_HTTP") @@ -4168,7 +4168,7 @@ CURLcode Curl_http_req_to_h2(struct dynhds *h2_headers, infof(data, "set pseudo header %s to %s", HTTP_PSEUDO_SCHEME, scheme); } else { - scheme = (data->conn && data->conn->handler->flags & PROTOPT_SSL) ? + scheme = Curl_conn_is_ssl(data->conn, FIRSTSOCKET) ? "https" : "http"; } } diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c index 5d76bddf72..f031d0abc8 100644 --- a/lib/http_negotiate.c +++ b/lib/http_negotiate.c @@ -27,6 +27,7 @@ #if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) #include "urldata.h" +#include "cfilters.h" #include "sendf.h" #include "http_negotiate.h" #include "vauth/vauth.h" @@ -109,7 +110,7 @@ CURLcode Curl_input_negotiate(struct Curl_easy *data, struct connectdata *conn, #endif /* Check if the connection is using SSL and get the channel binding data */ #if defined(USE_SSL) && defined(HAVE_GSSAPI) - if(conn->handler->flags & PROTOPT_SSL) { + if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) { Curl_dyn_init(&neg_ctx->channel_binding_data, SSL_CB_MAX_SIZE + 1); result = Curl_ssl_get_channel_binding( data, FIRSTSOCKET, &neg_ctx->channel_binding_data); diff --git a/lib/imap.c b/lib/imap.c index e424cdb056..df9dc343b5 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -1390,7 +1390,7 @@ static CURLcode imap_multi_statemach(struct Curl_easy *data, bool *done) struct connectdata *conn = data->conn; struct imap_conn *imapc = &conn->proto.imapc; - if((conn->handler->flags & PROTOPT_SSL) && !imapc->ssldone) { + if(Curl_conn_is_ssl(conn, FIRSTSOCKET) && !imapc->ssldone) { bool ssldone = FALSE; result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); imapc->ssldone = ssldone; diff --git a/lib/ldap.c b/lib/ldap.c index 97484a2b4d..7bba2162b5 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -83,6 +83,7 @@ #include "urldata.h" #include +#include "cfilters.h" #include "sendf.h" #include "escape.h" #include "progress.h" @@ -351,7 +352,7 @@ static CURLcode ldap_do(struct Curl_easy *data, bool *done) } /* Get the URL scheme (either ldap or ldaps) */ - if(conn->given->flags & PROTOPT_SSL) + if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) ldap_ssl = 1; infof(data, "LDAP local: trying to establish %s connection", ldap_ssl ? "encrypted" : "cleartext"); diff --git a/lib/openldap.c b/lib/openldap.c index 8c4af22bef..9676ad3d0d 100644 --- a/lib/openldap.c +++ b/lib/openldap.c @@ -571,7 +571,7 @@ static CURLcode oldap_connect(struct Curl_easy *data, bool *done) ldap_set_option(li->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); #ifdef USE_SSL - if(conn->handler->flags & PROTOPT_SSL) + if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) return oldap_ssl_connect(data, OLDAP_SSL); if(data->set.use_ssl) { diff --git a/lib/pop3.c b/lib/pop3.c index db6ec04c7b..83dd64cdad 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -1110,7 +1110,7 @@ static CURLcode pop3_multi_statemach(struct Curl_easy *data, bool *done) struct connectdata *conn = data->conn; struct pop3_conn *pop3c = &conn->proto.pop3c; - if((conn->handler->flags & PROTOPT_SSL) && !pop3c->ssldone) { + if(Curl_conn_is_ssl(conn, FIRSTSOCKET) && !pop3c->ssldone) { bool ssldone = FALSE; result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); pop3c->ssldone = ssldone; diff --git a/lib/smb.c b/lib/smb.c index 3e8a0f7760..7ae339f8a9 100644 --- a/lib/smb.c +++ b/lib/smb.c @@ -840,7 +840,7 @@ static CURLcode smb_connection_state(struct Curl_easy *data, bool *done) if(smbc->state == SMB_CONNECTING) { #ifdef USE_SSL - if((conn->handler->flags & PROTOPT_SSL)) { + if(Curl_conn_is_ssl(conn, FIRSTSOCKET)) { bool ssl_done = FALSE; result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssl_done); if(result && result != CURLE_AGAIN) diff --git a/lib/smtp.c b/lib/smtp.c index d854d364f8..c7fb0a4ca2 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -1286,7 +1286,7 @@ static CURLcode smtp_multi_statemach(struct Curl_easy *data, bool *done) struct connectdata *conn = data->conn; struct smtp_conn *smtpc = &conn->proto.smtpc; - if((conn->handler->flags & PROTOPT_SSL) && !smtpc->ssldone) { + if(Curl_conn_is_ssl(conn, FIRSTSOCKET) && !smtpc->ssldone) { bool ssldone = FALSE; result = Curl_conn_connect(data, FIRSTSOCKET, FALSE, &ssldone); smtpc->ssldone = ssldone; diff --git a/lib/url.c b/lib/url.c index 843f504a1a..1461674fa7 100644 --- a/lib/url.c +++ b/lib/url.c @@ -956,12 +956,12 @@ static bool url_match_conn(struct connectdata *conn, void *userdata) return FALSE; #endif - if((needle->handler->flags&PROTOPT_SSL) != - (conn->handler->flags&PROTOPT_SSL)) - /* do not do mixed SSL and non-SSL connections */ - if(get_protocol_family(conn->handler) != - needle->handler->protocol || !conn->bits.tls_upgraded) - /* except protocols that have been upgraded via TLS */ + if((!(needle->handler->flags&PROTOPT_SSL) != + !Curl_conn_is_ssl(conn, FIRSTSOCKET)) && + !(get_protocol_family(conn->handler) == needle->handler->protocol && + conn->bits.tls_upgraded)) + /* Deny `conn` if it is not fit for `needle`'s SSL needs, + * UNLESS `conn` is the same protocol family and was upgraded to SSL. */ return FALSE; #ifndef CURL_DISABLE_PROXY -- 2.47.2