From c56fa51709278f2be4e155ae5fbad270188cbe64 Mon Sep 17 00:00:00 2001 From: Thomas Wolf Date: Wed, 17 Oct 2018 20:22:26 +0200 Subject: Apache MINA sshd: use NumberOfPasswordPrompts for encrypted keys sshd only asks exactly once for the password. C.f. upstream issue SSHD-850.[1] So we have to work around this limitation for now. Once we move to sshd > 2.1.0, this can be simplified somewhat. [1] https://issues.apache.org/jira/browse/SSHD-850 Bug: 520927 Change-Id: Id65650228486c5ed30affa9c62eac982e01ae207 Signed-off-by: Thomas Wolf --- .../eclipse/jgit/transport/ssh/SshTestBase.java | 47 +++++++++++++++++++--- .../eclipse/jgit/transport/ssh/SshTestHarness.java | 28 ++++++++++--- 2 files changed, 65 insertions(+), 10 deletions(-) (limited to 'org.eclipse.jgit.test') 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 3e4493119e..86dbc4edcd 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 @@ -54,12 +54,10 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.List; -import java.util.Map; import org.eclipse.jgit.api.errors.TransportException; import org.eclipse.jgit.transport.CredentialItem; import org.eclipse.jgit.transport.JschConfigSessionFactory; -import org.eclipse.jgit.transport.URIish; import org.junit.Test; import org.junit.experimental.theories.DataPoints; import org.junit.experimental.theories.Theory; @@ -221,6 +219,45 @@ public abstract class SshTestBase extends SshTestHarness { provider.getLog().size()); } + @Test(expected = TransportException.class) + public void testSshEncryptedUsedKeyWrongPassword() throws Exception { + File encryptedKey = new File(sshDir, "id_dsa_test_key"); + copyTestResource("id_dsa_testpass", encryptedKey); + File encryptedPublicKey = new File(sshDir, "id_dsa_test_key.pub"); + copyTestResource("id_dsa_testpass.pub", encryptedPublicKey); + server.setTestUserPublicKey(encryptedPublicKey.toPath()); + TestCredentialsProvider provider = new TestCredentialsProvider( + "wrongpass"); + cloneWith("ssh://localhost/doesntmatter", // + defaultCloneDir, provider, // + "Host localhost", // + "HostName localhost", // + "Port " + testPort, // + "User " + TEST_USER, // + "NumberOfPasswordPrompts 1", // + "IdentityFile " + encryptedKey.getAbsolutePath()); + } + + @Test + public void testSshEncryptedUsedKeySeveralPassword() throws Exception { + File encryptedKey = new File(sshDir, "id_dsa_test_key"); + copyTestResource("id_dsa_testpass", encryptedKey); + File encryptedPublicKey = new File(sshDir, "id_dsa_test_key.pub"); + copyTestResource("id_dsa_testpass.pub", encryptedPublicKey); + server.setTestUserPublicKey(encryptedPublicKey.toPath()); + TestCredentialsProvider provider = new TestCredentialsProvider( + "wrongpass", "wrongpass2", "testpass"); + cloneWith("ssh://localhost/doesntmatter", // + defaultCloneDir, provider, // + "Host localhost", // + "HostName localhost", // + "Port " + testPort, // + "User " + TEST_USER, // + "IdentityFile " + encryptedKey.getAbsolutePath()); + assertEquals("CredentialsProvider should have been called 3 times", 3, + provider.getLog().size()); + } + @Test(expected = TransportException.class) public void testSshWithoutKnownHosts() throws Exception { assertTrue("Could not delete known_hosts", knownHosts.delete()); @@ -248,7 +285,7 @@ public abstract class SshTestBase extends SshTestHarness { "Port " + testPort, // "User " + TEST_USER, // "IdentityFile " + privateKey1.getAbsolutePath()); - Map> messages = provider.getLog(); + List messages = provider.getLog(); assertFalse("Expected user interaction", messages.isEmpty()); if (getSessionFactory() instanceof JschConfigSessionFactory) { // JSch doesn't create a non-existing file. @@ -361,8 +398,8 @@ public abstract class SshTestBase extends SshTestHarness { } catch (Exception e) { assertEquals("Expected to be told about the modified key", 1, provider.getLog().size()); - assertTrue("Only messages expected", provider.getLog().values() - .stream().flatMap(List::stream).allMatch( + assertTrue("Only messages expected", provider.getLog().stream() + .flatMap(l -> l.getItems().stream()).allMatch( c -> c instanceof CredentialItem.InformationalMessage)); throw e; } diff --git a/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestHarness.java b/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestHarness.java index 347c72b3d7..59925a5a16 100644 --- a/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestHarness.java +++ b/org.eclipse.jgit.test/src/org/eclipse/jgit/transport/ssh/SshTestHarness.java @@ -56,12 +56,11 @@ import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import org.eclipse.jgit.api.CloneCommand; import org.eclipse.jgit.api.Git; @@ -420,15 +419,34 @@ public abstract class SshTestHarness extends RepositoryTestCase { return true; } - private Map> log = new LinkedHashMap<>(); + private List log = new ArrayList<>(); private void logItems(URIish uri, CredentialItem... items) { - log.put(uri, Arrays.asList(items)); + log.add(new LogEntry(uri, Arrays.asList(items))); } - public Map> getLog() { + public List getLog() { return log; } } + protected static class LogEntry { + + private URIish uri; + + private List items; + + public LogEntry(URIish uri, List items) { + this.uri = uri; + this.items = items; + } + + public URIish getURIish() { + return uri; + } + + public List getItems() { + return items; + } + } } -- cgit v1.2.3