You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2018/11/19 12:50:16 UTC
[1/3] mina-sshd git commit: [SSHD-865] 'SshClient' and
'ClientSession' use only a KeyIdentityProvider instead of KeyPairProvider
Repository: mina-sshd
Updated Branches:
refs/heads/master e88a08326 -> fc7a8e7c2
[SSHD-865] 'SshClient' and 'ClientSession' use only a KeyIdentityProvider instead of KeyPairProvider
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/e849cc5a
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/e849cc5a
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/e849cc5a
Branch: refs/heads/master
Commit: e849cc5a4c1fc1d14ad556cd656b6bca54dd0840
Parents: e88a083
Author: Lyor Goldstein <lg...@apache.org>
Authored: Sun Nov 18 15:32:47 2018 +0200
Committer: Lyor Goldstein <lg...@apache.org>
Committed: Mon Nov 19 14:50:09 2018 +0200
----------------------------------------------------------------------
CHANGES.md | 3 ++
.../sshd/cli/client/SshClientCliSupport.java | 5 +--
.../keys/DefaultClientIdentitiesWatcher.java | 3 +-
.../keyprovider/KeyIdentityProviderHolder.java | 36 ++++++++++++++++++++
.../client/ClientAuthenticationManager.java | 7 ++--
.../java/org/apache/sshd/client/SshClient.java | 34 ++++++++++++------
.../client/session/AbstractClientSession.java | 13 +++++++
.../sshd/client/session/ClientSession.java | 2 +-
.../common/kex/AbstractKexFactoryManager.java | 14 --------
.../sshd/common/kex/KexFactoryManager.java | 3 +-
.../server/ServerAuthenticationManager.java | 3 +-
.../java/org/apache/sshd/server/SshServer.java | 12 +++++++
.../server/global/OpenSshHostKeysHandler.java | 11 +++---
.../server/session/AbstractServerSession.java | 15 ++++++++
.../client/ClientAuthenticationManagerTest.java | 14 ++++----
.../hosts/HostConfigEntryResolverTest.java | 12 +++----
.../sshd/common/auth/AuthenticationTest.java | 3 +-
.../sshd/common/kex/KexFactoryManagerTest.java | 11 ------
.../server/ServerAuthenticationManagerTest.java | 11 ++++++
.../sshd/util/test/CoreTestSupportUtils.java | 4 +--
20 files changed, 150 insertions(+), 66 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/CHANGES.md
----------------------------------------------------------------------
diff --git a/CHANGES.md b/CHANGES.md
index 60f941b..3ca0d3d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -57,6 +57,9 @@ accept also an `AttributeRepository` connection context argument (propagated fro
* `ApacheSshdSftpSessionFactory#get/setPrivateKey` has been renamed to `get/setPrivateKeyLocation`.
+* `SshClient` and `ClientSession` use a `KeyIdentityProvider` instead of a full blown `KeyPairProvider`.
+`KeyPairProvider` is used only in the context of an `SshServer` and/or `ServerSession`.
+
## Behavioral changes and enhancements
* [SSHD-849](https://issues.apache.org/jira/browse/SSHD-849) - Data forwarding code makes sure all
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java
----------------------------------------------------------------------
diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java b/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java
index 9286324..4741e72 100644
--- a/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java
+++ b/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java
@@ -343,7 +343,8 @@ public abstract class SshClientCliSupport extends CliSupport {
}
}
- public static FileKeyPairProvider setupSessionIdentities(ClientFactoryManager client, Collection<? extends Path> identities,
+ public static FileKeyPairProvider setupSessionIdentities(
+ ClientFactoryManager client, Collection<? extends Path> identities,
BufferedReader stdin, PrintStream stdout, PrintStream stderr)
throws Throwable {
client.setFilePasswordProvider((session, file, index) -> {
@@ -362,7 +363,7 @@ public abstract class SshClientCliSupport extends CliSupport {
}
};
provider.setPaths(identities);
- client.setKeyPairProvider(provider);
+ client.setKeyIdentityProvider(provider);
return provider;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
index 3afa129..ee710c3 100644
--- a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
@@ -40,7 +40,8 @@ public class DefaultClientIdentitiesWatcher extends BuiltinClientIdentitiesWatch
this(true, loader, provider, strict);
}
- public DefaultClientIdentitiesWatcher(boolean supportedOnly, ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
+ public DefaultClientIdentitiesWatcher(
+ boolean supportedOnly, ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
this(supportedOnly,
GenericUtils.supplierOf(Objects.requireNonNull(loader, "No client identity loader")),
GenericUtils.supplierOf(Objects.requireNonNull(provider, "No password provider")),
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProviderHolder.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProviderHolder.java b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProviderHolder.java
new file mode 100644
index 0000000..b33064a
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProviderHolder.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.common.keyprovider;
+
+/**
+ * TODO Add javadoc
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface KeyIdentityProviderHolder {
+ /**
+ * @return The {@link KeyIdentityProvider} used to provide key-pair(s)
+ * for public key authentication
+ */
+ KeyIdentityProvider getKeyIdentityProvider();
+
+ void setKeyIdentityProvider(KeyIdentityProvider provider);
+
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/main/java/org/apache/sshd/client/ClientAuthenticationManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/ClientAuthenticationManager.java b/sshd-core/src/main/java/org/apache/sshd/client/ClientAuthenticationManager.java
index a9ae68c..4b84752 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/ClientAuthenticationManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/ClientAuthenticationManager.java
@@ -33,7 +33,7 @@ import org.apache.sshd.client.auth.password.PasswordIdentityProvider;
import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.NamedResource;
-import org.apache.sshd.common.keyprovider.KeyPairProviderHolder;
+import org.apache.sshd.common.keyprovider.KeyIdentityProviderHolder;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
@@ -41,7 +41,7 @@ import org.apache.sshd.common.util.ValidateUtils;
* Holds information required for the client to perform authentication with the server
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface ClientAuthenticationManager extends KeyPairProviderHolder {
+public interface ClientAuthenticationManager extends KeyIdentityProviderHolder {
/**
* Ordered comma separated list of authentications methods.
@@ -74,7 +74,8 @@ public interface ClientAuthenticationManager extends KeyPairProviderHolder {
* candidates
*
* @return The {@link PasswordIdentityProvider} instance - ignored if {@code null}
- * (i.e., no passwords available)
+ * (i.e., no passwords available).
+ * @see #addPasswordIdentity(String)
*/
PasswordIdentityProvider getPasswordIdentityProvider();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/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 fba078c..796d781 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
@@ -80,6 +80,7 @@ import org.apache.sshd.common.helpers.AbstractFactoryManager;
import org.apache.sshd.common.io.IoConnectFuture;
import org.apache.sshd.common.io.IoConnector;
import org.apache.sshd.common.io.IoSession;
+import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.session.helpers.AbstractSession;
import org.apache.sshd.common.util.GenericUtils;
@@ -167,6 +168,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
private ServerKeyVerifier serverKeyVerifier;
private HostConfigEntryResolver hostConfigEntryResolver;
private ClientIdentityLoader clientIdentityLoader;
+ private KeyIdentityProvider keyIdentityProvider;
private FilePasswordProvider filePasswordProvider;
private PasswordIdentityProvider passwordIdentityProvider;
@@ -325,6 +327,16 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
}
@Override
+ public KeyIdentityProvider getKeyIdentityProvider() {
+ return keyIdentityProvider;
+ }
+
+ @Override
+ public void setKeyIdentityProvider(KeyIdentityProvider keyIdentityProvider) {
+ this.keyIdentityProvider = keyIdentityProvider;
+ }
+
+ @Override
protected void checkConfig() {
super.checkConfig();
@@ -335,17 +347,17 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
Objects.requireNonNull(getFilePasswordProvider(), "FilePasswordProvider not set");
// if no client identities override use the default
- KeyPairProvider defaultIdentities = getKeyPairProvider();
+ KeyIdentityProvider defaultIdentities = getKeyIdentityProvider();
if (defaultIdentities == null) {
- setKeyPairProvider(new DefaultClientIdentitiesWatcher(this::getClientIdentityLoader, this::getFilePasswordProvider));
+ setKeyIdentityProvider(new DefaultClientIdentitiesWatcher(this::getClientIdentityLoader, this::getFilePasswordProvider));
}
// Register the additional agent forwarding channel if needed
SshAgentFactory agentFactory = getAgentFactory();
if (agentFactory != null) {
List<NamedFactory<Channel>> forwarders =
- ValidateUtils.checkNotNullAndNotEmpty(
- agentFactory.getChannelForwardingFactories(this), "No agent channel forwarding factories for %s", agentFactory);
+ ValidateUtils.checkNotNullAndNotEmpty(
+ agentFactory.getChannelForwardingFactories(this), "No agent channel forwarding factories for %s", agentFactory);
List<NamedFactory<Channel>> factories = getChannelFactories();
if (GenericUtils.isEmpty(factories)) {
factories = forwarders;
@@ -656,15 +668,15 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
protected void setupDefaultSessionIdentities(ClientSession session) {
// check if session listener intervened
- KeyPairProvider kpSession = session.getKeyPairProvider();
- KeyPairProvider kpClient = getKeyPairProvider();
+ KeyIdentityProvider kpSession = session.getKeyIdentityProvider();
+ KeyIdentityProvider kpClient = getKeyIdentityProvider();
boolean debugEnabled = log.isDebugEnabled();
if (kpSession == null) {
- session.setKeyPairProvider(kpClient);
+ session.setKeyIdentityProvider(kpClient);
} else {
if (kpSession != kpClient) {
if (debugEnabled) {
- log.debug("setupDefaultSessionIdentities({}) key-pair provider override", session);
+ log.debug("setupDefaultSessionIdentities({}) key identity provider override", session);
}
}
}
@@ -828,7 +840,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
* @param options The {@link LinkOption}s to apply when checking
* for existence
* @return The updated <tt>client</tt> instance - provided a non-{@code null}
- * {@link KeyPairProvider} was generated
+ * {@link KeyIdentityProvider} was generated
* @throws IOException If failed to access the file system
* @throws GeneralSecurityException If failed to load the keys
* @see ClientIdentity#loadDefaultKeyPairProvider(Path, boolean, boolean, FilePasswordProvider, LinkOption...)
@@ -836,10 +848,10 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
public static <C extends SshClient> C setKeyPairProvider(
C client, Path dir, boolean strict, boolean supportedOnly, FilePasswordProvider provider, LinkOption... options)
throws IOException, GeneralSecurityException {
- KeyPairProvider kpp =
+ KeyIdentityProvider kpp =
ClientIdentity.loadDefaultKeyPairProvider(dir, strict, supportedOnly, provider, options);
if (kpp != null) {
- client.setKeyPairProvider(kpp);
+ client.setKeyIdentityProvider(kpp);
}
return client;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/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 1c329ef..57485ad 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
@@ -58,6 +58,7 @@ import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.IoWriteFuture;
import org.apache.sshd.common.kex.KexProposalOption;
import org.apache.sshd.common.kex.KexState;
+import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.apache.sshd.common.session.ConnectionService;
import org.apache.sshd.common.session.SessionContext;
import org.apache.sshd.common.session.helpers.AbstractConnectionService;
@@ -80,6 +81,7 @@ public abstract class AbstractClientSession extends AbstractSession implements C
private ServerKeyVerifier serverKeyVerifier;
private UserInteraction userInteraction;
private PasswordIdentityProvider passwordIdentityProvider;
+ private KeyIdentityProvider keyIdentityProvider;
private List<NamedFactory<UserAuth>> userAuthFactories;
private SocketAddress connectAddress;
private ClientProxyConnector proxyConnector;
@@ -160,6 +162,17 @@ public abstract class AbstractClientSession extends AbstractSession implements C
}
@Override
+ public KeyIdentityProvider getKeyIdentityProvider() {
+ ClientFactoryManager manager = getFactoryManager();
+ return resolveEffectiveProvider(KeyIdentityProvider.class, keyIdentityProvider, manager.getKeyIdentityProvider());
+ }
+
+ @Override
+ public void setKeyIdentityProvider(KeyIdentityProvider keyIdentityProvider) {
+ this.keyIdentityProvider = keyIdentityProvider;
+ }
+
+ @Override
public ClientProxyConnector getClientProxyConnector() {
ClientFactoryManager manager = getFactoryManager();
return resolveEffectiveProvider(ClientProxyConnector.class, proxyConnector, manager.getClientProxyConnector());
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/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 b7b5377..59df28c 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
@@ -381,7 +381,7 @@ public interface ClientSession
return (session == null)
? KeyIdentityProvider.EMPTY_KEYS_PROVIDER
: KeyIdentityProvider.resolveKeyIdentityProvider(
- session.getRegisteredIdentities(), session.getKeyPairProvider());
+ session.getRegisteredIdentities(), session.getKeyIdentityProvider());
}
/**
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractKexFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractKexFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractKexFactoryManager.java
index aa111af..eb502e4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractKexFactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractKexFactoryManager.java
@@ -25,7 +25,6 @@ import java.util.List;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.cipher.Cipher;
import org.apache.sshd.common.compression.Compression;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.mac.Mac;
import org.apache.sshd.common.signature.Signature;
import org.apache.sshd.common.util.GenericUtils;
@@ -43,7 +42,6 @@ public abstract class AbstractKexFactoryManager
private List<NamedFactory<Compression>> compressionFactories;
private List<NamedFactory<Mac>> macFactories;
private List<NamedFactory<Signature>> signatureFactories;
- private KeyPairProvider keyPairProvider;
protected AbstractKexFactoryManager() {
this(null);
@@ -117,18 +115,6 @@ public abstract class AbstractKexFactoryManager
this.signatureFactories = signatureFactories;
}
- @Override
- public KeyPairProvider getKeyPairProvider() {
- KexFactoryManager parent = getDelegate();
- return resolveEffectiveProvider(KeyPairProvider.class, keyPairProvider,
- (parent == null) ? null : parent.getKeyPairProvider());
- }
-
- @Override
- public void setKeyPairProvider(KeyPairProvider keyPairProvider) {
- this.keyPairProvider = keyPairProvider;
- }
-
protected <V> List<NamedFactory<V>> resolveEffectiveFactories(
Class<V> factoryType, List<NamedFactory<V>> local, List<NamedFactory<V>> inherited) {
if (GenericUtils.isEmpty(local)) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/main/java/org/apache/sshd/common/kex/KexFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/KexFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/KexFactoryManager.java
index 7aa8cba..6e46154 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/KexFactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/KexFactoryManager.java
@@ -30,7 +30,6 @@ import org.apache.sshd.common.cipher.BuiltinCiphers;
import org.apache.sshd.common.cipher.Cipher;
import org.apache.sshd.common.compression.BuiltinCompressions;
import org.apache.sshd.common.compression.Compression;
-import org.apache.sshd.common.keyprovider.KeyPairProviderHolder;
import org.apache.sshd.common.mac.BuiltinMacs;
import org.apache.sshd.common.mac.Mac;
import org.apache.sshd.common.signature.SignatureFactoriesManager;
@@ -41,7 +40,7 @@ import org.apache.sshd.common.util.ValidateUtils;
* Holds KEX negotiation stage configuration
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface KexFactoryManager extends KeyPairProviderHolder, SignatureFactoriesManager {
+public interface KexFactoryManager extends SignatureFactoriesManager {
/**
* Retrieve the list of named factories for <code>KeyExchange</code>.
*
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java b/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java
index 1d3a96d..c9a1b51 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java
@@ -27,6 +27,7 @@ import java.util.List;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.keyprovider.KeyPairProviderHolder;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.server.auth.BuiltinUserAuthFactories;
@@ -46,7 +47,7 @@ import org.apache.sshd.server.auth.pubkey.UserAuthPublicKeyFactory;
* Holds providers and helpers related to the server side authentication process
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface ServerAuthenticationManager {
+public interface ServerAuthenticationManager extends KeyPairProviderHolder {
/**
* Key used to retrieve the value in the configuration properties map
* of the maximum number of failed authentication requests before the
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
index c5a6918..72ed860 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
@@ -40,6 +40,7 @@ import org.apache.sshd.common.helpers.AbstractFactoryManager;
import org.apache.sshd.common.io.IoAcceptor;
import org.apache.sshd.common.io.IoServiceFactory;
import org.apache.sshd.common.io.IoSession;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.session.helpers.AbstractSession;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
@@ -103,6 +104,7 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
private CommandFactory commandFactory;
private List<NamedFactory<Command>> subsystemFactories;
private List<NamedFactory<UserAuth>> userAuthFactories;
+ private KeyPairProvider keyPairProvider;
private PasswordAuthenticator passwordAuthenticator;
private PublickeyAuthenticator publickeyAuthenticator;
private KeyboardInteractiveAuthenticator interactiveAuthenticator;
@@ -249,6 +251,16 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
}
@Override
+ public KeyPairProvider getKeyPairProvider() {
+ return keyPairProvider;
+ }
+
+ @Override
+ public void setKeyPairProvider(KeyPairProvider keyPairProvider) {
+ this.keyPairProvider = keyPairProvider;
+ }
+
+ @Override
protected void checkConfig() {
super.checkConfig();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/main/java/org/apache/sshd/server/global/OpenSshHostKeysHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/OpenSshHostKeysHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/OpenSshHostKeysHandler.java
index 35a7d68..c3f9477 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/global/OpenSshHostKeysHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/global/OpenSshHostKeysHandler.java
@@ -40,6 +40,7 @@ import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.apache.sshd.common.util.buffer.keys.BufferPublicKeyParser;
+import org.apache.sshd.server.session.ServerSession;
/**
* An initial handler for "hostkeys-prove-00@openssh.com" request
@@ -90,10 +91,10 @@ public class OpenSshHostKeysHandler extends AbstractOpenSshHostKeysHandler imple
// according to the specification there MUST be reply required by the server
ValidateUtils.checkTrue(wantReply, "No reply required for host keys of %s", session);
Collection<? extends NamedFactory<Signature>> factories =
- ValidateUtils.checkNotNullAndNotEmpty(
- SignatureFactoriesManager.resolveSignatureFactories(this, session),
- "No signature factories available for host keys of session=%s",
- session);
+ ValidateUtils.checkNotNullAndNotEmpty(
+ SignatureFactoriesManager.resolveSignatureFactories(this, session),
+ "No signature factories available for host keys of session=%s",
+ session);
if (log.isDebugEnabled()) {
log.debug("handleHostKeys({})[want-reply={}] received {} keys - factories={}",
session, wantReply, GenericUtils.size(keys), NamedResource.getNames(factories));
@@ -104,7 +105,7 @@ public class OpenSshHostKeysHandler extends AbstractOpenSshHostKeysHandler imple
Buffer buf = new ByteArrayBuffer();
byte[] sessionId = session.getSessionId();
- KeyPairProvider kpp = Objects.requireNonNull(session.getKeyPairProvider(), "No server keys provider");
+ KeyPairProvider kpp = Objects.requireNonNull(((ServerSession) session).getKeyPairProvider(), "No server keys provider");
for (PublicKey k : keys) {
String keyType = KeyUtils.getKeyType(k);
Signature verifier = ValidateUtils.checkNotNull(
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
index 6af869e..2a5209c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
@@ -40,6 +40,7 @@ import org.apache.sshd.common.auth.AbstractUserAuthServiceFactory;
import org.apache.sshd.common.io.IoService;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.IoWriteFuture;
+import org.apache.sshd.common.kex.KexFactoryManager;
import org.apache.sshd.common.kex.KexProposalOption;
import org.apache.sshd.common.kex.KexState;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
@@ -50,6 +51,7 @@ import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.server.ServerAuthenticationManager;
import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.auth.UserAuth;
import org.apache.sshd.server.auth.WelcomeBannerPhase;
@@ -73,6 +75,7 @@ public abstract class AbstractServerSession extends AbstractSession implements S
private GSSAuthenticator gssAuthenticator;
private HostBasedAuthenticator hostBasedAuthenticator;
private List<NamedFactory<UserAuth>> userAuthFactories;
+ private KeyPairProvider keyPairProvider;
protected AbstractServerSession(ServerFactoryManager factoryManager, IoSession ioSession) {
super(true, factoryManager, ioSession);
@@ -168,6 +171,18 @@ public abstract class AbstractServerSession extends AbstractSession implements S
this.userAuthFactories = userAuthFactories; // OK if null/empty - inherit from parent
}
+ @Override
+ public KeyPairProvider getKeyPairProvider() {
+ KexFactoryManager parent = getDelegate();
+ return resolveEffectiveProvider(KeyPairProvider.class, keyPairProvider,
+ (parent == null) ? null : ((ServerAuthenticationManager) parent).getKeyPairProvider());
+ }
+
+ @Override
+ public void setKeyPairProvider(KeyPairProvider keyPairProvider) {
+ this.keyPairProvider = keyPairProvider;
+ }
+
/**
* Sends the server identification + any extra header lines
*
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/test/java/org/apache/sshd/client/ClientAuthenticationManagerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/ClientAuthenticationManagerTest.java b/sshd-core/src/test/java/org/apache/sshd/client/ClientAuthenticationManagerTest.java
index 30ce313..d4279f9 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/ClientAuthenticationManagerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/ClientAuthenticationManagerTest.java
@@ -43,7 +43,7 @@ import org.apache.sshd.common.forward.DefaultForwarderFactory;
import org.apache.sshd.common.forward.PortForwardingEventListener;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.IoWriteFuture;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.apache.sshd.common.random.JceRandomFactory;
import org.apache.sshd.common.random.Random;
import org.apache.sshd.common.random.SingletonRandomFactory;
@@ -81,13 +81,13 @@ public class ClientAuthenticationManagerTest extends BaseTestSupport {
}
@Override
- public KeyPairProvider getKeyPairProvider() {
+ public KeyIdentityProvider getKeyIdentityProvider() {
return null;
}
@Override
- public void setKeyPairProvider(KeyPairProvider keyPairProvider) {
- throw new UnsupportedOperationException("setKeyPairProvider(" + keyPairProvider + ")");
+ public void setKeyIdentityProvider(KeyIdentityProvider provider) {
+ throw new UnsupportedOperationException("setKeyIdentityProvider(" + provider + ")");
}
@Override
@@ -183,7 +183,7 @@ public class ClientAuthenticationManagerTest extends BaseTestSupport {
PasswordIdentityProvider.class,
ServerKeyVerifier.class,
UserInteraction.class,
- KeyPairProvider.class
+ KeyIdentityProvider.class
}) {
testClientProvidersPropagation(provider, client, session);
}
@@ -191,7 +191,9 @@ public class ClientAuthenticationManagerTest extends BaseTestSupport {
}
}
- private void testClientProvidersPropagation(Class<?> type, ClientAuthenticationManager client, ClientAuthenticationManager session) throws Exception {
+ private void testClientProvidersPropagation(
+ Class<?> type, ClientAuthenticationManager client, ClientAuthenticationManager session)
+ throws Exception {
String baseName = type.getSimpleName();
outputDebugMessage("testClientProvidersPropagation(%s)", baseName);
assertTrue(baseName + ": not an interface", type.isInterface());
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java b/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
index 1a767c6..b76e46c 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
@@ -43,7 +43,7 @@ import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.session.SessionContext;
import org.apache.sshd.common.util.ValidateUtils;
@@ -185,13 +185,13 @@ public class HostConfigEntryResolverTest extends BaseTestSupport {
@Test
public void testUseIdentitiesOnly() throws Exception {
Path clientIdFile = assertHierarchyTargetFolderExists(getTempTargetRelativeFile(getClass().getSimpleName()));
- KeyPairProvider clientIdProvider =
+ KeyIdentityProvider clientIdProvider =
CommonTestSupportUtils.createTestHostKeyProvider(clientIdFile.resolve(getCurrentTestName() + ".pem"));
KeyPair specificIdentity = CommonTestSupportUtils.getFirstKeyPair(sshd);
KeyPair defaultIdentity = CommonTestSupportUtils.getFirstKeyPair(clientIdProvider);
ValidateUtils.checkTrue(!KeyUtils.compareKeyPairs(specificIdentity, defaultIdentity),
"client identity not different then entry one");
- client.setKeyPairProvider(clientIdProvider);
+ client.setKeyIdentityProvider(clientIdProvider);
String user = getCurrentTestName();
AtomicBoolean defaultClientIdentityAttempted = new AtomicBoolean(false);
@@ -234,17 +234,17 @@ public class HostConfigEntryResolverTest extends BaseTestSupport {
PropertyResolverUtils.updateProperty(client, ClientFactoryManager.IGNORE_INVALID_IDENTITIES, false);
Collection<KeyPair> clientIdentities = Collections.singletonList(defaultIdentity);
- KeyPairProvider provider = new AbstractKeyPairProvider() {
+ KeyIdentityProvider provider = new AbstractKeyPairProvider() {
@Override
public Iterable<KeyPair> loadKeys(SessionContext session) {
return clientIdentities;
}
};
- client.setKeyPairProvider(provider);
+ client.setKeyIdentityProvider(provider);
client.start();
try (ClientSession session = client.connect(entry).verify(7L, TimeUnit.SECONDS).getSession()) {
- assertSame("Unexpected session key pairs provider", provider, session.getKeyPairProvider());
+ assertSame("Unexpected session key pairs provider", provider, session.getKeyIdentityProvider());
session.auth().verify(5L, TimeUnit.SECONDS);
assertFalse("Unexpected default client identity attempted", defaultClientIdentityAttempted.get());
assertNull("Default client identity auto-added", session.removePublicKeyIdentity(defaultIdentity));
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java b/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
index e55d150..34c418b 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
@@ -53,6 +53,7 @@ import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.IoWriteFuture;
+import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.session.SessionContext;
@@ -916,7 +917,7 @@ public class AuthenticationTest extends BaseTestSupport {
return "super secret passphrase";
}
};
- s.setKeyPairProvider(new KeyPairProvider() {
+ s.setKeyIdentityProvider(new KeyIdentityProvider() {
@Override
public Iterable<KeyPair> loadKeys(SessionContext session) throws IOException, GeneralSecurityException {
assertSame("Mismatched session context", s, session);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/test/java/org/apache/sshd/common/kex/KexFactoryManagerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/kex/KexFactoryManagerTest.java b/sshd-core/src/test/java/org/apache/sshd/common/kex/KexFactoryManagerTest.java
index 63c0346..8242a62 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/kex/KexFactoryManagerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/kex/KexFactoryManagerTest.java
@@ -27,7 +27,6 @@ import org.apache.sshd.common.cipher.BuiltinCiphers;
import org.apache.sshd.common.cipher.Cipher;
import org.apache.sshd.common.compression.BuiltinCompressions;
import org.apache.sshd.common.compression.Compression;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.mac.BuiltinMacs;
import org.apache.sshd.common.mac.Mac;
import org.apache.sshd.common.signature.BuiltinSignatures;
@@ -129,16 +128,6 @@ public class KexFactoryManagerTest extends BaseTestSupport {
}
@Override
- public KeyPairProvider getKeyPairProvider() {
- return null;
- }
-
- @Override
- public void setKeyPairProvider(KeyPairProvider keyPairProvider) {
- throw new UnsupportedOperationException("N/A");
- }
-
- @Override
public List<NamedFactory<Signature>> getSignatureFactories() {
return signatures;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/test/java/org/apache/sshd/server/ServerAuthenticationManagerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/ServerAuthenticationManagerTest.java b/sshd-core/src/test/java/org/apache/sshd/server/ServerAuthenticationManagerTest.java
index fc7b11c..9be1cb0 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/ServerAuthenticationManagerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/ServerAuthenticationManagerTest.java
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicReference;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.server.auth.BuiltinUserAuthFactories;
import org.apache.sshd.server.auth.UserAuth;
@@ -113,6 +114,16 @@ public class ServerAuthenticationManagerTest extends BaseTestSupport {
public void setHostBasedAuthenticator(HostBasedAuthenticator hostBasedAuthenticator) {
throw new UnsupportedOperationException("setHostBasedAuthenticator(" + hostBasedAuthenticator + ")");
}
+
+ @Override
+ public KeyPairProvider getKeyPairProvider() {
+ return null;
+ }
+
+ @Override
+ public void setKeyPairProvider(KeyPairProvider keyPairProvider) {
+ throw new UnsupportedOperationException("setKeyPairProvider(" + keyPairProvider + ")");
+ }
};
assertEquals("Mismatched initial factories list", "", manager.getUserAuthFactoriesNameList());
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e849cc5a/sshd-core/src/test/java/org/apache/sshd/util/test/CoreTestSupportUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/CoreTestSupportUtils.java b/sshd-core/src/test/java/org/apache/sshd/util/test/CoreTestSupportUtils.java
index e6bb6cb..7d2b9b9 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/test/CoreTestSupportUtils.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/CoreTestSupportUtils.java
@@ -25,7 +25,7 @@ import java.net.ServerSocket;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.config.hosts.HostConfigEntryResolver;
import org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.pubkey.AcceptAllPublickeyAuthenticator;
import org.apache.sshd.server.shell.UnknownCommandFactory;
@@ -47,7 +47,7 @@ public final class CoreTestSupportUtils {
SshClient client = SshClient.setUpDefaultClient();
client.setServerKeyVerifier(AcceptAllServerKeyVerifier.INSTANCE);
client.setHostConfigEntryResolver(HostConfigEntryResolver.EMPTY);
- client.setKeyPairProvider(KeyPairProvider.EMPTY_KEYPAIR_PROVIDER);
+ client.setKeyIdentityProvider(KeyIdentityProvider.EMPTY_KEYS_PROVIDER);
return client;
}
[3/3] mina-sshd git commit: The various 'ClientIdentitiesWatcher'(s)
use a type-safe 'ClientIdentityLoaderHolder' and 'FilePasswordProviderHolder'
instead of the generic 'Supplier' definition
Posted by lg...@apache.org.
The various 'ClientIdentitiesWatcher'(s) use a type-safe 'ClientIdentityLoaderHolder' and 'FilePasswordProviderHolder' instead of the generic 'Supplier' definition
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/fc7a8e7c
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/fc7a8e7c
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/fc7a8e7c
Branch: refs/heads/master
Commit: fc7a8e7c2f90a2b20ea4882a4d8b08be31753446
Parents: 98a708a
Author: Lyor Goldstein <lg...@apache.org>
Authored: Mon Nov 19 14:46:10 2018 +0200
Committer: Lyor Goldstein <lg...@apache.org>
Committed: Mon Nov 19 14:50:10 2018 +0200
----------------------------------------------------------------------
CHANGES.md | 6 ++++++
.../sshd/client/config/hosts/HostConfigEntry.java | 4 ++--
.../keys/BuiltinClientIdentitiesWatcher.java | 10 +++++-----
.../config/keys/ClientIdentitiesWatcher.java | 18 +++++++++---------
.../config/keys/ClientIdentityFileWatcher.java | 18 ++++++++----------
.../config/keys/ClientIdentityLoaderHolder.java | 6 ++++--
.../keys/DefaultClientIdentitiesWatcher.java | 13 ++++++-------
.../config/keys/FilePasswordProviderHolder.java | 6 ++++--
8 files changed, 44 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fc7a8e7c/CHANGES.md
----------------------------------------------------------------------
diff --git a/CHANGES.md b/CHANGES.md
index 9cbb99f..5074ade 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -63,6 +63,9 @@ accept also an `AttributeRepository` connection context argument (propagated fro
* `SshClient#loadClientIdentities` has been renamed to `preloadClientIdentities` + it returns a
`KeyIdentityProvider` instead of a collection of strings representing paths.
+* The various `ClientIdentitiesWatcher`(s) use a type-safe `ClientIdentityLoaderHolder` and
+`FilePasswordProviderHolder` instead of the generic `Supplier` definition.
+
## Behavioral changes and enhancements
* [SSHD-849](https://issues.apache.org/jira/browse/SSHD-849) - Data forwarding code makes sure all
@@ -92,6 +95,9 @@ key loading methods are invoked.
* [SSHD-864](https://issues.apache.org/jira/browse/SSHD-864) - Using a `NamedResource` instead of plain old string
in order to provide key file(s) location information
+* [SSHD-865](https://issues.apache.org/jira/browse/SSHD-865) - Key identities overrides specified in the
+[ssh_config](http://www.gsp.com/cgi-bin/man.cgi?topic=ssh_config) configuration file are also lazy loaded
+
* [SSHD-866](https://issues.apache.org/jira/browse/SSHD-866) - Counting empty challenges separately when enforcing
max. attempts during `keyboard-interactive` authentication
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fc7a8e7c/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java b/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
index eafedd8..c2d3bcb 100644
--- a/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
@@ -61,8 +61,8 @@ import org.apache.sshd.common.util.io.NoCloseReader;
/**
* Represents an entry in the client's configuration file as defined by
- * the <A HREF="http://www.gsp.com/cgi-bin/man.cgi?topic=ssh_config">configuration
- * file format</A>
+ * the <A HREF="http://www.gsp.com/cgi-bin/man.cgi?topic=ssh_config">ssh_config</A>
+ * configuration file format
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class HostConfigEntry extends HostPatternsHolder implements MutableUserHolder {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fc7a8e7c/sshd-common/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
index bb3f738..5986e25 100644
--- a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
@@ -26,11 +26,11 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
-import java.util.function.Supplier;
import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.config.keys.BuiltinIdentities;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
+import org.apache.sshd.common.config.keys.FilePasswordProviderHolder;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.session.SessionContext;
import org.apache.sshd.common.util.GenericUtils;
@@ -49,18 +49,18 @@ public class BuiltinClientIdentitiesWatcher extends ClientIdentitiesWatcher {
public BuiltinClientIdentitiesWatcher(Path keysFolder, Collection<String> ids, boolean supportedOnly,
ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
this(keysFolder, ids, supportedOnly,
- GenericUtils.supplierOf(Objects.requireNonNull(loader, "No client identity loader")),
- GenericUtils.supplierOf(Objects.requireNonNull(provider, "No password provider")),
+ ClientIdentityLoaderHolder.loaderHolderOf(Objects.requireNonNull(loader, "No client identity loader")),
+ FilePasswordProviderHolder.providerHolderOf(Objects.requireNonNull(provider, "No password provider")),
strict);
}
public BuiltinClientIdentitiesWatcher(Path keysFolder, boolean supportedOnly,
- Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
+ ClientIdentityLoaderHolder loader, FilePasswordProviderHolder provider, boolean strict) {
this(keysFolder, NamedResource.getNameList(BuiltinIdentities.VALUES), supportedOnly, loader, provider, strict);
}
public BuiltinClientIdentitiesWatcher(Path keysFolder, Collection<String> ids, boolean supportedOnly,
- Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
+ ClientIdentityLoaderHolder loader, FilePasswordProviderHolder provider, boolean strict) {
super(getBuiltinIdentitiesPaths(keysFolder, ids), loader, provider, strict);
this.supportedOnly = supportedOnly;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fc7a8e7c/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
index eed14e9..d3e567c 100644
--- a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
@@ -26,9 +26,9 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
-import java.util.function.Supplier;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
+import org.apache.sshd.common.config.keys.FilePasswordProviderHolder;
import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.session.SessionContext;
@@ -50,18 +50,18 @@ public class ClientIdentitiesWatcher extends AbstractKeyPairProvider implements
public ClientIdentitiesWatcher(Collection<? extends Path> paths,
ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
this(paths,
- GenericUtils.supplierOf(Objects.requireNonNull(loader, "No client identity loader")),
- GenericUtils.supplierOf(Objects.requireNonNull(provider, "No password provider")),
+ ClientIdentityLoaderHolder.loaderHolderOf(Objects.requireNonNull(loader, "No client identity loader")),
+ FilePasswordProviderHolder.providerHolderOf(Objects.requireNonNull(provider, "No password provider")),
strict);
}
public ClientIdentitiesWatcher(Collection<? extends Path> paths,
- Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider) {
+ ClientIdentityLoaderHolder loader, FilePasswordProviderHolder provider) {
this(paths, loader, provider, true);
}
public ClientIdentitiesWatcher(Collection<? extends Path> paths,
- Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
+ ClientIdentityLoaderHolder loader, FilePasswordProviderHolder provider, boolean strict) {
this(buildProviders(paths, loader, provider, strict));
}
@@ -102,14 +102,14 @@ public class ClientIdentitiesWatcher extends AbstractKeyPairProvider implements
public static List<ClientIdentityProvider> buildProviders(
Collection<? extends Path> paths, ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
return buildProviders(paths,
- GenericUtils.supplierOf(Objects.requireNonNull(loader, "No client identity loader")),
- GenericUtils.supplierOf(Objects.requireNonNull(provider, "No password provider")),
+ ClientIdentityLoaderHolder.loaderHolderOf(Objects.requireNonNull(loader, "No client identity loader")),
+ FilePasswordProviderHolder.providerHolderOf(Objects.requireNonNull(provider, "No password provider")),
strict);
}
public static List<ClientIdentityProvider> buildProviders(
- Collection<? extends Path> paths, Supplier<? extends ClientIdentityLoader> loader,
- Supplier<? extends FilePasswordProvider> provider, boolean strict) {
+ Collection<? extends Path> paths, ClientIdentityLoaderHolder loader,
+ FilePasswordProviderHolder provider, boolean strict) {
if (GenericUtils.isEmpty(paths)) {
return Collections.emptyList();
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fc7a8e7c/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
index 5832911..56f946d 100644
--- a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
@@ -27,13 +27,11 @@ import java.security.PublicKey;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.Supplier;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.config.keys.FilePasswordProviderHolder;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.session.SessionContext;
-import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.io.ModifiableFileWatcher;
import org.apache.sshd.common.util.io.resource.PathResource;
@@ -48,8 +46,8 @@ public class ClientIdentityFileWatcher
extends ModifiableFileWatcher
implements ClientIdentityProvider, ClientIdentityLoaderHolder, FilePasswordProviderHolder {
private final AtomicReference<KeyPair> identityHolder = new AtomicReference<>(null);
- private final Supplier<? extends ClientIdentityLoader> loaderHolder;
- private final Supplier<? extends FilePasswordProvider> providerHolder;
+ private final ClientIdentityLoaderHolder loaderHolder;
+ private final FilePasswordProviderHolder providerHolder;
private final boolean strict;
public ClientIdentityFileWatcher(Path path, ClientIdentityLoader loader, FilePasswordProvider provider) {
@@ -58,18 +56,18 @@ public class ClientIdentityFileWatcher
public ClientIdentityFileWatcher(Path path, ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
this(path,
- GenericUtils.supplierOf(Objects.requireNonNull(loader, "No client identity loader")),
- GenericUtils.supplierOf(Objects.requireNonNull(provider, "No password provider")),
+ ClientIdentityLoaderHolder.loaderHolderOf(Objects.requireNonNull(loader, "No client identity loader")),
+ FilePasswordProviderHolder.providerHolderOf(Objects.requireNonNull(provider, "No password provider")),
strict);
}
public ClientIdentityFileWatcher(
- Path path, Supplier<? extends ClientIdentityLoader> loader, Supplier<? extends FilePasswordProvider> provider) {
+ Path path, ClientIdentityLoaderHolder loader, FilePasswordProviderHolder provider) {
this(path, loader, provider, true);
}
public ClientIdentityFileWatcher(
- Path path, Supplier<? extends ClientIdentityLoader> loader, Supplier<? extends FilePasswordProvider> provider, boolean strict) {
+ Path path, ClientIdentityLoaderHolder loader, FilePasswordProviderHolder provider, boolean strict) {
super(path);
this.loaderHolder = Objects.requireNonNull(loader, "No client identity loader");
this.providerHolder = Objects.requireNonNull(provider, "No password provider");
@@ -82,12 +80,12 @@ public class ClientIdentityFileWatcher
@Override
public ClientIdentityLoader getClientIdentityLoader() {
- return loaderHolder.get();
+ return loaderHolder.getClientIdentityLoader();
}
@Override
public FilePasswordProvider getFilePasswordProvider() {
- return providerHolder.get();
+ return providerHolder.getFilePasswordProvider();
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fc7a8e7c/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java
index ecd0f0e..922f346 100644
--- a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java
@@ -20,8 +20,6 @@
package org.apache.sshd.client.config.keys;
/**
- * TODO Add javadoc
- *
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
@FunctionalInterface
@@ -31,4 +29,8 @@ public interface ClientIdentityLoaderHolder {
* key pair identities - never {@code null}
*/
ClientIdentityLoader getClientIdentityLoader();
+
+ static ClientIdentityLoaderHolder loaderHolderOf(ClientIdentityLoader loader) {
+ return () -> loader;
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fc7a8e7c/sshd-common/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
index ee710c3..cee0af5 100644
--- a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
@@ -22,11 +22,10 @@ package org.apache.sshd.client.config.keys;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
-import java.util.function.Supplier;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
+import org.apache.sshd.common.config.keys.FilePasswordProviderHolder;
import org.apache.sshd.common.config.keys.PublicKeyEntry;
-import org.apache.sshd.common.util.GenericUtils;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -43,21 +42,21 @@ public class DefaultClientIdentitiesWatcher extends BuiltinClientIdentitiesWatch
public DefaultClientIdentitiesWatcher(
boolean supportedOnly, ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
this(supportedOnly,
- GenericUtils.supplierOf(Objects.requireNonNull(loader, "No client identity loader")),
- GenericUtils.supplierOf(Objects.requireNonNull(provider, "No password provider")),
+ ClientIdentityLoaderHolder.loaderHolderOf(Objects.requireNonNull(loader, "No client identity loader")),
+ FilePasswordProviderHolder.providerHolderOf(Objects.requireNonNull(provider, "No password provider")),
strict);
}
- public DefaultClientIdentitiesWatcher(Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider) {
+ public DefaultClientIdentitiesWatcher(ClientIdentityLoaderHolder loader, FilePasswordProviderHolder provider) {
this(loader, provider, true);
}
- public DefaultClientIdentitiesWatcher(Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
+ public DefaultClientIdentitiesWatcher(ClientIdentityLoaderHolder loader, FilePasswordProviderHolder provider, boolean strict) {
this(true, loader, provider, strict);
}
public DefaultClientIdentitiesWatcher(boolean supportedOnly,
- Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
+ ClientIdentityLoaderHolder loader, FilePasswordProviderHolder provider, boolean strict) {
super(PublicKeyEntry.getDefaultKeysFolderPath(), supportedOnly, loader, provider, strict);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fc7a8e7c/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java
index a872fac..9e2ce16 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java
@@ -20,8 +20,6 @@
package org.apache.sshd.common.config.keys;
/**
- * TODO Add javadoc
- *
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
@FunctionalInterface
@@ -32,4 +30,8 @@ public interface FilePasswordProviderHolder {
* @see FilePasswordProvider#EMPTY
*/
FilePasswordProvider getFilePasswordProvider();
+
+ static FilePasswordProviderHolder providerHolderOf(FilePasswordProvider provider) {
+ return () -> provider;
+ }
}
[2/3] mina-sshd git commit: [SSHD-865] Use lazy-loading for keys
specified in the HostConfigEntry
Posted by lg...@apache.org.
[SSHD-865] Use lazy-loading for keys specified in the HostConfigEntry
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/98a708a5
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/98a708a5
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/98a708a5
Branch: refs/heads/master
Commit: 98a708a555cd5ba123161c8cbaa627cb855dff65
Parents: e849cc5
Author: Lyor Goldstein <lg...@apache.org>
Authored: Sun Nov 18 17:32:30 2018 +0200
Committer: Lyor Goldstein <lg...@apache.org>
Committed: Mon Nov 19 14:50:10 2018 +0200
----------------------------------------------------------------------
CHANGES.md | 3 +
.../config/keys/ClientIdentityFileWatcher.java | 13 +-
.../config/keys/ClientIdentityLoader.java | 22 +++
.../config/keys/ClientIdentityLoaderHolder.java | 34 ++++
.../keys/ClientIdentityLoaderManager.java | 29 ++++
.../keys/LazyClientKeyIdentityProvider.java | 157 +++++++++++++++++++
.../config/keys/FilePasswordProviderHolder.java | 35 +++++
.../keys/FilePasswordProviderManager.java | 9 +-
.../common/keyprovider/KeyIdentityProvider.java | 19 ++-
.../KeyIdentityProviderResolutionTest.java | 90 +++++++++++
.../sshd/client/ClientFactoryManager.java | 10 +-
.../java/org/apache/sshd/client/SshClient.java | 112 +++++--------
.../hosts/HostConfigEntryResolverTest.java | 10 +-
13 files changed, 438 insertions(+), 105 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/CHANGES.md
----------------------------------------------------------------------
diff --git a/CHANGES.md b/CHANGES.md
index 3ca0d3d..9cbb99f 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -60,6 +60,9 @@ accept also an `AttributeRepository` connection context argument (propagated fro
* `SshClient` and `ClientSession` use a `KeyIdentityProvider` instead of a full blown `KeyPairProvider`.
`KeyPairProvider` is used only in the context of an `SshServer` and/or `ServerSession`.
+* `SshClient#loadClientIdentities` has been renamed to `preloadClientIdentities` + it returns a
+`KeyIdentityProvider` instead of a collection of strings representing paths.
+
## Behavioral changes and enhancements
* [SSHD-849](https://issues.apache.org/jira/browse/SSHD-849) - Data forwarding code makes sure all
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
index ca81e47..5832911 100644
--- a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
@@ -30,6 +30,7 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
+import org.apache.sshd.common.config.keys.FilePasswordProviderHolder;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.session.SessionContext;
import org.apache.sshd.common.util.GenericUtils;
@@ -43,7 +44,9 @@ import org.apache.sshd.common.util.io.resource.PathResource;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public class ClientIdentityFileWatcher extends ModifiableFileWatcher implements ClientIdentityProvider {
+public class ClientIdentityFileWatcher
+ extends ModifiableFileWatcher
+ implements ClientIdentityProvider, ClientIdentityLoaderHolder, FilePasswordProviderHolder {
private final AtomicReference<KeyPair> identityHolder = new AtomicReference<>(null);
private final Supplier<? extends ClientIdentityLoader> loaderHolder;
private final Supplier<? extends FilePasswordProvider> providerHolder;
@@ -73,15 +76,17 @@ public class ClientIdentityFileWatcher extends ModifiableFileWatcher implements
this.strict = strict;
}
- public final boolean isStrict() {
+ public boolean isStrict() {
return strict;
}
- public final ClientIdentityLoader getClientIdentityLoader() {
+ @Override
+ public ClientIdentityLoader getClientIdentityLoader() {
return loaderHolder.get();
}
- public final FilePasswordProvider getFilePasswordProvider() {
+ @Override
+ public FilePasswordProvider getFilePasswordProvider() {
return providerHolder.get();
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoader.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoader.java b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoader.java
index 1d941ac..ceb914e 100644
--- a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoader.java
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoader.java
@@ -26,11 +26,14 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
+import java.util.Collection;
import java.util.Objects;
import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
+import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
import org.apache.sshd.common.session.SessionContext;
+import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.io.resource.PathResource;
@@ -105,4 +108,23 @@ public interface ClientIdentityLoader {
KeyPair loadClientIdentity(
SessionContext session, NamedResource location, FilePasswordProvider provider)
throws IOException, GeneralSecurityException;
+
+ /**
+ * Uses the provided {@link ClientIdentityLoader} to <U>lazy</U> load the keys locations
+ *
+ * @param loader The loader instance to use
+ * @param locations The locations to load - ignored if {@code null}/empty
+ * @param passwordProvider The {@link FilePasswordProvider} to use if any
+ * encrypted keys found
+ * @param ignoreNonExisting Whether to ignore non existing locations as indicated
+ * by {@link #isValidLocation(NamedResource)}
+ * @return The {@link KeyIdentityProvider} wrapper
+ */
+ static KeyIdentityProvider asKeyIdentityProvider(
+ ClientIdentityLoader loader, Collection<? extends NamedResource> locations,
+ FilePasswordProvider passwordProvider, boolean ignoreNonExisting) {
+ return GenericUtils.isEmpty(locations)
+ ? KeyIdentityProvider.EMPTY_KEYS_PROVIDER
+ : new LazyClientKeyIdentityProvider(loader, locations, passwordProvider, ignoreNonExisting);
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java
new file mode 100644
index 0000000..ecd0f0e
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderHolder.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.client.config.keys;
+
+/**
+ * TODO Add javadoc
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FunctionalInterface
+public interface ClientIdentityLoaderHolder {
+ /**
+ * @return The {@link ClientIdentityLoader} to use in order to load client
+ * key pair identities - never {@code null}
+ */
+ ClientIdentityLoader getClientIdentityLoader();
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderManager.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderManager.java b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderManager.java
new file mode 100644
index 0000000..9aa2e55
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityLoaderManager.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.client.config.keys;
+
+/**
+ * TODO Add javadoc
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface ClientIdentityLoaderManager extends ClientIdentityLoaderHolder {
+ void setClientIdentityLoader(ClientIdentityLoader loader);
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/sshd-common/src/main/java/org/apache/sshd/client/config/keys/LazyClientKeyIdentityProvider.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/keys/LazyClientKeyIdentityProvider.java b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/LazyClientKeyIdentityProvider.java
new file mode 100644
index 0000000..05596be
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/client/config/keys/LazyClientKeyIdentityProvider.java
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.client.config.keys;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.config.keys.FilePasswordProvider;
+import org.apache.sshd.common.config.keys.FilePasswordProviderHolder;
+import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
+import org.apache.sshd.common.session.SessionContext;
+import org.apache.sshd.common.util.GenericUtils;
+
+/**
+ * TODO Add javadoc
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class LazyClientKeyIdentityProvider implements KeyIdentityProvider, ClientIdentityLoaderHolder, FilePasswordProviderHolder {
+ private final ClientIdentityLoader clientIdentityLoader;
+ private final Collection<? extends NamedResource> locations;
+ private final FilePasswordProvider passwordProvider;
+ private final boolean ignoreNonExisting;
+
+ public LazyClientKeyIdentityProvider(
+ ClientIdentityLoader loader, Collection<? extends NamedResource> locations,
+ FilePasswordProvider passwordProvider, boolean ignoreNonExisting) {
+ this.clientIdentityLoader = Objects.requireNonNull(loader, "No client identity loader provided");
+ this.locations = locations;
+ this.passwordProvider = passwordProvider;
+ this.ignoreNonExisting = ignoreNonExisting;
+ }
+
+ @Override
+ public ClientIdentityLoader getClientIdentityLoader() {
+ return clientIdentityLoader;
+ }
+
+ public Collection<? extends NamedResource> getLocations() {
+ return locations;
+ }
+
+ @Override
+ public FilePasswordProvider getFilePasswordProvider() {
+ return passwordProvider;
+ }
+
+ public boolean isIgnoreNonExisting() {
+ return ignoreNonExisting;
+ }
+
+ @Override
+ public Iterable<KeyPair> loadKeys(SessionContext session)
+ throws IOException, GeneralSecurityException {
+ Collection<? extends NamedResource> locs = getLocations();
+ if (GenericUtils.isEmpty(locs)) {
+ return Collections.emptyList();
+ }
+
+ return () -> new Iterator<KeyPair>() {
+ private final Iterator<? extends NamedResource> iter = locs.iterator();
+ private KeyPair currentPair;
+ private boolean finished;
+
+ @Override
+ public boolean hasNext() {
+ if (finished) {
+ return false;
+ }
+
+ while (iter.hasNext()) {
+ NamedResource l = iter.next();
+ try {
+ currentPair = loadClientIdentity(session, l);
+ } catch (IOException | GeneralSecurityException e) {
+ throw new RuntimeException("Failed (" + e.getClass().getSimpleName() + ")"
+ + " to load key from " + l.getName() + ": " + e.getMessage(), e);
+ }
+
+ if (currentPair != null) {
+ return true;
+ }
+ }
+
+ finished = true;
+ return false;
+ }
+
+ @Override
+ public KeyPair next() {
+ if (finished) {
+ throw new NoSuchElementException("All identities have been exhausted");
+ }
+ if (currentPair == null) {
+ throw new IllegalStateException("'next()' called without asking 'hasNext()'");
+ }
+
+ KeyPair kp = currentPair;
+ currentPair = null;
+ return kp;
+ }
+
+ @Override
+ public String toString() {
+ return Iterator.class.getSimpleName() + "[" + LazyClientKeyIdentityProvider.class.getSimpleName() + "]";
+ }
+ };
+ }
+
+ protected KeyPair loadClientIdentity(SessionContext session, NamedResource location)
+ throws IOException, GeneralSecurityException {
+ ClientIdentityLoader loader = getClientIdentityLoader();
+ boolean ignoreInvalid = isIgnoreNonExisting();
+ try {
+ if (!loader.isValidLocation(location)) {
+ if (ignoreInvalid) {
+ return null;
+ }
+
+ throw new FileNotFoundException("Invalid identity location: " + location.getName());
+ }
+ } catch (IOException e) {
+ if (ignoreInvalid) {
+ return null;
+ }
+
+ throw e;
+ }
+
+ return loader.loadClientIdentity(session, location, getFilePasswordProvider());
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java
new file mode 100644
index 0000000..a872fac
--- /dev/null
+++ b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderHolder.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.common.config.keys;
+
+/**
+ * TODO Add javadoc
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FunctionalInterface
+public interface FilePasswordProviderHolder {
+ /**
+ * @return The {@link FilePasswordProvider} to use if need to load encrypted
+ * identities keys - never {@code null}
+ * @see FilePasswordProvider#EMPTY
+ */
+ FilePasswordProvider getFilePasswordProvider();
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderManager.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderManager.java b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderManager.java
index aae151c..e38443a 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderManager.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/config/keys/FilePasswordProviderManager.java
@@ -24,13 +24,6 @@ package org.apache.sshd.common.config.keys;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface FilePasswordProviderManager {
- /**
- * @return The {@link FilePasswordProvider} to use if need to load encrypted
- * identities keys - never {@code null}
- * @see FilePasswordProvider#EMPTY
- */
- FilePasswordProvider getFilePasswordProvider();
-
+public interface FilePasswordProviderManager extends FilePasswordProviderHolder {
void setFilePasswordProvider(FilePasswordProvider provider);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
index 3298f20..6ce5996 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
@@ -62,12 +62,20 @@ public interface KeyIdentityProvider {
Iterable<KeyPair> loadKeys(SessionContext session) throws IOException, GeneralSecurityException;
/**
+ * @param provider The {@link KeyIdentityProvider} instance to verify
+ * @return {@code true} if instance is {@code null} or the {@link #EMPTY_KEYS_PROVIDER}
+ */
+ static boolean isEmpty(KeyIdentityProvider provider) {
+ return (provider == null) || GenericUtils.isSameReference(provider, EMPTY_KEYS_PROVIDER);
+ }
+
+ /**
* <P>Creates a "unified" {@link KeyIdentityProvider} out of 2 possible ones
* as follows:</P></BR>
* <UL>
* <LI>If both are {@code null} then return {@code null}.</LI>
- * <LI>If either one is {@code null} then use the non-{@code null} one.</LI>
- * <LI>If both are the same instance then use it.</U>
+ * <LI>If either one is {@code null}/{@link #EMPTY_KEYS_PROVIDER empty} then use the non-{@code null} one.</LI>
+ * <LI>If both are the same instance then use the instance.</U>
* <LI>Otherwise, returns a wrapper that groups both providers.</LI>
* </UL>
*
@@ -78,9 +86,10 @@ public interface KeyIdentityProvider {
*/
static KeyIdentityProvider resolveKeyIdentityProvider(
KeyIdentityProvider identities, KeyIdentityProvider keys) {
- if ((keys == null) || (identities == keys)) {
- return identities;
- } else if (identities == null) {
+ if (isEmpty(keys) || GenericUtils.isSameReference(identities, keys)) {
+ // Prefer EMPTY over null
+ return (identities == null) ? keys : identities;
+ } else if (isEmpty(identities)) {
return keys;
} else {
return multiProvider(identities, keys);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/KeyIdentityProviderResolutionTest.java
----------------------------------------------------------------------
diff --git a/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/KeyIdentityProviderResolutionTest.java b/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/KeyIdentityProviderResolutionTest.java
new file mode 100644
index 0000000..15ebb5d
--- /dev/null
+++ b/sshd-common/src/test/java/org/apache/sshd/common/keyprovider/KeyIdentityProviderResolutionTest.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.common.keyprovider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.sshd.util.test.JUnit4ClassRunnerWithParametersFactory;
+import org.apache.sshd.util.test.JUnitTestSupport;
+import org.apache.sshd.util.test.NoIoTestCase;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.Parameterized.UseParametersRunnerFactory;
+import org.mockito.Mockito;
+
+/**
+ * TODO Add javadoc
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RunWith(Parameterized.class) // see https://github.com/junit-team/junit/wiki/Parameterized-tests
+@UseParametersRunnerFactory(JUnit4ClassRunnerWithParametersFactory.class)
+@Category({ NoIoTestCase.class })
+public class KeyIdentityProviderResolutionTest extends JUnitTestSupport {
+ private final KeyIdentityProvider p1;
+ private final KeyIdentityProvider p2;
+ private final KeyIdentityProvider expected;
+
+ public KeyIdentityProviderResolutionTest(
+ KeyIdentityProvider p1, KeyIdentityProvider p2, KeyIdentityProvider expected) {
+ this.p1 = p1;
+ this.p2 = p2;
+ this.expected = expected;
+ }
+
+ @Parameters(name = "p1={0}, p2={1}, expected={2}")
+ public static List<Object[]> parameters() {
+ return new ArrayList<Object[]>() {
+ // Not serializing it
+ private static final long serialVersionUID = 1L;
+
+ {
+ add(new Object[]{null, null, null});
+ add(new Object[]{null, KeyIdentityProvider.EMPTY_KEYS_PROVIDER, KeyIdentityProvider.EMPTY_KEYS_PROVIDER});
+ add(new Object[]{KeyIdentityProvider.EMPTY_KEYS_PROVIDER, null, KeyIdentityProvider.EMPTY_KEYS_PROVIDER});
+ add(new Object[]{KeyIdentityProvider.EMPTY_KEYS_PROVIDER, KeyIdentityProvider.EMPTY_KEYS_PROVIDER, KeyIdentityProvider.EMPTY_KEYS_PROVIDER});
+
+ KeyIdentityProvider p = createKeyIdentityProvider("MOCK");
+ add(new Object[]{null, p, p});
+ add(new Object[]{KeyIdentityProvider.EMPTY_KEYS_PROVIDER, p, p});
+ add(new Object[]{p, null, p});
+ add(new Object[]{p, KeyIdentityProvider.EMPTY_KEYS_PROVIDER, p});
+ }
+
+ private KeyIdentityProvider createKeyIdentityProvider(String name) {
+ KeyIdentityProvider p = Mockito.mock(KeyIdentityProvider.class);
+ Mockito.when(p.toString()).thenReturn(name);
+ return p;
+ }
+ };
+ }
+
+ @Test
+ public void testResolveKeyIdentityProvider() {
+ assertSame(expected, KeyIdentityProvider.resolveKeyIdentityProvider(p1, p2));
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
index 35b42b1..368ebc2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
@@ -20,6 +20,7 @@ package org.apache.sshd.client;
import org.apache.sshd.client.config.hosts.HostConfigEntryResolver;
import org.apache.sshd.client.config.keys.ClientIdentityLoader;
+import org.apache.sshd.client.config.keys.ClientIdentityLoaderManager;
import org.apache.sshd.client.session.ClientProxyConnectorHolder;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.config.keys.FilePasswordProviderManager;
@@ -34,6 +35,7 @@ public interface ClientFactoryManager
extends FactoryManager,
ClientProxyConnectorHolder,
FilePasswordProviderManager,
+ ClientIdentityLoaderManager,
ClientAuthenticationManager {
/**
@@ -84,12 +86,4 @@ public interface ClientFactoryManager
HostConfigEntryResolver getHostConfigEntryResolver();
void setHostConfigEntryResolver(HostConfigEntryResolver resolver);
-
- /**
- * @return The {@link ClientIdentityLoader} to use in order to load client
- * key pair identities - never {@code null}
- */
- ClientIdentityLoader getClientIdentityLoader();
-
- void setClientIdentityLoader(ClientIdentityLoader loader);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/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 796d781..1dc6859 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
@@ -18,9 +18,7 @@
*/
package org.apache.sshd.client;
-import java.io.FileNotFoundException;
import java.io.IOException;
-import java.io.StreamCorruptedException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
@@ -501,7 +499,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
log.debug("connect({}@{}:{}) no overrides", username, host, port);
}
- return doConnect(username, targetAddress, context, localAddress, Collections.emptyList(), true);
+ return doConnect(username, targetAddress, context, localAddress, KeyIdentityProvider.EMPTY_KEYS_PROVIDER, true);
} else {
if (log.isDebugEnabled()) {
log.debug("connect({}@{}:{}) effective: {}", username, host, port, entry);
@@ -513,7 +511,7 @@ 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, context, localAddress, Collections.emptyList(), true);
+ return doConnect(username, targetAddress, context, localAddress, KeyIdentityProvider.EMPTY_KEYS_PROVIDER, true);
}
}
@@ -530,60 +528,27 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
Collection<PathResource> idFiles = GenericUtils.isEmpty(hostIds)
? Collections.emptyList()
: hostIds.stream()
- .map(l -> Paths.get(l))
+ .map(Paths::get)
.map(PathResource::new)
.collect(Collectors.toCollection(() -> new ArrayList<>(hostIds.size())));
- Collection<KeyPair> keys = loadClientIdentities(idFiles);
+ KeyIdentityProvider keys = preloadClientIdentities(idFiles);
return doConnect(hostConfig.getUsername(), new InetSocketAddress(host, port),
context, localAddress, keys, !hostConfig.isIdentitiesOnly());
}
- protected List<KeyPair> loadClientIdentities(Collection<? extends NamedResource> locations) throws IOException {
- if (GenericUtils.isEmpty(locations)) {
- return Collections.emptyList();
- }
-
- List<KeyPair> ids = new ArrayList<>(locations.size());
- boolean ignoreNonExisting = this.getBooleanProperty(IGNORE_INVALID_IDENTITIES, DEFAULT_IGNORE_INVALID_IDENTITIES);
- ClientIdentityLoader loader = Objects.requireNonNull(getClientIdentityLoader(), "No ClientIdentityLoader");
- FilePasswordProvider provider = getFilePasswordProvider();
- boolean debugEnabled = log.isDebugEnabled();
- for (NamedResource l : locations) {
- if (!loader.isValidLocation(l)) {
- if (ignoreNonExisting) {
- if (debugEnabled) {
- log.debug("loadClientIdentities - skip non-existing identity location: {}", l);
- }
- continue;
- }
-
- throw new FileNotFoundException("Invalid identity location: " + l);
- }
-
- try {
- KeyPair kp = loader.loadClientIdentity(null /* TODO use lazy-load here as well */, l, provider);
- if (kp == null) {
- throw new IOException("No identity loaded from " + l);
- }
-
- if (debugEnabled) {
- log.debug("loadClientIdentities({}) type={}, fingerprint={}",
- l, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint(kp.getPublic()));
- }
-
- ids.add(kp);
- } catch (GeneralSecurityException e) {
- throw new StreamCorruptedException("Failed (" + e.getClass().getSimpleName() + ") to load identity from " + l + ": " + e.getMessage());
- }
- }
-
- return ids;
+ protected KeyIdentityProvider preloadClientIdentities(Collection<? extends NamedResource> locations) throws IOException {
+ return GenericUtils.isEmpty(locations)
+ ? KeyIdentityProvider.EMPTY_KEYS_PROVIDER
+ : ClientIdentityLoader.asKeyIdentityProvider(
+ Objects.requireNonNull(getClientIdentityLoader(), "No ClientIdentityLoader"),
+ locations, getFilePasswordProvider(),
+ this.getBooleanProperty(IGNORE_INVALID_IDENTITIES, DEFAULT_IGNORE_INVALID_IDENTITIES));
}
protected ConnectFuture doConnect(
String username, SocketAddress targetAddress,
AttributeRepository context, SocketAddress localAddress,
- Iterable<? extends KeyPair> identities, boolean useDefaultIdentities)
+ KeyIdentityProvider identities, boolean useDefaultIdentities)
throws IOException {
if (connector == null) {
throw new IllegalStateException("SshClient not started. Please call start() method before connecting to a server");
@@ -600,7 +565,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
protected SshFutureListener<IoConnectFuture> createConnectCompletionListener(
ConnectFuture connectFuture, String username, SocketAddress address,
- Iterable<? extends KeyPair> identities, boolean useDefaultIdentities) {
+ KeyIdentityProvider identities, boolean useDefaultIdentities) {
return new SshFutureListener<IoConnectFuture>() {
@Override
@SuppressWarnings("synthetic-access")
@@ -643,53 +608,46 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
protected void onConnectOperationComplete(
IoSession ioSession, ConnectFuture connectFuture, String username,
- SocketAddress address, Iterable<? extends KeyPair> identities, boolean useDefaultIdentities) {
+ SocketAddress address, KeyIdentityProvider identities, boolean useDefaultIdentities) {
AbstractClientSession session = (AbstractClientSession) AbstractSession.getSession(ioSession);
session.setUsername(username);
session.setConnectAddress(address);
if (useDefaultIdentities) {
- setupDefaultSessionIdentities(session);
- }
-
- if (identities != null) {
- boolean traceEnabled = log.isTraceEnabled();
- for (KeyPair kp : identities) {
- if (traceEnabled) {
- log.trace("onConnectOperationComplete({}) add identity type={}, fingerprint={}",
- session, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint(kp.getPublic()));
- }
- session.addPublicKeyIdentity(kp);
- }
+ setupDefaultSessionIdentities(session, identities);
+ } else {
+ session.setKeyIdentityProvider((identities == null) ? KeyIdentityProvider.EMPTY_KEYS_PROVIDER : identities);
}
connectFuture.setSession(session);
}
- protected void setupDefaultSessionIdentities(ClientSession session) {
+ protected void setupDefaultSessionIdentities(ClientSession session, KeyIdentityProvider extraIdentities) {
+ boolean debugEnabled = log.isDebugEnabled();
// check if session listener intervened
KeyIdentityProvider kpSession = session.getKeyIdentityProvider();
KeyIdentityProvider kpClient = getKeyIdentityProvider();
- boolean debugEnabled = log.isDebugEnabled();
- if (kpSession == null) {
- session.setKeyIdentityProvider(kpClient);
- } else {
- if (kpSession != kpClient) {
- if (debugEnabled) {
- log.debug("setupDefaultSessionIdentities({}) key identity provider override", session);
- }
+ if (GenericUtils.isSameReference(kpSession, kpClient)) {
+ if (debugEnabled) {
+ log.debug("setupDefaultSessionIdentities({}) key identity provider override in session listener", session);
+ }
+ }
+
+ // Prefer the extra identities to come first since they were probably indicate by the host-config entry
+ KeyIdentityProvider kpEffective =
+ KeyIdentityProvider.resolveKeyIdentityProvider(extraIdentities, kpSession);
+ if (!GenericUtils.isSameReference(kpSession, kpEffective)) {
+ if (debugEnabled) {
+ log.debug("setupDefaultSessionIdentities({}) key identity provider enhanced", session);
}
+ session.setKeyIdentityProvider(kpEffective);
}
PasswordIdentityProvider passSession = session.getPasswordIdentityProvider();
PasswordIdentityProvider passClient = getPasswordIdentityProvider();
- if (passSession == null) {
- session.setPasswordIdentityProvider(passClient);
- } else {
- if (passSession != passClient) {
- if (debugEnabled) {
- log.debug("setupDefaultSessionIdentities({}) password provider override", session);
- }
+ if (!GenericUtils.isSameReference(passSession, passClient)) {
+ if (debugEnabled) {
+ log.debug("setupDefaultSessionIdentities({}) password provider override", session);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/98a708a5/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java b/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
index b76e46c..8ede710 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
@@ -32,6 +32,7 @@ import java.util.Collections;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import org.apache.sshd.client.ClientFactoryManager;
import org.apache.sshd.client.SshClient;
@@ -214,6 +215,7 @@ public class HostConfigEntryResolverTest extends BaseTestSupport {
entry.addIdentity(clientIdentity);
entry.setIdentitiesOnly(true);
+ AtomicInteger specificIdentityLoadCount = new AtomicInteger(0);
client.setClientIdentityLoader(new ClientIdentityLoader() {
@Override
public boolean isValidLocation(NamedResource location) throws IOException {
@@ -225,6 +227,7 @@ public class HostConfigEntryResolverTest extends BaseTestSupport {
SessionContext session, NamedResource location, FilePasswordProvider provider)
throws IOException, GeneralSecurityException {
if (isValidLocation(location)) {
+ specificIdentityLoadCount.incrementAndGet();
return specificIdentity;
}
@@ -243,12 +246,13 @@ public class HostConfigEntryResolverTest extends BaseTestSupport {
client.setKeyIdentityProvider(provider);
client.start();
- try (ClientSession session = client.connect(entry).verify(7L, TimeUnit.SECONDS).getSession()) {
- assertSame("Unexpected session key pairs provider", provider, session.getKeyIdentityProvider());
+ try (ClientSession session = client.connect(entry)
+ .verify(7L, TimeUnit.SECONDS)
+ .getSession()) {
session.auth().verify(5L, TimeUnit.SECONDS);
assertFalse("Unexpected default client identity attempted", defaultClientIdentityAttempted.get());
assertNull("Default client identity auto-added", session.removePublicKeyIdentity(defaultIdentity));
- assertNotNull("Entry identity not automatically added", session.removePublicKeyIdentity(specificIdentity));
+ assertEquals("Entry identity not used", 1, specificIdentityLoadCount.get());
assertEffectiveRemoteAddress(session, entry);
} finally {
client.stop();