You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2017/03/10 12:20:25 UTC

[2/2] karaf git commit: [KARAF-4861] Fix ssh agent

[KARAF-4861] Fix ssh agent

Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/9275458d
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/9275458d
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/9275458d

Branch: refs/heads/master
Commit: 9275458dd57ea681efb30cd0bdda6b9744ed6516
Parents: 9117d47
Author: Guillaume Nodet <gn...@apache.org>
Authored: Thu Mar 9 16:11:00 2017 +0100
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Fri Mar 10 12:12:19 2017 +0100

----------------------------------------------------------------------
 .../main/java/org/apache/karaf/client/Main.java | 29 ++++++++++---
 pom.xml                                         |  2 +-
 .../org/apache/karaf/shell/ssh/Activator.java   | 11 +++--
 .../karaf/shell/ssh/KarafAgentFactory.java      |  7 +++
 .../org/apache/karaf/shell/ssh/SshAction.java   | 45 +++-----------------
 5 files changed, 42 insertions(+), 52 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/9275458d/client/src/main/java/org/apache/karaf/client/Main.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/karaf/client/Main.java b/client/src/main/java/org/apache/karaf/client/Main.java
index 424b90b..4162de6 100644
--- a/client/src/main/java/org/apache/karaf/client/Main.java
+++ b/client/src/main/java/org/apache/karaf/client/Main.java
@@ -46,6 +46,7 @@ import org.apache.sshd.agent.local.LocalAgentFactory;
 import org.apache.sshd.client.ClientBuilder;
 import org.apache.sshd.client.SshClient;
 import org.apache.sshd.client.auth.keyboard.UserInteraction;
+import org.apache.sshd.client.channel.ChannelExec;
 import org.apache.sshd.client.channel.ChannelShell;
 import org.apache.sshd.client.channel.ClientChannel;
 import org.apache.sshd.client.channel.ClientChannelEvent;
@@ -55,6 +56,8 @@ import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.RuntimeSshException;
 import org.apache.sshd.common.channel.PtyMode;
+import org.apache.sshd.common.config.keys.FilePasswordProvider;
+import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
 import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
 import org.apache.sshd.common.util.io.NoCloseInputStream;
 import org.jline.terminal.Attributes;
@@ -97,10 +100,17 @@ public class Main {
 
         try (SshClient client = ClientBuilder.builder().build())
         {
-            setupAgent(config.getUser(), config.getKeyFile(), client);
-            client.getProperties().put(FactoryManager.IDLE_TIMEOUT, String.valueOf(config.getIdleTimeout()));
+            FilePasswordProvider passwordProvider = null;
             final Console console = System.console();
             if (console != null) {
+                passwordProvider = new FilePasswordProvider() {
+                    @Override
+                    public String getPassword(String resourceKey) throws IOException {
+                        char[] pwd = console.readPassword("Enter password for " + resourceKey + ": ");
+                        return new String(pwd);
+                    }
+                };
+                client.setFilePasswordProvider(passwordProvider);
                 client.setUserInteraction(new UserInteraction() {
                     @Override
                     public void welcome(ClientSession s, String banner, String lang) {
@@ -138,6 +148,10 @@ public class Main {
                     }
                 });
             }
+            setupAgent(config.getUser(), config.getKeyFile(), client, passwordProvider);
+            client.getProperties().put(FactoryManager.IDLE_TIMEOUT, String.valueOf(config.getIdleTimeout()));
+            // TODO: remove the line below when SSHD-732 is fixed
+            client.setKeyPairProvider(new FileKeyPairProvider());
             client.start();
             if (console != null) {
                 console.printf("Logging in as %s\n", config.getUser());
@@ -154,8 +168,10 @@ public class Main {
                 try {
                     ClientChannel channel;
                     if (config.getCommand().length() > 0) {
-                        channel = session.createChannel("exec", config.getCommand() + "\n");
+                        ChannelExec exec = session.createExecChannel(config.getCommand() + "\n");
+                        channel = exec;
                         channel.setIn(new ByteArrayInputStream(new byte[0]));
+                        exec.setAgentForwarding(true);
                     } else {
                         ChannelShell shell = session.createShellChannel();
                         channel = shell;
@@ -254,10 +270,10 @@ public class Main {
         return attributes.getLocalFlag(flag) ? 1 : 0;
     }
 
-    private static void setupAgent(String user, String keyFile, SshClient client) {
+    private static void setupAgent(String user, String keyFile, SshClient client, FilePasswordProvider passwordProvider) {
         SshAgent agent;
         URL builtInPrivateKey = Main.class.getClassLoader().getResource("karaf.key");
-        agent = startAgent(user, builtInPrivateKey, keyFile);
+        agent = startAgent(user, builtInPrivateKey, keyFile, passwordProvider);
         client.setAgentFactory(new LocalAgentFactory(agent));
         client.getProperties().put(SshAgent.SSH_AUTHSOCKET_ENV_NAME, "local");
     }
@@ -282,7 +298,7 @@ public class Main {
         return session;
     }
 
-    private static SshAgent startAgent(String user, URL privateKeyUrl, String keyFile) {
+    private static SshAgent startAgent(String user, URL privateKeyUrl, String keyFile, FilePasswordProvider passwordProvider) {
         InputStream is = null;
         try {
             SshAgent agent = new AgentImpl();
@@ -293,6 +309,7 @@ public class Main {
             agent.addIdentity(keyPair, user);
             if (keyFile != null) {
                 FileKeyPairProvider fileKeyPairProvider = new FileKeyPairProvider(Paths.get(keyFile));
+                fileKeyPairProvider.setPasswordFinder(passwordProvider);
                 for (KeyPair key : fileKeyPairProvider.loadKeys()) {
                     agent.addIdentity(key, user);                
                 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/9275458d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 5cd008b..f54bd92 100644
--- a/pom.xml
+++ b/pom.xml
@@ -281,7 +281,7 @@
         <spring43.version>4.3.5.RELEASE_1</spring43.version>
         <spring.security31.version>3.1.4.RELEASE</spring.security31.version>
 
-        <sshd.version>1.4.0-SNAPSHOT</sshd.version>
+        <sshd.version>1.4.0</sshd.version>
         <derby-version>10.12.1.1</derby-version>
         <directory-version>2.0.0-M20</directory-version>
         <struts.bundle.version>1.3.10_1</struts.bundle.version>

http://git-wip-us.apache.org/repos/asf/karaf/blob/9275458d/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/Activator.java
----------------------------------------------------------------------
diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/Activator.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/Activator.java
index d28440d..f7d2c7a 100644
--- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/Activator.java
+++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/Activator.java
@@ -35,6 +35,7 @@ import org.apache.karaf.util.tracker.annotation.Services;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory;
 import org.apache.sshd.server.SshServer;
+import org.apache.sshd.server.forward.AcceptAllForwardingFilter;
 import org.apache.sshd.server.keyprovider.AbstractGeneratorHostKeyProvider;
 import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
 import org.apache.sshd.server.scp.ScpCommandFactory;
@@ -57,26 +58,23 @@ public class Activator extends BaseActivator implements ManagedService {
     static final Logger LOGGER = LoggerFactory.getLogger(Activator.class);
 
     ServiceTracker<Session, Session> sessionTracker;
-    KarafAgentFactory agentFactory;
     SessionFactory sessionFactory;
     SshServer server;
 
     @Override
     protected void doOpen() throws Exception {
-        agentFactory = new KarafAgentFactory();
-
         super.doOpen();
 
         sessionTracker = new ServiceTracker<Session, Session>(bundleContext, Session.class, null) {
             @Override
             public Session addingService(ServiceReference<Session> reference) {
                 Session session = super.addingService(reference);
-                agentFactory.registerSession(session);
+                KarafAgentFactory.getInstance().registerSession(session);
                 return session;
             }
             @Override
             public void removedService(ServiceReference<Session> reference, Session session) {
-                agentFactory.unregisterSession(session);
+                KarafAgentFactory.getInstance().unregisterSession(session);
                 super.removedService(reference, session);
             }
         };
@@ -193,7 +191,8 @@ public class Activator extends BaseActivator implements ManagedService {
         server.setPublickeyAuthenticator(authenticator);
         server.setFileSystemFactory(new VirtualFileSystemFactory(Paths.get(System.getProperty("karaf.base"))));
         server.setUserAuthFactories(authFactoriesFactory.getFactories());
-        server.setAgentFactory(agentFactory);
+        server.setAgentFactory(KarafAgentFactory.getInstance());
+        server.setTcpipForwardingFilter(AcceptAllForwardingFilter.INSTANCE);
         server.getProperties().put(SshServer.IDLE_TIMEOUT, Long.toString(sshIdleTimeout));
         if (moduliUrl != null) {
             server.getProperties().put(SshServer.MODULI_URL, moduliUrl);

http://git-wip-us.apache.org/repos/asf/karaf/blob/9275458d/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/KarafAgentFactory.java
----------------------------------------------------------------------
diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/KarafAgentFactory.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/KarafAgentFactory.java
index 61e69e1..38a25e1 100644
--- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/KarafAgentFactory.java
+++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/KarafAgentFactory.java
@@ -40,6 +40,7 @@ import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.session.Session;
 import org.apache.sshd.server.session.ServerSession;
+import org.omg.PortableInterceptor.INACTIVE;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -50,6 +51,12 @@ public class KarafAgentFactory implements SshAgentFactory {
     private final Map<String, AgentServerProxy> proxies = new ConcurrentHashMap<>();
     private final Map<String, SshAgent> locals = new ConcurrentHashMap<>();
 
+    private static final KarafAgentFactory INSTANCE = new KarafAgentFactory();
+
+    public static KarafAgentFactory getInstance() {
+        return INSTANCE;
+    }
+
     @Override
     public List<NamedFactory<Channel>> getChannelForwardingFactories(FactoryManager factoryManager) {
         return LocalAgentFactory.DEFAULT_FORWARDING_CHANNELS;

http://git-wip-us.apache.org/repos/asf/karaf/blob/9275458d/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/SshAction.java
----------------------------------------------------------------------
diff --git a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/SshAction.java b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/SshAction.java
index 8a62b5f..63c1167 100644
--- a/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/SshAction.java
+++ b/shell/ssh/src/main/java/org/apache/karaf/shell/ssh/SshAction.java
@@ -22,11 +22,6 @@ import java.io.ByteArrayInputStream;
 import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.net.URL;
-import java.nio.file.Paths;
-import java.security.KeyPair;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.List;
@@ -43,8 +38,6 @@ import org.apache.karaf.shell.api.console.Signal;
 import org.apache.karaf.shell.api.console.SignalListener;
 import org.apache.karaf.shell.api.console.Terminal;
 import org.apache.sshd.agent.SshAgent;
-import org.apache.sshd.agent.local.AgentImpl;
-import org.apache.sshd.agent.local.LocalAgentFactory;
 import org.apache.sshd.client.channel.ClientChannelEvent;
 import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
 import org.apache.sshd.client.SshClient;
@@ -123,10 +116,15 @@ public class SshAction implements Action {
         }
 
         SshClient client = SshClient.setUpDefaultClient();
-        setupAgent(username, keyFile, client);
+        if (this.session.get(SshAgent.SSH_AUTHSOCKET_ENV_NAME) != null) {
+            client.setAgentFactory(KarafAgentFactory.getInstance());
+            String agentSocket = this.session.get(SshAgent.SSH_AUTHSOCKET_ENV_NAME).toString();
+            client.getProperties().put(SshAgent.SSH_AUTHSOCKET_ENV_NAME, agentSocket);
+        }
         KnownHostsManager knownHostsManager = new KnownHostsManager(new File(System.getProperty("user.home"), ".sshkaraf/known_hosts"));
         ServerKeyVerifier serverKeyVerifier = new ServerKeyVerifierImpl(knownHostsManager, quiet);
         client.setServerKeyVerifier(serverKeyVerifier);
+        client.setKeyPairProvider(new FileKeyPairProvider());
         log.debug("Created client: {}", client);
         client.setUserInteraction(new UserInteraction() {
             @Override
@@ -306,37 +304,6 @@ public class SshAction implements Action {
         return term != null ? term.getHeight() : 25;
     }
 
-    private void setupAgent(String user, String keyFile, SshClient client) {
-        SshAgent agent;
-        URL url = getClass().getClassLoader().getResource("karaf.key");
-        agent = startAgent(user, url, keyFile);
-        client.setAgentFactory(new LocalAgentFactory(agent));
-        client.getProperties().put(SshAgent.SSH_AUTHSOCKET_ENV_NAME, "local");
-    }
-
-    private SshAgent startAgent(String user, URL privateKeyUrl, String keyFile) {
-        InputStream is = null;
-        try {
-            SshAgent agent = new AgentImpl();
-            is = privateKeyUrl.openStream();
-            ObjectInputStream r = new ObjectInputStream(is);
-            KeyPair keyPair = (KeyPair) r.readObject();
-            is.close();
-            agent.addIdentity(keyPair, user);
-            if (keyFile != null) {
-                FileKeyPairProvider fileKeyPairProvider = new FileKeyPairProvider(Paths.get(keyFile));
-                for (KeyPair key : fileKeyPairProvider.loadKeys()) {
-                    agent.addIdentity(key, user);
-                }
-            }
-            return agent;
-        } catch (Throwable e) {
-            close(is);
-            System.err.println("Error starting ssh agent for: " + e.getMessage());
-            return null;
-        }
-    }
-
     private static ClientSession connectWithRetries(SshClient client, String username, String host, int port, int maxAttempts) throws Exception, InterruptedException {
         ClientSession session = null;
         int retries = 0;