diff options
author | Thomas Wolf <thomas.wolf@paranor.ch> | 2022-04-01 16:56:05 +0200 |
---|---|---|
committer | Thomas Wolf <thomas.wolf@paranor.ch> | 2022-05-01 08:48:44 +0200 |
commit | 4dd9a94ec532aa2512dc220ab9d2f4929264c741 (patch) | |
tree | 308e89a844e2caf4757ba53b2682bb94221cdf8e /org.eclipse.jgit.ssh.apache.test | |
parent | 8b8999dca8d71b976da94715e06162510bb51460 (diff) | |
download | jgit-4dd9a94ec532aa2512dc220ab9d2f4929264c741.tar.gz jgit-4dd9a94ec532aa2512dc220ab9d2f4929264c741.zip |
[sshd] Better user feedback on authentication failure
When authentication fails, JGit produces an exception with an error
message telling the user that it could not log in (including the host
name). The causal chain has an SshException from Apache MINA sshd with
message "No more authentication methods available".
This is not very helpful. The user was left without any indication why
authentication failed.
Include in the exception message a log of all attempted authentications.
That way, the user can see which keys were tried, in which order and
with which signature algorithms. The log also reports authentication
attempts for gssapi-with-mic or password authentication. For
keyboard-interactive Apache MINA sshd is lacking a callback interface.
The way Apache MINA sshd loads keys from files, the file names are lost
in higher layers. Add a mechanism to record on the session for each
key fingerprint the file it was loaded from, if any. That way the
exception message can refer to keys by file name, which is easier to
understand by users than the rather cryptic key fingerprints.
Bug: 571390
Change-Id: Ic4b6ce6b99f307d5e798fcc91b16b9ffd995d224
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/ApacheSshTest.java | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java index 3d7c7651c1..a8fcca7b8e 100644 --- a/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java +++ b/org.eclipse.jgit.ssh.apache.test/tst/org/eclipse/jgit/transport/sshd/ApacheSshTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others + * Copyright (C) 2018, 2022 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 @@ -789,4 +789,76 @@ public class ApacheSshTest extends SshTestBase { session.disconnect(); } } + + private void verifyAuthLog(String message, String first) { + assertTrue(message.contains(System.lineSeparator())); + String[] lines = message.split(System.lineSeparator()); + int pubkeyIndex = -1; + int passwordIndex = -1; + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + if (i == 0) { + assertTrue(line.contains(first)); + } + if (line.contains("publickey:")) { + if (pubkeyIndex < 0) { + pubkeyIndex = i; + assertTrue(line.contains("/userkey")); + } + } else if (line.contains("password:")) { + if (passwordIndex < 0) { + passwordIndex = i; + assertTrue(line.contains("attempt 1")); + } + } + } + assertTrue(pubkeyIndex > 0 && passwordIndex > 0); + assertTrue(pubkeyIndex < passwordIndex); + } + + @Test + public void testAuthFailureMessageCancel() throws Exception { + File userKey = new File(getTemporaryDirectory(), "userkey"); + copyTestResource("id_ed25519", userKey); + File publicKey = new File(getTemporaryDirectory(), "userkey.pub"); + copyTestResource("id_ed25519.pub", publicKey); + // Don't set this as the user's key; we do want to try with a wrong key. + server.enablePasswordAuthentication(); + TestCredentialsProvider provider = new TestCredentialsProvider( + "wrongpass"); + TransportException e = assertThrows(TransportException.class, + () -> cloneWith("ssh://git/doesntmatter", defaultCloneDir, + provider, // + "Host git", // + "HostName localhost", // + "Port " + testPort, // + "User " + TEST_USER, // + "IdentityFile " + userKey.getAbsolutePath(), // + "PreferredAuthentications publickey,password")); + verifyAuthLog(e.getMessage(), "canceled"); + } + + @Test + public void testAuthFailureMessage() throws Exception { + File userKey = new File(getTemporaryDirectory(), "userkey"); + copyTestResource("id_ed25519", userKey); + File publicKey = new File(getTemporaryDirectory(), "userkey.pub"); + copyTestResource("id_ed25519.pub", publicKey); + // Don't set this as the user's key; we do want to try with a wrong key. + server.enablePasswordAuthentication(); + // Enough passwords not to cancel authentication + TestCredentialsProvider provider = new TestCredentialsProvider( + "wrongpass", "wrongpass", "wrongpass"); + TransportException e = assertThrows(TransportException.class, + () -> cloneWith("ssh://git/doesntmatter", defaultCloneDir, + provider, // + "Host git", // + "HostName localhost", // + "Port " + testPort, // + "User " + TEST_USER, // + "IdentityFile " + userKey.getAbsolutePath(), // + "PreferredAuthentications publickey,password")); + verifyAuthLog(e.getMessage(), "log in"); + } + } |