A new API in Session
is introduced for making SSH global requests and handling the reply asynchronously.
public GlobalRequestFuture request(Buffer buffer, String request, ReplyHandler replyHandler) throws IOException;
The Buffer
is supposed to contain the full request, including the request
name (for instance, “tcpip-forward”), the want-reply
flag, and any additional data needed. There are several possible ways to use it.
want-reply == true
and replyHandler != null
: the methods sends the request and returns a future that is fulfilled when the request was actually sent. The future is fulfilled with an exception if sending the request failed, or with null
if it was sent successfully. Once the reply is received, the handler is invoked with the SSH command (SSH_MSG_REQUEST_SUCCESS
, SSH_MSG_REQUEST_FAILURE
, or SSH_MSG_UNIMPLEMENTED
) and the buffer received.want-reply == true
and replyHandler == null
: the method sends the request and returns a future that is fulfilled with an exception if sending it failed, or if a SSH_MSG_REQUEST_FAILURE
or SSH_MSG_UNIMPLEMENTED
reply was received. Otherwise the future is fulfilled with the received Buffer once the reply has been received.want-reply == false
: the method sends the request and returns a future that is fulfilled when the request was actually sent. The future is fulfilled with an exception if sending the request failed, or with an empty buffer if it was sent successfully. If replyHandler != null
, it is invoked with an empty buffer once the request was sent.If the method throws an IOException
, the request was not sent, and the handler will not be invoked.
Changes that may affect existing code
/** * Force the use of a max. packet length for {@link AbstractSftpSubsystemHelper#doWrite(Buffer, int)} protection * against malicious packets */ public static final Property<Integer> MAX_WRITE_DATA_PACKET_LENGTH = Property.integer("sftp-max-writedata-packet-length", 256 * 1024);
This might cause SFTP write failures for clients that might have sent larger buffers and they have been accepted so far. If this happens, simply increase this value (though the choice of 256KB should be compatible with the vast majority of clients).
The relevant API(s) have been modified accordingly - which may cause a few incompatibility issues with code that extends/implements existing Channel
classes and interfaces. In this context, the Channel interface now extends ChannelIdentifier where getId() has been renamed to getChannelId()
There are several exceptions to this rule:
The SFTP packet id field - an “opaque” value anyway, not used for allocation or indexing anyway
Various flags and mask field - there is no reason to encapsulate them into a long value since they do not represent a cardinal number of 32 bits
Various status code fields - ditto.
Cases where the value serves as argument for allocation of other data structures based on its value - e.g., arrays, lists. This was done for convenience reasons since Java does not support unsigned array/list sizes. In such cases, special validation code was applied to make sure the requested value does not exceed Integer#MAX_VALUE
(sometimes even less) in order to protect the code from malicious or malformed packets. It is important to bear in mind that in the vast majority of the cases we do not want to be able to allocate arrays or lists having billions of elements as it would almost definitely cause out-of-memory issues.
Was originally in HostConfigEntry.
long
rather than int
to align with protocol UINT32 definition