diff options
author | Matthias Sohn <matthias.sohn@sap.com> | 2025-02-26 23:00:32 +0000 |
---|---|---|
committer | Gerrit Code Review <support@gerrithub.io> | 2025-02-26 23:00:32 +0000 |
commit | 3483bd76e9d5f6ee68fedfa67b4800f80a21d637 (patch) | |
tree | f34aa3813ad703d25cfaeb5ca3ddad8f945d8fc8 | |
parent | 9ad4310db312ccaca1db80738334df5d3b0b817f (diff) | |
parent | 3edab4e9fd1b29fe676d8f66b99c93a2db482ad6 (diff) | |
download | jgit-3483bd76e9d5f6ee68fedfa67b4800f80a21d637.tar.gz jgit-3483bd76e9d5f6ee68fedfa67b4800f80a21d637.zip |
Merge "[ssh known_hosts] Handle unknown keys better"
2 files changed, 62 insertions, 20 deletions
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabaseTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabaseTest.java index b2e6401816..6b61821a0f 100644 --- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabaseTest.java +++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabaseTest.java @@ -478,6 +478,29 @@ public class OpenSshServerKeyDatabaseTest { new KnownHostsConfig(), null)); } + @Test + public void testUnknownKeyType() throws Exception { + List<String> initialKnownHosts = List.of( + "localhost,127.0.0.1 " + PublicKeyEntry.toString(ec384) + .replace("ecdsa", "foo"), + "some.other.com " + PublicKeyEntry.toString(ec384)); + Files.write(knownHosts, initialKnownHosts); + TestCredentialsProvider ui = new TestCredentialsProvider(true, true); + assertTrue(database.accept("localhost", LOCAL, ec384, + new KnownHostsConfig( + ServerKeyDatabase.Configuration.StrictHostKeyChecking.ASK), + ui)); + assertEquals(1, ui.invocations); + // The "modified key" dialog has two questions; whereas the "add new + // key" is just a simple question. + assertEquals(2, ui.questions); + List<String> expected = new ArrayList<>(initialKnownHosts); + expected.add("localhost,127.0.0.1 " + PublicKeyEntry.toString(ec384)); + assertFile(knownHosts, expected); + assertTrue(database.accept("127.0.0.1:22", LOCAL, ec384, + new KnownHostsConfig(), null)); + } + private void assertFile(Path path, List<String> lines) throws Exception { assertEquals(lines, Files.readAllLines(path).stream() .filter(s -> !s.isBlank()).toList()); @@ -489,6 +512,8 @@ public class OpenSshServerKeyDatabaseTest { int invocations = 0; + int questions = 0; + TestCredentialsProvider(boolean accept, boolean store) { values = new boolean[] { accept, store }; } @@ -512,6 +537,7 @@ public class OpenSshServerKeyDatabaseTest { if (item instanceof CredentialItem.YesNoType) { ((CredentialItem.YesNoType) item) .setValue(i < values.length && values[i++]); + questions++; } } return true; diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java index 40d8d3f04c..acb77c5bb7 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/OpenSshServerKeyDatabase.java @@ -53,6 +53,7 @@ import org.apache.sshd.common.config.keys.KeyUtils; import org.apache.sshd.common.config.keys.OpenSshCertificate; import org.apache.sshd.common.config.keys.PublicKeyEntry; import org.apache.sshd.common.config.keys.PublicKeyEntryResolver; +import org.apache.sshd.common.config.keys.UnsupportedSshPublicKey; import org.apache.sshd.common.digest.BuiltinDigests; import org.apache.sshd.common.mac.Mac; import org.apache.sshd.common.util.io.ModifiableFileWatcher; @@ -185,6 +186,9 @@ public class OpenSshServerKeyDatabase for (HostKeyFile file : filesToUse) { for (HostEntryPair current : file.get()) { KnownHostEntry entry = current.getHostEntry(); + if (current.getServerKey() instanceof UnsupportedSshPublicKey) { + continue; + } if (!isRevoked(entry) && !isCertificateAuthority(entry)) { for (SshdSocketAddress host : candidates) { if (entry.isHostMatch(host.getHostName(), @@ -235,12 +239,20 @@ public class OpenSshServerKeyDatabase remoteAddress, modified[0].getServerKey(), serverKey, path); if (toDo == AskUser.ModifiedKeyHandling.ALLOW_AND_STORE) { - try { - updateModifiedServerKey(serverKey, modified[0], path); - knownHostsFiles.get(path).resetReloadAttributes(); - } catch (IOException e) { - LOG.warn(format(SshdText.get().knownHostsCouldNotUpdate, - path)); + if (modified[0] + .getServerKey() instanceof UnsupportedSshPublicKey) { + // Never update a line containing an unknown key type, + // always add. + addKeyToFile(filesToUse.get(0), candidates, serverKey, ask, + config); + } else { + try { + updateModifiedServerKey(serverKey, modified[0], path); + knownHostsFiles.get(path).resetReloadAttributes(); + } catch (IOException e) { + LOG.warn(format(SshdText.get().knownHostsCouldNotUpdate, + path)); + } } } if (toDo == AskUser.ModifiedKeyHandling.DENY) { @@ -253,19 +265,8 @@ public class OpenSshServerKeyDatabase return true; } else if (ask.acceptUnknownKey(remoteAddress, serverKey)) { if (!filesToUse.isEmpty()) { - HostKeyFile toUpdate = filesToUse.get(0); - path = toUpdate.getPath(); - try { - if (Files.exists(path) || !askAboutNewFile - || ask.createNewFile(path)) { - updateKnownHostsFile(candidates, serverKey, path, - config); - toUpdate.resetReloadAttributes(); - } - } catch (Exception e) { - LOG.warn(format(SshdText.get().knownHostsCouldNotUpdate, - path), e); - } + addKeyToFile(filesToUse.get(0), candidates, serverKey, ask, + config); } return true; } @@ -379,6 +380,21 @@ public class OpenSshServerKeyDatabase return userFiles; } + private void addKeyToFile(HostKeyFile file, + Collection<SshdSocketAddress> candidates, PublicKey serverKey, + AskUser ask, Configuration config) { + Path path = file.getPath(); + try { + if (Files.exists(path) || !askAboutNewFile + || ask.createNewFile(path)) { + updateKnownHostsFile(candidates, serverKey, path, config); + file.resetReloadAttributes(); + } + } catch (Exception e) { + LOG.warn(format(SshdText.get().knownHostsCouldNotUpdate, path), e); + } + } + private void updateKnownHostsFile(Collection<SshdSocketAddress> candidates, PublicKey serverKey, Path path, Configuration config) throws Exception { @@ -663,7 +679,7 @@ public class OpenSshServerKeyDatabase } try { PublicKey serverKey = keyPart.resolvePublicKey(null, - PublicKeyEntryResolver.IGNORING); + PublicKeyEntryResolver.UNSUPPORTED); if (serverKey == null) { LOG.warn(format( SshdText.get().knownHostsUnknownKeyType, |