KnownHostsServerKeyVerifier verifier = new DefaultKnownHostsServerKeyVerifier(new ServerKeyVerifier() { @Override public boolean verifyServerKey(ClientSession clientSession, SocketAddress remoteAddress, PublicKey serverKey) {
@Override public final boolean verifyServerKey(ClientSession sshClientSession, SocketAddress remoteAddress, PublicKey serverKey) { boolean accepted = isAccepted(); if (accepted) { handleAcceptance(sshClientSession, remoteAddress, serverKey); } else { handleRejection(sshClientSession, remoteAddress, serverKey); } return accepted; }
@Override protected Collection<SshdSocketAddress> resolveHostNetworkIdentities( ClientSession clientSession, SocketAddress remoteAddress) { // Make this method accessible return super.resolveHostNetworkIdentities(clientSession, remoteAddress); } }
@Override public boolean verifyServerKey(ClientSession clientSession, SocketAddress remoteAddress, PublicKey serverKey) { Collection<HostEntryPair> knownHosts = getLoadedHostsEntries(); try { if (checkReloadRequired()) { Path file = getPath(); if (exists()) { knownHosts = reloadKnownHosts(file); } else { if (log.isDebugEnabled()) { log.debug("verifyServerKey({})[{}] missing known hosts file {}", clientSession, remoteAddress, file); } knownHosts = Collections.emptyList(); } setLoadedHostsEntries(knownHosts); } } catch (Throwable t) { return acceptIncompleteHostKeys(clientSession, remoteAddress, serverKey, t); } return acceptKnownHostEntries(clientSession, remoteAddress, serverKey, knownHosts); }
protected boolean acceptKnownHostEntries( ClientSession clientSession, SocketAddress remoteAddress, PublicKey serverKey, Collection<HostEntryPair> knownHosts) { HostEntryPair match = findKnownHostEntry(clientSession, remoteAddress, knownHosts); if (match == null) { return acceptUnknownHostKey(clientSession, remoteAddress, serverKey); KnownHostEntry entry = match.getHostEntry(); PublicKey expected = match.getServerKey(); if (KeyUtils.compareKeys(expected, serverKey)) { return acceptKnownHostEntry(clientSession, remoteAddress, serverKey, entry); if (!acceptModifiedServerKey(clientSession, remoteAddress, entry, expected, serverKey)) { return false; Path file = getPath(); try { updateModifiedServerKey(clientSession, remoteAddress, match, serverKey, file, knownHosts); } catch (Throwable t) { handleModifiedServerKeyUpdateFailure(clientSession, remoteAddress, match, serverKey, file, knownHosts, t);
/** * Invoked if none of the known hosts matches the current one - by default invokes the delegate. * If the delegate accepts the key, then it is <U>appended</U> to the currently monitored entries * and the file is updated * * @param clientSession The {@link ClientSession} * @param remoteAddress The remote host address * @param serverKey The presented server {@link PublicKey} * @return {@code true} if accept the server key * @see #updateKnownHostsFile(ClientSession, SocketAddress, PublicKey, Path, Collection) * @see #handleKnownHostsFileUpdateFailure(ClientSession, SocketAddress, PublicKey, Path, Collection, Throwable) */ protected boolean acceptUnknownHostKey(ClientSession clientSession, SocketAddress remoteAddress, PublicKey serverKey) { if (log.isDebugEnabled()) { log.debug("acceptUnknownHostKey({}) host={}, key={}", clientSession, remoteAddress, KeyUtils.getFingerPrint(serverKey)); } if (delegate.verifyServerKey(clientSession, remoteAddress, serverKey)) { Path file = getPath(); Collection<HostEntryPair> keys = getLoadedHostsEntries(); try { updateKnownHostsFile(clientSession, remoteAddress, serverKey, file, keys); } catch (Throwable t) { handleKnownHostsFileUpdateFailure(clientSession, remoteAddress, serverKey, file, keys, t); } return true; } return false; }
@Override protected List<HostEntryPair> reloadKnownHosts(Path file) throws IOException, GeneralSecurityException { if (isStrict()) { if (log.isDebugEnabled()) { log.debug("reloadKnownHosts({}) check permissions", file); } Map.Entry<String, ?> violation = validateStrictConfigFilePermissions(file); if (violation != null) { log.warn("reloadKnownHosts({}) invalid file permissions: {}", file, violation.getKey()); updateReloadAttributes(); return Collections.emptyList(); } } return super.reloadKnownHosts(file); } }
@Override public boolean acceptModifiedServerKey(ClientSession clientSession, SocketAddress remoteAddress, KnownHostEntry entry, PublicKey expected, PublicKey actual) throws Exception { ModifiedServerKeyAcceptor acceptor = getModifiedServerKeyAcceptor(); if (acceptor != null) { return acceptor.acceptModifiedServerKey(clientSession, remoteAddress, entry, expected, actual); } log.warn("acceptModifiedServerKey({}) mismatched keys presented by {} for entry={}: expected={}-{}, actual={}-{}", clientSession, remoteAddress, entry, KeyUtils.getKeyType(expected), KeyUtils.getFingerPrint(expected), KeyUtils.getKeyType(actual), KeyUtils.getFingerPrint(actual)); return false; } }
@Override public boolean verifyServerKey(ClientSession sshClientSession, SocketAddress remoteAddress, PublicKey serverKey) { Map<Object, Object> metadataMap = sshClientSession.getMetadataMap(); Object verifier = metadataMap.get(ServerKeyVerifier.class); if (verifier == null) { if (log.isTraceEnabled()) { log.trace("verifyServerKey(" + remoteAddress + ") No verifier found in ClientSession metadata; accepting server key"); } return true; } // We throw if it's not a ServerKeyVerifier... return ((ServerKeyVerifier) verifier).verifyServerKey(sshClientSession, remoteAddress, serverKey); } }
@Override public String toString() { return String.valueOf(getHostEntry()); } }
@Override protected KnownHostEntry prepareKnownHostEntry( ClientSession clientSession, SocketAddress remoteAddress, PublicKey serverKey) throws IOException { // Make this method accessible try { return super.prepareKnownHostEntry(clientSession, remoteAddress, serverKey); } catch (Exception e) { throw new IOException(e.getMessage(), e); } }
@Override protected String prepareModifiedServerKeyLine( ClientSession clientSession, SocketAddress remoteAddress, KnownHostEntry entry, String curLine, PublicKey expected, PublicKey actual) throws IOException { // Make this method accessible try { return super.prepareModifiedServerKeyLine(clientSession, remoteAddress, entry, curLine, expected, actual); } catch (Exception e) { throw new IOException(e.getMessage(), e); } }
@Override public boolean verifyServerKey(ClientSession clientSession, SocketAddress remoteAddress, PublicKey serverKey) { Collection<HostEntryPair> knownHosts = getLoadedHostsEntries(); try { if (checkReloadRequired()) { Path file = getPath(); if (exists()) { knownHosts = reloadKnownHosts(clientSession, file); } else { if (log.isDebugEnabled()) { log.debug("verifyServerKey({})[{}] missing known hosts file {}", clientSession, remoteAddress, file); } knownHosts = Collections.emptyList(); } setLoadedHostsEntries(knownHosts); } } catch (Throwable t) { return acceptIncompleteHostKeys(clientSession, remoteAddress, serverKey, t); } return acceptKnownHostEntries(clientSession, remoteAddress, serverKey, knownHosts); }
/** * Invoked if none of the known hosts matches the current one - by default invokes the delegate. * If the delegate accepts the key, then it is <U>appended</U> to the currently monitored entries * and the file is updated * * @param clientSession The {@link ClientSession} * @param remoteAddress The remote host address * @param serverKey The presented server {@link PublicKey} * @return {@code true} if accept the server key * @see #updateKnownHostsFile(ClientSession, SocketAddress, PublicKey, Path, Collection) * @see #handleKnownHostsFileUpdateFailure(ClientSession, SocketAddress, PublicKey, Path, Collection, Throwable) */ protected boolean acceptUnknownHostKey(ClientSession clientSession, SocketAddress remoteAddress, PublicKey serverKey) { if (log.isDebugEnabled()) { log.debug("acceptUnknownHostKey({}) host={}, key={}", clientSession, remoteAddress, KeyUtils.getFingerPrint(serverKey)); } if (delegate.verifyServerKey(clientSession, remoteAddress, serverKey)) { Path file = getPath(); Collection<HostEntryPair> keys = getLoadedHostsEntries(); try { updateKnownHostsFile(clientSession, remoteAddress, serverKey, file, keys); } catch (Throwable t) { handleKnownHostsFileUpdateFailure(clientSession, remoteAddress, serverKey, file, keys, t); } return true; } return false; }
@Override protected List<HostEntryPair> reloadKnownHosts(ClientSession session, Path file) throws IOException, GeneralSecurityException { if (isStrict()) { if (log.isDebugEnabled()) { log.debug("reloadKnownHosts({}) check permissions", file); } Map.Entry<String, ?> violation = validateStrictConfigFilePermissions(file); if (violation != null) { log.warn("reloadKnownHosts({}) invalid file permissions: {}", file, violation.getKey()); updateReloadAttributes(); return Collections.emptyList(); } } return super.reloadKnownHosts(session, file); } }
@Override public final boolean verifyServerKey(ClientSession sshClientSession, SocketAddress remoteAddress, PublicKey serverKey) { boolean accepted = isAccepted(); if (accepted) { handleAcceptance(sshClientSession, remoteAddress, serverKey); } else { handleRejection(sshClientSession, remoteAddress, serverKey); } return accepted; }
@Override public boolean acceptModifiedServerKey(ClientSession clientSession, SocketAddress remoteAddress, KnownHostEntry entry, PublicKey expected, PublicKey actual) throws Exception { ModifiedServerKeyAcceptor acceptor = getModifiedServerKeyAcceptor(); if (acceptor != null) { return acceptor.acceptModifiedServerKey(clientSession, remoteAddress, entry, expected, actual); } log.warn("acceptModifiedServerKey({}) mismatched keys presented by {} for entry={}: expected={}-{}, actual={}-{}", clientSession, remoteAddress, entry, KeyUtils.getKeyType(expected), KeyUtils.getFingerPrint(expected), KeyUtils.getKeyType(actual), KeyUtils.getFingerPrint(actual)); return false; } }
@Override public boolean verifyServerKey(ClientSession sshClientSession, SocketAddress remoteAddress, PublicKey serverKey) { Map<Object, Object> metadataMap = sshClientSession.getMetadataMap(); Object verifier = metadataMap.get(ServerKeyVerifier.class); if (verifier == null) { if (log.isTraceEnabled()) { log.trace("verifyServerKey(" + remoteAddress + ") No verifier found in ClientSession metadata; accepting server key"); } return true; } // We throw if it's not a ServerKeyVerifier... return ((ServerKeyVerifier) verifier).verifyServerKey(sshClientSession, remoteAddress, serverKey); } }
@Override public String toString() { return String.valueOf(getHostEntry()); } }
@Override protected void checkKeys() throws SshException { ServerKeyVerifier serverKeyVerifier = getServerKeyVerifier(); // The super implementation always uses // getIoSession().getRemoteAddress(). In case of a proxy connection, // that would be the address of the proxy! SocketAddress remoteAddress = getConnectAddress(); PublicKey serverKey = getKex().getServerKey(); if (!serverKeyVerifier.verifyServerKey(this, remoteAddress, serverKey)) { throw new SshException( org.apache.sshd.common.SshConstants.SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE, SshdText.get().kexServerKeyInvalid); } }