You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2014/02/07 23:54:18 UTC

[3/3] git commit: Fix client main() to support logging, key pairs, password-interactive auth

Fix client main() to support logging, key pairs, password-interactive auth

Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/1a3aae3e
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/1a3aae3e
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/1a3aae3e

Branch: refs/heads/master
Commit: 1a3aae3e0f98ac5a442d546b237f7b156b39da25
Parents: e0cbc8b
Author: Guillaume Nodet <gn...@apache.org>
Authored: Fri Feb 7 23:54:08 2014 +0100
Committer: Guillaume Nodet <gn...@apache.org>
Committed: Fri Feb 7 23:54:08 2014 +0100

----------------------------------------------------------------------
 assembly/pom.xml                                |   2 +-
 pom.xml                                         |   5 +
 .../main/java/org/apache/sshd/SshClient.java    | 223 +++++++++++--------
 sshd-git/README.txt                             |   2 +-
 4 files changed, 143 insertions(+), 89 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1a3aae3e/assembly/pom.xml
----------------------------------------------------------------------
diff --git a/assembly/pom.xml b/assembly/pom.xml
index 403a2a4..9f04f1d 100644
--- a/assembly/pom.xml
+++ b/assembly/pom.xml
@@ -58,7 +58,7 @@
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-simple</artifactId>
+            <artifactId>slf4j-jdk14</artifactId>
         </dependency>
         <dependency>
             <groupId>org.bouncycastle</groupId>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1a3aae3e/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 07f4cda..d38e0c7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -136,6 +136,11 @@
             </dependency>
             <dependency>
                 <groupId>org.slf4j</groupId>
+                <artifactId>slf4j-jdk14</artifactId>
+                <version>1.6.4</version>
+            </dependency>
+            <dependency>
+                <groupId>org.slf4j</groupId>
                 <artifactId>slf4j-simple</artifactId>
                 <version>1.6.4</version>
             </dependency>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1a3aae3e/sshd-core/src/main/java/org/apache/sshd/SshClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/SshClient.java
index d784dba..fddc498 100644
--- a/sshd-core/src/main/java/org/apache/sshd/SshClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/SshClient.java
@@ -21,19 +21,29 @@ package org.apache.sshd;
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.io.Writer;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.security.InvalidKeyException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Date;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.Executors;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Formatter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
 
 import org.apache.sshd.client.ClientFactoryManager;
 import org.apache.sshd.client.ServerKeyVerifier;
@@ -44,7 +54,6 @@ import org.apache.sshd.client.auth.UserAuthKeyboardInteractive;
 import org.apache.sshd.client.auth.UserAuthPassword;
 import org.apache.sshd.client.auth.UserAuthPublicKey;
 import org.apache.sshd.client.channel.ChannelShell;
-import org.apache.sshd.client.future.AuthFuture;
 import org.apache.sshd.client.future.ConnectFuture;
 import org.apache.sshd.client.future.DefaultConnectFuture;
 import org.apache.sshd.client.kex.DHG1;
@@ -65,6 +74,7 @@ import org.apache.sshd.common.Closeable;
 import org.apache.sshd.common.Compression;
 import org.apache.sshd.common.Factory;
 import org.apache.sshd.common.KeyExchange;
+import org.apache.sshd.common.KeyPairProvider;
 import org.apache.sshd.common.Mac;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.Signature;
@@ -86,6 +96,7 @@ import org.apache.sshd.common.future.SshFutureListener;
 import org.apache.sshd.common.io.DefaultIoServiceFactory;
 import org.apache.sshd.common.io.IoConnectFuture;
 import org.apache.sshd.common.io.IoConnector;
+import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
 import org.apache.sshd.common.mac.HMACMD5;
 import org.apache.sshd.common.mac.HMACMD596;
 import org.apache.sshd.common.mac.HMACSHA1;
@@ -99,10 +110,10 @@ import org.apache.sshd.common.session.AbstractSession;
 import org.apache.sshd.common.signature.SignatureDSA;
 import org.apache.sshd.common.signature.SignatureECDSA;
 import org.apache.sshd.common.signature.SignatureRSA;
-import org.apache.sshd.common.util.CloseableUtils;
 import org.apache.sshd.common.util.NoCloseInputStream;
 import org.apache.sshd.common.util.NoCloseOutputStream;
 import org.apache.sshd.common.util.SecurityUtils;
+import org.bouncycastle.openssl.PasswordFinder;
 
 /**
  * Entry point for the client side of the SSH protocol.
@@ -436,6 +447,35 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
      *=================================*/
 
     public static void main(String[] args) throws Exception {
+        Handler fh = new ConsoleHandler();
+        fh.setLevel(Level.FINEST);
+        fh.setFormatter(new Formatter() {
+            @Override
+            public String format(LogRecord record) {
+                String message = formatMessage(record);
+                String throwable = "";
+                if (record.getThrown() != null) {
+                    StringWriter sw = new StringWriter();
+                    PrintWriter pw = new PrintWriter(sw);
+                    pw.println();
+                    record.getThrown().printStackTrace(pw);
+                    pw.close();
+                    throwable = sw.toString();
+                }
+                return String.format("%1$tY-%1$tm-%1$td: %2$-7.7s: %3$-32.32s: %4$s%5$s%n",
+                        new Date(record.getMillis()),
+                        record.getLevel().getName(),
+                        record.getLoggerName(),
+                        message,
+                        throwable);
+            }
+        });
+        Logger root = Logger.getLogger("");
+        for (Handler handler : root.getHandlers()) {
+            root.removeHandler(handler);
+        }
+        root.addHandler(fh);
+
         int port = 22;
         String host = null;
         String login = System.getProperty("user.name");
@@ -443,6 +483,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
         List<String> command = null;
         int logLevel = 0;
         boolean error = false;
+        List<String> identities = new ArrayList<String>();
 
         for (int i = 0; i < args.length; i++) {
             if (command == null && "-p".equals(args[i])) {
@@ -460,15 +501,22 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
                 }
                 login = args[++i];
             } else if (command == null && "-v".equals(args[i])) {
-                logLevel = 1;
+                logLevel += 1;
             } else if (command == null && "-vv".equals(args[i])) {
-                logLevel = 2;
+                logLevel += 2;
             } else if (command == null && "-vvv".equals(args[i])) {
-                logLevel = 3;
+                logLevel += 3;
             } else if ("-A".equals(args[i])) {
                 agentForward = true;
             } else if ("-a".equals(args[i])) {
                 agentForward = false;
+            } else if ("-i".equals(args[i])) {
+                if (i + 1 >= args.length) {
+                    System.err.println("option requires and argument: " + args[i]);
+                    error = true;
+                    break;
+                }
+                identities.add(args[++i]);
             } else if (command == null && args[i].startsWith("-")) {
                 System.err.println("illegal option: " + args[i]);
                 error = true;
@@ -492,103 +540,104 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             System.err.println("usage: ssh [-A|-a] [-v[v][v]] [-l login] [-p port] hostname [command]");
             System.exit(-1);
         }
+        if (logLevel <= 0) {
+            root.setLevel(Level.WARNING);
+        } else if (logLevel == 1) {
+            root.setLevel(Level.INFO);
+        } else if (logLevel == 2) {
+            root.setLevel(Level.FINE);
+        } else {
+            root.setLevel(Level.FINEST);
+        }
 
         // TODO: handle log level
 
+        KeyPairProvider provider = null;
+        List<String> files = new ArrayList<String>();
+        File f = new File(System.getProperty("user.home"), ".ssh/id_dsa");
+        if (f.exists() && f.isFile() && f.canRead()) {
+            files.add(f.getAbsolutePath());
+        }
+        f = new File(System.getProperty("user.home"), ".ssh/id_rsa");
+        if (f.exists() && f.isFile() && f.canRead()) {
+            files.add(f.getAbsolutePath());
+        }
+        if (files.size() > 0) {
+            provider = new FileKeyPairProvider(files.toArray(new String[files.size()]), new PasswordFinder() {
+                public char[] getPassword() {
+                    try {
+                        System.out.println("Enter password for private key: ");
+                        BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
+                        String password = r.readLine();
+                        return password.toCharArray();
+                    } catch (IOException e) {
+                        return null;
+                    }
+                }
+            });
+        }
+
         SshClient client = SshClient.setUpDefaultClient();
         client.start();
-
-        try {
-            boolean hasKeys = false;
-
-            /*
-            String authSock = System.getenv(SshAgent.SSH_AUTHSOCKET_ENV_NAME);
-            if (authSock == null) {
-                KeyPair[] keys = null;
-                AgentServer server = new AgentServer();
-                authSock = server.start();
-                List<String> files = new ArrayList<String>();
-                File f = new File(System.getProperty("user.home"), ".ssh/id_dsa");
-                if (f.exists() && f.isFile() && f.canRead()) {
-                    files.add(f.getAbsolutePath());
-                }
-                f = new File(System.getProperty("user.home"), ".ssh/id_rsa");
-                if (f.exists() && f.isFile() && f.canRead()) {
-                    files.add(f.getAbsolutePath());
-                }
+        client.setKeyPairProvider(provider);
+        client.setUserInteraction(new UserInteraction() {
+            public void welcome(String banner) {
+                System.out.println(banner);
+            }
+            public String[] interactive(String destination, String name, String instruction, String[] prompt, boolean[] echo) {
+                String[] answers = new String[prompt.length];
                 try {
-                    if (files.size() > 0) {
-                        keys = new FileKeyPairProvider(files.toArray(new String[0]), new PasswordFinder() {
-                            public char[] getPassword() {
-                                try {
-                                    System.out.println("Enter password for private key: ");
-                                    BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
-                                    String password = r.readLine();
-                                    return password.toCharArray();
-                                } catch (IOException e) {
-                                    return null;
-                                }
-                            }
-                        }).loadKeys();
+                    for (int i = 0; i < prompt.length; i++) {
+                        BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
+                        System.out.print(prompt[i] + " ");
+                        answers[i] = r.readLine();
                     }
-                } catch (Exception e) {
+                } catch (IOException e) {
                 }
-                SshAgent agent = new AgentClient(authSock);
-                for (KeyPair key : keys) {
-                    agent.addIdentity(key, "");
-                }
-                agent.close();
+                return answers;
             }
-            if (authSock != null) {
-                SshAgent agent = new AgentClient(authSock);
-                hasKeys = agent.getIdentities().size() > 0;
+        });
+
+        /*
+        String authSock = System.getenv(SshAgent.SSH_AUTHSOCKET_ENV_NAME);
+        if (authSock == null && provider != null) {
+            Iterable<KeyPair> keys = provider.loadKeys();
+            AgentServer server = new AgentServer();
+            authSock = server.start();
+            SshAgent agent = new AgentClient(authSock);
+            for (KeyPair key : keys) {
+                agent.addIdentity(key, "");
             }
+            agent.close();
             client.getProperties().put(SshAgent.SSH_AUTHSOCKET_ENV_NAME, authSock);
-            */
+        }
+        */
 
-            ClientSession session = client.connect(host, port).await().getSession();
-            int ret = ClientSession.WAIT_AUTH;
+        ClientSession session = client.connect(login, host, port).await().getSession();
+        session.auth().verify();
 
-            AuthFuture authFuture;
-            do {
-                if (hasKeys) {
-                    authFuture = session.authAgent(login);
-                } else {
-                    System.out.print("Password:");
-                    BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
-                    String password = r.readLine();
-                    authFuture = session.authPassword(login, password);
-                }
-                authFuture.await();
-            } while (authFuture.isFailure());
-            if (!authFuture.isSuccess()) {
-                System.err.println("error");
-                System.exit(-1);
-            }
-            ClientChannel channel;
-            if (command == null) {
-                channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
-                ((ChannelShell) channel).setAgentForwarding(agentForward);
-                channel.setIn(new NoCloseInputStream(System.in));
-            } else {
-                channel = session.createChannel(ClientChannel.CHANNEL_EXEC);
-                ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                Writer w = new OutputStreamWriter(baos);
-                for (String cmd : command) {
-                    w.append(cmd).append(" ");
-                }
-                w.append("\n");
-                w.close();
-                channel.setIn(new ByteArrayInputStream(baos.toByteArray()));
+        ClientChannel channel;
+        if (command == null) {
+            channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
+            ((ChannelShell) channel).setAgentForwarding(agentForward);
+            channel.setIn(new NoCloseInputStream(System.in));
+        } else {
+            channel = session.createChannel(ClientChannel.CHANNEL_EXEC);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            Writer w = new OutputStreamWriter(baos);
+            for (String cmd : command) {
+                w.append(cmd).append(" ");
             }
-            channel.setOut(new NoCloseOutputStream(System.out));
-            channel.setErr(new NoCloseOutputStream(System.err));
-            channel.open().await();
-            channel.waitFor(ClientChannel.CLOSED, 0);
-            session.close(false);
-        } finally {
-            client.stop();
+            w.append("\n");
+            w.close();
+            channel.setIn(new ByteArrayInputStream(baos.toByteArray()));
         }
+        channel.setOut(new NoCloseOutputStream(System.out));
+        channel.setErr(new NoCloseOutputStream(System.err));
+        channel.open().await();
+        channel.waitFor(ClientChannel.CLOSED, 0);
+        session.close(false);
+        client.stop();
     }
 
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1a3aae3e/sshd-git/README.txt
----------------------------------------------------------------------
diff --git a/sshd-git/README.txt b/sshd-git/README.txt
index 046f7c5..4977b98 100644
--- a/sshd-git/README.txt
+++ b/sshd-git/README.txt
@@ -1,4 +1,4 @@
 This module contains an SSHD CommandFactory to support git through SSH.
 The git commands are provided by a modified version of jgit-pgm
 available at:
-  https://github.com/gnodet/jgit/tree/%23413522
+  https://github.com/gnodet/jgit/tree/413522