public Void call()

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;
    }