1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-07-25 03:41:56 +03:00

auth: Process outstanding packets before selecting signature algorithm

Originally reported by Till on mailing list here:

https://archive.libssh.org/libssh/2025-05/0000000.html

After some debugging, it turns out the client code does not guarantee
the extensions are processed before making decisions on the signature algorithm
that is being used for authentication, causing false-positive failures.

This does not happen in the tests, where we initially call ssh_userauth_none,
which enumerates authentications methods and as a side effect processes
outstanding packets such as SSH_EXT_INFO message with the server-sig-algs
extension.

When the first function called after `ssh_connect()` is
`ssh_userauth_publickey()`, the `ssh_userauth_request_service()` was wrongly
called only after the signature algorithm compatibility was checked.

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Norbert Pocs <norbertpocs0@gmail.com>
(cherry picked from commit 12baa5200a)
This commit is contained in:
Jakub Jelen
2025-05-30 09:47:34 +02:00
parent 65699380cf
commit 1a2c46781c

View File

@ -521,6 +521,17 @@ int ssh_userauth_try_publickey(ssh_session session,
return SSH_AUTH_ERROR;
}
/* Note, that this is intentionally before checking the signature type
* compatibility to make sure the possible EXT_INFO packet is processed,
* extensions recorded and the right signature type is used below
*/
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* Check if the given public key algorithm is allowed */
sig_type_c = ssh_key_get_signature_algorithm(session, pubkey->type);
if (sig_type_c == NULL) {
@ -544,13 +555,6 @@ int ssh_userauth_try_publickey(ssh_session session,
return SSH_AUTH_DENIED;
}
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* public key */
rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_s);
if (rc < 0) {
@ -652,6 +656,17 @@ int ssh_userauth_publickey(ssh_session session,
return SSH_AUTH_ERROR;
}
/* Note, that this is intentionally before checking the signature type
* compatibility to make sure the possible EXT_INFO packet is processed,
* extensions recorded and the right signature type is used below
*/
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* Cert auth requires presenting the cert type name (*-cert@openssh.com) */
key_type = privkey->cert != NULL ? privkey->cert_type : privkey->type;
@ -678,13 +693,6 @@ int ssh_userauth_publickey(ssh_session session,
return SSH_AUTH_DENIED;
}
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;
} else if (rc == SSH_ERROR) {
return SSH_AUTH_ERROR;
}
/* get public key or cert */
rc = ssh_pki_export_pubkey_blob(privkey, &str);
if (rc < 0) {
@ -769,6 +777,10 @@ static int ssh_userauth_agent_publickey(ssh_session session,
return SSH_ERROR;
}
/* Note, that this is intentionally before checking the signature type
* compatibility to make sure the possible EXT_INFO packet is processed,
* extensions recorded and the right signature type is used below
*/
rc = ssh_userauth_request_service(session);
if (rc == SSH_AGAIN) {
return SSH_AUTH_AGAIN;