Skip to content

Commit d4535ca

Browse files
authored
spring-projectsGH-8674: Fix ServerKeyVerifier impl for key type (spring-projects#8675)
Fixes spring-projects#8674 The `ResourceKnownHostsServerKeyVerifier` does not take into account that several different keys can be present in the known hosts resource for the same host/port * Fix `ResourceKnownHostsServerKeyVerifier` to find a list of knows host for the requested session. Then iterate of this result to match the key type first and then compare keys and their `revoked` marker **Cherry-pick to `6.1.x` & `6.0.x`**
1 parent f527025 commit d4535ca

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

spring-integration-sftp/src/main/java/org/springframework/integration/sftp/session/ResourceKnownHostsServerKeyVerifier.java

+20-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2022 the original author or authors.
2+
* Copyright 2022-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -66,18 +66,19 @@ public ResourceKnownHostsServerKeyVerifier(Resource knownHostsResource) {
6666
@Override
6767
public boolean verifyServerKey(ClientSession clientSession, SocketAddress remoteAddress, PublicKey serverKey) {
6868
Collection<KnownHostsServerKeyVerifier.HostEntryPair> knownHosts = this.keysSupplier.get();
69-
KnownHostsServerKeyVerifier.HostEntryPair match = findKnownHostEntry(clientSession, remoteAddress, knownHosts);
70-
if (match == null) {
69+
List<KnownHostsServerKeyVerifier.HostEntryPair> matches =
70+
findKnownHostEntries(clientSession, remoteAddress, knownHosts);
71+
72+
if (matches.isEmpty()) {
7173
return false;
7274
}
7375

74-
KnownHostEntry entry = match.getHostEntry();
75-
PublicKey expected = match.getServerKey();
76-
if (KeyUtils.compareKeys(expected, serverKey)) {
77-
return !"revoked".equals(entry.getMarker());
78-
}
76+
String serverKeyType = KeyUtils.getKeyType(serverKey);
7977

80-
return false;
78+
return matches.stream()
79+
.filter(match -> serverKeyType.equals(match.getHostEntry().getKeyEntry().getKeyType()))
80+
.filter(match -> KeyUtils.compareKeys(match.getServerKey(), serverKey))
81+
.anyMatch(match -> !"revoked".equals(match.getHostEntry().getMarker()));
8182
}
8283

8384
private static Supplier<Collection<KnownHostsServerKeyVerifier.HostEntryPair>> getKnownHostSupplier(
@@ -106,26 +107,32 @@ private static PublicKey resolveHostKey(KnownHostEntry entry) throws IOException
106107
return authEntry.resolvePublicKey(null, PublicKeyEntryResolver.IGNORING);
107108
}
108109

109-
private static KnownHostsServerKeyVerifier.HostEntryPair findKnownHostEntry(
110+
private static List<KnownHostsServerKeyVerifier.HostEntryPair> findKnownHostEntries(
110111
ClientSession clientSession, SocketAddress remoteAddress,
111112
Collection<KnownHostsServerKeyVerifier.HostEntryPair> knownHosts) {
112113

114+
if (GenericUtils.isEmpty(knownHosts)) {
115+
return Collections.emptyList();
116+
}
117+
113118
Collection<SshdSocketAddress> candidates = resolveHostNetworkIdentities(clientSession, remoteAddress);
114119

115120
if (GenericUtils.isEmpty(candidates)) {
116-
return null;
121+
return Collections.emptyList();
117122
}
118123

124+
List<KnownHostsServerKeyVerifier.HostEntryPair> matches = new ArrayList<>();
119125
for (KnownHostsServerKeyVerifier.HostEntryPair match : knownHosts) {
120126
KnownHostEntry entry = match.getHostEntry();
121127
for (SshdSocketAddress host : candidates) {
122128
if (entry.isHostMatch(host.getHostName(), host.getPort())) {
123-
return match;
129+
matches.add(match);
130+
break;
124131
}
125132
}
126133
}
127134

128-
return null; // no match found
135+
return matches;
129136
}
130137

131138
private static Collection<SshdSocketAddress> resolveHostNetworkIdentities(

spring-integration-sftp/src/test/java/org/springframework/integration/sftp/session/SftpSessionFactoryTests.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.io.File;
2020
import java.io.IOException;
2121
import java.net.ConnectException;
22+
import java.time.Duration;
2223
import java.util.ArrayList;
2324
import java.util.Collections;
2425
import java.util.List;
@@ -121,7 +122,7 @@ public void concurrentGetSessionDoesntCauseFailure() throws IOException {
121122
asyncTaskExecutor.execute(() -> concurrentSessions.add(sftpSessionFactory.getSession()));
122123
}
123124

124-
await().until(() -> concurrentSessions.size() == 3);
125+
await().atMost(Duration.ofSeconds(30)).until(() -> concurrentSessions.size() == 3);
125126

126127
assertThat(concurrentSessions.get(0))
127128
.isNotEqualTo(concurrentSessions.get(1))

0 commit comments

Comments
 (0)