Class SSHClient

  • All Implemented Interfaces:
    RemoteAddressProvider, java.io.Closeable, java.lang.AutoCloseable, SessionFactory

    public class SSHClient
    extends SocketClient
    implements java.io.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 Detail

      • DEFAULT_PORT

        public static final int DEFAULT_PORT
        Default port for SSH
        See Also:
        Constant Field Values
      • 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
      • remoteCharset

        protected java.nio.charset.Charset remoteCharset
        character set of the remote machine
    • Constructor Detail

      • 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 Detail

      • 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
      • addHostKeyVerifier

        public void addHostKeyVerifier​(java.lang.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:
        SecurityUtils.getFingerprint(java.security.PublicKey)
      • auth

        public void auth​(java.lang.String username,
                         java.lang.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​(java.lang.String username,
                                 java.lang.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​(java.lang.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
      • authPublickey

        public void authPublickey​(java.lang.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​(java.lang.String username,
                                  java.lang.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​(java.lang.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​(java.lang.String username,
                                  java.lang.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​(java.lang.String username,
                                      javax.security.auth.login.LoginContext context,
                                      org.ietf.jgss.Oid supportedOid,
                                      org.ietf.jgss.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 java.io.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:
        java.io.IOException
      • getRemoteSocketAddress

        public java.net.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 java.nio.charset.Charset getRemoteCharset()
        Returns the character set used to communicate with the remote machine for certain strings (like paths).
        Returns:
        remote character set
      • getTransport

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

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

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

        public KeyProvider loadKeys​(java.security.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​(java.lang.String location)
                             throws java.io.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
        java.io.IOException - if the key file format is not known, if the file could not be read, etc.
      • loadKeys

        public KeyProvider loadKeys​(java.lang.String location,
                                    char[] passphrase)
                             throws java.io.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
        java.io.IOException - if the key file format is not known, if the file could not be read, etc.
      • loadKeys

        public KeyProvider loadKeys​(java.lang.String location,
                                    PasswordFinder passwordFinder)
                             throws java.io.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
        java.io.IOException - if the key file format is not known, if the file could not be read, etc.
      • loadKeys

        public KeyProvider loadKeys​(java.lang.String location,
                                    java.lang.String passphrase)
                             throws java.io.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:
        java.io.IOException - if the key file format is not known, if the file could not be read etc.
      • loadKeys

        public KeyProvider loadKeys​(java.lang.String privateKey,
                                    java.lang.String publicKey,
                                    PasswordFinder passwordFinder)
                             throws java.io.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
        java.io.IOException - if the key file format is not known, etc.
      • loadKnownHosts

        public void loadKnownHosts()
                            throws java.io.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:
        java.io.IOException - if there is an error loading from both locations
      • loadKnownHosts

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

        public LocalPortForwarder newLocalPortForwarder​(Parameters parameters,
                                                        java.net.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​(java.lang.String hostname,
                                                    int port)
                                             throws java.io.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:
        java.io.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
      • newSFTPClient

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

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

        public void setRemoteCharset​(java.nio.charset.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
      • 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:
        java.lang.ClassNotFoundException - if JZlib is not in classpath
        TransportException - if an error occurs during renegotiation
      • close

        public void close()
                   throws java.io.IOException
        Same as disconnect().
        Specified by:
        close in interface java.lang.AutoCloseable
        Specified by:
        close in interface java.io.Closeable
        Throws:
        java.io.IOException