J2SSH - Advanced Connectivity

Connection Properties
Connection Profiles
Monitoring the Connection State
Verifying the Server's Host Key

Connection Properties

Each SSH connection has a number of components, they include encryption ciphers, message authentication algorithms and compression settings. The SSH protocol states that these components must run independently of each other in both directions on the connection. The following class makes it possible to configure these settings:

import com.sshtools.j2ssh.configuration.SshConnectionProperties

When using the SshClient connect method, it is possible to pass an SshConnectionProperties instance instead of
a hostname.

SshConnectionProperties properties = new SshConnectionProperties();
properties.setHost("firestar"); properties.setPort(22);
ssh.connect(properties);

There are additional methods to set the preferred ciphers:

// Sets the preferred client->server encryption cipher
properties.setPrefCSEncryption("blowfish-cbc");
// Sets the preferred server->client encryption cipher properties.setPrefSCEncryption("3des-cbc");

The parameter passed should be the name of the SSH cipher that you require, this can be any installed cipher, the following are currently supported.

• 3des-cbc
• blowfish-cbc
• twofish256-cbc*
• twofish196-cbc*
• twofish128-cbc*
• aes256-cbc*
• aes196-cbc*
• aes128-cbc*
• cast128-cbc*

* Installed as part of the Bouncy Castle cipher extensions package

In the same way you can set the message authentication algorithms for each direction of the connection:

//Sets the preferred client->server message authenticaiton
properties.setPrefCSMac("hmac-sha1");
// Sets the preferred server->client message authentication properties.setPrefSCMac("hmac-md5");

The following message authentication algorithms are currently supported:

• hmac-sha1
• hmac-sha1-96
• hmac-md5
• hmac-md5-96

You can set the preferred server host key for server authentication using:

// Set the preferred server host key
properties.setPrefPublicKey("ssh-rsa");

The following public-key algorithms are supported:

• ssh-dss DSA public keys
• ssh-rsa RSA public keys

Back to top


Connection Profiles

J2SSH includes a connection profile class that is more useful for more advanced purposes such as graphical
front-ends and automating authentication procedures.

import com.sshtools.j2ssh.util.SshtoolsConnectionProfile;

This class can output to XML and so provides a mechanism for storing connection details. It has a number of
useful methods that allow application level settings to be stored alongside the existing SSH connection properties.

Back to top

Monitoring the Connection State

It is possible to monitor the connection state in order to determine whether a session is active, or disconnected.
A number of other connection states may also be tested for.

import com.sshtools.j2ssh.transport.TransportProtocolState;
import com.sshtools.j2ssh.SshClient;
...
SshClient ssh = new SshClient(); ...
TransportProtocolState state = ssh.getConnectionState();
if (state.getValue()==TransportProtocolState.DISCONNECTED) { System.out.println("Transport protocol has disconnected!"); }

The following states are available, you will be mostly concerned with the connected and disconnected states, but
it is possible for the protocol to not have a CONNECTED state but still be connected. When trying to determine
the current connection state it should always be evaluated against the DISCONNECTED state.

/**
* the transport protocol is uninitialized
*/
public final static int UNINITIALIZED = 1;
/** * the transport protocol is connected and negotiating the protocol version */ public final static int NEGOTIATING_PROTOCOL = 2;
/** * the transport protocol is performing key exchange */ public final static int PERFORMING_KEYEXCHANGE = 3;
/** * the transport protocol is connected */ public final static int CONNECTED = 4;
/** * the transport protocol is disconnected */ public final static int DISCONNECTED = 5;

It is possible to wait for a specific state, there are a number of methods available that will cause the current thread to wait until the required state has been reached.

// To wait for a specific state
state.waitForState(TransportProtocolState.DISCONNECTED);

// To wait for a state update
state.waitForStateUpdate();
Back to top

Verifying the Server Host Key

When the client connects to the server, the server supplies its public key for the client to verify. You will have already seen that calling SshClient.connect prompts the user within the console to verify the key:

The host firestar is currently unknown to the system
The host key fingerprint is: 1028: 69 54 9c 49 e5 92 59 40 5 66 c5 2e 9d 86 af ed
Do you want to allow this host key? [Yes|No|Always]:

In the default implementation J2SSH reads the $HOME/.ssh/known_hosts file to determine which hosts connections may be allowed or denied. This is provided by the class ConsoleKnownHostsKeyVerification and the default behaviour can be emulated by the following code:

import com.sshtools.j2ssh.transport.ConsoleKnownHostsKeyVerification;
...
SshClient ssh = new SshClient();
ssh.connect("firestar", new ConsoleKnownHostsKeyVerification());

The ConsoleKnownHostsKeyVerification class provides a simple console request mechanism to allow for host key verification. An addtional mechanism is available for swing applications which is implemented by the DialogKnownHostsKeyVerfication class. This prompts the user using a standard JOptionPane dialog:

import com.sshtools.j2ssh.transport.DialogKnownHostsKeyVerification;

If you prefer to ignore the host key verification process you can use the following class:

import com.sshtools.j2ssh.transport.IgnoreHostKeyVerification

To override the default behaviour with your own mechanism, there are two choices. First you can extend the AbstractKnownHostsKeyVerification class. This provides persistence to known_hosts and is recommended for users with additonal implementations where these default styles are not appropriate. For a more simple method with no persistence you can implement the base interface for host verification.

Back to top