git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [JGIT PATCH 1/2 v2] Add support for ~/.ssh/config PreferredAuthentications
@ 2008-09-16 15:44 Shawn O. Pearce
  2008-09-16 15:44 ` [JGIT PATCH 2/2] Add support for ~/.ssh/config BatchMode Shawn O. Pearce
  0 siblings, 1 reply; 4+ messages in thread
From: Shawn O. Pearce @ 2008-09-16 15:44 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

Some configurations may wish to disable interactive methods of
authentication, such as when running from automated cron or batch
style jobs that have no user available.

Typically in an OpenSSH based system this would be configured on a
per-host basis in the current user's ~/.ssh/config file, by setting
PreferredAuthentications to the list of authentication methods
(e.g. just "publickey") that are reasonable.

JSch honors this configuration setting, but we need to transfer it
from our own OpenSshConfig class, otherwise it has no knowledge of
the setting.

http://code.google.com/p/egit/issues/detail?id=33

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---

 This replaces my earlier patch of the same title from about 14
 hours ago.  This v2 patch actually parses the data from the
 config file and includes unit tests to verify it is parsing.

 .../spearce/egit/ui/EclipseSshSessionFactory.java  |    4 +++
 .../spearce/jgit/transport/OpenSshConfigTest.java  |   22 ++++++++++++++++-
 .../jgit/transport/DefaultSshSessionFactory.java   |    4 +++
 .../org/spearce/jgit/transport/OpenSshConfig.java  |   25 ++++++++++++++++++++
 4 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/EclipseSshSessionFactory.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/EclipseSshSessionFactory.java
index 640a165..67c5f16 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/EclipseSshSessionFactory.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/EclipseSshSessionFactory.java
@@ -50,6 +50,10 @@ public Session getSession(String user, String pass, String host, int port)
 			session.setPassword(pass);
 		else
 			new UserInfoPrompter(session);
+
+		final String pauth = hc.getPreferredAuthentications();
+		if (pauth != null)
+			session.setConfig("PreferredAuthentications", pauth);
 		return session;
 	}
 
diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/transport/OpenSshConfigTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/OpenSshConfigTest.java
index a250f9d..1a71d08 100644
--- a/org.spearce.jgit.test/tst/org/spearce/jgit/transport/OpenSshConfigTest.java
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/OpenSshConfigTest.java
@@ -103,7 +103,6 @@ config("Host orcz\n" + "\tHostName repo.or.cz\n" + "\tPort 2222\n"
 		assertEquals(new File(home, ".ssh/id_jex"), h.getIdentityFile());
 	}
 
-
 	public void testAlias_OptionsKeywordCaseInsensitive() throws Exception {
 		config("hOsT orcz\n" + "\thOsTnAmE repo.or.cz\n" + "\tPORT 2222\n"
 				+ "\tuser jex\n" + "\tidentityfile .ssh/id_jex\n"
@@ -128,4 +127,25 @@ config("Host orcz\n" + "\tHostName repo.or.cz\n" + "\n" + "Host *\n"
 		assertEquals(2222, h.getPort());
 		assertEquals(new File(home, ".ssh/id_jex"), h.getIdentityFile());
 	}
+
+	public void testAlias_PreferredAuthenticationsDefault() throws Exception {
+		final Host h = osc.lookup("orcz");
+		assertNotNull(h);
+		assertNull(h.getPreferredAuthentications());
+	}
+
+	public void testAlias_PreferredAuthentications() throws Exception {
+		config("Host orcz\n" + "\tPreferredAuthentications publickey\n");
+		final Host h = osc.lookup("orcz");
+		assertNotNull(h);
+		assertEquals("publickey", h.getPreferredAuthentications());
+	}
+
+	public void testAlias_InheritPreferredAuthentications() throws Exception {
+		config("Host orcz\n" + "\tHostName repo.or.cz\n" + "\n" + "Host *\n"
+				+ "\tPreferredAuthentications publickey, hostbased\n");
+		final Host h = osc.lookup("orcz");
+		assertNotNull(h);
+		assertEquals("publickey,hostbased", h.getPreferredAuthentications());
+	}
 }
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 74fca66..b6f58f0 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java
@@ -103,6 +103,10 @@ public synchronized Session getSession(String user, String pass,
 			session.setPassword(pass);
 		else
 			session.setUserInfo(new AWT_UserInfo());
+
+		final String pauth = hc.getPreferredAuthentications();
+		if (pauth != null)
+			session.setConfig("PreferredAuthentications", pauth);
 		return session;
 	}
 
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/OpenSshConfig.java b/org.spearce.jgit/src/org/spearce/jgit/transport/OpenSshConfig.java
index cf7c388..2f41e56 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/OpenSshConfig.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/OpenSshConfig.java
@@ -220,6 +220,10 @@ else if (sp < 0)
 				for (final Host c : current)
 					if (c.identityFile == null)
 						c.identityFile = toFile(dequote(argValue));
+			} else if ("PreferredAuthentications".equalsIgnoreCase(keyword)) {
+				for (final Host c : current)
+					if (c.preferredAuthentications == null)
+						c.preferredAuthentications = nows(dequote(argValue));
 			}
 		}
 
@@ -247,6 +251,15 @@ private static String dequote(final String value) {
 		return value;
 	}
 
+	private static String nows(final String value) {
+		final StringBuilder b = new StringBuilder();
+		for (int i = 0; i < value.length(); i++) {
+			if (!Character.isSpaceChar(value.charAt(i)))
+				b.append(value.charAt(i));
+		}
+		return b.toString();
+	}
+
 	private File toFile(final String path) {
 		if (path.startsWith("~/"))
 			return new File(home, path.substring(2));
@@ -278,6 +291,8 @@ private File toFile(final String path) {
 
 		String user;
 
+		String preferredAuthentications;
+
 		void copyFrom(final Host src) {
 			if (hostName == null)
 				hostName = src.hostName;
@@ -287,6 +302,8 @@ void copyFrom(final Host src) {
 				identityFile = src.identityFile;
 			if (user == null)
 				user = src.user;
+			if (preferredAuthentications == null)
+				preferredAuthentications = src.preferredAuthentications;
 		}
 
 		/**
@@ -317,5 +334,13 @@ public File getIdentityFile() {
 		public String getUser() {
 			return user;
 		}
+
+		/**
+		 * @return the preferred authentication methods, separated by commas if
+		 *         more than one authentication method is preferred.
+		 */
+		public String getPreferredAuthentications() {
+			return preferredAuthentications;
+		}
 	}
 }
-- 
1.6.0.2.389.g421e0

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [JGIT PATCH 2/2] Add support for ~/.ssh/config BatchMode
  2008-09-16 15:44 [JGIT PATCH 1/2 v2] Add support for ~/.ssh/config PreferredAuthentications Shawn O. Pearce
@ 2008-09-16 15:44 ` Shawn O. Pearce
  2008-09-16 22:46   ` Robin Rosenberg
  0 siblings, 1 reply; 4+ messages in thread
From: Shawn O. Pearce @ 2008-09-16 15:44 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

Connections created through batch processes (e.g. those started by
cron) don't have a terminal to interact with a user through.  A
common way to disable password prompting with OpenSSH is to setup
a Host block in ~/.ssh/config with "BatchMode yes" enabled, thus
telling the client not to prompt for passphases or passwords.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---
 .../spearce/egit/ui/EclipseSshSessionFactory.java  |    2 +-
 .../spearce/jgit/transport/OpenSshConfigTest.java  |   21 +++++++++++++++++++
 .../jgit/transport/DefaultSshSessionFactory.java   |    2 +-
 .../org/spearce/jgit/transport/OpenSshConfig.java  |   22 ++++++++++++++++++++
 4 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/EclipseSshSessionFactory.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/EclipseSshSessionFactory.java
index 67c5f16..098d234 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/EclipseSshSessionFactory.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/EclipseSshSessionFactory.java
@@ -48,7 +48,7 @@ public Session getSession(String user, String pass, String host, int port)
 			addIdentity(hc.getIdentityFile());
 		if (pass != null)
 			session.setPassword(pass);
-		else
+		else if (!hc.isBatchMode())
 			new UserInfoPrompter(session);
 
 		final String pauth = hc.getPreferredAuthentications();
diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/transport/OpenSshConfigTest.java b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/OpenSshConfigTest.java
index 1a71d08..959b6b7 100644
--- a/org.spearce.jgit.test/tst/org/spearce/jgit/transport/OpenSshConfigTest.java
+++ b/org.spearce.jgit.test/tst/org/spearce/jgit/transport/OpenSshConfigTest.java
@@ -148,4 +148,25 @@ config("Host orcz\n" + "\tHostName repo.or.cz\n" + "\n" + "Host *\n"
 		assertNotNull(h);
 		assertEquals("publickey,hostbased", h.getPreferredAuthentications());
 	}
+
+	public void testAlias_BatchModeDefault() throws Exception {
+		final Host h = osc.lookup("orcz");
+		assertNotNull(h);
+		assertEquals(false, h.isBatchMode());
+	}
+
+	public void testAlias_BatchModeYes() throws Exception {
+		config("Host orcz\n" + "\tBatchMode yes\n");
+		final Host h = osc.lookup("orcz");
+		assertNotNull(h);
+		assertEquals(true, h.isBatchMode());
+	}
+
+	public void testAlias_InheritBatchMode() throws Exception {
+		config("Host orcz\n" + "\tHostName repo.or.cz\n" + "\n" + "Host *\n"
+				+ "\tBatchMode yes\n");
+		final Host h = osc.lookup("orcz");
+		assertNotNull(h);
+		assertEquals(true, h.isBatchMode());
+	}
 }
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 b6f58f0..89beab7 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/DefaultSshSessionFactory.java
@@ -101,7 +101,7 @@ public synchronized Session getSession(String user, String pass,
 			addIdentity(hc.getIdentityFile());
 		if (pass != null)
 			session.setPassword(pass);
-		else
+		else if (!hc.isBatchMode())
 			session.setUserInfo(new AWT_UserInfo());
 
 		final String pauth = hc.getPreferredAuthentications();
diff --git a/org.spearce.jgit/src/org/spearce/jgit/transport/OpenSshConfig.java b/org.spearce.jgit/src/org/spearce/jgit/transport/OpenSshConfig.java
index 2f41e56..df38e18 100644
--- a/org.spearce.jgit/src/org/spearce/jgit/transport/OpenSshConfig.java
+++ b/org.spearce.jgit/src/org/spearce/jgit/transport/OpenSshConfig.java
@@ -224,6 +224,10 @@ else if (sp < 0)
 				for (final Host c : current)
 					if (c.preferredAuthentications == null)
 						c.preferredAuthentications = nows(dequote(argValue));
+			} else if ("BatchMode".equalsIgnoreCase(keyword)) {
+				for (final Host c : current)
+					if (c.batchMode == null)
+						c.batchMode = yesno(dequote(argValue));
 			}
 		}
 
@@ -260,6 +264,12 @@ private static String nows(final String value) {
 		return b.toString();
 	}
 
+	private static Boolean yesno(final String value) {
+		if ("yes".equalsIgnoreCase(value))
+			return Boolean.TRUE;
+		return Boolean.FALSE;
+	}
+
 	private File toFile(final String path) {
 		if (path.startsWith("~/"))
 			return new File(home, path.substring(2));
@@ -293,6 +303,8 @@ private File toFile(final String path) {
 
 		String preferredAuthentications;
 
+		Boolean batchMode;
+
 		void copyFrom(final Host src) {
 			if (hostName == null)
 				hostName = src.hostName;
@@ -304,6 +316,8 @@ void copyFrom(final Host src) {
 				user = src.user;
 			if (preferredAuthentications == null)
 				preferredAuthentications = src.preferredAuthentications;
+			if (batchMode == null)
+				batchMode = src.batchMode;
 		}
 
 		/**
@@ -342,5 +356,13 @@ public String getUser() {
 		public String getPreferredAuthentications() {
 			return preferredAuthentications;
 		}
+
+		/**
+		 * @return true if batch (non-interactive) mode is preferred for this
+		 *         host connection.
+		 */
+		public boolean isBatchMode() {
+			return batchMode != null && batchMode.booleanValue();
+		}
 	}
 }
-- 
1.6.0.2.389.g421e0

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [JGIT PATCH 2/2] Add support for ~/.ssh/config BatchMode
  2008-09-16 15:44 ` [JGIT PATCH 2/2] Add support for ~/.ssh/config BatchMode Shawn O. Pearce
@ 2008-09-16 22:46   ` Robin Rosenberg
  2008-09-16 22:52     ` Shawn O. Pearce
  0 siblings, 1 reply; 4+ messages in thread
From: Robin Rosenberg @ 2008-09-16 22:46 UTC (permalink / raw)
  To: Shawn O. Pearce; +Cc: git

tisdagen den 16 september 2008 17.44.29 skrev Shawn O. Pearce:
> Connections created through batch processes (e.g. those started by
> cron) don't have a terminal to interact with a user through.  A
> common way to disable password prompting with OpenSSH is to setup
> a Host block in ~/.ssh/config with "BatchMode yes" enabled, thus
> telling the client not to prompt for passphases or passwords.

That did not work when any of the identities in  ~/.ssh matched. Though
I specifically told jgit to use an identity that should not work, it found another
that did. During setup all identities are loaded and made available to JSch.

That bug is not related to this code (so I pushed it) other than it made it tricky
to test. OpenSSH only tries the identity I tell it to, or default  if not told.

-- robin

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [JGIT PATCH 2/2] Add support for ~/.ssh/config BatchMode
  2008-09-16 22:46   ` Robin Rosenberg
@ 2008-09-16 22:52     ` Shawn O. Pearce
  0 siblings, 0 replies; 4+ messages in thread
From: Shawn O. Pearce @ 2008-09-16 22:52 UTC (permalink / raw)
  To: Robin Rosenberg; +Cc: git

Robin Rosenberg <robin.rosenberg@dewire.com> wrote:
> tisdagen den 16 september 2008 17.44.29 skrev Shawn O. Pearce:
> > Connections created through batch processes (e.g. those started by
> > cron) don't have a terminal to interact with a user through.  A
> > common way to disable password prompting with OpenSSH is to setup
> > a Host block in ~/.ssh/config with "BatchMode yes" enabled, thus
> > telling the client not to prompt for passphases or passwords.
> 
> That did not work when any of the identities in  ~/.ssh matched. Though
> I specifically told jgit to use an identity that should not work, it found another
> that did. During setup all identities are loaded and made available to JSch.

Yes, that's a known bug.
 
> That bug is not related to this code (so I pushed it) other than it made it tricky
> to test. OpenSSH only tries the identity I tell it to, or default  if not told.

I have a plan on how to fix it.  I just didn't find the time today
to actually implement it.  I'll put an issue on the issue tracker
with my thoughts on how IdentityFile can be implemented correctly.
If I don't get to it this week maybe someone else can, it looks
pretty simple on the surface.

-- 
Shawn.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-09-16 22:53 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-16 15:44 [JGIT PATCH 1/2 v2] Add support for ~/.ssh/config PreferredAuthentications Shawn O. Pearce
2008-09-16 15:44 ` [JGIT PATCH 2/2] Add support for ~/.ssh/config BatchMode Shawn O. Pearce
2008-09-16 22:46   ` Robin Rosenberg
2008-09-16 22:52     ` Shawn O. Pearce

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).