Author: gnodet Date: Fri Nov 13 07:17:14 2009 New Revision: 835763 URL: http://svn.apache.org/viewvc?rev=835763&view=rev Log: SSHD-52: refactor command / shell / subsystem interfaces into something more coherent
Added: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/Factory.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Command.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Environment.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SessionAware.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java - copied, changed from r835279, mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SessionFactory.java Removed: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SessionFactory.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ShellFactory.java 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/common/AbstractFactoryManager.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/PtyMode.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.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/Signal.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommandFactory.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/UnknownCommand.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/util/EchoShellFactory.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=835763&r1=835762&r2=835763&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 Fri Nov 13 07:17:14 2009 @@ -31,14 +31,7 @@ import org.apache.mina.core.service.IoAcceptor; import org.apache.mina.core.session.IoSession; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; -import org.apache.sshd.common.AbstractFactoryManager; -import org.apache.sshd.common.Channel; -import org.apache.sshd.common.Cipher; -import org.apache.sshd.common.Compression; -import org.apache.sshd.common.KeyExchange; -import org.apache.sshd.common.Mac; -import org.apache.sshd.common.NamedFactory; -import org.apache.sshd.common.Signature; +import org.apache.sshd.common.*; import org.apache.sshd.common.cipher.AES128CBC; import org.apache.sshd.common.cipher.AES192CBC; import org.apache.sshd.common.cipher.AES256CBC; @@ -59,13 +52,7 @@ import org.apache.sshd.common.signature.SignatureDSA; import org.apache.sshd.common.signature.SignatureRSA; import org.apache.sshd.common.util.SecurityUtils; -import org.apache.sshd.server.CommandFactory; -import org.apache.sshd.server.PasswordAuthenticator; -import org.apache.sshd.server.PublickeyAuthenticator; -import org.apache.sshd.server.ServerFactoryManager; -import org.apache.sshd.server.SessionFactory; -import org.apache.sshd.server.ShellFactory; -import org.apache.sshd.server.UserAuth; +import org.apache.sshd.server.*; import org.apache.sshd.server.auth.UserAuthPassword; import org.apache.sshd.server.auth.UserAuthPublicKey; import org.apache.sshd.server.channel.ChannelDirectTcpip; @@ -73,6 +60,7 @@ import org.apache.sshd.server.kex.DHG1; import org.apache.sshd.server.kex.DHG14; import org.apache.sshd.server.session.ServerSession; +import org.apache.sshd.server.session.SessionFactory; import org.apache.sshd.server.shell.ProcessShellFactory; /** @@ -83,7 +71,7 @@ * or programmatically. Basic setup is usually done using the {...@link #setUpDefaultServer()} * method, which will known ciphers, macs, channels, etc... * Besides this basic setup, a few things have to be manually configured such as the - * port number, {...@link ShellFactory}, the {...@link org.apache.sshd.common.KeyPairProvider} + * port number, {...@link Factory}, the {...@link org.apache.sshd.common.KeyPairProvider} * and the {...@link PasswordAuthenticator}. * * Some properties can also be configured using the {...@link #setProperties(java.util.Map)} @@ -104,10 +92,10 @@ private int port; private boolean reuseAddress = true; private List<NamedFactory<UserAuth>> userAuthFactories; - private ShellFactory shellFactory; + private Factory<Command> shellFactory; private SessionFactory sessionFactory; private CommandFactory commandFactory; - private List<NamedFactory<CommandFactory.Command>> subsystemFactories; + private List<NamedFactory<Command>> subsystemFactories; private PasswordAuthenticator passwordAuthenticator; private PublickeyAuthenticator publickeyAuthenticator; @@ -143,11 +131,11 @@ this.userAuthFactories = userAuthFactories; } - public ShellFactory getShellFactory() { + public Factory<Command> getShellFactory() { return shellFactory; } - public void setShellFactory(ShellFactory shellFactory) { + public void setShellFactory(Factory<Command> shellFactory) { this.shellFactory = shellFactory; } @@ -167,11 +155,11 @@ this.commandFactory = commandFactory; } - public List<NamedFactory<CommandFactory.Command>> getSubsystemFactories() { + public List<NamedFactory<Command>> getSubsystemFactories() { return subsystemFactories; } - public void setSubsystemFactories(List<NamedFactory<CommandFactory.Command>> subsystemFactories) { + public void setSubsystemFactories(List<NamedFactory<Command>> subsystemFactories) { this.subsystemFactories = subsystemFactories; } Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java Fri Nov 13 07:17:14 2009 @@ -42,7 +42,7 @@ private List<NamedFactory<Compression>> compressionFactories; private List<NamedFactory<Mac>> macFactories; private List<NamedFactory<Signature>> signatureFactories; - private NamedFactory<Random> randomFactory; + private Factory<Random> randomFactory; private KeyPairProvider keyPairProvider; private String version; private List<NamedFactory<Channel>> channelFactories; @@ -91,11 +91,11 @@ this.signatureFactories = signatureFactories; } - public NamedFactory<Random> getRandomFactory() { + public Factory<Random> getRandomFactory() { return randomFactory; } - public void setRandomFactory(NamedFactory<Random> randomFactory) { + public void setRandomFactory(Factory<Random> randomFactory) { this.randomFactory = randomFactory; } Added: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/Factory.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/Factory.java?rev=835763&view=auto ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/Factory.java (added) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/Factory.java Fri Nov 13 07:17:14 2009 @@ -0,0 +1,36 @@ +/* + * 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; + +/** + * Fatory is a simple interface that is used to create other objects. + * + * @param <T> type of objets this factory will create + * + * @author <a href="mailto:d...@mina.apache.org">Apache MINA SSHD Project</a> + */ +public interface Factory<T> { + + /** + * Create a new instance + * @return + */ + T create(); + +} Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java Fri Nov 13 07:17:14 2009 @@ -125,7 +125,7 @@ * * @return the <code>Random</code> factory, never <code>null</code> */ - NamedFactory<Random> getRandomFactory(); + Factory<Random> getRandomFactory(); /** * Retrieve the list of named factories for <code>Channel</code> objects. Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java Fri Nov 13 07:17:14 2009 @@ -28,7 +28,7 @@ * * @author <a href="mailto:d...@mina.apache.org">Apache MINA SSHD Project</a> */ -public interface NamedFactory<T> { +public interface NamedFactory<T> extends Factory<T> { /** * Name of this factory @@ -37,12 +37,6 @@ String getName(); /** - * Create a new instance - * @return - */ - T create(); - - /** * Utility class to help using NamedFactories */ public static class Utils { Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/PtyMode.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/PtyMode.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/PtyMode.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/common/PtyMode.java Fri Nov 13 07:17:14 2009 @@ -18,8 +18,6 @@ */ package org.apache.sshd.common; -import org.apache.sshd.server.ShellFactory; - import java.util.HashMap; import java.util.Map; Added: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Command.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Command.java?rev=835763&view=auto ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Command.java (added) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Command.java Fri Nov 13 07:17:14 2009 @@ -0,0 +1,75 @@ +/* + * 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; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +/** + * Represents a command, shell or subsystem that can be used to send command. + * + * This command have direct streams, meaning those streams will be provided by the ssh server + * for the shell to use directy. This interface is suitable for implementing commands in java, + * rather than using external processes. For wrapping such processes or using inverted streams, + * see {...@link org.apache.sshd.server.shell.InvertedShellWrapper}. + */ +public interface Command { + + /** + * Set the input stream that can be used by the shell to read input. + * @param in + */ + void setInputStream(InputStream in); + + /** + * Set the output stream that can be used by the shell to write its output. + * @param out + */ + void setOutputStream(OutputStream out); + + /** + * Set the error stream that can be used by the shell to write its errors. + * @param err + */ + void setErrorStream(OutputStream err); + + /** + * Set the callback that the shell has to call when it is closed. + * @param callback + */ + void setExitCallback(ExitCallback callback); + + /** + * Starts the shell. + * All streams must have been set before calling this method. + * + * @param env + * @throws java.io.IOException + */ + void start(Environment env) throws IOException; + + /** + * Destroy the shell. + * This method can be called by the SSH server to destroy the shell because + * the client has disconnected somehow. + */ + void destroy(); + +} Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/CommandFactory.java Fri Nov 13 07:17:14 2009 @@ -43,77 +43,4 @@ */ Command createCommand(String command); - /** - * Interface that can be implemented by a command to be able to access the - * server session in which this command will be used. - */ - public interface SessionAware { - - /** - * Set the server session in which this command will be executed. - * - * @param session - */ - void setSession(ServerSession session); - } - - /** - * A command that can be executed on the server side - */ - public interface Command { - - /** - * Set the input stream that can be used by the shell to read input. - * @param in - */ - void setInputStream(InputStream in); - - /** - * Set the output stream that can be used by the shell to write its output. - * @param out - */ - void setOutputStream(OutputStream out); - - /** - * Set the error stream that can be used by the shell to write its errors. - * @param err - */ - void setErrorStream(OutputStream err); - - /** - * Set the callback that the shell has to call when it is closed. - */ - void setExitCallback(ExitCallback callback); - - /** - * Execute the command and return its status - * - * @return - * @throws java.io.IOException - */ - void start() throws IOException; - } - - - /** - * Callback used by a command to notify the SSH server is has exited - */ - public interface ExitCallback { - - /** - * Informs the SSH client/server that the shell has exited - * - * @param exitValue the exit value - */ - void onExit(int exitValue); - - /** - * Informs the SSH client/server that the shell has exited - * - * @param exitValue the exit value - * @param exitMessage exit value description - */ - void onExit(int exitValue, String exitMessage); - } - } Added: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Environment.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Environment.java?rev=835763&view=auto ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Environment.java (added) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Environment.java Fri Nov 13 07:17:14 2009 @@ -0,0 +1,92 @@ +/* + * 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; + +import org.apache.sshd.common.PtyMode; + +import java.util.EnumSet; +import java.util.Map; + +/** + * Interface providing access to the environment map and allowing the registration + * of listeners for certain signals. + * + * @see org.apache.sshd.server.Signal + */ +public interface Environment { + /** + * Key for the user environment variable + */ + public static final String ENV_USER = "USER"; + /** + * Key for the lines environment variable. Specifies the number of + * lines visible on the client side. {...@link Environment#ENV_LINES} and + * {...@link Environment#ENV_COLUMNS} make up the console screen size. + */ + public static final String ENV_LINES = "LINES"; + /** + * Key for the columns environment variable. Specifies the number of + * columns visible on the client side. {...@link Environment#ENV_LINES} and + * {...@link Environment#ENV_COLUMNS} make up the console screen size. + */ + public static final String ENV_COLUMNS = "COLUMNS"; + /** + * Key for the term environment variable. Describes the terminal or + * terminal emulation which is in use. + */ + public static final String ENV_TERM = "TERM"; + + /** + * Retrieve the environment map + * @return the environment map + */ + Map<String, String> getEnv(); + + /** + * Retrieve the pty modes + * @return the map of pty modes + */ + Map<PtyMode, Integer> getPtyModes(); + + /** + * Add a qualified listener for the specific signal + * @param listener the listener to register + * @param signal the signal the listener is interested in + */ + void addSignalListener(SignalListener listener, Signal... signal); + + /** + * Add a qualified listener for the specific set of signal + * @param listener the listener to register + * @param signals the signals the listener is interested in + */ + void addSignalListener(SignalListener listener, EnumSet<Signal> signals); + + /** + * Add a global listener for all signals + * @param listener the listener to register + */ + void addSignalListener(SignalListener listener); + + /** + * Remove a previously registered listener for all the signals it was registered + * @param listener the listener to remove + */ + void removeSignalListener(SignalListener listener); +} Added: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java?rev=835763&view=auto ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java (added) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java Fri Nov 13 07:17:14 2009 @@ -0,0 +1,40 @@ +/* + * 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; + +/** + * Callback used by the shell to notify the SSH server is has exited + */ +public interface ExitCallback { + + /** + * Informs the SSH server that the shell has exited + * + * @param exitValue the exit value + */ + void onExit(int exitValue); + + /** + * Informs the SSH client/server that the shell has exited + * + * @param exitValue the exit value + * @param exitMessage exit value description + */ + void onExit(int exitValue, String exitMessage); +} 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=835763&r1=835762&r2=835763&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 Fri Nov 13 07:17:14 2009 @@ -20,6 +20,7 @@ import java.util.List; +import org.apache.sshd.common.Factory; import org.apache.sshd.common.FactoryManager; import org.apache.sshd.common.NamedFactory; @@ -64,7 +65,7 @@ * @return a valid <code>ShellFactory</code> object or <code>null</code> if shells * are not supported on this server */ - ShellFactory getShellFactory(); + Factory<Command> getShellFactory(); /** * Retrieve the <code>CommandFactory</code> to be used to process commands requests. @@ -81,6 +82,6 @@ * @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(); + List<NamedFactory<Command>> getSubsystemFactories(); } Added: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SessionAware.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SessionAware.java?rev=835763&view=auto ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SessionAware.java (added) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SessionAware.java Fri Nov 13 07:17:14 2009 @@ -0,0 +1,35 @@ +/* + * 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; + +import org.apache.sshd.server.session.ServerSession; + +/** + * Interface that can be implemented by a command to be able to access the + * server session in which this command will be used. + */ +public interface SessionAware { + + /** + * Set the server session in which this shell will be executed. + * + * @param session + */ + void setSession(ServerSession session); +} Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Signal.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Signal.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Signal.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/Signal.java Fri Nov 13 07:17:14 2009 @@ -24,7 +24,7 @@ /** * System signals definition that the shell can receive. * - * @see ShellFactory.Environment + * @see Environment */ public enum Signal { Added: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java?rev=835763&view=auto ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java (added) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java Fri Nov 13 07:17:14 2009 @@ -0,0 +1,31 @@ +/* + * 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; + +/** + * Define a listener to receive signals + */ +public interface SignalListener { + + /** + * + * @param signal + */ + void signal(Signal signal); +} 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=835763&r1=835762&r2=835763&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 Fri Nov 13 07:17:14 2009 @@ -42,11 +42,8 @@ import org.apache.sshd.common.util.IoUtils; import org.apache.sshd.common.util.LfToCrLfFilterOutputStream; import org.apache.sshd.common.util.LoggingFilterOutputStream; -import org.apache.sshd.server.CommandFactory; -import org.apache.sshd.server.ShellFactory; -import org.apache.sshd.server.Signal; -import org.apache.sshd.server.ShellFactory.Environment; -import org.apache.sshd.server.ShellFactory.SignalListener; +import org.apache.sshd.server.*; +import org.apache.sshd.server.Environment; import org.apache.sshd.server.session.ServerSession; /** @@ -132,7 +129,7 @@ } /** - * adds a variable to the environment. This method is called <code>set</code> + * adds a variable to the environment. This method is called <code>set</code> * according to the name of the appropriate posix command <code>set</code> * @param key environment variable name * @param value environment variable value @@ -163,10 +160,8 @@ protected InputStream in; protected OutputStream out; protected OutputStream err; - protected ShellFactory.Shell shell; + protected Command command; protected OutputStream shellIn; - protected InputStream shellOut; - protected InputStream shellErr; protected StandardEnvironment env = new StandardEnvironment(); public ChannelSession() { @@ -175,12 +170,12 @@ public CloseFuture close(boolean immediately) { return super.close(immediately).addListener(new SshFutureListener() { public void operationComplete(SshFuture sshFuture) { - if (shell != null) { - shell.destroy(); - shell = null; + if (command != null) { + command.destroy(); + command = null; } remoteWindow.notifyClosed(); - IoUtils.closeQuietly(in, out, err, shellIn, shellOut, shellErr); + IoUtils.closeQuietly(in, out, err, shellIn); } }); } @@ -321,12 +316,12 @@ int tWidth = buffer.getInt(); int tHeight = buffer.getInt(); log.debug("window-change for channel {}: ({} - {}), ({}, {})", new Object[] { id, tColumns, tRows, tWidth, tHeight }); - + final StandardEnvironment e = getEnvironment(); e.set(Environment.ENV_COLUMNS, Integer.toString(tColumns)); e.set(Environment.ENV_LINES, Integer.toString(tRows)); e.signal(Signal.WINCH); - + if (wantReply) { buffer = session.createBuffer(SshConstants.Message.SSH_MSG_CHANNEL_SUCCESS); buffer.putInt(recipient); @@ -339,15 +334,15 @@ boolean wantReply = buffer.getBoolean(); String name = buffer.getString(); log.debug("Signal received on channel {}: {}", id, name); - + final Signal signal = Signal.get(name); if (signal != null) { getEnvironment().signal(signal); } else { log.warn("Unknown signal received: " + name); } - - + + if (wantReply) { buffer = session.createBuffer(SshConstants.Message.SSH_MSG_CHANNEL_SUCCESS); buffer.putInt(recipient); @@ -358,144 +353,88 @@ protected boolean handleShell(Buffer buffer) throws IOException { boolean wantReply = buffer.getBoolean(); - if (((ServerSession) session).getServerFactoryManager().getShellFactory() == null) { return false; } - addEnvVariable(Environment.ENV_USER, ((ServerSession) session).getUsername()); - shell = ((ServerSession) session).getServerFactoryManager().getShellFactory().createShell(); - // If the shell wants to be aware of the session, let's do that - if (shell instanceof ShellFactory.SessionAware) { - ((ShellFactory.SessionAware) shell).setSession((ServerSession) session); - } - 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); - if (getPtyModeValue(PtyMode.ONLCR) != 0) { - out = new LfToCrLfFilterOutputStream(out); - err = new LfToCrLfFilterOutputStream(err); - } - in = new ChannelPipedInputStream(localWindow); - shellIn = new ChannelPipedOutputStream((ChannelPipedInputStream) in); - shell.setInputStream(in); - shell.setOutputStream(out); - shell.setErrorStream(err); - shell.setExitCallback(new ShellFactory.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); - } - }); - + command = ((ServerSession) session).getServerFactoryManager().getShellFactory().create(); + prepareCommand(); if (wantReply) { buffer = session.createBuffer(SshConstants.Message.SSH_MSG_CHANNEL_SUCCESS); buffer.putInt(recipient); session.writePacket(buffer); } - - shell.start(getEnvironment()); - shellIn = new LoggingFilterOutputStream(shellIn, "IN: ", log); - + command.start(getEnvironment()); return true; } - protected int getPtyModeValue(PtyMode mode) { - Integer v = getEnvironment().getPtyModes().get(mode); - return v != null ? v : 0; - } - protected boolean handleExec(Buffer buffer) throws IOException { - CommandFactory.Command command; boolean wantReply = buffer.getBoolean(); String commandLine = buffer.getString(); - if (((ServerSession) session).getServerFactoryManager().getCommandFactory() == null) { return false; } - try { command = ((ServerSession) session).getServerFactoryManager().getCommandFactory().createCommand(commandLine); } catch (IllegalArgumentException iae) { // TODO: Shouldn't we log errors on the server side? 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); - } - }); - + prepareCommand(); if (wantReply) { buffer = session.createBuffer(SshConstants.Message.SSH_MSG_CHANNEL_SUCCESS); buffer.putInt(recipient); session.writePacket(buffer); } - // Launch command - command.start(); - + command.start(getEnvironment()); return true; } protected boolean handleSubsystem(Buffer buffer) throws IOException { boolean wantReply = buffer.getBoolean(); String subsystem = buffer.getString(); - - List<NamedFactory<CommandFactory.Command>> factories = ((ServerSession) session).getServerFactoryManager().getSubsystemFactories(); + List<NamedFactory<Command>> factories = ((ServerSession) session).getServerFactoryManager().getSubsystemFactories(); if (factories == null) { return false; } - CommandFactory.Command command = NamedFactory.Utils.create(factories, subsystem); + 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); + prepareCommand(); + if (wantReply) { + buffer = session.createBuffer(SshConstants.Message.SSH_MSG_CHANNEL_SUCCESS); + buffer.putInt(recipient); + session.writePacket(buffer); + } + // Launch command + command.start(getEnvironment()); + return true; + } + + protected void prepareCommand() { + // Add the user + addEnvVariable(Environment.ENV_USER, ((ServerSession) session).getUsername()); + // If the shell wants to be aware of the session, let's do that + if (command instanceof SessionAware) { + ((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); + if (getPtyModeValue(PtyMode.ONLCR) != 0) { + out = new LfToCrLfFilterOutputStream(out); + err = new LfToCrLfFilterOutputStream(err); + } in = new ChannelPipedInputStream(localWindow); shellIn = new ChannelPipedOutputStream((ChannelPipedInputStream) in); + shellIn = new LoggingFilterOutputStream(shellIn, "IN: ", log); command.setInputStream(in); command.setOutputStream(out); command.setErrorStream(err); - command.setExitCallback(new CommandFactory.ExitCallback() { + command.setExitCallback(new ExitCallback() { public void onExit(int exitValue) { try { closeShell(exitValue); @@ -507,17 +446,11 @@ 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; + protected int getPtyModeValue(PtyMode mode) { + Integer v = getEnvironment().getPtyModes().get(mode); + return v != null ? v : 0; } protected boolean handleAgentForwarding(Buffer buffer) throws IOException { @@ -549,7 +482,7 @@ protected StandardEnvironment getEnvironment() { return env; } - + protected void closeShell(int exitValue) throws IOException { sendEof(); sendExitStatus(exitValue); Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java Fri Nov 13 07:17:14 2009 @@ -27,7 +27,10 @@ import java.io.OutputStream; import java.util.Arrays; +import org.apache.sshd.server.Command; import org.apache.sshd.server.CommandFactory; +import org.apache.sshd.server.Environment; +import org.apache.sshd.server.ExitCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,7 +41,7 @@ * * @author <a href="mailto:d...@mina.apache.org">Apache MINA SSHD Project</a> */ -public class ScpCommand implements CommandFactory.Command, Runnable { +public class ScpCommand implements Command, Runnable { private static final Logger log = LoggerFactory.getLogger(ScpCommand.class); private static final int OK = 0; @@ -53,7 +56,7 @@ private InputStream in; private OutputStream out; private OutputStream err; - private CommandFactory.ExitCallback callback; + private ExitCallback callback; private IOException error; public ScpCommand(String[] args) { @@ -106,17 +109,20 @@ this.err = err; } - public void setExitCallback(CommandFactory.ExitCallback callback) { + public void setExitCallback(ExitCallback callback) { this.callback = callback; } - public void start() throws IOException { + public void start(Environment env) throws IOException { if (error != null) { throw error; } new Thread(this).start(); } + public void destroy() { + } + public void run() { int exitValue = OK; String exitMessage = null; Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommandFactory.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommandFactory.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommandFactory.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommandFactory.java Fri Nov 13 07:17:14 2009 @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; +import org.apache.sshd.server.Command; import org.apache.sshd.server.CommandFactory; /** Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/UnknownCommand.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/UnknownCommand.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/UnknownCommand.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/command/UnknownCommand.java Fri Nov 13 07:17:14 2009 @@ -22,16 +22,19 @@ import java.io.InputStream; import java.io.OutputStream; +import org.apache.sshd.server.Command; import org.apache.sshd.server.CommandFactory; +import org.apache.sshd.server.Environment; +import org.apache.sshd.server.ExitCallback; /** * Implementation of an unknown command that can be returned by <code>CommandFactory</code> - * when the command is not knownas it is supposed to always + * when the command is not known, as it is supposed to always * return a valid <code>Command</code> object. * * @author <a href="mailto:d...@mina.apache.org">Apache MINA SSHD Project</a> */ -public class UnknownCommand implements CommandFactory.Command { +public class UnknownCommand implements Command { public UnknownCommand(String command) { } @@ -48,12 +51,16 @@ //To change body of implemented methods use File | Settings | File Templates. } - public void setExitCallback(CommandFactory.ExitCallback callback) { + public void setExitCallback(ExitCallback callback) { //To change body of implemented methods use File | Settings | File Templates. } - public void start() throws IOException { + public void start(Environment env) throws IOException { //To change body of implemented methods use File | Settings | File Templates. // TODO: send back an error ? } + + public void destroy() { + //To change body of implemented methods use File | Settings | File Templates. + } } Copied: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java (from r835279, mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SessionFactory.java) URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java?p2=mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java&p1=mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SessionFactory.java&r1=835279&r2=835763&rev=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/SessionFactory.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java Fri Nov 13 07:17:14 2009 @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.sshd.server; +package org.apache.sshd.server.session; import org.apache.mina.core.session.IoSession; import org.apache.sshd.SshServer; Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java Fri Nov 13 07:17:14 2009 @@ -27,7 +27,7 @@ * This shell have inverted streams, such as the one obtained when launching a * new {...@link Process} from java. This interface is meant to be used with * {...@link InvertedShellWrapper} class as an implementation of - * {...@link org.apache.sshd.server.ShellFactory.Shell}. + * {...@link Factory}. * * @author <a href="mailto:d...@mina.apache.org">Apache MINA SSHD Project</a> */ Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java Fri Nov 13 07:17:14 2009 @@ -21,10 +21,10 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.util.Map; -import org.apache.sshd.server.ShellFactory; -import org.apache.sshd.server.ShellFactory.Environment; +import org.apache.sshd.server.Command; +import org.apache.sshd.server.Environment; +import org.apache.sshd.server.ExitCallback; /** * A shell implementation that wraps an instance of {...@link InvertedShell} @@ -35,7 +35,7 @@ * * @author <a href="mailto:d...@mina.apache.org">Apache MINA SSHD Project</a> */ -public class InvertedShellWrapper implements ShellFactory.Shell { +public class InvertedShellWrapper implements Command { private final InvertedShell shell; private InputStream in; @@ -44,7 +44,7 @@ private OutputStream shellIn; private InputStream shellOut; private InputStream shellErr; - private ShellFactory.ExitCallback callback; + private ExitCallback callback; private Thread thread; public InvertedShellWrapper(InvertedShell shell) { @@ -63,7 +63,7 @@ this.err = err; } - public void setExitCallback(ShellFactory.ExitCallback callback) { + public void setExitCallback(ExitCallback callback) { this.callback = callback; } Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java (original) +++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java Fri Nov 13 07:17:14 2009 @@ -23,7 +23,8 @@ import java.io.OutputStream; import java.util.Map; -import org.apache.sshd.server.ShellFactory; +import org.apache.sshd.common.Factory; +import org.apache.sshd.server.Command; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,7 +34,7 @@ * * @author <a href="mailto:d...@mina.apache.org">Apache MINA SSHD Project</a> */ -public class ProcessShellFactory implements ShellFactory { +public class ProcessShellFactory implements Factory<Command> { private static final Logger LOG = LoggerFactory.getLogger(ProcessShellFactory.class); @@ -54,7 +55,7 @@ this.command = command; } - public Shell createShell() { + public Command create() { return new InvertedShellWrapper(new ProcessShell(command)); } Modified: mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/util/EchoShellFactory.java URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/util/EchoShellFactory.java?rev=835763&r1=835762&r2=835763&view=diff ============================================================================== --- mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/util/EchoShellFactory.java (original) +++ mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/util/EchoShellFactory.java Fri Nov 13 07:17:14 2009 @@ -23,22 +23,24 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; -import java.util.Map; -import org.apache.sshd.server.ShellFactory; +import org.apache.sshd.common.Factory; +import org.apache.sshd.server.Command; +import org.apache.sshd.server.Environment; +import org.apache.sshd.server.ExitCallback; /** * TODO Add javadoc * * @author <a href="mailto:d...@mina.apache.org">Apache MINA SSHD Project</a> */ -public class EchoShellFactory implements ShellFactory { +public class EchoShellFactory implements Factory<Command> { - public Shell createShell() { + public Command create() { return new EchoShell(); } - protected static class EchoShell implements Shell, Runnable { + protected static class EchoShell implements Command, Runnable { private InputStream in; private OutputStream out; private OutputStream err;