tomaswolf commented on code in PR #368:
URL: https://github.com/apache/mina-sshd/pull/368#discussion_r1186889041


##########
sshd-core/src/main/java/org/apache/sshd/client/keyverifier/KnownHostsServerKeyVerifier.java:
##########
@@ -267,36 +268,55 @@ protected PublicKeyEntryResolver 
getFallbackPublicKeyEntryResolver() {
     protected boolean acceptKnownHostEntries(
             ClientSession clientSession, SocketAddress remoteAddress, 
PublicKey serverKey,
             Collection<HostEntryPair> knownHosts) {
-        // TODO allow for several candidates and check if ANY of them matches 
the key and has 'revoked' marker
-        HostEntryPair match = findKnownHostEntry(clientSession, remoteAddress, 
knownHosts);
-        if (match == null) {
+
+        List<HostEntryPair> hostMatches = findKnownHostEntries(clientSession, 
remoteAddress, knownHosts);
+        if (hostMatches.isEmpty()) {
             return acceptUnknownHostKey(clientSession, remoteAddress, 
serverKey);
         }
 
-        KnownHostEntry entry = match.getHostEntry();
-        PublicKey expected = match.getServerKey();
-        if (KeyUtils.compareKeys(expected, serverKey)) {
-            return acceptKnownHostEntry(clientSession, remoteAddress, 
serverKey, entry);
+        String serverKeyType = KeyUtils.getKeyType(serverKey);
+
+        List<HostEntryPair> keyMatches = hostMatches.stream()
+                .filter(entry -> 
serverKeyType.equals(entry.getHostEntry().getKeyEntry().getKeyType()))
+                .filter(k -> KeyUtils.compareKeys(k.getServerKey(), serverKey))
+                .collect(Collectors.toList());
+
+        if (keyMatches.stream()
+                .anyMatch(k -> !acceptKnownHostEntry(clientSession, 
remoteAddress, serverKey, k.getHostEntry()))) {
+            return false;
         }
 
-        try {
-            if (!acceptModifiedServerKey(clientSession, remoteAddress, entry, 
expected, serverKey)) {
-                return false;
+        if (!keyMatches.isEmpty()) {
+            return true;
+        }
+
+        for (HostEntryPair match : hostMatches) {

Review Comment:
   This loop again goes over revoked entries. Those should probably never be 
fed to `acceptModifiedServerKey()`. Because if we have only revoked keys, it's 
not a "modified server key" case, but an "unknown server key".



##########
sshd-core/src/main/java/org/apache/sshd/client/keyverifier/KnownHostsServerKeyVerifier.java:
##########
@@ -267,36 +268,55 @@ protected PublicKeyEntryResolver 
getFallbackPublicKeyEntryResolver() {
     protected boolean acceptKnownHostEntries(
             ClientSession clientSession, SocketAddress remoteAddress, 
PublicKey serverKey,
             Collection<HostEntryPair> knownHosts) {
-        // TODO allow for several candidates and check if ANY of them matches 
the key and has 'revoked' marker
-        HostEntryPair match = findKnownHostEntry(clientSession, remoteAddress, 
knownHosts);
-        if (match == null) {
+
+        List<HostEntryPair> hostMatches = findKnownHostEntries(clientSession, 
remoteAddress, knownHosts);
+        if (hostMatches.isEmpty()) {
             return acceptUnknownHostKey(clientSession, remoteAddress, 
serverKey);
         }
 
-        KnownHostEntry entry = match.getHostEntry();
-        PublicKey expected = match.getServerKey();
-        if (KeyUtils.compareKeys(expected, serverKey)) {
-            return acceptKnownHostEntry(clientSession, remoteAddress, 
serverKey, entry);
+        String serverKeyType = KeyUtils.getKeyType(serverKey);
+
+        List<HostEntryPair> keyMatches = hostMatches.stream()
+                .filter(entry -> 
serverKeyType.equals(entry.getHostEntry().getKeyEntry().getKeyType()))
+                .filter(k -> KeyUtils.compareKeys(k.getServerKey(), serverKey))
+                .collect(Collectors.toList());
+
+        if (keyMatches.stream()
+                .anyMatch(k -> !acceptKnownHostEntry(clientSession, 
remoteAddress, serverKey, k.getHostEntry()))) {
+            return false;
         }
 
-        try {
-            if (!acceptModifiedServerKey(clientSession, remoteAddress, entry, 
expected, serverKey)) {
-                return false;
+        if (!keyMatches.isEmpty()) {
+            return true;
+        }
+
+        for (HostEntryPair match : hostMatches) {
+            KnownHostEntry entry = match.getHostEntry();
+            PublicKey expected = match.getServerKey();
+
+            try {
+                if (acceptModifiedServerKey(clientSession, remoteAddress, 
entry, expected, serverKey)) {
+                    updateModifiedServerKey(clientSession, remoteAddress, 
serverKey, knownHosts, match);
+                    return true;
+                }
+            } catch (Throwable t) {
+                warn("acceptKnownHostEntries({})[{}] failed ({}) to accept 
modified server key: {}",
+                        clientSession, remoteAddress, 
t.getClass().getSimpleName(), t.getMessage(), t);
             }
-        } catch (Throwable t) {
-            warn("acceptKnownHostEntries({})[{}] failed ({}) to accept 
modified server key: {}",
-                    clientSession, remoteAddress, 
t.getClass().getSimpleName(), t.getMessage(), t);
-            return false;
         }
 
+        return false;

Review Comment:
   If the above loop skips revoked entries (or `acceptModifiedServerKey` 
skipped them and returned `false`), then we can get here if we have for 
instance only revoked keys, all different from the actual server key. So here 
we should then call `return acceptUnknownHostKey(...);`.



##########
sshd-core/src/main/java/org/apache/sshd/client/keyverifier/KnownHostsServerKeyVerifier.java:
##########
@@ -267,36 +268,55 @@ protected PublicKeyEntryResolver 
getFallbackPublicKeyEntryResolver() {
     protected boolean acceptKnownHostEntries(
             ClientSession clientSession, SocketAddress remoteAddress, 
PublicKey serverKey,
             Collection<HostEntryPair> knownHosts) {
-        // TODO allow for several candidates and check if ANY of them matches 
the key and has 'revoked' marker
-        HostEntryPair match = findKnownHostEntry(clientSession, remoteAddress, 
knownHosts);
-        if (match == null) {
+
+        List<HostEntryPair> hostMatches = findKnownHostEntries(clientSession, 
remoteAddress, knownHosts);
+        if (hostMatches.isEmpty()) {
             return acceptUnknownHostKey(clientSession, remoteAddress, 
serverKey);
         }
 
-        KnownHostEntry entry = match.getHostEntry();
-        PublicKey expected = match.getServerKey();
-        if (KeyUtils.compareKeys(expected, serverKey)) {
-            return acceptKnownHostEntry(clientSession, remoteAddress, 
serverKey, entry);
+        String serverKeyType = KeyUtils.getKeyType(serverKey);
+
+        List<HostEntryPair> keyMatches = hostMatches.stream()
+                .filter(entry -> 
serverKeyType.equals(entry.getHostEntry().getKeyEntry().getKeyType()))
+                .filter(k -> KeyUtils.compareKeys(k.getServerKey(), serverKey))
+                .collect(Collectors.toList());
+
+        if (keyMatches.stream()
+                .anyMatch(k -> !acceptKnownHostEntry(clientSession, 
remoteAddress, serverKey, k.getHostEntry()))) {
+            return false;
         }
 
-        try {
-            if (!acceptModifiedServerKey(clientSession, remoteAddress, entry, 
expected, serverKey)) {
-                return false;
+        if (!keyMatches.isEmpty()) {
+            return true;
+        }
+
+        for (HostEntryPair match : hostMatches) {
+            KnownHostEntry entry = match.getHostEntry();
+            PublicKey expected = match.getServerKey();
+
+            try {
+                if (acceptModifiedServerKey(clientSession, remoteAddress, 
entry, expected, serverKey)) {
+                    updateModifiedServerKey(clientSession, remoteAddress, 
serverKey, knownHosts, match);
+                    return true;
+                }

Review Comment:
   I presume you can return false here after the `if`. No need to ask several 
times whether to accept a modified key -- and we know that none of the entries 
match the server key.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org
For additional commands, e-mail: dev-h...@mina.apache.org

Reply via email to