This is an automated email from the ASF dual-hosted git repository.
twolf pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
The following commit(s) were added to refs/heads/master by this push:
new 22b9b07d9 GH-827: known_hosts: skip and log invalid lines
22b9b07d9 is described below
commit 22b9b07d9f2185e3f7dc43e1feef615e0be49fb2
Author: Thomas Wolf <[email protected]>
AuthorDate: Sun Sep 28 18:58:15 2025 +0200
GH-827: known_hosts: skip and log invalid lines
Previous code would throw an exception on the first error encountered.
---
CHANGES.md | 1 +
.../sshd/client/config/hosts/KnownHostEntry.java | 23 ++++++++++++++--------
.../keyverifier/KnownHostsUnsupportedKeysTest.java | 17 ++++++++++++++++
3 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/CHANGES.md b/CHANGES.md
index e0602b749..35c21e19c 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -31,6 +31,7 @@
* [GH-807](https://github.com/apache/mina-sshd/issues/807) Handle "verified"
flag for sk-* keys
* [GH-809](https://github.com/apache/mina-sshd/pull/809) Fix server-side
authentication for FIDO/U2F sk-* keys with flags in `authorized_keys`
+* [GH-827](https://github.com/apache/mina-sshd/pull/827) Don't fail on invalid
`known_hosts` lines; log and skip them
## New Features
diff --git
a/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/KnownHostEntry.java
b/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/KnownHostEntry.java
index a0c35d666..aa2ba97db 100644
---
a/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/KnownHostEntry.java
+++
b/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/KnownHostEntry.java
@@ -24,7 +24,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
-import java.io.StreamCorruptedException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -34,13 +33,14 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import org.apache.sshd.common.config.ConfigFileReaderSupport;
import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
import org.apache.sshd.common.config.keys.PublicKeyEntry;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.io.input.NoCloseInputStream;
import org.apache.sshd.common.util.io.input.NoCloseReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Contains a representation of an entry in the <code>known_hosts</code> file
@@ -59,6 +59,8 @@ public class KnownHostEntry extends HostPatternsHolder {
*/
public static final String STD_HOSTS_FILENAME = "known_hosts";
+ private static final Logger LOG =
LoggerFactory.getLogger(KnownHostEntry.class);
+
private static final class LazyDefaultConfigFileHolder {
private static final Path HOSTS_FILE =
PublicKeyEntry.getDefaultKeysFolderPath().resolve(STD_HOSTS_FILENAME);
@@ -183,7 +185,7 @@ public class KnownHostEntry extends HostPatternsHolder {
continue;
}
- int pos = line.indexOf(ConfigFileReaderSupport.COMMENT_CHAR);
+ int pos = line.indexOf(PublicKeyEntry.COMMENT_CHAR);
if (pos == 0) {
continue;
}
@@ -203,9 +205,8 @@ public class KnownHostEntry extends HostPatternsHolder {
entries = new ArrayList<>();
}
entries.add(entry);
- } catch (RuntimeException | Error e) { // TODO consider consulting
a user callback
- throw new StreamCorruptedException("Failed (" +
e.getClass().getSimpleName() + ") to parse line #"
- + lineNumber + " '" + line
+ "': " + e.getMessage());
+ } catch (RuntimeException e) { // TODO consider consulting a user
callback
+ LOG.warn("Invalid known_hosts line #" + lineNumber + " '" +
line + "': " + e.getMessage());
}
}
@@ -217,13 +218,16 @@ public class KnownHostEntry extends HostPatternsHolder {
}
public static KnownHostEntry parseKnownHostEntry(String line) {
- return parseKnownHostEntry(GenericUtils.isEmpty(line) ? null : new
KnownHostEntry(), line);
+ return GenericUtils.isEmpty(line) ? null : parseKnownHostEntry(new
KnownHostEntry(), line);
}
public static <E extends KnownHostEntry> E parseKnownHostEntry(E entry,
String data) {
+ if (data == null) {
+ return null;
+ }
String line = GenericUtils.replaceWhitespaceAndTrim(data);
if (GenericUtils.isEmpty(line) || (line.charAt(0) ==
PublicKeyEntry.COMMENT_CHAR)) {
- return entry;
+ return null;
}
entry.setConfigLine(line);
@@ -254,6 +258,9 @@ public class KnownHostEntry extends HostPatternsHolder {
}
AuthorizedKeyEntry key = PublicKeyEntry.parsePublicKeyEntry(new
AuthorizedKeyEntry(),
ValidateUtils.checkNotNullAndNotEmpty(line, "No valid key
entry recovered from line=%s", data));
+ if (key == null) {
+ return null;
+ }
entry.setKeyEntry(key);
return entry;
}
diff --git
a/sshd-core/src/test/java/org/apache/sshd/client/keyverifier/KnownHostsUnsupportedKeysTest.java
b/sshd-core/src/test/java/org/apache/sshd/client/keyverifier/KnownHostsUnsupportedKeysTest.java
index dedd9015d..4b34056c6 100644
---
a/sshd-core/src/test/java/org/apache/sshd/client/keyverifier/KnownHostsUnsupportedKeysTest.java
+++
b/sshd-core/src/test/java/org/apache/sshd/client/keyverifier/KnownHostsUnsupportedKeysTest.java
@@ -70,6 +70,23 @@ class KnownHostsUnsupportedKeysTest extends JUnitTestSupport
{
assertTrue(invokeVerifier(verifier, new SshdSocketAddress("127.0.0.1",
2222), key));
}
+ @Test
+ void invalidLineIgnored() throws Exception {
+ Path knownHosts = tmp.resolve("known_hosts");
+ String entry
+ = "[127.0.0.1]:2222 ecdsa-sha2-nistp256
AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCbZVVpqEHGLNWMqMeyU1VbWb91XteoamVcgpy4yxNVbZffb5IDdbo1ons/y9KAhcub6LZeLrvXzVUZbXCZiUkg=";
+ List<String> lines = new ArrayList<>();
+ lines.add(entry + entry);
+ lines.add(entry);
+ Files.write(knownHosts, lines);
+ KnownHostsServerKeyVerifier verifier = new
KnownHostsServerKeyVerifier(RejectAllServerKeyVerifier.INSTANCE, knownHosts);
+ KnownHostEntry knownHost =
KnownHostEntry.parseKnownHostEntry(lines.get(1));
+ AuthorizedKeyEntry keyEntry = knownHost.getKeyEntry();
+ assertNotNull(keyEntry);
+ PublicKey key = keyEntry.resolvePublicKey(null,
PublicKeyEntryResolver.FAILING);
+ assertTrue(invokeVerifier(verifier, new SshdSocketAddress("127.0.0.1",
2222), key));
+ }
+
@Test
void unknownNewKey() throws Exception {
KeyPair kp =
CommonTestSupportUtils.generateKeyPair(KeyUtils.RSA_ALGORITHM, 1024);