protected void processUserAuth()

in sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java [285:394]


    protected void processUserAuth(int cmd, Buffer buffer, AuthFuture authFuture) throws Exception {
        ClientSession session = getClientSession();
        if (cmd == SshConstants.SSH_MSG_USERAUTH_SUCCESS) {
            if (log.isDebugEnabled()) {
                log.debug("processUserAuth({}) SSH_MSG_USERAUTH_SUCCESS Succeeded with {}",
                        session, (currentUserAuth == null) ? "<unknown>" : currentUserAuth.getName());
            }

            if (currentUserAuth != null) {
                try {
                    currentUserAuth.signalAuthMethodSuccess(session, service, buffer);
                } finally {
                    clearUserAuth();
                }
            } else {
                destroyPubkeyAuth();
            }
            session.setAuthenticated();
            ((ClientSessionImpl) session).switchToNextService();

            // Will wake up anyone sitting in waitFor
            authFuture.setAuthed(true);
            return;
        }

        authFuture.setCancellable(true);
        if (authFuture.isCanceled()) {
            authFuture.getCancellation().setCanceled();
            clearUserAuth();
            return;
        }
        if (cmd == SshConstants.SSH_MSG_USERAUTH_FAILURE) {
            String methods = buffer.getString();
            boolean partial = buffer.getBoolean();
            if (log.isDebugEnabled()) {
                log.debug("processUserAuth({}) Received SSH_MSG_USERAUTH_FAILURE - partial={}, methods={}",
                        session, partial, methods);
            }
            List<String> allowedMethods;
            if (GenericUtils.isEmpty(methods)) {
                if (serverMethods == null) {
                    // RFC 4252 section 5.2 says that in the SSH_MSG_USERAUTH_FAILURE response
                    // to a 'none' request a server MAY return a list of methods. Here it didn't,
                    // so we just assume all methods that the client knows are fine.
                    //
                    // https://datatracker.ietf.org/doc/html/rfc4252#section-5.2
                    allowedMethods = new ArrayList<>(clientMethods);
                } else if (partial) {
                    // Don't reset to an empty list; keep going with the previous methods. Sending
                    // a partial success without methods that may continue makes no sense and would
                    // be a server bug.
                    //
                    // currentUserAuth should always be set here!
                    if (log.isDebugEnabled()) {
                        log.debug(
                                "processUserAuth({}) : potential bug in {} server: SSH_MSG_USERAUTH_FAILURE with partial success after {} authentication, but without continuation methods",
                                session, session.getServerVersion(),
                                currentUserAuth != null ? currentUserAuth.getName() : "UNKNOWN");
                    }
                    allowedMethods = serverMethods;
                } else {
                    allowedMethods = new ArrayList<>();
                }
            } else {
                allowedMethods = Arrays.asList(GenericUtils.split(methods, ','));
            }
            if (currentUserAuth != null) {
                try {
                    currentUserAuth.signalAuthMethodFailure(session, service, partial,
                            Collections.unmodifiableList(allowedMethods), buffer);
                } catch (Exception e) {
                    clearUserAuth();
                    throw e;
                }

                // Check if the current method is still allowed.
                if (allowedMethods.indexOf(currentUserAuth.getName()) < 0) {
                    if (currentUserAuth == pubkeyAuth) {
                        // Don't destroy it yet, we might still need it later on
                        currentUserAuth = null;
                    } else {
                        destroyUserAuth();
                    }
                }
            }
            if (partial || (serverMethods == null)) {
                currentMethod = 0;
            }
            serverMethods = allowedMethods;

            tryNext(cmd, authFuture);
            return;
        }

        if (currentUserAuth == null) {
            throw new IllegalStateException("Received unknown packet: " + SshConstants.getCommandMessageName(cmd));
        }

        if (log.isDebugEnabled()) {
            log.debug("processUserAuth({}) delegate processing of {} to {}",
                    session, SshConstants.getCommandMessageName(cmd), currentUserAuth.getName());
        }

        buffer.rpos(buffer.rpos() - 1);
        if (!currentUserAuth.process(buffer)) {
            tryNext(cmd, authFuture);
        } else {
            authFuture.setCancellable(currentUserAuth.isCancellable());
        }
    }