123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705 |
- /*
- * Copyright (C) 2018, 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.apache.sshd.core.CoreModuleProperties.MAX_CONCURRENT_SESSIONS;
- import static org.junit.Assert.assertEquals;
- import static org.junit.Assert.assertFalse;
- import static org.junit.Assert.assertNotNull;
- import static org.junit.Assert.assertThrows;
- import static org.junit.Assert.assertTrue;
-
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.IOException;
- import java.io.UncheckedIOException;
- import java.net.URISyntaxException;
- import java.nio.charset.StandardCharsets;
- import java.nio.file.Files;
- import java.nio.file.StandardOpenOption;
- import java.security.KeyPair;
- import java.security.KeyPairGenerator;
- import java.security.PublicKey;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.List;
- import java.util.stream.Collectors;
-
- import org.apache.sshd.client.config.hosts.KnownHostEntry;
- import org.apache.sshd.client.config.hosts.KnownHostHashValue;
- import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
- import org.apache.sshd.common.config.keys.KeyUtils;
- import org.apache.sshd.common.config.keys.PublicKeyEntry;
- import org.apache.sshd.common.config.keys.PublicKeyEntryResolver;
- import org.apache.sshd.common.session.Session;
- import org.apache.sshd.common.util.net.SshdSocketAddress;
- import org.apache.sshd.server.ServerAuthenticationManager;
- import org.apache.sshd.server.SshServer;
- import org.apache.sshd.server.forward.StaticDecisionForwardingFilter;
- import org.eclipse.jgit.api.Git;
- import org.eclipse.jgit.api.errors.TransportException;
- import org.eclipse.jgit.junit.ssh.SshTestBase;
- import org.eclipse.jgit.lib.Constants;
- import org.eclipse.jgit.transport.RemoteSession;
- import org.eclipse.jgit.transport.SshSessionFactory;
- import org.eclipse.jgit.transport.URIish;
- import org.eclipse.jgit.util.FS;
- import org.junit.Test;
- import org.junit.experimental.theories.Theories;
- import org.junit.runner.RunWith;
-
- @RunWith(Theories.class)
- public class ApacheSshTest extends SshTestBase {
-
- @Override
- protected SshSessionFactory createSessionFactory() {
- SshdSessionFactory result = new SshdSessionFactory(new JGitKeyCache(),
- null);
- // The home directory is mocked at this point!
- result.setHomeDirectory(FS.DETECTED.userHome());
- result.setSshDirectory(sshDir);
- return result;
- }
-
- @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);
- }
- }
- }
-
- @Test
- public void testEd25519HostKey() throws Exception {
- // Using ed25519 user identities is tested in the super class in
- // testSshKeys().
- File newHostKey = new File(getTemporaryDirectory(), "newhostkey");
- copyTestResource("id_ed25519", newHostKey);
- server.addHostKey(newHostKey.toPath(), true);
- File newHostKeyPub = new File(getTemporaryDirectory(),
- "newhostkey.pub");
- copyTestResource("id_ed25519.pub", newHostKeyPub);
- createKnownHostsFile(knownHosts, "localhost", testPort, newHostKeyPub);
- cloneWith("ssh://git/doesntmatter", defaultCloneDir, null, //
- "Host git", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath());
- }
-
- @Test
- public void testHashedKnownHosts() throws Exception {
- assertTrue("Failed to delete known_hosts", knownHosts.delete());
- // The provider will answer "yes" to all questions, so we should be able
- // to connect and end up with a new known_hosts file with the host key.
- TestCredentialsProvider provider = new TestCredentialsProvider();
- cloneWith("ssh://localhost/doesntmatter", defaultCloneDir, provider, //
- "HashKnownHosts yes", //
- "Host localhost", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath());
- List<LogEntry> messages = provider.getLog();
- assertFalse("Expected user interaction", messages.isEmpty());
- assertEquals(
- "Expected to be asked about the key, and the file creation", 2,
- messages.size());
- assertTrue("~/.ssh/known_hosts should exist now", knownHosts.exists());
- // Let's clone again without provider. If it works, the server host key
- // was written correctly.
- File clonedAgain = new File(getTemporaryDirectory(), "cloned2");
- cloneWith("ssh://localhost/doesntmatter", clonedAgain, null, //
- "Host localhost", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath());
- // Check that the first line contains neither "localhost" nor
- // "127.0.0.1", but does contain the expected hash.
- List<String> lines = Files.readAllLines(knownHosts.toPath()).stream()
- .filter(s -> s != null && s.length() >= 1 && s.charAt(0) != '#'
- && !s.trim().isEmpty())
- .collect(Collectors.toList());
- assertEquals("Unexpected number of known_hosts lines", 1, lines.size());
- String line = lines.get(0);
- assertFalse("Found host in line", line.contains("localhost"));
- assertFalse("Found IP in line", line.contains("127.0.0.1"));
- assertTrue("Hash not found", line.contains("|"));
- KnownHostEntry entry = KnownHostEntry.parseKnownHostEntry(line);
- assertTrue("Hash doesn't match localhost",
- entry.isHostMatch("localhost", testPort)
- || entry.isHostMatch("127.0.0.1", testPort));
- }
-
- @Test
- public void testPreamble() throws Exception {
- // Test that the client can deal with strange lines being sent before
- // the server identification string.
- StringBuilder b = new StringBuilder();
- for (int i = 0; i < 257; i++) {
- b.append('a');
- }
- server.setPreamble("A line with a \000 NUL",
- "A long line: " + b.toString());
- cloneWith(
- "ssh://" + TEST_USER + "@localhost:" + testPort
- + "/doesntmatter",
- defaultCloneDir, null,
- "IdentityFile " + privateKey1.getAbsolutePath());
- }
-
- @Test
- public void testLongPreamble() throws Exception {
- // Test that the client can deal with a long (about 60k) preamble.
- StringBuilder b = new StringBuilder();
- for (int i = 0; i < 1024; i++) {
- b.append('a');
- }
- String line = b.toString();
- String[] lines = new String[60];
- for (int i = 0; i < lines.length; i++) {
- lines[i] = line;
- }
- server.setPreamble(lines);
- cloneWith(
- "ssh://" + TEST_USER + "@localhost:" + testPort
- + "/doesntmatter",
- defaultCloneDir, null,
- "IdentityFile " + privateKey1.getAbsolutePath());
- }
-
- @Test
- public void testHugePreamble() throws Exception {
- // Test that the connection fails when the preamble is longer than 64k.
- StringBuilder b = new StringBuilder();
- for (int i = 0; i < 1024; i++) {
- b.append('a');
- }
- String line = b.toString();
- String[] lines = new String[70];
- for (int i = 0; i < lines.length; i++) {
- lines[i] = line;
- }
- server.setPreamble(lines);
- TransportException e = assertThrows(TransportException.class,
- () -> cloneWith(
- "ssh://" + TEST_USER + "@localhost:" + testPort
- + "/doesntmatter",
- defaultCloneDir, null,
- "IdentityFile " + privateKey1.getAbsolutePath()));
- // The assertions test that we don't run into bug 565394 / SSHD-1050
- assertFalse(e.getMessage().contains("timeout"));
- assertTrue(e.getMessage().contains("65536")
- || e.getMessage().contains("closed"));
- }
-
- /**
- * Test for SSHD-1028. If the server doesn't close sessions, the second
- * fetch will fail. Occurs on sshd 2.5.[01].
- *
- * @throws Exception
- * on errors
- * @see <a href=
- * "https://issues.apache.org/jira/projects/SSHD/issues/SSHD-1028">SSHD-1028</a>
- */
- @Test
- public void testCloneAndFetchWithSessionLimit() throws Exception {
- MAX_CONCURRENT_SESSIONS
- .set(server.getPropertyResolver(), Integer.valueOf(2));
- File localClone = cloneWith("ssh://localhost/doesntmatter",
- defaultCloneDir, null, //
- "Host localhost", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath());
- // Fetch a couple of times
- try (Git git = Git.open(localClone)) {
- git.fetch().call();
- git.fetch().call();
- }
- }
-
- /**
- * Creates a simple SSH server without git setup.
- *
- * @param user
- * to accept
- * @param userKey
- * public key of that user at this server
- * @return the {@link SshServer}, not yet started
- * @throws Exception
- */
- private SshServer createServer(String user, File userKey) throws Exception {
- SshServer srv = SshServer.setUpDefaultServer();
- // Give the server its own host key
- KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
- generator.initialize(2048);
- KeyPair proxyHostKey = generator.generateKeyPair();
- srv.setKeyPairProvider(
- session -> Collections.singletonList(proxyHostKey));
- // Allow (only) publickey authentication
- srv.setUserAuthFactories(Collections.singletonList(
- ServerAuthenticationManager.DEFAULT_USER_AUTH_PUBLIC_KEY_FACTORY));
- // Install the user's public key
- PublicKey userProxyKey = AuthorizedKeyEntry
- .readAuthorizedKeys(userKey.toPath()).get(0)
- .resolvePublicKey(null, PublicKeyEntryResolver.IGNORING);
- srv.setPublickeyAuthenticator(
- (userName, publicKey, session) -> user.equals(userName)
- && KeyUtils.compareKeys(userProxyKey, publicKey));
- return srv;
- }
-
- /**
- * Writes the server's host key to our knownhosts file.
- *
- * @param srv to register
- * @throws Exception
- */
- private void registerServer(SshServer srv) throws Exception {
- // Add the proxy's host key to knownhosts
- try (BufferedWriter writer = Files.newBufferedWriter(
- knownHosts.toPath(), StandardCharsets.US_ASCII,
- StandardOpenOption.WRITE, StandardOpenOption.APPEND)) {
- writer.append('\n');
- KnownHostHashValue.appendHostPattern(writer, "localhost",
- srv.getPort());
- writer.append(',');
- KnownHostHashValue.appendHostPattern(writer, "127.0.0.1",
- srv.getPort());
- writer.append(' ');
- PublicKeyEntry.appendPublicKeyEntry(writer,
- srv.getKeyPairProvider().loadKeys(null).iterator().next().getPublic());
- writer.append('\n');
- }
- }
-
- /**
- * Creates a simple proxy server. Accepts only publickey authentication from
- * the given user with the given key, allows all forwardings. Adds the
- * proxy's host key to {@link #knownHosts}.
- *
- * @param user
- * to accept
- * @param userKey
- * public key of that user at this server
- * @param report
- * single-element array to report back the forwarded address.
- * @return the started server
- * @throws Exception
- */
- private SshServer createProxy(String user, File userKey,
- SshdSocketAddress[] report) throws Exception {
- SshServer proxy = createServer(user, userKey);
- // Allow forwarding
- proxy.setForwardingFilter(new StaticDecisionForwardingFilter(true) {
-
- @Override
- protected boolean checkAcceptance(String request, Session session,
- SshdSocketAddress target) {
- report[0] = target;
- return super.checkAcceptance(request, session, target);
- }
- });
- proxy.start();
- registerServer(proxy);
- return proxy;
- }
-
- @Test
- public void testJumpHost() throws Exception {
- SshdSocketAddress[] forwarded = { null };
- try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
- forwarded)) {
- try {
- // Now try to clone via the proxy
- cloneWith("ssh://server/doesntmatter", defaultCloneDir, null, //
- "Host server", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath(), //
- "ProxyJump " + TEST_USER + "X@proxy:" + proxy.getPort(), //
- "", //
- "Host proxy", //
- "Hostname localhost", //
- "IdentityFile " + privateKey2.getAbsolutePath());
- assertNotNull(forwarded[0]);
- assertEquals(testPort, forwarded[0].getPort());
- } finally {
- proxy.stop();
- }
- }
- }
-
- @Test
- public void testJumpHostWrongKeyAtProxy() throws Exception {
- // Test that we find the proxy server's URI in the exception message
- SshdSocketAddress[] forwarded = { null };
- try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
- forwarded)) {
- try {
- // Now try to clone via the proxy
- TransportException e = assertThrows(TransportException.class,
- () -> cloneWith("ssh://server/doesntmatter",
- defaultCloneDir, null, //
- "Host server", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath(),
- "ProxyJump " + TEST_USER + "X@proxy:"
- + proxy.getPort(), //
- "", //
- "Host proxy", //
- "Hostname localhost", //
- "IdentityFile "
- + privateKey1.getAbsolutePath()));
- String message = e.getMessage();
- assertTrue(message.contains("localhost:" + proxy.getPort()));
- assertTrue(message.contains("proxy:" + proxy.getPort()));
- } finally {
- proxy.stop();
- }
- }
- }
-
- @Test
- public void testJumpHostWrongKeyAtServer() throws Exception {
- // Test that we find the target server's URI in the exception message
- SshdSocketAddress[] forwarded = { null };
- try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
- forwarded)) {
- try {
- // Now try to clone via the proxy
- TransportException e = assertThrows(TransportException.class,
- () -> cloneWith("ssh://server/doesntmatter",
- defaultCloneDir, null, //
- "Host server", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey2.getAbsolutePath(),
- "ProxyJump " + TEST_USER + "X@proxy:"
- + proxy.getPort(), //
- "", //
- "Host proxy", //
- "Hostname localhost", //
- "IdentityFile "
- + privateKey2.getAbsolutePath()));
- String message = e.getMessage();
- assertTrue(message.contains("localhost:" + testPort));
- assertTrue(message.contains("ssh://server"));
- } finally {
- proxy.stop();
- }
- }
- }
-
- @Test
- public void testJumpHostNonSsh() throws Exception {
- SshdSocketAddress[] forwarded = { null };
- try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
- forwarded)) {
- try {
- TransportException e = assertThrows(TransportException.class,
- () -> cloneWith("ssh://server/doesntmatter",
- defaultCloneDir, null, //
- "Host server", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath(), //
- "ProxyJump http://" + TEST_USER + "X@proxy:"
- + proxy.getPort(), //
- "", //
- "Host proxy", //
- "Hostname localhost", //
- "IdentityFile "
- + privateKey2.getAbsolutePath()));
- // Find the expected message
- Throwable t = e;
- while (t != null) {
- if (t instanceof URISyntaxException) {
- break;
- }
- t = t.getCause();
- }
- assertNotNull(t);
- assertTrue(t.getMessage().contains("Non-ssh"));
- } finally {
- proxy.stop();
- }
- }
- }
-
- @Test
- public void testJumpHostWithPath() throws Exception {
- SshdSocketAddress[] forwarded = { null };
- try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
- forwarded)) {
- try {
- TransportException e = assertThrows(TransportException.class,
- () -> cloneWith("ssh://server/doesntmatter",
- defaultCloneDir, null, //
- "Host server", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath(), //
- "ProxyJump ssh://" + TEST_USER + "X@proxy:"
- + proxy.getPort() + "/wrongPath", //
- "", //
- "Host proxy", //
- "Hostname localhost", //
- "IdentityFile "
- + privateKey2.getAbsolutePath()));
- // Find the expected message
- Throwable t = e;
- while (t != null) {
- if (t instanceof URISyntaxException) {
- break;
- }
- t = t.getCause();
- }
- assertNotNull(t);
- assertTrue(t.getMessage().contains("wrongPath"));
- } finally {
- proxy.stop();
- }
- }
- }
-
- @Test
- public void testJumpHostWithPathShort() throws Exception {
- SshdSocketAddress[] forwarded = { null };
- try (SshServer proxy = createProxy(TEST_USER + 'X', publicKey2,
- forwarded)) {
- try {
- TransportException e = assertThrows(TransportException.class,
- () -> cloneWith("ssh://server/doesntmatter",
- defaultCloneDir, null, //
- "Host server", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath(), //
- "ProxyJump " + TEST_USER + "X@proxy:wrongPath", //
- "", //
- "Host proxy", //
- "Hostname localhost", //
- "Port " + proxy.getPort(), //
- "IdentityFile "
- + privateKey2.getAbsolutePath()));
- // Find the expected message
- Throwable t = e;
- while (t != null) {
- if (t instanceof URISyntaxException) {
- break;
- }
- t = t.getCause();
- }
- assertNotNull(t);
- assertTrue(t.getMessage().contains("wrongPath"));
- } finally {
- proxy.stop();
- }
- }
- }
-
- @Test
- public void testJumpHostChain() throws Exception {
- SshdSocketAddress[] forwarded1 = { null };
- SshdSocketAddress[] forwarded2 = { null };
- try (SshServer proxy1 = createProxy(TEST_USER + 'X', publicKey2,
- forwarded1);
- SshServer proxy2 = createProxy("foo", publicKey1, forwarded2)) {
- try {
- // Clone proxy1 -> proxy2 -> server
- cloneWith("ssh://server/doesntmatter", defaultCloneDir, null, //
- "Host server", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath(), //
- "ProxyJump proxy2," + TEST_USER + "X@proxy:"
- + proxy1.getPort(), //
- "", //
- "Host proxy", //
- "Hostname localhost", //
- "IdentityFile " + privateKey2.getAbsolutePath(), //
- "", //
- "Host proxy2", //
- "Hostname localhost", //
- "User foo", //
- "Port " + proxy2.getPort(), //
- "IdentityFile " + privateKey1.getAbsolutePath());
- assertNotNull(forwarded1[0]);
- assertEquals(proxy2.getPort(), forwarded1[0].getPort());
- assertNotNull(forwarded2[0]);
- assertEquals(testPort, forwarded2[0].getPort());
- } finally {
- proxy1.stop();
- proxy2.stop();
- }
- }
- }
-
- @Test
- public void testJumpHostCascade() throws Exception {
- SshdSocketAddress[] forwarded1 = { null };
- SshdSocketAddress[] forwarded2 = { null };
- try (SshServer proxy1 = createProxy(TEST_USER + 'X', publicKey2,
- forwarded1);
- SshServer proxy2 = createProxy("foo", publicKey1, forwarded2)) {
- try {
- // Clone proxy2 -> proxy1 -> server
- cloneWith("ssh://server/doesntmatter", defaultCloneDir, null, //
- "Host server", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath(), //
- "ProxyJump " + TEST_USER + "X@proxy", //
- "", //
- "Host proxy", //
- "Hostname localhost", //
- "Port " + proxy1.getPort(), //
- "ProxyJump ssh://proxy2:" + proxy2.getPort(), //
- "IdentityFile " + privateKey2.getAbsolutePath(), //
- "", //
- "Host proxy2", //
- "Hostname localhost", //
- "User foo", //
- "IdentityFile " + privateKey1.getAbsolutePath());
- assertNotNull(forwarded1[0]);
- assertEquals(testPort, forwarded1[0].getPort());
- assertNotNull(forwarded2[0]);
- assertEquals(proxy1.getPort(), forwarded2[0].getPort());
- } finally {
- proxy1.stop();
- proxy2.stop();
- }
- }
- }
-
- @Test
- public void testJumpHostRecursion() throws Exception {
- SshdSocketAddress[] forwarded1 = { null };
- SshdSocketAddress[] forwarded2 = { null };
- try (SshServer proxy1 = createProxy(TEST_USER + 'X', publicKey2,
- forwarded1);
- SshServer proxy2 = createProxy("foo", publicKey1, forwarded2)) {
- try {
- TransportException e = assertThrows(TransportException.class,
- () -> cloneWith(
- "ssh://server/doesntmatter", defaultCloneDir, null, //
- "Host server", //
- "HostName localhost", //
- "Port " + testPort, //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath(), //
- "ProxyJump " + TEST_USER + "X@proxy", //
- "", //
- "Host proxy", //
- "Hostname localhost", //
- "Port " + proxy1.getPort(), //
- "ProxyJump ssh://proxy2:" + proxy2.getPort(), //
- "IdentityFile " + privateKey2.getAbsolutePath(), //
- "", //
- "Host proxy2", //
- "Hostname localhost", //
- "User foo", //
- "ProxyJump " + TEST_USER + "X@proxy", //
- "IdentityFile " + privateKey1.getAbsolutePath()));
- assertTrue(e.getMessage().contains("proxy"));
- } finally {
- proxy1.stop();
- proxy2.stop();
- }
- }
- }
-
- /**
- * Tests that one can log in to an old server that doesn't handle
- * rsa-sha2-512 if one puts ssh-rsa first in the client's list of public key
- * signature algorithms.
- *
- * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=572056">bug
- * 572056</a>
- * @throws Exception
- * on failure
- */
- @Test
- public void testConnectAuthSshRsaPubkeyAcceptedAlgorithms()
- throws Exception {
- try (SshServer oldServer = createServer(TEST_USER, publicKey1)) {
- oldServer.setSignatureFactoriesNames("ssh-rsa");
- oldServer.start();
- registerServer(oldServer);
- installConfig("Host server", //
- "HostName localhost", //
- "Port " + oldServer.getPort(), //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath(), //
- "PubkeyAcceptedAlgorithms ^ssh-rsa");
- RemoteSession session = getSessionFactory().getSession(
- new URIish("ssh://server/doesntmatter"), null, FS.DETECTED,
- 10000);
- assertNotNull(session);
- session.disconnect();
- }
- }
-
- /**
- * Tests that one can log in to an old server that knows only the ssh-rsa
- * signature algorithm. The client has by default the list of signature
- * algorithms for RSA as "rsa-sha2-512,rsa-sha2-256,ssh-rsa". It should try
- * all three with the single key configured, and finally succeed.
- * <p>
- * The re-ordering mechanism (see
- * {@link #testConnectAuthSshRsaPubkeyAcceptedAlgorithms()}) is still
- * important; servers may impose a penalty (back-off delay) for subsequent
- * attempts with signature algorithms unknown to the server. So a user
- * connecting to such a server and noticing delays may still want to put
- * ssh-rsa first in the list for that host.
- * </p>
- *
- * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=572056">bug
- * 572056</a>
- * @throws Exception
- * on failure
- */
- @Test
- public void testConnectAuthSshRsa() throws Exception {
- try (SshServer oldServer = createServer(TEST_USER, publicKey1)) {
- oldServer.setSignatureFactoriesNames("ssh-rsa");
- oldServer.start();
- registerServer(oldServer);
- installConfig("Host server", //
- "HostName localhost", //
- "Port " + oldServer.getPort(), //
- "User " + TEST_USER, //
- "IdentityFile " + privateKey1.getAbsolutePath());
- RemoteSession session = getSessionFactory().getSession(
- new URIish("ssh://server/doesntmatter"), null, FS.DETECTED,
- 10000);
- assertNotNull(session);
- session.disconnect();
- }
- }
- }
|