/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.sshd.common.session; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.apache.sshd.common.AttributeStore; import org.apache.sshd.common.Closeable; import org.apache.sshd.common.FactoryManagerHolder; import org.apache.sshd.common.PropertyResolver; import org.apache.sshd.common.Service; import org.apache.sshd.common.auth.MutableUserHolder; import org.apache.sshd.common.channel.ChannelListenerManager; import org.apache.sshd.common.cipher.CipherInformation; import org.apache.sshd.common.compression.CompressionInformation; import org.apache.sshd.common.forward.PortForwardingEventListenerManager; import org.apache.sshd.common.future.KeyExchangeFuture; import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.io.IoWriteFuture; import org.apache.sshd.common.kex.KexFactoryManager; import org.apache.sshd.common.kex.KexProposalOption; import org.apache.sshd.common.kex.KeyExchange; import org.apache.sshd.common.mac.MacInformation; import org.apache.sshd.common.util.buffer.Buffer; /** * Represents an SSH session. <B>Note:</B> the associated username for the session * may be {@code null}/empty if the session is not yet authenticated * * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a> */ public interface Session extends KexFactoryManager, SessionListenerManager, ReservedSessionMessagesManager, ChannelListenerManager, PortForwardingEventListenerManager, FactoryManagerHolder, PropertyResolver, AttributeStore, Closeable, MutableUserHolder { /** * Default prefix expected for the client / server identification string * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-4.2">RFC 4253 - section 4.2</A> */ String DEFAULT_SSH_VERSION_PREFIX = "SSH-2.0-"; /** * Maximum number of characters for any single line sent as part * of the initial handshake - according to * <A HREF="https://tools.ietf.org/html/rfc4253#section-4.2">RFC 4253 - section 4.2</A>:</BR> * * <P><CODE> * The maximum length of the string is 255 characters, * including the Carriage Return and Line Feed. * </CODE></P> */ int MAX_VERSION_LINE_LENGTH = 256; /** * Timeout status. */ enum TimeoutStatus { NoTimeout, AuthTimeout, IdleTimeout } /** * Retrieve the client version for this session. * * @return the client version. */ String getClientVersion(); /** * Retrieve the server version for this session. * * @return the server version. */ String getServerVersion(); /** * Retrieve one of the negotiated values during the KEX stage * * @param paramType The request {@link KexProposalOption} value - ignored * if {@code null} * @return The negotiated parameter value - {@code null} if invalid * parameter or no negotiated value */ String getNegotiatedKexParameter(KexProposalOption paramType); /** * Retrieves current cipher information - <B>Note:</B> may change if * key re-exchange executed * * @param incoming If {@code true} then the cipher for the incoming data, * otherwise for the outgoing data * @return The {@link CipherInformation} - or {@code null} if not negotiated yet. */ CipherInformation getCipherInformation(boolean incoming); /** * Retrieves current compression information - <B>Note:</B> may change if * key re-exchange executed * * @param incoming If {@code true} then the compression for the incoming data, * otherwise for the outgoing data * @return The {@link CompressionInformation} - or {@code null} if not negotiated yet. */ CompressionInformation getCompressionInformation(boolean incoming); /** * Retrieves current MAC information - <B>Note:</B> may change if * key re-exchange executed * * @param incoming If {@code true} then the MAC for the incoming data, * otherwise for the outgoing data * @return The {@link MacInformation} - or {@code null} if not negotiated yet. */ MacInformation getMacInformation(boolean incoming); /** * Create a new buffer for the specified SSH packet and reserve the needed space * (5 bytes) for the packet header. * * @param cmd the SSH command * @return a new buffer ready for write */ Buffer createBuffer(byte cmd); /** * Create a new buffer for the specified SSH packet and reserve the needed space * (5 bytes) for the packet header. * * @param cmd The SSH command to initialize the buffer with * @param estimatedSize Estimated number of bytes the buffer will hold, 0 if unknown. * @return a new buffer ready for write * @see #prepareBuffer(byte, Buffer) */ Buffer createBuffer(byte cmd, int estimatedSize); /** * Prepare a new "clean" buffer while reserving the needed space * (5 bytes) for the packet header. * @param cmd The SSH command to initialize the buffer with * @param buffer The {@link Buffer} instance to initialize * @return The initialized buffer */ Buffer prepareBuffer(byte cmd, Buffer buffer); /** * Sends an {@code SSH_MSG_DEBUG} to the peer session * * @param display {@code true} if OK to display the message at the peer as-is * @param msg The message object whose {@code toString()} value to be used - if * {@code null} then the "null" string is sent * @param lang The language - {@code null}/empty if some pre-agreed default is used * @return An {@code IoWriteFuture} that can be used to check when the packet has actually been sent * @throws IOException if an error occurred when encoding sending the packet * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-11.3">RFC 4253 - section 11.3</A> */ IoWriteFuture sendDebugMessage(boolean display, Object msg, String lang) throws IOException; /** * Sends an {@code SSH_MSG_IGNORE} to the peer session * * @param data The message data * @return An {@code IoWriteFuture} that can be used to check when the packet has actually been sent * @throws IOException if an error occurred when encoding sending the packet * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-11.2">RFC 4253 - section 11.2</A> */ IoWriteFuture sendIgnoreMessage(byte... data) throws IOException; /** * 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. * * @param buffer the buffer to encode and send * @return An {@code IoWriteFuture} that can be used to check when the packet has actually been sent * @throws IOException if an error occurred when encoding sending the packet */ IoWriteFuture writePacket(Buffer buffer) throws IOException; /** * Encode and send the given buffer with the specified timeout. * If the buffer could not be written before the timeout elapses, the returned * {@link org.apache.sshd.common.io.IoWriteFuture} will be set with a * {@link java.util.concurrent.TimeoutException} exception to indicate a timeout. * * @param buffer the buffer to encode and spend * @param timeout the timeout * @param unit the time unit of the timeout parameter * @return a future that can be used to check when the packet has actually been sent * @throws IOException if an error occurred when encoding sending the packet */ IoWriteFuture writePacket(Buffer buffer, long timeout, TimeUnit unit) throws IOException; /** * Send a global request and wait for the response. This must only be used when sending * a {@code SSH_MSG_GLOBAL_REQUEST} with a result expected, else it will time out * * @param request the request name - used mainly for logging and debugging * @param buffer the buffer containing the global request * @param timeout The number of time units to wait - must be <U>positive</U> * @param unit The {@link TimeUnit} to wait for the response * @return the return buffer if the request was successful, {@code null} otherwise. * @throws IOException if an error occurred when encoding sending the packet */ Buffer request(String request, Buffer buffer, long timeout, TimeUnit unit) throws IOException; /** * Handle any exceptions that occurred on this session. * The session will be closed and a disconnect packet will be * sent before if the given exception is an * {@link org.apache.sshd.common.SshException} with a positive error code * * @param t the exception to process */ void exceptionCaught(Throwable t); /** * Initiate a new key exchange. * * @return A {@link KeyExchangeFuture} for awaiting the completion of the exchange * @throws IOException If failed to request keys re-negotiation */ KeyExchangeFuture reExchangeKeys() throws IOException; /** * Get the service of the specified type. * If the service is not of the specified class, * an IllegalStateException will be thrown. * * @param <T> The generic {@link Service} type * @param clazz The service class * @return The service instance * @throws IllegalStateException If failed to find a matching service */ <T extends Service> T getService(Class<T> clazz); /** * @return the {@link IoSession} associated to this session */ IoSession getIoSession(); /** * Re-start idle timeout timer */ void resetIdleTimeout(); /** * Check if timeout has occurred. * * @return the timeout status, never {@code null} */ TimeoutStatus getTimeoutStatus(); /** * @return Timeout value in milliseconds for authentication stage */ long getAuthTimeout(); /** * @return Timeout value in milliseconds for communication */ long getIdleTimeout(); boolean isAuthenticated(); void setAuthenticated() throws IOException; /** * @return The established session identifier - {@code null} if * not yet established */ byte[] getSessionId(); KeyExchange getKex(); /** * Send a disconnect packet with the given reason and message. * Once the packet has been sent, the session will be closed * asynchronously. * * @param reason the reason code for this disconnect * @param msg the text message * @throws IOException if an error occurred sending the packet */ void disconnect(int reason, String msg) throws IOException; /** * @param name Service name * @throws Exception If failed to start it */ void startService(String name) throws Exception; }