Simplify SSH in order to better support native image
authorMathieu Baudier <mbaudier@argeo.org>
Sun, 7 Aug 2022 05:51:57 +0000 (07:51 +0200)
committerMathieu Baudier <mbaudier@argeo.org>
Sun, 7 Aug 2022 05:51:57 +0000 (07:51 +0200)
org.argeo.cms.lib.sshd/src/org/argeo/cms/ssh/AbstractSsh.java
org.argeo.cms.lib.sshd/src/org/argeo/cms/ssh/cli/DefaultClientIdentityLoader.java [new file with mode: 0644]
org.argeo.cms.lib.sshd/src/org/argeo/cms/ssh/cli/SshShell.java

index 47b46cdd2c9de9629131a5eba5b6b6b7a44643fa..c91ab48058f06944489e559a519b6b0789eb348a 100644 (file)
@@ -22,8 +22,8 @@ import org.argeo.api.cms.CmsLog;
 public abstract class AbstractSsh {
        private final static CmsLog log = CmsLog.getLog(AbstractSsh.class);
 
-       private static SshClient sshClient;
-       private static SftpFileSystemProvider sftpFileSystemProvider;
+       private SshClient sshClient;
+       private SftpFileSystemProvider sftpFileSystemProvider;
 
        private boolean passwordSet = false;
        private ClientSession session;
diff --git a/org.argeo.cms.lib.sshd/src/org/argeo/cms/ssh/cli/DefaultClientIdentityLoader.java b/org.argeo.cms.lib.sshd/src/org/argeo/cms/ssh/cli/DefaultClientIdentityLoader.java
new file mode 100644 (file)
index 0000000..9199198
--- /dev/null
@@ -0,0 +1,54 @@
+package org.argeo.cms.ssh.cli;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.util.Objects;
+
+import org.apache.sshd.client.config.keys.ClientIdentityLoader;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.config.keys.FilePasswordProvider;
+import org.apache.sshd.common.session.SessionContext;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.io.IoUtils;
+import org.apache.sshd.common.util.io.resource.PathResource;
+import org.apache.sshd.common.util.security.SecurityUtils;
+
+/** Separate class in order to avoit static field from Apache SSHD. */
+class DefaultClientIdentityLoader implements ClientIdentityLoader {
+       @Override
+       public boolean isValidLocation(NamedResource location) throws IOException {
+               Path path = toPath(location);
+               return Files.exists(path, IoUtils.EMPTY_LINK_OPTIONS);
+       }
+
+       @Override
+       public Iterable<KeyPair> loadClientIdentities(SessionContext session, NamedResource location,
+                       FilePasswordProvider provider) throws IOException, GeneralSecurityException {
+               Path path = toPath(location);
+               PathResource resource = new PathResource(path);
+               try (InputStream inputStream = resource.openInputStream()) {
+                       return SecurityUtils.loadKeyPairIdentities(session, resource, inputStream, provider);
+               }
+       }
+
+       @Override
+       public String toString() {
+               return "DEFAULT";
+       }
+
+       private Path toPath(NamedResource location) {
+               Objects.requireNonNull(location, "No location provided");
+
+               Path path = Paths
+                               .get(ValidateUtils.checkNotNullAndNotEmpty(location.getName(), "No location value for %s", location));
+               path = path.toAbsolutePath();
+               path = path.normalize();
+               return path;
+       }
+
+}
index f8870b97b6131da21f5cd8cc3c96a4cc4ab47f61..dffb440f1fb94b3fe56026244337e32ea61b6b20 100644 (file)
@@ -14,7 +14,6 @@ import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.SshAgentFactory;
 import org.apache.sshd.agent.local.LocalAgentFactory;
 import org.apache.sshd.agent.unix.UnixAgentFactory;
-import org.apache.sshd.client.config.keys.ClientIdentityLoader;
 import org.apache.sshd.common.NamedResource;
 import org.apache.sshd.common.config.keys.FilePasswordProvider;
 import org.argeo.api.cli.CommandArgsException;
@@ -83,7 +82,7 @@ public class SshShell implements DescribedCommand<String> {
                                                return keyPath;
                                        }
                                };
-                               KeyPair keyPair = ClientIdentityLoader.DEFAULT
+                               KeyPair keyPair = new DefaultClientIdentityLoader()
                                                .loadClientIdentities(null, namedResource, FilePasswordProvider.of(new String(keyPassword)))
                                                .iterator().next();
                                sshAgent.addIdentity(keyPair, "NO COMMENT");