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; }