fix(git-gate): accept any key type from ssh-keyscan, prefer ed25519
lint / lint (push) Successful in 2m0s
test / unit (pull_request) Successful in 53s
test / integration (pull_request) Successful in 16s
test / coverage (pull_request) Successful in 1m6s

Servers that don't offer ed25519 (ecdsa-only or rsa-only gitea
instances) would raise "ssh-keyscan returned no ed25519 key" because
`-t ed25519` produced no output.

Remove the `-t ed25519` restriction: ssh-keyscan now returns all
supported key types and the function picks the best available via
_KEY_TYPE_PREFERENCE (ed25519 > ecdsa > rsa > first).

Also adds four new fetch_host_key tests covering multi-type preference
logic and updates the stale "no ed25519 key" assertion.
This commit is contained in:
2026-07-09 16:45:47 +00:00
parent f9662c88a5
commit 61740cdb6a
2 changed files with 57 additions and 10 deletions
+28 -1
View File
@@ -71,7 +71,34 @@ class TestFetchHostKey(unittest.TestCase):
with patch("subprocess.run", return_value=self._run_result("")):
with self.assertRaises(RuntimeError) as cm:
fetch_host_key("example.com", "22")
self.assertIn("no ed25519 key", str(cm.exception))
self.assertIn("no host key", str(cm.exception))
def test_prefers_ed25519_over_ecdsa(self) -> None:
stdout = (
"gitea.example.com ecdsa-sha2-nistp256 BBBBB\n"
"gitea.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA\n"
)
with patch("subprocess.run", return_value=self._run_result(stdout)):
key = fetch_host_key("gitea.example.com", "22")
self.assertEqual("ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA", key)
def test_falls_back_to_ecdsa_without_ed25519(self) -> None:
stdout = "gitea.example.com ecdsa-sha2-nistp256 BBBBB\n"
with patch("subprocess.run", return_value=self._run_result(stdout)):
key = fetch_host_key("gitea.example.com", "22")
self.assertEqual("ecdsa-sha2-nistp256 BBBBB", key)
def test_falls_back_to_rsa_without_ed25519_or_ecdsa(self) -> None:
stdout = "gitea.example.com ssh-rsa AAAAB3NzaC1yc2EAAAA\n"
with patch("subprocess.run", return_value=self._run_result(stdout)):
key = fetch_host_key("gitea.example.com", "22")
self.assertEqual("ssh-rsa AAAAB3NzaC1yc2EAAAA", key)
def test_falls_back_to_first_for_unknown_type(self) -> None:
stdout = "gitea.example.com ssh-unknown CCCCC\n"
with patch("subprocess.run", return_value=self._run_result(stdout)):
key = fetch_host_key("gitea.example.com", "22")
self.assertEqual("ssh-unknown CCCCC", key)
def test_raises_includes_stderr_when_present(self) -> None:
r = self._run_result("")