in sshd-cli/src/main/java/org/apache/sshd/cli/client/SshKeyScanMain.java [181:297]
public Void call() throws Exception {
ValidateUtils.checkTrue(isOpen(), "Scanner is closed");
Collection<String> typeNames = getKeyTypes();
Map<String, List<KeyPair>> pairsMap = createKeyPairs(typeNames);
/*
* We will need to switch signature factories for each specific key type in order to force the server to send
* ONLY that specific key, so pre-create the factories map according to the selected key types
*/
SortedMap<String, List<NamedFactory<Signature>>> sigFactories = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
Collection<String> sigTypes = GenericUtils.asSortedSet(sigFactories.comparator(), pairsMap.keySet());
for (String kt : sigTypes) {
List<NamedFactory<Signature>> factories = resolveSignatureFactories(kt);
if (GenericUtils.isEmpty(factories)) {
if (isEnabledLevel(Level.FINEST)) {
log(Level.FINEST, "Skip empty signature factories for " + kt);
}
pairsMap.remove(kt);
} else {
sigFactories.put(kt, factories);
}
}
ValidateUtils.checkTrue(!MapEntryUtils.isEmpty(pairsMap), "No client key pairs");
ValidateUtils.checkTrue(!MapEntryUtils.isEmpty(sigFactories), "No signature factories");
Exception err = null;
try {
ValidateUtils.checkTrue(client == null, "Client still active");
client = SshClient.setUpDefaultClient();
client.setServerKeyVerifier(this);
try (BufferedReader rdr = new BufferedReader(new InputStreamReader(getInputStream(), StandardCharsets.UTF_8))) {
client.setUserInteraction(new UserInteraction() {
@Override
public boolean isInteractionAllowed(ClientSession session) {
return true;
}
@Override
public String[] interactive(
ClientSession session, String name, String instruction,
String lang, String[] prompt, boolean[] echo) {
return null;
}
@Override
public String getUpdatedPassword(ClientSession session, String prompt, String lang) {
return null;
}
@Override
public void serverVersionInfo(ClientSession session, List<String> lines) {
if (isEnabledLevel(Level.FINE) && GenericUtils.isNotEmpty(lines)) {
for (String l : lines) {
log(Level.FINE, "Server Info: " + l);
}
}
}
@Override
public void welcome(ClientSession session, String banner, String lang) {
if (isEnabledLevel(Level.FINE) && GenericUtils.isNotEmpty(banner)) {
String[] lines = GenericUtils.split(banner, '\n');
for (String l : lines) {
log(Level.FINE, "Welcome[" + lang + "]: " + l);
}
}
}
});
client.start();
for (String line = rdr.readLine(); line != null; line = rdr.readLine()) {
line = GenericUtils.replaceWhitespaceAndTrim(line);
String[] hosts = GenericUtils.split(line, ',');
if (GenericUtils.isEmpty(hosts)) {
continue;
}
for (String h : hosts) {
if (!isOpen()) {
throw new InterruptedIOException("Closed while preparing to contact host=" + h);
}
try {
resolveServerKeys(client, h, pairsMap, sigFactories);
} catch (Exception e) {
// check if interrupted while scanning host keys
if (e instanceof InterruptedIOException) {
throw e;
}
if (isEnabledLevel(Level.FINE)) {
log(Level.FINE, "Failed to retrieve keys from " + h, e);
}
err = ExceptionUtils.accumulateException(err, e);
} finally {
currentHostFingerprints.clear();
}
}
}
}
} finally {
try {
close();
} catch (IOException e) {
err = ExceptionUtils.accumulateException(err, e);
}
}
if (err != null) {
throw err;
}
return null;
}