You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2009/11/12 18:33:08 UTC

svn commit: r835461 - in /mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd: SshServer.java server/ServerFactoryManager.java server/channel/ChannelSession.java

Author: gnodet
Date: Thu Nov 12 17:33:08 2009
New Revision: 835461

URL: http://svn.apache.org/viewvc?rev=835461&view=rev
Log:
SSHD-51: Support for subsystems

Modified:
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshServer.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java

Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshServer.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshServer.java?rev=835461&r1=835460&r2=835461&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshServer.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshServer.java Thu Nov 12 17:33:08 2009
@@ -107,6 +107,7 @@
     private ShellFactory shellFactory;
     private SessionFactory sessionFactory;
     private CommandFactory commandFactory;
+    private List<NamedFactory<CommandFactory.Command>> subsystemFactories;
     private PasswordAuthenticator passwordAuthenticator;
     private PublickeyAuthenticator publickeyAuthenticator;
 
@@ -166,6 +167,14 @@
         this.commandFactory = commandFactory;
     }
 
+    public List<NamedFactory<CommandFactory.Command>> getSubsystemFactories() {
+        return subsystemFactories;
+    }
+
+    public void setSubsystemFactories(List<NamedFactory<CommandFactory.Command>> subsystemFactories) {
+        this.subsystemFactories = subsystemFactories;
+    }
+
     public PasswordAuthenticator getPasswordAuthenticator() {
         return passwordAuthenticator;
     }

Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java?rev=835461&r1=835460&r2=835461&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java Thu Nov 12 17:33:08 2009
@@ -74,4 +74,13 @@
      */
     CommandFactory getCommandFactory();
 
+    /**
+     * Retrieve the list of named factories for <code>CommandFactory.Command</code> to
+     * be used to create subsystems.
+     *
+     * @return a list of named <code>CommandFactory.Command</code> factories
+     *         or <code>null</code> if subsystems are not supported on this server
+     */
+    List<NamedFactory<CommandFactory.Command>> getSubsystemFactories();
+
 }

Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java?rev=835461&r1=835460&r2=835461&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java Thu Nov 12 17:33:08 2009
@@ -22,6 +22,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.EnumSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -389,6 +390,9 @@
                     log.info("Error closing shell", e);
                 }
             }
+            public void onExit(int exitValue, String exitMessage) {
+                onExit(exitValue);
+            }
         });
 
         if (wantReply) {
@@ -465,12 +469,54 @@
 
     protected boolean handleSubsystem(Buffer buffer) throws IOException {
         boolean wantReply = buffer.getBoolean();
-        // TODO: start subsystem
+        String subsystem = buffer.getString();
+
+        List<NamedFactory<CommandFactory.Command>> factories = ((ServerSession) session).getServerFactoryManager().getSubsystemFactories();
+        if (factories == null) {
+            return false;
+        }
+        CommandFactory.Command command = NamedFactory.Utils.create(factories, subsystem);
+        if (command == null) {
+            return false;
+        }
+        
+        // If the command wants to be aware of the session, let's do that
+        if (command instanceof CommandFactory.SessionAware) {
+            ((CommandFactory.SessionAware) command).setSession((ServerSession) session);
+        }
+        // Set streams and exit callback
+        out = new ChannelOutputStream(this, remoteWindow, log, SshConstants.Message.SSH_MSG_CHANNEL_DATA);
+        err = new ChannelOutputStream(this, remoteWindow, log, SshConstants.Message.SSH_MSG_CHANNEL_EXTENDED_DATA);
+        // Wrap in logging filters
+        out = new LoggingFilterOutputStream(out, "OUT:", log);
+        err = new LoggingFilterOutputStream(err, "ERR:", log);
+        in = new ChannelPipedInputStream(localWindow);
+        shellIn = new ChannelPipedOutputStream((ChannelPipedInputStream) in);
+        command.setInputStream(in);
+        command.setOutputStream(out);
+        command.setErrorStream(err);
+        command.setExitCallback(new CommandFactory.ExitCallback() {
+            public void onExit(int exitValue) {
+                try {
+                    closeShell(exitValue);
+                } catch (IOException e) {
+                    log.info("Error closing shell", e);
+                }
+            }
+            public void onExit(int exitValue, String exitMessage) {
+                onExit(exitValue);
+            }
+        });
+
         if (wantReply) {
             buffer = session.createBuffer(SshConstants.Message.SSH_MSG_CHANNEL_SUCCESS);
             buffer.putInt(recipient);
             session.writePacket(buffer);
         }
+
+        // Launch command
+        command.start();
+
         return true;
     }