mina-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lgoldst...@apache.org
Subject [3/5] mina-sshd git commit: [SSHD-859] Provide client session connection context that is propagated to the SSH session
Date Wed, 31 Oct 2018 05:03:11 GMT
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-common/src/main/java/org/apache/sshd/common/SshConstants.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/SshConstants.java b/sshd-common/src/main/java/org/apache/sshd/common/SshConstants.java
index 01e8ae7..ee8ae63 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/SshConstants.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/SshConstants.java
@@ -33,6 +33,8 @@ import org.apache.sshd.common.util.logging.LoggingUtils;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public final class SshConstants {
+    public static final int DEFAULT_PORT = 22;
+
     //
     // SSH message identifiers
     //

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-common/src/main/java/org/apache/sshd/common/config/ConfigFileReaderSupport.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/config/ConfigFileReaderSupport.java b/sshd-common/src/main/java/org/apache/sshd/common/config/ConfigFileReaderSupport.java
index aea9f24..b6cab4f 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/config/ConfigFileReaderSupport.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/config/ConfigFileReaderSupport.java
@@ -58,7 +58,6 @@ public final class ConfigFileReaderSupport {
     public static final String LISTEN_ADDRESS_CONFIG_PROP = "ListenAddress";
     public static final String DEFAULT_BIND_ADDRESS = SshdSocketAddress.IPV4_ANYADDR;
     public static final String PORT_CONFIG_PROP = "Port";
-    public static final int DEFAULT_PORT = 22;
     public static final String KEEP_ALIVE_CONFIG_PROP = "TCPKeepAlive";
     public static final boolean DEFAULT_KEEP_ALIVE = true;
     public static final String USE_DNS_CONFIG_PROP = "UseDNS";

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-common/src/test/java/org/apache/sshd/client/config/hosts/KnownHostHashEntryTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/client/config/hosts/KnownHostHashEntryTest.java b/sshd-common/src/test/java/org/apache/sshd/client/config/hosts/KnownHostHashEntryTest.java
index 6bf1177..1b76ff0 100644
--- a/sshd-common/src/test/java/org/apache/sshd/client/config/hosts/KnownHostHashEntryTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/client/config/hosts/KnownHostHashEntryTest.java
@@ -22,7 +22,7 @@ package org.apache.sshd.client.config.hosts;
 import java.util.Arrays;
 import java.util.List;
 
-import org.apache.sshd.common.config.ConfigFileReaderSupport;
+import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.util.test.JUnit4ClassRunnerWithParametersFactory;
 import org.apache.sshd.util.test.JUnitTestSupport;
@@ -64,7 +64,7 @@ public class KnownHostHashEntryTest extends JUnitTestSupport {
         return Arrays.asList(
             // line generated `ssh xenon@localhost hostname` (SSH-2.0-OpenSSH_7.5)
             new Object[] {
-                "localhost", ConfigFileReaderSupport.DEFAULT_PORT,
+                "localhost", SshConstants.DEFAULT_PORT,
                 "|1|vLQs+atPgodQmPes21ZaMSgLD0s=|A2K2Ym0ZPtQmD8kB3FVViQvQ7qQ=", "ecdsa-sha2-nistp256",
                 "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJTsDTYFSYyRMlOec6JBfC8dEFqHNNWu7n8N0niS1zmHpggX+L4cndxhJPE0ILi9otHO7h0mp0cmqqho2tsX8lc=",
                 "xenon@localhost"
@@ -92,7 +92,7 @@ public class KnownHostHashEntryTest extends JUnitTestSupport {
 
     @Test
     public void testHostHashMatchOnDefaultPort() {
-        Assume.assumeTrue("No-default port used", port == ConfigFileReaderSupport.DEFAULT_PORT);
+        Assume.assumeTrue("No-default port used", port == SshConstants.DEFAULT_PORT);
         KnownHostEntry entry = KnownHostEntry.parseKnownHostEntry(line);
         assertTrue(entry.isHostMatch(host, 0));
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-common/src/test/java/org/apache/sshd/client/config/hosts/KnownHostHashValueTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/client/config/hosts/KnownHostHashValueTest.java b/sshd-common/src/test/java/org/apache/sshd/client/config/hosts/KnownHostHashValueTest.java
index 3ecea7f..72c6e89 100644
--- a/sshd-common/src/test/java/org/apache/sshd/client/config/hosts/KnownHostHashValueTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/client/config/hosts/KnownHostHashValueTest.java
@@ -22,7 +22,7 @@ package org.apache.sshd.client.config.hosts;
 import java.util.Arrays;
 import java.util.Collection;
 
-import org.apache.sshd.common.config.ConfigFileReaderSupport;
+import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.util.test.JUnit4ClassRunnerWithParametersFactory;
 import org.apache.sshd.util.test.JUnitTestSupport;
 import org.apache.sshd.util.test.NoIoTestCase;
@@ -62,9 +62,9 @@ public class KnownHostHashValueTest extends JUnitTestSupport {
             new Object[]{"localhost", 10022,
                 "|1|qhjoqX12EcnwZO3KNbpoFbxrdYE=|J+voEFzRbRL49TiHV+jbUfaS+kg="},
             // line generated `ssh xenon@localhost hostname` (SSH-2.0-OpenSSH_7.5)
-            new Object[]{"localhost", ConfigFileReaderSupport.DEFAULT_PORT,
+            new Object[]{"localhost", SshConstants.DEFAULT_PORT,
                 "|1|vLQs+atPgodQmPes21ZaMSgLD0s=|A2K2Ym0ZPtQmD8kB3FVViQvQ7qQ="},
-            new Object[]{"192.168.1.61", ConfigFileReaderSupport.DEFAULT_PORT,
+            new Object[]{"192.168.1.61", SshConstants.DEFAULT_PORT,
                 "|1|F1E1KeoE/eEWhi10WpGv4OdiO6Y=|3988QV0VE8wmZL7suNrYQLITLCg="}
         );
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/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 84339c3..227a4d5 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
@@ -63,6 +63,7 @@ import org.apache.sshd.client.session.ClientUserAuthServiceFactory;
 import org.apache.sshd.client.session.SessionFactory;
 import org.apache.sshd.client.simple.AbstractSimpleClientSessionCreator;
 import org.apache.sshd.client.simple.SimpleClient;
+import org.apache.sshd.common.AttributeRepository;
 import org.apache.sshd.common.Closeable;
 import org.apache.sshd.common.Factory;
 import org.apache.sshd.common.NamedFactory;
@@ -441,7 +442,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
 
     @Override
     public ConnectFuture connect(
-            String username, String host, int port, SocketAddress localAddress)
+            String username, String host, int port, AttributeRepository context, SocketAddress localAddress)
                 throws IOException {
         HostConfigEntryResolver resolver = getHostConfigEntryResolver();
         HostConfigEntry entry = resolver.resolveEffectiveHost(host, port, username);
@@ -464,12 +465,12 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             }
         }
 
-        return connect(entry, localAddress);
+        return connect(entry, context, localAddress);
     }
 
     @Override
     public ConnectFuture connect(
-            String username, SocketAddress targetAddress, SocketAddress localAddress)
+            String username, SocketAddress targetAddress, AttributeRepository context, SocketAddress localAddress)
                 throws IOException {
         Objects.requireNonNull(targetAddress, "No target address");
         if (targetAddress instanceof InetSocketAddress) {
@@ -485,7 +486,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
                     log.debug("connect({}@{}:{}) no overrides", username, host, port);
                 }
 
-                return doConnect(username, targetAddress, localAddress, Collections.emptyList(), true);
+                return doConnect(username, targetAddress, context, localAddress, Collections.emptyList(), true);
             } else {
                 if (log.isDebugEnabled()) {
                     log.debug("connect({}@{}:{}) effective: {}", username, host, port, entry);
@@ -497,12 +498,14 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             if (log.isDebugEnabled()) {
                 log.debug("connect({}@{}) not an InetSocketAddress: {}", username, targetAddress, targetAddress.getClass().getName());
             }
-            return doConnect(username, targetAddress, localAddress, Collections.emptyList(), true);
+            return doConnect(username, targetAddress, context, localAddress, Collections.emptyList(), true);
         }
     }
 
     @Override
-    public ConnectFuture connect(HostConfigEntry hostConfig, SocketAddress localAddress) throws IOException {
+    public ConnectFuture connect(
+            HostConfigEntry hostConfig, AttributeRepository context, SocketAddress localAddress)
+                throws IOException {
         Objects.requireNonNull(hostConfig, "No host configuration");
         String host = ValidateUtils.checkNotNullAndNotEmpty(hostConfig.getHostName(), "No target host");
         int port = hostConfig.getPort();
@@ -510,7 +513,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
 
         Collection<KeyPair> keys = loadClientIdentities(hostConfig.getIdentities(), IoUtils.EMPTY_LINK_OPTIONS);
         return doConnect(hostConfig.getUsername(), new InetSocketAddress(host, port),
-                localAddress, keys, !hostConfig.isIdentitiesOnly());
+                context, localAddress, keys, !hostConfig.isIdentitiesOnly());
     }
 
     protected List<KeyPair> loadClientIdentities(Collection<String> locations, LinkOption... options) throws IOException {
@@ -556,7 +559,8 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
     }
 
     protected ConnectFuture doConnect(
-            String username, SocketAddress targetAddress, SocketAddress localAddress,
+            String username, SocketAddress targetAddress,
+            AttributeRepository context, SocketAddress localAddress,
             Collection<? extends KeyPair> identities, boolean useDefaultIdentities)
                 throws IOException {
         if (connector == null) {
@@ -565,8 +569,10 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
 
         ConnectFuture connectFuture = new DefaultConnectFuture(username + "@" + targetAddress, null);
         SshFutureListener<IoConnectFuture> listener =
-            createConnectCompletionListener(connectFuture, username, targetAddress, identities, useDefaultIdentities);
-        connector.connect(targetAddress, localAddress).addListener(listener);
+            createConnectCompletionListener(
+                connectFuture, username, targetAddress, identities, useDefaultIdentities);
+        IoConnectFuture connectingFuture = connector.connect(targetAddress, context, localAddress);
+        connectingFuture.addListener(listener);
         return connectFuture;
     }
 
@@ -586,7 +592,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
                 if (t != null) {
                     if (log.isDebugEnabled()) {
                         log.debug("operationComplete({}@{}) failed ({}): {}",
-                              username, address, t.getClass().getSimpleName(), t.getMessage());
+                            username, address, t.getClass().getSimpleName(), t.getMessage());
                     }
                     connectFuture.setException(t);
                 } else {
@@ -595,7 +601,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
                         onConnectOperationComplete(ioSession, connectFuture, username, address, identities, useDefaultIdentities);
                     } catch (RuntimeException e) {
                         log.warn("operationComplete({}@{}) failed ({}) to signal completion of session={}: {}",
-                                username, address, e.getClass().getSimpleName(), ioSession, e.getMessage());
+                            username, address, e.getClass().getSimpleName(), ioSession, e.getMessage());
                         if (log.isDebugEnabled()) {
                             log.debug("operationComplete(" + username + "@" + address + ") session=" + ioSession + " completion signal failure details", e);
                         }
@@ -613,8 +619,9 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
         };
     }
 
-    protected void onConnectOperationComplete(IoSession ioSession, ConnectFuture connectFuture,
-            String username, SocketAddress address, Collection<? extends KeyPair> identities, boolean useDefaultIdentities) {
+    protected void onConnectOperationComplete(
+            IoSession ioSession, ConnectFuture connectFuture,  String username,
+            SocketAddress address, Collection<? extends KeyPair> identities, boolean useDefaultIdentities) {
         AbstractClientSession session = (AbstractClientSession) AbstractSession.getSession(ioSession);
         session.setUsername(username);
         session.setConnectAddress(address);
@@ -633,7 +640,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             for (KeyPair kp : identities) {
                 if (traceEnabled) {
                     log.trace("onConnectOperationComplete({}) add identity type={}, fingerprint={}",
-                              session, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint(kp.getPublic()));
+                        session, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint(kp.getPublic()));
                 }
                 session.addPublicKeyIdentity(kp);
             }
@@ -676,14 +683,14 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             if (id instanceof String) {
                 if (traceEnabled) {
                     log.trace("setupDefaultSessionIdentities({}) add password fingerprint={}",
-                              session, KeyUtils.getFingerPrint(id.toString()));
+                        session, KeyUtils.getFingerPrint(id.toString()));
                 }
                 session.addPasswordIdentity((String) id);
             } else if (id instanceof KeyPair) {
                 KeyPair kp = (KeyPair) id;
                 if (traceEnabled) {
                     log.trace("setupDefaultSessionIdentities({}) add identity type={}, fingerprint={}",
-                              session, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint(kp.getPublic()));
+                        session, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint(kp.getPublic()));
                 }
                 session.addPublicKeyIdentity(kp);
             } else {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java b/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
index 2ee30e8..3fac01c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
@@ -40,6 +40,7 @@ import org.apache.sshd.client.channel.ChannelShell;
 import org.apache.sshd.client.channel.ChannelSubsystem;
 import org.apache.sshd.client.channel.ClientChannel;
 import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
+import org.apache.sshd.common.AttributeRepository;
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.NamedResource;
@@ -74,6 +75,8 @@ import org.apache.sshd.common.util.net.SshdSocketAddress;
 public abstract class AbstractClientSession extends AbstractSession implements ClientSession {
     private final List<Object> identities = new CopyOnWriteArrayList<>();
     private final AuthenticationIdentitiesProvider identitiesProvider;
+    private final AttributeRepository connectionContext;
+
     private ServerKeyVerifier serverKeyVerifier;
     private UserInteraction userInteraction;
     private PasswordIdentityProvider passwordIdentityProvider;
@@ -84,6 +87,13 @@ public abstract class AbstractClientSession extends AbstractSession implements C
     protected AbstractClientSession(ClientFactoryManager factoryManager, IoSession ioSession) {
         super(false, factoryManager, ioSession);
         identitiesProvider = AuthenticationIdentitiesProvider.wrapIdentities(identities);
+        this.connectionContext =
+            (AttributeRepository) ioSession.getAttribute(AttributeRepository.class);
+    }
+
+    @Override
+    public AttributeRepository getConnectionContext() {
+        return connectionContext;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
index b016ae3..808586f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
@@ -47,6 +47,7 @@ import org.apache.sshd.client.channel.ClientChannelEvent;
 import org.apache.sshd.client.future.AuthFuture;
 import org.apache.sshd.client.session.forward.DynamicPortForwardingTracker;
 import org.apache.sshd.client.session.forward.ExplicitPortForwardingTracker;
+import org.apache.sshd.common.AttributeRepository;
 import org.apache.sshd.common.forward.PortForwardingManager;
 import org.apache.sshd.common.future.KeyExchangeFuture;
 import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
@@ -108,6 +109,12 @@ public interface ClientSession
     SocketAddress getConnectAddress();
 
     /**
+     * @return The &quot;context&quot; data provided when
+     * session connection was established - {@code null} if none.
+     */
+    AttributeRepository getConnectionContext();
+
+    /**
      * Starts the authentication process.
      * User identities will be tried until the server successfully authenticate the user.
      * User identities must be provided before calling this method using

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionCreator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionCreator.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionCreator.java
index 4d0a7e8..cfbc570 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionCreator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionCreator.java
@@ -23,6 +23,7 @@ import java.net.SocketAddress;
 
 import org.apache.sshd.client.config.hosts.HostConfigEntry;
 import org.apache.sshd.client.future.ConnectFuture;
+import org.apache.sshd.common.AttributeRepository;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -40,7 +41,25 @@ public interface ClientSessionCreator {
      * @see #connect(HostConfigEntry)
      */
     default ConnectFuture connect(String username, String host, int port) throws IOException {
-        return connect(username, host, port, null);
+        return connect(username, host, port, (AttributeRepository) null);
+    }
+
+    /**
+     * Resolves the <U>effective</U> {@link HostConfigEntry} and connects to it
+     *
+     * @param username The intended username
+     * @param host The target host name/address - never {@code null}/empty
+     * @param port The target port
+     * @param context An optional &quot;context&quot; to be attached to the established
+     * session if successfully connected
+     * @return A {@link ConnectFuture}
+     * @throws IOException If failed to resolve the effective target or
+     * connect to it
+     */
+    default ConnectFuture connect(
+            String username, String host, int port, AttributeRepository context)
+                throws IOException {
+        return connect(username, host, port, context, null);
     }
 
     /**
@@ -56,7 +75,29 @@ public interface ClientSessionCreator {
      * connect to it
      * @see #connect(HostConfigEntry)
      */
-    ConnectFuture connect(String username, String host, int port, SocketAddress localAddress) throws IOException;
+    default ConnectFuture connect(
+            String username, String host, int port, SocketAddress localAddress)
+                throws IOException {
+        return connect(username, host, port, null, localAddress);
+    }
+
+    /**
+     * Resolves the <U>effective</U> {@link HostConfigEntry} and connects to it
+     *
+     * @param username The intended username
+     * @param host The target host name/address - never {@code null}/empty
+     * @param port The target port
+     * @param context An optional &quot;context&quot; to be attached to the established
+     * session if successfully connected
+     * @param localAddress The local address to use - if {@code null} an
+     * automatic ephemeral port and bind address is used
+     * @return A {@link ConnectFuture}
+     * @throws IOException If failed to resolve the effective target or
+     * connect to it
+     */
+    ConnectFuture connect(
+        String username, String host, int port, AttributeRepository context, SocketAddress localAddress)
+            throws IOException;
 
     /**
      * Resolves the <U>effective</U> {@link HostConfigEntry} and connects to it
@@ -71,7 +112,26 @@ public interface ClientSessionCreator {
      * @see #connect(HostConfigEntry)
      */
     default ConnectFuture connect(String username, SocketAddress address) throws IOException {
-        return connect(username, address, null);
+        return connect(username, address, (AttributeRepository) null);
+    }
+
+    /**
+     * Resolves the <U>effective</U> {@link HostConfigEntry} and connects to it
+     *
+     * @param username The intended username
+     * @param address The intended {@link SocketAddress} - never {@code null}. If
+     * this is an {@link java.net.InetSocketAddress} then the <U>effective</U> {@link HostConfigEntry}
+     * is resolved and used.
+     * @param context An optional &quot;context&quot; to be attached to the established
+     * session if successfully connected
+     * @return A {@link ConnectFuture}
+     * @throws IOException If failed to resolve the effective target or
+     * connect to it
+     */
+    default ConnectFuture connect(
+            String username, SocketAddress address, AttributeRepository context)
+                throws IOException {
+        return connect(username, address, context, null);
     }
 
     /**
@@ -88,7 +148,29 @@ public interface ClientSessionCreator {
      * connect to it
      * @see #connect(HostConfigEntry)
      */
-    ConnectFuture connect(String username, SocketAddress targetAddress, SocketAddress localAddress) throws IOException;
+    default ConnectFuture connect(
+            String username, SocketAddress targetAddress, SocketAddress localAddress)
+                throws IOException {
+        return connect(username, targetAddress, null, localAddress);
+    }
+
+    /**
+     * Resolves the <U>effective</U> {@link HostConfigEntry} and connects to it
+     *
+     * @param username The intended username
+     * @param targetAddress The intended target {@link SocketAddress} - never {@code null}.
+     * If this is an {@link java.net.InetSocketAddress} then the <U>effective</U>
+     * {@link HostConfigEntry} is resolved and used.
+     * @param context An optional &quot;context&quot; to be attached to the established
+     * session if successfully connected
+     * @param localAddress The local address to use - if {@code null} an
+     * automatic ephemeral port and bind address is used
+     * @return A {@link ConnectFuture}
+     * @throws IOException If failed to resolve the effective target or connect to it
+     */
+    ConnectFuture connect(
+        String username, SocketAddress targetAddress, AttributeRepository context, SocketAddress localAddress)
+            throws IOException;
 
     /**
      * @param hostConfig The effective {@link HostConfigEntry} to connect to - never {@code null}
@@ -96,15 +178,41 @@ public interface ClientSessionCreator {
      * @throws IOException If failed to create the connection future
      */
     default ConnectFuture connect(HostConfigEntry hostConfig) throws IOException {
-        return connect(hostConfig, null);
+        return connect(hostConfig, (AttributeRepository) null);
+    }
+
+    /**
+     * @param hostConfig The effective {@link HostConfigEntry} to connect to - never {@code null}
+     * @param context An optional &quot;context&quot; to be attached to the established
+     * session if successfully connected
+     * @return A {@link ConnectFuture}
+     * @throws IOException If failed to create the connection future
+     */
+    default ConnectFuture connect(HostConfigEntry hostConfig, AttributeRepository context) throws IOException {
+        return connect(hostConfig, context, null);
+    }
+
+    /**
+     * @param hostConfig The effective {@link HostConfigEntry} to connect to - never {@code null}
+     * @param localAddress The local address to use - if {@code null} an
+     * automatic ephemeral port and bind address is used
+     * @return A {@link ConnectFuture}
+     * @throws IOException If failed to create the connection future
+     */
+    default ConnectFuture connect(HostConfigEntry hostConfig, SocketAddress localAddress) throws IOException {
+        return connect(hostConfig, null, localAddress);
     }
 
     /**
      * @param hostConfig The effective {@link HostConfigEntry} to connect to - never {@code null}
+     * @param context An optional &quot;context&quot; to be attached to the established
+     * session if successfully connected
      * @param localAddress The local address to use - if {@code null} an
      * automatic ephemeral port and bind address is used
      * @return A {@link ConnectFuture}
      * @throws IOException If failed to create the connection future
      */
-    ConnectFuture connect(HostConfigEntry hostConfig, SocketAddress localAddress) throws IOException;
+    ConnectFuture connect(
+        HostConfigEntry hostConfig, AttributeRepository context, SocketAddress localAddress)
+            throws IOException;
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java b/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
index 3dd904f..288a693 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
@@ -30,6 +30,7 @@ import org.apache.sshd.client.future.AuthFuture;
 import org.apache.sshd.client.future.ConnectFuture;
 import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.client.session.ClientSessionCreator;
+import org.apache.sshd.common.AttributeRepository;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 
@@ -136,6 +137,7 @@ public abstract class AbstractSimpleClientSessionCreator extends AbstractSimpleC
      * @return The {@link SimpleClient} wrapper. <B>Note:</B> closing the wrapper
      * also closes the underlying sessions creator.
      */
+    @SuppressWarnings("checkstyle:anoninnerlength")
     public static SimpleClient wrap(ClientSessionCreator creator, Channel channel) {
         Objects.requireNonNull(creator, "No sessions creator");
         Objects.requireNonNull(channel, "No channel");
@@ -173,6 +175,44 @@ public abstract class AbstractSimpleClientSessionCreator extends AbstractSimpleC
             }
 
             @Override
+            public ConnectFuture connect(
+                    HostConfigEntry hostConfig, AttributeRepository context, SocketAddress localAddress)
+                        throws IOException {
+                return creator.connect(hostConfig, context, localAddress);
+            }
+
+            @Override
+            public ConnectFuture connect(
+                    String username, SocketAddress targetAddress, AttributeRepository context, SocketAddress localAddress)
+                        throws IOException {
+                return creator.connect(username, targetAddress, context, localAddress);
+            }
+
+            @Override
+            public ConnectFuture connect(
+                    String username, String host, int port, AttributeRepository context, SocketAddress localAddress)
+                        throws IOException {
+                return creator.connect(username, host, port, context, localAddress);
+            }
+
+            @Override
+            public ConnectFuture connect(HostConfigEntry hostConfig, AttributeRepository context) throws IOException {
+                return creator.connect(hostConfig, context);
+            }
+
+            @Override
+            public ConnectFuture connect(String username, SocketAddress address, AttributeRepository context)
+                    throws IOException {
+                return creator.connect(username, address, context);
+            }
+
+            @Override
+            public ConnectFuture connect(String username, String host, int port, AttributeRepository context)
+                    throws IOException {
+                return creator.connect(username, host, port, context);
+            }
+
+            @Override
             public boolean isOpen() {
                 return channel.isOpen();
             }
@@ -181,6 +221,11 @@ public abstract class AbstractSimpleClientSessionCreator extends AbstractSimpleC
             public void close() throws IOException {
                 channel.close();
             }
+
+            @Override
+            public String toString() {
+                return SimpleClient.class.getSimpleName() + "[" + channel + "]";
+            }
         };
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleClientConfigurator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleClientConfigurator.java b/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleClientConfigurator.java
index 31a994b..e8038e1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleClientConfigurator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleClientConfigurator.java
@@ -19,7 +19,7 @@
 
 package org.apache.sshd.client.simple;
 
-import org.apache.sshd.common.config.ConfigFileReaderSupport;
+import org.apache.sshd.common.SshConstants;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -35,7 +35,7 @@ public interface SimpleClientConfigurator {
      */
     long DEFAULT_AUTHENTICATION_TIMEOUT = Long.MAX_VALUE;   // virtually infinite
 
-    int DEFAULT_PORT = ConfigFileReaderSupport.DEFAULT_PORT;
+    int DEFAULT_PORT = SshConstants.DEFAULT_PORT;
 
     /**
      * @return Current connect timeout (msec.) - always positive

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/main/java/org/apache/sshd/common/io/IoAcceptor.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoAcceptor.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoAcceptor.java
index a86b73e..2a0e80d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoAcceptor.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoAcceptor.java
@@ -40,5 +40,4 @@ public interface IoAcceptor extends IoService {
     void unbind();
 
     Set<SocketAddress> getBoundAddresses();
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnector.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnector.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnector.java
index c546d44..193a209 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnector.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoConnector.java
@@ -20,16 +20,19 @@ package org.apache.sshd.common.io;
 
 import java.net.SocketAddress;
 
+import org.apache.sshd.common.AttributeRepository;
+
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public interface IoConnector extends IoService {
-
     /**
      * @param targetAddress The target address to connect to
+     * @param context An optional &quot;context&quot; to be attached to the established
+     * session if successfully connected
      * @param localAddress The local address to use - if {@code null} an
      * automatic ephemeral port and bind address is used
      * @return The {@link IoConnectFuture future} representing the connection request
      */
-    IoConnectFuture connect(SocketAddress targetAddress, SocketAddress localAddress);
+    IoConnectFuture connect(SocketAddress targetAddress, AttributeRepository context, SocketAddress localAddress);
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListener.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListener.java
index 53d6611..6bb51d2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListener.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListener.java
@@ -22,6 +22,7 @@ package org.apache.sshd.common.io;
 import java.io.IOException;
 import java.net.SocketAddress;
 
+import org.apache.sshd.common.AttributeRepository;
 import org.apache.sshd.common.util.SshdEventListener;
 
 /**
@@ -34,10 +35,14 @@ public interface IoServiceEventListener extends SshdEventListener {
      *
      * @param connector The {@link IoConnector} through which the connection was established
      * @param local The local connection endpoint
+     * @param context An optional &quot;context&quot; provided by the user when connection
+     * was requested
      * @param remote The remote connection endpoint
      * @throws IOException If failed to handle the event - in which case connection will be aborted
      */
-    default void connectionEstablished(IoConnector connector, SocketAddress local, SocketAddress remote) throws IOException {
+    default void connectionEstablished(
+            IoConnector connector, SocketAddress local, AttributeRepository context, SocketAddress remote)
+                throws IOException {
         // Do nothing
     }
 
@@ -47,14 +52,16 @@ public interface IoServiceEventListener extends SshdEventListener {
      *
      * @param connector The {@link IoConnector} through which the connection was established
      * @param local The local connection endpoint
+     * @param context An optional &quot;context&quot; provided by the user when connection
+     * was requested
      * @param remote The remote connection endpoint
      * @param reason The reason for aborting - may be an exception thrown by
-     * {@link #connectionEstablished(IoConnector, SocketAddress, SocketAddress) connectionEstablished}
+     * {@link #connectionEstablished(IoConnector, SocketAddress, AttributeRepository, SocketAddress) connectionEstablished}
      * @throws IOException If failed to handle the event - the exception is logged but does not
      * prevent further connections from being accepted
      */
     default void abortEstablishedConnection(
-            IoConnector connector, SocketAddress local, SocketAddress remote, Throwable reason)
+            IoConnector connector, SocketAddress local, AttributeRepository context, SocketAddress remote, Throwable reason)
                 throws IOException {
         // Do nothing
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java
index e8410e7..61eac91 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java
@@ -23,6 +23,7 @@ import java.net.SocketAddress;
 import java.nio.channels.AsynchronousChannelGroup;
 import java.nio.channels.AsynchronousSocketChannel;
 
+import org.apache.sshd.common.AttributeRepository;
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.future.DefaultSshFuture;
 import org.apache.sshd.common.io.IoConnectFuture;
@@ -44,7 +45,7 @@ public class Nio2Connector extends Nio2Service implements IoConnector {
     }
 
     @Override
-    public IoConnectFuture connect(SocketAddress address, SocketAddress localAddress) {
+    public IoConnectFuture connect(SocketAddress address, AttributeRepository context, SocketAddress localAddress) {
         boolean debugEnabled = log.isDebugEnabled();
         if (debugEnabled) {
             log.debug("Connecting to {}", address);
@@ -62,7 +63,8 @@ public class Nio2Connector extends Nio2Service implements IoConnector {
             }
             Nio2CompletionHandler<Void, Object> completionHandler =
                 ValidateUtils.checkNotNull(
-                    createConnectionCompletionHandler(future, socket, getFactoryManager(), getIoHandler()),
+                    createConnectionCompletionHandler(
+                        future, socket, context, getFactoryManager(), getIoHandler()),
                     "No connection completion handler created for %s",
                     address);
             socket.connect(address, null, completionHandler);
@@ -111,20 +113,24 @@ public class Nio2Connector extends Nio2Service implements IoConnector {
     }
 
     protected Nio2CompletionHandler<Void, Object> createConnectionCompletionHandler(
-            IoConnectFuture future, AsynchronousSocketChannel socket, FactoryManager manager, IoHandler handler) {
-        return new ConnectionCompletionHandler(future, socket, manager, handler);
+            IoConnectFuture future, AsynchronousSocketChannel socket,
+            AttributeRepository context, FactoryManager manager, IoHandler handler) {
+        return new ConnectionCompletionHandler(future, socket, context, manager, handler);
     }
 
     protected class ConnectionCompletionHandler extends Nio2CompletionHandler<Void, Object> {
         protected final IoConnectFuture future;
         protected final AsynchronousSocketChannel socket;
+        protected final AttributeRepository context;
         protected final FactoryManager manager;
         protected final IoHandler handler;
 
         protected ConnectionCompletionHandler(
-                IoConnectFuture future, AsynchronousSocketChannel socket, FactoryManager manager, IoHandler handler) {
+                IoConnectFuture future, AsynchronousSocketChannel socket,
+                AttributeRepository context, FactoryManager manager, IoHandler handler) {
             this.future = future;
             this.socket = socket;
+            this.context = context;
             this.manager = manager;
             this.handler = handler;
         }
@@ -138,10 +144,14 @@ public class Nio2Connector extends Nio2Service implements IoConnector {
                 if (listener != null) {
                     SocketAddress local = socket.getLocalAddress();
                     SocketAddress remote = socket.getRemoteAddress();
-                    listener.connectionEstablished(Nio2Connector.this, local, remote);
+                    listener.connectionEstablished(Nio2Connector.this, local, context, remote);
                 }
 
                 Nio2Session session = createSession(manager, handler, socket);
+                if (context != null) {
+                    session.setAttribute(AttributeRepository.class, context);
+                }
+
                 handler.sessionCreated(session);
                 sessionId = session.getId();
                 sessions.put(sessionId, session);
@@ -162,7 +172,8 @@ public class Nio2Connector extends Nio2Service implements IoConnector {
                     try {
                         SocketAddress localAddress = socket.getLocalAddress();
                         SocketAddress remoteAddress = socket.getRemoteAddress();
-                        listener.abortEstablishedConnection(Nio2Connector.this, localAddress, remoteAddress, t);
+                        listener.abortEstablishedConnection(
+                            Nio2Connector.this, localAddress, context, remoteAddress, t);
                     } catch (Exception e) {
                         if (debugEnabled) {
                             log.debug("onCompleted() listener=" + listener + " ignoring abort event exception", e);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
index c02c039..25cbf2f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
@@ -82,6 +82,7 @@ public abstract class SessionHelper extends AbstractKexFactoryManager implements
      * The underlying network session
      */
     private final IoSession ioSession;
+
     /**
      * The session specific properties
      */

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
index 1007494..ea0e365 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
@@ -236,7 +236,7 @@ public class TcpipServerChannel extends AbstractServerChannel implements Forward
 
         IoServiceFactory ioServiceFactory = manager.getIoServiceFactory();
         connector = ioServiceFactory.createConnector(handler);
-        IoConnectFuture future = connector.connect(address.toInetSocketAddress(), getLocalAddress());
+        IoConnectFuture future = connector.connect(address.toInetSocketAddress(), null, getLocalAddress());
         future.addListener(future1 -> handleChannelConnectResult(f, future1));
         return f;
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java b/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
index 12c416d..520c862 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
@@ -24,8 +24,13 @@ import java.nio.charset.StandardCharsets;
 import java.rmi.RemoteException;
 import java.rmi.ServerException;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.sshd.client.SshClient;
+import org.apache.sshd.common.AttributeRepository;
+import org.apache.sshd.common.AttributeRepository.AttributeKey;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionListener;
 import org.apache.sshd.server.SshServer;
 import org.apache.sshd.util.test.BaseTestSupport;
 import org.apache.sshd.util.test.CommandExecutionHelper;
@@ -41,6 +46,9 @@ import org.junit.runners.MethodSorters;
  */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class ClientSessionTest extends BaseTestSupport {
+    private static final long CONNECT_TIMEOUT = 7L;
+    private static final long AUTH_TIMEOUT = 5L;
+
     private static SshServer sshd;
     private static SshClient client;
     private static int port;
@@ -97,9 +105,11 @@ public class ClientSessionTest extends BaseTestSupport {
             }
         });
 
-        try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
+        try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port)
+                    .verify(CONNECT_TIMEOUT, TimeUnit.SECONDS)
+                    .getSession()) {
             session.addPasswordIdentity(getCurrentTestName());
-            session.auth().verify(5L, TimeUnit.SECONDS);
+            session.auth().verify(AUTH_TIMEOUT, TimeUnit.SECONDS);
 
             // NOTE !!! The LF is only because we are using a buffered reader on the server end to read the command
             String actualResponse = session.executeRemoteCommand(expectedCommand + "\n");
@@ -127,9 +137,11 @@ public class ClientSessionTest extends BaseTestSupport {
         });
 
         String actualErrorMessage = null;
-        try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
+        try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port)
+                    .verify(CONNECT_TIMEOUT, TimeUnit.SECONDS)
+                    .getSession()) {
             session.addPasswordIdentity(getCurrentTestName());
-            session.auth().verify(5L, TimeUnit.SECONDS);
+            session.auth().verify(AUTH_TIMEOUT, TimeUnit.SECONDS);
 
             // NOTE !!! The LF is only because we are using a buffered reader on the server end to read the command
             String response = session.executeRemoteCommand(expectedCommand + "\n");
@@ -175,9 +187,11 @@ public class ClientSessionTest extends BaseTestSupport {
         });
 
         String actualErrorMessage = null;
-        try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
+        try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port)
+                    .verify(CONNECT_TIMEOUT, TimeUnit.SECONDS)
+                    .getSession()) {
             session.addPasswordIdentity(getCurrentTestName());
-            session.auth().verify(5L, TimeUnit.SECONDS);
+            session.auth().verify(AUTH_TIMEOUT, TimeUnit.SECONDS);
 
             // NOTE !!! The LF is only because we are using a buffered reader on the server end to read the command
             String response = session.executeRemoteCommand(expectedCommand + "\n");
@@ -197,4 +211,33 @@ public class ClientSessionTest extends BaseTestSupport {
 
         assertEquals("Mismatched captured error code", Integer.toString(expectedErrorCode), actualErrorMessage);
     }
+
+    @Test   // see SSHD-859
+    public void testConnectionContextPropagation() throws Exception {
+        AttributeRepository expected = AttributeRepository.ofKeyValuePair(
+            new AttributeKey<String>(), getCurrentTestName());
+        AtomicInteger creationCount = new AtomicInteger(0);
+        SessionListener listener = new SessionListener() {
+            @Override
+            public void sessionCreated(Session session) {
+                AttributeRepository actual = ((ClientSession) session).getConnectionContext();
+                assertSame("Mismatched connection context", expected, actual);
+                creationCount.incrementAndGet();
+            }
+        };
+
+        try {
+            client.addSessionListener(listener);
+
+            try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port, expected)
+                        .verify(CONNECT_TIMEOUT, TimeUnit.SECONDS)
+                        .getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(AUTH_TIMEOUT, TimeUnit.SECONDS);
+                assertEquals("Session listener invocation count mismatch", 1, creationCount.getAndSet(0));
+            }
+        } finally {
+            client.removeSessionListener(listener);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java
----------------------------------------------------------------------
diff --git a/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java b/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java
index e7229ec..deeb371 100644
--- a/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java
+++ b/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaConnector.java
@@ -29,6 +29,7 @@ import org.apache.mina.core.service.IoProcessor;
 import org.apache.mina.core.session.IoSession;
 import org.apache.mina.transport.socket.nio.NioSession;
 import org.apache.mina.transport.socket.nio.NioSocketConnector;
+import org.apache.sshd.common.AttributeRepository;
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.future.DefaultSshFuture;
 import org.apache.sshd.common.io.IoConnectFuture;
@@ -79,10 +80,12 @@ public class MinaConnector extends MinaService implements org.apache.sshd.common
         IoServiceEventListener listener = getIoServiceEventListener();
         SocketAddress local = session.getLocalAddress();
         SocketAddress remote = session.getRemoteAddress();
+        AttributeRepository context =
+            (AttributeRepository) session.getAttribute(AttributeRepository.class);
         try {
             if (listener != null) {
                 try {
-                    listener.connectionEstablished(this, local, remote);
+                    listener.connectionEstablished(this, local, context, remote);
                 } catch (Exception e) {
                     session.closeNow();
                     throw e;
@@ -93,7 +96,7 @@ public class MinaConnector extends MinaService implements org.apache.sshd.common
         } catch (Exception e) {
             if (listener != null) {
                 try {
-                    listener.abortEstablishedConnection(this, local, remote, e);
+                    listener.abortEstablishedConnection(this, local, context, remote, e);
                 } catch (Exception exc) {
                     if (log.isDebugEnabled()) {
                         log.debug("sessionCreated(" + session + ") listener=" + listener + " ignoring abort event exception", exc);
@@ -106,7 +109,7 @@ public class MinaConnector extends MinaService implements org.apache.sshd.common
     }
 
     @Override
-    public IoConnectFuture connect(SocketAddress address, SocketAddress localAddress) {
+    public IoConnectFuture connect(SocketAddress address, AttributeRepository context, SocketAddress localAddress) {
         class Future extends DefaultSshFuture<IoConnectFuture> implements IoConnectFuture {
             Future(Object lock) {
                 super(address, lock);
@@ -131,6 +134,10 @@ public class MinaConnector extends MinaService implements org.apache.sshd.common
 
             @Override
             public void setSession(org.apache.sshd.common.io.IoSession session) {
+                if (context != null) {
+                    session.setAttribute(AttributeRepository.class, context);
+                }
+
                 setValue(session);
             }
 
@@ -142,7 +149,13 @@ public class MinaConnector extends MinaService implements org.apache.sshd.common
 
         IoConnectFuture future = new Future(null);
         IoConnector connector = getConnector();
-        ConnectFuture connectFuture = connector.connect(address, localAddress);
+        ConnectFuture connectFuture = connector.connect(
+            address, localAddress,
+            (s, f) -> {
+                if (context != null) {
+                    s.setAttribute(AttributeRepository.class, context);
+                }
+            });
         connectFuture.addListener((IoFutureListener<ConnectFuture>) cf -> {
             Throwable t = cf.getException();
             if (t != null) {
@@ -152,6 +165,9 @@ public class MinaConnector extends MinaService implements org.apache.sshd.common
             } else {
                 IoSession ioSession = cf.getSession();
                 org.apache.sshd.common.io.IoSession sshSession = getSession(ioSession);
+                if (context != null) {
+                    sshSession.setAttribute(AttributeRepository.class, context);
+                }
                 future.setSession(sshSession);
             }
         });

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java
----------------------------------------------------------------------
diff --git a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java
index 9230803..1c7bdf9 100644
--- a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java
+++ b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java
@@ -21,6 +21,7 @@ package org.apache.sshd.netty;
 
 import java.net.SocketAddress;
 
+import org.apache.sshd.common.AttributeRepository;
 import org.apache.sshd.common.future.DefaultSshFuture;
 import org.apache.sshd.common.io.IoConnectFuture;
 import org.apache.sshd.common.io.IoConnector;
@@ -63,10 +64,13 @@ public class NettyIoConnector extends NettyIoService implements IoConnector {
                     IoServiceEventListener listener = getIoServiceEventListener();
                     SocketAddress local = ch.localAddress();
                     SocketAddress remote = ch.remoteAddress();
+                    AttributeRepository context = ch.hasAttr(CONTEXT_KEY)
+                        ? ch.attr(CONTEXT_KEY).get()
+                        : null;
                     try {
                         if (listener != null) {
                             try {
-                                listener.connectionEstablished(NettyIoConnector.this, local, remote);
+                                listener.connectionEstablished(NettyIoConnector.this, local, context, remote);
                             } catch (Exception e) {
                                 ch.close();
                                 throw e;
@@ -75,13 +79,17 @@ public class NettyIoConnector extends NettyIoService implements IoConnector {
 
                         @SuppressWarnings("resource")
                         NettyIoSession session = new NettyIoSession(NettyIoConnector.this, handler);
+                        if (context != null) {
+                            session.setAttribute(AttributeRepository.class, context);
+                        }
+
                         ChannelPipeline p = ch.pipeline();
                         p.addLast(new LoggingHandler(LogLevel.INFO));   // TODO make this configurable
                         p.addLast(session.adapter);
                     } catch (Exception e) {
                         if (listener != null) {
                             try {
-                                listener.abortEstablishedConnection(NettyIoConnector.this, local, remote, e);
+                                listener.abortEstablishedConnection(NettyIoConnector.this, local, context, remote, e);
                             } catch (Exception exc) {
                                 if (log.isDebugEnabled()) {
                                     log.debug("initChannel(" + ch + ") listener=" + listener + " ignoring abort event exception", exc);
@@ -96,7 +104,7 @@ public class NettyIoConnector extends NettyIoService implements IoConnector {
     }
 
     @Override
-    public IoConnectFuture connect(SocketAddress address, SocketAddress localAddress) {
+    public IoConnectFuture connect(SocketAddress address, AttributeRepository context, SocketAddress localAddress) {
         boolean debugEnabled = log.isDebugEnabled();
         if (debugEnabled) {
             log.debug("Connecting to {}", address);
@@ -111,6 +119,10 @@ public class NettyIoConnector extends NettyIoService implements IoConnector {
         }
         Channel channel = chf.channel();
         channel.attr(CONNECT_FUTURE_KEY).set(future);
+        if (context != null) {
+            channel.attr(CONTEXT_KEY).set(context);
+        }
+
         chf.addListener(cf -> {
             Throwable t = chf.cause();
             if (t != null) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoService.java
----------------------------------------------------------------------
diff --git a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoService.java b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoService.java
index ea2ca8f..4e36da7 100644
--- a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoService.java
+++ b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoService.java
@@ -24,6 +24,7 @@ import java.util.Objects;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicLong;
 
+import org.apache.sshd.common.AttributeRepository;
 import org.apache.sshd.common.io.IoConnectFuture;
 import org.apache.sshd.common.io.IoHandler;
 import org.apache.sshd.common.io.IoService;
@@ -42,6 +43,8 @@ public abstract class NettyIoService extends AbstractCloseable implements IoServ
 
     public static final AttributeKey<IoConnectFuture> CONNECT_FUTURE_KEY =
         AttributeKey.valueOf(IoConnectFuture.class.getName());
+    public static final AttributeKey<AttributeRepository> CONTEXT_KEY =
+        AttributeKey.valueOf(AttributeRepository.class.getName());
 
     protected final AtomicLong sessionSeq = new AtomicLong();
     protected final Map<Long, IoSession> sessions = new ConcurrentHashMap<>();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-sftp/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
----------------------------------------------------------------------
diff --git a/sshd-sftp/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java b/sshd-sftp/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
index d4db7c7..3c171d0 100644
--- a/sshd-sftp/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
+++ b/sshd-sftp/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
@@ -73,8 +73,8 @@ import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.client.subsystem.sftp.SftpClient.Attributes;
 import org.apache.sshd.common.PropertyResolver;
 import org.apache.sshd.common.PropertyResolverUtils;
+import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.SshException;
-import org.apache.sshd.common.config.ConfigFileReaderSupport;
 import org.apache.sshd.common.io.IoSession;
 import org.apache.sshd.common.subsystem.sftp.SftpConstants;
 import org.apache.sshd.common.subsystem.sftp.SftpException;
@@ -181,7 +181,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
         String host = ValidateUtils.checkNotNullAndNotEmpty(uri.getHost(), "Host not provided");
         int port = uri.getPort();
         if (port <= 0) {
-            port = ConfigFileReaderSupport.DEFAULT_PORT;
+            port = SshConstants.DEFAULT_PORT;
         }
 
         String userInfo = ValidateUtils.checkNotNullAndNotEmpty(uri.getUserInfo(), "UserInfo not provided");
@@ -1220,13 +1220,13 @@ public class SftpFileSystemProvider extends FileSystemProvider {
             InetSocketAddress inetAddr = (InetSocketAddress) addr;
             return getFileSystemIdentifier(inetAddr.getHostString(), inetAddr.getPort(), username);
         } else {
-            return getFileSystemIdentifier(addr.toString(), ConfigFileReaderSupport.DEFAULT_PORT, username);
+            return getFileSystemIdentifier(addr.toString(), SshConstants.DEFAULT_PORT, username);
         }
     }
 
     public static String getFileSystemIdentifier(String host, int port, String username) {
         return GenericUtils.trimToEmpty(host) + ':'
-                + ((port <= 0) ? ConfigFileReaderSupport.DEFAULT_PORT : port) + ':'
+                + ((port <= 0) ? SshConstants.DEFAULT_PORT : port) + ':'
                 + GenericUtils.trimToEmpty(username);
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/403402f5/sshd-spring-sftp/src/main/java/org/apache/sshd/spring/integration/sftp/ApacheSshdSftpSessionFactory.java
----------------------------------------------------------------------
diff --git a/sshd-spring-sftp/src/main/java/org/apache/sshd/spring/integration/sftp/ApacheSshdSftpSessionFactory.java b/sshd-spring-sftp/src/main/java/org/apache/sshd/spring/integration/sftp/ApacheSshdSftpSessionFactory.java
index 7dc2eb0..dfa5855 100644
--- a/sshd-spring-sftp/src/main/java/org/apache/sshd/spring/integration/sftp/ApacheSshdSftpSessionFactory.java
+++ b/sshd-spring-sftp/src/main/java/org/apache/sshd/spring/integration/sftp/ApacheSshdSftpSessionFactory.java
@@ -37,7 +37,7 @@ import org.apache.sshd.client.subsystem.sftp.SftpClient.DirEntry;
 import org.apache.sshd.client.subsystem.sftp.SftpClientFactory;
 import org.apache.sshd.client.subsystem.sftp.SftpVersionSelector;
 import org.apache.sshd.common.PropertyResolverUtils;
-import org.apache.sshd.common.config.ConfigFileReaderSupport;
+import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.config.keys.FilePasswordProvider;
 import org.apache.sshd.common.config.keys.KeyUtils;
 import org.apache.sshd.common.config.keys.loader.pem.PEMResourceParserUtils;
@@ -72,7 +72,7 @@ public class ApacheSshdSftpSessionFactory
     private final AtomicReference<ClientSession> sharedSessionHolder = new AtomicReference<>();
 
     private volatile String hostValue;
-    private volatile int portValue = ConfigFileReaderSupport.DEFAULT_PORT;
+    private volatile int portValue = SshConstants.DEFAULT_PORT;
     private volatile String userValue;
     private volatile String passwordValue;
     private volatile Resource privateKey;


Mime
View raw message