aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2018-10-01 23:27:10 +0200
committerMatthias Sohn <matthias.sohn@sap.com>2018-11-13 10:49:26 -0800
commit06387d4bfdddf96e0d590649cdc6b7f89a53e341 (patch)
tree5f092cef7d0ea110d7658906198ff06e3d22bcfe
parent9b31969f3c8b10747ee4af4fff83e9f45c6b41b0 (diff)
downloadjgit-06387d4bfdddf96e0d590649cdc6b7f89a53e341.tar.gz
jgit-06387d4bfdddf96e0d590649cdc6b7f89a53e341.zip
Add ssh tests for PreferredAuthentications
Tests that it works with unknown authentications in the list, and fails if there are no common authentications between server and client. The latter also tests that the ssh config setting is taken into account at all. And promptly the JGit sshd client didn't. Add a fix for this. It's a tiny bit hacky: Apache MINA looks up a custom property set on a hierarchy of "PropertyResolver"s starting with the session. On the session itself this property can never be set since it's read already in the session constructor before anyone had any chance to set it. The next element in the resolver hierarchy is the sshd SshClient, and so we set that property there. Since we use one SshClient and one ClientSession per JGit SshdSession, this is OK. Bug: 520927 Change-Id: I62446fc1fffde125a8965c030240f0918ae234b7 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
-rw-r--r--org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java20
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java19
-rw-r--r--org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java23
4 files changed, 63 insertions, 0 deletions
diff --git a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
index acc81018e8..f79287d75e 100644
--- a/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.ssh.apache/META-INF/MANIFEST.MF
@@ -51,6 +51,7 @@ Import-Package: org.apache.sshd.agent;version="[2.0.0,2.1.0)",
org.apache.sshd.common.digest;version="[2.0.0,2.1.0)",
org.apache.sshd.common.forward;version="[2.0.0,2.1.0)",
org.apache.sshd.common.future;version="[2.0.0,2.1.0)",
+ org.apache.sshd.common.helpers;version="[2.0.0,2.1.0)",
org.apache.sshd.common.io;version="[2.0.0,2.1.0)",
org.apache.sshd.common.kex;version="[2.0.0,2.1.0)",
org.apache.sshd.common.keyprovider;version="[2.0.0,2.1.0)",
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
index 98d4e3e5e5..2d8a6361ca 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitSshClient.java
@@ -82,6 +82,12 @@ import org.eclipse.jgit.transport.sshd.KeyCache;
*/
public class JGitSshClient extends SshClient {
+ /**
+ * An attribute key for the comma-separated list of default preferred
+ * authentication mechanisms.
+ */
+ public static final AttributeKey<String> PREFERRED_AUTHENTICATIONS = new AttributeKey<>();
+
private KeyCache keyCache;
private CredentialsProvider credentialsProvider;
@@ -109,10 +115,24 @@ public class JGitSshClient extends SshClient {
userName + '@' + address, null);
SshFutureListener<IoConnectFuture> listener = createConnectCompletionListener(
connectFuture, userName, address, hostConfig);
+ // sshd needs some entries from the host config already in the
+ // constructor of the session. Put those as properties on this client,
+ // where it will find them. We can set the host config only once the
+ // session object has been created.
+ copyProperty(
+ hostConfig.getProperty(SshConstants.PREFERRED_AUTHENTICATIONS,
+ getAttribute(PREFERRED_AUTHENTICATIONS)),
+ PREFERRED_AUTHS);
connector.connect(address).addListener(listener);
return connectFuture;
}
+ private void copyProperty(String value, String key) {
+ if (value != null && !value.isEmpty()) {
+ getProperties().put(key, value);
+ }
+ }
+
private SshFutureListener<IoConnectFuture> createConnectCompletionListener(
ConnectFuture connectFuture, String username,
InetSocketAddress address, HostConfigEntry hostConfig) {
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
index 862b5590e9..62fa6afdf9 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
@@ -217,6 +217,12 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable {
JGitSshClient jgitClient = (JGitSshClient) client;
jgitClient.setKeyCache(getKeyCache());
jgitClient.setCredentialsProvider(credentialsProvider);
+ String defaultAuths = getDefaultPreferredAuthentications();
+ if (defaultAuths != null) {
+ jgitClient.setAttribute(
+ JGitSshClient.PREFERRED_AUTHENTICATIONS,
+ defaultAuths);
+ }
// Other things?
return client;
});
@@ -433,4 +439,17 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable {
UserAuthKeyboardInteractiveFactory.INSTANCE,
UserAuthPasswordFactory.INSTANCE));
}
+
+ /**
+ * Gets the list of default preferred authentication mechanisms. If
+ * {@code null} is returned the openssh default list will be in effect. If
+ * the ssh config defines {@code PreferredAuthentications} the value from
+ * the ssh config takes precedence.
+ *
+ * @return a comma-separated list of algorithm names, or {@code null} if
+ * none
+ */
+ protected String getDefaultPreferredAuthentications() {
+ return null;
+ }
}
diff --git a/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java
index 2f623e3305..3b5aa5adb7 100644
--- a/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java
+++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestBase.java
@@ -572,6 +572,29 @@ public abstract class SshTestBase extends SshTestHarness {
"HostKeyAlgorithms ssh-rsa,ssh-dss");
}
+ @Test
+ public void testSshWithUnknownAuthInConfig() throws Exception {
+ cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
+ "Host git", //
+ "HostName localhost", //
+ "Port " + testPort, //
+ "User " + TEST_USER, //
+ "IdentityFile " + privateKey1.getAbsolutePath(), //
+ "PreferredAuthentications gssapi-with-mic,hostbased,publickey,keyboard-interactive,password");
+ }
+
+ @Test(expected = TransportException.class)
+ public void testSshWithNoMatchingAuthInConfig() throws Exception {
+ // Server doesn't do password, and anyway we set no password.
+ cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
+ "Host git", //
+ "HostName localhost", //
+ "Port " + testPort, //
+ "User " + TEST_USER, //
+ "IdentityFile " + privateKey1.getAbsolutePath(), //
+ "PreferredAuthentications password");
+ }
+
@Theory
public void testSshKeys(String keyName) throws Exception {
// JSch fails on ECDSA 384/521 keys. Compare