creds: hold credentials

Authorizdation credentials are kept in `struct Curl_creds`. This contains:

* `user`: the username, maybe the empty string
* `passwd`: the password, maybe the empty string
* `sasl_authzid`: the SASL authz value, maybe the empty string
* `oauth_bearer`: the OAUTH bearer token, maybe the empty string
* `source`: where the credentials from from
* `refcount`: a reference counter to link/unkink creds

A `creds` with all values empty is equivalent to NULL, e.g. no `creds`
instance. With reference counting, `creds` can be linked/unlinked
in several places.

See docs/internals/CREDENTIALS.md for use.

Closes #21548
This commit is contained in:
Stefan Eissing 2026-05-11 14:25:52 +02:00 committed by Daniel Stenberg
parent a32a2b0b77
commit 8f71d0fde5
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
47 changed files with 1138 additions and 962 deletions

View file

@ -148,11 +148,12 @@ static void kbd_callback(const char *name, int name_len,
#endif /* CURL_LIBSSH2_DEBUG */
if(num_prompts == 1) {
struct connectdata *conn = data->conn;
const char *passwd = Curl_creds_passwd(conn->creds);
/* this function must allocate memory that can be freed by libssh2, which
uses the LIBSSH2_FREE_FUNC callback */
responses[0].text = Curl_cstrdup(conn->passwd);
responses[0].text = Curl_cstrdup(passwd);
responses[0].length =
responses[0].text == NULL ? 0 : curlx_uztoui(strlen(conn->passwd));
responses[0].text == NULL ? 0 : curlx_uztoui(strlen(passwd));
}
(void)prompts;
} /* kbd_callback */
@ -1496,9 +1497,9 @@ static CURLcode ssh_state_authlist(struct Curl_easy *data,
* Therefore always specify it here.
*/
struct connectdata *conn = data->conn;
const char *user = Curl_creds_user(conn->creds);
sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
conn->user,
curlx_uztoui(strlen(conn->user)));
user, curlx_uztoui(strlen(user)));
if(!sshc->authlist) {
int rc;
@ -1527,11 +1528,11 @@ static CURLcode ssh_state_auth_pkey(struct Curl_easy *data,
/* The function below checks if the files exists, no need to stat() here.
*/
struct connectdata *conn = data->conn;
const char *user = Curl_creds_user(conn->creds);
int rc =
libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
conn->user,
curlx_uztoui(
strlen(conn->user)),
user,
curlx_uztoui(strlen(user)),
sshc->rsa_pub,
sshc->rsa, sshc->passphrase);
if(rc == LIBSSH2_ERROR_EAGAIN)
@ -1579,11 +1580,13 @@ static CURLcode ssh_state_auth_pass(struct Curl_easy *data,
struct ssh_conn *sshc)
{
struct connectdata *conn = data->conn;
const char *user = Curl_creds_user(conn->creds);
const char *passwd = Curl_creds_passwd(conn->creds);
int rc =
libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
curlx_uztoui(strlen(conn->user)),
conn->passwd,
curlx_uztoui(strlen(conn->passwd)),
libssh2_userauth_password_ex(sshc->ssh_session, user,
curlx_uztoui(strlen(user)),
passwd,
curlx_uztoui(strlen(passwd)),
NULL);
if(rc == LIBSSH2_ERROR_EAGAIN) {
return CURLE_AGAIN;
@ -1680,7 +1683,7 @@ static CURLcode ssh_state_auth_agent(struct Curl_easy *data,
if(rc == 0) {
struct connectdata *conn = data->conn;
rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
rc = libssh2_agent_userauth(sshc->ssh_agent, Curl_creds_user(conn->creds),
sshc->sshagent_identity);
if(rc < 0) {
@ -1727,11 +1730,10 @@ static CURLcode ssh_state_auth_key(struct Curl_easy *data,
{
/* Authentication failed. Continue with keyboard-interactive now. */
struct connectdata *conn = data->conn;
const char *user = Curl_creds_user(conn->creds);
int rc =
libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
conn->user,
curlx_uztoui(
strlen(conn->user)),
user, curlx_uztoui(strlen(user)),
&kbd_callback);
if(rc == LIBSSH2_ERROR_EAGAIN)
return CURLE_AGAIN;
@ -3452,9 +3454,9 @@ static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
if(!sshc)
return CURLE_FAILED_INIT;
infof(data, "User: '%s'", conn->user);
infof(data, "User: '%s'", Curl_creds_user(conn->creds));
#ifdef CURL_LIBSSH2_DEBUG
infof(data, "Password: %s", conn->passwd);
infof(data, "Password: %s", Curl_creds_passwd(conn->creds));
sock = conn->sock[FIRSTSOCKET];
#endif /* CURL_LIBSSH2_DEBUG */