{"thread":{"id":"14090","subject":"[JGIT RFC PATCH] Add a stdio prompt for SSH connection information.","startedAt":"2008-06-22T21:06:25Z","lastAt":"2008-06-23T06:34:30Z","messageCount":4,"participants":["Robin Rosenberg","Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"80642","messageId":"200806222306.25434.robin.rosenberg.lists@dewire.com","threadId":"14090","inReplyTo":null,"subject":"[JGIT RFC PATCH] Add a stdio prompt for SSH connection information.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg.lists@dewire.com","sentAt":"2008-06-22T21:06:25Z","receivedAt":"2008-06-22T21:06:25Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"With Java6 there is support for echo-less input of information\nlike passwords from the console.\n\nWindows users must set the system headless promperty java.awt.headless\nto true (-Djava.awt.headless=true) manually. Only unix system headless\noperation is detected automatically via the DISPLAY environment variable.\n\nSigned-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>\n---\n\nStarting a command line utility like jgit and getting a graphical prompt is almost\nan insult. The problem here is that Java 5, which we support, does not have a\nportable way of disabling echoing of characters. Java 6 (and anythung newr)\ndoes. There are several solutions involving non-portable tricks. Should we \nsupport an insecure practice of echoing passwords, or as I do here, only support\nit if one is using Java 6. A downside of supporting it at all is that one needs a\nJavaSE 6 compiler to build the thing.\n\nbtw, does anyone know if console() yields null when runnings as a Windows\nservice? I tentatively assume that it does without explicily setting the headless\nproperty.\n\nI'm also a little unsure about how to invoke the promptKeyboardInteractive method.\n\n .../jgit/transport/DefaultSshSessionFactory.java   |   86 +++++++++++++++++++-\n 1 files changed, 84 insertions(+), 2 deletions(-)\n\ndiff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java b/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java\nindex 8a59904..c895988 100644\n--- a/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java\n+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java\n@@ -39,6 +39,7 @@\n package org.spearce.jgit.transport;\n \n import java.awt.Container;\n+import java.awt.GraphicsEnvironment;\n import java.awt.GridBagConstraints;\n import java.awt.GridBagLayout;\n import java.awt.Insets;\n@@ -90,8 +91,18 @@ class DefaultSshSessionFactory extends SshSessionFactory {\n \t\tfinal Session session = getUserJSch().getSession(user, host, port);\n \t\tif (pass != null)\n \t\t\tsession.setPassword(pass);\n-\t\telse\n-\t\t\tsession.setUserInfo(new AWT_UserInfo());\n+\t\tUserInfo userInfo = null;\n+\t\ttry {\n+\t\t\tSystem.class.getMethod(\"console\");\n+\t\t\tif (GraphicsEnvironment.isHeadless() || System.console() == null)\n+\t\t\t\tuserInfo = new StdioUserInfo();\n+\t\t} catch (NoSuchMethodException e) {\n+\t\t\tthrow new IllegalStateException(\n+\t\t\t\t\t\"You will need JavaSE 6 for stdio based password prompts\");\n+\t\t}\n+\t\tif (userInfo == null)\n+\t\t\tuserInfo = new AWT_UserInfo();\n+\t\tsession.setUserInfo(userInfo);\n \t\treturn session;\n \t}\n \n@@ -249,4 +260,75 @@ class DefaultSshSessionFactory extends SshSessionFactory {\n \t\t\treturn null; // cancel\n \t\t}\n \t}\n+\n+\tstatic class StdioUserInfo implements UserInfo, UIKeyboardInteractive {\n+\n+\t\tString password;\n+\n+\t\tString passphrase;\n+\n+\t\tpublic String getPassphrase() {\n+\t\t\treturn passphrase;\n+\t\t}\n+\n+\t\tpublic String getPassword() {\n+\t\t\treturn password;\n+\t\t}\n+\n+\t\tpublic boolean promptPassphrase(String msg) {\n+\t\t\tpassphrase = null;\n+\t\t\tchar[] readPassword = System.console().readPassword(\"Passphrase: \");\n+\t\t\tif (readPassword == null)\n+\t\t\t\treturn false;\n+\t\t\tpassphrase = new String(readPassword);\n+\t\t\treturn true;\n+\t\t}\n+\n+\t\tpublic boolean promptPassword(String msg) {\n+\t\t\tpassword = null;\n+\t\t\tchar[] readPassword = System.console().readPassword(\"Password: \");\n+\t\t\tif (readPassword == null)\n+\t\t\t\treturn false;\n+\t\t\tpassword = new String(readPassword);\n+\t\t\treturn true;\n+\t\t}\n+\n+\t\tpublic boolean promptYesNo(String msg) {\n+\t\t\tString readLine = System.console().readLine(\"%s [Y/n]: \", msg);\n+\t\t\tif (readLine == null)\n+\t\t\t\treturn false;\n+\t\t\tif (readLine.indexOf(\"yY\") > 0)\n+\t\t\t\treturn true;\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\tpublic void showMessage(String msg) {\n+\t\t\tSystem.console().format(\"%s\\n\", msg);\n+\t\t}\n+\n+\t\tpublic String[] promptKeyboardInteractive(final String destination,\n+\t\t\t\tfinal String name, final String instruction,\n+\t\t\t\tfinal String[] prompt, final boolean[] echo) {\n+\t\t\tSystem.console().printf(\"%s\\n\", instruction);\n+\t\t\tSystem.console().printf(\"Information for %s@%s required.\\n\", name,\n+\t\t\t\t\tdestination);\n+\t\t\tString[] ret = new String[prompt.length];\n+\t\t\tfor (int i = 0; i < ret.length; ++i) {\n+\t\t\t\tString s;\n+\t\t\t\tif (echo[i])\n+\t\t\t\t\ts = System.console().readLine(\"%s :\", prompt[i]);\n+\t\t\t\telse {\n+\t\t\t\t\tchar[] cha = System.console().readPassword(\"%s :\",\n+\t\t\t\t\t\t\tprompt[i]);\n+\t\t\t\t\tif (cha == null)\n+\t\t\t\t\t\ts = null;\n+\t\t\t\t\telse\n+\t\t\t\t\t\ts = new String(cha);\n+\t\t\t\t}\n+\t\t\t\tret[i] = s;\n+\t\t\t}\n+\t\t\treturn ret;\n+\t\t}\n+\n+\t}\n }\n-- \n1.5.5.1.178.g1f811\n"},{"id":"80654","messageId":"20080622231355.GH11793@spearce.org","threadId":"14090","inReplyTo":"200806222306.25434.robin.rosenberg.lists@dewire.com","subject":"Re: [JGIT RFC PATCH] Add a stdio prompt for SSH connection information.","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-06-22T23:13:55Z","receivedAt":"2008-06-22T23:13:55Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Robin Rosenberg <robin.rosenberg.lists@dewire.com> wrote:\n> Starting a command line utility like jgit and getting a graphical prompt is almost\n> an insult. The problem here is that Java 5, which we support, does not have a\n> portable way of disabling echoing of characters. Java 6 (and anythung newr)\n> does. There are several solutions involving non-portable tricks. Should we \n> support an insecure practice of echoing passwords, or as I do here, only support\n> it if one is using Java 6. A downside of supporting it at all is that one needs a\n> JavaSE 6 compiler to build the thing.\n\nWe really shouldn't support insecure entry of the password.  But I'm\nalso not ready to give up on Java 5 support either.  I wonder if\nwe shouldn't hide the console reading/writing into a class in our\nutil package and use reflection to access it, like we do for the\nexecutable flag of java.io.File.\n \n> btw, does anyone know if console() yields null when runnings as a Windows\n> service? I tentatively assume that it does without explicily setting the headless\n> property.\n\nI think that services on Windows have no console, and also can't\ntalk to the desktop UI, so its both headless and without a console.\n\n> I'm also a little unsure about how to invoke the promptKeyboardInteractive method.\n\nI think you implemented this method correctly.  Its a confusing API,\nbut it does seem to make sense.\n \n-- \nShawn.\n"},{"id":"80675","messageId":"200806230823.20534.robin.rosenberg.lists@dewire.com","threadId":"14090","inReplyTo":"20080622231355.GH11793@spearce.org","subject":"Re: [JGIT RFC PATCH] Add a stdio prompt for SSH connection information.","fromName":"Robin Rosenberg","fromEmail":"robin.rosenberg.lists@dewire.com","sentAt":"2008-06-23T06:23:20Z","receivedAt":"2008-06-23T06:23:20Z","isPatch":true,"sender":{"key":"robin.rosenberg@dewire.com","avatar":"https://avatars.githubusercontent.com/u/46357?v=4"},"body":"måndagen den 23 juni 2008 01.13.55 skrev Shawn O. Pearce:\n> I think that services on Windows have no console, and also can't\n> talk to the desktop UI, so its both headless and without a console.\n\nOn Windows a service in Java throws up dialogs in void. Your programs will just hang. You have to tell awt that you are headless or your services may just hang. There is an option on services that makes it show windows on the console, but it's not the default and seems to have no effect on the headless property. As for the console() returning null or not I haven't tried it yet.\n\n> > I'm also a little unsure about how to invoke the promptKeyboardInteractive method.\n> \n> I think you implemented this method correctly.  Its a confusing API,\n> but it does seem to make sense.\n\nNo idea on how to make JSch inoke it?\n\n-- robin\n"},{"id":"80676","messageId":"20080623063430.GO11793@spearce.org","threadId":"14090","inReplyTo":"200806230823.20534.robin.rosenberg.lists@dewire.com","subject":"Re: [JGIT RFC PATCH] Add a stdio prompt for SSH connection information.","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-06-23T06:34:30Z","receivedAt":"2008-06-23T06:34:30Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Robin Rosenberg <robin.rosenberg.lists@dewire.com> wrote:\n> \n> > > I'm also a little unsure about how to invoke the promptKeyboardInteractive method.\n> > \n> > I think you implemented this method correctly.  Its a confusing API,\n> > but it does seem to make sense.\n> \n> No idea on how to make JSch inoke it?\n\nMight require a server that has a token cards for authentication.\nServer can ask for a user password and also give you a code to\nenter into the card, which gives you the response to enter back in.\nI have never worked with such a configuration so I have never seen\nthat sort of multi-input prompt come up in any SSH client before.\n\n-- \nShawn.\n"}]}