Class AbstractSession
- All Implemented Interfaces:
Closeable,AutoCloseable,Channel,AttributeRepository,AttributeStore,MutableUserHolder,UsernameHolder,ChannelListenerManager,ChannelStreamWriterResolver,ChannelStreamWriterResolverManager,Closeable,FactoryManagerHolder,PortForwardingEventListenerManager,PortForwardingInformationProvider,KexExtensionHandlerManager,KexFactoryManager,PropertyResolver,ReservedSessionMessagesManager,Session,SessionContext,SessionDisconnectHandlerManager,SessionHeartbeatController,SessionListenerManager,UnknownChannelReferenceHandlerManager,SignatureFactoriesHolder,SignatureFactoriesManager,ConnectionEndpointsIndicator
- Direct Known Subclasses:
AbstractClientSession,AbstractServerSession
The AbstractSession handles all the basic SSH protocol such as key exchange, authentication, encoding and decoding.
Both server side and client side sessions should inherit from this abstract class. Some basic packet processing
methods are defined but the actual call to these methods should be done from the handleMessage(Buffer)
method, which is dependent on the state and side of this session.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static enumprotected static classMessage encoding or decoding settings as determined at the end of a key exchange.Nested classes/interfaces inherited from class org.apache.sshd.common.util.closeable.AbstractCloseable
AbstractCloseable.StateNested classes/interfaces inherited from interface org.apache.sshd.common.AttributeRepository
AttributeRepository.AttributeKey<T>Nested classes/interfaces inherited from interface org.apache.sshd.common.session.SessionHeartbeatController
SessionHeartbeatController.HeartbeatType -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final ChannelListenerprotected final Collection<ChannelListener> Channel events listener containerprivate byte[]protected final Map<KexProposalOption, String> protected Stringprotected final CurrentServiceprotected final Objectprotected final SessionWorkBufferprotected intprotected intprotected final Objectprotected Booleanprivate final Map<Buffer, LongConsumer> protected intprotected final AtomicLongprotected longprotected intprotected final AtomicLongprotected final AtomicLongprotected Cipherprotected intprotected Compressionprotected booleanprotected longprotected Macprotected byte[]protected intprotected final AtomicLongprotected AbstractSession.MessageCodingSettingsResulting message coding settings at the end of a key exchange for incoming messages.protected KeyExchangeprotected final AtomicReference<DefaultKeyExchangeFuture> protected final KeyExchangeMessageHandlerTheKeyExchangeMessageHandlerinstance also serves as lock protectingkexStatechanges from DONE to INIT or RUN, and from KEYS to DONE.protected DefaultKeyExchangeFutureprotected final AtomicReference<KexState> Holds the current key exchange state.protected final AtomicReference<Instant> protected final AtomicLongprotected longprotected Durationprotected longprotected final Map<KexProposalOption, String> protected final AtomicLongprotected final AtomicLongprotected Cipherprotected intprotected Compressionprotected Macprotected intprotected final AtomicLongprotected AbstractSession.MessageCodingSettingsResulting message coding settings at the end of a key exchange for outgoing messages.private final Deque<GlobalRequestFuture> Used to wait for results of global requests sent withwant-reply = true.protected final RandomThe pseudo random generatorprotected final Objectprotected longInput packet sequence number.protected longOutput packet sequence number.private byte[]protected final Map<KexProposalOption, String> protected Stringstatic final StringName of the property where this session is stored in the attributes of the underlying MINA session.protected byte[]protected final SessionListenerprotected final Collection<SessionListener> Session listeners containerprotected boolean"Strict KEX" is a mitigation for the "Terrapin attack".protected final PortForwardingEventListenerprotected final Collection<PortForwardingEventListener> Port forwarding events listener containerprotected SessionWorkBufferprotected final Map<KexProposalOption, String> protected final Map<KexProposalOption, String> protected final Map<KexProposalOption, String> Fields inherited from class org.apache.sshd.common.session.helpers.SessionHelper
authStart, idleStart, initialKexProposalFields inherited from class org.apache.sshd.common.util.closeable.AbstractCloseable
closeFuture, futureLock, stateFields inherited from class org.apache.sshd.common.util.logging.AbstractLoggingBean
logFields inherited from interface org.apache.sshd.common.channel.throttle.ChannelStreamWriterResolver
NONEFields inherited from interface org.apache.sshd.common.PropertyResolver
EMPTYFields inherited from interface org.apache.sshd.common.session.SessionContext
DEFAULT_SSH_VERSION_PREFIX, FALLBACK_SSH_VERSION_PREFIX, MAX_VERSION_LINE_LENGTH -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedAbstractSession(boolean serverSession, FactoryManager factoryManager, IoSession ioSession) Create a new session. -
Method Summary
Modifier and TypeMethodDescriptionvoidaddChannelListener(ChannelListener listener) Add a channel listenervoidAdd a port forwarding listenervoidaddSessionListener(SessionListener listener) Add a session listener.protected voidaeadOutgoingBuffer(Buffer buf, int offset, int len) protected voidappendOutgoingMac(Buffer buf, int offset, int len) static voidattachSession(IoSession ioSession, AbstractSession session) Attach an SSHAbstractSessionto the I/O sessionstatic intcalculatePadLength(int len, int blockSize, boolean etmMode) protected abstract voidIndicates the the key exchange is completed and the exchanged keys can now be verified - e.g., client can verify the server's keyprotected KeyExchangeFutureChecks if a re-keying is required and if so initiates itCompares the specifiedKexProposalOptionoption value for client vs.createBuffer(byte cmd, int len) Create a new buffer for the specified SSH packet and reserve the needed space (5 bytes) for the packet header.protected voiddecode()Decode the incoming buffer and handle packets as needed.protected longdetermineRekeyBlockLimit(int inCipherBlockSize, int outCipherBlockSize) Compute the number of blocks after which we should re-key again.protected voiddoHandleMessage(Buffer buffer) protected booleandoInvokeUnimplementedMessageHandler(int cmd, Buffer buffer) protected voidprotected Map<KexProposalOption, String> doStrictKexProposal(Map<KexProposalOption, String> proposal) protected IoWriteFuturedoWritePacket(Buffer buffer) protected BufferEncode a buffer into the SSH protocol.protected voidencryptOutgoingBuffer(Buffer buf, int offset, int len) protected voidfailStrictKex(int cmd) getCipherInformation(boolean incoming) Retrieves current cipher information - Note: may change if key re-exchange executedprotected byte[]Retrieve the client version for this session.getCompressionInformation(boolean incoming) Retrieves current compression information - Note: may change if key re-exchange executedprotected CloseablegetKex()getMacInformation(boolean incoming) Retrieves current MAC information - Note: may change if key re-exchange executedgetNegotiatedKexParameter(KexProposalOption paramType) Retrieve one of the negotiated values during the KEX stageprotected byte[]Retrieve the server version for this session.<T extends Service>
TgetService(Class<T> clazz) Get the service of the specified type.static AbstractSessiongetSession(IoSession ioSession) Retrieve the SSH session from the I/O session.static AbstractSessiongetSession(IoSession ioSession, boolean allowNull) Retrieve the session SSH from the I/O session.byte[]protected booleanhandleFirstKexPacketFollows(int cmd, Buffer buffer, boolean followFlag) protected voidhandleKexExtension(int cmd, Buffer buffer) protected voidhandleKexInit(Buffer buffer) protected voidhandleKexMessage(int cmd, Buffer buffer) protected voidhandleMessage(Buffer buffer) Abstract method for processing incoming decoded packets.protected voidhandleNewCompression(int cmd, Buffer buffer) protected voidhandleNewKeys(int cmd, Buffer buffer) protected voidhandleServiceAccept(String serviceName, Buffer buffer) protected voidhandleServiceAccept(Buffer buffer) protected booleanhandleServiceRequest(String serviceName, Buffer buffer) protected voidhandleServiceRequest(Buffer buffer) protected CurrentServiceCreates a newCurrentServiceinstance managing this session's current SSH service.protected KeyExchangeMessageHandlerCreates a newKeyExchangeMessageHandlerinstance managing packet sending for this session.protected booleanprotected booleanprotected booleanprotected booleanprotected booleanvoidmessageReceived(Readable buffer) Main input point for the MINA framework.protected Map<KexProposalOption, String> Compute the negotiated proposals by merging the client and server proposal.protected IoWriteFuturenotImplemented(int cmd, Buffer buffer) Send aSSH_MSG_UNIMPLEMENTEDpacket.protected voidpreClose()preClose is guaranteed to be called before doCloseGracefully or doCloseImmediately.prepareBuffer(byte cmd, Buffer buffer) Prepare a new "clean" buffer while reserving the needed space (5 bytes) for the packet header.protected voidPrepares the new ciphers, macs and compression algorithms according to the negotiated server and client proposals and stores them ininSettingsandoutSettings.protected BufferpreProcessEncodeBuffer(int cmd, Buffer buffer) Invoked by the session before encoding the buffer in order to make sure that it is at least of sizeSSH_PACKET_HEADER_LEN.protected abstract booleanreadIdentification(Buffer buffer) Read the other side identification.protected abstract voidreceiveKexInit(Map<KexProposalOption, String> proposal, byte[] seed) protected byte[]receiveKexInit(Buffer buffer) protected byte[]receiveKexInit(Buffer buffer, Map<KexProposalOption, String> proposal) Receive the remote key exchange init message.Initiate a new key exchange.protected voidRefresh whatever internal configuration is notfinalvoidremoveChannelListener(ChannelListener listener) Remove a channel listenervoidRemove a port forwarding listenervoidremoveSessionListener(SessionListener listener) Remove a session listener.protected booleanremoveValue(Map<KexProposalOption, String> options, KexProposalOption option, String toRemove) Given a KEX proposal and aKexProposalOption, removes all occurrences of a value from a comma-separated value list.Send a global request and wait for the response, if the request is sent withwant-reply = true.request(Buffer buffer, String request, GlobalRequestFuture.ReplyHandler replyHandler) Send a global request and handle the reply asynchronously.protected voidrequestFailure(Buffer buffer) Indicates the reception of aSSH_MSG_REQUEST_FAILUREmessageprotected KeyExchangeFutureInitiates a new keys exchange if one not already in progressprotected voidrequestSuccess(Buffer buffer) Indicates the reception of aSSH_MSG_REQUEST_SUCCESSmessageprotected intprotected BufferresolveOutputPacket(Buffer buffer) protected StringresolveSessionKexProposal(String hostKeyTypes) protected byte[]protected byte[]sendKexInit(Map<KexProposalOption, String> proposal) Send the key exchange initialization packet.protected IoWriteFutureSend a message to put new keys into use.protected voidsetClientKexData(byte[] data) protected voidInstalls the current preparedinSettingsso that they are effective and will be applied to any future incoming packet.protected abstract voidsetKexSeed(byte... seed) protected Map<KexProposalOption, String> protected voidInstalls the current preparedoutSettingsso that they are effective and will be applied to any future outgoing packet.protected voidsetServerKexData(byte[] data) protected voidvalidateIncomingMac(byte[] data, int offset, int len) protected voidvalidateKexState(int cmd, KexState expected) protected booleanvalidateServiceKexState(KexState state) protected <B extends Buffer>
BvalidateTargetBuffer(int cmd, B buffer) Makes sure that the buffer used for output is notnullor one of the session's internal ones used for decoding and uncompressingprivate booleanwritePacket(Buffer buffer) Encode and send the given buffer.writePacket(Buffer buffer, long timeout, TimeUnit unit) Encode and send the given buffer with the specified timeout.Methods inherited from class org.apache.sshd.common.session.helpers.SessionHelper
attributeKeys, calculateNextIgnorePacketCount, checkAuthenticationTimeout, checkForTimeouts, checkIdleTimeout, clearAttributes, computeAttributeIfAbsent, createProposal, disconnect, doInvokeDebugMessageHandler, doInvokeIgnoreMessageHandler, doReadIdentification, exceptionCaught, getAttribute, getAttributesCount, getAuthTimeout, getAuthTimeoutStart, getBoundLocalPortForwards, getBoundRemotePortForward, getChannelStreamWriterResolver, getConnectionService, getFactoryManager, getForwarder, getIdleTimeout, getIdleTimeoutStart, getIoSession, getKexProposal, getLocalForwardsBindings, getParentPropertyResolver, getProperties, getRemoteForwardsBindings, getReservedSessionMessagesHandler, getSessionDisconnectHandler, getStartedLocalPortForwards, getStartedRemotePortForwards, getTimeoutStatus, getUnknownChannelReferenceHandler, getUsername, handleDebug, handleDisconnect, handleDisconnect, handleIgnore, handleUnimplemented, invokeSessionSignaller, isAuthenticated, isLocalPortForwardingStartedForPort, isRemotePortForwardingStartedForPort, isServerSession, mergeProposals, removeAttribute, resetAuthTimeout, resetIdleTimeout, resizeKey, resolveAvailableSignaturesProposal, resolveAvailableSignaturesProposal, resolveChannelStreamWriterResolver, resolveIdentificationString, resolvePeerAddress, resolveReservedSessionMessagesHandler, resolveUnknownChannelReferenceHandler, sendDebugMessage, sendIdentification, sendIgnoreMessage, sendNotImplemented, setAttribute, setAuthenticated, setChannelStreamWriterResolver, setReservedSessionMessagesHandler, setSessionDisconnectHandler, setUnknownChannelReferenceHandler, setUsername, signalDisconnect, signalDisconnect, signalExceptionCaught, signalExceptionCaught, signalNegotiationEnd, signalNegotiationEnd, signalNegotiationOptionsCreated, signalNegotiationOptionsCreated, signalNegotiationStart, signalNegotiationStart, signalPeerIdentificationReceived, signalPeerIdentificationReceived, signalReadPeerIdentificationLine, signalReadPeerIdentificationLine, signalSendIdentification, signalSendIdentification, signalSessionClosed, signalSessionClosed, signalSessionCreated, signalSessionCreated, signalSessionEstablished, signalSessionEstablished, signalSessionEvent, signalSessionEvent, toStringMethods inherited from class org.apache.sshd.common.kex.AbstractKexFactoryManager
getCipherFactories, getCompressionFactories, getDelegate, getKexExtensionHandler, getKeyExchangeFactories, getMacFactories, getSignatureFactories, resolveEffectiveFactories, resolveEffectiveProvider, setCipherFactories, setCompressionFactories, setKexExtensionHandler, setKeyExchangeFactories, setMacFactories, setSignatureFactoriesMethods inherited from class org.apache.sshd.common.util.closeable.AbstractInnerCloseable
doCloseGracefully, doCloseImmediatelyMethods inherited from class org.apache.sshd.common.util.closeable.AbstractCloseable
addCloseFutureListener, builder, close, getFutureLock, isClosed, isClosing, removeCloseFutureListenerMethods inherited from class org.apache.sshd.common.util.logging.AbstractLoggingBean
debug, debug, debug, debug, debug, error, error, error, error, error, getSimplifiedLogger, info, info, warn, warn, warn, warn, warn, warn, warn, warnMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface org.apache.sshd.common.channel.throttle.ChannelStreamWriterResolverManager
resolveChannelStreamWriterMethods inherited from interface org.apache.sshd.common.Closeable
addCloseFutureListener, close, close, isClosed, isClosing, isOpen, removeCloseFutureListenerMethods inherited from interface org.apache.sshd.common.kex.extension.KexExtensionHandlerManager
getKexExtensionHandler, setKexExtensionHandlerMethods inherited from interface org.apache.sshd.common.kex.KexFactoryManager
getCipherFactories, getCipherFactoriesNameList, getCipherFactoriesNames, getCompressionFactories, getCompressionFactoriesNameList, getCompressionFactoriesNames, getKeyExchangeFactories, getMacFactories, getMacFactoriesNameList, getMacFactoriesNames, setCipherFactories, setCipherFactoriesNameList, setCipherFactoriesNames, setCipherFactoriesNames, setCompressionFactories, setCompressionFactoriesNameList, setCompressionFactoriesNames, setCompressionFactoriesNames, setKeyExchangeFactories, setMacFactories, setMacFactoriesNameList, setMacFactoriesNames, setMacFactoriesNamesMethods inherited from interface org.apache.sshd.common.PropertyResolver
getBoolean, getBooleanProperty, getCharset, getInteger, getIntProperty, getLong, getLongProperty, getObject, getString, getStringProperty, isEmptyMethods inherited from interface org.apache.sshd.common.session.Session
createBuffer, getLocalAddress, getRemoteAddress, request, request, resolveAttribute, startService, writePacket, writePacketMethods inherited from interface org.apache.sshd.common.session.SessionHeartbeatController
disableSessionHeartbeat, getSessionHeartbeatInterval, getSessionHeartbeatType, setSessionHeartbeat, setSessionHeartbeatMethods inherited from interface org.apache.sshd.common.signature.SignatureFactoriesHolder
getSignatureFactories, getSignatureFactoriesNameList, getSignatureFactoriesNamesMethods inherited from interface org.apache.sshd.common.signature.SignatureFactoriesManager
setSignatureFactories, setSignatureFactoriesNameList, setSignatureFactoriesNames, setSignatureFactoriesNames
-
Field Details
-
SESSION
Name of the property where this session is stored in the attributes of the underlying MINA session. SeegetSession(IoSession, boolean)andattachSession(IoSession, AbstractSession).- See Also:
-
random
The pseudo random generator -
sessionListeners
Session listeners container -
sessionListenerProxy
-
channelListeners
Channel events listener container -
channelListenerProxy
-
tunnelListeners
Port forwarding events listener container -
tunnelListenerProxy
-
sessionId
protected byte[] sessionId -
serverVersion
-
clientVersion
-
serverProposal
-
unmodServerProposal
-
clientProposal
-
unmodClientProposal
-
negotiationResult
-
unmodNegotiationResult
-
kex
-
firstKexPacketFollows
-
initialKexDone
protected boolean initialKexDone -
kexState
Holds the current key exchange state. -
kexFutureHolder
-
kexInitializedFuture
-
outCipher
-
inCipher
-
outCipherSize
protected int outCipherSize -
inCipherSize
protected int inCipherSize -
outMac
-
inMac
-
outMacSize
protected int outMacSize -
inMacSize
protected int inMacSize -
inMacResult
protected byte[] inMacResult -
outCompression
-
inCompression
-
seqi
protected long seqiInput packet sequence number. -
seqo
protected long seqoOutput packet sequence number. -
uncompressBuffer
-
decoderBuffer
-
decoderState
protected int decoderState -
decoderLength
protected int decoderLength -
encodeLock
-
decodeLock
-
requestLock
-
strictKex
protected boolean strictKex"Strict KEX" is a mitigation for the "Terrapin attack". The KEX protocol is modified as follows:- 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.
- 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.
-
initialKexInitSequenceNumber
protected long initialKexInitSequenceNumber -
kexHandler
TheKeyExchangeMessageHandlerinstance also serves as lock protectingkexStatechanges from DONE to INIT or RUN, and from KEYS to DONE. -
inPacketsCount
-
outPacketsCount
-
inBytesCount
-
outBytesCount
-
inBlocksCount
-
outBlocksCount
-
lastKeyTimeValue
-
maxRekyPackets
protected long maxRekyPackets -
maxRekeyBytes
protected long maxRekeyBytes -
maxRekeyInterval
-
inSettings
Resulting message coding settings at the end of a key exchange for incoming messages.- See Also:
-
outSettings
Resulting message coding settings at the end of a key exchange for outgoing messages.- See Also:
-
currentService
-
ignorePacketDataLength
protected int ignorePacketDataLength -
ignorePacketsFrequency
protected long ignorePacketsFrequency -
ignorePacketsVariance
protected int ignorePacketsVariance -
maxRekeyBlocks
-
ignorePacketsCount
-
pendingGlobalRequests
Used to wait for results of global requests sent withwant-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 = falseare never added to this list; they are fire-and-forget. According to the SSH RFCs, the peer MUST not reply on a message withwant-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:
-
globalSequenceNumbers
-
clientKexData
private byte[] clientKexData -
serverKexData
private byte[] serverKexData
-
-
Constructor Details
-
AbstractSession
protected AbstractSession(boolean serverSession, FactoryManager factoryManager, IoSession ioSession) Create a new session.- Parameters:
serverSession-trueif this is a server session,falseif client onefactoryManager- the factory managerioSession- the underlying I/O session
-
-
Method Details
-
initializeKeyExchangeMessageHandler
Creates a newKeyExchangeMessageHandlerinstance managing packet sending for this session.This initialization method is invoked once from the
AbstractSessionconstructor. Do not rely on subclass fields being initialized.- Returns:
- a new
KeyExchangeMessageHandlerinstance for the session
-
initializeCurrentService
Creates a newCurrentServiceinstance managing this session's current SSH service.This initialization method is invoked once from the
AbstractSessionconstructor. Do not rely on subclass fields being initialized.- Returns:
- a new
CurrentServiceinstance for the session
-
calculatePadLength
public static int calculatePadLength(int len, int blockSize, boolean etmMode) - Parameters:
len- The packet payload sizeblockSize- The cipher block sizeetmMode- Whether using "encrypt-then-MAC" mode- Returns:
- The required padding length
-
getServerVersion
Description copied from interface:SessionContextRetrieve the server version for this session.- Returns:
- the server version - may be
null/empty if versions not yet exchanged
-
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:
-
getClientVersion
Description copied from interface:SessionContextRetrieve the client version for this session.- Returns:
- the client version - may be
null/empty if versions not yet exchanged
-
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:
-
getKex
- Returns:
- The current
KeyExchangein progress -nullif KEX not started or successfully completed
-
getKexState
-
getSessionId
public byte[] getSessionId()- Returns:
- A clone of the established session identifier -
nullif not yet established
-
getKexNegotiationResult
-
getNegotiatedKexParameter
Description copied from interface:SessionContextRetrieve one of the negotiated values during the KEX stage- Parameters:
paramType- The requestKexProposalOptionvalue - ignored ifnull- Returns:
- The negotiated parameter value -
nullif invalid parameter or no negotiated value. - See Also:
-
getCipherInformation
Description copied from interface:SessionContextRetrieves current cipher information - Note: may change if key re-exchange executed- Parameters:
incoming- Iftruethen the cipher for the incoming data, otherwise for the outgoing data- Returns:
- The
CipherInformation- ornullif not negotiated yet.
-
getCompressionInformation
Description copied from interface:SessionContextRetrieves current compression information - Note: may change if key re-exchange executed- Parameters:
incoming- Iftruethen the compression for the incoming data, otherwise for the outgoing data- Returns:
- The
CompressionInformation- ornullif not negotiated yet.
-
getMacInformation
Description copied from interface:SessionContextRetrieves current MAC information - Note: may change if key re-exchange executed- Parameters:
incoming- Iftruethen the MAC for the incoming data, otherwise for the outgoing data- Returns:
- The
MacInformation- ornullif not negotiated yet.
-
messageReceived
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:
Exception- if an error occurs while decoding or handling the data
-
refreshConfiguration
protected void refreshConfiguration()Refresh whatever internal configuration is notfinal -
handleMessage
Abstract method for processing incoming decoded packets. The given buffer will hold the decoded packet, starting from the command byte at the read position. -
doHandleMessage
- Throws:
Exception
-
failStrictKex
- Throws:
SshException
-
handleFirstKexPacketFollows
-
comparePreferredKexProposalOption
Compares the specifiedKexProposalOptionoption value for client vs. server- Parameters:
option- The option to check- Returns:
nullif option is equal, otherwise a key/value pair where key=client option value and value=the server-side one
-
sendNewKeys
Send a message to put new keys into use.- Returns:
- An
IoWriteFuturethat can be used to wait and check the result of sending the packet - Throws:
Exception- if an error occurs sending the message
-
handleKexMessage
- Throws:
Exception
-
handleKexExtension
- Throws:
Exception
-
handleNewCompression
- Throws:
Exception
-
handleServiceRequest
- Throws:
Exception
-
handleServiceRequest
- Throws:
Exception
-
validateServiceKexState
-
handleServiceAccept
- Throws:
Exception
-
handleServiceAccept
- Throws:
Exception
-
handleKexInit
- Throws:
Exception
-
doKexNegotiation
- Throws:
Exception
-
handleNewKeys
- Throws:
Exception
-
validateKexState
-
getInnerCloseable
- Specified by:
getInnerCloseablein classAbstractInnerCloseable
-
preClose
protected void preClose()Description copied from class:AbstractCloseablepreClose is guaranteed to be called before doCloseGracefully or doCloseImmediately. When preClose() is called, isClosing() == true- Overrides:
preClosein classAbstractCloseable
-
getServices
-
getService
Description copied from interface:SessionGet the service of the specified type. If the service is not of the specified class, an IllegalStateException will be thrown.- Type Parameters:
T- The genericServicetype- Parameters:
clazz- The service class- Returns:
- The service instance
-
preProcessEncodeBuffer
Description copied from class:SessionHelperInvoked by the session before encoding the buffer in order to make sure that it is at least of sizeSSH_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:
preProcessEncodeBufferin classSessionHelper- Parameters:
cmd- The command stored in the bufferbuffer- The originalBuffer- 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:
IOException- If failed to process the buffer
-
writePacket
Description copied from interface:SessionEncode 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
IoWriteFuturethat can be used to check when the packet has actually been sent - Throws:
IOException- if an error occurred when encoding sending the packet
-
writePacket
Description copied from interface:SessionEncode and send the given buffer with the specified timeout. If the buffer could not be written before the timeout elapses, the returnedIoWriteFuturewill be set with aTimeoutExceptionexception to indicate a timeout.- Parameters:
buffer- the buffer to encode and spendtimeout- the timeoutunit- the time unit of the timeout parameter- Returns:
- a future that can be used to check when the packet has actually been sent
- Throws:
IOException- if an error occurred when encoding or sending the packet
-
resolveOutputPacket
- Throws:
IOException
-
doWritePacket
- Throws:
IOException
-
resolveIgnoreBufferDataLength
protected int resolveIgnoreBufferDataLength() -
wantReply
-
request
Description copied from interface:SessionSend a global request and wait for the response, if the request is sent withwant-reply = true.- Parameters:
request- the request name - used mainly for logging and debuggingbuffer- the buffer containing the global requestmaxWaitMillis- maximum time in milliseconds to wait for the request to finish - must be positive- Returns:
- the return buffer if the request was successful,
nullotherwise. - Throws:
IOException- if an error occurred when encoding or sending the packet
-
request
public GlobalRequestFuture request(Buffer buffer, String request, GlobalRequestFuture.ReplyHandler replyHandler) throws IOException Description copied from interface:SessionSend a global request and handle the reply asynchronously. Ifwant-reply = true, pass the receivedBufferto the givenGlobalRequestFuture.ReplyHandler, which may execute in a different thread.- want-reply == true && replyHandler != null
- The returned future is fulfilled with
nullwhen the request was sent, or with an exception if the request could not be sent. ThereplyHandleris 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
Bufferwhen 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- theBuffercontaining the global request, with thewant-replyflag set as appropriaterequest- the request namereplyHandler-GlobalRequestFuture.ReplyHandlerfor handling the reply; may benull- Returns:
- Created
GlobalRequestFuture - Throws:
IOException- if an error occurred while encoding or sending the packet
-
doInvokeUnimplementedMessageHandler
- Overrides:
doInvokeUnimplementedMessageHandlerin classSessionHelper- Parameters:
cmd- The unimplemented commandbuffer- The inputBuffer- Returns:
- Result of invoking
handleUnimplementedMessage - Throws:
Exception- if failed to handle the message
-
createBuffer
Description copied from interface:SessionCreate 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 withlen- Estimated number of bytes the buffer will hold, 0 if unknown.- Returns:
- a new buffer ready for write
- See Also:
-
prepareBuffer
Description copied from interface:SessionPrepare a new "clean" buffer while reserving the needed space (5 bytes) for the packet header.- Parameters:
cmd- The SSH command to initialize the buffer withbuffer- TheBufferinstance to initialize- Returns:
- The initialized buffer
-
validateTargetBuffer
Makes sure that the buffer used for output is notnullor one of the session's internal ones used for decoding and uncompressing- Type Parameters:
B- TheBuffertype 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:
IllegalArgumentException- if any of the conditions is violated
-
encode
Encode a buffer into the SSH protocol. Note: This method must be called inside asynchronizedblock usingencodeLock.- 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:
IOException- if an exception occurs during the encoding process
-
aeadOutgoingBuffer
- Throws:
Exception
-
appendOutgoingMac
- Throws:
Exception
-
encryptOutgoingBuffer
- Throws:
Exception
-
decode
Decode the incoming buffer and handle packets as needed.- Throws:
Exception- If failed to decode
-
validateIncomingMac
- Throws:
Exception
-
readIdentification
Read the other side identification. This method is specific to the client or server side, but both should callSessionHelper.doReadIdentification(Buffer, boolean)and store the result in the needed property. -
sendKexInit
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:
Exception- if an error occurred sending the packet
-
receiveKexInit
protected byte[] receiveKexInit(Buffer buffer, Map<KexProposalOption, String> proposal) throws ExceptionReceive the remote key exchange init message. The packet data is returned for later use. -
prepareNewKeys
Prepares the new ciphers, macs and compression algorithms according to the negotiated server and client proposals and stores them ininSettingsandoutSettings. The new settings do not take effect yet; usesetInputEncoding()orsetOutputEncoding()for that.- Throws:
Exception- if an error occurs
-
setOutputEncoding
Installs the current preparedoutSettingsso that they are effective and will be applied to any future outgoing packet. ClearsoutSettings.- Throws:
Exception- on errors
-
setInputEncoding
Installs the current preparedinSettingsso that they are effective and will be applied to any future incoming packet. ClearsinSettings.- Throws:
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 cipheroutCipherBlockSize- block size of the output cipher- Returns:
- the number of block after which re-keying occur at the latest
- See Also:
-
notImplemented
Send aSSH_MSG_UNIMPLEMENTEDpacket. 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 valuebuffer- TheBufferthat contains the command. Note: the buffer's read position is just beyond the command.- Returns:
- An
IoWriteFuturethat can be used to wait for packet write completion -nullif the registeredReservedSessionMessagesHandlerdecided to handle the command internally - Throws:
Exception- if an error occurred while handling the packet.- See Also:
-
removeValue
protected boolean removeValue(Map<KexProposalOption, String> options, KexProposalOption option, String toRemove) Given a KEX proposal and aKexProposalOption, removes all occurrences of a value from a comma-separated value list.- Parameters:
options-Mapholding the Kex proposaloption-KexProposalOptionto modifytoRemove- value to remove- Returns:
trueif the option contained the value (and it was removed);falseotherwise
-
negotiate
Compute the negotiated proposals by merging the client and server proposal. The negotiated proposal will also be stored in thenegotiationResultproperty. -
setNegotiationResult
-
requestSuccess
Indicates the reception of aSSH_MSG_REQUEST_SUCCESSmessage -
requestFailure
Indicates the reception of aSSH_MSG_REQUEST_FAILUREmessage -
addSessionListener
Description copied from interface:SessionListenerManagerAdd a session listener.- Parameters:
listener- TheSessionListenerto add - notnull
-
removeSessionListener
Description copied from interface:SessionListenerManagerRemove a session listener.- Parameters:
listener- TheSessionListenerto remove
-
getSessionListenerProxy
- Returns:
- A (never
nullproxySessionListenerthat represents all the currently registered listeners. Any method invocation on the proxy is replicated to the currently registered listeners
-
addChannelListener
Description copied from interface:ChannelListenerManagerAdd a channel listener- Parameters:
listener- TheChannelListenerto add - notnull
-
removeChannelListener
Description copied from interface:ChannelListenerManagerRemove a channel listener- Parameters:
listener- TheChannelListenerto remove
-
getChannelListenerProxy
- Returns:
- A (never
nullproxyChannelListenerthat represents all the currently registered listeners. Any method invocation on the proxy is replicated to the currently registered listeners
-
getPortForwardingEventListenerProxy
- Returns:
- A proxy listener representing all the currently registered listener through this manager
-
addPortForwardingEventListener
Description copied from interface:PortForwardingEventListenerManagerAdd a port forwarding listener- Parameters:
listener- ThePortForwardingEventListenerto add - nevernull
-
removePortForwardingEventListener
Description copied from interface:PortForwardingEventListenerManagerRemove a port forwarding listener- Parameters:
listener- ThePortForwardingEventListenerto remove - ignored ifnull
-
reExchangeKeys
Description copied from interface:SessionInitiate a new key exchange.- Returns:
- A
KeyExchangeFuturefor awaiting the completion of the exchange - Throws:
IOException- If failed to request keys re-negotiation
-
checkRekey
Checks if a re-keying is required and if so initiates it- Returns:
- A
KeyExchangeFutureto wait for the initiated exchange ornullif no need to re-key or an exchange is already in progress - Throws:
Exception- If failed load/generate the keys or send the request- See Also:
-
requestNewKeysExchange
Initiates a new keys exchange if one not already in progress- Returns:
- A
KeyExchangeFutureto wait for the initiated exchange ornullif an exchange is already in progress - Throws:
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
- Overrides:
resolveSessionKexProposalin classSessionHelper- Throws:
IOException
-
doStrictKexProposal
-
sendKexInit
- Throws:
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
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:
IOException- If validation failed
-
receiveKexInit
- Throws:
Exception
-
receiveKexInit
protected abstract void receiveKexInit(Map<KexProposalOption, String> proposal, byte[] seed) throws IOException- Throws:
IOException
-
getSession
public static AbstractSession getSession(IoSession ioSession) throws MissingAttachedSessionException Retrieve the SSH session from the I/O session. If the session has not been attached, an exception will be thrown- Parameters:
ioSession- TheIoSession- Returns:
- The SSH session attached to the I/O session
- Throws:
MissingAttachedSessionException- if no attached SSH session- See Also:
-
attachSession
public static void attachSession(IoSession ioSession, AbstractSession session) throws MultipleAttachedSessionException Attach an SSHAbstractSessionto the I/O session- Parameters:
ioSession- TheIoSessionsession- The SSH session to attach- Throws:
MultipleAttachedSessionException- If a previous session already attached
-
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 isfalse, an exception will be thrown, otherwise anullwill be returned.- Parameters:
ioSession- TheIoSessionallowNull- Iftrue, anullvalue 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
-