/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.sshd.server.auth.keyboard; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.sshd.common.RuntimeSshException; import org.apache.sshd.common.SshConstants; import org.apache.sshd.common.SshException; import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.buffer.Buffer; import org.apache.sshd.server.auth.AbstractUserAuth; import org.apache.sshd.server.session.ServerSession; /** * Issue a "keyboard-interactive" command according to <A HREF="https://www.ietf.org/rfc/rfc4256.txt">RFC4256</A> * * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a> */ public class UserAuthKeyboardInteractive extends AbstractUserAuth { public static final String NAME = UserAuthKeyboardInteractiveFactory.NAME; public UserAuthKeyboardInteractive() { super(NAME); } @Override protected Boolean doAuth(Buffer buffer, boolean init) throws Exception { ServerSession session = getServerSession(); String username = getUsername(); KeyboardInteractiveAuthenticator auth = session.getKeyboardInteractiveAuthenticator(); if (init) { String lang = buffer.getString(); String subMethods = buffer.getString(); if (auth == null) { if (log.isDebugEnabled()) { log.debug("doAuth({}@{})[methods={}, lang={}] - no interactive authenticator to generate challenge", username, session, subMethods, lang); } return false; } InteractiveChallenge challenge; try { challenge = auth.generateChallenge(session, username, lang, subMethods); } catch (Error e) { log.warn("doAuth({}@{}) failed ({}) to generate authenticator challenge: {}", username, session, e.getClass().getSimpleName(), e.getMessage()); if (log.isDebugEnabled()) { log.debug("doAuth(" + username + "@" + session + ") authenticator challenge failure details", e); } throw new RuntimeSshException(e); } if (challenge == null) { if (log.isDebugEnabled()) { log.debug("doAuth({}@{})[methods={}, lang={}] - no interactive challenge generated", username, session, subMethods, lang); } return false; } if (log.isDebugEnabled()) { log.debug("doAuth({}@{})[methods={}, lang={}] challenge name={}, instruction={}, lang={}, num. prompts={}", username, session, subMethods, lang, challenge.getInteractionName(), challenge.getInteractionInstruction(), challenge.getLanguageTag(), GenericUtils.size(challenge.getPrompts())); } // Prompt for password buffer = session.createBuffer(SshConstants.SSH_MSG_USERAUTH_INFO_REQUEST); challenge.append(buffer); session.writePacket(buffer); return null; } else { int cmd = buffer.getUByte(); if (cmd != SshConstants.SSH_MSG_USERAUTH_INFO_RESPONSE) { throw new SshException("Received unexpected message: " + SshConstants.getCommandMessageName(cmd)); } int num = buffer.getInt(); List<String> responses = (num <= 0) ? Collections.emptyList() : new ArrayList<>(num); for (int index = 0; index < num; index++) { String value = buffer.getString(); if (log.isTraceEnabled()) { log.trace("doAuth({}@{}) response #{}: {}", username, session, index + 1, value); } responses.add(value); } if (auth == null) { if (log.isDebugEnabled()) { log.debug("doAuth({}@{}) no interactive authenticator to validate {} responses", username, session, num); } return false; } boolean authed; try { authed = auth.authenticate(session, username, responses); } catch (Error e) { log.warn("doAuth({}@{}) failed ({}) to consult authenticator: {}", username, session, e.getClass().getSimpleName(), e.getMessage()); if (log.isDebugEnabled()) { log.debug("doAuth(" + username + "@" + session + ") authenticator consultation failure details", e); } throw new RuntimeSshException(e); } if (log.isDebugEnabled()) { log.debug("doAuth({}@{}) authenticate {} responses result: {}", username, session, num, authed); } return authed; } } }