summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.ssh.apache.test
diff options
context:
space:
mode:
authorThomas Wolf <thomas.wolf@paranor.ch>2020-04-23 18:30:19 +0200
committerThomas Wolf <thomas.wolf@paranor.ch>2020-05-23 16:46:22 +0200
commit3a499606b1d8f18cb129cd47e63dd17f54e80def (patch)
treed469eba5c868cde9d7a250b9e5493de7342bc75f /org.eclipse.jgit.ssh.apache.test
parentbdb7357228c6611cea2d266255c7751bd9ed368e (diff)
downloadjgit-3a499606b1d8f18cb129cd47e63dd17f54e80def.tar.gz
jgit-3a499606b1d8f18cb129cd47e63dd17f54e80def.zip
Builder API to configure SshdSessionFactories
A builder API provides a more convenient way to define a customized SshdSessionFactory by hiding the subclassing. Also provide a new interface SshConfigStore to abstract away the specifics of reading a ssh config file, and provide a way to customize the concrete ssh config implementation to be used. This facilitates using an alternate ssh config implementation that may or may not be based on files. Change-Id: Ib9038e8ff2a4eb3a9ce7b3554d1450befec8e1e1 Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
Diffstat (limited to 'org.eclipse.jgit.ssh.apache.test')
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshBuilderTest.java163
-rw-r--r--org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java1
2 files changed, 163 insertions, 1 deletions
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshBuilderTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshBuilderTest.java
new file mode 100644
index 0000000000..04208fef32
--- /dev/null
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshBuilderTest.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Distribution License v. 1.0 which is available at
+ * https://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+package org.eclipse.jgit.transport.sshd;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UncheckedIOException;
+import java.net.InetSocketAddress;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
+import org.apache.sshd.common.session.SessionContext;
+import org.apache.sshd.common.util.net.SshdSocketAddress;
+import org.apache.sshd.common.util.security.SecurityUtils;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.SshSessionFactory;
+import org.eclipse.jgit.transport.ssh.SshTestHarness;
+import org.eclipse.jgit.util.FS;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * Test for using the SshdSessionFactory without files in ~/.ssh but with an
+ * in-memory setup, creating the factory via the builder API.
+ */
+public class NoFilesSshBuilderTest extends SshTestHarness {
+
+ private PublicKey testServerKey;
+
+ private KeyPair testUserKey;
+
+ @Override
+ protected SshSessionFactory createSessionFactory() {
+ return new SshdSessionFactoryBuilder() //
+ .setConfigStoreFactory((h, f, u) -> null)
+ .setDefaultKeysProvider(f -> new KeyAuthenticator())
+ .setServerKeyDatabase((h, s) -> new ServerKeyDatabase() {
+
+ @Override
+ public List<PublicKey> lookup(String connectAddress,
+ InetSocketAddress remoteAddress,
+ Configuration config) {
+ return Collections.singletonList(testServerKey);
+ }
+
+ @Override
+ public boolean accept(String connectAddress,
+ InetSocketAddress remoteAddress,
+ PublicKey serverKey, Configuration config,
+ CredentialsProvider provider) {
+ return KeyUtils.compareKeys(serverKey, testServerKey);
+ }
+
+ }) //
+ .setPreferredAuthentications("publickey")
+ .setHomeDirectory(FS.DETECTED.userHome())
+ .setSshDirectory(sshDir) //
+ .build(new JGitKeyCache());
+ }
+
+ private class KeyAuthenticator
+ implements KeyIdentityProvider, Iterable<KeyPair> {
+
+ @Override
+ public Iterator<KeyPair> iterator() {
+ // Should not be called. The use of the Iterable interface in
+ // SshdSessionFactory.getDefaultKeys() made sense in sshd 2.0.0,
+ // but sshd 2.2.0 added the SessionContext, which although good
+ // (without it we couldn't check here) breaks the Iterable analogy.
+ // But we're stuck now with that interface for getDefaultKeys, and
+ // so this override throwing an exception is unfortunately needed.
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Iterable<KeyPair> loadKeys(SessionContext session)
+ throws IOException, GeneralSecurityException {
+ if (!TEST_USER.equals(session.getUsername())) {
+ return Collections.emptyList();
+ }
+ SshdSocketAddress remoteAddress = SshdSocketAddress
+ .toSshdSocketAddress(session.getRemoteAddress());
+ switch (remoteAddress.getHostName()) {
+ case "localhost":
+ case "127.0.0.1":
+ return Collections.singletonList(testUserKey);
+ default:
+ return Collections.emptyList();
+ }
+ }
+ }
+
+ @After
+ public void cleanUp() {
+ testServerKey = null;
+ testUserKey = null;
+ }
+
+ @Override
+ protected void installConfig(String... config) {
+ File configFile = new File(sshDir, Constants.CONFIG);
+ if (config != null) {
+ try {
+ Files.write(configFile.toPath(), Arrays.asList(config));
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+ }
+
+ private KeyPair load(Path path) throws Exception {
+ try (InputStream in = Files.newInputStream(path)) {
+ return SecurityUtils
+ .loadKeyPairIdentities(null,
+ NamedResource.ofName(path.toString()), in, null)
+ .iterator().next();
+ }
+ }
+
+ @Test
+ public void testCloneWithBuiltInKeys() throws Exception {
+ // This test should fail unless our in-memory setup is taken: no
+ // known_hosts file, and a config that specifies a non-existing key.
+ File newHostKey = new File(getTemporaryDirectory(), "newhostkey");
+ copyTestResource("id_ed25519", newHostKey);
+ server.addHostKey(newHostKey.toPath(), true);
+ testServerKey = load(newHostKey.toPath()).getPublic();
+ assertTrue(newHostKey.delete());
+ testUserKey = load(privateKey1.getAbsoluteFile().toPath());
+ assertNotNull(testServerKey);
+ assertNotNull(testUserKey);
+ cloneWith(
+ "ssh://" + TEST_USER + "@localhost:" + testPort
+ + "/doesntmatter",
+ new File(getTemporaryDirectory(), "cloned"), null, //
+ "Host localhost", //
+ "IdentityFile "
+ + new File(sshDir, "does_not_exist").getAbsolutePath());
+ }
+
+}
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java
index 608f647bc5..fa026a5c03 100644
--- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java
+++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/NoFilesSshTest.java
@@ -47,7 +47,6 @@ import org.junit.Test;
*/
public class NoFilesSshTest extends SshTestHarness {
-
private PublicKey testServerKey;
private KeyPair testUserKey;