This is an automated email from the ASF dual-hosted git repository. lgoldstein pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
commit f4aa59fd93aa8a17a7853cc397607aec081e73b9 Author: Lyor Goldstein <lgoldst...@apache.org> AuthorDate: Fri Jan 1 08:38:10 2021 +0200 [SSHD-1114] Added HostBasedAuthenticationReporter#signalAuthenticationExhausted --- docs/client-setup.md | 6 +++--- .../hostbased/HostBasedAuthenticationReporter.java | 18 ++++++++++++++++ .../client/auth/hostbased/UserAuthHostBased.java | 25 +++++++++++++--------- .../sshd/client/auth/pubkey/UserAuthPublicKey.java | 3 +-- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/docs/client-setup.md b/docs/client-setup.md index 7f71922..0fc059e 100644 --- a/docs/client-setup.md +++ b/docs/client-setup.md @@ -100,9 +100,9 @@ This interface is required for full support of `keyboard-interactive` authentica The client can handle a simple password request from the server, but if more complex challenge-response interaction is required, then this interface must be provided - including support for `SSH_MSG_USERAUTH_PASSWD_CHANGEREQ` as described in [RFC 4252 section 8](https://tools.ietf.org/html/rfc4252#section-8). -While RFC-4256 support is the primary purpose of this interface, it can also be used to retrieve the server's welcome banner as described -in [RFC 4252 section 5.4](https://tools.ietf.org/html/rfc4252#section-5.4) as well as its initial identification string as described -in [RFC 4253 section 4.2](https://tools.ietf.org/html/rfc4253#section-4.2). +While ]RFC-4256](https://tools.ietf.org/html/rfc4256) support is the primary purpose of this interface, it can also be used to retrieve the server's +welcome banner as described in [RFC 4252 section 5.4](https://tools.ietf.org/html/rfc4252#section-5.4) as well as its initial identification string +as described in [RFC 4253 section 4.2](https://tools.ietf.org/html/rfc4253#section-4.2). In this context, regardless of whether such interaction is configured, the default implementation for the client side contains code that attempts to auto-detect a password prompt. If it detects it, then it attempts to use one of the registered passwords (if any) as diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/hostbased/HostBasedAuthenticationReporter.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/hostbased/HostBasedAuthenticationReporter.java index 18c2193..749b5bc 100644 --- a/sshd-core/src/main/java/org/apache/sshd/client/auth/hostbased/HostBasedAuthenticationReporter.java +++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/hostbased/HostBasedAuthenticationReporter.java @@ -49,6 +49,24 @@ public interface HostBasedAuthenticationReporter { } /** + * Signals end of host based attempts and optionally switching to other authentication methods. <B>Note:</B> neither + * {@link #signalAuthenticationSuccess(ClientSession, String, KeyPair, String, String) signalAuthenticationSuccess} + * nor {@link #signalAuthenticationFailure(ClientSession, String, KeyPair, String, String, boolean, List) + * signalAuthenticationFailure} are invoked. + * + * @param session The {@link ClientSession} + * @param service The requesting service name + * @param hostname The host name value sent to the server + * @param username The username value sent to the server + * @throws Exception If failed to handle the callback - <B>Note:</B> may cause session close + */ + default void signalAuthenticationExhausted( + ClientSession session, String service, String hostname, String username) + throws Exception { + // ignored + } + + /** * @param session The {@link ClientSession} * @param service The requesting service name * @param identity The {@link KeyPair} identity being attempted diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/hostbased/UserAuthHostBased.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/hostbased/UserAuthHostBased.java index 5c18b5f..2e9ded2 100644 --- a/sshd-core/src/main/java/org/apache/sshd/client/auth/hostbased/UserAuthHostBased.java +++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/hostbased/UserAuthHostBased.java @@ -96,15 +96,22 @@ public class UserAuthHostBased extends AbstractUserAuth implements SignatureFact protected boolean sendAuthDataRequest(ClientSession session, String service) throws Exception { String name = getName(); boolean debugEnabled = log.isDebugEnabled(); - if ((keys == null) || (!keys.hasNext())) { + String clientUsername = resolveClientUsername(session); + String clientHostname = resolveClientHostname(session); + HostBasedAuthenticationReporter reporter = session.getHostBasedAuthenticationReporter(); + keyInfo = ((keys != null) && keys.hasNext()) ? keys.next() : null; + if (keyInfo == null) { if (debugEnabled) { log.debug("sendAuthDataRequest({})[{}][{}] no more keys to send", session, service, name); } + if (reporter != null) { + reporter.signalAuthenticationExhausted(session, service, clientUsername, clientHostname); + } + return false; } - keyInfo = keys.next(); KeyPair kp = keyInfo.getKey(); PublicKey pub = kp.getPublic(); String keyType = KeyUtils.getKeyType(pub); @@ -124,8 +131,6 @@ public class UserAuthHostBased extends AbstractUserAuth implements SignatureFact byte[] id = session.getSessionId(); String username = session.getUsername(); - String clientUsername = resolveClientUsername(); - String clientHostname = resolveClientHostname(); if (debugEnabled) { log.debug("sendAuthDataRequest({})[{}][{}] client={}@{}", session, service, name, clientUsername, clientHostname); @@ -164,7 +169,6 @@ public class UserAuthHostBased extends AbstractUserAuth implements SignatureFact byte[] signature = appendSignature( session, service, keyType, pub, keyBytes, clientHostname, clientUsername, verifier, buffer); - HostBasedAuthenticationReporter reporter = session.getHostBasedAuthenticationReporter(); if (reporter != null) { reporter.signalAuthenticationAttempt( session, service, kp, clientHostname, clientUsername, signature); @@ -231,8 +235,8 @@ public class UserAuthHostBased extends AbstractUserAuth implements SignatureFact HostBasedAuthenticationReporter reporter = session.getHostBasedAuthenticationReporter(); if (reporter != null) { reporter.signalAuthenticationSuccess( - session, service, (keyInfo == null) ? null : keyInfo.getKey(), resolveClientHostname(), - resolveClientUsername()); + session, service, (keyInfo == null) ? null : keyInfo.getKey(), + resolveClientHostname(session), resolveClientUsername(session)); } } @@ -244,16 +248,17 @@ public class UserAuthHostBased extends AbstractUserAuth implements SignatureFact if (reporter != null) { reporter.signalAuthenticationFailure( session, service, (keyInfo == null) ? null : keyInfo.getKey(), - resolveClientHostname(), resolveClientUsername(), partial, serverMethods); + resolveClientHostname(session), resolveClientUsername(session), + partial, serverMethods); } } - protected String resolveClientUsername() { + protected String resolveClientUsername(ClientSession session) { String value = getClientUsername(); return GenericUtils.isEmpty(value) ? OsUtils.getCurrentUser() : value; } - protected String resolveClientHostname() { + protected String resolveClientHostname(ClientSession session) { String value = getClientHostname(); if (GenericUtils.isEmpty(value)) { value = SshdSocketAddress.toAddressString( diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKey.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKey.java index 26ee56d..f55fc4e 100644 --- a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKey.java +++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKey.java @@ -101,12 +101,12 @@ public class UserAuthPublicKey extends AbstractUserAuth implements SignatureFact throw new RuntimeSshException(e); } + PublicKeyAuthenticationReporter reporter = session.getPublicKeyAuthenticationReporter(); if (current == null) { if (debugEnabled) { log.debug("resolveAttemptedPublicKeyIdentity({})[{}] no more keys to send", session, service); } - PublicKeyAuthenticationReporter reporter = session.getPublicKeyAuthenticationReporter(); if (reporter != null) { reporter.signalAuthenticationExhausted(session, service); } @@ -145,7 +145,6 @@ public class UserAuthPublicKey extends AbstractUserAuth implements SignatureFact session, service, name, algo, KeyUtils.getFingerPrint(pubKey)); } - PublicKeyAuthenticationReporter reporter = session.getPublicKeyAuthenticationReporter(); if (reporter != null) { reporter.signalAuthenticationAttempt(session, service, keyPair, algo); }