SSHClient supports keyboard interactive authentication as defined by RFC 4256. Depending on the requirements of the SSH server, it can be used instead of password authentication.
Keyboard interactive is a general purpose authentication method, suitable for interactive authentications where the authentication data is entered via a keyboard or equivalent alphanumeric input device. The major goal of this method is to allow the SSH client to support a whole class of authentication mechanisms without knowing the specifics of the actual authentication mechanisms.
In practical terms, with keyboard interactive authentication, the SSH server sends text prompts to the client. These prompts must be given a text answer to. The client sends the responses back to the server. If accepted, more prompts can be sent to the client for response or the authentication can be declared successful or failed.
The text prompts are arbitrary strings. There are no standard or predefined texts. The server decides the content of the prompts and what the required response is. As such, the SSHClient class cannot parse or process the prompts it receives as part of keyboard interactive authentication. Your application must process the prompts and supply responses programmatically or display the prompts to the end-user for them to type the responses.
To authenticate with keyboard interactive, call Authenticate with a userName and a KeyBoardInteractiveAuthenticationHandler delegate.
The delegate KeyBoardInteractiveAuthenticationHandler is a callback method that will be invoked as part of keyboard interactive authentication. It is defined as follows:
Where:
userName is the user name that was specified in the call to the Authenticate method.
name is a server-supplied string that may indicate a logical name for the series of requests. It can be an empty string, but it will not be null.
instruction is a server-supplied string that may indicate instructions on how to respond to the series of requests. It can be an empty string, but it will not be null.
languageTag is a string that specifies the language of the messages. In most cases, this parameter will be an empty string, and the language will be English.
requests is an array of KeyboardInteractiveRequest objects that specify the information prompts and their responses. The array will not be null. Each element in the array represents a prompt that must be answered. The response for each element is prefilled with an empty string. It is possible that the array will be empty, but it will not be null.
KeyboardInteractiveRequest is a simple class that holds the following properties:
Prompt is the server-supplied string that specifies what information is required. For example, it could be something like "Password:". There are no pre-defined prompt strings. The server can supply any text it wants here.
Echo is a boolean value that specifies whether the response to the prompt should be echoed to the screen. In general, this value will be false when the prompt refers to sensitive information like passwords and true otherwise.
Response is the string that will contain the response to the prompt. Your handler will set the this property's value. The string will then be sent back to the server for authentication. The response can be set to an empty string. If the property is set to null, an empty string will be sent back to the server.
Each request in the requests array represents a prompt. If the prompts are presented to an end-user, each prompt should be displayed to the user one by one and in order. The requests array will typically contain one prompt but it might contain more. The KeyBoardInteractiveAuthenticationHandler might be called again with more prompts. There is no predefined limit on the number of prompts that may be asked.
The KeyBoardInteractiveAuthenticationHandler will be invoked by the component on the same thread that Authenticate() was called on. Authenticate() will therefore block while it waits for the KeyBoardInteractiveAuthenticationHandler to return. The component does not impose any timeout on how long control can stay in the handler. However, be aware that some SSH servers enforce a limit on how long authentication takes. For example, the default limit on the OpenSSH server is 120 seconds.
If you are certain of the contents and formatting of the prompts you will receive from the server, you may implement a KeyBoardInteractiveAuthenticationHandler method that processes and answers the prompts automatically.
Consider this example for OpenSSH servers that use the ChallengeResponseAuthentication option:
Another way to approach this authentication is to display the prompts to the console and accept input for the answers.
Here's an example that puts it all together, with the exceptions that Authenticate
can throw when called for the keyboard interactive method.
Some servers require multiple authentications be used to log in. Here is an example that chains different authentications one after the other.