com.mindbright.ssh2
public class SSH2Transport extends java.lang.Object implements NIOCallback, NQueueCallback
SSH2TransportEventHandler
).
To create a SSH2Transport
instance a TCP connection to the ssh2
server must first be established using a java.net.Socket
. This
socket is passed to the constructor. The constructor is passive in that it
doesn't start any communication. To start the protocol engine and begin
communcation with the server the method boot
must be called. In
this method the version information echange is done and two threads are
started which handles the protocol engine and all communication with the
server.
The operation of the transport layer can be controlled and monitored with
instances of the classes SSH2Preferences
and
SSH2TransportEventHandler
which are provided to the
constructor.
After initial negotiation the chosen key exchange algorithm is handled by a
subclass of the abstract class SSH2KeyExchanger
. When the key
exchange is complete, keys for encryption and message authentication can be
derived. The communciation at this point is secured with the selected
cipher/mac algorithms. The actual encryption, message authentication and
compression is handled in the class SSH2TransportPDU
which is
the data container implementing the specific formatting defined in the
protocol.
Before the upper layers (i.e. the user authentication and connection layers)
of the protocol can be started the key exchange stage must be
completed. This must be checked by calling the blocking method
waitForKEXComplete
. When the key exchange is complete a secure
connection to an authenticated server has been established. The function of
the transport layer at this point is the multiplexing of protocol data units
(referred to as PDU or packet) between the server and the upper layers which
are implemented in the classes SSH2UserAuth
and
SSH2Connection
.
Modifier and Type | Class and Description |
---|---|
static class |
SSH2Transport.TransceiverContext
Context for transport transceiver/receiver.
|
Modifier and Type | Field and Description |
---|---|
protected boolean |
activity |
protected SSH2TransportEventHandler |
eventHandler |
boolean |
incompatibleBuggyChannelClose |
boolean |
incompatibleCantReKey |
boolean |
incompatibleChannelOpenFail |
boolean |
incompatibleHMACKeyLength |
boolean |
incompatibleMayReceiveDataAfterClose |
boolean |
incompatibleOldDHGex |
boolean |
incompatiblePublicKeyAuth |
boolean |
incompatiblePublicKeyUserId |
boolean |
incompatibleRijndael |
boolean |
incompatibleSFTPSymlink |
boolean |
incompatibleSignature |
protected SSH2Preferences |
ourPrefs |
protected SSH2Preferences |
peerPrefs |
protected NonBlockingInput |
tpIn |
protected Log |
tpLog |
protected NonBlockingOutput |
tpOut |
protected SecureRandomAndPad |
tpRand |
protected NetworkConnection |
tpSocket |
Constructor and Description |
---|
SSH2Transport(NetworkConnection tpSocket,
SecureRandomAndPad rand)
This is the basic constructor used when default preferences is ok and no
logging or event handling is needed.
|
SSH2Transport(NetworkConnection tpSocket,
SSH2Preferences prefs,
SecureRandomAndPad rand)
This is the basic constructor used when no logging or event handling is
needed.
|
SSH2Transport(NetworkConnection tpSocket,
SSH2Preferences prefs,
SSH2TransportEventHandler eventHandler,
SecureRandomAndPad rand)
This is the constructor used when an event handler is needed but no
logging.
|
SSH2Transport(NetworkConnection tpSocket,
SSH2Preferences prefs,
SSH2TransportEventHandler eventHandler,
SecureRandomAndPad rand,
Log log)
This is the constructor used when both an event handler and logging is
needed.
|
Modifier and Type | Method and Description |
---|---|
void |
authenticateHost(byte[] serverHostKey,
byte[] serverSigH,
byte[] exchangeHash_H)
Authenticates the server through its host key.
|
void |
boot()
Starts the protocol engine and begins communication with the server.
|
void |
boot(int timeout)
Starts the protocol engine and begins communication with the server.
|
void |
completed(java.nio.ByteBuffer buf)
Called once the network read operation has been completed
|
void |
connected(boolean timeout)
Called when the network connection has been established.
|
void |
connectionFailed(java.lang.Exception e)
Called if the connection failed (assuming
interest for this has been registered by calling the
NotifyWhenConnected method of Switchboard ). |
void |
disableKeepAlive()
Disables keep-alive function.
|
protected void |
disconnectInternal(int reason,
java.lang.String description,
java.lang.String languageTag,
boolean fromPeer) |
void |
enableKeepAlive(int intervalSeconds)
Enables keep-alive function which sends IGNORE packets on the given time
interval.
|
static int |
extractMajor(java.lang.String versionStr)
Extracts the major version from a version string (as defined in the
protocol spec.)
|
static int |
extractMinor(java.lang.String versionStr)
Extracts the minor version from a version string (as defined in the
protocol spec.)
|
static java.lang.String |
extractPackageVersion(java.lang.String versionStr)
Extracts the package version (defined as softwareversion and comments in
the protocol spec.) from a version string.
|
void |
fatalDisconnect(int reason,
java.lang.String description)
Disconnects from peer using the DISCONNECT packet type with the given
reason and description.
|
SSH2TransportPDU |
getClientKEXINITPDU()
Gets the PDU containing the key exchange initialization (KEXINIT) sent by
the client.
|
java.lang.String |
getClientVersion()
Gets the client's version string
|
java.lang.String |
getDisconnectMessage()
Gets the message describing why transport was disconnected.
|
SSH2TransportEventHandler |
getEventHandler()
Gets the event handler currently in use.
|
int |
getKeepAliveInterval()
Gets the keep-alive interval.
|
java.lang.String |
getLocalHostName() |
Log |
getLog()
Gets the log handler currently in use.
|
SSH2Preferences |
getOurPreferences()
Gets our preferences.
|
SSH2Preferences |
getPeerPreferences()
Gets the preferences peer want.
|
byte[] |
getRemoteAddress() |
java.lang.String |
getRemoteHostName() |
long |
getRxBytesCompressed() |
long |
getRxBytesUncompressed() |
SSH2Compressor |
getRxCompressor()
Gets the
SSH2Compressor currently in use for the
receiver. |
java.security.SecureRandom |
getSecureRandom()
Gets the
SecureRandom currently in use. |
SSH2TransportPDU |
getServerKEXINITPDU()
Gets the PDU containing the key exchange initialization (KEXINIT) sent by
the server.
|
java.lang.String |
getServerVersion()
Gets the server's version string.
|
byte[] |
getSessionId()
Gets the session identifier calculated at key exchange as defined in the
protool spec.
|
Switchboard |
getSwitchboard() |
long |
getTxBytesCompressed() |
long |
getTxBytesUncompressed() |
SSH2Compressor |
getTxCompressor()
Gets the
SSH2Compressor currently in use for the
transmitter. |
protected boolean |
handleExtensionRxPacket(SSH2TransportPDU pdu)
Function which can be overridden in subclasses to handle
extensions to the SSH2 protocol.
|
void |
handleQueue(java.lang.Object obj)
Handle a packet which should be sent out the wire
|
boolean |
isConnected()
Checks if currently connected to a server.
|
boolean |
isServer()
Checks whether we are a server or a client.
|
boolean |
keyExchangeInProgress()
Checks if key exchange is currently in progress.
|
boolean |
keyExchangeTimedOut()
Checks if key exchange has timed out.
|
void |
normalDisconnect(java.lang.String description)
Disconnects from peer using the DISCONNECT packet type with the
reason code DISCONNECT_BY_APPLICATION and the given description.
|
void |
readFailed(java.lang.Exception e)
Called if the read failed
|
protected void |
reportInactivity(int duration)
Called by the KeepAliveThread thread (if launched) to report when
the connection has been inactive for a time.
|
void |
requestService(java.lang.String service)
Requests the given service (currently the only service defined is the
"ssh-userauth" service which starts the user authentication).
|
void |
sendDebug(boolean alwaysDisp,
java.lang.String message,
java.lang.String language)
Sends a DEBUG packet (as defined in the protocol spec.) with the given
message.
|
void |
sendIgnore(byte[] data)
Sends an IGNORE packet (as defined in the protocol spec.) with the given
data as payload.
|
void |
sendIgnore(byte[] data,
int off,
int len)
Sends an IGNORE packet (as defined in the protocol spec.) with the given
data as payload.
|
void |
sendNewKeys()
Sends the NEWKEYS paket type and changes the transmitter keys according
to the current prefs (as negotiated before).
|
void |
setConnection(SSH2Connection connection)
Sets the
SSH2Connection to use for the connection layer. |
void |
setEventHandler(SSH2TransportEventHandler eventHandler)
Sets the event handler to use.
|
void |
setLog(Log log)
Sets the log handler to use.
|
void |
setSocketOptions(java.lang.String desc,
NetworkConnection conn) |
void |
setSocketOptions(java.lang.String desc,
java.net.Socket conn) |
void |
setUserAuth(SSH2UserAuth userAuth)
Sets the
SSH2UserAuth to use for the user authenticaton
stage. |
void |
startKeyExchange()
Starts a key exchange with the preferences set in the constructor.
|
void |
startKeyExchange(SSH2Preferences newPrefs)
Starts a key exchange with the given preferences.
|
java.lang.String |
toString() |
void |
transmit(SSH2TransportPDU pdu)
Transmits the given PDU if we are connected.
|
void |
transmitInternal(SSH2TransportPDU pdu)
Transmits the given PDU without checking if we are connected.
|
boolean |
waitForKEXComplete()
Waits (blocks) for key exchange to complete (if not in progress returns
immediately).
|
void |
writeFailed()
Called if the write failed
|
protected SSH2Preferences ourPrefs
protected SSH2Preferences peerPrefs
protected SSH2TransportEventHandler eventHandler
protected Log tpLog
protected NetworkConnection tpSocket
protected NonBlockingInput tpIn
protected NonBlockingOutput tpOut
protected SecureRandomAndPad tpRand
protected boolean activity
public boolean incompatibleSignature
public boolean incompatiblePublicKeyAuth
public boolean incompatibleHMACKeyLength
public boolean incompatiblePublicKeyUserId
public boolean incompatibleChannelOpenFail
public boolean incompatibleRijndael
public boolean incompatibleCantReKey
public boolean incompatibleBuggyChannelClose
public boolean incompatibleMayReceiveDataAfterClose
public boolean incompatibleOldDHGex
public boolean incompatibleSFTPSymlink
public SSH2Transport(NetworkConnection tpSocket, SecureRandomAndPad rand)
tpSocket
- the connection to the ssh2 serverrand
- the source of randomness for keys and paddingpublic SSH2Transport(NetworkConnection tpSocket, SSH2Preferences prefs, SecureRandomAndPad rand)
tpSocket
- the connection to the ssh2 serverprefs
- the protocol preferencesrand
- the source of randomness for keys and paddingpublic SSH2Transport(NetworkConnection tpSocket, SSH2Preferences prefs, SSH2TransportEventHandler eventHandler, SecureRandomAndPad rand)
tpSocket
- the connection to the ssh2 serverprefs
- the protocol preferenceseventHandler
- the event handler which receives callbacksrand
- the source of randomness for keys and paddingpublic SSH2Transport(NetworkConnection tpSocket, SSH2Preferences prefs, SSH2TransportEventHandler eventHandler, SecureRandomAndPad rand, Log log)
tpSocket
- the connection to the ssh2 serverprefs
- the protocol preferenceseventHandler
- the event handler which receives callbacksrand
- the source of randomness for keys and paddinglog
- the log handler which receives all logspublic java.lang.String toString()
toString
in class java.lang.Object
public Switchboard getSwitchboard()
public void boot() throws SSH2Exception
SSH2Exception
- if a fatal error occurs such as an I/O error or
a protocol mismatch.public void boot(int timeout) throws SSH2Exception
timeout
- handshake timeout in msSSH2Exception
- if a fatal error occurs such as an I/O error or
a protocol mismatch.public void setSocketOptions(java.lang.String desc, java.net.Socket conn) throws java.io.IOException
java.io.IOException
public void setSocketOptions(java.lang.String desc, NetworkConnection conn) throws java.io.IOException
java.io.IOException
public java.lang.String getLocalHostName()
public java.lang.String getRemoteHostName()
public byte[] getRemoteAddress()
public byte[] getSessionId()
public SSH2TransportPDU getClientKEXINITPDU()
public SSH2TransportPDU getServerKEXINITPDU()
public java.lang.String getClientVersion()
public java.lang.String getServerVersion()
public SSH2Preferences getOurPreferences()
public SSH2Preferences getPeerPreferences()
public void setEventHandler(SSH2TransportEventHandler eventHandler)
eventHandler
- the event handler to use.public SSH2TransportEventHandler getEventHandler()
public Log getLog()
public void setLog(Log log)
log
- the log handler to usepublic boolean isServer()
public java.security.SecureRandom getSecureRandom()
SecureRandom
currently in use.SecureRandom
in use.public SSH2Compressor getRxCompressor()
SSH2Compressor
currently in use for the
receiver.SSH2Compressor
in use,
null
if none.public SSH2Compressor getTxCompressor()
SSH2Compressor
currently in use for the
transmitter.SSH2Compressor
in use,
null
if none.public void setUserAuth(SSH2UserAuth userAuth)
SSH2UserAuth
to use for the user authenticaton
stage. The user authentication service is started from the class
SSH2UserAuth
through the method
requestService
.userAuth
- the userAuth layerpublic void requestService(java.lang.String service)
service
- the name of the service to requestpublic void setConnection(SSH2Connection connection)
SSH2Connection
to use for the connection layer. All
actions after this stage are made through the connection layer.connection
- the connection layerpublic void startKeyExchange() throws SSH2Exception
SSH2Exception
- if a fatal error occurs.public void startKeyExchange(SSH2Preferences newPrefs) throws SSH2Exception
newPrefs
- the new preferences to useSSH2Exception
- if a fatal error occurspublic boolean waitForKEXComplete() throws SSH2Exception
an
- exception if any failures ocurred before the kex phaseSSH2Exception
public boolean keyExchangeInProgress()
public boolean keyExchangeTimedOut()
public boolean isConnected()
public java.lang.String getDisconnectMessage()
null
if still connectedpublic void sendIgnore(byte[] data)
data
- a byte array containing the payloadpublic void sendIgnore(byte[] data, int off, int len)
data
- a byte array containing the payloadoff
- offset in data
where payload startslen
- length of payloadpublic void sendDebug(boolean alwaysDisp, java.lang.String message, java.lang.String language)
alwaysDisp
- boolean indicating whether this message must always be
displayed or not.message
- the debug message to sendlanguage
- the language tag to usepublic void enableKeepAlive(int intervalSeconds)
intervalSeconds
- interval time in secondspublic int getKeepAliveInterval()
public void disableKeepAlive()
public void transmit(SSH2TransportPDU pdu)
pdu
- PDU to sendpublic void transmitInternal(SSH2TransportPDU pdu)
OutputStream
to the peer, hence it can only be used when
the transmitter is not running.pdu
- PDU to sendpublic void fatalDisconnect(int reason, java.lang.String description)
SSH2
for reason codes.reason
- the reason codedescription
- the textual description for the cause of disconnectSSH2
public void normalDisconnect(java.lang.String description)
description
- the textual description for the cause of disconnectprotected void disconnectInternal(int reason, java.lang.String description, java.lang.String languageTag, boolean fromPeer)
public static int extractMajor(java.lang.String versionStr) throws SSH2Exception
versionStr
- the full version stringSSH2Exception
- if there is a format errorpublic static int extractMinor(java.lang.String versionStr) throws SSH2Exception
versionStr
- the full version stringSSH2Exception
- if there is a format errorpublic static java.lang.String extractPackageVersion(java.lang.String versionStr) throws SSH2Exception
versionStr
- the full version stringSSH2Exception
- if there is a format errorpublic void sendNewKeys() throws SSH2Exception
SSH2KeyExchanger
.SSH2Exception
- if an error occurs while sending the packet.public void authenticateHost(byte[] serverHostKey, byte[] serverSigH, byte[] exchangeHash_H) throws SSH2Exception
SSH2KeyExchanger
.serverHostKey
- byte array containing server's host key (e.g. a
public key blob or a certificate).serverSigH
- byte array containing server's signature of the
exchange hash which should be verified.exchangeHash_H
- the exchange hashSSH2Exception
- if an error occurspublic void handleQueue(java.lang.Object obj)
handleQueue
in interface NQueueCallback
obj
- the object to handleprotected boolean handleExtensionRxPacket(SSH2TransportPDU pdu)
public long getTxBytesCompressed()
public long getTxBytesUncompressed()
public long getRxBytesCompressed()
public long getRxBytesUncompressed()
protected void reportInactivity(int duration)
duration
- How long (in seconds) the connection has been inactivepublic void completed(java.nio.ByteBuffer buf)
NIOCallback
completed
in interface NIOCallback
buf
- the buffer provided to the read callpublic void readFailed(java.lang.Exception e)
NIOCallback
readFailed
in interface NIOCallback
public void writeFailed()
NIOCallback
writeFailed
in interface NIOCallback
public void connected(boolean timeout)
connected
in interface NIOCallback
timeout
- true if the connection attempt timed outpublic void connectionFailed(java.lang.Exception e)
NIOCallback
NotifyWhenConnected
method of Switchboard
).connectionFailed
in interface NIOCallback
e
- the exception the connection failed with.