public class SSHClient extends SocketClient implements java.io.Closeable, SessionFactory
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.Modifier and Type | Field and Description |
---|---|
protected UserAuth |
auth
ssh-userauth service |
protected Connection |
conn
ssh-connection service |
static int |
DEFAULT_PORT
Default port for SSH
|
protected org.slf4j.Logger |
log |
protected LoggerFactory |
loggerFactory
Logger
|
protected Transport |
trans
Transport layer
|
Constructor and Description |
---|
SSHClient()
Default constructor.
|
SSHClient(Config config)
Constructor that allows specifying a
config to be used. |
Modifier and Type | Method and Description |
---|---|
void |
addAlgorithmsVerifier(AlgorithmsVerifier verifier)
Add a
AlgorithmsVerifier which will be invoked for verifying negotiated algorithms. |
void |
addHostKeyVerifier(HostKeyVerifier verifier)
Add a
HostKeyVerifier which will be invoked for verifying host key during connection establishment and
future key exchanges. |
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 , e.g. |
void |
auth(java.lang.String username,
AuthMethod... methods)
Authenticate
username using the supplied methods . |
void |
auth(java.lang.String username,
java.lang.Iterable<AuthMethod> methods)
Authenticate
username using the supplied methods . |
void |
authGssApiWithMic(java.lang.String username,
javax.security.auth.login.LoginContext context,
org.ietf.jgss.Oid supportedOid,
org.ietf.jgss.Oid... supportedOids)
Authenticate
username using the "gssapi-with-mic" authentication method, given a login context
for the peer GSS machine and a list of supported OIDs. |
void |
authPassword(java.lang.String username,
char[] password)
Authenticate
username using the "password" authentication method and as a fallback basic
challenge-response authentication.. |
void |
authPassword(java.lang.String username,
PasswordFinder pfinder)
Authenticate
username using the "password" authentication method and as a fallback basic
challenge-response authentication. |
void |
authPassword(java.lang.String username,
PasswordFinder pfinder,
PasswordUpdateProvider newPasswordProvider)
Authenticate
username using the "password" authentication method and as a fallback basic
challenge-response authentication. |
void |
authPassword(java.lang.String username,
java.lang.String password)
Authenticate
username using the "password" authentication method and as a fallback basic
challenge-response authentication. |
void |
authPublickey(java.lang.String username)
Authenticate
username using the "publickey" authentication method, with keys from some common
locations on the file system. |
void |
authPublickey(java.lang.String username,
java.lang.Iterable<KeyProvider> keyProviders)
Authenticate
username using the "publickey" authentication method. |
void |
authPublickey(java.lang.String username,
KeyProvider... keyProviders)
Authenticate
username using the "publickey" authentication method. |
void |
authPublickey(java.lang.String username,
java.lang.String... locations)
Authenticate
username using the "publickey" authentication method, with keys from one or more
locations in the file system. |
void |
close()
Same as
disconnect() . |
void |
disconnect()
Disconnects from the connected SSH server.
|
protected void |
doKex()
Do key exchange.
|
Connection |
getConnection() |
RemotePortForwarder |
getRemotePortForwarder() |
Transport |
getTransport() |
UserAuth |
getUserAuth() |
boolean |
isAuthenticated() |
boolean |
isConnected() |
KeyProvider |
loadKeys(java.security.KeyPair kp)
Creates a
KeyProvider from supplied KeyPair . |
KeyProvider |
loadKeys(java.lang.String location)
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. |
KeyProvider |
loadKeys(java.lang.String location,
char[] passphrase)
Utility function for createing a
KeyProvider instance from given location on the file system. |
KeyProvider |
loadKeys(java.lang.String location,
PasswordFinder passwordFinder)
Creates a
KeyProvider instance from given location on the file system. |
KeyProvider |
loadKeys(java.lang.String location,
java.lang.String passphrase)
Convenience method for creating a
KeyProvider instance from a location where an encrypted
key file is located. |
KeyProvider |
loadKeys(java.lang.String privateKey,
java.lang.String publicKey,
PasswordFinder passwordFinder)
Creates a
KeyProvider instance from passed strings. |
void |
loadKnownHosts()
Attempts loading the user's
known_hosts file from the default locations, i.e. |
void |
loadKnownHosts(java.io.File location)
Adds a
OpenSSHKnownHosts object created from the specified location as a host key verifier. |
LocalPortForwarder |
newLocalPortForwarder(LocalPortForwarder.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 . |
SCPFileTransfer |
newSCPFileTransfer() |
SFTPClient |
newSFTPClient() |
protected void |
onConnect()
On connection establishment, also initializes the SSH transport via
Transport.init(java.lang.String, int, java.io.InputStream, java.io.OutputStream) and doKex() . |
X11Forwarder |
registerX11Forwarder(ConnectListener listener)
Register a
listener for handling forwarded X11 channels. |
void |
rekey()
Does key re-exchange.
|
Session |
startSession()
Opens a
session channel. |
void |
useCompression()
Adds
zlib compression to preferred compression algorithms. |
connect, connect, connect, connect, connect, connect, connect, connect, connect, connect, getConnectTimeout, getLocalAddress, getLocalPort, getRemoteAddress, getRemoteHostname, getRemotePort, getSocket, getSocketFactory, getTimeout, setConnectTimeout, setSocketFactory, setTimeout
public static final int DEFAULT_PORT
protected final LoggerFactory loggerFactory
protected final org.slf4j.Logger log
protected final Transport trans
protected final UserAuth auth
ssh-userauth
serviceprotected final Connection conn
ssh-connection
servicepublic SSHClient()
DefaultConfig
.public void addHostKeyVerifier(HostKeyVerifier verifier)
HostKeyVerifier
which will be invoked for verifying host key during connection establishment and
future key exchanges.verifier
- HostKeyVerifier
instancepublic void addAlgorithmsVerifier(AlgorithmsVerifier verifier)
AlgorithmsVerifier
which will be invoked for verifying negotiated algorithms.verifier
- AlgorithmsVerifier
instancepublic void addHostKeyVerifier(java.lang.String fingerprint)
HostKeyVerifier
that will verify any host that's able to claim a host key with the given fingerprint
, e.g. "4b:69:6c:72:6f:79:20:77:61:73:20:68:65:72:65:21"
fingerprint
- expected fingerprint in colon-delimited format (16 octets in hex delimited by a colon)SecurityUtils.getFingerprint(java.security.PublicKey)
public void auth(java.lang.String username, AuthMethod... methods) throws UserAuthException, TransportException
username
using the supplied methods
.username
- user to authenticatemethods
- one or more authentication methodUserAuthException
- in case of authentication failureTransportException
- if there was a transport-layer errorpublic void auth(java.lang.String username, java.lang.Iterable<AuthMethod> methods) throws UserAuthException, TransportException
username
using the supplied methods
.username
- user to authenticatemethods
- one or more authentication methodUserAuthException
- in case of authentication failureTransportException
- if there was a transport-layer errorpublic void authPassword(java.lang.String username, java.lang.String password) throws UserAuthException, TransportException
username
using the "password"
authentication method and as a fallback basic
challenge-response authentication.username
- user to authenticatepassword
- the password to use for authenticationUserAuthException
- in case of authentication failureTransportException
- if there was a transport-layer errorpublic void authPassword(java.lang.String username, char[] password) throws UserAuthException, TransportException
username
using the "password"
authentication method and as a fallback basic
challenge-response authentication.. The password
array is blanked out after use.username
- user to authenticatepassword
- the password to use for authenticationUserAuthException
- in case of authentication failureTransportException
- if there was a transport-layer errorpublic void authPassword(java.lang.String username, PasswordFinder pfinder) throws UserAuthException, TransportException
username
using the "password"
authentication method and as a fallback basic
challenge-response authentication.username
- user to authenticatepfinder
- the PasswordFinder
to use for authenticationUserAuthException
- in case of authentication failureTransportException
- if there was a transport-layer errorpublic void authPassword(java.lang.String username, PasswordFinder pfinder, PasswordUpdateProvider newPasswordProvider) throws UserAuthException, TransportException
username
using the "password"
authentication method and as a fallback basic
challenge-response authentication.username
- user to authenticatepfinder
- the PasswordFinder
to use for authenticationnewPasswordProvider
- the PasswordUpdateProvider
to use when a new password is being requested from the user.UserAuthException
- in case of authentication failureTransportException
- if there was a transport-layer errorpublic void authPublickey(java.lang.String username) throws UserAuthException, TransportException
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.username
- user to authenticateUserAuthException
- in case of authentication failureTransportException
- if there was a transport-layer errorpublic void authPublickey(java.lang.String username, java.lang.Iterable<KeyProvider> keyProviders) throws UserAuthException, TransportException
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.username
- user to authenticatekeyProviders
- one or more KeyProvider
instancesUserAuthException
- in case of authentication failureTransportException
- if there was a transport-layer errorpublic void authPublickey(java.lang.String username, KeyProvider... keyProviders) throws UserAuthException, TransportException
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.username
- user to authenticatekeyProviders
- one or more KeyProvider
instancesUserAuthException
- in case of authentication failureTransportException
- if there was a transport-layer errorpublic void authPublickey(java.lang.String username, java.lang.String... locations) throws UserAuthException, TransportException
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.username
- user to authenticatelocations
- one or more locations in the file system containing the private keyUserAuthException
- in case of authentication failureTransportException
- if there was a transport-layer errorpublic 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
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 requiredusername
- user to authenticatecontext
- LoginContext
for the peer GSS machinesupportedOid
- first supported OIDsupportedOids
- other supported OIDsUserAuthException
- in case of authentication failureTransportException
- if there was a transport-layer errorpublic void disconnect() throws java.io.IOException
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.disconnect
in class SocketClient
java.io.IOException
public Connection getConnection()
Connection
instance.public RemotePortForwarder getRemotePortForwarder()
RemotePortForwarder
that allows requesting remote forwarding over this connection.public UserAuth getUserAuth()
UserAuth
instance. This allows access to information like the authentication banner
, whether authentication was at least partially successful
.public boolean isAuthenticated()
public boolean isConnected()
isConnected
in class SocketClient
public KeyProvider loadKeys(java.security.KeyPair kp)
KeyProvider
from supplied KeyPair
.kp
- the key pairpublic KeyProvider loadKeys(java.lang.String location) throws java.io.IOException
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
.location
- the location for the key fileSSHException
- if there was no suitable key provider available for the file format; typically because
BouncyCastle is not in the classpathjava.io.IOException
- if the key file format is not known, if the file could not be read, etc.public KeyProvider loadKeys(java.lang.String location, char[] passphrase) throws java.io.IOException
KeyProvider
instance from given location on the file system. Creates a
one-off PasswordFinder
using PasswordUtils.createOneOff(char[])
, and calls loadKeys(String, PasswordFinder)
.location
- location of the key filepassphrase
- passphrase as a char-arraySSHException
- if there was no suitable key provider available for the file format; typically because
BouncyCastle is not in the classpathjava.io.IOException
- if the key file format is not known, if the file could not be read, etc.public KeyProvider loadKeys(java.lang.String location, PasswordFinder passwordFinder) throws java.io.IOException
KeyProvider
instance from given location on the file system. Currently the following private key files are supported:
location
- the location of the key filepasswordFinder
- the PasswordFinder
that can supply the passphrase for decryption (may be null
in case keyfile is not encrypted)SSHException
- if there was no suitable key provider available for the file format; typically because
BouncyCastle is not in the classpathjava.io.IOException
- if the key file format is not known, if the file could not be read, etc.public KeyProvider loadKeys(java.lang.String location, java.lang.String passphrase) throws java.io.IOException
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.location
- location of the key filepassphrase
- passphrase as a stringjava.io.IOException
- if the key file format is not known, if the file could not be read etc.public KeyProvider loadKeys(java.lang.String privateKey, java.lang.String publicKey, PasswordFinder passwordFinder) throws java.io.IOException
KeyProvider
instance from passed strings. Currently only PKCS8 format private key files are
supported (OpenSSH uses this format).
privateKey
- the private key as a stringpublicKey
- the public key as a string if it's not included with the private keypasswordFinder
- the PasswordFinder
that can supply the passphrase for decryption (may be null
in case keyfile is not encrypted)SSHException
- if there was no suitable key provider available for the file format; typically because
BouncyCastle is not in the classpathjava.io.IOException
- if the key file format is not known, etc.public void loadKnownHosts() throws java.io.IOException
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)
.java.io.IOException
- if there is an error loading from both locationspublic void loadKnownHosts(java.io.File location) throws java.io.IOException
OpenSSHKnownHosts
object created from the specified location as a host key verifier.location
- location for known_hosts
filejava.io.IOException
- if there is an error loading from any of these locationspublic LocalPortForwarder newLocalPortForwarder(LocalPortForwarder.Parameters parameters, java.net.ServerSocket serverSocket)
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 for the forwarding setupserverSocket
- bound server socketLocalPortForwarder
public X11Forwarder registerX11Forwarder(ConnectListener listener)
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
.listener
- the ConnectListener
that should be delegated the responsibility of handling forwarded
X11Forwarder.X11Channel
'sX11Forwarder
that allows to stop acting
on X11 requests from
serverpublic SCPFileTransfer newSCPFileTransfer()
SCPFileTransfer
implementation.public SFTPClient newSFTPClient() throws java.io.IOException
SFTPClient
implementation.java.io.IOException
- if there is an error starting the sftp
subsystemStatefulSFTPClient
public void rekey() throws TransportException
TransportException
- if an error occurs during key exchangepublic Session startSession() throws ConnectionException, TransportException
SessionFactory
session
channel. The returned Session
instance allows executing a remote command
, starting a subsystem
, or starting a shell
.startSession
in interface SessionFactory
session
channelConnectionException
TransportException
Session
public void useCompression() throws TransportException
zlib
compression to preferred compression algorithms. There is no guarantee that it will be
successfully negotiatied.
If the client is already connected renegotiation is done; otherwise this method simply returns (and compression
will be negotiated during connection establishment).java.lang.ClassNotFoundException
- if JZlib
is not in classpathTransportException
- if an error occurs during renegotiationprotected void onConnect() throws java.io.IOException
Transport.init(java.lang.String, int, java.io.InputStream, java.io.OutputStream)
and doKex()
.java.io.IOException
protected void doKex() throws TransportException
TransportException
- if error during kexpublic void close() throws java.io.IOException
disconnect()
.close
in interface java.io.Closeable
close
in interface java.lang.AutoCloseable
java.io.IOException