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 2018/04/25 05:58:24 UTC

mina-sshd git commit: [SSHD-820] Add provision to override default shell factory in SSH server

Repository: mina-sshd
Updated Branches:
  refs/heads/master af415e5fe -> cda53d6f9


[SSHD-820] Add provision to override default shell factory in SSH server


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

Branch: refs/heads/master
Commit: cda53d6f93f51b5744f82311fc9f88bd94cc2c45
Parents: af415e5
Author: Goldstein Lyor <ly...@c-b4.com>
Authored: Wed Apr 25 08:58:00 2018 +0300
Committer: Goldstein Lyor <ly...@c-b4.com>
Committed: Wed Apr 25 08:58:18 2018 +0300

----------------------------------------------------------------------
 README.md                                       |  4 ++
 .../apache/sshd/cli/client/ScpCommandMain.java  |  2 +-
 .../sshd/cli/client/SshClientCliSupport.java    |  6 +-
 .../sshd/cli/server/SshServerCliSupport.java    | 58 +++++++++++++++-----
 .../apache/sshd/cli/server/SshServerMain.java   | 54 +++++++++---------
 .../apache/sshd/cli/server/SshFsMounter.java    | 25 +++++----
 .../sshd/server/shell/ProcessShellFactory.java  |  2 +-
 .../apache/sshd/server/shell/ShellFactory.java  | 32 +++++++++++
 .../sshd/util/test/AsyncEchoShellFactory.java   |  4 +-
 .../apache/sshd/util/test/EchoShellFactory.java |  4 +-
 10 files changed, 132 insertions(+), 59 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cda53d6f/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 5a1e249..cb04e3f 100644
--- a/README.md
+++ b/README.md
@@ -1417,6 +1417,10 @@ be according to their order in the specified list.
 the `ServiceLoader` mechanism. The special value `none` may be used to indicate that no subsystem is to be configured. **Note:** no specific order is
 provided when subsystems are auto-detected and/or filtered.
 
+* **Shell** - unless otherwise instructed, the default SSH server uses an internal shell (see `InteractiveProcessShellFactory`). The shell can be overridden
+or disabled by specifying a `-o ShellFactory=XXX` option where the value can either be `none` to specify that no shell is to be used, or the fully-qualified
+name of a class that implements the `ShellFactory` interface. The implementation must be public and have a public no-args constructor for instantiating it.
+
 ## GIT support
 
 The _sshd-git_ artifact contains both client and server-side command factories for issuing and handling some _git_ commands. The code is based on [JGit](https://github.com/eclipse/jgit)

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cda53d6f/sshd-cli/src/main/java/org/apache/sshd/cli/client/ScpCommandMain.java
----------------------------------------------------------------------
diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/client/ScpCommandMain.java b/sshd-cli/src/main/java/org/apache/sshd/cli/client/ScpCommandMain.java
index 3f233ef..3421cca 100644
--- a/sshd-cli/src/main/java/org/apache/sshd/cli/client/ScpCommandMain.java
+++ b/sshd-cli/src/main/java/org/apache/sshd/cli/client/ScpCommandMain.java
@@ -71,7 +71,7 @@ public class ScpCommandMain extends SshClientCliSupport {
         for (int index = 0; (index < numArgs) && (!error); index++) {
             String argName = args[index];
             // handled by 'setupClientSession'
-            if (isArgumentedOption(SCP_PORT_OPTION, argName)) {
+            if (isArgumentedOption(SCP_PORT_OPTION, argName) || "-creator".equals(argName)) {
                 index++;
                 if (index >= numArgs) {
                     error = showError(stderr, "option requires an argument: " + argName);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cda53d6f/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java
----------------------------------------------------------------------
diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java b/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java
index 5278ba9..5cf4fd3 100644
--- a/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java
+++ b/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java
@@ -93,6 +93,7 @@ public abstract class SshClientCliSupport extends CliSupport {
 
     public static boolean isArgumentedOption(String portOption, String argName) {
         return portOption.equals(argName)
+             || "-io".equals(argName)
              || "-i".equals(argName)
              || "-o".equals(argName)
              || "-l".equals(argName)
@@ -121,12 +122,13 @@ public abstract class SshClientCliSupport extends CliSupport {
             String argName = args[i];
             String argVal = null;
             if (isArgumentedOption(portOption, argName)) {
-                if ((i + 1) >= numArgs) {
+                i++;
+                if (i >= numArgs) {
                     error = showError(stderr, "option requires an argument: " + argName);
                     break;
                 }
 
-                argVal = args[++i];
+                argVal = args[i];
             }
 
             if (portOption.equals(argName)) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cda53d6f/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java
----------------------------------------------------------------------
diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java
index 585f4a9..910566f 100644
--- a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java
+++ b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerCliSupport.java
@@ -19,8 +19,8 @@
 
 package org.apache.sshd.cli.server;
 
-import java.io.File;
 import java.io.InputStream;
+import java.io.PrintStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -57,6 +57,8 @@ import org.apache.sshd.server.config.SshServerConfigFileReader;
 import org.apache.sshd.server.forward.ForwardingFilter;
 import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvider;
 import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
+import org.apache.sshd.server.shell.InteractiveProcessShellFactory;
+import org.apache.sshd.server.shell.ShellFactory;
 import org.apache.sshd.server.subsystem.SubsystemFactory;
 
 /**
@@ -65,19 +67,24 @@ import org.apache.sshd.server.subsystem.SubsystemFactory;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public abstract class SshServerCliSupport extends CliSupport {
+    public static final String SHELL_FACTORY_OPTION = "ShellFactory";
+    public static final ShellFactory DEFAULT_SHELL_FACTORY = InteractiveProcessShellFactory.INSTANCE;
+
     protected SshServerCliSupport() {
         super();
     }
 
-    public static KeyPairProvider setupServerKeys(SshServer sshd, String hostKeyType, int hostKeySize, Collection<String> keyFiles) throws Exception {
+    public static KeyPairProvider resolveServerKeys(
+            PrintStream stderr, String hostKeyType, int hostKeySize, Collection<String> keyFiles)
+                throws Exception {
         if (GenericUtils.isEmpty(keyFiles)) {
             AbstractGeneratorHostKeyProvider hostKeyProvider;
             Path hostKeyFile;
             if (SecurityUtils.isBouncyCastleRegistered()) {
-                hostKeyFile = new File("key.pem").toPath();
+                hostKeyFile = Paths.get("key.pem");
                 hostKeyProvider = SecurityUtils.createGeneratorHostKeyProvider(hostKeyFile);
             } else {
-                hostKeyFile = new File("key.ser").toPath();
+                hostKeyFile = Paths.get("key.ser");
                 hostKeyProvider = new SimpleGeneratorHostKeyProvider(hostKeyFile);
             }
             hostKeyProvider.setAlgorithm(hostKeyType);
@@ -112,9 +119,10 @@ public abstract class SshServerCliSupport extends CliSupport {
                     KeyPair kp = SecurityUtils.loadKeyPairIdentity(keyFilePath, inputStream, null);
                     pairs.add(kp);
                 } catch (Exception e) {
-                    System.err.append("Failed (" + e.getClass().getSimpleName() + ")"
-                                + " to load host key file=" + keyFilePath
-                                + ": " + e.getMessage());
+                    stderr.append("Failed (").append(e.getClass().getSimpleName()).append(')')
+                        .append(" to load host key file=").append(keyFilePath)
+                        .append(": ").println(e.getMessage());
+                    stderr.flush();
                     throw e;
                 }
             }
@@ -135,7 +143,7 @@ public abstract class SshServerCliSupport extends CliSupport {
         return banner;
     }
 
-    public static List<NamedFactory<Command>> setupServerSubsystems(SshServer server, PropertyResolver options) {
+    public static List<NamedFactory<Command>> resolveServerSubsystems(PrintStream stderr, PropertyResolver options) throws Exception {
         ClassLoader cl = ThreadUtils.resolveDefaultClassLoader(SubsystemFactory.class);
         String classList = System.getProperty(SubsystemFactory.class.getName());
         if (GenericUtils.isNotEmpty(classList)) {
@@ -146,12 +154,12 @@ public abstract class SshServerCliSupport extends CliSupport {
                     Class<?> clazz = cl.loadClass(fqcn);
                     SubsystemFactory factory = SubsystemFactory.class.cast(clazz.newInstance());
                     subsystems.add(factory);
-                } catch (Throwable t) {
-                    System.err.append("Failed (").append(t.getClass().getSimpleName()).append(')')
+                } catch (Exception e) {
+                    stderr.append("Failed (").append(e.getClass().getSimpleName()).append(')')
                         .append(" to instantiate subsystem=").append(fqcn)
-                        .append(": ").println(t.getMessage());
-                    System.err.flush();
-                    throw GenericUtils.toRuntimeException(t, true);
+                        .append(": ").println(e.getMessage());
+                    stderr.flush();
+                    throw e;
                 }
             }
 
@@ -181,4 +189,28 @@ public abstract class SshServerCliSupport extends CliSupport {
 
         return subsystems;
     }
+
+    public static ShellFactory resolveShellFactory(PrintStream stderr, PropertyResolver options) throws Exception {
+        String factory = (options == null) ? null : options.getString(SHELL_FACTORY_OPTION);
+        if (GenericUtils.isEmpty(factory)) {
+            return DEFAULT_SHELL_FACTORY;
+        }
+
+        if ("none".equalsIgnoreCase(factory)) {
+            return null;
+        }
+
+        ClassLoader cl = ThreadUtils.resolveDefaultClassLoader(ShellFactory.class);
+        try {
+            Class<?> clazz = cl.loadClass(factory);
+            Object instance = clazz.newInstance();
+            return ShellFactory.class.cast(instance);
+        } catch (Exception e) {
+            stderr.append("Failed (").append(e.getClass().getSimpleName()).append(')')
+                .append(" to instantiate shell factory=").append(factory)
+                .append(": ").println(e.getMessage());
+            stderr.flush();
+            throw e;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cda53d6f/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
----------------------------------------------------------------------
diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
index 05c1069..cba6fc2 100644
--- a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
+++ b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java
@@ -39,8 +39,8 @@ import org.apache.sshd.server.auth.pubkey.AcceptAllPublickeyAuthenticator;
 import org.apache.sshd.server.config.keys.ServerIdentity;
 import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvider;
 import org.apache.sshd.server.scp.ScpCommandFactory;
-import org.apache.sshd.server.shell.InteractiveProcessShellFactory;
 import org.apache.sshd.server.shell.ProcessShellFactory;
+import org.apache.sshd.server.shell.ShellFactory;
 
 /**
  * TODO Add javadoc
@@ -66,14 +66,16 @@ public class SshServerMain extends SshServerCliSupport {
         for (int i = 0; i < numArgs; i++) {
             String argName = args[i];
             if ("-p".equals(argName)) {
-                if ((i + 1) >= numArgs) {
+                i++;
+                if (i >= numArgs) {
                     System.err.println("option requires an argument: " + argName);
                     error = true;
                     break;
                 }
-                port = Integer.parseInt(args[++i]);
+                port = Integer.parseInt(args[i]);
             } else if ("-key-type".equals(argName)) {
-                if ((i + 1) >= numArgs) {
+                i++;
+                if (i >= numArgs) {
                     System.err.println("option requires an argument: " + argName);
                     error = true;
                     break;
@@ -84,9 +86,10 @@ public class SshServerMain extends SshServerCliSupport {
                     error = true;
                     break;
                 }
-                hostKeyType = args[++i].toUpperCase();
+                hostKeyType = args[i].toUpperCase();
             } else if ("-key-size".equals(argName)) {
-                if ((i + 1) >= numArgs) {
+                i++;
+                if (i >= numArgs) {
                     System.err.println("option requires an argument: " + argName);
                     error = true;
                     break;
@@ -98,27 +101,29 @@ public class SshServerMain extends SshServerCliSupport {
                     break;
                 }
 
-                hostKeySize = Integer.parseInt(args[++i]);
+                hostKeySize = Integer.parseInt(args[i]);
             } else if ("-key-file".equals(argName)) {
-                if ((i + 1) >= numArgs) {
+                i++;
+                if (i >= numArgs) {
                     System.err.println("option requires an argument: " + argName);
                     error = true;
                     break;
                 }
 
-                String keyFilePath = args[++i];
+                String keyFilePath = args[i];
                 if (keyFiles == null) {
                     keyFiles = new LinkedList<>();
                 }
                 keyFiles.add(keyFilePath);
             } else if ("-o".equals(argName)) {
-                if ((i + 1) >= numArgs) {
+                i++;
+                if (i >= numArgs) {
                     System.err.println("option requires and argument: " + argName);
                     error = true;
                     break;
                 }
 
-                String opt = args[++i];
+                String opt = args[i];
                 int idx = opt.indexOf('=');
                 if (idx <= 0) {
                     System.err.println("bad syntax for option: " + opt);
@@ -138,18 +143,10 @@ public class SshServerMain extends SshServerCliSupport {
                 } else {
                     options.put(optName, optValue);
                 }
-            } else if (argName.startsWith("-")) {
-                System.err.println("illegal option: " + argName);
-                error = true;
-                break;
-            } else {
-                System.err.println("extra argument: " + argName);
-                error = true;
-                break;
             }
         }
 
-        SshServer sshd = setupIoServiceFactory(SshServer.setUpDefaultServer(), System.err, args);
+        SshServer sshd = error ? null : setupIoServiceFactory(SshServer.setUpDefaultServer(), System.err, args);
         if (sshd == null) {
             error = true;
         }
@@ -163,7 +160,7 @@ public class SshServerMain extends SshServerCliSupport {
         props.putAll(options);
 
         PropertyResolver resolver = PropertyResolverUtils.toPropertyResolver(options);
-        KeyPairProvider hostKeyProvider = setupServerKeys(sshd, hostKeyType, hostKeySize, keyFiles);
+        KeyPairProvider hostKeyProvider = resolveServerKeys(System.err, hostKeyType, hostKeySize, keyFiles);
         sshd.setKeyPairProvider(hostKeyProvider);
         // Should come AFTER key pair provider setup so auto-welcome can be generated if needed
         setupServerBanner(sshd, resolver);
@@ -174,15 +171,20 @@ public class SshServerMain extends SshServerCliSupport {
             SshConfigFileReader.configureMacs(sshd, macsOverride, true, true);
         }
 
-        sshd.setShellFactory(InteractiveProcessShellFactory.INSTANCE);
+        ShellFactory shellFactory = resolveShellFactory(System.err, resolver);
+        if (shellFactory != null) {
+            System.out.append("Using shell=").println(shellFactory.getClass().getName());
+            sshd.setShellFactory(shellFactory);
+        }
+
         sshd.setPasswordAuthenticator((username, password, session) -> Objects.equals(username, password));
         sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
         setupServerForwarding(sshd, resolver);
-        sshd.setCommandFactory(new ScpCommandFactory.Builder().withDelegate(
-            command -> new ProcessShellFactory(GenericUtils.split(command, ' ')).create()
-        ).build());
+        sshd.setCommandFactory(new ScpCommandFactory.Builder()
+            .withDelegate(command -> new ProcessShellFactory(GenericUtils.split(command, ' ')).create())
+            .build());
 
-        List<NamedFactory<Command>> subsystems = setupServerSubsystems(sshd, resolver);
+        List<NamedFactory<Command>> subsystems = resolveServerSubsystems(System.err, resolver);
         if (GenericUtils.isNotEmpty(subsystems)) {
             System.out.append("Setup subsystems=").println(NamedResource.getNames(subsystems));
             sshd.setSubsystemFactories(subsystems);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cda53d6f/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java
----------------------------------------------------------------------
diff --git a/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java b/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java
index aad7cd5..74a5a83 100644
--- a/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java
+++ b/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java
@@ -54,7 +54,7 @@ import org.apache.sshd.server.forward.AcceptAllForwardingFilter;
 import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
 import org.apache.sshd.server.scp.ScpCommandFactory;
 import org.apache.sshd.server.session.ServerSession;
-import org.apache.sshd.server.shell.InteractiveProcessShellFactory;
+import org.apache.sshd.server.shell.ShellFactory;
 import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory;
 import org.apache.sshd.util.test.Utils;
 
@@ -286,22 +286,19 @@ public final class SshFsMounter extends SshServerCliSupport {
                     break;
                 }
                 options.put(opt.substring(0, idx), opt.substring(idx + 1));
-            } else if (argName.startsWith("-")) {
-                System.err.println("illegal option: " + argName);
-                error = true;
-                break;
-            } else {
-                System.err.println("extra argument: " + argName);
-                error = true;
-                break;
             }
         }
+
+        SshServer sshd = error ? null : setupIoServiceFactory(Utils.setupTestServer(SshFsMounter.class), System.err, args);
+        if (sshd == null) {
+            error = true;
+        }
+
         if (error) {
-            System.err.println("usage: sshfs [-p port] [-io mina|nio2] [-o option=value]");
+            System.err.println("usage: sshfs [-p port] [-io mina|nio2|netty] [-o option=value]");
             System.exit(-1);
         }
 
-        SshServer sshd = Utils.setupTestServer(SshFsMounter.class);
         Map<String, Object> props = sshd.getProperties();
         props.putAll(options);
         PropertyResolver resolver = PropertyResolverUtils.toPropertyResolver(options);
@@ -314,7 +311,11 @@ public final class SshFsMounter extends SshServerCliSupport {
         // Should come AFTER key pair provider setup so auto-welcome can be generated if needed
         setupServerBanner(sshd, resolver);
 
-        sshd.setShellFactory(InteractiveProcessShellFactory.INSTANCE);
+        ShellFactory shellFactory = resolveShellFactory(System.err, resolver);
+        if (shellFactory != null) {
+            System.out.append("Using shell=").println(shellFactory.getClass().getName());
+            sshd.setShellFactory(shellFactory);
+        }
         sshd.setPasswordAuthenticator(AcceptAllPasswordAuthenticator.INSTANCE);
         sshd.setForwardingFilter(AcceptAllForwardingFilter.INSTANCE);
         sshd.setCommandFactory(new ScpCommandFactory.Builder().withDelegate(MounterCommandFactory.INSTANCE).build());

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cda53d6f/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java
index 1bd34cd..3398e63 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java
@@ -35,7 +35,7 @@ import org.apache.sshd.server.Command;
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class ProcessShellFactory extends AbstractLoggingBean implements Factory<Command> {
+public class ProcessShellFactory extends AbstractLoggingBean implements ShellFactory {
     private List<String> command;
 
     public ProcessShellFactory() {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cda53d6f/sshd-core/src/main/java/org/apache/sshd/server/shell/ShellFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/ShellFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/ShellFactory.java
new file mode 100644
index 0000000..0a80f67
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/ShellFactory.java
@@ -0,0 +1,32 @@
+/*
+ * 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.server.shell;
+
+import org.apache.sshd.common.Factory;
+import org.apache.sshd.server.Command;
+
+/**
+ * Useful marker interface
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface ShellFactory extends Factory<Command> {
+    // Nothing extra
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cda53d6f/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java b/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
index 67d1516..5193cec 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/AsyncEchoShellFactory.java
@@ -23,7 +23,6 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 
-import org.apache.sshd.common.Factory;
 import org.apache.sshd.common.channel.BufferedIoOutputStream;
 import org.apache.sshd.common.channel.Window;
 import org.apache.sshd.common.io.IoInputStream;
@@ -37,13 +36,14 @@ import org.apache.sshd.server.Environment;
 import org.apache.sshd.server.ExitCallback;
 import org.apache.sshd.server.channel.ChannelDataReceiver;
 import org.apache.sshd.server.channel.ChannelSession;
+import org.apache.sshd.server.shell.ShellFactory;
 
 /**
  * TODO Add javadoc
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class AsyncEchoShellFactory implements Factory<Command> {
+public class AsyncEchoShellFactory implements ShellFactory {
     public AsyncEchoShellFactory() {
         super();
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cda53d6f/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java b/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java
index bfce2ca..fe97a2f 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/EchoShellFactory.java
@@ -18,15 +18,15 @@
  */
 package org.apache.sshd.util.test;
 
-import org.apache.sshd.common.Factory;
 import org.apache.sshd.server.Command;
+import org.apache.sshd.server.shell.ShellFactory;
 
 /**
  * TODO Add javadoc
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class EchoShellFactory implements Factory<Command> {
+public class EchoShellFactory implements ShellFactory {
     public static final EchoShellFactory INSTANCE = new EchoShellFactory();
 
     public EchoShellFactory() {