git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[JGIT RFC PATCH] Add a stdio prompt for SSH connection information.

From
Robin Rosenberg <robin.rosenberg.lists@dewire.com>
Date
Jun 22, 2008, 21:06 UTC
Message-ID
<200806222306.25434.robin.rosenberg.lists@dewire.com>

With Java6 there is support for echo-less input of information like passwords from the console.

Windows users must set the system headless promperty java.awt.headless to true (-Djava.awt.headless=true) manually. Only unix system headless operation is detected automatically via the DISPLAY environment variable.

Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
---

Starting a command line utility like jgit and getting a graphical prompt is almost an insult. The problem here is that Java 5, which we support, does not have a portable way of disabling echoing of characters. Java 6 (and anythung newr) does. There are several solutions involving non-portable tricks. Should we support an insecure practice of echoing passwords, or as I do here, only support it if one is using Java 6. A downside of supporting it at all is that one needs a JavaSE 6 compiler to build the thing.

btw, does anyone know if console() yields null when runnings as a Windows service? I tentatively assume that it does without explicily setting the headless property.

I'm also a little unsure about how to invoke the promptKeyboardInteractive method.
 .../jgit/transport/DefaultSshSessionFactory.java   |   86 +++++++++++++++++++-
 1 files changed, 84 insertions(+), 2 deletions(-)
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java b/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java
index 8a59904..c895988 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java
@@ -39,6 +39,7 @@
 package org.spearce.jgit.transport;
 
 import java.awt.Container;
+import java.awt.GraphicsEnvironment;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 import java.awt.Insets;
@@ -90,8 +91,18 @@ class DefaultSshSessionFactory extends SshSessionFactory {
 		final Session session = getUserJSch().getSession(user, host, port);
 		if (pass != null)
 			session.setPassword(pass);
-		else
-			session.setUserInfo(new AWT_UserInfo());
+		UserInfo userInfo = null;
+		try {
+			System.class.getMethod("console");
+			if (GraphicsEnvironment.isHeadless() || System.console() == null)
+				userInfo = new StdioUserInfo();
+		} catch (NoSuchMethodException e) {
+			throw new IllegalStateException(
+					"You will need JavaSE 6 for stdio based password prompts");
+		}
+		if (userInfo == null)
+			userInfo = new AWT_UserInfo();
+		session.setUserInfo(userInfo);
 		return session;
 	}
 
@@ -249,4 +260,75 @@ class DefaultSshSessionFactory extends SshSessionFactory {
 			return null; // cancel
 		}
 	}
+
+	static class StdioUserInfo implements UserInfo, UIKeyboardInteractive {
+
+		String password;
+
+		String passphrase;
+
+		public String getPassphrase() {
+			return passphrase;
+		}
+
+		public String getPassword() {
+			return password;
+		}
+
+		public boolean promptPassphrase(String msg) {
+			passphrase = null;
+			char[] readPassword = System.console().readPassword("Passphrase: ");
+			if (readPassword == null)
+				return false;
+			passphrase = new String(readPassword);
+			return true;
+		}
+
+		public boolean promptPassword(String msg) {
+			password = null;
+			char[] readPassword = System.console().readPassword("Password: ");
+			if (readPassword == null)
+				return false;
+			password = new String(readPassword);
+			return true;
+		}
+
+		public boolean promptYesNo(String msg) {
+			String readLine = System.console().readLine("%s [Y/n]: ", msg);
+			if (readLine == null)
+				return false;
+			if (readLine.indexOf("yY") > 0)
+				return true;
+			return false;
+		}
+
+		public void showMessage(String msg) {
+			System.console().format("%s\n", msg);
+		}
+
+		public String[] promptKeyboardInteractive(final String destination,
+				final String name, final String instruction,
+				final String[] prompt, final boolean[] echo) {
+			System.console().printf("%s\n", instruction);
+			System.console().printf("Information for %s@%s required.\n", name,
+					destination);
+			String[] ret = new String[prompt.length];
+			for (int i = 0; i < ret.length; ++i) {
+				String s;
+				if (echo[i])
+					s = System.console().readLine("%s :", prompt[i]);
+				else {
+					char[] cha = System.console().readPassword("%s :",
+							prompt[i]);
+					if (cha == null)
+						s = null;
+					else
+						s = new String(cha);
+				}
+				ret[i] = s;
+			}
+			return ret;
+		}
+
+	}
 }
-- 
1.5.5.1.178.g1f811
Next: Shawn O. Pearce
Message 1 of 4 in “Add a stdio prompt for SSH connection information.”
  1. Add a stdio prompt for SSH connection information.Robin Rosenberg, Jun 22, 2008
  2. Shawn O. PearceJun 22, 2008
  3. Robin RosenbergJun 23, 2008
  4. Shawn O. PearceJun 23, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.