You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2016/09/15 16:02:05 UTC

[1/5] mina-sshd git commit: [SSHD-694] Provide README.md file(s) with useful code snippets

Repository: mina-sshd
Updated Branches:
  refs/heads/master 71f5dea3b -> f1df8a2c7


[SSHD-694] Provide README.md file(s) with useful code snippets


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/6a9bb2b6
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/6a9bb2b6
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/6a9bb2b6

Branch: refs/heads/master
Commit: 6a9bb2b6bfee53935756a56311838d5bf9e94fae
Parents: 71f5dea
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Thu Sep 15 19:00:02 2016 +0300
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Thu Sep 15 19:00:02 2016 +0300

----------------------------------------------------------------------
 README.md | 913 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 913 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6a9bb2b6/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..94a1bd4
--- /dev/null
+++ b/README.md
@@ -0,0 +1,913 @@
+![Apache MINA SSHD](https://mina.apache.org/staticresources/images/header-sshd.png "Apache MINA SSHD")
+# Apache MINA SSHD
+
+Apache SSHD is a 100% pure java library to support the SSH protocols on both the client and server side. This library can leverage [Apache MINA](http://mina.apache.org), a scalable and high performance asynchronous IO library. SSHD does not really aim at being a replacement for the SSH client or SSH server from Unix operating systems, but rather provides support for Java based applications requiring SSH support.
+
+# Core requirements
+
+* Java 8+ (as of version 1.3)
+
+* [Slf4j](http://www.slf4j.org/)
+
+The code only requires the core abstract [slf4j-api](https://mvnrepository.com/artifact/org.slf4j/slf4j-api) module. The actual implementation of the logging API can be selected from the many existing adaptors.
+
+* [Bouncy Castle](https://www.bouncycastle.org/)
+
+Required only for reading/writing keys from/to PEM files or for special keys/ciphers/etc. that are not part of the standard [Java Cryptography Extension](https://en.wikipedia.org/wiki/Java_Cryptography_Extension). See [Java Cryptography Architecture (JCA) Reference Guide](https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html) for key classes and explanations as to how _Bouncy Castle_ is plugged in (other security providers).
+
+* [MINA core](https://mina.apache.org/mina-project/)
+
+Optional dependency to enable choosing between NIO asynchronous sockets (the default - for improved performance), and "legacy" sockets. See `IoServiceFactoryFactory` implementations and specifically the `DefaultIoServiceFactoryFactory` for the available options and how it can be configured to select among them.
+
+# Set up an SSH client in 5 minutes
+
+SSHD is designed to easily allow setting up and using an SSH client in a few simple steps. The client needs to be configured and then started before it can be used to connect to an SSH server. There are a few simple steps for creating a client instance - for more more details refer to the `SshClient` class.
+
+## Creating an instance of the `SshClient` class
+
+This is simply done by calling
+
+```java
+
+    SshClient client = SshClient.setupDefaultClient();
+
+```
+
+The call will create an instance with a default configuration suitable for most use cases - including ciphers, compression, MACs, key exchanges, signatures, etc... If your code requires some special configuration, you can look at the code for `setupDefaultClient` and `checkConfig` as a reference for available options and configure the SSH client the way you need.
+
+## Set up client side security
+
+The SSH client contains some security related configuration that one needs to consider
+
+### `ServerKeyVerifier`
+
+`client.setServerKeyVerifier(...);` sets up the server key verifier. As part of the SSH connection initialization protocol, the server proves its "identity" by presenting a public key. The client can examine the key (e.g., present it to the user via some UI) and decide whether to trust the server and continue with the connection setup. By default the client is initialized with an `AcceptAllServerKeyVerifier` that simply logs a warning that an un-verified server key was accepted. There are other out-of-the-box verifiers available in the code:
+
+* `RejectAllServerKeyVerifier` - rejects all server key - usually used in tests or as a fallback verifier if none of it predecesors validated the server key
+
+
+* `RequiredServerKeyVerifier` - accepts only **one** specific server key (similar to certificate pinning for SSL)
+
+
+* `KnownHostsServerKeyVerifier` - uses the [known_hosts](https://en.wikibooks.org/wiki/OpenSSH/Client_Configuration_Files#Public_Keys_from_other_Hosts_.E2.80.93_.7E.2F.ssh.2Fknown_hosts) file to validate the server key. One can use this class + some existing code to **update** the file when new servers are detected and their keys are accepted.
+
+
+Of course, one can implement the verifier in whatever other manner is suitable for the specific code needs.
+
+### ClientIdentityLoader/KeyPairProvider
+
+One can set up the public/private keys to be used in case a password-less authentication is needed. By default, the client is configured to automatically detect and use the identity files residing in the user's *~/.ssh* folder (e.g., *id_rsa*, *id_ecdsa*) and present them as part of the authentication process. **Note:** if the identity files are encrypted via a password, one must configure a `FilePasswordProvider` so that the code can decrypt them before using and presenting them to the server as part of the authentication process. Reading key files in PEM format (including encrypted ones) requires that the [Bouncy Castle](https://www.bouncycastle.org/) supporting artifacts be available in the code's classpath.
+
+### UserInteraction
+
+This interface is required for full support of `keyboard-interactive` authentication protocol as described in [RFC 4256](https://www.ietf.org/rfc/rfc4256.txt). The client can handle a simple password request from the server, but if more complex challenge-response interaction is required, then this interface must be provided - including support for `SSH_MSG_USERAUTH_PASSWD_CHANGEREQ` as described in [RFC 4252 section 8](https://www.ietf.org/rfc/rfc4252.txt).
+
+While RFC-4256 support is the primary purpose of this interface, it can also be used to retrieve the server's welcome banner as described in [RFC 4252 section 5.4](https://www.ietf.org/rfc/rfc4252.txt) as well as its initial identification string as described in [RFC 4253 section 4.2](https://tools.ietf.org/html/rfc4253#section-4.2).
+
+## Using the `SshClient` to connect to a server
+
+Once the `SshClient` instance is properly configured it needs to be `start()`-ed in order to connect to a server. **Note:** one can use a single `SshClient` instance to connnect to multiple server as well as modifying the default configuration (ciphers, MACs, keys, etc.) on a per-session manner (see more in the *Advanced usage* section). Furthermore, one can change almost any configured `SshClient` parameter - although its influence on currently established sessions depends on the actual changed configuration. Here is how a typical usage would look like
+
+```java
+
+    SshClient client = SshClient.setupDefaultClient();
+    // override any default configuration...
+    client.setSomeConfiguration(...);
+    client.setOtherConfiguration(...);
+    client.start();
+
+        // using the client for multiple sessions...
+        try (ClientSession session = client.connect(user, host, port).verify(...timeout...).getSession()) {
+            session.addPasswordIdentity(...password..); // for password-based authentication
+            // or
+            session.addPublicKeyIdentity(...key-pair...); // for password-less authentication
+            // Note: can add BOTH password AND public key identities - depends on the client/server security setup
+
+            session.auth().verify(...timeout...);
+            // start using the session to run commands, do SCP/SFTP, create local/remote port forwarding, etc...
+        }
+
+        // NOTE: this is just an example - one can open multiple concurrent sessions using the same client.
+        //      No need to close the previous session before establishing a new one
+        try (ClientSession anotherSession = client.connect(otherUser, otherHost, port).verify(...timeout...).getSession()) {
+            anotherSession.addPasswordIdentity(...password..); // for password-based authentication
+            anotherSession.addPublicKeyIdentity(...key-pair...); // for password-less authentication
+            anotherSession.auth().verify(...timeout...);
+            // start using the session to run commands, do SCP/SFTP, create local/remote port forwarding, etc...
+        }
+
+    // exiting in an orderly fashion once the code no longer needs to establish SSH session
+    // NOTE: this can/should be done when the application exits.
+    client.stop();
+
+```
+
+# Embedding an SSHD server instance in 5 minutes
+
+SSHD is designed to be easily embedded in your application as an SSH server. The embedded SSH server needs to be configured before it can be started. Essentially, there are a few simple steps for creating the server - for more details refer to the `SshServer` class.
+
+## Creating an instance of the `SshServer` class
+
+Creating an instance of `SshServer` is as simple as creating a new object
+
+```java
+
+    SshServer sshd = SshServer.setUpDefaultServer();
+
+```
+
+It will configure the server with sensible defaults for ciphers, macs, key exchange algorithm, etc... If you want a different behavior, you can look at the code of the `setUpDefaultServer` as well as `checkConfig` methods as a reference for available options and configure the SSH server the way you need.
+
+## Configuring the server instance
+
+There are a few things that need to be configured on the server before being able to actually use it:
+
+* Port - `sshd.setPort(22);` - sets the listen port for the server instance. If not set explicitly then a **random** free port is selected by the O/S. In any case, once the server is `start()`-ed one can query the instance as to the assigned port via `sshd.getPort()`.
+
+
+In this context, the listen bind address can also be specified explicitly via `sshd.setHost(...some IP address...)` that causes the server to bind to a specific network address rather than all addresses (the default). Using "0.0.0.0" as the bind address is also tantamount to binding to all addresses.
+
+
+* `KeyPairProvider` - `sshd.setKeyPairProvider(...);` - sets the host's private keys used for key exchange with clients as well as representing the host's "identities". There are several choices - one can load keys from standard PEM files or generate them in the code.  It's usually a good idea to save generated keys, so that if the SSHD server is restarted, the same keys will be used to authenticate the server and avoid the warning the clients might get if the host keys are modified. **Note**: loading or saving key files in PEM format requires  that the [Bouncy Castle](https://www.bouncycastle.org/) supporting artifacts be available in the code's classpath.
+
+
+* `ShellFactory` - That's the part you will usually have to write to customize the SSHD server. The shell factory will be used to create a new shell each time a user logs in and wants to run an interactive shelll. SSHD provides a simple implementation that you can use if you want. This implementation will create a process and delegate everything to it, so it's mostly useful to launch the OS native shell. E.g.,
+
+
+```java
+
+    sshd.setShellFactory(new ProcessShellFactory(new String[] { "/bin/sh", "-i", "-l" }));
+
+```
+
+
+There is an out-of-the-box `InteractiveProcessShellFactory` that detects the O/S and spawns the relevant shell. Note that the `ShellFactory` is not required. If none is configured, any request for an interactive shell will be denied to clients.
+
+
+* `CommandFactory` - The `CommandFactory` provides the ability to run a **single** direct command at a time instead of an interactive session (it also uses a **different** channel type than shells). It can be used **in addition** to the `ShellFactory`.
+
+
+SSHD provides a `CommandFactory` to support SCP that can be configured in the following way:
+
+
+```java
+
+    sshd.setCommandFactory(new ScpCommandFactory());
+
+```
+
+You can also use the `ScpCommandFactory` on top of your own `CommandFactory` by placing your command factory as a **delegate** of the `ScpCommandFactory`. The `ScpCommandFactory` will intercept SCP commands and execute them by itself, while passing all other commands to (your) delegate `CommandFactory`
+
+
+```java
+
+    sshd.setCommandFactory(new ScpCommandFactory(myCommandFactory));
+
+```
+
+Note that using a `CommandFactory` is also **optional**. If none is configured, any direct command sent by clients will be rejected.
+
+## Server side security setup
+
+The SSHD server security layer has to be customized to suit your needs. This layer is pluggable and uses the following interfaces:
+
+* `PasswordAuthenticator` for password based authentication - [RFC 4252 section 8](https://www.ietf.org/rfc/rfc4252.txt)
+* `PublickeyAuthenticator` for key based authentication - [RFC 4252 section 7](https://www.ietf.org/rfc/rfc4252.txt)
+* `HostBasedAuthenticator` for host based authentication - [RFC 4252 section 9](https://www.ietf.org/rfc/rfc4252.txt)
+* `KeyboardInteractiveAuthenticator` for user interactive authentication - [RFC 4256](https://www.ietf.org/rfc/rfc4256.txt)
+
+
+These custom classes can be configured on the SSHD server using the respective setter methods:
+
+
+```java
+
+    sshd.setPasswordAuthenticator(new MyPasswordAuthenticator());
+    sshd.setPublickeyAuthenticator(new MyPublickeyAuthenticator());
+    sshd.setKeyboardInteractiveAuthenticator(new MyKeyboardInteractiveAuthenticator());
+    ...etc...
+
+```
+
+Several useful implementations are available that can be used as-is or extended in order to provide some custom behavior. In any case, the default initializations are:
+
+* `DefaultAuthorizedKeysAuthenticator` - uses the _authorized_keys_ file the same way as the SSH daemon does
+* `DefaultKeyboardInteractiveAuthenticator` - for password-based or interactive authentication. **Note:** this authenticator requires a `PasswordAuthenticator` to be configured since it delegates some of the functionality to it.
+
+## Configuring ciphers, macs, digest...
+
+SSH supports pluggable factories to define various configuration parts such as ciphers, digests, key exchange, etc...
+The list of supported implementations can be changed to suit your needs, or you can also implement your own factories.
+
+Configuring supported ciphers can be done with the following code:
+
+```java
+
+    sshd.setCipherFactories(Arrays.asList(BuiltinCiphers.aes256ctr, BuiltinCiphers.aes192ctr, BuiltinCiphers.aes128ctr));
+
+```
+
+You can configure other security components using builtin factories the same way.
+
+## Starting the Server
+
+Once we have configured the server, one need only call `sshd.start();`. **Note**: once the server is started, all of the configurations (except the port) can still be *overridden* while the server is running (caveat emptor). In such cases, only **new** clients that connect to the server after the change will be affected - with the exception of the negotiation options (keys, macs, ciphers, etc...) which take effect the next time keys are re-exchanged, that can affect live sessions and not only new ones.
+
+# SSH functionality breakdown
+
+## `FileSystemFactory` usage
+
+This interface is used to provide "file"-related services - e.g., SCP and SFTP - although it can be used for remote command execution
+as well (see the section about commands and the `Aware` interfaces). The default implementation is a `NativeFileSystemFactory`
+that simply exposes the [FileSystems.getDefault()](https://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystems.html#getDefault)
+result. However, for "sandboxed" implementations one can use the `VirtualFileSystemFactory`. This implementation provides a way for
+deciding what is the logged-in user's file system view and then use a `RootedFileSystemProvider` in order to provide a "sandboxed"
+file system where the logged-in user can access only the files under the specified root and no others.
+
+```java
+
+    SshServer sshd = SshServer.setupDefaultServer();
+    sshd.setFileSystemFactory(new VirtualFileSystemFactory() {
+        @Override
+        protected Path computeRootDir(Session session) throws IOException  {
+            String username = session.getUsername(); // or any other session related parameter
+            Path path = resolveUserHome(username);
+            return path;
+        }
+    });
+
+```
+
+The usage of a `FileSystemFactory` is not limited though to the server only - the `ScpClient` implementation also uses
+it in order to retrieve the *local* path for upload/download-ing files/folders. This means that the client side can also
+be tailored to present different views for different clients
+
+
+## `ExecutorService`-s
+
+The framework requires from time to time spawning some threads in order to function correctly - e.g., commands, SFTP subsystem,
+port forwarding (among others) require such support. By default, the framework will allocate an [ExecutorService](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html) for each specific purpose and then shut it down when the module has completed its work - e.g., session
+was closed. Users may provide their own `ExecutorService`(s) instead of the internally auto-allocated ones - e.g., in
+order to control the max. spawned threads, stack size, track threads, etc... If this is done, then one must also provide
+the `shutdownOnExit` value indicating to the overridden module whether to shut down the service once it is no longer necessary.
+
+```java
+
+    /*
+     * An example for SFTP - there are other such locations. By default,
+     * the SftpSubsystem implementation creates a single-threaded executor
+     * for each session, uses it to spawn the SFTP command handler and shuts
+     * it down when the command is destroyed
+     */
+    SftpSubsystemFactory factory = new SftpSubsystemFactory.Builder()
+        .withExecutorService(mySuperDuperExecutorService)
+        .withShutdownOnExit(false)  // I will take care of shutting it down
+        .build();
+    SshServer sshd = SshServer.setupDefaultServer();
+    sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(factory));
+
+```
+
+## Remote command execution
+
+All command execution - be it shell or single command - boils down to a `Command` instance being created, initialized and then
+started. In this context, it is **crucial** to notice that the command's `start()` method implementation **must spawn a new thread** - even
+for the simplest or most trivial command. Any attempt to communicate via the established session will most likely **fail** since
+the packets processing thread may be blocked by this call. **Note:** one might get away with executing some command in the
+context of the thread that called the `start()` method, but it is **extremely dangerous** and should not be attempted.
+
+The command execution code can communicate with the peer client via the input/output/error streams that are provided as
+part of the command initialization process. Once the command is done, it should call the `ExitCallback#onExit` method to indicate
+that it has finished. The framework will then take care of propagating the exit code, closing the session and (eventually) `destroy()`-ing
+the command. **Note**: the command may not assume that it is done until its `destroy()` method is called - i.e., it should not
+release or null-ify any of its internal state even if `onExit()` was called.
+
+Upon calling the `onExit` method the code sends an [SSH_MSG_CHANNEL_EOF](https://tools.ietf.org/html/rfc4254#section-5.3) message, and the provided result status code
+is sent as an `exit-status` message as described in [RFC4254 - section 6.10](https://tools.ietf.org/html/rfc4254#section-6.10).
+The provided message is simply logged at DEBUG level.
+
+```java
+
+    // A simple command implementation example
+    class MyCommand implements Command, Runnable {
+        private InputStream in;
+        private OutputStream out, err;
+        private ExitCallback callback;
+
+        public MyCommand() {
+            super();
+        }
+
+        @Override
+        public void setInputStream(InputStream in) {
+            this.in = in;
+        }
+
+        @Override
+        public void setOutputStream(OutputStream out) {
+            this.out = out;
+        }
+
+        @Override
+        public void setErrorStream(OutputStream err) {
+            this.err = err;
+        }
+
+        @Override
+        public void setExitCallback(ExitCallback callback) {
+            this.callback = callback;
+        }
+
+        @Override
+        public void start(Environment env) throws IOException {
+            spawnHandlerThread(this);
+        }
+
+        @Override
+        public void run() {
+            while(true) {
+                try {
+                    String cmd = readCommand(in);
+                    if ("exit".equals(cmd)) {
+                        break;
+                    }
+
+                    handleCommand(cmd, out);
+                } catch (Exception e) {
+                    writeError(err, e);
+                    onExit(-1, e.getMessage());
+                    return;
+            }
+
+            callback.onExit(0);
+        }
+    }
+```
+
+### `Aware` interfaces
+
+Once created, the `Command` instance is checked to see if it implements one of the `Aware` interfaces that enables
+injecting some dynamic data before the command is `start()`-ed.
+
+* `SessionAware` - Injects the `Session` instance through which the command request was received.
+
+* `ChannelSessionAware` - Injects the `ChannelSession` instance through which the command request was received.
+
+* `FileSystemAware` - Injects the result of consulting the `FileSystemFactory` as to the [FileSystem](https://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystem.html)
+associated with this command.
+
+
+## SCP
+
+Besides the `ScpTransferEventListener`, the SCP module also uses a `ScpFileOpener` instance in order to access
+the local files - client or server-side. The default implementation simply opens an [InputStream](https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html)
+or [OutputStream](https://docs.oracle.com/javase/8/docs/api/java/io/OutputStream.html) on the requested local path. However,
+the user may replace it and intercept the calls - e.g., for logging, for wrapping/filtering the streams, etc... **Note:**
+due to SCP protocol limitations one cannot change the **size** of the input/output since it is passed as part of the command
+**before** the file opener is invoked - so there are a few limitations on what one can do within this interface implementation.
+
+
+## SFTP
+
+In addition to the `SftpEventListener` there are a few more SFTP-related special interfaces and modules.
+
+
+### Version selection via `SftpVersionSelector`
+
+
+The SFTP subsystem code supports versions 3-6 (inclusive), and by default attempts to negotiate the **highest**
+possible one - on both client and server code. The user can intervene and force a specific version or a narrower
+range.
+
+
+```java
+
+    SftpVersionSelector myVersionSelector = new SftpVersionSelector() {
+        @Override
+        public int selectVersion(ClientSession session, int current, List<Integer> available) {
+            int selectedVersion = ...run some logic to decide...;
+            return selectedVersion;
+        }
+    };
+
+    try (ClientSession session = client.connect(user, host, port).verify(timeout).getSession()) {
+        session.addPasswordIdentity(password);
+        session.auth.verify(timeout);
+
+        try (SftpClient sftp = session.createSftpClient(myVersionSelector)) {
+            ... do SFTP related stuff...
+        }
+    }
+
+```
+
+On the server side, version selection restriction is more complex - please remember that the **client** chooses
+the version, and all we can do at the server is require a **specific** version via the `SftpSubsystem#SFTP_VERSION`
+configuration key. For more advanced restrictions on needs to sub-class `SftpSubSystem` and provide a non-default
+`SftpSubsystemFactory` that uses the sub-classed code.
+
+### Using `SftpFileSystemProvider` to create an `SftpFileSystem`
+
+
+The code automatically registers the `SftpFileSystemProvider` as the handler for `sftp://` URL(s). Such URLs are
+interpreted as remote file locations and automatically exposed to the user as [Path](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html)
+objects. In effect, this allows the code to "mount" a remote directory via SFTP and treat it as if it were local using
+standard [java.nio](https://docs.oracle.com/javase/8/docs/api/java/nio/package-frame.html) calls like any "ordinary" file
+system.
+
+```java
+
+    // Direct URI
+    Path remotePath = Paths.get(new URI("sftp://user:password@host/some/remote/path"));
+
+    // "Mounting" a file system
+    URI uri = SftpFileSystemProvider.createFileSystemURI(host, port, username, password);
+    FileSystem fs = FileSystems.newFileSystem(uri, Collections.<String, Object>emptyMap());
+    Path remotePath = fs.getPath("/some/remote/path");
+
+    // Full programmatic control
+    SshClient client = ...setup and start the SshClient instance...
+    SftpFileSystemProvider provider = new SftpFileSystemProvider(client);
+    URI uri = SftpFileSystemProvider.createFileSystemURI(host, port, username, password);
+    FileSystem fs = provider.newFileSystem(uri, Collections.<String, Object>emptyMap());
+    Path remotePath = fs.getPath("/some/remote/path");
+
+```
+
+ The obtained `Path` instance can be used in exactly the same way as any other "regular" one:
+
+
+ ```java
+
+    try (InputStream input = Files.newInputStream(remotePath)) {
+        ...read from remote file...
+    }
+
+    try (DirectoryStream<Path> ds = Files.newDirectoryStream(remoteDir)) {
+        for (Path remoteFile : ds) {
+            if (Files.isRegularFile(remoteFile)) {
+                System.out.println("Delete " + remoteFile + " size=" + Files.size(remoteFile));
+                Files.delete(remoteFile);
+            } else if (Files.isDirectory(remoteFile)) {
+                System.out.println(remoteFile + " - directory");
+            }
+        }
+    }
+```
+
+#### Configuring the `SftpFileSystemProvider`
+
+When "mounting" a new file system one can provide configuration parameters using either the
+environment map in the [FileSystems#newFileSystem](https://docs.oracle.com/javase/8/docs/api/java/nio/file/FileSystems.html#newFileSystem)
+method or via the URI query parameters. See the `SftpFileSystemProvider` for the available
+configuration keys and values.
+
+
+```java
+
+    // Using explicit parameters
+    Map<String, Object> params = new HashMap<>();
+    params.put("param1", value1);
+    params.put("param2", value2);
+    ...etc...
+
+    URI uri = SftpFileSystemProvider.createFileSystemURI(host, port, username, password);
+    FileSystem fs = FileSystems.newFileSystem(uri, params);
+    Path remotePath = fs.getPath("/some/remote/path");
+
+    // Using URI parameters
+    Path remotePath = Paths.get(new URI("sftp://user:password@host/some/remote/path?param1=value1&param2=value2..."));
+
+```
+
+**Note**: if **both** options are used then the URI parameters **override** the environment ones
+
+
+```java
+
+    Map<String, Object> params = new HashMap<>();
+    params.put("param1", value1);
+    params.put("param2", value2);
+
+    // The value of 'param1' is overridden in the URI
+    FileSystem fs = FileSystems.newFileSystem(new URI("sftp://user:password@host/some/remote/path?param1=otherValue1", params);
+    Path remotePath = fs.getPath("/some/remote/path");
+
+```
+
+
+### Supported SFTP extensions
+
+Both client and server support several of the SFTP extensions specified in various drafts:
+
+* `supported` - [DRAFT 05 - section 4.4](http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-05.tx)
+* `supported2` - [DRAFT 13 section 5.4](https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#page-10)
+* `versions` - [DRAFT 09 Section 4.6](http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt)
+* `vendor-id` - [DRAFT 09 - section 4.4](http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt)
+* `acl-supported` - [DRAFT 11 - section 5.4](https://tools.ietf.org/html/draft-ietf-secsh-filexfer-11)
+* `newline` - [DRAFT 09 Section 4.3](http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt)
+* `md5-hash`, `md5-hash-handle` - [DRAFT 09 - section 9.1.1](http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt)
+* `check-file-handle`, `check-file-name` - [DRAFT 09 - section 9.1.2](http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt)
+* `copy-file`, `copy-data` - [DRAFT 00 - sections 6, 7](http://tools.ietf.org/id/draft-ietf-secsh-filexfer-extensions-00.txt)
+* `space-available` - [DRAFT 09 - section 9.3](http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt)
+
+Furthermore several [OpenSSH SFTP extensions](https://github.com/openssh/openssh-portable/blob/master/PROTOCOL) are also supported:
+
+* `fsync@openssh.com`
+* `fstatvfs@openssh.com`
+* `hardlink@openssh.com`
+* `posix-rename@openssh.com`
+* `statvfs@openssh.com`
+
+
+On the server side, the reported standard extensions are configured via the `SftpSubsystem.CLIENT_EXTENSIONS_PROP` configuration key, and the _OpenSSH_ ones via the `SftpSubsystem.OPENSSH_EXTENSIONS_PROP`.
+
+On the client side, all the supported extensions are classes that implement `SftpClientExtension`. These classes can be used to query the client whether the remote server supports the specific extension and then obtain a parser for its contents. Users can easily add support for more extensions in a similar manner as the existing ones by implementing an appropriate `ExtensionParser` and then registring it at the `ParserUtils` - see the existing ones for details how this can be achieved.
+
+
+```java
+
+    // properietary/special extension parser
+    ParserUtils.registerExtension(new MySpecialExtension());
+
+    try (ClientSession session = client.connect(username, host, port).verify(timeout).getSession()) {
+        session.addPasswordIdentity(password);
+        session.auth().verify(timeout);
+
+        try (SftpClient sftp = session.createSftpClient()) {
+            Map<String, byte[]> extensions = sftp.getServerExtensions();
+            // Key=extension name, value=registered parser instance
+            Map<String, ?> data = ParserUtils.parse(extensions);
+            for (Map.Entry<String, ?> de : data.entrySet()) {
+                String extName = de.getKey();
+                Object extValue = de.getValue();
+                if (SftpConstants.EXT_ACL_SUPPORTED.equalsIgnoreCase(extName)) {
+                    AclCapabilities capabilities = (AclCapabilities) extValue;
+                    ...see what other information can be gleaned from it...
+                } else if ((SftpConstants.EXT_VERSIONS.equalsIgnoreCase(extName)) {
+                    Versions versions = (Versions) extValue;
+                    ...see what other information can be gleaned from it...
+                } else if ("my-special-extension".equalsIgnoreCase(extName)) {
+                    MySpecialExtension special = (MySpecialExtension) extValue;
+                    ...see what other information can be gleaned from it...
+                } // ...etc....
+            }
+        }
+    }
+
+```
+
+One can skip all the conditional code if a specific known extension is required:
+
+
+```java
+    try (ClientSession session = client.connect(username, host, port).verify(timeout).getSession()) {
+        session.addPasswordIdentity(password);
+        session.auth().verify(timeout);
+
+        try (SftpClient sftp = session.createSftpClient()) {
+            // Returns null if extension is not supported by remote server
+            SpaceAvailableExtension space = sftp.getExtension(SpaceAvailableExtension.class);
+            if (space != null) {
+                ...use it...
+            }
+        }
+    }
+```
+
+## Port forwarding
+
+### Standard port forwarding
+
+Port forwarding as specified in [RFC 4254 - section 7](https://tools.ietf.org/html/rfc4254#section-7) is fully supported by the client and server. From the client side, this capability is exposed via the `start/stopLocal/RemotePortForwarding` method. The key player in this capability is the configured `ForwardingFilter` that controls this feature - on **both** sides - client and server. By default, this capability is **disabled** - i.e., the user must provide an implementation and call the appropriate `setTcpipForwardingFilter` method on the client/server.
+
+The code contains 2 simple implementations - an accept-all and a reject-all one that can be used for these trivial policies. **Note:** setting a _null_ filter is equivalent to rejecting all such attempts.
+
+### SOCKS
+
+The code implements a [SOCKS](https://en.wikipedia.org/wiki/SOCKS) proxy for versions 4 and 5. The proxy capability is invoked via the `start/stopDynamicPortForwarding` methods.
+
+### Proxy agent
+
+The code provides to some extent an SSH proxy agent via the available `SshAgentFactory` implementations.
+
+# Advanced configuration and interaction
+
+## Properties and inheritance model
+The code's behavior is highly customizable not only via non-default implementations of interfaces but also as far as the **parameters** that govern its behavior - e.g., timeouts, min./max. values, allocated memory size, etc... All the customization related code flow implements a **hierarchical** `PropertyResolver` inheritance model where the "closest" entity is consulted first, and then its "owner", and so on until the required value is found. If the entire hierarchy yielded no specific result, then some pre-configured default is used. E.g., if a channel requires some parameter in order to decide how to behave, then the following configuration hierarchy is consulted:
+
+* The channel-specific configuration
+* The "owning" session configuration
+* The "owning" client/server instance configuration
+* The system properties - **Note:** any configuration value required by the code can be provided via a system property bearing the `org.apache.sshd.config` prefix - see `SyspropsMapWrapper` for the implementation details.
+
+
+### Using the inheritance model for fine-grained/targeted configuration
+
+As previously mentioned, this hierarchical lookup model is not limited to "simple" configuration values (strings, integers, etc.), but used also for **interfaces/implementations** such as cipher/MAC/compression/authentication/etc. factories - the exception being that the system properties are not consulted in such a case. This code behavior provides highly customizable fine-grained/targeted control of the code's behavior - e.g., one could impose usage of specific ciphers/authentication methods/etc. or present different public key "identities"/welcome banner behavior/etc., based on address, username or whatever other decision parameter is deemed relevant by the user's code. This can be done on __both__ sides of the connection - client or server. E.g., the client could present different keys based on the server's address/identity string/welcome banner, or the server could accept only specific types of authentication methods based on the client's address/username/etc... This can be don
 e in conjuction with the usage of the various `EventListener`-s provided by the code (see below).
+
+One of the code locations where this behavior can be leveraged is when the server provides __file-based__ services (SCP, SFTP) in order to provide a different/limited view of the available files based on the username - see the section dealing with `FileSystemFactory`-ies.
+
+## Welcome banner configuration
+
+According to [RFC 4252 - section 5.4](https://tools.ietf.org/html/rfc4252#section-5.4) the server may send a welcome banner message during the authentication process. Both the message contents and the phase at which it is sent can be configured/customized.
+
+### Welcome banner content customization
+
+The welcome banner contents are controlled by the `ServerAuthenticationManager.WELCOME_BANNER` configuration key - there are several possible values for this key:
+
+* A simple string - in which case its contents are the welcome banner.
+
+
+* A file [URI](https://docs.oracle.com/javase/8/docs/api/java/net/URI.html) - or a string starting with `"file:/"` followed by the file path - see below.
+
+
+* A [URL](https://docs.oracle.com/javase/8/docs/api/java/net/URL.html) - or a string contaning "://" - in which case the [URL#openStream()](https://docs.oracle.com/javase/8/docs/api/java/net/URL.html#openStream) method is invoked and its contents are read.
+
+
+* A [File](https://docs.oracle.com/javase/8/docs/api/java/io/File.html) or a [Path](https://docs.oracle.com/javase/8/docs/api/java/nio/file/Path.html) - in this case, the file's contents are __re-loaded__ every time it is required and sent as the banner contents.
+
+
+* The special value `ServerAuthenticationManager.AUTO_WELCOME_BANNER_VALUE` which generates a combined "random art" of all the server's keys as described in `Perrig A.` and `Song D.`-s article [Hash Visualization: a New Technique to improve Real-World Security](http://sparrow.ece.cmu.edu/~adrian/projects/validation/validation.pdf) - _International Workshop on Cryptographic Techniques and E-Commerce (CrypTEC '99)_
+
+
+* One can also override the `ServerUserAuthService#resolveWelcomeBanner` method and use whatever other content customization one sees fit.
+
+**Note:**
+
+
+1. If any of the sources yields an empty string or is missing (in the case of a resource) then no welcome banner message is sent.
+
+2. If the banner is loaded from a file or URL resource, then one can configure the [Charset](https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html) used to convert the file's contents into a string via the `ServerAuthenticationManager.WELCOME_BANNER_CHARSET` configuration key (default=`UTF-8`).
+
+3. In this context, see also the `ServerAuthenticationManager.WELCOME_BANNER_LANGUAGE` configuration key - which provides control over the declared language tag, although most clients seem to ignore it.
+
+
+### Welcome banner sending phase
+
+According to [RFC 4252 - section 5.4](https://tools.ietf.org/html/rfc4252#section-5.4):
+
+> The SSH server may send an SSH_MSG_USERAUTH_BANNER message at any time after this authentication protocol starts and before authentication is successful.
+
+
+The code contains a `WelcomeBannerPhase` enumeration that can be used to configure via the `ServerAuthenticationManager.WELCOME_BANNER_PHASE` configuration key the authentication phase at which the welcome banner is sent (see also the `ServerAuthenticationManager.DEFAULT_BANNER_PHASE` value). In this context, note that if the `NEVER` phase is configured, no banner will be sent even if one has been configured via one of the methods mentioned previously.
+
+
+## `HostConfigEntryResolver`
+
+This interface provides the ability to intervene during the connection and authentication phases and "re-write" the user's original parameters. The `DefaultConfigFileHostEntryResolver` instance used to set up the default client instance follows the [SSH config file](https://www.digitalocean.com/community/tutorials/how-to-configure-custom-connection-options-for-your-ssh-client) standards, but the interface can be replaced so as to implement whatever proprietary logic is required.
+
+
+```java
+
+    SshClient client = SshClient.setupDefaultClient();
+    client.setHostConfigEntryResolver(new MyHostConfigEntryResolver());
+    client.start();
+
+    /*
+     * The resolver might decide to connect to some host2/port2 using user2 and password2
+     * (or maybe using some key instead of the password).
+     */
+    try (ClientSession session = client.connect(user1, host1, port1).verify(...timeout...).getSession()) {
+        session.addPasswordIdentity(...password1...);
+        session.auth().verify(...timeout...);
+    }
+```
+
+
+## `SshConfigFileReader`
+
+Can be used to read various standard SSH [client](http://linux.die.net/man/5/ssh_config) or [server](http://manpages.ubuntu.com/manpages/precise/en/man5/sshd_config.5.html) configuration files and initialize the client/server respectively. Including (among other things), bind address, ciphers, signature, MAC(s), KEX protocols, compression, welcome banner, etc..
+
+## Event listeners
+
+The code supports registering many types of event listeners that enable receiving notifications about important events as well as sometimes intervening in the way these events are handled. All listener interfaces extend `SshdEventListener` so they can be easily detected and distinguished from other `EventListener`(s).
+
+In general, event listeners are **cumulative** - e.g., any channel event listeners registered on the `SshClient/Server` are automatically added to all sessions, *in addition* to any such listeners registered on the `Session`, as well as any specific listeners registered on a specific `Channel` - e.g.,
+
+
+```java
+
+    // Any channel event will be signalled to ALL the registered listeners
+    sshClient/Server.addChannelListener(new Listener1());
+    sshClient/Server.addSessionListener(new SessionListener() {
+        @Override
+        public void sessionCreated(Session session) {
+            session.addChannelListener(new Listener2());
+            session.addChannelListener(new ChannelListener() {
+                @Override
+                public void channelInitialized(Channel channel) {
+                    channel.addChannelListener(new Listener3());
+                }
+            });
+        }
+    });
+
+```
+
+
+### `SessionListener`
+
+Informs about session related events. One can modify the session - although the modification effect depends on the session's **state**. E.g., if one changes the ciphers *after* the key exchange (KEX) phase, then they will take effect only if the keys are re-negotiated. It is important to read the documentation very carefully and understand at which stage each listener method is invoked and what are the repercussions of changes at that stage. In this context, it is worth mentioning that one can attach to sessions **arbitrary attributes** that can be retrieved by the user's code later on:
+
+
+```java
+
+    public static final AttributeKey<String> STR_KEY = new AttributeKey<>();
+    public static final AttributeKey<Long> LONG_KEY = new AttributeKey<>();
+
+    sshClient/Server.addSessionListener(new SessionListener() {
+        @Override
+        public void sessionCreated(Session session) {
+            session.setAttribute(STR_KEY, "Some string value");
+            session.setAttribute(LONG_KEY, 3777347L);
+            // ...etc...
+        }
+
+        @Override
+        public void sessionClosed(Session session) {
+            String str = session.getAttribute(STR_KEY);
+            Long l = session.getAttribute(LONG_KEY);
+            // ... do something with the retrieved attributes ...
+        }
+    });
+```
+
+### `ChannelListener`
+
+
+Informs about channel related events - as with sessions, once can influence the channel to some extent, depending on the channel's **state**. The ability to influence channels is much more limited than sessions. In this context, it is worth mentioning that one can attach to channels **arbitrary attributes** that can be retrieved by the user's code later on - same was as it is done for sessions.
+
+
+### `SignalListener`
+
+Informs about signal requests as described in [RFC 4254 - section 6.9](https://tools.ietf.org/html/rfc4254#section-6.9), break requests (sent as SIGINT) as described in [RFC 4335](https://tools.ietf.org/html/rfc4335) and "window-change" (sent as SIGWINCH) requests as described in [RFC 4254 - section 6.7](https://tools.ietf.org/html/rfc4254#section-6.7)
+
+
+### `SftpEventListener`
+
+Provides information about major SFTP protocol events. The listener is registered at the `SftpSubsystemFactory`:
+
+
+```java
+
+    SftpSubsystemFactory factory = new SftpSubsystemFactory();
+    factory.addSftpEventListener(new MySftpEventListener());
+    sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(factory));
+
+```
+
+
+### `PortForwardingEventListener`
+
+Informs and allows tracking of port forwarding events as described in [RFC 4254 - section 7](https://tools.ietf.org/html/rfc4254#section-7) as well as the (simple) [SOCKS](https://en.wikipedia.org/wiki/SOCKS) protocol (versions 4, 5). In this context, one can create a `PortForwardingTracker` that can be used in a `try-with-resource` block so that the set up forwarding is automatically torn down when the tracker is `close()`-d:
+
+
+```java
+
+    try (ClientSession session = client.connect(user, host, port).verify(...timeout...).getSession()) {
+        session.addPasswordIdentity(password);
+        session.auth().verify(...timeout...);
+
+        try (PortForwardingTracker tracker = session.createLocal/RemotePortForwardingTracker(...)) {
+            ...do something that requires the tunnel...
+        }
+
+        // Tunnel is torn down when code reaches this point
+    }
+```
+
+
+### `ScpTransferEventListener`
+
+Inform about SCP related events. `ScpTransferEventListener`(s) can be registered on *both* client and server side:
+
+
+```java
+
+    // Server side
+    ScpCommandFactory factory = new ScpCommandFactory(...with/out delegate..);
+    factory.addEventListener(new MyServerSideScpTransferEventListener());
+    sshd.setCommandFactory(factory);
+
+    // Client side
+    try (ClientSession session = client.connect(user, host, port).verify(...timeout...).getSession()) {
+        session.addPasswordIdentity(password);
+        session.auth().verify(...timeout...);
+
+        ScpClient scp = session.createScpClient(new MyClientSideScpTransferEventListener());
+        ...scp.upload/download...
+    }
+```
+
+
+### `ReservedSessionMessagesHandler`
+
+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
+
+
+```java
+
+    // client side
+    SshClient client = SshClient.setupDefaultClient();
+    // This is the default for ALL sessions unless specifically overridden
+    client.setReservedSessionMessagesHandler(new MyClientSideReservedSessionMessagesHandler());
+    // Adding it via a session listener
+    client.setSessionListener(new SessionListener() {
+            @Override
+            public void sessionCreated(Session session) {
+                // Overrides the one set at the client level.
+                if (isSomeSessionOfInterest(session)) {
+                    session.setReservedSessionMessagesHandler(new MyClientSessionReservedSessionMessagesHandler(session));
+                }
+            }
+    });
+
+    try (ClientSession session = client.connect(user, host, port).verify(...timeout...).getSession()) {
+        // setting it explicitly
+        session.setReservedSessionMessagesHandler(new MyOtherClientSessionReservedSessionMessagesHandler(session));
+        session.addPasswordIdentity(password);
+        session.auth().verify(...timeout...);
+
+        ...use the session...
+    }
+
+
+    // server side
+    SshServer server = SshServer.setupDefaultServer();
+    // This is the default for ALL sessions unless specifically overridden
+    server.setReservedSessionMessagesHandler(new MyServerSideReservedSessionMessagesHandler());
+    // Adding it via a session listener
+    server.setSessionListener(new SessionListener() {
+            @Override
+            public void sessionCreated(Session session) {
+                // Overrides the one set at the server level.
+                if (isSomeSessionOfInterest(session)) {
+                    session.setReservedSessionMessagesHandler(new MyServerSessionReservedSessionMessagesHandler(session));
+                }
+            }
+    });
+
+```
+
+**NOTE:** Unlike "regular" event listeners, the handler is not cumulative - i.e., setting it overrides the previous instance
+rather than being accumulated. However, one can use the `EventListenerUtils` and create a cumulative listener - see how
+`SessionListener` or `ChannelListener` proxies were implemented.
+
+
+# Extension modules
+
+There are several extension modules available
+
+## Command line clients
+
+The _apache-sshd.zip_ distribution provides `Windows/Linux` scripts that use the MINA SSHD code base to implement the common _ssh, scp, sftp_ commands. The clients accept most useful switches from the original commands they mimic, where the `-o Option=Value` arguments can be used to configure the client/server in addition to the system properties mechanism. For more details, consult the _main_ methods code in the respective `SshClient`, `SftpCommand` and `DefaultScpClient` classes.
+
+The code includes `SshKeyScan#main` that is an equivalent for [ssh-keyscan(1)](https://www.freebsd.org/cgi/man.cgi?query=ssh-keyscan&sektion=1), though it is not wrapped inside a script.
+
+The distribution also includes also an _sshd_ script that can be used to launch a server instance - see `SshServer#main` for activation command line arguments and options.
+
+## GIT support
+
+The _sshd-git_ artifact contains server-side command factories for handling some _git_ commands - see `GitPackCommandFactory` and `GitPgmCommandFactory`. These command factories accept a delegate to which non-_git_ commands are routed:
+
+
+```java
+
+    sshd.setCommandFactory(new GitPackCommandFactory(rootDir, new MyCommandFactory()));
+
+    // Here is how it looks if SCP is also requested
+    sshd.setCommandFactory(new GitPackCommandFactory(rootDir, new ScpCommandFactory(new MyCommandFactory())))
+    // or
+    sshd.setCommandFactory(new ScpCommandFactory(new GitPackCommandFactory(rootDir, new MyCommandFactory())))
+    // or
+    sshd.setCommandFactory(new GitPackCommandFactory(rootDir, new ScpCommandFactory(new MyCommandFactory())))
+    // or any other combination ...
+```
+
+
+## LDAP adaptors
+
+The _sshd-ldap_ artifact contains an [LdapPasswordAuthenticator](https://issues.apache.org/jira/browse/SSHD-607) and an [LdapPublicKeyAuthenticator](https://issues.apache.org/jira/browse/SSHD-608) that have been written along the same lines as the [openssh-ldap-publickey](https://github.com/AndriiGrytsenko/openssh-ldap-publickey) project. The authenticators can be easily configured to match most LDAP schemes, or alternatively serve as base classes for code that extends them and adds proprietary logic.
+
+## PROXY / SSLH protocol hooks
+
+The code contains [support for "wrapper" protocols](https://issues.apache.org/jira/browse/SSHD-656) such as [PROXY](http://www.haproxy.org/download/1.6/doc/proxy-protocol.txt) or  [sslh](http://www.rutschle.net/tech/sslh.shtml). The idea is that one can register either a `ClientProxyConnector` or `ServerProxyAcceptor` and intercept the 1st packet being sent/received (respectively) **before** it reaches the SSHD code. This gives the programmer the capability to write a front-end that routes outgoing/incoming packets:
+
+* `SshClient/ClientSesssion#setClientProxyConnector` - sets a proxy that intercepts the 1st packet before being sent to the server
+
+* `SshServer/ServerSession#setServerProxyAcceptor` - sets a proxy that intercept the 1st incoming packet before being processed by the server
+
+# Builtin components
+
+Below is the list of builtin components:
+
+* **Ciphers**: aes128cbc, aes128ctr, aes192cbc, aes192ctr, aes256cbc, aes256ctr, arcfour128, arcfour256, blowfishcbc, tripledescbc
+* **Digests**: md5, sha1, sha224, sha384, sha512
+* **Macs**: hmacmd5, hmacmd596, hmacsha1, hmacsha196, hmacsha256, hmacsha512
+* **Key exchange**: dhg1, dhg14, dhgex, dhgex256, ecdhp256, ecdhp384, ecdhp521
+* **Compressions**: none, zlib, zlib@openssh.com
+* **Signatures**: ssh-dss, ssh-rsa, nistp256, nistp384, nistp521
+


[4/5] mina-sshd git commit: [SSHD-694] Updated documentation in some classes

Posted by lg...@apache.org.
[SSHD-694] Updated documentation in some classes


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/c334fd65
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/c334fd65
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/c334fd65

Branch: refs/heads/master
Commit: c334fd65712b9de76efec00584c396fce57b36f6
Parents: 3453416
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Thu Sep 15 19:03:26 2016 +0300
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Thu Sep 15 19:03:26 2016 +0300

----------------------------------------------------------------------
 .../org/apache/sshd/agent/local/AgentForwardedChannel.java  | 1 -
 .../channel/exit/ExitSignalChannelRequestHandler.java       | 2 +-
 .../channel/exit/ExitStatusChannelRequestHandler.java       | 2 +-
 .../config/hosts/DefaultConfigFileHostEntryResolver.java    | 2 --
 .../extensions/helpers/CheckFileHandleExtensionImpl.java    | 3 +++
 .../sftp/extensions/helpers/CheckFileNameExtensionImpl.java | 3 +++
 .../sftp/extensions/helpers/CopyDataExtensionImpl.java      | 3 +++
 .../sftp/extensions/helpers/CopyFileExtensionImpl.java      | 3 +++
 .../sftp/extensions/helpers/MD5FileExtensionImpl.java       | 3 +++
 .../sftp/extensions/helpers/MD5HandleExtensionImpl.java     | 3 +++
 .../extensions/helpers/SpaceAvailableExtensionImpl.java     | 3 +++
 .../common/file/virtualfs/VirtualFileSystemFactory.java     | 9 +++++----
 .../org/apache/sshd/common/io/IoServiceFactoryFactory.java  | 2 +-
 .../org/apache/sshd/server/ServerAuthenticationManager.java | 2 +-
 .../src/main/java/org/apache/sshd/server/SshServer.java     | 2 +-
 .../src/test/java/org/apache/sshd/client/ClientTest.java    | 2 +-
 .../extensions/helpers/SpaceAvailableExtensionImplTest.java | 4 ++--
 .../extensions/openssh/helpers/OpenSSHExtensionsTest.java   | 4 ++--
 .../org/apache/sshd/server/subsystem/sftp/SshFsMounter.java | 7 +++----
 .../java/org/apache/sshd/git/pack/GitPackCommandTest.java   | 4 ++--
 .../java/org/apache/sshd/git/pgm/GitPgmCommandTest.java     | 4 ++--
 21 files changed, 43 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
index 29d70f2..9a33990 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
@@ -115,5 +115,4 @@ public class AgentForwardedChannel extends AbstractClientChannel {
             }
         }
     }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/ExitSignalChannelRequestHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/ExitSignalChannelRequestHandler.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/ExitSignalChannelRequestHandler.java
index eac6514..6ebb7b2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/ExitSignalChannelRequestHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/ExitSignalChannelRequestHandler.java
@@ -26,7 +26,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- * @see <A HREF="https://tools.ietf.org/html/rfc4254#page-15">RFC4254 section 6.10</A>
+ * @see <A HREF="https://tools.ietf.org/html/rfc4254#section-6.10">RFC4254 section 6.10</A>
  */
 public class ExitSignalChannelRequestHandler extends AbstractChannelExitRequestHandler<String> {
     public static final String NAME = "exit-signal";

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/ExitStatusChannelRequestHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/ExitStatusChannelRequestHandler.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/ExitStatusChannelRequestHandler.java
index 407668d..39954b1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/ExitStatusChannelRequestHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/ExitStatusChannelRequestHandler.java
@@ -26,7 +26,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- * @see <A HREF="https://tools.ietf.org/html/rfc4254#page-15">RFC4254 section 6.10</A>
+ * @see <A HREF="https://tools.ietf.org/html/rfc4254#section-6.10">RFC4254 section 6.10</A>
  */
 public class ExitStatusChannelRequestHandler extends AbstractChannelExitRequestHandler<Integer> {
     public static final String NAME = "exit-status";

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/DefaultConfigFileHostEntryResolver.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/DefaultConfigFileHostEntryResolver.java b/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/DefaultConfigFileHostEntryResolver.java
index 3d39b6d..174a14b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/DefaultConfigFileHostEntryResolver.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/DefaultConfigFileHostEntryResolver.java
@@ -38,7 +38,6 @@ import org.apache.sshd.common.util.io.IoUtils;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class DefaultConfigFileHostEntryResolver extends ConfigFileHostEntryResolver {
-
     /**
      * The default instance that enforces the same permissions regime as {@code OpenSSH}
      */
@@ -93,5 +92,4 @@ public class DefaultConfigFileHostEntryResolver extends ConfigFileHostEntryResol
 
         return super.reloadHostConfigEntries(path, host, port, username);
     }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CheckFileHandleExtensionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CheckFileHandleExtensionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CheckFileHandleExtensionImpl.java
index 4fba6a1..65e6b54 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CheckFileHandleExtensionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CheckFileHandleExtensionImpl.java
@@ -30,6 +30,9 @@ import org.apache.sshd.common.subsystem.sftp.SftpConstants;
 import org.apache.sshd.common.util.Pair;
 
 /**
+ * Implements &quot;check-file-handle&quot; extension
+ *
+ * @see <A HREF="http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt">DRAFT 09 - section 9.1.2</A>
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class CheckFileHandleExtensionImpl extends AbstractCheckFileExtension implements CheckFileHandleExtension {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CheckFileNameExtensionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CheckFileNameExtensionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CheckFileNameExtensionImpl.java
index 4dffc1f..77c4af3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CheckFileNameExtensionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CheckFileNameExtensionImpl.java
@@ -29,6 +29,9 @@ import org.apache.sshd.common.subsystem.sftp.SftpConstants;
 import org.apache.sshd.common.util.Pair;
 
 /**
+ * Implements &quot;check-file-name&quot; extension
+ *
+ * @see <A HREF="http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt">DRAFT 09 - section 9.1.2</A>
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class CheckFileNameExtensionImpl extends AbstractCheckFileExtension implements CheckFileNameExtension {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyDataExtensionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyDataExtensionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyDataExtensionImpl.java
index c56129f..85623b8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyDataExtensionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyDataExtensionImpl.java
@@ -31,6 +31,9 @@ import org.apache.sshd.common.util.NumberUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
+ * Implements the &quot;copy-data&quot; extension
+ *
+ * @see <A HREF="http://tools.ietf.org/id/draft-ietf-secsh-filexfer-extensions-00.txt">DRFAT 00 - section 7</A>
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class CopyDataExtensionImpl extends AbstractSftpClientExtension implements CopyDataExtension {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyFileExtensionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyFileExtensionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyFileExtensionImpl.java
index 5ce5f9a..63f79e5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyFileExtensionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyFileExtensionImpl.java
@@ -30,6 +30,9 @@ import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
+ * Implements the &quot;copy-file&quot; extension
+ *
+ * @see <A HREF="http://tools.ietf.org/id/draft-ietf-secsh-filexfer-extensions-00.txt">DRFAT 00 - section 6</A>
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class CopyFileExtensionImpl extends AbstractSftpClientExtension implements CopyFileExtension {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/MD5FileExtensionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/MD5FileExtensionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/MD5FileExtensionImpl.java
index ee27b4f..bc6149e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/MD5FileExtensionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/MD5FileExtensionImpl.java
@@ -28,6 +28,9 @@ import org.apache.sshd.client.subsystem.sftp.extensions.MD5FileExtension;
 import org.apache.sshd.common.subsystem.sftp.SftpConstants;
 
 /**
+ * Implements &quot;md5-hash&quot; extension
+ *
+ * @see <A HREF="http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt">DRAFT 09 - section 9.1.1</A>
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class MD5FileExtensionImpl extends AbstractMD5HashExtension implements MD5FileExtension {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/MD5HandleExtensionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/MD5HandleExtensionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/MD5HandleExtensionImpl.java
index 5a67abd..d71edd6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/MD5HandleExtensionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/MD5HandleExtensionImpl.java
@@ -28,6 +28,9 @@ import org.apache.sshd.client.subsystem.sftp.extensions.MD5HandleExtension;
 import org.apache.sshd.common.subsystem.sftp.SftpConstants;
 
 /**
+ * Implements &quot;md5-hash-handle&quot; extension
+ *
+ * @see <A HREF="http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt">DRAFT 09 - section 9.1.1</A>
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class MD5HandleExtensionImpl extends AbstractMD5HashExtension implements MD5HandleExtension {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImpl.java
index 4185366..6fc0745 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImpl.java
@@ -31,6 +31,9 @@ import org.apache.sshd.common.subsystem.sftp.extensions.SpaceAvailableExtensionI
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
+ * Implements &quot;space-available&quot; extension
+ *
+ * @see <A HREF="http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt">DRAFT 09 - section 9.3</A>
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class SpaceAvailableExtensionImpl extends AbstractSftpClientExtension implements SpaceAvailableExtension {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/common/file/virtualfs/VirtualFileSystemFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/file/virtualfs/VirtualFileSystemFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/file/virtualfs/VirtualFileSystemFactory.java
index 205d170..60921c8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/file/virtualfs/VirtualFileSystemFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/file/virtualfs/VirtualFileSystemFactory.java
@@ -37,7 +37,7 @@ import org.apache.sshd.common.util.ValidateUtils;
 public class VirtualFileSystemFactory implements FileSystemFactory {
 
     private Path defaultHomeDir;
-    private final Map<String, Path> homeDirs = new ConcurrentHashMap<String, Path>();
+    private final Map<String, Path> homeDirs = new ConcurrentHashMap<>();
 
     public VirtualFileSystemFactory() {
         super();
@@ -67,7 +67,7 @@ public class VirtualFileSystemFactory implements FileSystemFactory {
     @Override
     public FileSystem createFileSystem(Session session) throws IOException {
         String username = session.getUsername();
-        Path dir = computeRootDir(username);
+        Path dir = computeRootDir(session);
         if (dir == null) {
             throw new InvalidPathException(username, "Cannot resolve home directory");
         }
@@ -75,8 +75,9 @@ public class VirtualFileSystemFactory implements FileSystemFactory {
         return new RootedFileSystemProvider().newFileSystem(dir, Collections.<String, Object>emptyMap());
     }
 
-    protected Path computeRootDir(String userName) throws IOException  {
-        Path homeDir = getUserHomeDir(userName);
+    protected Path computeRootDir(Session session) throws IOException  {
+        String username = session.getUsername();
+        Path homeDir = getUserHomeDir(username);
         if (homeDir == null) {
             homeDir = getDefaultHomeDir();
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactoryFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactoryFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactoryFactory.java
index 374b3f4..47b40bb 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactoryFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactoryFactory.java
@@ -21,9 +21,9 @@ package org.apache.sshd.common.io;
 import org.apache.sshd.common.FactoryManager;
 
 /**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public interface IoServiceFactoryFactory {
 
     IoServiceFactory create(FactoryManager manager);
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java b/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java
index 188fd3f..e19c680 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java
@@ -87,7 +87,7 @@ public interface ServerAuthenticationManager {
      *      will be used as the banner contents.
      *      </LI></P>
      * </UL>
-     * @see <A HREF="https://www.ietf.org/rfc/rfc4252.txt">RFC-4252 section 5.4</A>
+     * @see <A HREF="https://tools.ietf.org/html/rfc4252#section-5.4">RFC-4252 section 5.4</A>
      */
     String WELCOME_BANNER = "welcome-banner";
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
index f8fcf39..b60fabd 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
@@ -601,7 +601,7 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
                 return new ProcessShellFactory(GenericUtils.split(command, ' ')).create();
             }
         }).build());
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
+        sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystemFactory()));
         sshd.start();
 
         Thread.sleep(Long.MAX_VALUE);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java b/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
index 97142f1..28d5436 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
@@ -444,7 +444,7 @@ public class ClientTest extends BaseTestSupport {
                 assertSame("Mismatched closed channel instances", channel, channelHolder.getAndSet(null));
             }
         });
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
+        sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystemFactory()));
 
         client.start();
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImplTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImplTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImplTest.java
index ef1cb61..e3f0c7f 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImplTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImplTest.java
@@ -24,7 +24,7 @@ import java.io.StreamCorruptedException;
 import java.nio.file.FileStore;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
@@ -68,7 +68,7 @@ public class SpaceAvailableExtensionImplTest extends AbstractSftpClientTestSuppo
         final SpaceAvailableExtensionInfo expected = new SpaceAvailableExtensionInfo(store);
 
         List<NamedFactory<Command>> factories = sshd.getSubsystemFactories();
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory() {
+        sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystemFactory() {
             @Override
             public Command create() {
                 return new SftpSubsystem(getExecutorService(), isShutdownOnExit(), getUnsupportedAttributePolicy()) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/openssh/helpers/OpenSSHExtensionsTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/openssh/helpers/OpenSSHExtensionsTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/openssh/helpers/OpenSSHExtensionsTest.java
index d69813e..375c846 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/openssh/helpers/OpenSSHExtensionsTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/openssh/helpers/OpenSSHExtensionsTest.java
@@ -27,7 +27,7 @@ import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
@@ -122,7 +122,7 @@ public class OpenSSHExtensionsTest extends AbstractSftpClientTestSupport {
         expected.f_fsid = 1L;
         expected.f_namemax = 256;
 
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory() {
+        sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystemFactory() {
             @Override
             public Command create() {
                 return new SftpSubsystem(getExecutorService(), isShutdownOnExit(), getUnsupportedAttributePolicy()) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-core/src/test/java/org/apache/sshd/server/subsystem/sftp/SshFsMounter.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/subsystem/sftp/SshFsMounter.java b/sshd-core/src/test/java/org/apache/sshd/server/subsystem/sftp/SshFsMounter.java
index 35cfece..4cc9472 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/subsystem/sftp/SshFsMounter.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/subsystem/sftp/SshFsMounter.java
@@ -25,7 +25,6 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -82,7 +81,7 @@ public final class SshFsMounter {
             int numComps = GenericUtils.length(comps);
             cmdName = GenericUtils.trimToEmpty(ValidateUtils.checkNotNullAndNotEmpty(comps[0], "No command name"));
             if (numComps > 1) {
-                args = new ArrayList<String>(numComps - 1);
+                args = new ArrayList<>(numComps - 1);
                 for (int index = 1; index < numComps; index++) {
                     String c = GenericUtils.trimToEmpty(comps[index]);
                     if (GenericUtils.isEmpty(c)) {
@@ -245,7 +244,7 @@ public final class SshFsMounter {
     public static void main(String[] args) throws Exception {
         int port = SshConfigFileReader.DEFAULT_PORT;
         boolean error = false;
-        Map<String, String> options = new LinkedHashMap<String, String>();
+        Map<String, String> options = new LinkedHashMap<>();
 
         int numArgs = GenericUtils.length(args);
         for (int i = 0; i < numArgs; i++) {
@@ -320,7 +319,7 @@ public final class SshFsMounter {
         sshd.setPasswordAuthenticator(AcceptAllPasswordAuthenticator.INSTANCE);
         sshd.setTcpipForwardingFilter(AcceptAllForwardingFilter.INSTANCE);
         sshd.setCommandFactory(new ScpCommandFactory.Builder().withDelegate(MounterCommandFactory.INSTANCE).build());
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
+        sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystemFactory()));
         sshd.start();
 
         Thread.sleep(Long.MAX_VALUE);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java b/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
index be818b7..bc26a9c 100644
--- a/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
+++ b/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
@@ -20,7 +20,7 @@ package org.apache.sshd.git.pack;
 
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.Arrays;
+import java.util.Collections;
 
 import com.jcraft.jsch.JSch;
 
@@ -73,7 +73,7 @@ public class GitPackCommandTest extends BaseTestSupport {
 
         try (SshServer sshd = setupTestServer()) {
             Path serverRootDir = gitRootDir.resolve("server");
-            sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
+            sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystemFactory()));
             sshd.setCommandFactory(new GitPackCommandFactory(Utils.resolveRelativeRemotePath(targetParent, serverRootDir)));
             sshd.start();
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c334fd65/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java b/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
index 77c14db..1898a47 100644
--- a/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
+++ b/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
@@ -20,8 +20,8 @@ package org.apache.sshd.git.pgm;
 
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.EnumSet;
 import java.util.concurrent.TimeUnit;
 
@@ -60,7 +60,7 @@ public class GitPgmCommandTest extends BaseTestSupport {
         //
 
         try (SshServer sshd = setupTestServer()) {
-            sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
+            sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystemFactory()));
             sshd.setCommandFactory(new GitPgmCommandFactory(Utils.resolveRelativeRemotePath(targetParent, serverDir)));
             sshd.start();
 


[3/5] mina-sshd git commit: Make all SSHD listeners extend SshdEventListener

Posted by lg...@apache.org.
Make all SSHD listeners extend SshdEventListener


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/3453416a
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/3453416a
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/3453416a

Branch: refs/heads/master
Commit: 3453416a133f6ed85b0492fcb29a8bc5a826ea7c
Parents: c42798c
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Thu Sep 15 19:02:05 2016 +0300
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Thu Sep 15 19:02:05 2016 +0300

----------------------------------------------------------------------
 .../sshd/common/channel/ChannelListener.java    |  4 +--
 .../forward/PortForwardingEventListener.java    |  4 +--
 .../sshd/common/future/SshFutureListener.java   |  4 +--
 .../common/scp/ScpTransferEventListener.java    |  5 ++--
 .../session/ReservedSessionMessagesHandler.java |  3 +-
 .../sshd/common/session/SessionListener.java    |  4 +--
 .../sshd/common/util/SshdEventListener.java     | 29 ++++++++++++++++++++
 .../org/apache/sshd/server/SignalListener.java  |  4 +--
 .../subsystem/sftp/SftpEventListener.java       |  4 +--
 .../common/util/EventListenerUtilsTest.java     |  2 +-
 10 files changed, 47 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3453416a/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelListener.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelListener.java
index 20eb29d..0124fca 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelListener.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelListener.java
@@ -19,7 +19,7 @@
 
 package org.apache.sshd.common.channel;
 
-import java.util.EventListener;
+import org.apache.sshd.common.util.SshdEventListener;
 
 /**
  * Provides a simple listener for client / server channels being established
@@ -29,7 +29,7 @@ import java.util.EventListener;
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public interface ChannelListener extends EventListener {
+public interface ChannelListener extends SshdEventListener {
     ChannelListener EMPTY = new ChannelListener() {
         @Override
         public String toString() {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3453416a/sshd-core/src/main/java/org/apache/sshd/common/forward/PortForwardingEventListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/PortForwardingEventListener.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/PortForwardingEventListener.java
index 25211bb..857fbfe 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/forward/PortForwardingEventListener.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/PortForwardingEventListener.java
@@ -20,15 +20,15 @@
 package org.apache.sshd.common.forward;
 
 import java.io.IOException;
-import java.util.EventListener;
 
 import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.util.SshdEventListener;
 import org.apache.sshd.common.util.net.SshdSocketAddress;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public interface PortForwardingEventListener extends EventListener {
+public interface PortForwardingEventListener extends SshdEventListener {
     PortForwardingEventListener EMPTY = new PortForwardingEventListener() {
         @Override
         public String toString() {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3453416a/sshd-core/src/main/java/org/apache/sshd/common/future/SshFutureListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/future/SshFutureListener.java b/sshd-core/src/main/java/org/apache/sshd/common/future/SshFutureListener.java
index 2fadaf7..a005c0f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/future/SshFutureListener.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/future/SshFutureListener.java
@@ -18,7 +18,7 @@
  */
 package org.apache.sshd.common.future;
 
-import java.util.EventListener;
+import org.apache.sshd.common.util.SshdEventListener;
 
 /**
  * Something interested in being notified when the completion
@@ -29,7 +29,7 @@ import java.util.EventListener;
  */
 @SuppressWarnings("rawtypes")
 @FunctionalInterface
-public interface SshFutureListener<T extends SshFuture> extends EventListener {
+public interface SshFutureListener<T extends SshFuture> extends SshdEventListener {
 
     /**
      * Invoked when the operation associated with the {@link SshFuture}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3453416a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpTransferEventListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpTransferEventListener.java b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpTransferEventListener.java
index 95380cd..2e99576 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpTransferEventListener.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpTransferEventListener.java
@@ -22,15 +22,16 @@ package org.apache.sshd.common.scp;
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.attribute.PosixFilePermission;
-import java.util.EventListener;
 import java.util.Set;
 
+import org.apache.sshd.common.util.SshdEventListener;
+
 /**
  * Can be registered in order to receive events about SCP transfers
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public interface ScpTransferEventListener extends EventListener {
+public interface ScpTransferEventListener extends SshdEventListener {
     enum FileOperation {
         SEND,
         RECEIVE

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3453416a/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
index 838b929..6c525f7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
@@ -19,6 +19,7 @@
 
 package org.apache.sshd.common.session;
 
+import org.apache.sshd.common.util.SshdEventListener;
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
@@ -27,7 +28,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public interface ReservedSessionMessagesHandler {
+public interface ReservedSessionMessagesHandler extends SshdEventListener {
     /**
      * Invoked when an {@code SSH_MSG_IGNORE} packet is received
      *

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3453416a/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java b/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java
index e4267dc..8466ee7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java
@@ -18,17 +18,17 @@
  */
 package org.apache.sshd.common.session;
 
-import java.util.EventListener;
 import java.util.Map;
 
 import org.apache.sshd.common.kex.KexProposalOption;
+import org.apache.sshd.common.util.SshdEventListener;
 
 /**
  * Represents an interface receiving session events.
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public interface SessionListener extends EventListener {
+public interface SessionListener extends SshdEventListener {
     enum Event {
         KeyEstablished, Authenticated, KexCompleted
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3453416a/sshd-core/src/main/java/org/apache/sshd/common/util/SshdEventListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/SshdEventListener.java b/sshd-core/src/main/java/org/apache/sshd/common/util/SshdEventListener.java
new file mode 100644
index 0000000..16dfc9f
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/SshdEventListener.java
@@ -0,0 +1,29 @@
+/*
+ * 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.util;
+
+import java.util.EventListener;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface SshdEventListener extends EventListener {
+    // marker interface for quickly locating our session listeners
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3453416a/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java b/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java
index f16dbfd..bdb6370 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java
@@ -18,12 +18,12 @@
  */
 package org.apache.sshd.server;
 
-import java.util.EventListener;
+import org.apache.sshd.common.util.SshdEventListener;
 
 /**
  * Define a listener to receive signals
  */
-public interface SignalListener extends EventListener {
+public interface SignalListener extends SshdEventListener {
 
     /**
      * @param signal The received {@link Signal}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3453416a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpEventListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpEventListener.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpEventListener.java
index 60a0d1f..f5736c9 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpEventListener.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpEventListener.java
@@ -23,9 +23,9 @@ import java.io.IOException;
 import java.nio.file.CopyOption;
 import java.nio.file.Path;
 import java.util.Collection;
-import java.util.EventListener;
 import java.util.Map;
 
+import org.apache.sshd.common.util.SshdEventListener;
 import org.apache.sshd.server.session.ServerSession;
 
 /**
@@ -35,7 +35,7 @@ import org.apache.sshd.server.session.ServerSession;
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public interface SftpEventListener extends EventListener {
+public interface SftpEventListener extends SshdEventListener {
     /**
      * Called when the SFTP protocol has been initialized
      *

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3453416a/sshd-core/src/test/java/org/apache/sshd/common/util/EventListenerUtilsTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/util/EventListenerUtilsTest.java b/sshd-core/src/test/java/org/apache/sshd/common/util/EventListenerUtilsTest.java
index 03d8d20..7b22fbe 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/util/EventListenerUtilsTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/util/EventListenerUtilsTest.java
@@ -111,7 +111,7 @@ public class EventListenerUtilsTest extends BaseTestSupport {
         assertEquals("Mismatched post p2-remove size", 0, s.size());
     }
 
-    interface ProxyListener extends EventListener {
+    interface ProxyListener extends SshdEventListener {
         void callMeWithString(String s);
 
         void callMeWithNumber(Number n);


[2/5] mina-sshd git commit: [SSHD-694] Ignore README.md file when scanning for license header

Posted by lg...@apache.org.
[SSHD-694] Ignore README.md file when scanning for license header


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/c42798cd
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/c42798cd
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/c42798cd

Branch: refs/heads/master
Commit: c42798cdc6ce75133c8851d78d176aacb9e8e80b
Parents: 6a9bb2b
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Thu Sep 15 19:00:46 2016 +0300
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Thu Sep 15 19:00:46 2016 +0300

----------------------------------------------------------------------
 pom.xml | 217 ++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 109 insertions(+), 108 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/c42798cd/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 759bc70..067142a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -402,50 +402,51 @@
                         </lifecycleMappingMetadata>
                     </configuration>
                 </plugin>
-				<plugin>
-					<groupId>org.apache.rat</groupId>
-					<artifactId>apache-rat-plugin</artifactId>
-					<version>0.11</version>
-					<configuration>
-						<excludes>
-							<exclude>**/*.iml</exclude>
-							<exclude>src/docs/**</exclude>
-							<exclude>src/test/resources/**</exclude>
-							<exclude>**/stty-output-*.txt</exclude>
+                <plugin>
+                    <groupId>org.apache.rat</groupId>
+                    <artifactId>apache-rat-plugin</artifactId>
+                    <version>0.11</version>
+                    <configuration>
+                        <excludes>
+                            <exclude>**/*.iml</exclude>
+                            <exclude>README.md</exclude>
+                            <exclude>src/docs/**</exclude>
+                            <exclude>src/test/resources/**</exclude>
+                            <exclude>**/stty-output-*.txt</exclude>
                             <exclude>*checkstyle*</exclude>
-							<exclude>**/big-msg.txt</exclude>
-								<!-- Eclipse files -->
-							<exclude>.metadata/**</exclude>
-							<exclude>.recommenders/**</exclude>
-							<exclude>RemoteSystemsTempFiles/**</exclude>
-							<exclude>.project</exclude>
-							<exclude>.classpath</exclude>
-							<exclude>.springBeans</exclude>
-							<exclude>.settings/**</exclude>
-						</excludes>
-					</configuration>
-				</plugin>
-				<plugin>
-					<groupId>org.codehaus.mojo</groupId>
-					<artifactId>animal-sniffer-maven-plugin</artifactId>
-					<version>1.15</version>
-					<configuration>
-						<signature>
-							<groupId>org.codehaus.mojo.signature</groupId>
-							<artifactId>java${java.major.version}${java.minor.version}</artifactId>
-							<version>${sniffer.signatures.version}</version>
-						</signature>
-					</configuration>
-						<!-- make sure the signatures artifact is downloaded -->
-					<dependencies>
-						<dependency>
-							<groupId>org.codehaus.mojo.signature</groupId>
-							<artifactId>java${java.major.version}${java.minor.version}</artifactId>
-							<version>${sniffer.signatures.version}</version>
-							<type>pom</type>
-						</dependency>
-					</dependencies>
-				</plugin>
+                            <exclude>**/big-msg.txt</exclude>
+                                <!-- Eclipse files -->
+                            <exclude>.metadata/**</exclude>
+                            <exclude>.recommenders/**</exclude>
+                            <exclude>RemoteSystemsTempFiles/**</exclude>
+                            <exclude>.project</exclude>
+                            <exclude>.classpath</exclude>
+                            <exclude>.springBeans</exclude>
+                            <exclude>.settings/**</exclude>
+                        </excludes>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.codehaus.mojo</groupId>
+                    <artifactId>animal-sniffer-maven-plugin</artifactId>
+                    <version>1.15</version>
+                    <configuration>
+                        <signature>
+                            <groupId>org.codehaus.mojo.signature</groupId>
+                            <artifactId>java${java.major.version}${java.minor.version}</artifactId>
+                            <version>${sniffer.signatures.version}</version>
+                        </signature>
+                    </configuration>
+                        <!-- make sure the signatures artifact is downloaded -->
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.codehaus.mojo.signature</groupId>
+                            <artifactId>java${java.major.version}${java.minor.version}</artifactId>
+                            <version>${sniffer.signatures.version}</version>
+                            <type>pom</type>
+                        </dependency>
+                    </dependencies>
+                </plugin>
                 <plugin>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-release-plugin</artifactId>
@@ -474,74 +475,74 @@
                     <artifactId>maven-javadoc-plugin</artifactId>
                     <version>2.10.3</version>
                 </plugin>
-			    <plugin>
-				    <groupId>org.codehaus.gmaven</groupId>
-				    <artifactId>groovy-maven-plugin</artifactId>
-				    <version>${gmaven.plugin.version}</version>
-				    <dependencies>
-					    <dependency>
-						    <groupId>org.codehaus.groovy</groupId>
-						    <artifactId>groovy-all</artifactId>
-						    <version>${groovy.version}</version>
-					    </dependency>
-					      <!-- referenced indirectly by groovy-all -->
-					    <dependency>
-						    <groupId>org.apache.ant</groupId>
-						    <artifactId>ant</artifactId>
-						    <version>${ant.version}</version>
-					    </dependency>
-					    <dependency>
-						    <groupId>org.apache.ant</groupId>
-						    <artifactId>ant-launcher</artifactId>
-						    <version>${ant.version}</version>
-					    </dependency>
-					    <dependency>    <!-- replace ant-junit artifact -->
-						    <groupId>org.apache.ant</groupId>
-						    <artifactId>ant-junit4</artifactId>
-						    <version>${ant.version}</version>
-					    </dependency>
-					    <dependency>
-						    <groupId>junit</groupId>
-						    <artifactId>junit</artifactId>
-						    <version>${junit.version}</version>
-					    </dependency>
-				    </dependencies>
-				</plugin>                
-				<plugin>
-					<groupId>org.apache.maven.plugins</groupId>
-					<artifactId>maven-checkstyle-plugin</artifactId>
-					<version>2.17</version>
-					<configuration>
-						<logViolationsToConsole>true</logViolationsToConsole>
+                <plugin>
+                    <groupId>org.codehaus.gmaven</groupId>
+                    <artifactId>groovy-maven-plugin</artifactId>
+                    <version>${gmaven.plugin.version}</version>
+                    <dependencies>
+                        <dependency>
+                            <groupId>org.codehaus.groovy</groupId>
+                            <artifactId>groovy-all</artifactId>
+                            <version>${groovy.version}</version>
+                        </dependency>
+                          <!-- referenced indirectly by groovy-all -->
+                        <dependency>
+                            <groupId>org.apache.ant</groupId>
+                            <artifactId>ant</artifactId>
+                            <version>${ant.version}</version>
+                        </dependency>
+                        <dependency>
+                            <groupId>org.apache.ant</groupId>
+                            <artifactId>ant-launcher</artifactId>
+                            <version>${ant.version}</version>
+                        </dependency>
+                        <dependency>    <!-- replace ant-junit artifact -->
+                            <groupId>org.apache.ant</groupId>
+                            <artifactId>ant-junit4</artifactId>
+                            <version>${ant.version}</version>
+                        </dependency>
+                        <dependency>
+                            <groupId>junit</groupId>
+                            <artifactId>junit</artifactId>
+                            <version>${junit.version}</version>
+                        </dependency>
+                    </dependencies>
+                </plugin>                
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-checkstyle-plugin</artifactId>
+                    <version>2.17</version>
+                    <configuration>
+                        <logViolationsToConsole>true</logViolationsToConsole>
                         <includeTestSourceDirectory>true</includeTestSourceDirectory>
-						<resourceExcludes>**/*.properties</resourceExcludes>
-					</configuration>
-					<dependencies>
-							<!-- see http://checkstyle.sourceforge.net/ for latest version -->
-						<dependency>
-							<groupId>com.puppycrawl.tools</groupId>
-							<artifactId>checkstyle</artifactId>
-							<version>7.0</version>
-							<exclusions>
-								<!-- MCHECKSTYLE-156 -->
-								<exclusion>
-									<groupId>com.sun</groupId>
-									<artifactId>tools</artifactId>
-								</exclusion>
-							</exclusions>
-						</dependency>
-					</dependencies>
-				</plugin>
+                        <resourceExcludes>**/*.properties</resourceExcludes>
+                    </configuration>
+                    <dependencies>
+                            <!-- see http://checkstyle.sourceforge.net/ for latest version -->
+                        <dependency>
+                            <groupId>com.puppycrawl.tools</groupId>
+                            <artifactId>checkstyle</artifactId>
+                            <version>7.0</version>
+                            <exclusions>
+                                <!-- MCHECKSTYLE-156 -->
+                                <exclusion>
+                                    <groupId>com.sun</groupId>
+                                    <artifactId>tools</artifactId>
+                                </exclusion>
+                            </exclusions>
+                        </dependency>
+                    </dependencies>
+                </plugin>
             </plugins>
         </pluginManagement>
 
         <plugins>
             <plugin>
-			    <groupId>org.codehaus.gmaven</groupId>
-			    <artifactId>groovy-maven-plugin</artifactId>
+                <groupId>org.codehaus.gmaven</groupId>
+                <artifactId>groovy-maven-plugin</artifactId>
                 <executions>
                     <!-- Works only for Maven 3.x -->
-					<execution>
+                    <execution>
                         <id>detect-workspace-root-dir</id>
                         <!-- NOTE: phase must be BEFORE checkstyle plugin one -->
                         <phase>validate</phase>
@@ -550,7 +551,7 @@
                         </goals>
                         <configuration>
                             <source>
-							    <![CDATA[
+                                <![CDATA[
                                     for (java.io.File file = new java.io.File(new java.net.URI('${project.baseUri}')); file != null; file = file.getParentFile()) {
                                         if (!file.isDirectory()) {
                                             continue
@@ -564,8 +565,8 @@
                                         }
                                     }
                                     
-                                    System.err.println("Failed to detected Insight root dir")
-							    ]]>
+                                    System.err.println("Failed to detect workspace root dir")
+                                ]]>
                             </source>
                         </configuration>
                     </execution>
@@ -633,7 +634,7 @@
                     <source>${javac.source}</source>
                     <target>${javac.target}</target>
                     <compilerArgument>-g</compilerArgument>
-						<!-- see http://www.javaworld.com/article/2073587/javac-s(dashdash)xlint-options.html -->
+                        <!-- see http://www.javaworld.com/article/2073587/javac-s(dashdash)xlint-options.html -->
                     <compilerArgument>-Xlint:-serial</compilerArgument>
                     <compilerArgument>-Xlint:unchecked</compilerArgument>
                 </configuration>
@@ -646,7 +647,7 @@
                     <execution>
                         <id>install</id>
                         <phase>install</phase>
-                        <goals>	<!-- automatically download the dependency sources - useful for debugging -->
+                        <goals>    <!-- automatically download the dependency sources - useful for debugging -->
                             <goal>sources</goal>
                         </goals>
                         <configuration>


[5/5] mina-sshd git commit: Provide ClientSession instance in SftpVersionSelector invocation

Posted by lg...@apache.org.
Provide ClientSession instance in SftpVersionSelector invocation


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/f1df8a2c
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/f1df8a2c
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/f1df8a2c

Branch: refs/heads/master
Commit: f1df8a2c76a52e4cb7a379e462f4ed2d067a9ddf
Parents: c334fd6
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Thu Sep 15 19:03:52 2016 +0300
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Thu Sep 15 19:03:52 2016 +0300

----------------------------------------------------------------------
 .../subsystem/sftp/DefaultSftpClient.java       |  2 +-
 .../subsystem/sftp/SftpFileSystemProvider.java  | 13 +++++++--
 .../subsystem/sftp/SftpVersionSelector.java     | 30 ++++++++++++++++----
 .../client/simple/SimpleSftpClientTest.java     |  4 +--
 .../subsystem/sftp/SftpFileSystemTest.java      |  5 ++--
 .../sshd/client/subsystem/sftp/SftpTest.java    |  2 +-
 .../subsystem/sftp/SftpVersionSelectorTest.java | 17 +++++++----
 7 files changed, 52 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1df8a2c/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
index 103773f..8b715a1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
@@ -425,7 +425,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
             }
         }
 
-        int selected = selector.selectVersion(current, new ArrayList<>(available));
+        int selected = selector.selectVersion(getClientSession(), current, new ArrayList<>(available));
         if (log.isDebugEnabled()) {
             log.debug("negotiateVersion({}) current={} {} -> {}", getClientChannel(), current, available, selected);
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1df8a2c/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
index a59d972..bfc8100 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
@@ -87,6 +87,13 @@ import org.apache.sshd.common.util.io.IoUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+/**
+ * A registered {@link FileSystemProvider} that registers the &quot;sftp://&quot;
+ * scheme so that URLs with this protocol are handled as remote SFTP {@link Path}-s
+ * - e.g., &quot;{@code sftp://user:password@host/remote/file/path}&quot;
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
 public class SftpFileSystemProvider extends FileSystemProvider {
     public static final String READ_BUFFER_PROP_NAME = "sftp-fs-read-buffer-size";
     public static final int DEFAULT_READ_BUFFER_SIZE = SftpClient.DEFAULT_READ_BUFFER_SIZE;
@@ -124,7 +131,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
 
     private final SshClient client;
     private final SftpVersionSelector selector;
-    private final Map<String, SftpFileSystem> fileSystems = new HashMap<String, SftpFileSystem>();
+    private final Map<String, SftpFileSystem> fileSystems = new HashMap<>();
 
     public SftpFileSystemProvider() {
         this((SshClient) null);
@@ -282,7 +289,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
             return Collections.unmodifiableMap(env);
         }
 
-        Map<String, Object> resolved = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
+        Map<String, Object> resolved = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
         resolved.putAll(env);
         resolved.putAll(uriParams);
         return resolved;
@@ -305,7 +312,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
         }
 
         String[] pairs = GenericUtils.split(params, '&');
-        Map<String, Object> map = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
+        Map<String, Object> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
         for (String p : pairs) {
             int pos = p.indexOf('=');
             if (pos < 0) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1df8a2c/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
index ccdf3ce..c5fdaf0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
@@ -22,6 +22,7 @@ package org.apache.sshd.client.subsystem.sftp;
 import java.util.Collection;
 import java.util.List;
 
+import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.NumberUtils;
 import org.apache.sshd.common.util.ValidateUtils;
@@ -29,6 +30,7 @@ import org.apache.sshd.common.util.ValidateUtils;
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
+@FunctionalInterface
 public interface SftpVersionSelector {
 
     /**
@@ -36,9 +38,14 @@ public interface SftpVersionSelector {
      */
     SftpVersionSelector CURRENT = new SftpVersionSelector() {
         @Override
-        public int selectVersion(int current, List<Integer> available) {
+        public int selectVersion(ClientSession session, int current, List<Integer> available) {
             return current;
         }
+
+        @Override
+        public String toString() {
+            return "CURRENT";
+        }
     };
 
     /**
@@ -46,7 +53,7 @@ public interface SftpVersionSelector {
      */
     SftpVersionSelector MAXIMUM = new SftpVersionSelector() {
         @Override
-        public int selectVersion(int current, List<Integer> available) {
+        public int selectVersion(ClientSession session, int current, List<Integer> available) {
             int candidate = current;
             if (GenericUtils.size(available) > 0) {
                 for (Number version : available) {
@@ -57,6 +64,11 @@ public interface SftpVersionSelector {
             }
             return candidate;
         }
+
+        @Override
+        public String toString() {
+            return "MAXIMUM";
+        }
     };
 
     /**
@@ -64,7 +76,7 @@ public interface SftpVersionSelector {
      */
     SftpVersionSelector MINIMUM = new SftpVersionSelector() {
         @Override
-        public int selectVersion(int current, List<Integer> available) {
+        public int selectVersion(ClientSession session, int current, List<Integer> available) {
             int candidate = current;
             if (GenericUtils.size(available) > 0) {
                 for (Number version : available) {
@@ -75,15 +87,21 @@ public interface SftpVersionSelector {
             }
             return candidate;
         }
+
+        @Override
+        public String toString() {
+            return "MINIMUM";
+        }
     };
 
     /**
+     * @param session   The {@link ClientSession} through which the SFTP connection is made
      * @param current   The current version negotiated with the server
      * @param available Extra versions available - may be empty and/or contain
      *                  only the current one
      * @return The new requested version - if same as current, then nothing is done
      */
-    int selectVersion(int current, List<Integer> available);
+    int selectVersion(ClientSession session, int current, List<Integer> available);
 
     /**
      * Utility class to help using {@link SftpVersionSelector}s
@@ -108,7 +126,7 @@ public interface SftpVersionSelector {
         public static SftpVersionSelector fixedVersionSelector(final int version) {
             return new SftpVersionSelector() {
                 @Override
-                public int selectVersion(int current, List<Integer> available) {
+                public int selectVersion(ClientSession session, int current, List<Integer> available) {
                     return version;
                 }
             };
@@ -148,7 +166,7 @@ public interface SftpVersionSelector {
 
             return new SftpVersionSelector() {
                 @Override
-                public int selectVersion(int current, List<Integer> available) {
+                public int selectVersion(ClientSession session, int current, List<Integer> available) {
                     for (Number prefValue : preferred) {
                         int version = prefValue.intValue();
                         if (version == current) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1df8a2c/sshd-core/src/test/java/org/apache/sshd/client/simple/SimpleSftpClientTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/simple/SimpleSftpClientTest.java b/sshd-core/src/test/java/org/apache/sshd/client/simple/SimpleSftpClientTest.java
index aed7641..bde1cc2 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/simple/SimpleSftpClientTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/simple/SimpleSftpClientTest.java
@@ -23,7 +23,7 @@ import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.EnumSet;
 
 import org.apache.sshd.client.subsystem.sftp.SftpClient;
@@ -59,7 +59,7 @@ public class SimpleSftpClientTest extends BaseSimpleClientTestSupport {
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
+        sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystemFactory()));
         sshd.setCommandFactory(new ScpCommandFactory());
         sshd.setFileSystemFactory(fileSystemFactory);
         client.start();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1df8a2c/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
index e3ee7ec..b673821 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
@@ -42,7 +42,6 @@ import java.nio.file.attribute.GroupPrincipal;
 import java.nio.file.attribute.PosixFilePermissions;
 import java.nio.file.attribute.UserPrincipalLookupService;
 import java.nio.file.attribute.UserPrincipalNotFoundException;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -94,7 +93,7 @@ public class SftpFileSystemTest extends BaseTestSupport {
     @BeforeClass
     public static void setupServerInstance() throws Exception {
         sshd = Utils.setupTestServer(SftpFileSystemTest.class);
-        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
+        sshd.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(new SftpSubsystemFactory()));
         sshd.setCommandFactory(new ScpCommandFactory());
         sshd.start();
         port = sshd.getPort();
@@ -297,7 +296,7 @@ public class SftpFileSystemTest extends BaseTestSupport {
         final AtomicInteger selected = new AtomicInteger(-1);
         SftpVersionSelector selector = new SftpVersionSelector() {
             @Override
-            public int selectVersion(int current, List<Integer> available) {
+            public int selectVersion(ClientSession session, int current, List<Integer> available) {
                 int numAvailable = GenericUtils.size(available);
                 Integer maxValue = null;
                 if (numAvailable == 1) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1df8a2c/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
index 983addf..996036a 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
@@ -1036,7 +1036,7 @@ public class SftpTest extends AbstractSftpClientTestSupport {
         final AtomicInteger selected = new AtomicInteger(-1);
         SftpVersionSelector selector = new SftpVersionSelector() {
             @Override
-            public int selectVersion(int current, List<Integer> available) {
+            public int selectVersion(ClientSession session, int current, List<Integer> available) {
                 int numAvailable = GenericUtils.size(available);
                 Integer maxValue = null;
                 if (numAvailable == 1) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f1df8a2c/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelectorTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelectorTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelectorTest.java
index ed2b3e9..ba0d456 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelectorTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelectorTest.java
@@ -25,11 +25,13 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Random;
 
+import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.server.subsystem.sftp.SftpSubsystem;
 import org.apache.sshd.util.test.BaseTestSupport;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
+import org.mockito.Mockito;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -44,8 +46,10 @@ public class SftpVersionSelectorTest extends BaseTestSupport {
     public void testCurrentVersionSelector() {
         List<Integer> available = new ArrayList<>();
         Random rnd = new Random(System.nanoTime());
+        ClientSession session = Mockito.mock(ClientSession.class);
         for (int expected = SftpSubsystem.LOWER_SFTP_IMPL; expected <= SftpSubsystem.HIGHER_SFTP_IMPL; expected++) {
-            assertEquals("Mismatched directly selected for available=" + available, expected, SftpVersionSelector.CURRENT.selectVersion(expected, available));
+            assertEquals("Mismatched directly selected for available=" + available,
+                    expected, SftpVersionSelector.CURRENT.selectVersion(session, expected, available));
             available.add(Integer.valueOf(expected));
         }
 
@@ -53,7 +57,7 @@ public class SftpVersionSelectorTest extends BaseTestSupport {
             for (int index = 0; index < available.size(); index++) {
                 Collections.shuffle(available, rnd);
                 assertEquals("Mismatched suffling selected for current=" + expected + ", available=" + available,
-                        expected, SftpVersionSelector.CURRENT.selectVersion(expected, available));
+                        expected, SftpVersionSelector.CURRENT.selectVersion(session, expected, available));
             }
         }
     }
@@ -74,6 +78,7 @@ public class SftpVersionSelectorTest extends BaseTestSupport {
         List<Integer> preferred = new ArrayList<>(available);
         List<Integer> unavailable = Arrays.asList(7365, 3777347);
         Random rnd = new Random(System.nanoTime());
+        ClientSession session = Mockito.mock(ClientSession.class);
         for (int index = 0; index < preferred.size(); index++) {
             Collections.shuffle(preferred, rnd);
             SftpVersionSelector selector = SftpVersionSelector.Utils.preferredVersionSelector(preferred);
@@ -81,12 +86,12 @@ public class SftpVersionSelectorTest extends BaseTestSupport {
 
             for (int current = SftpSubsystem.LOWER_SFTP_IMPL; current <= SftpSubsystem.HIGHER_SFTP_IMPL; current++) {
                 assertEquals("Mismatched selected for current= " + current + ", available=" + available + ", preferred=" + preferred,
-                             expected, selector.selectVersion(current, available));
+                             expected, selector.selectVersion(session, current, available));
 
                 try {
                     Collections.shuffle(unavailable, rnd);
                     int version = unavailable.get(0);
-                    int actual = selector.selectVersion(version, unavailable);
+                    int actual = selector.selectVersion(session, version, unavailable);
                     fail("Unexpected selected version (" + actual + ")"
                             + " for current= " + version
                             + ", available=" + unavailable
@@ -115,9 +120,11 @@ public class SftpVersionSelectorTest extends BaseTestSupport {
         }
 
         Random rnd = new Random(System.nanoTime());
+        ClientSession session = Mockito.mock(ClientSession.class);
         for (int current = SftpSubsystem.LOWER_SFTP_IMPL; current <= SftpSubsystem.HIGHER_SFTP_IMPL; current++) {
             for (int index = 0; index < available.size(); index++) {
-                assertEquals("Mismatched selection for current=" + current + ", availble=" + available, expected, selector.selectVersion(current, available));
+                assertEquals("Mismatched selection for current=" + current + ", availble=" + available,
+                        expected, selector.selectVersion(session, current, available));
                 Collections.shuffle(available, rnd);
             }
         }