in sshd-core/src/main/java/org/apache/sshd/server/session/ServerUserAuthService.java [206:342]
protected boolean handleUserAuthRequestMessage(
ServerSession session, Buffer buffer, AtomicReference<Boolean> authHolder)
throws Exception {
boolean debugEnabled = log.isDebugEnabled();
/*
* According to RFC4252 section 5.1:
*
*
* When SSH_MSG_USERAUTH_SUCCESS has been sent, any further authentication requests received after that SHOULD
* be silently ignored.
*/
if (session.isAuthenticated()) {
String username = buffer.getString();
String service = buffer.getString();
String method = buffer.getString();
if (debugEnabled) {
log.debug("handleUserAuthRequestMessage({}) ignore user={}, service={}, method={}"
+ " auth. request since session already authenticated",
session, username, service, method);
}
return false;
}
if (WelcomeBannerPhase.FIRST_REQUEST.equals(getWelcomePhase())) {
sendWelcomeBanner(session);
}
if (currentAuth != null) {
try {
currentAuth.destroy();
} finally {
currentAuth = null;
}
}
String username = buffer.getString();
String service = buffer.getString();
String method = buffer.getString();
if (debugEnabled) {
log.debug("handleUserAuthRequestMessage({}) Received SSH_MSG_USERAUTH_REQUEST user={}, service={}, method={}",
session, username, service, method);
}
if ((this.authUserName == null) || (this.authService == null)) {
this.authUserName = username;
this.authService = service;
} else if (this.authUserName.equals(username) && this.authService.equals(service)) {
nbAuthRequests++;
if (nbAuthRequests > maxAuthRequests) {
boolean disconnectSession = true;
try {
SessionDisconnectHandler handler = session.getSessionDisconnectHandler();
disconnectSession = (handler == null)
|| (!handler.handleAuthCountDisconnectReason(
session, this, service, method, username, nbAuthRequests, maxAuthRequests));
} catch (IOException | RuntimeException e) {
warn("handleUserAuthRequestMessage({}) failed ({}) to invoke disconnect handler due to"
+ " user={}/{}, service={}/{} - {}/{} auth requests: {}",
session, e.getClass().getSimpleName(),
this.authUserName, username, this.authService, service,
nbAuthRequests, maxAuthRequests, e.getMessage(), e);
}
if (disconnectSession) {
session.disconnect(SshConstants.SSH2_DISCONNECT_PROTOCOL_ERROR,
"Too many authentication failures: " + nbAuthRequests);
return false;
}
if (debugEnabled) {
log.debug(
"handleUserAuthRequestMessage({}) ignore mismatched authentication counts: user={}/{}, service={}/{}: {}/{}",
session, this.authUserName, username, this.authService, service, nbAuthRequests, maxAuthRequests);
}
}
} else {
boolean disconnectSession = true;
try {
SessionDisconnectHandler handler = session.getSessionDisconnectHandler();
disconnectSession = (handler == null)
|| (!handler.handleAuthParamsDisconnectReason(
session, this, this.authUserName, username, this.authService, service));
} catch (IOException | RuntimeException e) {
warn("handleUserAuthRequestMessage({}) failed ({}) to invoke disconnect handler due to"
+ " user={}/{}, service={}/{} mismatched parameters: {}",
session, e.getClass().getSimpleName(),
this.authUserName, username, this.authService, service, e.getMessage(), e);
}
if (disconnectSession) {
session.disconnect(SshConstants.SSH2_DISCONNECT_PROTOCOL_ERROR,
"Change of username or service is not allowed (" + this.authUserName + ", " + this.authService + ")"
+ " -> (" + username + ", " + service + ")");
} else {
if (debugEnabled) {
log.debug(
"handleUserAuthRequestMessage({}) ignore mismatched authentication parameters: user={}/{}, service={}/{}",
session, this.authUserName, username, this.authService, service);
}
}
return false;
}
// TODO: verify that the service is supported
this.authMethod = method;
if (debugEnabled) {
log.debug(
"handleUserAuthRequestMessage({}) Authenticating user '{}' with service '{}' and method '{}' (attempt {} / {})",
session, username, service, method, nbAuthRequests, maxAuthRequests);
}
UserAuthFactory factory = NamedResource.findByName(
method, String.CASE_INSENSITIVE_ORDER, userAuthFactories);
if (factory == null) {
if (debugEnabled) {
log.debug("handleUserAuthRequestMessage({}) no authentication factory for method={}", session, method);
}
return true;
}
currentAuth = ValidateUtils.checkNotNull(
factory.createUserAuth(session), "No authenticator created for method=%s", method);
try {
Boolean authed = currentAuth.auth(session, username, service, buffer);
authHolder.set(authed);
} catch (AsyncAuthException async) {
async.addListener(authenticated -> asyncAuth(SshConstants.SSH_MSG_USERAUTH_REQUEST, buffer, authenticated));
return false;
} catch (Exception e) {
warn("handleUserAuthRequestMessage({}) Failed ({}) to authenticate using factory method={}: {}",
session, e.getClass().getSimpleName(), method, e.getMessage(), e);
}
return true;
}