[SSHD-700 Added support for Secure Shell Authentication Agent Protocol Draft 02

* See https://tools.ietf.org/html/draft-ietf-secsh-agent-02


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/dd299ae7
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/dd299ae7
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/dd299ae7

Branch: refs/heads/master
Commit: dd299ae7aca4d1073a97756372ab0a1af851d852
Parents: 008f1b6
Author: Lyor Goldstein <[email protected]>
Authored: Sat Oct 1 16:09:26 2016 +0300
Committer: Lyor Goldstein <[email protected]>
Committed: Sat Oct 1 16:09:26 2016 +0300

----------------------------------------------------------------------
 .../org/apache/sshd/agent/SshAgentFactory.java  | 14 +++++-
 .../org/apache/sshd/agent/SshAgentServer.java   | 11 ++++-
 .../sshd/agent/local/AgentForwardedChannel.java |  5 +--
 .../sshd/agent/local/AgentServerProxy.java      |  7 ++-
 .../local/ChannelAgentForwardingFactory.java    | 13 ++++--
 .../sshd/agent/local/LocalAgentFactory.java     | 10 ++++-
 .../sshd/agent/local/ProxyAgentFactory.java     |  7 +--
 .../sshd/agent/unix/AgentForwardedChannel.java  |  4 +-
 .../sshd/agent/unix/AgentServerProxy.java       |  3 +-
 .../org/apache/sshd/agent/unix/AprLibrary.java  |  6 +--
 .../unix/ChannelAgentForwardingFactory.java     | 13 ++++--
 .../sshd/agent/unix/UnixAgentFactory.java       | 46 ++++++++++++++------
 .../java/org/apache/sshd/client/SshClient.java  | 15 ++++---
 .../channel/PtyCapableChannelSession.java       |  5 ++-
 .../sshd/server/channel/ChannelSession.java     | 31 ++++++-------
 .../sshd/server/forward/ForwardingFilter.java   |  6 ++-
 .../forward/StaticDecisionForwardingFilter.java |  8 ++--
 .../java/org/apache/sshd/agent/AgentTest.java   | 39 +++++++++--------
 .../sshd/common/ForwardingFilterTest.java       |  4 +-
 19 files changed, 158 insertions(+), 89 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentFactory.java 
b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentFactory.java
index 8176230..551d14d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentFactory.java
@@ -19,6 +19,7 @@
 package org.apache.sshd.agent;
 
 import java.io.IOException;
+import java.util.List;
 
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.NamedFactory;
@@ -29,15 +30,24 @@ import org.apache.sshd.common.session.ConnectionService;
  * The <code>SshAgentFactory</code> is used to communicate with an SshAgent.
  */
 public interface SshAgentFactory {
+    /**
+     * Value that can be set in order to control the type of authentication
+     * channel being requested when forwarding a PTY session. If not defined
+     * then {@link #DEFAULT_PROXY_AUTH_CHANNEL_TYPE} is used
+     */
+    String PROXY_AUTH_CHANNEL_TYPE = 
"ssh-agent-factory-proxy-auth-channel-type";
+    // see also https://tools.ietf.org/html/draft-ietf-secsh-agent-02
+    String DEFAULT_PROXY_AUTH_CHANNEL_TYPE = "[email protected]";
 
     /**
      * The channels are requested by the ssh server when forwarding a client 
request.
      * The channel will receive agent requests and need to forward them to the 
agent,
      * either local or through another proxy.
      *
-     * @return The (named) channel factory used to create channels on the 
client side
+     * @param manager The {@link FactoryManager} through which the request is 
made
+     * @return The (named) channel factories used to create channels on the 
client side
      */
-    NamedFactory<Channel> getChannelForwardingFactory();
+    List<NamedFactory<Channel>> getChannelForwardingFactories(FactoryManager 
manager);
 
     /**
      * Create an SshAgent that can be used on the client side by the 
authentication

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentServer.java 
b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentServer.java
index 1cb5cb9..4ff5de3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentServer.java
@@ -25,7 +25,7 @@ public interface SshAgentServer extends Channel {
 
     /**
      * Value that can be set on the {@link 
org.apache.sshd.common.FactoryManager}
-     * to configure the channel open timeout value (millis). If not specified
+     * or the session to configure the channel open timeout value (millis). If 
not specified
      * then {@link #DEFAULT_CHANNEL_OPEN_TIMEOUT} value is used
      */
     String CHANNEL_OPEN_TIMEOUT_PROP = "ssh-agent-server-channel-open-timeout";
@@ -33,6 +33,15 @@ public interface SshAgentServer extends Channel {
     long DEFAULT_CHANNEL_OPEN_TIMEOUT = TimeUnit.SECONDS.toMillis(30L);
 
     /**
+     * Value used to configure the type of proxy forwarding channel to be
+     * used. If not specified, then {@link #DEFAULT_PROXY_CHANNEL_TYPE}
+     * is used
+     */
+    String PROXY_CHANNEL_TYPE = "ssh-agent-server-channel-proxy-type";
+    // see also https://tools.ietf.org/html/draft-ietf-secsh-agent-02
+    String DEFAULT_PROXY_CHANNEL_TYPE = "[email protected]";
+
+    /**
      * @return Agent server identifier
      */
     String getId();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
 
b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
index 18ae890..355856a 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
@@ -36,12 +36,11 @@ import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 
 public class AgentForwardedChannel extends AbstractClientChannel {
-
     private final Queue<Buffer> messages = new ArrayBlockingQueue<>(10);
     private final Buffer receiveBuffer = new ByteArrayBuffer();
 
-    public AgentForwardedChannel() {
-        super("[email protected]");
+    public AgentForwardedChannel(String channelType) {
+        super(channelType);
     }
 
     public SshAgent getAgent() {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentServerProxy.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentServerProxy.java 
b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentServerProxy.java
index a21a976..967fc5a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentServerProxy.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentServerProxy.java
@@ -26,6 +26,7 @@ import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.SshAgentServer;
 import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.session.ConnectionService;
+import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.logging.AbstractLoggingBean;
 
@@ -44,7 +45,9 @@ public class AgentServerProxy extends AbstractLoggingBean 
implements SshAgentSer
 
     public SshAgent createClient() throws IOException {
         try {
-            AgentForwardedChannel channel = new AgentForwardedChannel();
+            Session session = this.service.getSession();
+            String channelType = 
PropertyResolverUtils.getStringProperty(session, PROXY_CHANNEL_TYPE, 
DEFAULT_PROXY_CHANNEL_TYPE);
+            AgentForwardedChannel channel = new 
AgentForwardedChannel(channelType);
             this.service.registerChannel(channel);
             
channel.open().verify(PropertyResolverUtils.getLongProperty(channel, 
CHANNEL_OPEN_TIMEOUT_PROP, DEFAULT_CHANNEL_OPEN_TIMEOUT));
             return channel.getAgent();
@@ -59,7 +62,7 @@ public class AgentServerProxy extends AbstractLoggingBean 
implements SshAgentSer
                 throw (IOException) t;
             }
 
-            throw (IOException) new IOException("Failed (" + 
t.getClass().getSimpleName() + ") to create client: " + t.getMessage(), t);
+            throw new IOException("Failed (" + t.getClass().getSimpleName() + 
") to create client: " + t.getMessage(), t);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/local/ChannelAgentForwardingFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/agent/local/ChannelAgentForwardingFactory.java
 
b/sshd-core/src/main/java/org/apache/sshd/agent/local/ChannelAgentForwardingFactory.java
index 2fed297..1396b61 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/agent/local/ChannelAgentForwardingFactory.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/agent/local/ChannelAgentForwardingFactory.java
@@ -21,20 +21,25 @@ package org.apache.sshd.agent.local;
 
 import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.channel.ChannelFactory;
+import org.apache.sshd.common.util.ValidateUtils;
 
 /**
  * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
  */
 public class ChannelAgentForwardingFactory implements ChannelFactory {
-    public static final ChannelAgentForwardingFactory INSTANCE = new 
ChannelAgentForwardingFactory();
+    public static final ChannelAgentForwardingFactory OPENSSH = new 
ChannelAgentForwardingFactory("[email protected]");
+    // see https://tools.ietf.org/html/draft-ietf-secsh-agent-02
+    public static final ChannelAgentForwardingFactory IETF = new 
ChannelAgentForwardingFactory("auth-agent");
 
-    public ChannelAgentForwardingFactory() {
-        super();
+    private final String name;
+
+    public ChannelAgentForwardingFactory(String name) {
+        this.name = ValidateUtils.checkNotNullAndNotEmpty(name, "No channel 
factory name specified");
     }
 
     @Override
     public String getName() {
-        return "[email protected]";
+        return name;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/local/LocalAgentFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/agent/local/LocalAgentFactory.java 
b/sshd-core/src/main/java/org/apache/sshd/agent/local/LocalAgentFactory.java
index 8ff02a9..0ad3664 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/LocalAgentFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/local/LocalAgentFactory.java
@@ -19,6 +19,9 @@
 package org.apache.sshd.agent.local;
 
 import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.SshAgentFactory;
@@ -30,6 +33,9 @@ import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.session.ConnectionService;
 
 public class LocalAgentFactory implements SshAgentFactory {
+    public static final List<NamedFactory<Channel>> 
DEFAULT_FORWARDING_CHANNELS =
+            Collections.unmodifiableList(
+                    
Arrays.<NamedFactory<Channel>>asList(ChannelAgentForwardingFactory.OPENSSH, 
ChannelAgentForwardingFactory.IETF));
 
     private final SshAgent agent;
 
@@ -46,8 +52,8 @@ public class LocalAgentFactory implements SshAgentFactory {
     }
 
     @Override
-    public NamedFactory<Channel> getChannelForwardingFactory() {
-        return ChannelAgentForwardingFactory.INSTANCE;
+    public List<NamedFactory<Channel>> 
getChannelForwardingFactories(FactoryManager manager) {
+        return DEFAULT_FORWARDING_CHANNELS;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java 
b/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java
index 39edf4e..07aae54 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java
@@ -19,6 +19,7 @@
 package org.apache.sshd.agent.local;
 
 import java.io.IOException;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -26,6 +27,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.SshAgentFactory;
 import org.apache.sshd.agent.SshAgentServer;
+import org.apache.sshd.agent.unix.UnixAgentFactory;
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.PropertyResolverUtils;
@@ -39,7 +41,6 @@ import org.apache.sshd.server.session.ServerSession;
  * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
  */
 public class ProxyAgentFactory implements SshAgentFactory {
-
     private final Map<String, AgentServerProxy> proxies = new 
ConcurrentHashMap<>();
 
     public ProxyAgentFactory() {
@@ -47,8 +48,8 @@ public class ProxyAgentFactory implements SshAgentFactory {
     }
 
     @Override
-    public NamedFactory<Channel> getChannelForwardingFactory() {
-        return ChannelAgentForwardingFactory.INSTANCE;
+    public List<NamedFactory<Channel>> 
getChannelForwardingFactories(FactoryManager manager) {
+        return UnixAgentFactory.DEFAULT_FORWARDING_CHANNELS;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentForwardedChannel.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentForwardedChannel.java 
b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentForwardedChannel.java
index 88fae33..01888af 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentForwardedChannel.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentForwardedChannel.java
@@ -33,8 +33,8 @@ public class AgentForwardedChannel extends 
AbstractClientChannel implements Runn
 
     private final long socket;
 
-    public AgentForwardedChannel(long socket) {
-        super("[email protected]");
+    public AgentForwardedChannel(long socket, String channelType) {
+        super(channelType);
         this.socket = socket;
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java 
b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
index 62b8e8f..3a8fa8c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
@@ -103,7 +103,8 @@ public class AgentServerProxy extends AbstractLoggingBean 
implements SshAgentSer
 
                             Session session = 
AgentServerProxy.this.service.getSession();
                             Socket.timeoutSet(clientSock, 
PropertyResolverUtils.getIntProperty(session, AUTH_SOCKET_TIMEOUT, 
DEFAULT_AUTH_SOCKET_TIMEOUT));
-                            AgentForwardedChannel channel = new 
AgentForwardedChannel(clientSock);
+                            String channelType = 
PropertyResolverUtils.getStringProperty(session, PROXY_CHANNEL_TYPE, 
DEFAULT_PROXY_CHANNEL_TYPE);
+                            AgentForwardedChannel channel = new 
AgentForwardedChannel(clientSock, channelType);
                             
AgentServerProxy.this.service.registerChannel(channel);
                             
channel.open().verify(PropertyResolverUtils.getLongProperty(session, 
CHANNEL_OPEN_TIMEOUT_PROP, DEFAULT_CHANNEL_OPEN_TIMEOUT));
                         } catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/unix/AprLibrary.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AprLibrary.java 
b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AprLibrary.java
index d77e2c3..34940ab 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AprLibrary.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AprLibrary.java
@@ -41,7 +41,7 @@ import org.apache.tomcat.jni.Pool;
  *
  * @author <a href="http://mina.apache.org";>Apache MINA Project</a>
  */
-final class AprLibrary {
+public final class AprLibrary {
 
     // is APR library was initialized (load of native libraries)
     private static AprLibrary library;
@@ -76,7 +76,7 @@ final class AprLibrary {
      *
      * @return the current APR library singleton
      */
-    static synchronized AprLibrary getInstance() {
+    public static synchronized AprLibrary getInstance() {
         if (!isInitialized()) {
             initialize();
         }
@@ -98,7 +98,7 @@ final class AprLibrary {
      *
      * @return true if the Library is initialized, false otherwise
      */
-    static synchronized boolean isInitialized() {
+    public static synchronized boolean isInitialized() {
         return library != null;
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/unix/ChannelAgentForwardingFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/agent/unix/ChannelAgentForwardingFactory.java
 
b/sshd-core/src/main/java/org/apache/sshd/agent/unix/ChannelAgentForwardingFactory.java
index dd04036..4f31f41 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/agent/unix/ChannelAgentForwardingFactory.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/agent/unix/ChannelAgentForwardingFactory.java
@@ -22,21 +22,26 @@ import java.util.concurrent.ExecutorService;
 
 import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.channel.ChannelFactory;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.threads.ExecutorServiceCarrier;
 
 /**
  * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
  */
 public class ChannelAgentForwardingFactory implements ChannelFactory, 
ExecutorServiceCarrier {
-    public static final ChannelAgentForwardingFactory INSTANCE = new 
ChannelAgentForwardingFactory();
+    public static final ChannelAgentForwardingFactory OPENSSH = new 
ChannelAgentForwardingFactory("[email protected]");
+    // see https://tools.ietf.org/html/draft-ietf-secsh-agent-02
+    public static final ChannelAgentForwardingFactory IETF = new 
ChannelAgentForwardingFactory("auth-agent");
 
-    public ChannelAgentForwardingFactory() {
-        super();
+    private final String name;
+
+    public ChannelAgentForwardingFactory(String name) {
+        this.name = ValidateUtils.checkNotNullAndNotEmpty(name, "No channel 
factory name specified");
     }
 
     @Override
     public String getName() {
-        return "[email protected]";
+        return name;
     }
 
     @Override   // user can override to provide an alternative

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/agent/unix/UnixAgentFactory.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/agent/unix/UnixAgentFactory.java 
b/sshd-core/src/main/java/org/apache/sshd/agent/unix/UnixAgentFactory.java
index 16fc4bd..d838d32 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/unix/UnixAgentFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/unix/UnixAgentFactory.java
@@ -19,6 +19,10 @@
 package org.apache.sshd.agent.unix;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.concurrent.ExecutorService;
 
 import org.apache.sshd.agent.SshAgent;
@@ -26,6 +30,7 @@ import org.apache.sshd.agent.SshAgentFactory;
 import org.apache.sshd.agent.SshAgentServer;
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
 import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.channel.Channel;
@@ -40,20 +45,12 @@ import org.apache.sshd.server.session.ServerSession;
  * @author <a href="mailto:[email protected]";>Apache MINA SSHD Project</a>
  */
 public class UnixAgentFactory implements SshAgentFactory, 
ExecutorServiceConfigurer {
+    public static final List<NamedFactory<Channel>> 
DEFAULT_FORWARDING_CHANNELS =
+            Collections.unmodifiableList(
+                    
Arrays.<NamedFactory<Channel>>asList(ChannelAgentForwardingFactory.OPENSSH, 
ChannelAgentForwardingFactory.IETF));
+
     private ExecutorService executor;
     private boolean shutdownExecutor;
-    private final NamedFactory<Channel> factory = new 
ChannelAgentForwardingFactory() {
-        @Override
-        public ExecutorService getExecutorService() {
-            return UnixAgentFactory.this.getExecutorService();
-        }
-
-        @Override
-        public boolean isShutdownOnExit() {
-            return UnixAgentFactory.this.isShutdownOnExit();
-        }
-
-    };
 
     public UnixAgentFactory() {
         super();
@@ -85,8 +82,29 @@ public class UnixAgentFactory implements SshAgentFactory, 
ExecutorServiceConfigu
     }
 
     @Override
-    public NamedFactory<Channel> getChannelForwardingFactory() {
-        return factory;
+    public List<NamedFactory<Channel>> 
getChannelForwardingFactories(FactoryManager manager) {
+        final ExecutorServiceConfigurer configurer = this;
+        return Collections.unmodifiableList(new 
ArrayList<NamedFactory<Channel>>(DEFAULT_FORWARDING_CHANNELS.size()) {
+            // Not serializing it
+            private static final long serialVersionUID = 1L;
+
+            {
+                for (NamedResource r : DEFAULT_FORWARDING_CHANNELS) {
+                    String channelType = r.getName();
+                    add(new ChannelAgentForwardingFactory(channelType) {
+                            @Override
+                            public ExecutorService getExecutorService() {
+                                return configurer.getExecutorService();
+                            }
+
+                            @Override
+                            public boolean isShutdownOnExit() {
+                                return configurer.isShutdownOnExit();
+                            }
+                    });
+                }
+            }
+        });
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java 
b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
index 17f8bb4..f5df111 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
@@ -383,21 +383,24 @@ public class SshClient extends AbstractFactoryManager 
implements ClientFactoryMa
         // if no client identities override use the default
         KeyPairProvider defaultIdentities = getKeyPairProvider();
         if (defaultIdentities == null) {
-            setKeyPairProvider(new DefaultClientIdentitiesWatcher(
-                    this::getClientIdentityLoader,
-                    this::getFilePasswordProvider));
+            setKeyPairProvider(new 
DefaultClientIdentitiesWatcher(this::getClientIdentityLoader, 
this::getFilePasswordProvider));
         }
 
         // Register the additional agent forwarding channel if needed
         SshAgentFactory agentFactory = getAgentFactory();
         if (agentFactory != null) {
+            List<NamedFactory<Channel>> forwarders =
+                    ValidateUtils.checkNotNullAndNotEmpty(
+                            agentFactory.getChannelForwardingFactories(this), 
"No agent channel forwarding factories for %s", agentFactory);
             List<NamedFactory<Channel>> factories = getChannelFactories();
             if (GenericUtils.isEmpty(factories)) {
-                factories = new ArrayList<>();
+                factories = forwarders;
             } else {
-                factories = new ArrayList<>(factories);
+                // create a copy in case un-modifiable original
+                factories = new ArrayList<>(factories.size() + 
forwarders.size());
+                factories.addAll(factories);
+                factories.addAll(forwarders);
             }
-            
factories.add(ValidateUtils.checkNotNull(agentFactory.getChannelForwardingFactory(),
 "No agent channel forwarding factory for %s", agentFactory));
 
             setChannelFactories(factories);
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
 
b/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
index 669ae0d..6bcdf53 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
@@ -24,6 +24,8 @@ import java.util.EnumMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
 
+import org.apache.sshd.agent.SshAgentFactory;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.channel.PtyMode;
 import org.apache.sshd.common.channel.SttySupport;
@@ -225,9 +227,10 @@ public class PtyCapableChannelSession extends 
ChannelSession {
                 log.debug("doOpenPty({}) Send agent forwarding request", this);
             }
 
+            String channelType = 
PropertyResolverUtils.getStringProperty(session, 
SshAgentFactory.PROXY_AUTH_CHANNEL_TYPE, 
SshAgentFactory.DEFAULT_PROXY_AUTH_CHANNEL_TYPE);
             Buffer buffer = 
session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST, Long.SIZE);
             buffer.putInt(getRecipient());
-            buffer.putString("[email protected]");
+            buffer.putString(channelType);
             buffer.putBoolean(false);   // want-reply
             writePacket(buffer);
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java 
b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
index 78d32fa..65fda21 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
@@ -318,10 +318,11 @@ public class ChannelSession extends AbstractServerChannel 
{
                     }
                     return RequestHandler.Result.ReplyFailure;
                 }
+            case "auth-agent-req":  // see 
https://tools.ietf.org/html/draft-ietf-secsh-agent-02
             case "[email protected]":
-                return handleAgentForwarding(buffer, wantReply);
+                return handleAgentForwarding(requestType, buffer, wantReply);
             case "x11-req":
-                return handleX11Forwarding(buffer, wantReply);
+                return handleX11Forwarding(requestType, buffer, wantReply);
             default:
                 return super.handleInternalRequest(requestType, wantReply, 
buffer);
         }
@@ -695,23 +696,23 @@ public class ChannelSession extends AbstractServerChannel 
{
         return v != null ? v.intValue() : 0;
     }
 
-    protected RequestHandler.Result handleAgentForwarding(Buffer buffer, 
boolean wantReply) throws IOException {
+    protected RequestHandler.Result handleAgentForwarding(String requestType, 
Buffer buffer, boolean wantReply) throws IOException {
         ServerSession session = getServerSession();
         FactoryManager manager = 
ValidateUtils.checkNotNull(session.getFactoryManager(), "No session factory 
manager");
         ForwardingFilter filter = manager.getTcpipForwardingFilter();
         SshAgentFactory factory = manager.getAgentFactory();
         try {
-            if ((factory == null) || (filter == null) || 
(!filter.canForwardAgent(session))) {
+            if ((factory == null) || (filter == null) || 
(!filter.canForwardAgent(session, requestType))) {
                 if (log.isDebugEnabled()) {
-                    log.debug("handleAgentForwarding(" + this + 
")[haveFactory=" + (factory != null) + ",haveFilter=" + (filter != null) + "] 
filtered out");
+                    log.debug("handleAgentForwarding(" + this + 
")[haveFactory=" + (factory != null) + ",haveFilter=" + (filter != null) + "] 
filtered out request=" + requestType);
                 }
                 return RequestHandler.Result.ReplyFailure;
             }
         } catch (Error e) {
-            log.warn("handleAgentForwarding({}) failed ({}) to consult 
forwarding filter: {}",
-                     this, e.getClass().getSimpleName(), e.getMessage());
+            log.warn("handleAgentForwarding({}) failed ({}) to consult 
forwarding filter for '{}': {}",
+                     this, e.getClass().getSimpleName(), requestType, 
e.getMessage());
             if (log.isDebugEnabled()) {
-                log.debug("handleAgentForwarding(" + this + ") filter 
consultation failure details", e);
+                log.debug("handleAgentForwarding(" + this + ")[" + requestType 
+ "] filter consultation failure details", e);
             }
             throw new RuntimeSshException(e);
         }
@@ -729,7 +730,7 @@ public class ChannelSession extends AbstractServerChannel {
         return RequestHandler.Result.ReplySuccess;
     }
 
-    protected RequestHandler.Result handleX11Forwarding(Buffer buffer, boolean 
wantReply) throws IOException {
+    protected RequestHandler.Result handleX11Forwarding(String requestType, 
Buffer buffer, boolean wantReply) throws IOException {
         ServerSession session = getServerSession();
         boolean singleConnection = buffer.getBoolean();
         String authProtocol = buffer.getString();
@@ -739,18 +740,18 @@ public class ChannelSession extends AbstractServerChannel 
{
         FactoryManager manager = 
ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
         ForwardingFilter filter = manager.getTcpipForwardingFilter();
         try {
-            if ((filter == null) || (!filter.canForwardX11(session))) {
+            if ((filter == null) || (!filter.canForwardX11(session, 
requestType))) {
                 if (log.isDebugEnabled()) {
-                    log.debug("handleX11Forwarding({}) single={}, protocol={}, 
cookie={}, screen={}, filter={}: filtered",
-                              this, singleConnection, authProtocol, 
authCookie, screenId, filter);
+                    log.debug("handleX11Forwarding({}) single={}, protocol={}, 
cookie={}, screen={}, filter={}: filtered request={}",
+                              this, singleConnection, authProtocol, 
authCookie, screenId, filter, requestType);
                 }
                 return RequestHandler.Result.ReplyFailure;
             }
         } catch (Error e) {
-            log.warn("handleX11Forwarding({}) failed ({}) to consult 
forwarding filter: {}",
-                     this, e.getClass().getSimpleName(), e.getMessage());
+            log.warn("handleX11Forwarding({}) failed ({}) to consult 
forwarding filter for '{}': {}",
+                     this, e.getClass().getSimpleName(), requestType, 
e.getMessage());
             if (log.isDebugEnabled()) {
-                log.debug("handleX11Forwarding(" + this + ") filter 
consultation failure details", e);
+                log.debug("handleX11Forwarding(" + this + ")[" + requestType + 
"] filter consultation failure details", e);
             }
             throw new RuntimeSshException(e);
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/server/forward/ForwardingFilter.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/server/forward/ForwardingFilter.java 
b/sshd-core/src/main/java/org/apache/sshd/server/forward/ForwardingFilter.java
index 09bacab..6c94581 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/server/forward/ForwardingFilter.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/server/forward/ForwardingFilter.java
@@ -45,9 +45,10 @@ public interface ForwardingFilter {
      * </p>
      *
      * @param session The {@link Session} requesting permission to forward the 
agent.
+     * @param requestType The request type string that triggered this call
      * @return true if the agent forwarding is permitted, false if denied.
      */
-    boolean canForwardAgent(Session session);
+    boolean canForwardAgent(Session session, String requestType);
 
     /**
      * <p>
@@ -61,9 +62,10 @@ public interface ForwardingFilter {
      * </p>
      *
      * @param session The {@link Session} requesting permission to forward X11 
connections.
+     * @param requestType The request type string that triggered this call
      * @return true if the X11 forwarding is permitted, false if denied.
      */
-    boolean canForwardX11(Session session);
+    boolean canForwardX11(Session session, String requestType);
 
     /**
      * <p>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/main/java/org/apache/sshd/server/forward/StaticDecisionForwardingFilter.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/server/forward/StaticDecisionForwardingFilter.java
 
b/sshd-core/src/main/java/org/apache/sshd/server/forward/StaticDecisionForwardingFilter.java
index a4a46fb..00ef488 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/server/forward/StaticDecisionForwardingFilter.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/server/forward/StaticDecisionForwardingFilter.java
@@ -41,13 +41,13 @@ public class StaticDecisionForwardingFilter extends 
AbstractLoggingBean implemen
     }
 
     @Override
-    public boolean canForwardAgent(Session session) {
-        return checkAcceptance("[email protected]", session, 
SshdSocketAddress.LOCALHOST_ADDRESS);
+    public boolean canForwardAgent(Session session, String requestType) {
+        return checkAcceptance(requestType, session, 
SshdSocketAddress.LOCALHOST_ADDRESS);
     }
 
     @Override
-    public boolean canForwardX11(Session session) {
-        return checkAcceptance("x11-req", session, 
SshdSocketAddress.LOCALHOST_ADDRESS);
+    public boolean canForwardX11(Session session, String requestType) {
+        return checkAcceptance(requestType, session, 
SshdSocketAddress.LOCALHOST_ADDRESS);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java 
b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
index e27b505..b846df6 100644
--- a/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/agent/AgentTest.java
@@ -31,6 +31,7 @@ import org.apache.sshd.agent.local.LocalAgentFactory;
 import org.apache.sshd.agent.local.ProxyAgentFactory;
 import org.apache.sshd.agent.unix.AgentClient;
 import org.apache.sshd.agent.unix.AgentServer;
+import org.apache.sshd.agent.unix.AprLibrary;
 import org.apache.sshd.client.SshClient;
 import org.apache.sshd.client.channel.ChannelShell;
 import org.apache.sshd.client.session.ClientSession;
@@ -46,6 +47,7 @@ import org.apache.sshd.util.test.EchoShell;
 import org.apache.sshd.util.test.EchoShellFactory;
 import org.apache.sshd.util.test.Utils;
 import org.junit.Assume;
+import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
@@ -56,25 +58,29 @@ public class AgentTest extends BaseTestSupport {
         super();
     }
 
-    @Test
-    public void testAgentServer() throws Exception {
+    @BeforeClass
+    public static void checkTestAssumptions() {
         // TODO: revisit this test to work without BC
         Assume.assumeTrue("BouncyCastle not registered", 
SecurityUtils.isBouncyCastleRegistered());
+        AprLibrary library = null;
+        try {
+            library = AprLibrary.getInstance();
+        } catch (RuntimeException e) {
+            Throwable cause = e.getCause();
+            if (cause instanceof UnsatisfiedLinkError) {
+                library = null;
+            } else {
+                throw e;
+            }
+        }
+        Assume.assumeTrue("Native library N/A", library != null);
+    }
+
+    @Test
+    public void testAgentServer() throws Exception {
 
         try (AgentServer agent = new AgentServer()) {
-            String authSocket;
-            try {
-                authSocket = agent.start();
-            } catch (RuntimeException e) {
-                Throwable cause = e.getCause();
-                if (cause instanceof UnsatisfiedLinkError) {
-                    // the native library is not available, so these tests 
should be skipped
-                    authSocket = null;
-                } else {
-                    throw e;
-                }
-            }
-            Assume.assumeTrue("Native library N/A", authSocket != null);
+            String authSocket = agent.start();
 
             try (SshAgent client = new AgentClient(authSocket)) {
                 List<Pair<PublicKey, String>> keys = client.getIdentities();
@@ -100,9 +106,6 @@ public class AgentTest extends BaseTestSupport {
     @Test
     @SuppressWarnings("checkstyle:nestedtrydepth")
     public void testAgentForwarding() throws Exception {
-        // TODO: revisit this test to work without BC
-        Assume.assumeTrue("BouncyCastle not registered", 
SecurityUtils.isBouncyCastleRegistered());
-
         TestEchoShellFactory shellFactory = new TestEchoShellFactory();
         ProxyAgentFactory agentFactory = new ProxyAgentFactory();
         LocalAgentFactory localAgentFactory = new LocalAgentFactory();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/dd299ae7/sshd-core/src/test/java/org/apache/sshd/common/ForwardingFilterTest.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/test/java/org/apache/sshd/common/ForwardingFilterTest.java 
b/sshd-core/src/test/java/org/apache/sshd/common/ForwardingFilterTest.java
index 2c3531a..38e3443 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/ForwardingFilterTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/ForwardingFilterTest.java
@@ -71,8 +71,8 @@ public class ForwardingFilterTest extends BaseTestSupport {
         assertEquals("Mismatched acceptance status", expected, 
filter.isAccepted());
 
         Session session = Mockito.mock(Session.class);
-        assertEquals("Mismatched 'canForwardAgent' result", expected, 
filter.canForwardAgent(session));
-        assertEquals("Mismatched 'canForwardX11' result", expected, 
filter.canForwardX11(session));
+        assertEquals("Mismatched 'canForwardAgent' result", expected, 
filter.canForwardAgent(session, "auth-agent-req"));
+        assertEquals("Mismatched 'canForwardX11' result", expected, 
filter.canForwardX11(session, "x11-req"));
         assertEquals("Mismatched 'canListen' result", expected, 
filter.canListen(SshdSocketAddress.LOCALHOST_ADDRESS, session));
 
         for (ForwardingFilter.Type t : ForwardingFilter.Type.VALUES) {

Reply via email to