Overview | Package | Class | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

## com.mindbright.ssh2
Class SSH2Transport

    java.lang.Object
      com.mindbright.ssh2.SSH2Transport

public class SSH2Transport
extends java.lang.Object

This class implements the transport layer of the secure shell version 2 (ssh2) protocol stack. It handles the initial negotiation of algorithms for key exchange, host key type, encryption, message authentication and compression. It also handles server authentication (through the provided `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`.

See Also:
  `SSH2TransportEventHandler`, `SSH2Preferences`, `SSH2UserAuth`, `SSH2Connection`

Nested Class Summary
`static class` | `SSH2Transport.TranceiverContext` Context for transport tranceiver/receiver.

Field Summary
`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` | `incompatibleSignature`
`protected SSH2Preferences` | `ourPrefs`
`protected SSH2Preferences` | `peerPrefs`
`protected java.io.InputStream` | `tpIn`
`protected Log` | `tpLog`
`protected java.io.OutputStream` | `tpOut`
`protected SecureRandomAndPad` | `tpRand`
`protected java.net.Socket` | `tpSocket`

Constructor Summary
`SSH2Transport(java.net.Socket tpSocket, SecureRandomAndPad rand)` This is the basic constructor used when default preferences is ok and no logging or event handling is needed.
`SSH2Transport(java.net.Socket tpSocket, SSH2Preferences prefs, SecureRandomAndPad rand)` This is the basic constructor used when no logging or event handling is needed.
`SSH2Transport(java.net.Socket tpSocket, SSH2Preferences prefs, SSH2TransportEventHandler eventHandler, SecureRandomAndPad rand)` This is the constructor used when an event handler is needed but no logging.
`SSH2Transport(java.net.Socket tpSocket, SSH2Preferences prefs, SSH2TransportEventHandler eventHandler, SecureRandomAndPad rand, Log log)` This is the constructor used when both an event handler and logging is needed.

Method Summary
`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` | `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.
`SSH2Compressor` | `getRxCompressor()` Gets the `SSH2Compressor` currently in use for the receiver.
`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.
`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.
`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.
`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.
`SSH2TransportPDU` | `receiveInternal()` Receives a PDU directly from the `InputStream` from the peer without checking if we are connected.
`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, java.net.Socket sock)`
`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.
`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).

Methods inherited from class java.lang.Object
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

Field Detail

### ourPrefs

    protected SSH2Preferences ourPrefs

### peerPrefs

    protected SSH2Preferences peerPrefs

### eventHandler

    protected SSH2TransportEventHandler eventHandler

### tpLog

    protected Log tpLog

### tpSocket

    protected java.net.Socket tpSocket

### tpIn

    protected java.io.InputStream tpIn

### tpOut

    protected java.io.OutputStream tpOut

### tpRand

    protected SecureRandomAndPad tpRand

### activity

    protected boolean activity

### incompatibleSignature

    public boolean incompatibleSignature

### incompatiblePublicKeyAuth

    public boolean incompatiblePublicKeyAuth

### incompatibleHMACKeyLength

    public boolean incompatibleHMACKeyLength

### incompatiblePublicKeyUserId

    public boolean incompatiblePublicKeyUserId

### incompatibleChannelOpenFail

    public boolean incompatibleChannelOpenFail

### incompatibleRijndael

    public boolean incompatibleRijndael

### incompatibleCantReKey

    public boolean incompatibleCantReKey

### incompatibleBuggyChannelClose

    public boolean incompatibleBuggyChannelClose

### incompatibleMayReceiveDataAfterClose

    public boolean incompatibleMayReceiveDataAfterClose

### incompatibleOldDHGex

    public boolean incompatibleOldDHGex

Constructor Detail

### SSH2Transport

    public SSH2Transport(java.net.Socket tpSocket,
                         SecureRandomAndPad rand)

  This is the basic constructor used when default preferences is ok and no logging or event handling is needed.

Parameters:
  `tpSocket` - the connection to the ssh2 server
  `rand` - the source of randomness for keys and padding

### SSH2Transport

    public SSH2Transport(java.net.Socket tpSocket,
                         SSH2Preferences prefs,
                         SecureRandomAndPad rand)

  This is the basic constructor used when no logging or event handling is needed.

Parameters:
  `tpSocket` - the connection to the ssh2 server
  `prefs` - the protocol preferences
  `rand` - the source of randomness for keys and padding

### SSH2Transport

    public SSH2Transport(java.net.Socket tpSocket,
                         SSH2Preferences prefs,
                         SSH2TransportEventHandler eventHandler,
                         SecureRandomAndPad rand)

  This is the constructor used when an event handler is needed but no logging.

Parameters:
  `tpSocket` - the connection to the ssh2 server
  `prefs` - the protocol preferences
  `eventHandler` - the event handler which receives callbacks
  `rand` - the source of randomness for keys and padding

### SSH2Transport

    public SSH2Transport(java.net.Socket tpSocket,
                         SSH2Preferences prefs,
                         SSH2TransportEventHandler eventHandler,
                         SecureRandomAndPad rand,
                         Log log)

  This is the constructor used when both an event handler and logging is needed.

Parameters:
  `tpSocket` - the connection to the ssh2 server
  `prefs` - the protocol preferences
  `eventHandler` - the event handler which receives callbacks
  `rand` - the source of randomness for keys and padding
  `log` - the log handler which receives all logs

Method Detail

### boot

    public void boot()
              throws SSH2Exception

  Starts the protocol engine and begins communication with the server. It completes the version negotiation and starts two threads which handles the protocol engine and all communication with the server. The key exchange is started here.

  Throws:
    `SSH2Exception` - if a fatal error occurs such as an I/O error or a protocol mismatch.

### boot

    public void boot(int timeout)
              throws SSH2Exception

  Starts the protocol engine and begins communication with the server. It completes the version negotiation and starts two threads which handles the protocol engine and all communication with the server. The key exchange is started here.

  Parameters:
    `timeout` - handshake timeout in ms
  Throws:
    `SSH2Exception` - if a fatal error occurs such as an I/O error or a protocol mismatch.

### setSocketOptions

    public void setSocketOptions(java.lang.String desc,
                                 java.net.Socket sock)
                          throws java.io.IOException

  Throws:
    `java.io.IOException`

### getLocalHostName

    public java.lang.String getLocalHostName()

### getSessionId

    public byte[] getSessionId()

  Gets the session identifier calculated at key exchange as defined in the protool spec.

  Returns:
    the session identifier as a byte array.

### getClientKEXINITPDU

    public SSH2TransportPDU getClientKEXINITPDU()

  Gets the PDU containing the key exchange initialization (KEXINIT) sent by the client.

  Returns:
    the PDU containing the KEXINIT packet

### getServerKEXINITPDU

    public SSH2TransportPDU getServerKEXINITPDU()

  Gets the PDU containing the key exchange initialization (KEXINIT) sent by the server.

  Returns:
    the PDU containing the KEXINIT packet.

### getClientVersion

    public java.lang.String getClientVersion()

  Gets the client's version string

  Returns:
    the client's version string

### getServerVersion

    public java.lang.String getServerVersion()

  Gets the server's version string.

  Returns:
    the server's version string.

### getOurPreferences

    public SSH2Preferences getOurPreferences()

  Gets our preferences.

  Returns:
    our preferences.

### getPeerPreferences

    public SSH2Preferences getPeerPreferences()

  Gets the preferences peer want.

  Returns:
    peer's preferences.

### setEventHandler

    public void setEventHandler(SSH2TransportEventHandler eventHandler)

  Sets the event handler to use.

  Parameters:
    `eventHandler` - the event handler to use.

### getEventHandler

    public SSH2TransportEventHandler getEventHandler()

  Gets the event handler currently in use.

  Returns:
    the event handler currently in use.

### getLog

    public Log getLog()

  Gets the log handler currently in use.

  Returns:
    the log handler currently in use.

### setLog

    public void setLog(Log log)

  Sets the log handler to use.

  Parameters:
    `log` - the log handler to use

### isServer

    public boolean isServer()

  Checks whether we are a server or a client.

  Returns:
    a boolean indicating if we are a server or not.

### getSecureRandom

    public SecureRandom getSecureRandom()

  Gets the `SecureRandom` currently in use.

  Returns:
    the `SecureRandom` in use.

### getRxCompressor

    public SSH2Compressor getRxCompressor()

  Gets the `SSH2Compressor` currently in use for the receiver.

  Returns:
    the `SSH2Compressor` in use, `null` if none.

### getTxCompressor

    public SSH2Compressor getTxCompressor()

  Gets the `SSH2Compressor` currently in use for the transmitter.

  Returns:
    the `SSH2Compressor` in use, `null` if none.

### setUserAuth

    public void setUserAuth(SSH2UserAuth userAuth)

  Sets the `SSH2UserAuth` to use for the user authenticaton stage. The user authentication service is started from the class `SSH2UserAuth` through the method `requestService`.

  Parameters:
    `userAuth` - the userAuth layer

### requestService

    public 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).

  Parameters:
    `service` - the name of the service to request

### setConnection

    public void setConnection(SSH2Connection connection)

  Sets the `SSH2Connection` to use for the connection layer. All actions after this stage are made through the connection layer.

  Parameters:
    `connection` - the connection layer

### startKeyExchange

    public void startKeyExchange()
                          throws SSH2Exception

  Starts a key exchange with the preferences set in the constructor. If a key exchange is allready in progress this call have no effect.

  Throws:
    `SSH2Exception` - if a fatal error occurs.

### startKeyExchange

    public void startKeyExchange(SSH2Preferences newPrefs)
                          throws SSH2Exception

  Starts a key exchange with the given preferences. That is change to new preferences and negotiate these with the peer. If a key exchange is allready in progress this call have no effect.

  Parameters:
    `newPrefs` - the new preferences to use
  Throws:
    `SSH2Exception` - if a fatal error occurs

### waitForKEXComplete

    public boolean waitForKEXComplete()

  Waits (blocks) for key exchange to complete (if not in progress returns immediately).

  Returns:
    a boolean indicating if key exchange was successful or not.

### keyExchangeInProgress

    public boolean keyExchangeInProgress()

  Checks if key exchange is currently in progress.

  Returns:
    a boolean indicating if key exchange is in progress or not.

### isConnected

    public boolean isConnected()

  Checks if currently connected to a server.

  Returns:
    a boolean indicating if we are connected or not.

### getDisconnectMessage

    public java.lang.String getDisconnectMessage()

  Gets the message describing why transport was disconnected. Useful when an error occurs and we are not hooked up with an eventhandler to see it (e.g. when an error occurs in the key exchange it's only reported as a disconnect reason).

  Returns:
    the disconnect message or `null` if still connected

### sendIgnore

    public void sendIgnore(byte[] data)

  Sends an IGNORE packet (as defined in the protocol spec.) with the given data as payload.

  Parameters:
    `data` - a byte array containing the payload

### sendIgnore

    public void sendIgnore(byte[] data,
                           int off,
                           int len)

  Sends an IGNORE packet (as defined in the protocol spec.) with the given data as payload.

  Parameters:
    `data` - a byte array containing the payload
    `off` - offset in `data` where payload starts
    `len` - length of payload

### sendDebug

    public 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.

  Parameters:
    `alwaysDisp` - boolean indicating whether this message must always be displayed or not.
    `message` - the debug message to send
    `language` - the language tag to use

### enableKeepAlive

    public void enableKeepAlive(int intervalSeconds)

  Enables keep-alive function which sends IGNORE packets on the given time interval. This is to prevent the connection from beeing timed out because of TCP connection subject to idle-timeouts in a firewall.

  Parameters:
    `intervalSeconds` - interval time in seconds

### getKeepAliveInterval

    public int getKeepAliveInterval()

  Gets the keep-alive interval.

  Returns:
    the keep-alive interval, 0 means keep-alive is disabled

### disableKeepAlive

    public void disableKeepAlive()

  Disables keep-alive function.

### transmit

    public void transmit(SSH2TransportPDU pdu)

  Transmits the given PDU if we are connected. The PDU is put in a queue which is processed by the internal threads hence this call is can only block in extreme cases since all internal queues are subject to flow control to prevent memory from beeing exhausted.

  Parameters:
    `pdu` - PDU to send

### transmitInternal

    public void transmitInternal(SSH2TransportPDU pdu)
                          throws SSH2Exception

  Transmits the given PDU without checking if we are connected. This version of transmit writes the PDU directly to the `OutputStream` to the peer, hence it can only be used when the transmitter is not running.

  Parameters:
    `pdu` - PDU to send
  Throws:
    `SSH2Exception` - if an I/O exception or other fatal error occurs

### fatalDisconnect

    public void fatalDisconnect(int reason,
                                java.lang.String description)

  Disconnects from peer using the DISCONNECT packet type with the given reason and description. See the class `SSH2` for reason codes.

  Parameters:
    `reason` - the reason code
    `description` - the textual description for the cause of disconnect
  See Also:
    `SSH2`

### normalDisconnect

    public 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.

  Parameters:
    `description` - the textual description for the cause of disconnect

### disconnectInternal

    protected void disconnectInternal(int reason,
                                      java.lang.String description,
                                      java.lang.String languageTag,
                                      boolean fromPeer)

### extractMajor

    public static int extractMajor(java.lang.String versionStr)
                            throws SSH2Exception

  Extracts the major version from a version string (as defined in the protocol spec.)

  Parameters:
    `versionStr` - the full version string
  Returns:
    the major version number
  Throws:
    `SSH2Exception` - if there is a format error

### extractMinor

    public static int extractMinor(java.lang.String versionStr)
                            throws SSH2Exception

  Extracts the minor version from a version string (as defined in the protocol spec.)

  Parameters:
    `versionStr` - the full version string
  Returns:
    the minor version number
  Throws:
    `SSH2Exception` - if there is a format error

### extractPackageVersion

    public static java.lang.String extractPackageVersion(java.lang.String versionStr)
                                                  throws SSH2Exception

  Extracts the package version (defined as softwareversion and comments in the protocol spec.) from a version string.

  Parameters:
    `versionStr` - the full version string
  Returns:
    the package version (i.e. software version and comments)
  Throws:
    `SSH2Exception` - if there is a format error

### sendNewKeys

    public void sendNewKeys()
                     throws SSH2Exception

  Sends the NEWKEYS paket type and changes the transmitter keys according to the current prefs (as negotiated before). Typically used from a subclass to `SSH2KeyExchanger`.

  Throws:
    `SSH2Exception` - if an error occurs while sending the packet.

### authenticateHost

    public void authenticateHost(byte[] serverHostKey,
                                 byte[] serverSigH,
                                 byte[] exchangeHash_H)
                          throws SSH2Exception

  Authenticates the server through its host key. Typically used from a subclass to `SSH2KeyExchanger`.

  Parameters:
    `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 hash
  Throws:
    `SSH2Exception` - if an error occurs

### handleExtensionRxPacket

    protected boolean handleExtensionRxPacket(SSH2TransportPDU pdu)
                                       throws ShortBufferException,
                                              java.io.IOException,
                                              SSH2Exception

  Function which can be overridden in subclasses to handle extensions to the SSH2 protocol.

  Returns:
    true if the packet was handled
  Throws:
    `ShortBufferException`
    `java.io.IOException`
    `SSH2Exception`

### receiveInternal

    public SSH2TransportPDU receiveInternal()
                                     throws SSH2Exception,
                                            ShortBufferException,
                                            java.io.IOException

  Receives a PDU directly from the `InputStream` from the peer without checking if we are connected. This method can only be used when the receiver is not running.

  Returns:
    the PDU which was read
  Throws:
    `SSH2Exception`
    `ShortBufferException`
    `java.io.IOException`

### reportInactivity

    protected void reportInactivity(int duration)

  Called by the KeepAliveThread thread (if launched) to report when the connection has been inactive for a time.

  Parameters:
    `duration` - How long (in seconds) the connection has been inactive

Overview | Package | Class | Tree | Deprecated | Index | Help
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD