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:d...@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 "context" 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:d...@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 "context" 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 "context" 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 "context" 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 "context" 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 "context" 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 "context" 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:d...@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:d...@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 "context" 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 "context" 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 "context" 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;