From 7726f9b52722ad55f33b4f57c10a1ee57769b314 Mon Sep 17 00:00:00 2001 From: "Shawn O. Pearce" Date: Tue, 16 Sep 2008 08:44:28 -0700 Subject: [PATCH] Add support for ~/.ssh/config PreferredAuthentications 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 Signed-off-by: Robin Rosenberg --- .../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 deletion(-) 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 640a165f..67c5f165 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 @@ class EclipseSshSessionFactory extends SshSessionFactory { 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 a250f9d9..1a71d082 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 @@ public class OpenSshConfigTest extends RepositoryTestCase { 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 @@ public class OpenSshConfigTest extends RepositoryTestCase { 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 74fca66f..b6f58f0b 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 @@ class DefaultSshSessionFactory extends SshSessionFactory { 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 cf7c3884..2f41e562 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 @@ public class OpenSshConfig { 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 @@ public class OpenSshConfig { 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 @@ public class OpenSshConfig { String user; + String preferredAuthentications; + void copyFrom(final Host src) { if (hostName == null) hostName = src.hostName; @@ -287,6 +302,8 @@ public class OpenSshConfig { identityFile = src.identityFile; if (user == null) user = src.user; + if (preferredAuthentications == null) + preferredAuthentications = src.preferredAuthentications; } /** @@ -317,5 +334,13 @@ public class OpenSshConfig { 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; + } } } -- 2.11.4.GIT