You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by "Grzegorz Grzybek (Jira)" <ji...@apache.org> on 2021/04/01 12:28:00 UTC
[jira] [Commented] (SSHD-1145)
EdDSASecurityProviderRegistrar#isSupported() should check more classloaders
[ https://issues.apache.org/jira/browse/SSHD-1145?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17313142#comment-17313142 ]
Grzegorz Grzybek commented on SSHD-1145:
----------------------------------------
[~gnodet], with this little change, EdDSASecurityProviderRegistrar can find EdDSA from net.i2p.crypto library
{noformat}
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java
index 431a04c11..04babe5a7 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/EdDSASecurityProviderRegistrar.java
@@ -26,7 +26,6 @@ import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ReflectionUtils;
import org.apache.sshd.common.util.security.AbstractSecurityProviderRegistrar;
import org.apache.sshd.common.util.security.SecurityUtils;
import org.apache.sshd.common.util.threads.ThreadUtils;
@@ -94,9 +93,10 @@ public class EdDSASecurityProviderRegistrar extends AbstractSecurityProviderRegi
return supported.booleanValue();
}
- ClassLoader cl = ThreadUtils.resolveDefaultClassLoader(getClass());
- supported = ReflectionUtils.isClassAvailable(cl, "net.i2p.crypto.eddsa.EdDSAKey");
- supportHolder.set(supported);
+ Class clazz
+ = ThreadUtils.resolveDefaultClass(getClass(), "net.i2p.crypto.eddsa.EdDSAKey");
+ supportHolder.set(clazz != null);
+ supported = supportHolder.get();
}
return supported.booleanValue();
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java b/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
index 9879b7482..ba229ecee 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
@@ -74,6 +74,21 @@ public final class ThreadUtils {
return () -> iterateDefaultClassLoaders(anchor);
}
+ public static Class<?> resolveDefaultClass(Class<?> anchor, String className) {
+ return resolveDefaultClass(resolveDefaultClassLoaders(anchor), className);
+ }
+
+ public static Class<?> resolveDefaultClass(Iterable<? extends ClassLoader> cls, String className) {
+ for (ClassLoader cl : cls) {
+ try {
+ return cl.loadClass(className);
+ } catch (Throwable ignored) {
+ // Ignore
+ }
+ }
+ return null;
+ }
+
public static <T> T createDefaultInstance(
Class<?> anchor, Class<T> targetType, String className)
throws ReflectiveOperationException {
{noformat}
The idea is to not use two step process like:
# org.apache.sshd.common.util.threads.ThreadUtils#resolveDefaultClassLoader(java.lang.Object) to get first non-null classloader
# org.apache.sshd.common.util.ReflectionUtils#isClassAvailable() to use the above CL to load a class
I added {{org.apache.sshd.common.util.threads.ThreadUtils#resolveDefaultClass(java.lang.Class<?>, java.lang.String)}} method and {{org.apache.sshd.common.util.threads.ThreadUtils#resolveDefaultClass(java.lang.Iterable<? extends java.lang.ClassLoader>, java.lang.String)}} method, so we can use all reachable classloaders to try to load a class.
My tests related to camel-ssh component in Karaf environment work fine.
The problem is that there are many places that use the code like:
{code:java}
ClassLoader cl = ThreadUtils.resolveDefaultClassLoader(getClass());
supported = ReflectionUtils.isClassAvailable(cl, PROVIDER_CLASS);
{code}
namely:
* org.apache.sshd.common.util.security.bouncycastle.BouncyCastleSecurityProviderRegistrar#isSupported()
* org.apache.sshd.cli.server.SshServerCliSupport#resolveServerSubsystems()
* org.apache.sshd.cli.client.ScpCommandMain#resolveScpClientCreator()
* org.apache.sshd.cli.client.SftpCommandMain#resolveSftpClientFactory()
* org.apache.sshd.cli.server.SshServerCliSupport#resolveShellFactory()
* org.apache.sshd.cli.client.SshClientCliSupport#setupSessionExtensions()
(and possibly other methods)
WDYT?
As alternative solution, for now I'm just adding net.i2p.crypto as boot library to Karaf.
> EdDSASecurityProviderRegistrar#isSupported() should check more classloaders
> ---------------------------------------------------------------------------
>
> Key: SSHD-1145
> URL: https://issues.apache.org/jira/browse/SSHD-1145
> Project: MINA SSHD
> Issue Type: Improvement
> Affects Versions: 2.5.1
> Reporter: Grzegorz Grzybek
> Priority: Major
>
> I'm working for Karaf and Camel fix that would allow me to use ssh-ed25519 for server key.
> EdDSA is supported via net.i2p.crypto/eddsa library, but its availability is checked in a way that is not correct (and not only in OSGi environment).
> It's is also problematic for BouncyCastleSecurityProviderRegistrar, but actually for all methods that use {{org.apache.sshd.common.util.threads.ThreadUtils#resolveDefaultClassLoader(java.lang.Class<?>)}}.
> {{resolveDefaultClassLoader()}} method result is a classloader which is checked for availability of e.g., "net.i2p.crypto.eddsa.EdDSAKey" class, but the check result is cached statically. The problem is that if TCCL is used (which is generally not defined in OSGi) it may be a false negative.
> More precisely - if in Karaf, I start Karaf's own sshd server with a TCCL that _sees_ {{net.i2p.crypto.eddsa}} package, I can use EdDSA algorithm.
> If I add camel-ssh usage, it _may_ have own TCCL (depending on how Camel is started - e.g., through OSGi blueprint) - the first one who calls {{org.apache.sshd.common.util.security.eddsa.EdDSASecurityProviderRegistrar#isSupported()}} _wins_.
> I'll work on a way to check more classloaders in search for given provider/registrar and send a PR soon.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@mina.apache.org
For additional commands, e-mail: dev-help@mina.apache.org