1
0
mirror of https://github.com/libssh2/libssh2.git synced 2026-10-24 03:48:58 +03:00

userauth: free key method when userauth_key_sign_algs() fails

`ssh2_userauth_publickey()` returns the `userauth_key_sign_algs()` error
without freeing `session->userauth_pblc_method`, which happens when the
server's `server-sig-algs` has none of the RSA algorithms we can upgrade
an RSA key to. The next call sees the non-NULL method and skips parsing
it from the new key, so when iterating agent identities an ed25519 key
is offered as `ssh-rsa` and every later key fails with "No signing
signature matched" (the fromfile/frommemory/sk paths overwrite and leak
it instead). Free it there like the other error returns in the function
do; the new `test_simple` case fails without the fix.

Closes #2673
This commit is contained in:
syed abdul khaliq
2026-10-16 14:38:20 +05:30
committed by Viktor Szakats
parent 6cf2e3da1e
commit 3209951db4
2 changed files with 45 additions and 1 deletions

View File

@@ -1443,8 +1443,10 @@ retry_auth:
if(auth_attempts == 1) {
rc = userauth_key_sign_algs(session,
&session->userauth_pblc_method);
if(rc)
if(rc) {
SSH2_SAFEFREE(session, session->userauth_pblc_method);
return rc;
}
}
if(session->userauth_pblc_method && *session->userauth_pblc_method) {

View File

@@ -373,6 +373,45 @@ static int test_ssh2_scp_parse_c_fields(void)
return err > 0;
}
#if LIBSSH2_RSA_SHA2
static int test_userauth_sign_algs_fail_cleanup(LIBSSH2_SESSION *session)
{
static const char server_algs[] = "ssh-ed25519";
static const unsigned char rsa_key[] = {
0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a',
0, 0, 0, 1, 3, 0, 0, 0, 1, 0x7f
};
int rc;
int err = 0;
/* server-sig-algs without any RSA algorithm we can upgrade to */
session->server_sign_algorithms = SSH2_ALLOC(session, sizeof(server_algs));
if(!session->server_sign_algorithms)
return 1;
memcpy(session->server_sign_algorithms, server_algs, sizeof(server_algs));
rc = libssh2_userauth_publickey(session, "user",
rsa_key, sizeof(rsa_key), NULL, NULL);
if(rc != LIBSSH2_ERROR_METHOD_NONE) {
fprintf(stderr, "userauth sign algs: rc=%d (want %d)\n",
rc, LIBSSH2_ERROR_METHOD_NONE);
err++;
}
/* a stale method name would be reused by the next key */
if(session->userauth_pblc_method) {
fprintf(stderr, "userauth sign algs: method left set: %s\n",
session->userauth_pblc_method);
SSH2_SAFEFREE(session, session->userauth_pblc_method);
err++;
}
SSH2_SAFEFREE(session, session->server_sign_algorithms);
return err > 0;
}
#endif
int main(int argc, char *argv[])
{
LIBSSH2_SESSION *session;
@@ -397,6 +436,9 @@ int main(int argc, char *argv[])
rc |= test_ssh2_dh_validate();
rc |= test_ssh2_bn_from_bin();
rc |= test_ssh2_scp_parse_c_fields();
#if LIBSSH2_RSA_SHA2
rc |= test_userauth_sign_algs_fail_cleanup(session);
#endif
libssh2_session_free(session);