svn commit: r830479 - in /mina/sshd/trunk/sshd-core/src: main/java/org/apache/sshd/server/ main/java/org/apache/sshd/server/channel/ main/java/org/apache/sshd/server/command/ test/java/org/apache/sshd/

View: New views
1 Messages — Rating Filter:   Alert me  

svn commit: r830479 - in /mina/sshd/trunk/sshd-core/src: main/java/org/apache/sshd/server/ main/java/org/apache/sshd/server/channel/ main/java/org/apache/sshd/server/command/ test/java/org/apache/sshd/

by gnodet-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Author: gnodet
Date: Wed Oct 28 09:27:36 2009
New Revision: 830479

URL: http://svn.apache.org/viewvc?rev=830479&view=rev
Log:
SSHD-44: NPE in ScpCommand and improvements to ScpCommandFactory.createCommand

Modified:
    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/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/test/java/org/apache/sshd/ScpTest.java

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=830479&r1=830478&r2=830479&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 Wed Oct 28 09:27:36 2009
@@ -101,12 +101,19 @@
     public interface ExitCallback {
 
         /**
-         * Informs the SSH server that the shell has exited
+         * 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);
     }
 
 }

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=830479&r1=830478&r2=830479&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 Wed Oct 28 09:27:36 2009
@@ -474,6 +474,7 @@
     }
 
     protected boolean handleExec(Buffer buffer) throws IOException {
+        CommandFactory.Command command;
         boolean wantReply = buffer.getBoolean();
         String commandLine = buffer.getString();
 
@@ -481,7 +482,12 @@
             return false;
         }
 
-        CommandFactory.Command command = ((ServerSession) session).getServerFactoryManager().getCommandFactory().createCommand(commandLine);
+        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);
@@ -505,6 +511,9 @@
                     log.info("Error closing shell", e);
                 }
             }
+            public void onExit(int exitValue, String exitMessage) {
+                onExit(exitValue);
+            }
         });
 
         if (wantReply) {

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=830479&r1=830478&r2=830479&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 Wed Oct 28 09:27:36 2009
@@ -41,6 +41,8 @@
 public class ScpCommand implements CommandFactory.Command, Runnable {
 
     private static final Logger log = LoggerFactory.getLogger(ScpCommand.class);
+    private static final int OK = 0;
+    private static final int ERROR = 2;
 
     private boolean optR;
     private boolean optT;
@@ -116,6 +118,9 @@
     }
 
     public void run() {
+        int exitValue = OK;
+        String exitMessage = null;
+        
         try {
             if (optT && !optR) {
                 ack();
@@ -143,8 +148,10 @@
             }
         } catch (IOException e) {
             try {
-                out.write(2);
-                out.write(e.getMessage().getBytes());
+                exitValue = ERROR;
+                exitMessage = e.getMessage();
+                out.write(exitValue);
+                out.write(exitMessage.getBytes());
                 out.write('\n');
                 out.flush();
             } catch (IOException e2) {
@@ -152,7 +159,9 @@
             }
             log.info("Error in scp command", e);
         } finally {
-            callback.onExit(0);
+            if (callback != null) {
+                callback.onExit(exitValue, exitMessage);
+            }
         }
     }
 

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=830479&r1=830478&r2=830479&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 Wed Oct 28 09:27:36 2009
@@ -18,6 +18,9 @@
  */
 package org.apache.sshd.server.command;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.sshd.server.CommandFactory;
 
 /**
@@ -40,15 +43,51 @@
         this.delegate = delegate;
     }
 
-    public Command createCommand(String command){
-        String[] args = command.split(" ");
-        if (args.length > 0 && "scp".equals(args[0])) {
-            return new ScpCommand(args);
+    /**
+     * Parses a command string and verifies that the basic syntax is
+     * correct. If parsing fails the responsibility is delegated to
+     * the configured {@link CommandFactory} instance; if one exist.
+     *
+     * @param command command to parse
+     * @return configured {@link CommandFactory.Command} instance
+     * @throws IllegalArgumentException
+     */
+    public Command createCommand(String command) {
+        try {
+            return new ScpCommand(splitCommandString(command));
+        } catch (IllegalArgumentException iae) {
+            if (delegate != null) {
+                return delegate.createCommand(command);
+            }
+            throw iae;
+        }
+    }
+
+    private String[] splitCommandString(String command) {
+        if (!command.trim().startsWith("scp")) {
+            throw new IllegalArgumentException("Unknown command, does not begin with 'scp'");
         }
-        if (delegate != null) {
-            return delegate.createCommand(command);
+
+        String[] args = command.split(" ");
+        List<String> parts = new ArrayList<String>();
+        parts.add(args[0]);
+        for (int i = 1; i < args.length; i++) {
+            if (!args[i].trim().startsWith("-")) {
+                parts.add(concatenateWithSpace(args, i));
+                break;
+            } else {
+                parts.add(args[i]);
+            }
         }
-        return new UnknownCommand(command);
+        return parts.toArray(new String[parts.size()]);
     }
 
+    private String concatenateWithSpace(String[] args, int from) {
+        StringBuilder sb = new StringBuilder();
+
+        for (int i = from; i < args.length; i++) {
+            sb.append(args[i] + " ");
+        }
+        return sb.toString().trim();
+    }
 }

Modified: mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/ScpTest.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/ScpTest.java?rev=830479&r1=830478&r2=830479&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/ScpTest.java (original)
+++ mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/ScpTest.java Wed Oct 28 09:27:36 2009
@@ -109,32 +109,32 @@
         String data = "0123456789\n";
 
         File root = new File("target/scp");
-        File target = new File("target/scp/out.txt");
+        File target = new File("target/scp/o ut.txt");
         root.mkdirs();
         assertTrue(root.exists());
 
         target.delete();
         assertFalse(target.exists());
-        sendFile("target/scp/out.txt", "out.txt", data);
+        sendFile("target/scp/o ut.txt", "out.txt", data);
         assertFileLength(target, data.length(), 5000);
 
         target.delete();
         assertFalse(target.exists());
-        sendFile("target/scp", "out.txt", data);
+        sendFile("target/scp", "o ut.txt", data);
         assertFileLength(target, data.length(), 5000);
 
         sendFileError("target", "scp", "0123456789\n");
 
         readFileError("target/scp");
 
-        assertEquals(data, readFile("target/scp/out.txt"));
+        assertEquals(data, readFile("target/scp/o ut.txt"));
 
         assertEquals(data, readDir("target/scp"));
 
         target.delete();
         root.delete();
 
-        sendDir("target", "scp", "out.txt", data);
+        sendDir("target", "scp", "o ut.txt", data);
         assertFileLength(target, data.length(), 5000);
     }
 
@@ -164,7 +164,7 @@
         OutputStream os = c.getOutputStream();
         InputStream is = c.getInputStream();
         String header = readLine(is);
-        assertEquals("C0644 11 out.txt", header);
+        assertEquals("C0644 11 o ut.txt", header);
         int length = Integer.parseInt(header.substring(6, header.indexOf(' ', 6)));
         os.write(0);
         os.flush();
@@ -191,7 +191,7 @@
         os.write(0);
         os.flush();
         header = readLine(is);
-        assertEquals("C0644 11 out.txt", header);
+        assertEquals("C0644 11 o ut.txt", header);
         int length = Integer.parseInt(header.substring(6, header.indexOf(' ', 6)));
         os.write(0);
         os.flush();