Repository: mina-sshd Updated Branches: refs/heads/master aa14ea40c -> 8c9fe09eb
[SSHD-694] Added documentation regarding global and channel-specific request messages Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/8c9fe09e Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/8c9fe09e Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/8c9fe09e Branch: refs/heads/master Commit: 8c9fe09eb8a998c804f92196f78f47486333e844 Parents: aa14ea4 Author: Lyor Goldstein <[email protected]> Authored: Sun Oct 2 10:32:45 2016 +0300 Committer: Lyor Goldstein <[email protected]> Committed: Sun Oct 2 10:32:45 2016 +0300 ---------------------------------------------------------------------- README.md | 108 ++++++++++++++++++- .../org/apache/sshd/common/BaseBuilder.java | 22 ++-- .../global/CancelTcpipForwardHandler.java | 3 +- .../sshd/server/global/KeepAliveHandler.java | 2 +- .../sshd/server/global/TcpipForwardHandler.java | 3 +- 5 files changed, 119 insertions(+), 19 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/8c9fe09e/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index 94a1bd4..7c1cdf4 100644 --- a/README.md +++ b/README.md @@ -589,7 +589,8 @@ The code implements a [SOCKS](https://en.wikipedia.org/wiki/SOCKS) proxy for ver ### Proxy agent -The code provides to some extent an SSH proxy agent via the available `SshAgentFactory` implementations. +The code provides to some extent an SSH proxy agent via the available `SshAgentFactory` implementations. As of latest version both [ Secure Shell Authentication Agent Protocol Draft 02](https://tools.ietf.org/html/draft-ietf-secsh-agent-02) and its [OpenSSH](https://www.libssh.org/features/) equivalent are supported. + # Advanced configuration and interaction @@ -801,12 +802,26 @@ Inform about SCP related events. `ScpTransferEventListener`(s) can be registered ``` -### `ReservedSessionMessagesHandler` +### Reserved messages + +The implementation can be used to intercept and process the [SSH_MSG_IGNORE](https://tools.ietf.org/html/rfc4253#section-11.2), [SSH_MSG_DEBUG](https://tools.ietf.org/html/rfc4253#section-11.3) and [SSH_MSG_UNIMPLEMENTED](https://tools.ietf.org/html/rfc4253#section-11.4) messages. The handler can be registered on either side - server +or client, as well as on the session. A special [patch](https://issues.apache.org/jira/browse/SSHD-699) has been introduced +that automatically ignores such messages if they are malformed - i.e., they never reach the handler. + +#### SSH message stream "stuffing" and keys re-exchange -The implementation can be used to intercept and process the [SSH_MSG_IGNORE](https://tools.ietf.org/html/rfc4253#section-11.2) -and [SSH_MSG_DEBUG](https://tools.ietf.org/html/rfc4253#section-11.3) messages. The handler can be registered on either side - server -or client, as well as on the session +[RFC 4253 - section 9](https://tools.ietf.org/html/rfc4253#section-9) recommends re-exchanging keys every once in a while +based on the amount of traffic and the selected cipher - the matter is further clarified in [RFC 4251 - section 9.3.2](https://tools.ietf.org/html/rfc4251#section-9.3.2). These recommendations are mirrored in the code via the `FactoryManager` +related `REKEY_TIME_LIMIT`, `REKEY_PACKETS_LIMIT` and `REKEY_BLOCKS_LIMIT` configuration properties that +can be used to configure said behavior - please be sure to read the relevant _Javadoc_ as well the aforementioned RFC section(s) when +manipulating them. This behavior can also be controlled programmatically by overriding the `AbstractSession#isRekeyRequired()` method. +As an added security mechanism [RFC 4251 - section 9.3.1](https://tools.ietf.org/html/rfc4251#section-9.3.1) recommends adding +"spurious" [SSH_MSG_IGNORE](https://tools.ietf.org/html/rfc4253#section-11.2) messages. This functionality is mirrored in the +`FactoryManager` related `IGNORE_MESSAGE_FREQUENCY`, `IGNORE_MESSAGE_VARIANCE` and `IGNORE_MESSAGE_SIZE` +configuration properties that can be used to configure said behavior - please be sure to read the relevant _Javadoc_ as well the aforementioned RFC section when manipulating them. This behavior can also be controlled programmatically by overriding the `AbstractSession#resolveIgnoreBufferDataLength()` method. + +#### `ReservedSessionMessagesHandler` ```java @@ -857,6 +872,89 @@ rather than being accumulated. However, one can use the `EventListenerUtils` and `SessionListener` or `ChannelListener` proxies were implemented. +### `RequestHandler`(s) + +The code supports both [global](https://tools.ietf.org/html/rfc4254#section-4) and [channel-specific](https://tools.ietf.org/html/rfc4254#section-5.4) requests via the registration of `RequestHandler`(s). +The global handlers are derived from `ConnectionServiceRequestHandler`(s) whereas the channel-specific +ones are derived from `ChannelRequestHandler`(s). In order to add a handler one need only register the correct +implementation and handle the request when it is detected: + +```java + + // NOTE: the following code can be employed on BOTH client and server - the example is for the server + SshServer server = SshServer.setUpDefaultServer(); + List<RequestHandler<ConnectionService>> oldGlobals = server.getGlobalRequestHandlers(); + // Create a copy in case current one is null/empty/un-modifiable + List<RequestHandler<ConnectionService>> newGlobals = new ArrayList<>(); + if (GenericUtils.size(oldGlobals) > 0) { + newGlobals.addAll(oldGLobals); + } + newGlobals.add(new MyGlobalRequestHandler()); + server.setGlobalRequestHandlers(newGlobals); + + // Similar code can be done with the server's channelRequestHandlers(); +``` + +The way request handlers are invoked when a global/channel-specific request is received is as follows: + +* All currently registered handlers' `process` method is invoked with the request type string parameter (among others). +The implementation should examine the request parameters and decide whether it is able to process it. + + +* If the handler returns `Result.Unsupported` then the next registered handler is invoked. +In other words, processing stops at the **first** handler that returned a valid response. Thus the importance of +the `List<RequestHandler<...>>` that defines the **order** in which the handlers are invoked. **Note**: while +it is possible to register multiple handlers for the same request and rely on their order, it is highly recommended +to avoid this situation as it makes debugging the code and diagnosing problems much more difficult. + + +* If no handler reported a valid result value then a failure message is sent back to the peer. Otherwise, the returned +result is translated into the appropriate success/failure response (if the sender asked for a response). In this context, +the handler may choose to build and send the response within its own code, in which case it should return the +`Result.Replied` value indicating that it has done so. + + +```java + + public class MySpecialChannelRequestHandler implements ChannelRequestHandler { + ... + + @Override + public Result process(Channel channel, String request, boolean wantReply, Buffer buffer) throws Exception { + if (!"my-special-request".equals(request)) { + return Result.Unsupported; // Not mine - maybe someone else can handle it + } + + ...handle the request - can read more parameters from the message buffer... + + return Result.ReplySuccess/Failure/Replied; // signal processing result + } + } +``` + + +#### Default registered handlers + +* `exit-signal`, `exit-status` - As described in [RFC4254 section 6.10](https://tools.ietf.org/html/rfc4254#section-6.10) + + +* `*@putty.projects.tartarus.org` - As described in [Appendix F: SSH-2 names specified for PuTTY](http://tartarus.org/~simon/putty-snapshots/htmldoc/AppendixF.html) + + +* `[email protected]`, `[email protected]` - As described in [OpenSSH protocol - section 2.5](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL) + + +* `tcpip-forward`, `cancel-tcpip-forward` - As described in [RFC4254 section 7](https://tools.ietf.org/html/rfc4254#section-7) + + +* `keepalive@*` - Used by many implementations (including this one) to "ping" the peer and make sure the connection is still alive. +In this context, the SSHD code allows the user to configure both the frequency and content of the heartbeat request (including whether to send this request at all) via the `ClientFactoryManager`-s `HEARTBEAT_INTERVAL`, `HEARTBEAT_REQUEST` and `DEFAULT_KEEP_ALIVE_HEARTBEAT_STRING` configuration properties. + + +* `no-more-sessions@*` - As described in [OpenSSH protocol section 2.2](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL). In this context, the code consults the `ServerFactoryManagder.MAX_CONCURRENT_SESSIONS` server-side configuration property in order to +decide whether to accept a successfully authentication session. + + # Extension modules There are several extension modules available http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/8c9fe09e/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java b/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java index 081db31..fa5a91c 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java @@ -182,57 +182,57 @@ public class BaseBuilder<T extends AbstractFactoryManager, S extends BaseBuilder return me(); } - public S signatureFactories(final List<NamedFactory<Signature>> signatureFactories) { + public S signatureFactories(List<NamedFactory<Signature>> signatureFactories) { this.signatureFactories = signatureFactories; return me(); } - public S randomFactory(final Factory<Random> randomFactory) { + public S randomFactory(Factory<Random> randomFactory) { this.randomFactory = randomFactory; return me(); } - public S cipherFactories(final List<NamedFactory<Cipher>> cipherFactories) { + public S cipherFactories(List<NamedFactory<Cipher>> cipherFactories) { this.cipherFactories = cipherFactories; return me(); } - public S compressionFactories(final List<NamedFactory<Compression>> compressionFactories) { + public S compressionFactories(List<NamedFactory<Compression>> compressionFactories) { this.compressionFactories = compressionFactories; return me(); } - public S macFactories(final List<NamedFactory<Mac>> macFactories) { + public S macFactories(List<NamedFactory<Mac>> macFactories) { this.macFactories = macFactories; return me(); } - public S channelFactories(final List<NamedFactory<Channel>> channelFactories) { + public S channelFactories(List<NamedFactory<Channel>> channelFactories) { this.channelFactories = channelFactories; return me(); } - public S fileSystemFactory(final FileSystemFactory fileSystemFactory) { + public S fileSystemFactory(FileSystemFactory fileSystemFactory) { this.fileSystemFactory = fileSystemFactory; return me(); } - public S forwardingFilter(final ForwardingFilter filter) { + public S forwardingFilter(ForwardingFilter filter) { this.forwardingFilter = filter; return me(); } - public S tcpipForwarderFactory(final TcpipForwarderFactory tcpipForwarderFactory) { + public S tcpipForwarderFactory(TcpipForwarderFactory tcpipForwarderFactory) { this.tcpipForwarderFactory = tcpipForwarderFactory; return me(); } - public S globalRequestHandlers(final List<RequestHandler<ConnectionService>> globalRequestHandlers) { + public S globalRequestHandlers(List<RequestHandler<ConnectionService>> globalRequestHandlers) { this.globalRequestHandlers = globalRequestHandlers; return me(); } - public S factory(final Factory<T> factory) { + public S factory(Factory<T> factory) { this.factory = factory; return me(); } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/8c9fe09e/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java index 354d678..9d28504 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java @@ -29,9 +29,10 @@ import org.apache.sshd.common.util.buffer.Buffer; import org.apache.sshd.common.util.net.SshdSocketAddress; /** - * Handler for cancel-tcpip-forward global request. + * Handler for "cancel-tcpip-forward" global request. * * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + * @see <A HREF="https://tools.ietf.org/html/rfc4254#section-7">RFC4254 section 7</A> */ public class CancelTcpipForwardHandler extends AbstractConnectionServiceRequestHandler { public static final String REQUEST = "cancel-tcpip-forward"; http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/8c9fe09e/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java index 1cfe6b1..6b6ca2c 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java @@ -23,7 +23,7 @@ import org.apache.sshd.common.session.helpers.AbstractConnectionServiceRequestHa import org.apache.sshd.common.util.buffer.Buffer; /** - * Handler for keepalive@xxx global request. + * Handler for "keepalive@xxx" global request. * * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/8c9fe09e/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java index 8b3368e..325b899 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java @@ -29,9 +29,10 @@ import org.apache.sshd.common.util.buffer.Buffer; import org.apache.sshd.common.util.net.SshdSocketAddress; /** - * Handler for tcpip-forward global request. + * Handler for "tcpip-forward" global request. * * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + * @see <A HREF="https://tools.ietf.org/html/rfc4254#section-7">RFC4254 section 7</A> */ public class TcpipForwardHandler extends AbstractConnectionServiceRequestHandler { public static final String REQUEST = "tcpip-forward";
