com.sshtools.ssh2.KBIAuthentication Maven / Gradle / Ivy
/**
* Copyright 2003-2016 SSHTOOLS Limited. All Rights Reserved.
*
* For product documentation visit https://www.sshtools.com/
*
* This file is part of J2SSH Maverick.
*
* J2SSH Maverick is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* J2SSH Maverick is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with J2SSH Maverick. If not, see .
*/
package com.sshtools.ssh2;
import java.io.IOException;
import com.sshtools.ssh.SshAuthentication;
import com.sshtools.ssh.SshException;
import com.sshtools.util.ByteArrayReader;
import com.sshtools.util.ByteArrayWriter;
/**
*
* keyboard-interactive authentication implementation as specified in
* draft-ietf-secsh-auth-kbdinteract-04.txt. Keyboard interactive provides a
* challenge-response type authentication which allows clients to support
* authentication mechanisms where the actual specification is not known.
*
*
*
* The process works by the client first requesting the keyboard-interactive
* method; the server then responds with any number of prompts to which the user
* must provide an answer. This is acheived through the use of the KBIRequestHandler interface.
*
*
*
*
* KBIAuthentication kbi = new KBIAuthentication();
*
* kbi.setKBIRequestHandler(new KBIRequestHandler() {
* public void showPrompts(String name, String instruction, KBIPrompt[] prompts) {
* try {
* System.out.println(name);
* System.out.println(instruction);
* for (int i = 0; i & ltprompts.length; i++) {
* System.out.print(prompts[i].getPrompt());
* prompts[i].setResponse(reader.readLine());
* }
* } catch (IOException e) {
* e.printStackTrace();
* }
* }
* });
*
* ssh.authenticate(kbi);
*
*
*
*
* Special care should be taken to check the echo flag of the KBIPrompt if set to false the user reponse
* entered by the user should not be echo'd back to the screen, for example in
* the process of entering a password.
*
*
* @author Lee David Painter
*/
public class KBIAuthentication implements AuthenticationClient {
String username;
KBIRequestHandler handler;
final static int SSH_MSG_USERAUTH_INFO_REQUEST = 60;
final static int SSH_MSG_USERAUTH_INFO_RESPONSE = 61;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getMethod() {
return "keyboard-interactive";
}
/**
* Set the KBIRequestHandler for this
* authentication attempt.
*
* @param handler
*/
public void setKBIRequestHandler(KBIRequestHandler handler) {
this.handler = handler;
}
public void authenticate(AuthenticationProtocol authentication,
String servicename) throws SshException, AuthenticationResult {
ByteArrayWriter baw = new ByteArrayWriter();
try {
if (handler == null) {
throw new SshException("A request handler must be set!",
SshException.BAD_API_USAGE);
}
// Send the authentication request
baw.writeString("");
baw.writeString("");
authentication.sendRequest(username, servicename,
"keyboard-interactive", baw.toByteArray());
// Read a message
while (true) {
byte[] msg = authentication.readMessage();
ByteArrayReader bar = new ByteArrayReader(msg);
try {
if (bar.read() != SSH_MSG_USERAUTH_INFO_REQUEST) {
authentication.transport.disconnect(
TransportProtocol.PROTOCOL_ERROR,
"Unexpected authentication message received!");
throw new SshException(
"Unexpected authentication message received!",
SshException.PROTOCOL_VIOLATION);
}
String name = bar.readString();
String instruction = bar.readString();
@SuppressWarnings("unused")
String langtag = bar.readString();
int num = (int) bar.readInt();
String prompt;
boolean echo;
KBIPrompt[] prompts = new KBIPrompt[num];
for (int i = 0; i < num; i++) {
prompt = bar.readString();
echo = (bar.read() == 1);
prompts[i] = new KBIPrompt(prompt, echo);
}
if (!handler.showPrompts(name, instruction, prompts)) {
throw new AuthenticationResult(
SshAuthentication.CANCELLED);
}
baw.reset();
baw.write(SSH_MSG_USERAUTH_INFO_RESPONSE);
baw.writeInt(prompts.length);
for (int i = 0; i < prompts.length; i++) {
baw.writeString(prompts[i].getResponse());
}
authentication.transport.sendMessage(baw.toByteArray(),
true);
} finally {
bar.close();
}
}
} catch (IOException ex) {
throw new SshException(ex, SshException.INTERNAL_ERROR);
} finally {
try {
baw.close();
} catch (IOException e) {
}
}
}
/**
*
* @return "keyboard-interactive"
*/
public String getMethodName() {
return "keyboard-interactive";
}
}