a73x

7f269ec9

Fix SSH auth rejecting RSA keys due to algorithm name mismatch

alex emery   2026-04-11 17:16

Modern SSH clients use rsa-sha2-256/rsa-sha2-512 algorithm names but
authorized_keys stores the key type as ssh-rsa. Normalize all RSA
variants to match when comparing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

diff --git a/src/server/ssh/auth.rs b/src/server/ssh/auth.rs
index 86bcc9a..d22bdf3 100644
--- a/src/server/ssh/auth.rs
+++ b/src/server/ssh/auth.rs
@@ -30,8 +30,16 @@ pub fn load_authorized_keys(path: &Path) -> Result<Vec<AuthorizedKey>, std::io::
    Ok(parse_authorized_keys(&content))
}

fn is_rsa_key_type(key_type: &str) -> bool {
    matches!(key_type, "ssh-rsa" | "rsa-sha2-256" | "rsa-sha2-512")
}

pub fn is_authorized(keys: &[AuthorizedKey], key_type: &str, key_data: &str) -> bool {
    keys.iter().any(|k| k.key_type == key_type && k.key_data == key_data)
    keys.iter().any(|k| {
        let type_matches = k.key_type == key_type
            || (is_rsa_key_type(&k.key_type) && is_rsa_key_type(key_type));
        type_matches && k.key_data == key_data
    })
}

#[cfg(test)]
@@ -80,4 +88,13 @@ mod tests {
        assert!(!is_authorized(&keys, "ssh-ed25519", "AAAA9999"));
        assert!(!is_authorized(&keys, "ssh-rsa", "AAAA1111"));
    }

    #[test]
    fn rsa_key_type_variants_match() {
        let keys = parse_authorized_keys("ssh-rsa AAAARSA user\n");
        assert!(is_authorized(&keys, "ssh-rsa", "AAAARSA"));
        assert!(is_authorized(&keys, "rsa-sha2-256", "AAAARSA"));
        assert!(is_authorized(&keys, "rsa-sha2-512", "AAAARSA"));
        assert!(!is_authorized(&keys, "rsa-sha2-256", "WRONG"));
    }
}