Class AbstractSession

    • Field Detail

      • random

        protected final Random random
        The pseudo random generator
      • sessionListeners

        protected final java.util.Collection<SessionListener> sessionListeners
        Session listeners container
      • sessionListenerProxy

        protected final SessionListener sessionListenerProxy
      • channelListeners

        protected final java.util.Collection<ChannelListener> channelListeners
        Channel events listener container
      • channelListenerProxy

        protected final ChannelListener channelListenerProxy
      • tunnelListeners

        protected final java.util.Collection<PortForwardingEventListener> tunnelListeners
        Port forwarding events listener container
      • sessionId

        protected byte[] sessionId
      • serverVersion

        protected java.lang.String serverVersion
      • clientVersion

        protected java.lang.String clientVersion
      • serverProposal

        protected final java.util.Map<KexProposalOption,​java.lang.String> serverProposal
      • unmodServerProposal

        protected final java.util.Map<KexProposalOption,​java.lang.String> unmodServerProposal
      • clientProposal

        protected final java.util.Map<KexProposalOption,​java.lang.String> clientProposal
      • unmodClientProposal

        protected final java.util.Map<KexProposalOption,​java.lang.String> unmodClientProposal
      • negotiationResult

        protected final java.util.Map<KexProposalOption,​java.lang.String> negotiationResult
      • unmodNegotiationResult

        protected final java.util.Map<KexProposalOption,​java.lang.String> unmodNegotiationResult
      • firstKexPacketFollows

        protected java.lang.Boolean firstKexPacketFollows
      • initialKexDone

        protected boolean initialKexDone
      • kexState

        protected final java.util.concurrent.atomic.AtomicReference<KexState> kexState
        Holds the current key exchange state.
      • kexFutureHolder

        protected final java.util.concurrent.atomic.AtomicReference<DefaultKeyExchangeFuture> kexFutureHolder
      • outCipher

        protected Cipher outCipher
      • inCipher

        protected Cipher inCipher
      • outCipherSize

        protected int outCipherSize
      • inCipherSize

        protected int inCipherSize
      • outMac

        protected Mac outMac
      • inMac

        protected Mac inMac
      • outMacSize

        protected int outMacSize
      • inMacSize

        protected int inMacSize
      • inMacResult

        protected byte[] inMacResult
      • seqi

        protected long seqi
        Input packet sequence number.
      • seqo

        protected long seqo
        Output packet sequence number.
      • decoderState

        protected int decoderState
      • decoderLength

        protected int decoderLength
      • encodeLock

        protected final java.lang.Object encodeLock
      • decodeLock

        protected final java.lang.Object decodeLock
      • requestLock

        protected final java.lang.Object requestLock
      • strictKex

        protected boolean strictKex
        "Strict KEX" is a mitigation for the "Terrapin attack". The KEX protocol is modified as follows:
        1. During the initial (unencrypted) KEX, no extra messages not strictly necessary for KEX are allowed. The KEX_INIT message must be the first one after the version identification, and no IGNORE or DEBUG messages are allowed until the KEX is completed. If a party receives such a message, it terminates the connection.
        2. Message sequence numbers are reset to zero after a key exchange (initial or later). When the NEW_KEYS message has been sent, the outgoing message number is reset; after a NEW_KEYS message has been received, the incoming message number is reset.
        Strict KEX is negotiated in the original KEX proposal; it is active if and only if both parties indicate that they support strict KEX.
      • initialKexInitSequenceNumber

        protected long initialKexInitSequenceNumber
      • inPacketsCount

        protected final java.util.concurrent.atomic.AtomicLong inPacketsCount
      • outPacketsCount

        protected final java.util.concurrent.atomic.AtomicLong outPacketsCount
      • inBytesCount

        protected final java.util.concurrent.atomic.AtomicLong inBytesCount
      • outBytesCount

        protected final java.util.concurrent.atomic.AtomicLong outBytesCount
      • inBlocksCount

        protected final java.util.concurrent.atomic.AtomicLong inBlocksCount
      • outBlocksCount

        protected final java.util.concurrent.atomic.AtomicLong outBlocksCount
      • lastKeyTimeValue

        protected final java.util.concurrent.atomic.AtomicReference<java.time.Instant> lastKeyTimeValue
      • maxRekyPackets

        protected long maxRekyPackets
      • maxRekeyBytes

        protected long maxRekeyBytes
      • maxRekeyInterval

        protected java.time.Duration maxRekeyInterval
      • ignorePacketDataLength

        protected int ignorePacketDataLength
      • ignorePacketsFrequency

        protected long ignorePacketsFrequency
      • ignorePacketsVariance

        protected int ignorePacketsVariance
      • maxRekeyBlocks

        protected final java.util.concurrent.atomic.AtomicLong maxRekeyBlocks
      • ignorePacketsCount

        protected final java.util.concurrent.atomic.AtomicLong ignorePacketsCount
      • pendingGlobalRequests

        private final java.util.Deque<GlobalRequestFuture> pendingGlobalRequests
        Used to wait for results of global requests sent with want-reply = true. Note that per RFC 4254, global requests may be sent at any time, but success/failure replies MUST come in the order the requests were sent. Some implementations may also reply with SSH_MSG_UNIMPLEMENTED, on which RFC 4253 says they must be sent in the order the message was received.

        This implies that it is legal to send "nested" global requests: a client or server may send two (or more) global requests, and then receives two (or more) replies in the correct order: first reply for the first request sent; second reply for the second request sent.

        We keep a FIFO list of pending global requests for which we expect a reply. We always add new global requests at the head. For success and failure replies, which don't identify the message sequence number of the global request, we apply the reply to the tail of the list. For unimplemented messages, we apply it to the request identified by the message sequence number, which normally also should be the tail.

        When a reply is received, the corresponding global request is removed from the list.

        Global requests sent with want-reply = false are never added to this list; they are fire-and-forget. According to the SSH RFCs, the peer MUST not reply on a message with want-reply = false. If it does so all the same, it is broken. We might then apply the result to the wrong pending global request if we have any.

        See Also:
        RFC 4254: Global Requests, RFC 4254: Reserved Messages, request(Buffer, String, org.apache.sshd.common.future.GlobalRequestFuture.ReplyHandler), requestSuccess(Buffer), requestFailure(Buffer), doInvokeUnimplementedMessageHandler(int, Buffer), preClose()
      • globalSequenceNumbers

        private final java.util.Map<Buffer,​java.util.function.LongConsumer> globalSequenceNumbers
      • clientKexData

        private byte[] clientKexData
      • serverKexData

        private byte[] serverKexData
    • Constructor Detail

      • AbstractSession

        protected AbstractSession​(boolean serverSession,
                                  FactoryManager factoryManager,
                                  IoSession ioSession)
        Create a new session.
        Parameters:
        serverSession - true if this is a server session, false if client one
        factoryManager - the factory manager
        ioSession - the underlying I/O session
    • Method Detail

      • initializeCurrentService

        protected CurrentService initializeCurrentService()
        Creates a new CurrentService instance managing this session's current SSH service.

        This initialization method is invoked once from the AbstractSession constructor. Do not rely on subclass fields being initialized.

        Returns:
        a new CurrentService instance for the session
      • calculatePadLength

        public static int calculatePadLength​(int len,
                                             int blockSize,
                                             boolean etmMode)
        Parameters:
        len - The packet payload size
        blockSize - The cipher block size
        etmMode - Whether using "encrypt-then-MAC" mode
        Returns:
        The required padding length
      • getServerVersion

        public java.lang.String getServerVersion()
        Description copied from interface: SessionContext
        Retrieve the server version for this session.
        Returns:
        the server version - may be null/empty if versions not yet exchanged
      • getServerKexProposals

        public java.util.Map<KexProposalOption,​java.lang.String> getServerKexProposals()
        Returns:
        An un-modifiable map of the latest KEX client proposal options. May be empty if KEX not yet completed or re-keying in progress
        See Also:
        SessionContext.getKexState()
      • getClientVersion

        public java.lang.String getClientVersion()
        Description copied from interface: SessionContext
        Retrieve the client version for this session.
        Returns:
        the client version - may be null/empty if versions not yet exchanged
      • getClientKexProposals

        public java.util.Map<KexProposalOption,​java.lang.String> getClientKexProposals()
        Returns:
        An un-modifiable map of the latest KEX client proposal options May be empty if KEX not yet completed or re-keying in progress
        See Also:
        SessionContext.getKexState()
      • getKex

        public KeyExchange getKex()
        Returns:
        The current KeyExchange in progress - null if KEX not started or successfully completed
      • getKexState

        public KexState getKexState()
      • getSessionId

        public byte[] getSessionId()
        Returns:
        A clone of the established session identifier - null if not yet established
      • getKexNegotiationResult

        public java.util.Map<KexProposalOption,​java.lang.String> getKexNegotiationResult()
      • getNegotiatedKexParameter

        public java.lang.String getNegotiatedKexParameter​(KexProposalOption paramType)
        Description copied from interface: SessionContext
        Retrieve one of the negotiated values during the KEX stage
        Parameters:
        paramType - The request KexProposalOption value - ignored if null
        Returns:
        The negotiated parameter value - null if invalid parameter or no negotiated value.
        See Also:
        SessionContext.getKexState()
      • getCipherInformation

        public CipherInformation getCipherInformation​(boolean incoming)
        Description copied from interface: SessionContext
        Retrieves current cipher information - Note: may change if key re-exchange executed
        Parameters:
        incoming - If true then the cipher for the incoming data, otherwise for the outgoing data
        Returns:
        The CipherInformation - or null if not negotiated yet.
      • getCompressionInformation

        public CompressionInformation getCompressionInformation​(boolean incoming)
        Description copied from interface: SessionContext
        Retrieves current compression information - Note: may change if key re-exchange executed
        Parameters:
        incoming - If true then the compression for the incoming data, otherwise for the outgoing data
        Returns:
        The CompressionInformation - or null if not negotiated yet.
      • getMacInformation

        public MacInformation getMacInformation​(boolean incoming)
        Description copied from interface: SessionContext
        Retrieves current MAC information - Note: may change if key re-exchange executed
        Parameters:
        incoming - If true then the MAC for the incoming data, otherwise for the outgoing data
        Returns:
        The MacInformation - or null if not negotiated yet.
      • messageReceived

        public void messageReceived​(Readable buffer)
                             throws java.lang.Exception

        Main input point for the MINA framework.

        This method will be called each time new data is received on the socket and will append it to the input buffer before calling the decode() method.

        Parameters:
        buffer - the new buffer received
        Throws:
        java.lang.Exception - if an error occurs while decoding or handling the data
      • refreshConfiguration

        protected void refreshConfiguration()
        Refresh whatever internal configuration is not final
      • handleMessage

        protected void handleMessage​(Buffer buffer)
                              throws java.lang.Exception
        Abstract method for processing incoming decoded packets. The given buffer will hold the decoded packet, starting from the command byte at the read position.
        Parameters:
        buffer - The Buffer containing the packet - it may be re-used to generate the response once request has been decoded
        Throws:
        java.lang.Exception - if an exception occurs while handling this packet.
        See Also:
        doHandleMessage(Buffer)
      • doHandleMessage

        protected void doHandleMessage​(Buffer buffer)
                                throws java.lang.Exception
        Throws:
        java.lang.Exception
      • handleFirstKexPacketFollows

        protected boolean handleFirstKexPacketFollows​(int cmd,
                                                      Buffer buffer,
                                                      boolean followFlag)
      • comparePreferredKexProposalOption

        protected java.util.Map.Entry<java.lang.String,​java.lang.String> comparePreferredKexProposalOption​(KexProposalOption option)
        Compares the specified KexProposalOption option value for client vs. server
        Parameters:
        option - The option to check
        Returns:
        null if option is equal, otherwise a key/value pair where key=client option value and value=the server-side one
      • sendNewKeys

        protected IoWriteFuture sendNewKeys()
                                     throws java.lang.Exception
        Send a message to put new keys into use.
        Returns:
        An IoWriteFuture that can be used to wait and check the result of sending the packet
        Throws:
        java.lang.Exception - if an error occurs sending the message
      • handleKexMessage

        protected void handleKexMessage​(int cmd,
                                        Buffer buffer)
                                 throws java.lang.Exception
        Throws:
        java.lang.Exception
      • handleKexExtension

        protected void handleKexExtension​(int cmd,
                                          Buffer buffer)
                                   throws java.lang.Exception
        Throws:
        java.lang.Exception
      • handleNewCompression

        protected void handleNewCompression​(int cmd,
                                            Buffer buffer)
                                     throws java.lang.Exception
        Throws:
        java.lang.Exception
      • handleServiceRequest

        protected void handleServiceRequest​(Buffer buffer)
                                     throws java.lang.Exception
        Throws:
        java.lang.Exception
      • handleServiceRequest

        protected boolean handleServiceRequest​(java.lang.String serviceName,
                                               Buffer buffer)
                                        throws java.lang.Exception
        Throws:
        java.lang.Exception
      • validateServiceKexState

        protected boolean validateServiceKexState​(KexState state)
      • handleServiceAccept

        protected void handleServiceAccept​(Buffer buffer)
                                    throws java.lang.Exception
        Throws:
        java.lang.Exception
      • handleServiceAccept

        protected void handleServiceAccept​(java.lang.String serviceName,
                                           Buffer buffer)
                                    throws java.lang.Exception
        Throws:
        java.lang.Exception
      • handleKexInit

        protected void handleKexInit​(Buffer buffer)
                              throws java.lang.Exception
        Throws:
        java.lang.Exception
      • doKexNegotiation

        protected void doKexNegotiation()
                                 throws java.lang.Exception
        Throws:
        java.lang.Exception
      • performKexNegotiation

        protected void performKexNegotiation()
                                      throws java.lang.Exception
        Throws:
        java.lang.Exception
      • handleNewKeys

        protected void handleNewKeys​(int cmd,
                                     Buffer buffer)
                              throws java.lang.Exception
        Throws:
        java.lang.Exception
      • validateKexState

        protected void validateKexState​(int cmd,
                                        KexState expected)
      • preClose

        protected void preClose()
        Description copied from class: AbstractCloseable
        preClose is guaranteed to be called before doCloseGracefully or doCloseImmediately. When preClose() is called, isClosing() == true
        Overrides:
        preClose in class AbstractCloseable
      • getServices

        protected java.util.List<Service> getServices()
      • getService

        public <T extends Service> T getService​(java.lang.Class<T> clazz)
        Description copied from interface: Session
        Get the service of the specified type. If the service is not of the specified class, an IllegalStateException will be thrown.
        Type Parameters:
        T - The generic Service type
        Parameters:
        clazz - The service class
        Returns:
        The service instance
      • preProcessEncodeBuffer

        protected Buffer preProcessEncodeBuffer​(int cmd,
                                                Buffer buffer)
                                         throws java.io.IOException
        Description copied from class: SessionHelper
        Invoked by the session before encoding the buffer in order to make sure that it is at least of size SSH_PACKET_HEADER_LEN. This is required in order to efficiently handle the encoding. If necessary, it re-allocates a new buffer and returns it instead.
        Overrides:
        preProcessEncodeBuffer in class SessionHelper
        Parameters:
        cmd - The command stored in the buffer
        buffer - The original Buffer - assumed to be properly formatted and be of at least the required minimum length.
        Returns:
        The adjusted Buffer. Note: users may use this method to totally alter the contents of the buffer being sent but it is highly discouraged as it may have unexpected results.
        Throws:
        java.io.IOException - If failed to process the buffer
      • writePacket

        public IoWriteFuture writePacket​(Buffer buffer)
                                  throws java.io.IOException
        Description copied from interface: Session
        Encode and send the given buffer. The buffer has to have 5 bytes free at the beginning to allow the encoding to take place. Also, the write position of the buffer has to be set to the position of the last byte to write.
        Parameters:
        buffer - the buffer to encode and send
        Returns:
        An IoWriteFuture that can be used to check when the packet has actually been sent
        Throws:
        java.io.IOException - if an error occurred when encoding sending the packet
      • writePacket

        public IoWriteFuture writePacket​(Buffer buffer,
                                         long timeout,
                                         java.util.concurrent.TimeUnit unit)
                                  throws java.io.IOException
        Description copied from interface: Session
        Encode and send the given buffer with the specified timeout. If the buffer could not be written before the timeout elapses, the returned IoWriteFuture will be set with a TimeoutException exception to indicate a timeout.
        Parameters:
        buffer - the buffer to encode and spend
        timeout - the timeout
        unit - the time unit of the timeout parameter
        Returns:
        a future that can be used to check when the packet has actually been sent
        Throws:
        java.io.IOException - if an error occurred when encoding or sending the packet
      • resolveOutputPacket

        protected Buffer resolveOutputPacket​(Buffer buffer)
                                      throws java.io.IOException
        Throws:
        java.io.IOException
      • doWritePacket

        protected IoWriteFuture doWritePacket​(Buffer buffer)
                                       throws java.io.IOException
        Throws:
        java.io.IOException
      • resolveIgnoreBufferDataLength

        protected int resolveIgnoreBufferDataLength()
      • wantReply

        private boolean wantReply​(Buffer buffer)
      • request

        public Buffer request​(java.lang.String request,
                              Buffer buffer,
                              long maxWaitMillis)
                       throws java.io.IOException
        Description copied from interface: Session
        Send a global request and wait for the response, if the request is sent with want-reply = true.
        Parameters:
        request - the request name - used mainly for logging and debugging
        buffer - the buffer containing the global request
        maxWaitMillis - maximum time in milliseconds to wait for the request to finish - must be positive
        Returns:
        the return buffer if the request was successful, null otherwise.
        Throws:
        java.io.IOException - if an error occurred when encoding or sending the packet
        java.net.SocketTimeoutException - If no response received within specified timeout
      • request

        public GlobalRequestFuture request​(Buffer buffer,
                                           java.lang.String request,
                                           GlobalRequestFuture.ReplyHandler replyHandler)
                                    throws java.io.IOException
        Description copied from interface: Session
        Send a global request and handle the reply asynchronously. If want-reply = true, pass the received Buffer to the given GlobalRequestFuture.ReplyHandler, which may execute in a different thread.
        want-reply == true && replyHandler != null
        The returned future is fulfilled with null when the request was sent, or with an exception if the request could not be sent. The replyHandler is invoked once the reply is received, with the SSH reply code and the data received.
        want-reply == true && replyHandler == null
        The returned future is fulfilled with an exception if the request could not be sent, or a failure reply was received. If a success reply was received, the future is fulfilled with the received data buffer.
        want-reply == false
        The returned future is fulfilled with an empty Buffer when the request was sent, or with an exception if the request could not be sent. If a reply handler is given, it is invoked with that empty buffer. The handler is not invoked if sending the request failed.
        Parameters:
        buffer - the Buffer containing the global request, with the want-reply flag set as appropriate
        request - the request name
        replyHandler - GlobalRequestFuture.ReplyHandler for handling the reply; may be null
        Returns:
        Created GlobalRequestFuture
        Throws:
        java.io.IOException - if an error occurred while encoding or sending the packet
      • createBuffer

        public Buffer createBuffer​(byte cmd,
                                   int len)
        Description copied from interface: Session
        Create a new buffer for the specified SSH packet and reserve the needed space (5 bytes) for the packet header.
        Parameters:
        cmd - The SSH command to initialize the buffer with
        len - Estimated number of bytes the buffer will hold, 0 if unknown.
        Returns:
        a new buffer ready for write
        See Also:
        Session.prepareBuffer(byte, Buffer)
      • prepareBuffer

        public Buffer prepareBuffer​(byte cmd,
                                    Buffer buffer)
        Description copied from interface: Session
        Prepare a new "clean" buffer while reserving the needed space (5 bytes) for the packet header.
        Parameters:
        cmd - The SSH command to initialize the buffer with
        buffer - The Buffer instance to initialize
        Returns:
        The initialized buffer
      • validateTargetBuffer

        protected <B extends Buffer> B validateTargetBuffer​(int cmd,
                                                            B buffer)
        Makes sure that the buffer used for output is not null or one of the session's internal ones used for decoding and uncompressing
        Type Parameters:
        B - The Buffer type being validated
        Parameters:
        cmd - The most likely command this buffer refers to (not guaranteed to be correct)
        buffer - The buffer to be examined
        Returns:
        The validated target instance - default same as input
        Throws:
        java.lang.IllegalArgumentException - if any of the conditions is violated
      • encode

        protected Buffer encode​(Buffer buffer)
                         throws java.io.IOException
        Encode a buffer into the SSH protocol. Note: This method must be called inside a synchronized block using encodeLock.
        Parameters:
        buffer - the buffer to encode
        Returns:
        The encoded buffer - may be different than original if input buffer does not have enough room for SshConstants.SSH_PACKET_HEADER_LEN, in which case a substitute buffer will be created and used.
        Throws:
        java.io.IOException - if an exception occurs during the encoding process
      • aeadOutgoingBuffer

        protected void aeadOutgoingBuffer​(Buffer buf,
                                          int offset,
                                          int len)
                                   throws java.lang.Exception
        Throws:
        java.lang.Exception
      • appendOutgoingMac

        protected void appendOutgoingMac​(Buffer buf,
                                         int offset,
                                         int len)
                                  throws java.lang.Exception
        Throws:
        java.lang.Exception
      • encryptOutgoingBuffer

        protected void encryptOutgoingBuffer​(Buffer buf,
                                             int offset,
                                             int len)
                                      throws java.lang.Exception
        Throws:
        java.lang.Exception
      • decode

        protected void decode()
                       throws java.lang.Exception
        Decode the incoming buffer and handle packets as needed.
        Throws:
        java.lang.Exception - If failed to decode
      • validateIncomingMac

        protected void validateIncomingMac​(byte[] data,
                                           int offset,
                                           int len)
                                    throws java.lang.Exception
        Throws:
        java.lang.Exception
      • readIdentification

        protected abstract boolean readIdentification​(Buffer buffer)
                                               throws java.lang.Exception
        Read the other side identification. This method is specific to the client or server side, but both should call SessionHelper.doReadIdentification(Buffer, boolean) and store the result in the needed property.
        Parameters:
        buffer - The Buffer containing the remote identification
        Returns:
        true if the identification has been fully read or false if more data is needed
        Throws:
        java.lang.Exception - if an error occurs such as a bad protocol version or unsuccessful KEX was involved
      • sendKexInit

        protected byte[] sendKexInit​(java.util.Map<KexProposalOption,​java.lang.String> proposal)
                              throws java.lang.Exception
        Send the key exchange initialization packet. This packet contains random data along with our proposal.
        Parameters:
        proposal - our proposal for key exchange negotiation
        Returns:
        the sent packet data which must be kept for later use when deriving the session keys
        Throws:
        java.lang.Exception - if an error occurred sending the packet
      • receiveKexInit

        protected byte[] receiveKexInit​(Buffer buffer,
                                        java.util.Map<KexProposalOption,​java.lang.String> proposal)
                                 throws java.lang.Exception
        Receive the remote key exchange init message. The packet data is returned for later use.
        Parameters:
        buffer - the Buffer containing the key exchange init packet
        proposal - the remote proposal to fill
        Returns:
        the packet data
        Throws:
        java.lang.Exception - If failed to handle the message
      • prepareNewKeys

        protected void prepareNewKeys()
                               throws java.lang.Exception
        Prepares the new ciphers, macs and compression algorithms according to the negotiated server and client proposals and stores them in inSettings and outSettings. The new settings do not take effect yet; use setInputEncoding() or setOutputEncoding() for that.
        Throws:
        java.lang.Exception - if an error occurs
      • setOutputEncoding

        protected void setOutputEncoding()
                                  throws java.lang.Exception
        Installs the current prepared outSettings so that they are effective and will be applied to any future outgoing packet. Clears outSettings.
        Throws:
        java.lang.Exception - on errors
      • setInputEncoding

        protected void setInputEncoding()
                                 throws java.lang.Exception
        Installs the current prepared inSettings so that they are effective and will be applied to any future incoming packet. Clears inSettings.
        Throws:
        java.lang.Exception - on errors
      • determineRekeyBlockLimit

        protected long determineRekeyBlockLimit​(int inCipherBlockSize,
                                                int outCipherBlockSize)
        Compute the number of blocks after which we should re-key again. See RFC 4344.
        Parameters:
        inCipherBlockSize - block size of the input cipher
        outCipherBlockSize - block size of the output cipher
        Returns:
        the number of block after which re-keying occur at the latest
        See Also:
        RFC 4344, section 3.2
      • notImplemented

        protected IoWriteFuture notImplemented​(int cmd,
                                               Buffer buffer)
                                        throws java.lang.Exception
        Send a SSH_MSG_UNIMPLEMENTED packet. This packet should contain the sequence id of the unsupported packet: this number is assumed to be the last packet received.
        Parameters:
        cmd - The un-implemented command value
        buffer - The Buffer that contains the command. Note: the buffer's read position is just beyond the command.
        Returns:
        An IoWriteFuture that can be used to wait for packet write completion - null if the registered ReservedSessionMessagesHandler decided to handle the command internally
        Throws:
        java.lang.Exception - if an error occurred while handling the packet.
        See Also:
        SessionHelper.sendNotImplemented(long)
      • removeValue

        protected boolean removeValue​(java.util.Map<KexProposalOption,​java.lang.String> options,
                                      KexProposalOption option,
                                      java.lang.String toRemove)
        Given a KEX proposal and a KexProposalOption, removes all occurrences of a value from a comma-separated value list.
        Parameters:
        options - Map holding the Kex proposal
        option - KexProposalOption to modify
        toRemove - value to remove
        Returns:
        true if the option contained the value (and it was removed); false otherwise
      • negotiate

        protected java.util.Map<KexProposalOption,​java.lang.String> negotiate()
                                                                             throws java.lang.Exception
        Compute the negotiated proposals by merging the client and server proposal. The negotiated proposal will also be stored in the negotiationResult property.
        Returns:
        The negotiated options Map
        Throws:
        java.lang.Exception - If negotiation failed
      • setNegotiationResult

        protected java.util.Map<KexProposalOption,​java.lang.String> setNegotiationResult​(java.util.Map<KexProposalOption,​java.lang.String> guess)
      • requestSuccess

        protected void requestSuccess​(Buffer buffer)
                               throws java.lang.Exception
        Indicates the reception of a SSH_MSG_REQUEST_SUCCESS message
        Parameters:
        buffer - The Buffer containing the message data
        Throws:
        java.lang.Exception - If failed to handle the message
      • requestFailure

        protected void requestFailure​(Buffer buffer)
                               throws java.lang.Exception
        Indicates the reception of a SSH_MSG_REQUEST_FAILURE message
        Parameters:
        buffer - The Buffer containing the message data
        Throws:
        java.lang.Exception - If failed to handle the message
      • getSessionListenerProxy

        public SessionListener getSessionListenerProxy()
        Returns:
        A (never null proxy SessionListener that represents all the currently registered listeners. Any method invocation on the proxy is replicated to the currently registered listeners
      • getChannelListenerProxy

        public ChannelListener getChannelListenerProxy()
        Returns:
        A (never null proxy ChannelListener that represents all the currently registered listeners. Any method invocation on the proxy is replicated to the currently registered listeners
      • getPortForwardingEventListenerProxy

        public PortForwardingEventListener getPortForwardingEventListenerProxy()
        Returns:
        A proxy listener representing all the currently registered listener through this manager
      • reExchangeKeys

        public KeyExchangeFuture reExchangeKeys()
                                         throws java.io.IOException
        Description copied from interface: Session
        Initiate a new key exchange.
        Returns:
        A KeyExchangeFuture for awaiting the completion of the exchange
        Throws:
        java.io.IOException - If failed to request keys re-negotiation
      • checkRekey

        protected KeyExchangeFuture checkRekey()
                                        throws java.lang.Exception
        Checks if a re-keying is required and if so initiates it
        Returns:
        A KeyExchangeFuture to wait for the initiated exchange or null if no need to re-key or an exchange is already in progress
        Throws:
        java.lang.Exception - If failed load/generate the keys or send the request
        See Also:
        isRekeyRequired(), requestNewKeysExchange()
      • requestNewKeysExchange

        protected KeyExchangeFuture requestNewKeysExchange()
                                                    throws java.lang.Exception
        Initiates a new keys exchange if one not already in progress
        Returns:
        A KeyExchangeFuture to wait for the initiated exchange or null if an exchange is already in progress
        Throws:
        java.lang.Exception - If failed to load/generate the keys or send the request
      • isRekeyRequired

        protected boolean isRekeyRequired()
      • isRekeyTimeIntervalExceeded

        protected boolean isRekeyTimeIntervalExceeded()
      • isRekeyPacketCountsExceeded

        protected boolean isRekeyPacketCountsExceeded()
      • isRekeyDataSizeExceeded

        protected boolean isRekeyDataSizeExceeded()
      • isRekeyBlocksCountExceeded

        protected boolean isRekeyBlocksCountExceeded()
      • resolveSessionKexProposal

        protected java.lang.String resolveSessionKexProposal​(java.lang.String hostKeyTypes)
                                                      throws java.io.IOException
        Overrides:
        resolveSessionKexProposal in class SessionHelper
        Throws:
        java.io.IOException
      • doStrictKexProposal

        protected java.util.Map<KexProposalOption,​java.lang.String> doStrictKexProposal​(java.util.Map<KexProposalOption,​java.lang.String> proposal)
      • sendKexInit

        protected byte[] sendKexInit()
                              throws java.lang.Exception
        Throws:
        java.lang.Exception
      • getClientKexData

        protected byte[] getClientKexData()
      • setClientKexData

        protected void setClientKexData​(byte[] data)
      • getServerKexData

        protected byte[] getServerKexData()
      • setServerKexData

        protected void setServerKexData​(byte[] data)
      • setKexSeed

        protected abstract void setKexSeed​(byte... seed)
        Parameters:
        seed - The result of the KEXINIT handshake - required for correct session key establishment
      • checkKeys

        protected abstract void checkKeys()
                                   throws java.io.IOException
        Indicates the the key exchange is completed and the exchanged keys can now be verified - e.g., client can verify the server's key
        Throws:
        java.io.IOException - If validation failed
      • receiveKexInit

        protected byte[] receiveKexInit​(Buffer buffer)
                                 throws java.lang.Exception
        Throws:
        java.lang.Exception
      • receiveKexInit

        protected abstract void receiveKexInit​(java.util.Map<KexProposalOption,​java.lang.String> proposal,
                                               byte[] seed)
                                        throws java.io.IOException
        Throws:
        java.io.IOException
      • getSession

        public static AbstractSession getSession​(IoSession ioSession,
                                                 boolean allowNull)
                                          throws MissingAttachedSessionException
        Retrieve the session SSH from the I/O session. If the session has not been attached and allowNull is false, an exception will be thrown, otherwise a null will be returned.
        Parameters:
        ioSession - The IoSession
        allowNull - If true, a null value may be returned if no session is attached
        Returns:
        the session attached to the I/O session or null
        Throws:
        MissingAttachedSessionException - if no attached session and allowNull=false