You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jd...@apache.org on 2007/09/18 17:40:34 UTC

svn commit: r576955 - in /geronimo/sandbox/gshell/trunk/gshell-remote: gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/ gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/ gshell-remote-common/src/m...

Author: jdillon
Date: Tue Sep 18 08:40:32 2007
New Revision: 576955

URL: http://svn.apache.org/viewvc?rev=576955&view=rev
Log:
Hooked up the security bits, fixed up the handshake+login messages... and well, its soo close I can feel it

Added:
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.java   (with props)
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java
      - copied, changed from r576852, geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java
Modified:
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RemoteShellProxy.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClientFactory.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshCommand.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/Message.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageCodecFactory.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageSupport.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitor.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorAdapter.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorSupport.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpProtocolHandler.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransportServer.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransportSupport.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShell.java
    geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerMessageVisitor.java

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RemoteShellProxy.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RemoteShellProxy.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RemoteShellProxy.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RemoteShellProxy.java Tue Sep 18 08:40:32 2007
@@ -51,7 +51,7 @@
 
     private boolean opened;
 
-    public RemoteShellProxy(final RshClient client, final IO io, final Terminal terminal) {
+    public RemoteShellProxy(final RshClient client, final IO io, final Terminal terminal) throws Exception {
         assert client != null;
         assert io != null;
         assert terminal != null;
@@ -61,9 +61,11 @@
         this.terminal = terminal;
 
         //
-        // TODO: Send OPEN_SHELL (send over some client-side details, like the terminal features, etc)
+        // TODO: send over some client-side details, like the terminal features, etc)
         //       If any problem or denial occurs, throw an exception, once created the proxy is considered valid.
         //
+        
+        client.openShell();
 
         this.opened = true;
     }
@@ -91,9 +93,12 @@
     }
 
     public void close() {
-        //
-        // TODO: Send CLOSE_SHELL
-        //
+        try {
+            client.closeShell();
+        }
+        catch (Exception e) {
+            log.error("Failure occured while closing remote shell; ignoring", e);
+        }
 
         opened = false;
         

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClient.java Tue Sep 18 08:40:32 2007
@@ -22,11 +22,16 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URI;
+import java.security.PublicKey;
 
+import org.apache.geronimo.gshell.remote.crypto.CryptoContext;
+import org.apache.geronimo.gshell.remote.message.CloseShellMessage;
 import org.apache.geronimo.gshell.remote.message.EchoMessage;
 import org.apache.geronimo.gshell.remote.message.ExecuteMessage;
 import org.apache.geronimo.gshell.remote.message.HandShakeMessage;
+import org.apache.geronimo.gshell.remote.message.LoginMessage;
 import org.apache.geronimo.gshell.remote.message.Message;
+import org.apache.geronimo.gshell.remote.message.OpenShellMessage;
 import org.apache.geronimo.gshell.remote.transport.Transport;
 import org.apache.geronimo.gshell.remote.transport.TransportFactory;
 import org.slf4j.Logger;
@@ -39,33 +44,67 @@
  */
 public class RshClient
 {
+    //
+    // TODO: If/when we want to add a state-machine to keep things in order, add client-side here.
+    //
+    
     private final Logger log = LoggerFactory.getLogger(getClass());
 
+    private final CryptoContext crypto;
+
     private final Transport transport;
 
-    public RshClient(final URI location, final TransportFactory factory) throws Exception {
+    public RshClient(final CryptoContext crypto, final URI location, final TransportFactory factory) throws Exception {
+        assert crypto != null;
         assert location != null;
         assert factory != null;
 
+        this.crypto = crypto;
+
+        // And then lets connect to the remote server
         transport = factory.connect(location);
 
         log.debug("Connected to: {}", location);
     }
 
+    public void login(final String username, final String password) throws Exception {
+        assert username != null;
+        assert password != null;
+
+        log.info("Starting handshake", username);
+
+        HandShakeMessage.Result handShakeResult = (HandShakeMessage.Result) transport.request(new HandShakeMessage(crypto.getPublicKey()));
+        PublicKey serverKey = handShakeResult.getPublicKey();
+
+        log.info("Logging in: {}", username);
+
+        LoginMessage.Result loginResult = (LoginMessage.Result) transport.request(new LoginMessage(serverKey, username, password));
+
+        log.info("Login Result: {}", loginResult);
+    }
+    
     public void echo(final String text) throws Exception {
         log.debug("Echoing: {}", text);
 
         transport.send(new EchoMessage(text));
     }
 
-    public void handshake() throws Exception {
-        log.info("Starting handshake");
+    public void openShell() throws Exception {
+        log.info("Opening remote shell");
 
-        Message resp = transport.request(new HandShakeMessage());
+        Message resp = transport.request(new OpenShellMessage());
 
         log.info("Response: {}", resp);
     }
 
+    public void closeShell() throws Exception {
+        log.info("Closing remote shell");
+
+        Message resp = transport.request(new CloseShellMessage());
+
+        log.info("Response: {}", resp);
+    }
+    
     public Object execute(final String line) throws Exception {
         assert line != null;
 

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClientFactory.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClientFactory.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClientFactory.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshClientFactory.java Tue Sep 18 08:40:32 2007
@@ -21,6 +21,7 @@
 
 import java.net.URI;
 
+import org.apache.geronimo.gshell.remote.crypto.CryptoContext;
 import org.apache.geronimo.gshell.remote.transport.TransportFactory;
 import org.apache.geronimo.gshell.remote.transport.TransportFactoryLocator;
 import org.codehaus.plexus.component.annotations.Component;
@@ -37,9 +38,12 @@
     @Requirement
     private TransportFactoryLocator locator;
 
+    @Requirement
+    private CryptoContext crypto;
+    
     public RshClient connect(final URI location) throws Exception {
         TransportFactory factory = locator.locate(location);
 
-        return new RshClient(location, factory);
+        return new RshClient(crypto, location, factory);
     }
 }

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshCommand.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshCommand.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshCommand.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-client/src/main/java/org/apache/geronimo/gshell/remote/client/RshCommand.java Tue Sep 18 08:40:32 2007
@@ -23,12 +23,11 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import jline.Terminal;
 import org.apache.geronimo.gshell.clp.Argument;
 import org.apache.geronimo.gshell.command.CommandSupport;
 import org.apache.geronimo.gshell.command.annotation.CommandComponent;
-import org.apache.geronimo.gshell.remote.client.RemoteShellProxy;
 import org.codehaus.plexus.component.annotations.Requirement;
-import jline.Terminal;
 
 /**
  * Command to connect to a remote shell server.
@@ -64,18 +63,14 @@
 
         io.info("Connected");
 
-        client.echo("TESTING");
-        
-        client.handshake();
+        client.login("jason", "password");
 
-        /*
         RemoteShellProxy shell = new RemoteShellProxy(client, io, terminal);
 
         shell.run(command.toArray());
 
         shell.close();
-        */
-
+        
         io.verbose("Disconnecting");
 
         client.close();

Added: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.java?rev=576955&view=auto
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.java (added)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.java Tue Sep 18 08:40:32 2007
@@ -0,0 +1,95 @@
+/*
+ * 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.geronimo.gshell.remote.message;
+
+import java.security.Key;
+
+import org.apache.geronimo.gshell.remote.crypto.CryptoContext;
+import org.apache.geronimo.gshell.remote.crypto.CryptoContextAware;
+import org.apache.mina.common.ByteBuffer;
+
+/**
+ * Support for messages are aware of the {@link CryptoContext}.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class CryptoAwareMessageSupport
+    extends MessageSupport
+    implements CryptoContextAware
+{
+    private transient CryptoContext ctx;
+
+    public CryptoAwareMessageSupport(final MessageType type) {
+        super(type);
+    }
+
+    public void setCryptoContext(final CryptoContext ctx) {
+        assert ctx != null;
+        
+        this.ctx = ctx;
+    }
+
+    protected CryptoContext getCryptoContext() {
+        if (ctx == null) {
+            throw new IllegalStateException("Crypto context is not set");
+        }
+        
+        return ctx;
+    }
+
+    protected String decryptString(final ByteBuffer in) throws Exception {
+        assert in != null;
+
+        int len = in.getInt();
+
+        if (len == -1) {
+            return null;
+        }
+        else {
+            byte[] bytes = new byte[len];
+
+            in.get(bytes);
+
+            bytes = getCryptoContext().decrypt(bytes);
+
+            return new String(bytes);
+        }
+    }
+
+    protected void encryptString(final ByteBuffer out, final Key key, final String str) throws Exception {
+        assert out != null;
+        assert key != null;
+
+        if (str == null) {
+            out.putInt(-1);
+        }
+        else {
+            byte[] bytes = getCryptoContext().encrypt(key, str.getBytes());
+
+            out.putInt(bytes.length);
+
+            out.put(bytes);
+        }
+    }
+
+    protected void encryptString(final ByteBuffer out, final String str) throws Exception {
+        encryptString(out, getCryptoContext().getPublicKey(), str);
+    }
+}
\ No newline at end of file

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/CryptoAwareMessageSupport.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java Tue Sep 18 08:40:32 2007
@@ -23,27 +23,40 @@
 
 import org.apache.mina.common.ByteBuffer;
 
+//
+// NOTE: This message does not support MessageListener, actually should never make it to a message listener anyways
+//       since this is consumed by the security filter.
+//
+
 /**
- * ???
+ * Initial client handshake which contains the clients public key.
  *
  * @version $Rev$ $Date$
  */
 public class HandShakeMessage
-    extends MessageSupport
+    extends CryptoAwareMessageSupport
 {
     private PublicKey publicKey;
 
-    public HandShakeMessage(final PublicKey publicKey) {
-        super(MessageType.HANDSHAKE);
+    protected HandShakeMessage(final MessageType type, final PublicKey publicKey) {
+        super(type);
 
-        setPublicKey(publicKey);
+        this.publicKey = publicKey;
     }
-    
+
+    public HandShakeMessage(final PublicKey publicKey) {
+        this(MessageType.HANDSHAKE, publicKey);
+    }
+
     public HandShakeMessage() {
         this(null);
     }
 
     public PublicKey getPublicKey() {
+        if (publicKey == null) {
+            throw new IllegalStateException("Missing public key");
+        }
+
         return publicKey;
     }
 
@@ -56,7 +69,18 @@
 
         super.readExternal(in);
 
-        publicKey = (PublicKey) in.getObject();
+        int len = in.getInt();
+
+        if (len == -1) {
+            publicKey = null;
+        }
+        else {
+            byte[] bytes = new byte[len];
+
+            in.get(bytes);
+
+            publicKey = getCryptoContext().deserializePublicKey(bytes);
+        }
     }
 
     public void writeExternal(final ByteBuffer out) throws Exception {
@@ -64,12 +88,30 @@
 
         super.writeExternal(out);
 
-        out.putObject(publicKey);
-    }
-
-    public void process(final MessageVisitor visitor) throws Exception {
-        assert visitor != null;
-
-        visitor.visitHandShake(this);
+        if (publicKey == null) {
+            out.putInt(-1);
+        }
+        else {
+            byte[] bytes = publicKey.getEncoded();
+
+            out.putInt(bytes.length);
+
+            out.put(bytes);
+        }
+    }
+
+    /**
+     * Reply from server to client which contains the server's public key.
+     */
+    public static class Result
+        extends HandShakeMessage
+    {
+        public Result(final PublicKey publicKey) {
+            super(MessageType.HANDSHAKE_RESULT, publicKey);
+        }
+
+        public Result() {
+            this(null);
+        }
     }
 }

Copied: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java (from r576852, geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java)
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java?p2=geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java&p1=geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java&r1=576852&r2=576955&rev=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/HandShakeMessage.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/LoginMessage.java Tue Sep 18 08:40:32 2007
@@ -23,32 +23,48 @@
 
 import org.apache.mina.common.ByteBuffer;
 
+//
+// NOTE: This message does not support MessageListener, actually should never make it to a message listener anyways
+//       since this is consumed by the security filter.
+//
+
 /**
- * ???
+ * Clients request to login to the server.
  *
  * @version $Rev$ $Date$
  */
-public class HandShakeMessage
-    extends MessageSupport
+public class LoginMessage
+    extends CryptoAwareMessageSupport
 {
-    private PublicKey publicKey;
+    private transient PublicKey serverKey;
 
-    public HandShakeMessage(final PublicKey publicKey) {
-        super(MessageType.HANDSHAKE);
+    private String username;
 
-        setPublicKey(publicKey);
-    }
+    //
+    // FIXME: Need to update the toString() for this message to omit the passwd
+    //
     
-    public HandShakeMessage() {
-        this(null);
+    private String password;
+
+    public LoginMessage(final PublicKey serverKey, final String username, final String password) {
+        super(MessageType.LOGIN);
+
+        this.serverKey = serverKey;
+
+        this.username = username;
+        this.password = password;
     }
 
-    public PublicKey getPublicKey() {
-        return publicKey;
+    public LoginMessage() {
+        this(null, null, null);
     }
 
-    public void setPublicKey(final PublicKey publicKey) {
-        this.publicKey = publicKey;
+    public String getUsername() {
+        return username;
+    }
+
+    public String getPassword() {
+        return password;
     }
 
     public void readExternal(final ByteBuffer in) throws Exception {
@@ -56,7 +72,9 @@
 
         super.readExternal(in);
 
-        publicKey = (PublicKey) in.getObject();
+        username = decryptString(in);
+
+        password = decryptString(in);
     }
 
     public void writeExternal(final ByteBuffer out) throws Exception {
@@ -64,12 +82,19 @@
 
         super.writeExternal(out);
 
-        out.putObject(publicKey);
-    }
+        encryptString(out, serverKey, username);
 
-    public void process(final MessageVisitor visitor) throws Exception {
-        assert visitor != null;
+        encryptString(out, serverKey, password);
+    }
 
-        visitor.visitHandShake(this);
+    /**
+     * Server to client message to indicate successfull login.
+     */
+    public static class Result
+        extends MessageSupport
+    {
+        public Result() {
+            super(MessageType.LOGIN_RESULT);
+        }
     }
 }

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/Message.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/Message.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/Message.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/Message.java Tue Sep 18 08:40:32 2007
@@ -22,8 +22,9 @@
 import java.io.IOException;
 import java.util.UUID;
 
-import org.apache.mina.common.IoSession;
 import org.apache.mina.common.ByteBuffer;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.common.WriteFuture;
 
 /**
  * Defines the basic attributes of all messages.
@@ -53,6 +54,8 @@
     void freeze();
 
     boolean isFrozen();
+
+    WriteFuture reply(Message msg);
 
     void readExternal(ByteBuffer in) throws Exception;
 

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageCodecFactory.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageCodecFactory.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageCodecFactory.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageCodecFactory.java Tue Sep 18 08:40:32 2007
@@ -19,6 +19,8 @@
 
 package org.apache.geronimo.gshell.remote.message;
 
+import org.apache.geronimo.gshell.remote.crypto.CryptoContext;
+import org.apache.geronimo.gshell.remote.crypto.CryptoContextAware;
 import org.apache.mina.common.ByteBuffer;
 import org.apache.mina.common.IoSession;
 import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
@@ -28,6 +30,8 @@
 import org.apache.mina.filter.codec.ProtocolDecoderOutput;
 import org.apache.mina.filter.codec.ProtocolEncoder;
 import org.apache.mina.filter.codec.ProtocolEncoderOutput;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,6 +40,7 @@
  *
  * @version $Rev$ $Date$
  */
+@Component(role=MessageCodecFactory.class)
 public class MessageCodecFactory
     implements ProtocolCodecFactory
 {
@@ -45,6 +50,11 @@
     
     public static final byte VERSION = 1;
 
+    private Logger log = LoggerFactory.getLogger(getClass());
+
+    @Requirement
+    private CryptoContext crypto;
+    
     private final Encoder encoder;
 
     private final Decoder decoder;
@@ -62,6 +72,15 @@
         return decoder;
     }
 
+    private void setCryptoContext(final Message msg) {
+        // We need to do a little bit of extra fluff to hook up support for encrypted messages
+        if (msg instanceof CryptoContextAware) {
+            log.trace("Attaching crypto context to: {}", msg);
+
+            ((CryptoContextAware)msg).setCryptoContext(crypto);
+        }
+    }
+    
     //
     // Encoder
     //
@@ -69,8 +88,6 @@
     public class Encoder
         implements ProtocolEncoder
     {
-        private Logger log = LoggerFactory.getLogger(getClass());
-
         public void encode(final IoSession session, final Object message, final ProtocolEncoderOutput out) throws Exception {
             assert session != null;
             assert message != null;
@@ -78,7 +95,9 @@
             
             Message msg = (Message)message;
 
-            log.debug("Serializing: {}", msg);
+            setCryptoContext(msg);
+
+            log.trace("Serializing: {}", msg);
 
             ByteBuffer buff = ByteBuffer.allocate(256, false);
             buff.setAutoExpand(true);
@@ -96,11 +115,7 @@
             out.write(buff);
         }
 
-        public void dispose(final IoSession session) throws Exception {
-            assert session != null;
-            
-            // Nothing
-        }
+        public void dispose(final IoSession session) throws Exception {}
     }
 
     //
@@ -110,8 +125,6 @@
     public class Decoder
         extends CumulativeProtocolDecoder
     {
-        private Logger log = LoggerFactory.getLogger(getClass());
-
         protected boolean doDecode(final IoSession session, final ByteBuffer in, final ProtocolDecoderOutput out) throws Exception {
             assert session != null;
             assert in != null;
@@ -129,9 +142,11 @@
 
             Message msg = MessageType.create(type);
 
+            setCryptoContext(msg);
+
             msg.readExternal(in);
 
-            log.debug("Deserialized: {}", msg);
+            log.trace("Deserialized: {}", msg);
 
             out.write(msg);
 

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageSupport.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageSupport.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageSupport.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageSupport.java Tue Sep 18 08:40:32 2007
@@ -132,11 +132,7 @@
         // Non-operation
     }
 
-    //
-    // Reply Helpers
-    //
-
-    public WriteFuture reply(final MessageSupport msg) {
+    public WriteFuture reply(final Message msg) {
         assert msg != null;
 
         IoSession session = getSession();
@@ -176,10 +172,6 @@
         
         out.putLong(sequence);
     }
-
-    //
-    // Marshal Helpers
-    //
 
     private static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
 

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageType.java Tue Sep 18 08:40:32 2007
@@ -26,12 +26,15 @@
  */
 public enum MessageType
 {
-    ECHO            (EchoMessage.class),
-    HANDSHAKE       (HandShakeMessage.class),
-    OPEN_SHELL      (OpenShellMessage.class),
-    CLOSE_SHELL     (CloseShellMessage.class),
-    EXECUTE         (ExecuteMessage.class),
-    WRITE_STREAM    (WriteStreamMessage.class),
+    ECHO                (EchoMessage.class),
+    HANDSHAKE           (HandShakeMessage.class),
+    HANDSHAKE_RESULT    (HandShakeMessage.Result.class),
+    LOGIN               (LoginMessage.class),
+    LOGIN_RESULT        (LoginMessage.Result.class),
+    OPEN_SHELL          (OpenShellMessage.class),
+    CLOSE_SHELL         (CloseShellMessage.class),
+    EXECUTE             (ExecuteMessage.class),
+    WRITE_STREAM        (WriteStreamMessage.class),
     ;
 
     private final Class<? extends Message> type;

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitor.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitor.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitor.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitor.java Tue Sep 18 08:40:32 2007
@@ -28,8 +28,6 @@
 {
     void visitEcho(EchoMessage msg) throws Exception;
 
-    void visitHandShake(HandShakeMessage msg) throws Exception;
-
     void visitOpenShell(OpenShellMessage msg) throws Exception;
 
     void visitCloseShell(CloseShellMessage msg) throws Exception;

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorAdapter.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorAdapter.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorAdapter.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorAdapter.java Tue Sep 18 08:40:32 2007
@@ -29,8 +29,6 @@
 {
     public void visitEcho(EchoMessage msg) throws Exception {}
 
-    public void visitHandShake(HandShakeMessage msg) throws Exception {}
-
     public void visitOpenShell(OpenShellMessage msg) throws Exception {}
 
     public void visitCloseShell(CloseShellMessage msg) throws Exception {}

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorSupport.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorSupport.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorSupport.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/message/MessageVisitorSupport.java Tue Sep 18 08:40:32 2007
@@ -22,9 +22,6 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 
-import org.apache.geronimo.gshell.remote.message.MessageVisitor;
-import org.apache.geronimo.gshell.remote.message.MessageVisitorAdapter;
-import org.apache.geronimo.gshell.remote.message.WriteStreamMessage;
 import org.apache.geronimo.gshell.remote.stream.IoSessionInputStream;
 import org.apache.geronimo.gshell.remote.transport.Transport;
 import org.apache.mina.common.IoSession;

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpProtocolHandler.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpProtocolHandler.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpProtocolHandler.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpProtocolHandler.java Tue Sep 18 08:40:32 2007
@@ -189,6 +189,10 @@
 
         log.info("Message received: {}", obj);
 
+        //
+        // TODO: Need to handle Exception muck, and send faul messages back to clients
+        //
+        
         if (obj instanceof Message) {
             //
             // This is the main protocol action, set the session, freeze the message and

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransportServer.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransportServer.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransportServer.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransportServer.java Tue Sep 18 08:40:32 2007
@@ -25,8 +25,10 @@
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
-import org.apache.geronimo.gshell.remote.transport.TransportServer;
 import org.apache.geronimo.gshell.remote.message.MessageVisitor;
+import org.apache.geronimo.gshell.remote.security.SecurityFilter;
+import org.apache.geronimo.gshell.remote.transport.TransportServer;
+import org.apache.mina.common.DefaultIoFilterChainBuilder;
 import org.apache.mina.transport.socket.nio.SocketAcceptor;
 
 /**
@@ -46,6 +48,8 @@
 
     protected boolean bound;
 
+    private SecurityFilter securityFilter;
+    
     public TcpTransportServer(final URI location) throws Exception {
         assert location != null;
 
@@ -53,6 +57,26 @@
         this.address = new InetSocketAddress(InetAddress.getByName(location.getHost()), location.getPort());
     }
 
+    public URI getLocation() {
+        return location;
+    }
+    
+    //
+    // NOTE: Setters exposed to support Plexus autowire()  Getters exposed to handle state checking.
+    //
+
+    public void setSecurityFilter(final SecurityFilter securityFilter) {
+        this.securityFilter = securityFilter;
+    }
+
+    protected SecurityFilter getSecurityFilter() {
+        if (securityFilter == null) {
+            throw new IllegalStateException("Security filter not bound");
+        }
+        
+        return securityFilter;
+    }
+
     protected synchronized void init() throws Exception {
         ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1);
         acceptor = new SocketAcceptor(Runtime.getRuntime().availableProcessors(), executor);
@@ -66,12 +90,10 @@
 
         configure(acceptor);
 
-        //
-        // TODO: Setup the authentication validation handler filter
-        //
-        
-        // DefaultIoFilterChainBuilder filterChain = service.getFilterChain();
-        // filterChain.addLast("auth", new AuthenticationFilter());
+        DefaultIoFilterChainBuilder filterChain = acceptor.getFilterChain();
+
+        // Install the authentication filter right after the protocol filter
+        filterChain.addAfter(PROTOCOL_FILTER_NAME, SecurityFilter.NAME, getSecurityFilter());
     }
 
     public synchronized void bind() throws Exception {
@@ -92,9 +114,5 @@
         acceptor.unbind();
 
         log.info("Closed");
-    }
-
-    public URI getLocation() {
-        return location;
     }
 }

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransportSupport.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransportSupport.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransportSupport.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-common/src/main/java/org/apache/geronimo/gshell/remote/transport/tcp/TcpTransportSupport.java Tue Sep 18 08:40:32 2007
@@ -22,7 +22,7 @@
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 
 import org.apache.geronimo.gshell.common.tostring.ReflectionToStringBuilder;
-import org.apache.geronimo.gshell.remote.filter.LoggingFilter;
+import org.apache.geronimo.gshell.remote.logging.LoggingFilter;
 import org.apache.geronimo.gshell.remote.message.MessageCodecFactory;
 import org.apache.geronimo.gshell.remote.message.MessageVisitor;
 import org.apache.geronimo.gshell.remote.transport.Transport;
@@ -42,6 +42,10 @@
  */
 public class TcpTransportSupport
 {
+    public static final String PROTOCOL_FILTER_NAME = "protocol";
+
+    public static final String REQRESP_FILTER_NAME = "reqresp";
+
     protected Logger log = LoggerFactory.getLogger(getClass());
 
     private PlexusContainer container;
@@ -50,6 +54,8 @@
 
     private TcpProtocolHandler protocolHandler;
 
+    private MessageCodecFactory codecFactory;
+
     public String toString() {
         return ReflectionToStringBuilder.toString(this);
     }
@@ -65,14 +71,14 @@
         DefaultIoFilterChainBuilder filterChain = service.getFilterChain();
         
         if (log.isDebugEnabled()) {
-            filterChain.addLast("logging", new LoggingFilter());
+            filterChain.addLast(LoggingFilter.NAME, new LoggingFilter());
         }
 
-        filterChain.addLast("protocol", new ProtocolCodecFilter(new MessageCodecFactory()));
+        filterChain.addLast(PROTOCOL_FILTER_NAME, new ProtocolCodecFilter(getMessageCodecFactory()));
 
         ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors());
 
-        filterChain.addLast("reqresp", new RequestResponseFilter(protocolHandler.getResponseInspector(), scheduler));
+        filterChain.addLast(REQRESP_FILTER_NAME, new RequestResponseFilter(handler.getResponseInspector(), scheduler));
     }
 
     //
@@ -80,6 +86,8 @@
     //
 
     public void setMessageVisitor(final MessageVisitor messageVisitor) {
+        assert messageVisitor != null;
+
         log.debug("Using message visitor: {}", messageVisitor);
 
         this.messageVisitor = messageVisitor;
@@ -94,6 +102,8 @@
     }
 
     public void setProtocolHandler(final TcpProtocolHandler protocolHandler) {
+        assert protocolHandler != null;
+
         log.debug("Using protocol handler: {}", protocolHandler);
 
         this.protocolHandler = protocolHandler;
@@ -105,6 +115,22 @@
         }
 
         return protocolHandler;
+    }
+
+    public void setMessageCodecFactory(final MessageCodecFactory codecFactory) {
+        assert codecFactory != null;
+        
+        log.debug("Using codec factory: {}", codecFactory);
+
+        this.codecFactory = codecFactory;
+    }
+
+    protected MessageCodecFactory getMessageCodecFactory() {
+        if (codecFactory == null) {
+            throw new IllegalStateException("Message codec factory not bound");
+        }
+
+        return codecFactory;
     }
 
     //

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShell.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShell.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShell.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RemoteShell.java Tue Sep 18 08:40:32 2007
@@ -66,7 +66,7 @@
     @Requirement
     private IO io;
 
-    private boolean opened;
+    private boolean opened = true;
     
     private void ensureOpened() {
         if (!opened) {
@@ -97,12 +97,9 @@
     }
 
     public void initialize() throws InitializationException {
-        //
-        // FIXME: This won't work as desired, as this shell instance is not yet registered, so if a profile
-        //        tries to run something that needs the shell instance... well, loopsvile.
-        //
-        //        This could be a warning sign that some of this class needs to be split up into smaller bits...
-        //
+        /*
+
+        FIXME: Client needs to request this to be done... ?
 
         try {
             loadProfileScripts();
@@ -110,6 +107,7 @@
         catch (Exception e) {
             throw new InitializationException(e.getMessage(), e);
         }
+        */
     }
 
     //

Modified: geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerMessageVisitor.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerMessageVisitor.java?rev=576955&r1=576954&r2=576955&view=diff
==============================================================================
--- geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerMessageVisitor.java (original)
+++ geronimo/sandbox/gshell/trunk/gshell-remote/gshell-remote-server/src/main/java/org/apache/geronimo/gshell/remote/server/RshServerMessageVisitor.java Tue Sep 18 08:40:32 2007
@@ -20,13 +20,13 @@
 package org.apache.geronimo.gshell.remote.server;
 
 import org.apache.geronimo.gshell.DefaultEnvironment;
+import org.apache.geronimo.gshell.ExitNotification;
 import org.apache.geronimo.gshell.command.IO;
 import org.apache.geronimo.gshell.lookup.EnvironmentLookup;
 import org.apache.geronimo.gshell.lookup.IOLookup;
 import org.apache.geronimo.gshell.remote.message.CloseShellMessage;
 import org.apache.geronimo.gshell.remote.message.EchoMessage;
 import org.apache.geronimo.gshell.remote.message.ExecuteMessage;
-import org.apache.geronimo.gshell.remote.message.HandShakeMessage;
 import org.apache.geronimo.gshell.remote.message.MessageVisitor;
 import org.apache.geronimo.gshell.remote.message.MessageVisitorSupport;
 import org.apache.geronimo.gshell.remote.message.OpenShellMessage;
@@ -46,6 +46,10 @@
 public class RshServerMessageVisitor
     extends MessageVisitorSupport
 {
+    //
+    // TODO: If/when we want to add a state-machine to keep things in order, add server-side here.
+    //
+
     @Requirement
     private PlexusContainer container;
 
@@ -107,18 +111,6 @@
         msg.reply(new EchoMessage(text));
     }
 
-    public void visitHandShake(final HandShakeMessage msg) throws Exception {
-        assert msg != null;
-
-        log.info("HANDSHAKE: {}", msg);
-
-        //
-        // TODO:
-        //
-        
-        msg.reply(new EchoMessage("SUCCESS"));
-    }
-
     public void visitOpenShell(final OpenShellMessage msg) throws Exception {
         assert msg != null;
 
@@ -143,8 +135,10 @@
         setRemoteShell(session, shell);
 
         //
-        // TODO: Send response
+        // TODO: Send a meaningful response
         //
+
+        msg.reply(new EchoMessage("OPEN SHELL SUCCESS"));
     }
 
     public void visitCloseShell(final CloseShellMessage msg) throws Exception {
@@ -161,8 +155,10 @@
         unsetRemoteShell(session);
 
         //
-        // TODO: Send response
+        // TODO: Send a meaningful response
         //
+
+        msg.reply(new EchoMessage("CLOSE SHELL SUCCESS"));
     }
 
     public void visitExecute(final ExecuteMessage msg) throws Exception {
@@ -172,12 +168,23 @@
 
         IoSession session = msg.getSession();
 
-        RemoteShell shell = getRemoteShell(session);
+        try {
+            RemoteShell shell = getRemoteShell(session);
 
-        Object result = msg.execute(shell);
+            Object result = msg.execute(shell);
 
-        //
-        // TODO: Send response
-        //
+            //
+            // TODO: Send response
+            //
+        }
+        catch (ExitNotification n) {
+            //
+            // TODO: Send client message with this detail...
+            //
+
+            log.info("Remote shell requested exit: {}", n);
+            
+            session.close();
+        }
     }
 }