From: Stefan Eissing Date: Fri, 23 May 2025 10:21:18 +0000 (+0200) Subject: sasl: give help when unable to select AUTH X-Git-Tag: curl-8_14_0~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=37b25f7bb0f055c5904da90ea529f29c818c5519;p=thirdparty%2Fcurl.git sasl: give help when unable to select AUTH When SASL is unable to select an AUTH mechanism, give user help in info message why no AUTH could be selected. Fixes #17420 Closes #17427 Reported-by: Aditya Garg --- diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 7943925bed..4fcbaac263 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -756,4 +756,101 @@ CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, return result; } + +#ifndef CURL_DISABLE_VERBOSE_STRINGS +static void sasl_unchosen(struct Curl_easy *data, unsigned short mech, + unsigned short enabledmechs, + bool built_in, bool platform, + const char *param_missing) +{ + const char *mname = NULL; + size_t i; + + if(!(enabledmechs & mech)) + return; + + for(i = 0; mechtable[i].name; ++i) { + if(mechtable[i].bit == mech) { + mname = mechtable[i].name; + break; + } + } + if(!mname) /* should not happen */ + return; + if(!built_in) + infof(data, "SASL: %s not builtin", mname); + else if(!platform) + infof(data, "SASL: %s not supported by the platform/libraries", mname); + else { + if(param_missing) + infof(data, "SASL: %s is missing %s", mname, param_missing); + if(!data->state.aptr.user) + infof(data, "SASL: %s is missing username", mname); + } +} +#endif /* CURL_DISABLE_VERBOSE_STRINGS */ + +CURLcode Curl_sasl_is_blocked(struct SASL *sasl, struct Curl_easy *data) +{ +#ifndef CURL_DISABLE_VERBOSE_STRINGS +#ifdef USE_KERBEROS5 +#define CURL_SASL_KERBEROS5 TRUE +#else +#define CURL_SASL_KERBEROS5 FALSE +#endif +#ifdef USE_GSASL +#define CURL_SASL_GASL TRUE +#else +#define CURL_SASL_GASL FALSE +#endif +#ifdef CURL_DISABLE_DIGEST_AUTH +#define CURL_SASL_DIGEST TRUE +#else +#define CURL_SASL_DIGEST FALSE +#endif +#ifndef USE_NTLM +#define CURL_SASL_NTLM TRUE +#else +#define CURL_SASL_NTLM FALSE +#endif + /* Failing SASL authentication is a pain. Give a helping hand if + * we were unable to select an AUTH mechanism. + * `sasl->authmechs` are mechanisms offered by the peer + * `sasl->prefmech` are mechanisms preferred by us */ + unsigned short enabledmechs = sasl->authmechs & sasl->prefmech; + + if(!sasl->authmechs) + infof(data, "SASL: no auth mechanism was offered or recognized"); + else if(!enabledmechs) + infof(data, "SASL: no overlap between offered and configured " + "auth mechanisms"); + else { + infof(data, "SASL: no auth mechanism offered could be selected"); + if((enabledmechs & SASL_MECH_EXTERNAL) && data->conn->passwd[0]) + infof(data, "SASL: auth EXTERNAL not chosen with password"); + sasl_unchosen(data, SASL_MECH_GSSAPI, enabledmechs, + CURL_SASL_KERBEROS5, Curl_auth_is_gssapi_supported(), NULL); + sasl_unchosen(data, SASL_MECH_SCRAM_SHA_256, enabledmechs, + CURL_SASL_GASL, FALSE, NULL); + sasl_unchosen(data, SASL_MECH_SCRAM_SHA_1, enabledmechs, + CURL_SASL_GASL, FALSE, NULL); + sasl_unchosen(data, SASL_MECH_DIGEST_MD5, enabledmechs, + CURL_SASL_DIGEST, Curl_auth_is_digest_supported(), NULL); + sasl_unchosen(data, SASL_MECH_CRAM_MD5, enabledmechs, + CURL_SASL_DIGEST, TRUE, NULL); + sasl_unchosen(data, SASL_MECH_NTLM, enabledmechs, + CURL_SASL_NTLM, Curl_auth_is_ntlm_supported(), NULL); + sasl_unchosen(data, SASL_MECH_OAUTHBEARER, enabledmechs, TRUE, TRUE, + data->set.str[STRING_BEARER] ? + NULL : "CURLOPT_XOAUTH2_BEARER"); + sasl_unchosen(data, SASL_MECH_XOAUTH2, enabledmechs, TRUE, TRUE, + data->set.str[STRING_BEARER] ? + NULL : "CURLOPT_XOAUTH2_BEARER"); + } +#endif /* CURL_DISABLE_VERBOSE_STRINGS */ + (void)sasl; + (void)data; + return CURLE_LOGIN_DENIED; +} + #endif /* protocols are enabled that use SASL */ diff --git a/lib/curl_sasl.h b/lib/curl_sasl.h index e94e6431a2..59983f7c66 100644 --- a/lib/curl_sasl.h +++ b/lib/curl_sasl.h @@ -162,4 +162,6 @@ CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data, CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data, int code, saslprogress *progress); +CURLcode Curl_sasl_is_blocked(struct SASL *sasl, struct Curl_easy *data); + #endif /* HEADER_CURL_SASL_H */ diff --git a/lib/imap.c b/lib/imap.c index 56e34e1593..4b2e6087f2 100644 --- a/lib/imap.c +++ b/lib/imap.c @@ -723,11 +723,8 @@ static CURLcode imap_perform_authentication(struct Curl_easy *data, else if(!imapc->login_disabled && (imapc->preftype & IMAP_TYPE_CLEARTEXT)) /* Perform clear text authentication */ result = imap_perform_login(data, imapc, data->conn); - else { - /* Other mechanisms not supported */ - infof(data, "No known authentication mechanisms supported"); - result = CURLE_LOGIN_DENIED; - } + else + result = Curl_sasl_is_blocked(&imapc->sasl, data); } return result; diff --git a/lib/openldap.c b/lib/openldap.c index c5e7229f3c..6343c40c09 100644 --- a/lib/openldap.c +++ b/lib/openldap.c @@ -491,7 +491,7 @@ static CURLcode oldap_perform_sasl(struct Curl_easy *data) oldap_state(data, li, OLDAP_SASL); if(!result && progress != SASL_INPROGRESS) - result = CURLE_LOGIN_DENIED; + result = Curl_sasl_is_blocked(&li->sasl, data); return result; } diff --git a/lib/pop3.c b/lib/pop3.c index 62d2e26add..852834ecec 100644 --- a/lib/pop3.c +++ b/lib/pop3.c @@ -726,11 +726,8 @@ static CURLcode pop3_perform_authentication(struct Curl_easy *data, if(pop3c->authtypes & pop3c->preftype & POP3_TYPE_CLEARTEXT) /* Perform clear text authentication */ result = pop3_perform_user(data, conn); - else { - /* Other mechanisms not supported */ - infof(data, "No known authentication mechanisms supported"); - result = CURLE_LOGIN_DENIED; - } + else + result = Curl_sasl_is_blocked(&pop3c->sasl, data); } return result; diff --git a/lib/smtp.c b/lib/smtp.c index f9711a3a17..cccb9f381a 100644 --- a/lib/smtp.c +++ b/lib/smtp.c @@ -590,11 +590,8 @@ static CURLcode smtp_perform_authentication(struct Curl_easy *data, if(!result) { if(progress == SASL_INPROGRESS) smtp_state(data, smtpc, SMTP_AUTH); - else { - /* Other mechanisms not supported */ - infof(data, "No known authentication mechanisms supported"); - result = CURLE_LOGIN_DENIED; - } + else + result = Curl_sasl_is_blocked(&smtpc->sasl, data); } return result; diff --git a/lib/vauth/vauth.h b/lib/vauth/vauth.h index 7ff0b05595..d845988067 100644 --- a/lib/vauth/vauth.h +++ b/lib/vauth/vauth.h @@ -167,6 +167,8 @@ CURLcode Curl_auth_create_ntlm_type3_message(struct Curl_easy *data, /* This is used to clean up the NTLM specific data */ void Curl_auth_cleanup_ntlm(struct ntlmdata *ntlm); +#else +#define Curl_auth_is_ntlm_supported() FALSE #endif /* USE_NTLM */ /* This is used to generate a base64 encoded OAuth 2.0 message */ @@ -207,6 +209,8 @@ CURLcode Curl_auth_create_gssapi_security_message(struct Curl_easy *data, /* This is used to clean up the GSSAPI specific data */ void Curl_auth_cleanup_gssapi(struct kerberos5data *krb5); +#else +#define Curl_auth_is_gssapi_supported() FALSE #endif /* USE_KERBEROS5 */ #if defined(USE_SPNEGO)