Class SSHClient

All Implemented Interfaces:
RemoteAddressProvider, Closeable, AutoCloseable, SessionFactory

public class SSHClient extends SocketClient implements Closeable, SessionFactory
Secure SHell client API.

Before connection is established, host key verification needs to be accounted for. This is done by specifying one or more HostKeyVerifier objects. Database of known hostname-key pairs in the OpenSSH "known_hosts" format can be loaded for host key verification.

User authentication can be performed by any of the auth*() method.

startSession() caters to the most typical use case of starting a session channel and executing a remote command, starting a subsystem, etc. If you wish to request X11 forwarding for some session, first register a ConnectListener for x11 channels.

Local and remote port forwarding is possible. There are also utility method for easily creating SCP and SFTP implementations.

A simple example:

 final SSHClient client = new SSHClient();
 client.loadKnownHosts();
 client.connect("hostname");
 try {
     client.authPassword("username", "password");
     final Session session = client.startSession();
     try {
          final Command cmd = session.exec("true");
          cmd.join(1, TimeUnit.SECONDS);
     } finally {
          session.close();
     }
 } finally {
      client.disconnect();
 }
 

Where a password or passphrase is required, if you're extra-paranoid use the char[] based method. The char[] will be blanked out after use.

  • Field Details

    • DEFAULT_PORT

      public static final int DEFAULT_PORT
      Default port for SSH
      See Also:
    • loggerFactory

      protected final LoggerFactory loggerFactory
      Logger
    • log

      protected final org.slf4j.Logger log
    • trans

      protected final Transport trans
      Transport layer
    • auth

      protected final UserAuth auth
      ssh-userauth service
    • conn

      protected final Connection conn
      ssh-connection service
    • forwarders

      private final List<LocalPortForwarder> forwarders
    • remoteCharset

      protected Charset remoteCharset
      character set of the remote machine
  • Constructor Details

    • SSHClient

      public SSHClient()
      Default constructor. Initializes this object using DefaultConfig.
    • SSHClient

      public SSHClient(Config config)
      Constructor that allows specifying a config to be used.
      Parameters:
      config - Config instance
  • Method Details

    • addHostKeyVerifier

      public void addHostKeyVerifier(HostKeyVerifier verifier)
      Add a HostKeyVerifier which will be invoked for verifying host key during connection establishment and future key exchanges.
      Parameters:
      verifier - HostKeyVerifier instance
    • addAlgorithmsVerifier

      public void addAlgorithmsVerifier(AlgorithmsVerifier verifier)
      Add a AlgorithmsVerifier which will be invoked for verifying negotiated algorithms.
      Parameters:
      verifier - AlgorithmsVerifier instance
    • addHostKeyVerifier

      public void addHostKeyVerifier(String fingerprint)
      Add a HostKeyVerifier that will verify any host that's able to claim a host key with the given fingerprint. The fingerprint can be specified in either an MD5 colon-delimited format (16 hexadecimal octets, delimited by a colon), or in a Base64 encoded format for SHA-1 or SHA-256 fingerprints. Valid examples are:
      • "SHA1:2Fo8c/96zv32xc8GZWbOGYOlRak="
      • "SHA256:oQGbQTujGeNIgh0ONthcEpA/BHxtt3rcYY+NxXTxQjs="
      • "MD5:d3:5e:40:72:db:08:f1:6d:0c:d7:6d:35:0d:ba:7c:32"
      • "d3:5e:40:72:db:08:f1:6d:0c:d7:6d:35:0d:ba:7c:32"
      Parameters:
      fingerprint - expected fingerprint in colon-delimited format (16 octets in hex delimited by a colon)
      See Also:
    • auth

      public void auth(String username, AuthMethod... methods) throws UserAuthException, TransportException
      Authenticate username using the supplied methods.
      Parameters:
      username - user to authenticate
      methods - one or more authentication method
      Throws:
      UserAuthException - in case of authentication failure
      TransportException - if there was a transport-layer error
    • auth

      public void auth(String username, Iterable<AuthMethod> methods) throws UserAuthException, TransportException
      Authenticate username using the supplied methods.
      Parameters:
      username - user to authenticate
      methods - one or more authentication method
      Throws:
      UserAuthException - in case of authentication failure
      TransportException - if there was a transport-layer error
    • authPassword

      public void authPassword(String username, String password) throws UserAuthException, TransportException
      Authenticate username using the "password" authentication method and as a fallback basic challenge-response authentication.
      Parameters:
      username - user to authenticate
      password - the password to use for authentication
      Throws:
      UserAuthException - in case of authentication failure
      TransportException - if there was a transport-layer error
    • authPassword

      public void authPassword(String username, char[] password) throws UserAuthException, TransportException
      Authenticate username using the "password" authentication method and as a fallback basic challenge-response authentication.. The password array is blanked out after use.
      Parameters:
      username - user to authenticate
      password - the password to use for authentication
      Throws:
      UserAuthException - in case of authentication failure
      TransportException - if there was a transport-layer error
    • authPassword

      public void authPassword(String username, PasswordFinder pfinder) throws UserAuthException, TransportException
      Authenticate username using the "password" authentication method and as a fallback basic challenge-response authentication.
      Parameters:
      username - user to authenticate
      pfinder - the PasswordFinder to use for authentication
      Throws:
      UserAuthException - in case of authentication failure
      TransportException - if there was a transport-layer error
    • authPassword

      public void authPassword(String username, PasswordFinder pfinder, PasswordUpdateProvider newPasswordProvider) throws UserAuthException, TransportException
      Authenticate username using the "password" authentication method and as a fallback basic challenge-response authentication.
      Parameters:
      username - user to authenticate
      pfinder - the PasswordFinder to use for authentication
      newPasswordProvider - the PasswordUpdateProvider to use when a new password is being requested from the user.
      Throws:
      UserAuthException - in case of authentication failure
      TransportException - if there was a transport-layer error
    • authPublickey

      public void authPublickey(String username) throws UserAuthException, TransportException
      Authenticate username using the "publickey" authentication method, with keys from some common locations on the file system. This method relies on ~/.ssh/id_rsa and ~/.ssh/id_dsa.

      This method does not provide a way to specify a passphrase.

      Parameters:
      username - user to authenticate
      Throws:
      UserAuthException - in case of authentication failure
      TransportException - if there was a transport-layer error
    • authPublickey

      public void authPublickey(String username, Iterable<KeyProvider> keyProviders) throws UserAuthException, TransportException
      Authenticate username using the "publickey" authentication method.

      KeyProvider instances can be created using any of the of the loadKeys() method provided in this class. In case multiple keyProviders are specified; authentication is attempted in order as long as the "publickey" authentication method is available.

      Parameters:
      username - user to authenticate
      keyProviders - one or more KeyProvider instances
      Throws:
      UserAuthException - in case of authentication failure
      TransportException - if there was a transport-layer error
    • authPublickey

      public void authPublickey(String username, KeyProvider... keyProviders) throws UserAuthException, TransportException
      Authenticate username using the "publickey" authentication method.

      KeyProvider instances can be created using any of the loadKeys() method provided in this class. In case multiple keyProviders are specified; authentication is attempted in order as long as the "publickey" authentication method is available.

      Parameters:
      username - user to authenticate
      keyProviders - one or more KeyProvider instances
      Throws:
      UserAuthException - in case of authentication failure
      TransportException - if there was a transport-layer error
    • authPublickey

      public void authPublickey(String username, String... locations) throws UserAuthException, TransportException
      Authenticate username using the "publickey" authentication method, with keys from one or more locations in the file system.

      In case multiple locations are specified; authentication is attempted in order as long as the "publickey" authentication method is available. If there is an error loading keys from any of them (e.g. file could not be read, file format not recognized) that key file it is ignored.

      This method does not provide a way to specify a passphrase.

      Parameters:
      username - user to authenticate
      locations - one or more locations in the file system containing the private key
      Throws:
      UserAuthException - in case of authentication failure
      TransportException - if there was a transport-layer error
    • authGssApiWithMic

      public void authGssApiWithMic(String username, LoginContext context, Oid supportedOid, Oid... supportedOids) throws UserAuthException, TransportException
      Authenticate username using the "gssapi-with-mic" authentication method, given a login context for the peer GSS machine and a list of supported OIDs.

      Supported OIDs should be ordered by preference as the SSH server will choose the first OID that it also supports. At least one OID is required

      Parameters:
      username - user to authenticate
      context - LoginContext for the peer GSS machine
      supportedOid - first supported OID
      supportedOids - other supported OIDs
      Throws:
      UserAuthException - in case of authentication failure
      TransportException - if there was a transport-layer error
    • disconnect

      public void disconnect() throws IOException
      Disconnects from the connected SSH server. SSHClient objects are not reusable therefore it is incorrect to attempt connection after this method has been called.

      This method should be called from a finally construct after connection is established; so that proper cleanup is done and the thread spawned by the transport layer for dealing with incoming packets is stopped.

      Overrides:
      disconnect in class SocketClient
      Throws:
      IOException
    • getConnection

      public Connection getConnection()
      Returns:
      the associated Connection instance.
    • getRemoteSocketAddress

      public InetSocketAddress getRemoteSocketAddress()
      Get Remote Socket Address from Transport
      Specified by:
      getRemoteSocketAddress in interface RemoteAddressProvider
      Returns:
      Remote Socket Address or null when not connected
    • getRemoteCharset

      public Charset getRemoteCharset()
      Returns the character set used to communicate with the remote machine for certain strings (like paths).
      Returns:
      remote character set
    • getRemotePortForwarder

      public RemotePortForwarder getRemotePortForwarder()
      Returns:
      a RemotePortForwarder that allows requesting remote forwarding over this connection.
    • getTransport

      public Transport getTransport()
      Returns:
      the associated Transport instance.
    • getUserAuth

      public UserAuth getUserAuth()
      Returns:
      the associated UserAuth instance. This allows access to information like the authentication banner, whether authentication was at least partially successful.
    • isAuthenticated

      public boolean isAuthenticated()
      Returns:
      whether authenticated.
    • isConnected

      public boolean isConnected()
      Overrides:
      isConnected in class SocketClient
      Returns:
      whether connected.
    • loadKeys

      public KeyProvider loadKeys(KeyPair kp)
      Creates a KeyProvider from supplied KeyPair.
      Parameters:
      kp - the key pair
      Returns:
      the key provider ready for use in authentication
    • loadKeys

      public KeyProvider loadKeys(String location) throws IOException
      Returns a KeyProvider instance created from a location on the file system where an unencrypted private key file (does not require a passphrase) can be found. Simply calls loadKeys(String, PasswordFinder) with the PasswordFinder argument as null.
      Parameters:
      location - the location for the key file
      Returns:
      the key provider ready for use in authentication
      Throws:
      SSHException - if there was no suitable key provider available for the file format; typically because BouncyCastle is not in the classpath
      IOException - if the key file format is not known, if the file could not be read, etc.
    • loadKeys

      public KeyProvider loadKeys(String location, char[] passphrase) throws IOException
      Utility function for creating a KeyProvider instance from given location on the file system. Creates a one-off PasswordFinder using PasswordUtils.createOneOff(char[]), and calls loadKeys(String, PasswordFinder).
      Parameters:
      location - location of the key file
      passphrase - passphrase as a char-array
      Returns:
      the key provider ready for use in authentication
      Throws:
      SSHException - if there was no suitable key provider available for the file format; typically because BouncyCastle is not in the classpath
      IOException - if the key file format is not known, if the file could not be read, etc.
    • loadKeys

      public KeyProvider loadKeys(String location, PasswordFinder passwordFinder) throws IOException
      Creates a KeyProvider instance from given location on the file system. Currently the following private key files are supported:
      • PKCS8 (OpenSSH uses this format)
      • PEM-encoded PKCS1
      • Putty keyfile
      • openssh-key-v1 (New OpenSSH keyfile format)

      Parameters:
      location - the location of the key file
      passwordFinder - the PasswordFinder that can supply the passphrase for decryption (may be null in case keyfile is not encrypted)
      Returns:
      the key provider ready for use in authentication
      Throws:
      SSHException - if there was no suitable key provider available for the file format; typically because BouncyCastle is not in the classpath
      IOException - if the key file format is not known, if the file could not be read, etc.
    • loadKeys

      public KeyProvider loadKeys(String location, String passphrase) throws IOException
      Convenience method for creating a KeyProvider instance from a location where an encrypted key file is located. Calls loadKeys(String, char[]) with a character array created from the supplied passphrase string.
      Parameters:
      location - location of the key file
      passphrase - passphrase as a string
      Returns:
      the key provider for use in authentication
      Throws:
      IOException - if the key file format is not known, if the file could not be read etc.
    • loadKeys

      public KeyProvider loadKeys(String privateKey, String publicKey, PasswordFinder passwordFinder) throws IOException
      Creates a KeyProvider instance from passed strings. Currently only PKCS8 format private key files are supported (OpenSSH uses this format).

      Parameters:
      privateKey - the private key as a string
      publicKey - the public key as a string if it's not included with the private key
      passwordFinder - the PasswordFinder that can supply the passphrase for decryption (may be null in case keyfile is not encrypted)
      Returns:
      the key provider ready for use in authentication
      Throws:
      SSHException - if there was no suitable key provider available for the file format; typically because BouncyCastle is not in the classpath
      IOException - if the key file format is not known, etc.
    • loadKnownHosts

      public void loadKnownHosts() throws IOException
      Attempts loading the user's known_hosts file from the default locations, i.e. ~/.ssh/known_hosts and ~/.ssh/known_hosts2 on most platforms. Adds the resulting OpenSSHKnownHosts object as a host key verifier.

      For finer control over which file is used, see loadKnownHosts(File).

      Throws:
      IOException - if there is an error loading from both locations
    • loadKnownHosts

      public void loadKnownHosts(File location) throws IOException
      Adds a OpenSSHKnownHosts object created from the specified location as a host key verifier.
      Parameters:
      location - location for known_hosts file
      Throws:
      IOException - if there is an error loading from any of these locations
    • newLocalPortForwarder

      public LocalPortForwarder newLocalPortForwarder(Parameters parameters, ServerSocket serverSocket)
      Create a LocalPortForwarder that will listen based on parameters using the bound serverSocket and forward incoming connections to the server; which will further forward them to host:port.

      The returned forwarder's listen() method should be called to actually start listening, this method just creates an instance.

      Parameters:
      parameters - parameters for the forwarding setup
      serverSocket - bound server socket
      Returns:
      a LocalPortForwarder
    • newDirectConnection

      public DirectConnection newDirectConnection(String hostname, int port) throws IOException
      Create a DirectConnection channel that connects to a remote address from the server. This can be used to open a tunnel to, for example, an HTTP server that is only accessible from the SSH server, or opening an SSH connection via a 'jump' server.
      Parameters:
      hostname - name of the host to connect to from the server.
      port - remote port number.
      Throws:
      IOException
    • registerX11Forwarder

      public X11Forwarder registerX11Forwarder(ConnectListener listener)
      Register a listener for handling forwarded X11 channels. Without having done this, an incoming X11 forwarding will be summarily rejected.

      It should be clarified that multiple listeners for X11 forwarding over a single SSH connection are not supported (and don't make much sense). So a subsequent call to this method is only going to replace the registered listener.

      Parameters:
      listener - the ConnectListener that should be delegated the responsibility of handling forwarded X11Forwarder.X11Channel 's
      Returns:
      an X11Forwarder that allows to stop acting on X11 requests from server
    • newSCPFileTransfer

      public SCPFileTransfer newSCPFileTransfer()
      Returns:
      Instantiated SCPFileTransfer implementation.
    • newSFTPClient

      public SFTPClient newSFTPClient() throws IOException
      Returns:
      Instantiated SFTPClient implementation.
      Throws:
      IOException - if there is an error starting the sftp subsystem
      See Also:
    • newStatefulSFTPClient

      public StatefulSFTPClient newStatefulSFTPClient() throws IOException
      Stateful FTP client is required in order to connect to Serv-U FTP servers.
      Returns:
      Instantiated SFTPClient implementation.
      Throws:
      IOException - if there is an error starting the sftp subsystem
    • rekey

      public void rekey() throws TransportException
      Does key re-exchange.
      Throws:
      TransportException - if an error occurs during key exchange
    • setRemoteCharset

      public void setRemoteCharset(Charset remoteCharset)
      Sets the character set used to communicate with the remote machine for certain strings (like paths)
      Parameters:
      remoteCharset - remote character set or null for default
    • startSession

      public Session startSession() throws ConnectionException, TransportException
      Description copied from interface: SessionFactory
      Opens a session channel. The returned Session instance allows executing a remote command, starting a subsystem, or starting a shell.
      Specified by:
      startSession in interface SessionFactory
      Returns:
      the opened session channel
      Throws:
      ConnectionException
      TransportException
      See Also:
    • useCompression

      public void useCompression() throws TransportException
      Adds zlib compression to preferred compression algorithms. There is no guarantee that it will be successfully negotiated.

      If the client is already connected renegotiation is done; otherwise this method simply returns (and compression will be negotiated during connection establishment).

      Throws:
      ClassNotFoundException - if JZlib is not in classpath
      TransportException - if an error occurs during renegotiation
    • onConnect

      protected void onConnect() throws IOException
      On connection establishment, also initializes the SSH transport via Transport.init(java.lang.String, int, java.io.InputStream, java.io.OutputStream) and doKex().
      Overrides:
      onConnect in class SocketClient
      Throws:
      IOException
    • doKex

      protected void doKex() throws TransportException
      Do key exchange.
      Throws:
      TransportException - if error during kex
    • close

      public void close() throws IOException
      Same as disconnect().
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Throws:
      IOException
    • checkConnected

      private void checkConnected()
    • checkAuthenticated

      private void checkAuthenticated()