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

svn commit: r891692 - in /mina/sshd/trunk: ./ sshd-core/ sshd-core/src/main/java/org/apache/sshd/ sshd-core/src/main/java/org/apache/sshd/agent/ sshd-core/src/main/java/org/apache/sshd/client/auth/ sshd-core/src/main/java/org/apache/sshd/client/channel...

Author: gnodet
Date: Thu Dec 17 13:33:52 2009
New Revision: 891692

URL: http://svn.apache.org/viewvc?rev=891692&view=rev
Log:
SSHD-8: agent forwarding

The main change in this commit is the switch from mina as the transport mechanism to plain tomcat/apr sockets mostly because the mina apr transport does not support the unix domain sockets.  This allow to interact with the openssh agent on unix platforms, and this also secure the agent correctly.

Added:
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentForwardSupport.java
      - copied, changed from r890679, mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/AgentForwardSupport.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AprLibrary.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/ChannelAgentForwarding.java
      - copied, changed from r890679, mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelAgentForwarding.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java
      - copied, changed from r891619, mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshAgent.java
Removed:
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshAgent.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelAgentForwarding.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/AgentForwardSupport.java
Modified:
    mina/sshd/trunk/pom.xml
    mina/sshd/trunk/sshd-core/pom.xml
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshClient.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentClient.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentLocal.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentServer.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthAgent.java
    mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ForwardingFilter.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/session/ServerSession.java
    mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/AgentTest.java

Modified: mina/sshd/trunk/pom.xml
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/pom.xml?rev=891692&r1=891691&r2=891692&view=diff
==============================================================================
--- mina/sshd/trunk/pom.xml (original)
+++ mina/sshd/trunk/pom.xml Thu Dec 17 13:33:52 2009
@@ -90,6 +90,11 @@
                 <version>2.0.0-RC1</version>
             </dependency>
             <dependency>
+                <groupId>tomcat</groupId>
+                <artifactId>tomcat-apr</artifactId>
+                <version>5.5.23</version>
+            </dependency>
+            <dependency>
                 <groupId>com.jcraft</groupId>
                 <artifactId>jzlib</artifactId>
                 <version>1.0.7</version>

Modified: mina/sshd/trunk/sshd-core/pom.xml
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/pom.xml?rev=891692&r1=891691&r2=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/pom.xml (original)
+++ mina/sshd/trunk/sshd-core/pom.xml Thu Dec 17 13:33:52 2009
@@ -44,6 +44,11 @@
             <artifactId>mina-core</artifactId>
         </dependency>
         <dependency>
+            <groupId>tomcat</groupId>
+            <artifactId>tomcat-apr</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
             <groupId>com.jcraft</groupId>
             <artifactId>jzlib</artifactId>
             <optional>true</optional>
@@ -107,6 +112,7 @@
                         <Import-Package>
                             com.jcraft.jzlib*;resolution:=optional,
                             org.bouncycastle*;resolution:=optional,
+                            org.apache.tomcat.jni*;resolution:=optional,
                             *
                         </Import-Package>
                         <Export-Package>

Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshClient.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshClient.java?rev=891692&r1=891691&r2=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshClient.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshClient.java Thu Dec 17 13:33:52 2009
@@ -21,7 +21,6 @@
 import java.io.*;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
-import java.security.KeyPair;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -32,10 +31,8 @@
 import org.apache.mina.core.future.IoFutureListener;
 import org.apache.mina.core.service.IoConnector;
 import org.apache.mina.transport.socket.nio.NioSocketConnector;
-import org.apache.sshd.agent.AgentClient;
-import org.apache.sshd.agent.AgentServer;
+import org.apache.sshd.agent.ChannelAgentForwarding;
 import org.apache.sshd.client.SessionFactory;
-import org.apache.sshd.client.channel.ChannelAgentForwarding;
 import org.apache.sshd.client.channel.ChannelShell;
 import org.apache.sshd.client.future.ConnectFuture;
 import org.apache.sshd.client.future.DefaultConnectFuture;
@@ -49,7 +46,6 @@
 import org.apache.sshd.common.cipher.BlowfishCBC;
 import org.apache.sshd.common.cipher.TripleDESCBC;
 import org.apache.sshd.common.compression.CompressionNone;
-import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
 import org.apache.sshd.common.mac.HMACMD5;
 import org.apache.sshd.common.mac.HMACMD596;
 import org.apache.sshd.common.mac.HMACSHA1;
@@ -63,7 +59,6 @@
 import org.apache.sshd.common.util.NoCloseInputStream;
 import org.apache.sshd.common.util.NoCloseOutputStream;
 import org.apache.sshd.common.util.SecurityUtils;
-import org.bouncycastle.openssl.PasswordFinder;
 
 /**
  * Entry point for the client side of the SSH protocol.
@@ -305,50 +300,58 @@
         client.start();
 
         try {
-            ClientSession session = client.connect(host, port).await().getSession();
-
-            int ret = ClientSession.WAIT_AUTH;
+            boolean hasKeys = false;
 
-            KeyPair[] keys = null;
             /*
-            AgentServer server = new AgentServer();
-            String authSock = server.start();
-            client.getProperties().put(org.apache.sshd.SshAgent.SSH_AUTHSOCKET_ENV_NAME, authSock);
-
-            List<String> files = new ArrayList<String>();
-            File f = new File(System.getProperty("user.home"), ".ssh/id_dsa");
-            if (f.exists() && f.isFile() && f.canRead()) {
-                files.add(f.getAbsolutePath());
-            }
-            f = new File(System.getProperty("user.home"), ".ssh/id_rsa");
-            if (f.exists() && f.isFile() && f.canRead()) {
-                files.add(f.getAbsolutePath());
-            }
-            try {
-                if (files.size() > 0) {
-                    keys = new FileKeyPairProvider(files.toArray(new String[0]), new PasswordFinder() {
-                        public char[] getPassword() {
-                            try {
-                                System.out.println("Enter password for private key: ");
-                                BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
-                                String password = r.readLine();
-                                return password.toCharArray();
-                            } catch (IOException e) {
-                                return null;
+            String authSock = System.getenv(SshAgent.SSH_AUTHSOCKET_ENV_NAME);
+            if (authSock == null) {
+                KeyPair[] keys = null;
+                AgentServer server = new AgentServer();
+                authSock = server.start();
+                List<String> files = new ArrayList<String>();
+                File f = new File(System.getProperty("user.home"), ".ssh/id_dsa");
+                if (f.exists() && f.isFile() && f.canRead()) {
+                    files.add(f.getAbsolutePath());
+                }
+                f = new File(System.getProperty("user.home"), ".ssh/id_rsa");
+                if (f.exists() && f.isFile() && f.canRead()) {
+                    files.add(f.getAbsolutePath());
+                }
+                try {
+                    if (files.size() > 0) {
+                        keys = new FileKeyPairProvider(files.toArray(new String[0]), new PasswordFinder() {
+                            public char[] getPassword() {
+                                try {
+                                    System.out.println("Enter password for private key: ");
+                                    BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
+                                    String password = r.readLine();
+                                    return password.toCharArray();
+                                } catch (IOException e) {
+                                    return null;
+                                }
                             }
-                        }
-                    }).loadKeys();
+                        }).loadKeys();
+                    }
+                } catch (Exception e) {
                 }
-            } catch (Exception e) {
+                SshAgent agent = new AgentClient(authSock);
+                for (KeyPair key : keys) {
+                    agent.addIdentity(key, "");
+                }
+                agent.close();
             }
-            SshAgent agent = new AgentClient(authSock);
-            for (KeyPair key : keys) {
-                agent.addIdentity(key, "");
+            if (authSock != null) {
+                SshAgent agent = new AgentClient(authSock);
+                hasKeys = agent.getIdentities().size() > 0;
             }
-            agent.close();
+            client.getProperties().put(SshAgent.SSH_AUTHSOCKET_ENV_NAME, authSock);
             */
+
+            ClientSession session = client.connect(host, port).await().getSession();
+            int ret = ClientSession.WAIT_AUTH;
+
             while ((ret & ClientSession.WAIT_AUTH) != 0) {
-                if (keys != null) {
+                if (hasKeys) {
                     session.authAgent(login);
                     ret = session.waitFor(ClientSession.WAIT_AUTH | ClientSession.CLOSED | ClientSession.AUTHED, 0);
                 } else {

Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentClient.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentClient.java?rev=891692&r1=891691&r2=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentClient.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentClient.java Thu Dec 17 13:33:52 2009
@@ -18,20 +18,16 @@
  */
 package org.apache.sshd.agent;
 
-import org.apache.mina.core.buffer.IoBuffer;
-import org.apache.mina.core.future.ConnectFuture;
-import org.apache.mina.core.service.IoConnector;
-import org.apache.mina.core.service.IoHandlerAdapter;
-import org.apache.mina.core.session.IoSession;
-import org.apache.mina.transport.socket.nio.NioSocketConnector;
-import org.apache.sshd.SshAgent;
+import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.util.Buffer;
+import org.apache.tomcat.jni.Local;
+import org.apache.tomcat.jni.Pool;
+import org.apache.tomcat.jni.Socket;
+import org.apache.tomcat.jni.Status;
 
 import java.io.IOException;
 import java.io.InterruptedIOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
 import java.security.KeyPair;
 import java.security.PublicKey;
 import java.util.ArrayList;
@@ -42,46 +38,54 @@
 /**
  * A client for a remote SSH agent
  */
-public class AgentClient implements SshAgent {
+public class AgentClient extends Thread implements SshAgent {
 
-    private IoConnector connector;
-    private SocketAddress address;
-    private ConnectFuture connect;
-    private IoSession session;
-    private Buffer receiveBuffer;
+    private final String authSocket;
+    private final long pool;
+    private final long handle;
+    private final Buffer receiveBuffer;
     private final Queue<Buffer> messages;
+    private boolean closed;
 
-    public AgentClient(String authSocket) {
-        connector = new NioSocketConnector();
-        connector.setHandler(new IoHandlerAdapter() {
-            @Override
-            public void messageReceived(IoSession session, Object message) throws Exception {
-                IoBuffer ioBuffer = (IoBuffer) message;
-                AgentClient.this.messageReceived(ioBuffer);
-            }
-//                @Override
-//                public void sessionClosed(IoSession session) throws Exception {
-//                    close();
-//                }
-        });
-        address = new InetSocketAddress("localhost", Integer.parseInt(authSocket));
-        receiveBuffer = new Buffer();
-        messages = new ArrayBlockingQueue<Buffer>(10);
-        connect = connector.connect(address);
-    }
-
-    protected IoSession getSession() throws Throwable {
-        if (session == null) {
-            connect.await();
-            if (connect.getException() != null) {
-                throw connect.getException();
+    public AgentClient(String authSocket) throws IOException {
+        try {
+            this.authSocket = authSocket;
+            pool = Pool.create(AprLibrary.getInstance().getRootPool());
+            handle = Local.create(authSocket, pool);
+            int result = Local.connect(handle, 0);
+            if (result != Status.APR_SUCCESS) {
+                throwException(result);
             }
-            session = connect.getSession();
+            receiveBuffer = new Buffer();
+            messages = new ArrayBlockingQueue<Buffer>(10);
+            start();
+        } catch (IOException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new SshException(e);
         }
-        return session;
     }
 
-    protected void messageReceived(IoBuffer buffer) throws Exception {
+    public void run() {
+        try {
+            byte[] buf = new byte[1024];
+            while (!closed) {
+                int result = Socket.recv(handle, buf, 0, buf.length);
+                if (result < Status.APR_SUCCESS) {
+                    throwException(result);
+                }
+                messageReceived(new Buffer(buf, 0, result));
+            }
+        } catch (Exception e) {
+            if (!closed) {
+                e.printStackTrace();
+            }
+        } finally {
+            close();
+        }
+    }
+
+    protected void messageReceived(Buffer buffer) throws Exception {
         Buffer message = null;
         synchronized (receiveBuffer) {
             receiveBuffer.putBuffer(buffer);
@@ -164,10 +168,10 @@
     }
 
     public void close() {
-        if (session != null) {
-            session.close(true);
+        if (!closed) {
+            closed = true;
+            Socket.close(handle);
         }
-        connector.dispose();
     }
 
     protected Buffer createBuffer(byte cmd) {
@@ -184,10 +188,10 @@
         buffer.wpos(wpos);
         synchronized (messages) {
             try {
-                IoBuffer buf = IoBuffer.allocate(buffer.available());
-                buf.put(buffer.array(), buffer.rpos(), buffer.available());
-                buf.flip();
-                connect.await().getSession().write(buf);
+                int result = Socket.send(handle, buffer.array(), buffer.rpos(), buffer.available());
+                if (result < Status.APR_SUCCESS) {
+                    throwException(result);
+                }
                 if (messages.isEmpty()) {
                     messages.wait();
                 }
@@ -198,4 +202,15 @@
         }
     }
 
+    /**
+     * transform an APR error number in a more fancy exception
+     * @param code APR error code
+     * @throws java.io.IOException the produced exception for the given APR error number
+     */
+    private void throwException(int code) throws IOException {
+        throw new IOException(
+                org.apache.tomcat.jni.Error.strerror(-code) +
+                " (code: " + code + ")");
+    }
+
 }

Copied: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentForwardSupport.java (from r890679, mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/AgentForwardSupport.java)
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentForwardSupport.java?p2=mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentForwardSupport.java&p1=mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/AgentForwardSupport.java&r1=890679&r2=891692&rev=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/AgentForwardSupport.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentForwardSupport.java Thu Dec 17 13:33:52 2009
@@ -16,106 +16,121 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sshd.server.session;
+package org.apache.sshd.agent;
 
-import org.apache.mina.core.buffer.IoBuffer;
-import org.apache.mina.core.service.IoAcceptor;
-import org.apache.mina.core.service.IoHandlerAdapter;
-import org.apache.mina.core.session.IoEventType;
-import org.apache.mina.core.session.IoSession;
-import org.apache.mina.filter.executor.ExecutorFilter;
-import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
 import org.apache.sshd.client.channel.AbstractClientChannel;
-import org.apache.sshd.client.future.DefaultOpenFuture;
 import org.apache.sshd.client.future.OpenFuture;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.channel.ChannelOutputStream;
-import org.apache.sshd.common.util.Buffer;
-import org.apache.sshd.server.TcpIpForwardFilter;
+import org.apache.sshd.server.session.ServerSession;
+import org.apache.tomcat.jni.Local;
+import org.apache.tomcat.jni.Pool;
+import org.apache.tomcat.jni.Socket;
+import org.apache.tomcat.jni.Status;
 
 import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.EnumSet;
-import java.util.Set;
 
 /**
  * The server side fake agent, acting as an agent, but actually forwarding the requests to the auth channel on the client side.
  */
-public class AgentForwardSupport extends IoHandlerAdapter {
+public class AgentForwardSupport {
 
     private final ServerSession session;
-    private IoAcceptor acceptor;
+    private String authSocket;
+    private long pool;
+    private long handle;
+    private Thread thread;
+    private boolean closed;
 
     public AgentForwardSupport(ServerSession session) {
         this.session = session;
     }
 
-    public synchronized int initialize() throws IOException {
-        if (this.acceptor == null) {
-            NioSocketAcceptor acceptor = new NioSocketAcceptor();
-            acceptor.setHandler(this);
-            acceptor.setReuseAddress(true);
-            acceptor.getFilterChain().addLast("executor", new ExecutorFilter(EnumSet.complementOf(EnumSet.of(IoEventType.SESSION_CREATED)).toArray(new IoEventType[0])));
-            this.acceptor = acceptor;
-            SocketAddress address = new InetSocketAddress("localhost", 0);
-            acceptor.bind(address);
+    public synchronized String initialize() throws IOException {
+        try {
+            if (authSocket == null) {
+                String authSocket = AprLibrary.createLocalSocketAddress();
+                pool = Pool.create(AprLibrary.getInstance().getRootPool());
+                handle = Local.create(authSocket, pool);
+                int result = Local.bind(handle, 0);
+                if (result != Status.APR_SUCCESS) {
+                    throwException(result);
+                }
+                AprLibrary.secureLocalSocket(authSocket, handle);
+                result = Local.listen(handle, 0);
+                if (result != Status.APR_SUCCESS) {
+                    throwException(result);
+                }
+                thread = new Thread() {
+                    public void run() {
+                        while (!closed) {
+                            try {
+                                long clientSock = Local.accept(handle);
+                                if (closed) {
+                                    break;
+                                }
+                                Socket.timeoutSet(clientSock, 10000000);
+                                AgentForwardedChannel channel = new AgentForwardedChannel(clientSock);
+                                AgentForwardSupport.this.session.registerChannel(channel);
+                                OpenFuture future = channel.open().await();
+                                Throwable t = future.getException();
+                                if (t instanceof Exception) {
+                                    throw (Exception) t;
+                                } else if (t != null) {
+                                    throw new Exception(t);
+                                }
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                };
+                thread.start();
+                this.authSocket = authSocket;
+            }
+            return authSocket;
+        } catch (IOException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new SshException(e);
         }
-        return ((InetSocketAddress) acceptor.getLocalAddress()).getPort();
     }
 
     public synchronized void close() {
-        if (acceptor != null) {
-            acceptor.dispose();
-            acceptor = null;
+        closed = true;
+        if (handle != 0) {
+            Socket.close(handle);
         }
     }
 
-    @Override
-    public void sessionCreated(IoSession session) throws Exception {
-        AgentForwardedChannel channel = new AgentForwardedChannel(session);
-        session.setAttribute(AgentForwardedChannel.class, channel);
-        this.session.registerChannel(channel);
-        OpenFuture future = channel.open().await();
-        Throwable t = future.getException();
-        if (t instanceof Exception) {
-            throw (Exception) t;
-        } else if (t != null) {
-            throw new Exception(t);
-        }
-    }
-
-    @Override
-    public void sessionClosed(IoSession session) throws Exception {
-        AgentForwardedChannel channel = (AgentForwardedChannel) session.getAttribute(AgentForwardedChannel.class);
-        channel.close(false);
-    }
-
-    @Override
-    public void messageReceived(IoSession session, Object message) throws Exception {
-        AgentForwardedChannel channel = (AgentForwardedChannel) session.getAttribute(AgentForwardedChannel.class);
-        IoBuffer ioBuffer = (IoBuffer) message;
-        int r = ioBuffer.remaining();
-        byte[] b = new byte[r];
-        ioBuffer.get(b, 0, r);
-        channel.getOut().write(b, 0, r);
-        channel.getOut().flush();
-    }
-
-    @Override
-    public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
-        cause.printStackTrace();
-        session.close(false);
-    }
+    public static class AgentForwardedChannel extends AbstractClientChannel implements Runnable {
 
-    public static class AgentForwardedChannel extends AbstractClientChannel {
+        private final long socket;
 
-        private final IoSession serverSession;
-
-        public AgentForwardedChannel(IoSession serverSession) {
+        public AgentForwardedChannel(long socket) {
             super("auth-agent@openssh.com");
-            this.serverSession = serverSession;
+            this.socket = socket;
+        }
+
+        public void run() {
+            try {
+                byte[] buf = new byte[1024];
+                while (true) {
+                    int result = Socket.recv(socket, buf, 0, buf.length);
+                    if (result == Status.APR_EOF) {
+                        break;
+                    } else if (result < Status.APR_SUCCESS) {
+                        throwException(result);
+                    }
+                    getOut().write(buf, 0, result);
+                    getOut().flush();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                close(false);
+            }
         }
 
         public synchronized OpenFuture open() throws Exception {
@@ -129,23 +144,30 @@
 
         @Override
         protected synchronized void doClose() {
-            serverSession.close(false);
+            Socket.close(socket);
             super.doClose();
         }
 
         protected synchronized void doWriteData(byte[] data, int off, int len) throws IOException {
-            IoBuffer buf = IoBuffer.allocate(len);
-            buf.put(data, off, len);
-            buf.flip();
             localWindow.consumeAndCheck(len);
-            serverSession.write(buf);
-        }
+            int result = Socket.send(socket, data, off, len);
+            if (result < Status.APR_SUCCESS) {
+                throwException(result);
+            }
 
-        @Override
-        public void handleEof() throws IOException {
-            super.handleEof();
-            serverSession.close(false);
         }
+
+    }
+
+    /**
+     * transform an APR error number in a more fancy exception
+     * @param code APR error code
+     * @throws java.io.IOException the produced exception for the given APR error number
+     */
+    private static void throwException(int code) throws IOException {
+        throw new IOException(
+                org.apache.tomcat.jni.Error.strerror(-code) +
+                " (code: " + code + ")");
     }
 
 }

Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentLocal.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentLocal.java?rev=891692&r1=891691&r2=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentLocal.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentLocal.java Thu Dec 17 13:33:52 2009
@@ -18,7 +18,6 @@
  */
 package org.apache.sshd.agent;
 
-import org.apache.sshd.SshAgent;
 import org.apache.sshd.common.Signature;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.signature.SignatureDSA;

Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentServer.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentServer.java?rev=891692&r1=891691&r2=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentServer.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AgentServer.java Thu Dec 17 13:33:52 2009
@@ -18,18 +18,14 @@
  */
 package org.apache.sshd.agent;
 
-import org.apache.mina.core.buffer.IoBuffer;
-import org.apache.mina.core.service.IoAcceptor;
-import org.apache.mina.core.service.IoHandlerAdapter;
-import org.apache.mina.core.session.IoSession;
-import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
-import org.apache.sshd.SshAgent;
 import org.apache.sshd.common.KeyPairProvider;
 import org.apache.sshd.common.util.Buffer;
+import org.apache.tomcat.jni.Local;
+import org.apache.tomcat.jni.Pool;
+import org.apache.tomcat.jni.Socket;
+import org.apache.tomcat.jni.Status;
 
 import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
 import java.security.KeyPair;
 import java.security.PublicKey;
 import java.security.interfaces.RSAPublicKey;
@@ -51,32 +47,44 @@
     static final byte SSH2_AGENT_FAILURE = 30;
 
     private final SshAgent engine = new AgentLocal();
-    private IoAcceptor acceptor;
-    private SocketAddress address;
-
+    private String authSocket;
+    private long pool;
+    private long handle;
+    private Thread thread;
 
     public String start() throws Exception {
-        acceptor = new NioSocketAcceptor();
-        acceptor.setHandler(new IoHandlerAdapter() {
-            @Override
-            public void sessionCreated(IoSession session) throws Exception {
-                SshAgentSession s = new SshAgentSession(session, engine);
-                session.setAttribute(SshAgentSession.class, s);
-            }
-            @Override
-            public void messageReceived(IoSession session, Object message) throws Exception {
-                SshAgentSession s = (SshAgentSession) session.getAttribute(SshAgentSession.class);
-                s.messageReceived(message);
-            }
-        });
-        acceptor.bind(new InetSocketAddress("localhost", 0));
-        address = acceptor.getLocalAddress();
-        return Integer.toString(((InetSocketAddress) address).getPort());
+        authSocket = AprLibrary.createLocalSocketAddress();
+        pool = Pool.create(AprLibrary.getInstance().getRootPool());
+        handle = Local.create(authSocket, pool);
+        int result = Local.bind(handle, 0);
+        if (result != Status.APR_SUCCESS) {
+            throwException(result);
+        }
+        AprLibrary.secureLocalSocket(authSocket, handle);
+        result = Local.listen(handle, 0);
+        if (result != Status.APR_SUCCESS) {
+            throwException(result);
+        }
+        thread = new Thread() {
+            public void run() {
+                try {
+                    while (true) {
+                        long clientSock = Local.accept(handle);
+                        Socket.timeoutSet(clientSock, 10000000);
+                        new SshAgentSession(clientSock, engine).start();
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        };
+        thread.start();
+        return authSocket;
     }
 
     public void close() {
         engine.close();
-        acceptor.dispose();
+        Socket.close(handle);
     }
 
     public List<Pair<PublicKey, String>> getIdentities() throws IOException {
@@ -99,20 +107,38 @@
         engine.removeAllIdentities();
     }
 
-    protected static class SshAgentSession {
+    protected static class SshAgentSession extends Thread {
 
-        private final IoSession session;
+        private final long socket;
         private final SshAgent engine;
         private final Buffer buffer = new Buffer();
 
-        public SshAgentSession(IoSession session, SshAgent engine) {
-            this.session = session;
+        public SshAgentSession(long socket, SshAgent engine) {
+            this.socket = socket;
             this.engine = engine;
         }
 
-        public synchronized void messageReceived(Object message) throws Exception {
-            IoBuffer ioBuffer = (IoBuffer) message;
-            buffer.putBuffer(ioBuffer);
+        public void run() {
+            try {
+                byte[] buf = new byte[1024];
+                while (true) {
+                    int result = Socket.recv(socket, buf, 0, buf.length);
+                    if (result == Status.APR_EOF) {
+                        break;    
+                    } else if (result < Status.APR_SUCCESS) {
+                        throwException(result);
+                    }
+                    messageReceived(new Buffer(buf, 0, result));
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            } finally {
+                Socket.close(socket);
+            }
+        }
+
+        public synchronized void messageReceived(Buffer message) throws Exception {
+            buffer.putBuffer(message);
             if (buffer.available() < 4) {
                 return;
             }
@@ -196,12 +222,23 @@
             buf.wpos(rpos - 4);
             buf.putInt(len);
             buf.wpos(wpos);
-            IoBuffer b = IoBuffer.allocate(buf.available());
-            b.put(buf.array(), buf.rpos(), buf.available());
-            b.flip();
-            session.write(b);
+            int result = Socket.send(socket, buf.array(), buf.rpos(), buf.available());
+            if (result < Status.APR_SUCCESS) {
+                throwException(result);
+            }
         }
 
     }
 
+    /**
+     * transform an APR error number in a more fancy exception
+     * @param code APR error code
+     * @throws java.io.IOException the produced exception for the given APR error number
+     */
+    private static void throwException(int code) throws IOException {
+        throw new IOException(
+                org.apache.tomcat.jni.Error.strerror(-code) +
+                " (code: " + code + ")");
+    }
+
 }

Added: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AprLibrary.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AprLibrary.java?rev=891692&view=auto
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AprLibrary.java (added)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/AprLibrary.java Thu Dec 17 13:33:52 2009
@@ -0,0 +1,135 @@
+/*
+ *  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.agent;
+
+import org.apache.tomcat.jni.Library;
+import org.apache.tomcat.jni.Pool;
+
+import java.io.File;
+import java.io.IOException;
+
+
+/**
+ * Internal singleton used for initializing correctly the APR native library
+ * and the associated root memory pool.
+ *
+ * It'll finalize nicely the native resources (libraries and memory pools).
+ *
+ * Each memory pool used in the APR transport module needs to be children of the
+ * root pool {@link AprLibrary#getRootPool()}.
+ *
+ * @author <a href="http://mina.apache.org">Apache MINA Project</a>
+ */
+class AprLibrary {
+
+    // is APR library was initialized (load of native libraries)
+    private static AprLibrary library = null;
+
+    /**
+     * get the shared instance of APR library, if none, initialize one
+     * @return the current APR library singleton
+     */
+    static synchronized AprLibrary getInstance() {
+        if (!isInitialized())
+            initialize();
+        return library;
+    }
+
+    /**
+     * initialize the APR Library by loading the associated native libraries
+     * and creating the associated singleton
+     */
+    private static synchronized void initialize() {
+        if (library == null)
+            library = new AprLibrary();
+    }
+
+    /**
+     * is the APR library was initialized.
+     * @return true if the Library is initialized, false otherwise
+     */
+    static synchronized boolean isInitialized() {
+        return library != null;
+    }
+
+    // APR memory pool (package wide mother pool)
+    private final long pool;
+
+    /**
+     * APR library singleton constructor. Called only when accessing the
+     * singleton the first time.
+     * It's initializing an APR memory pool for the whole package (a.k.a mother or root pool).
+     */
+    private AprLibrary() {
+        try {
+            Library.initialize(null);
+        } catch (Exception e) {
+            throw new RuntimeException(
+                    "Error loading Apache Portable Runtime (APR).", e);
+        }
+        pool = Pool.create(0);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        library = null;
+        Pool.destroy(pool);
+        Library.terminate();
+        super.finalize();
+    }
+
+    /**
+     * get the package wide root pool, the mother of all the pool created
+     * in APR transport module.
+     * @return number identifying the root pool
+     */
+    long getRootPool() {
+        return pool;
+    }
+
+    static String createLocalSocketAddress() throws IOException {
+        String name;
+        String os = System.getProperty("os.name").toLowerCase();
+        if (os.indexOf("windows") < 0) {
+            File socket = File.createTempFile("mina", "apr");
+            socket.delete();
+            name = socket.getAbsolutePath();
+        } else {
+            File socket = File.createTempFile("mina", "apr");
+            socket.delete();
+            name = "\\\\.\\pipe\\" + socket.getName();
+        }
+        return name;
+    }
+
+    static void secureLocalSocket(String authSocket, long handle) throws IOException {
+        String os = System.getProperty("os.name").toLowerCase();
+        if (os.indexOf("windows") < 0) {
+            File file = new File(authSocket);
+            if (!file.setReadable(false, false) || !file.setReadable(true, true)
+                    || !file.setExecutable(false, false) || !file.setExecutable(true, true)) {
+                throw new IOException("Unable to secure local socket");
+            }
+
+        } else {
+            // should be ok on windows
+        }
+    }
+}

Copied: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/ChannelAgentForwarding.java (from r890679, mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelAgentForwarding.java)
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/ChannelAgentForwarding.java?p2=mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/ChannelAgentForwarding.java&p1=mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelAgentForwarding.java&r1=890679&r2=891692&rev=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelAgentForwarding.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/ChannelAgentForwarding.java Thu Dec 17 13:33:52 2009
@@ -16,42 +16,26 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sshd.client.channel;
+package org.apache.sshd.agent;
 
-import org.apache.mina.core.buffer.IoBuffer;
-import org.apache.mina.core.future.ConnectFuture;
-import org.apache.mina.core.future.IoFutureListener;
-import org.apache.mina.core.service.IoConnector;
-import org.apache.mina.core.service.IoHandler;
-import org.apache.mina.core.service.IoHandlerAdapter;
-import org.apache.mina.core.session.IoSession;
-import org.apache.mina.transport.socket.nio.NioSocketConnector;
-import org.apache.mina.transport.vmpipe.VmPipeAddress;
-import org.apache.mina.transport.vmpipe.VmPipeConnector;
-import org.apache.sshd.SshAgent;
 import org.apache.sshd.client.future.DefaultOpenFuture;
 import org.apache.sshd.client.future.OpenFuture;
 import org.apache.sshd.common.Channel;
-import org.apache.sshd.common.Mac;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.SshConstants;
-import org.apache.sshd.common.channel.AbstractChannel;
 import org.apache.sshd.common.channel.ChannelOutputStream;
 import org.apache.sshd.common.future.CloseFuture;
 import org.apache.sshd.common.future.SshFuture;
 import org.apache.sshd.common.future.SshFutureListener;
 import org.apache.sshd.common.util.Buffer;
-import org.apache.sshd.common.util.BufferUtils;
-import org.apache.sshd.server.TcpIpForwardFilter;
 import org.apache.sshd.server.channel.AbstractServerChannel;
-import org.apache.sshd.server.channel.OpenChannelException;
-import org.apache.sshd.server.session.ServerSession;
+import org.apache.tomcat.jni.Local;
+import org.apache.tomcat.jni.Pool;
+import org.apache.tomcat.jni.Socket;
+import org.apache.tomcat.jni.Status;
 
 import java.io.IOException;
 import java.io.OutputStream;
-import java.net.ConnectException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
 
 /**
  * The client side channel that will receive requests forwards by the SSH server.
@@ -69,9 +53,10 @@
         }
     }
 
-    private IoConnector connector;
-    private SocketAddress address;
-    private IoSession ioSession;
+    private String authSocket;
+    private long pool;
+    private long handle;
+    private Thread thread;
     private OutputStream out;
 
     public ChannelAgentForwarding() {
@@ -79,46 +64,37 @@
 
     protected OpenFuture doInit(Buffer buffer) {
         final OpenFuture f = new DefaultOpenFuture(this);
-
-        createConnectorAndAddress();
-
-        out = new ChannelOutputStream(this, remoteWindow, log, SshConstants.Message.SSH_MSG_CHANNEL_DATA);
-        IoHandler handler = new IoHandlerAdapter() {
-            @Override
-            public void messageReceived(IoSession session, Object message) throws Exception {
-                IoBuffer ioBuffer = (IoBuffer) message;
-                int r = ioBuffer.remaining();
-                byte[] b = new byte[r];
-                ioBuffer.get(b, 0, r);
-                out.write(b, 0, r);
-                out.flush();
-            }
-
-            @Override
-            public void sessionClosed(IoSession session) throws Exception {
-                sendEof();
+        try {
+            out = new ChannelOutputStream(this, remoteWindow, log, SshConstants.Message.SSH_MSG_CHANNEL_DATA);
+            authSocket = session.getFactoryManager().getProperties().get(SshAgent.SSH_AUTHSOCKET_ENV_NAME);
+            pool = Pool.create(AprLibrary.getInstance().getRootPool());
+            handle = Local.create(authSocket, pool);
+            int result = Local.connect(handle, 0);
+            if (result != Status.APR_SUCCESS) {
+                throwException(result);
             }
-        };
-        connector.setHandler(handler);
-        ConnectFuture future = connector.connect(address);
-        future.addListener(new IoFutureListener<ConnectFuture>() {
-            public void operationComplete(ConnectFuture future) {
-                if (future.isConnected()) {
-                    ioSession = future.getSession();
-                    f.setOpened();
-                } else if (future.getException() != null) {
-                    closeImmediately0();
-                    if (future.getException() instanceof ConnectException) {
-                        f.setException(new OpenChannelException(
-                            SshConstants.SSH_OPEN_CONNECT_FAILED,
-                            future.getException().getMessage(),
-                            future.getException()));
-                    } else {
-                        f.setException(future.getException());
+            thread = new Thread() {
+                public void run() {
+                    try {
+                        byte[] buf = new byte[1024];
+                        while (true) {
+                            int len = Socket.recv(handle, buf, 0, buf.length);
+                            if (len > 0) {
+                                out.write(buf, 0, len);
+                                out.flush();
+                            }
+                        }
+                    } catch (IOException e) {
+                        close(true);
                     }
                 }
-            }
-        });
+            };
+            thread.start();
+            f.setOpened();
+
+        } catch (Exception e) {
+            f.setException(e);
+        }
         return f;
     }
 
@@ -130,18 +106,9 @@
         //
         super.close(true);
 
-        // We also need to dispose of the connector, but unfortunately we
-        // are being invoked by the connector thread or the connector's
-        // own processor thread.  Disposing of the connector within either
-        // causes deadlock.  Instead create a new thread to dispose of the
-        // connector in the background.
+        // We also need to close the socket.
         //
-        new Thread("AgentForward-ConnectorCleanup") {
-            @Override
-            public void run() {
-                connector.dispose();
-            }
-        }.start();
+        Socket.close(handle);
     }
 
     public CloseFuture close(boolean immediately) {
@@ -159,10 +126,10 @@
     }
 
     protected void doWriteData(byte[] data, int off, int len) throws IOException {
-        IoBuffer buf = IoBuffer.allocate(len);
-        buf.put(data, off, len);
-        buf.flip();
-        ioSession.write(buf);
+        int result = Socket.send(handle, data, off, len);
+        if (result < Status.APR_SUCCESS) {
+            throwException(result);
+        }
     }
 
     protected void doWriteExtendedData(byte[] data, int off, int len) throws IOException {
@@ -178,10 +145,14 @@
         session.writePacket(buffer);
     }
 
-    protected void createConnectorAndAddress() {
-        String authSocket = session.getFactoryManager().getProperties().get(SshAgent.SSH_AUTHSOCKET_ENV_NAME);
-        connector = new NioSocketConnector();
-        address = new InetSocketAddress("localhost", Integer.parseInt(authSocket));
+    /**
+     * transform an APR error number in a more fancy exception
+     * @param code APR error code
+     * @throws java.io.IOException the produced exception for the given APR error number
+     */
+    private void throwException(int code) throws IOException {
+        throw new IOException(
+                org.apache.tomcat.jni.Error.strerror(-code) +
+                " (code: " + code + ")");
     }
-
 }

Copied: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java (from r891619, mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshAgent.java)
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java?p2=mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java&p1=mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshAgent.java&r1=891619&r2=891692&rev=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/SshAgent.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java Thu Dec 17 13:33:52 2009
@@ -16,32 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sshd;
-
-import org.apache.mina.core.buffer.IoBuffer;
-import org.apache.mina.core.future.ConnectFuture;
-import org.apache.mina.core.service.IoAcceptor;
-import org.apache.mina.core.service.IoConnector;
-import org.apache.mina.core.service.IoHandlerAdapter;
-import org.apache.mina.core.session.IoSession;
-import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
-import org.apache.mina.transport.socket.nio.NioSocketConnector;
-import org.apache.sshd.common.*;
-import org.apache.sshd.common.signature.SignatureDSA;
-import org.apache.sshd.common.signature.SignatureRSA;
-import org.apache.sshd.common.util.Buffer;
+package org.apache.sshd.agent;
 
 import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
 import java.security.KeyPair;
 import java.security.PublicKey;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.RSAPublicKey;
-import java.util.*;
-import java.util.concurrent.ArrayBlockingQueue;
+import java.util.List;
 
 /**
  * SSH key agent server

Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthAgent.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthAgent.java?rev=891692&r1=891691&r2=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthAgent.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthAgent.java Thu Dec 17 13:33:52 2009
@@ -18,9 +18,8 @@
  */
 package org.apache.sshd.client.auth;
 
-import org.apache.sshd.SshAgent;
+import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.AgentClient;
-import org.apache.sshd.agent.AgentServer;
 import org.apache.sshd.client.UserAuth;
 import org.apache.sshd.client.session.ClientSessionImpl;
 import org.apache.sshd.common.KeyPairProvider;
@@ -49,7 +48,7 @@
     public UserAuthAgent(ClientSessionImpl session, String username) throws IOException {
         this.session = session;
         this.username = username;
-        String authSocket = session.getFactoryManager().getProperties().get(org.apache.sshd.SshAgent.SSH_AUTHSOCKET_ENV_NAME);
+        String authSocket = session.getFactoryManager().getProperties().get(SshAgent.SSH_AUTHSOCKET_ENV_NAME);
         SshAgent agent = new AgentClient(authSocket);
         this.agent = agent;
         keys = agent.getIdentities().iterator();

Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ForwardingFilter.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ForwardingFilter.java?rev=891692&r1=891691&r2=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ForwardingFilter.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/ForwardingFilter.java Thu Dec 17 13:33:52 2009
@@ -18,7 +18,7 @@
  */
 package org.apache.sshd.server;
 
-import org.apache.sshd.SshAgent;
+import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.server.session.ServerSession;
 
 import java.net.InetSocketAddress;

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=891692&r1=891691&r2=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java Thu Dec 17 13:33:52 2009
@@ -28,7 +28,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArraySet;
 
-import org.apache.sshd.SshAgent;
+import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.common.Channel;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.PtyMode;
@@ -378,6 +378,9 @@
         if (((ServerSession) session).getServerFactoryManager().getCommandFactory() == null) {
             return false;
         }
+        if (log.isInfoEnabled()) {
+            log.info("Executing command: {}", commandLine);
+        }
         try {
             command = ((ServerSession) session).getServerFactoryManager().getCommandFactory().createCommand(commandLine);
         } catch (IllegalArgumentException iae) {
@@ -470,8 +473,8 @@
             return true;
         }
 
-        int authSocket = server.initAgentForward();
-        addEnvVariable(SshAgent.SSH_AUTHSOCKET_ENV_NAME, Integer.toString(authSocket));
+        String authSocket = ((ServerSession) session).initAgentForward();
+        addEnvVariable(SshAgent.SSH_AUTHSOCKET_ENV_NAME, authSocket);
 
         if (wantReply) {
             buffer = session.createBuffer(SshConstants.Message.SSH_MSG_CHANNEL_SUCCESS, 0);

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=891692&r1=891691&r2=891692&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 Thu Dec 17 13:33:52 2009
@@ -47,6 +47,7 @@
     protected static final int OK = 0;
     protected static final int ERROR = 2;
 
+    protected String name;
     protected boolean optR;
     protected boolean optT;
     protected boolean optF;
@@ -60,8 +61,9 @@
     protected IOException error;
 
     public ScpCommand(String[] args) {
+        name = Arrays.asList(args).toString();
         if (log.isDebugEnabled()) {
-            log.debug("Executing command {}", Arrays.asList(args));
+            log.debug("Executing command {}", name);
         }
         root = new File(".");
         for (int i = 1; i < args.length; i++) {
@@ -117,7 +119,7 @@
         if (error != null) {
             throw error;
         }
-        new Thread(this).start();
+        new Thread(this, "ScpCommand: " + name).start();
     }
 
     public void destroy() {
@@ -238,6 +240,11 @@
         } else {
             throw new IOException("Can not write to " + path);
         }
+        if (file.exists() && file.isDirectory()) {
+            throw new IOException("File is a directory: " + file);
+        } else if (file.exists() && !file.canWrite()) {
+            throw new IOException("Can not write to file: " + file);
+        }
         OutputStream os = new FileOutputStream(file);
         try {
             ack();

Modified: mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java?rev=891692&r1=891691&r2=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java (original)
+++ mina/sshd/trunk/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java Thu Dec 17 13:33:52 2009
@@ -26,6 +26,7 @@
 import java.util.TimerTask;
 
 import org.apache.mina.core.session.IoSession;
+import org.apache.sshd.agent.AgentForwardSupport;
 import org.apache.sshd.client.future.OpenFuture;
 import org.apache.sshd.common.Channel;
 import org.apache.sshd.common.FactoryManager;
@@ -455,7 +456,7 @@
         }
     }
 
-    public int initAgentForward() throws IOException {
+    public String initAgentForward() throws IOException {
         return agentForward.initialize();
     }
 

Modified: mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/AgentTest.java
URL: http://svn.apache.org/viewvc/mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/AgentTest.java?rev=891692&r1=891691&r2=891692&view=diff
==============================================================================
--- mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/AgentTest.java (original)
+++ mina/sshd/trunk/sshd-core/src/test/java/org/apache/sshd/AgentTest.java Thu Dec 17 13:33:52 2009
@@ -20,6 +20,7 @@
 
 import org.apache.sshd.agent.AgentClient;
 import org.apache.sshd.agent.AgentServer;
+import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
 import org.junit.Test;