diff options
author | Konrad Windszus <konrad_w@gmx.de> | 2024-02-20 14:30:39 +0100 |
---|---|---|
committer | Konrad Windszus <konrad_w@gmx.de> | 2024-02-22 13:35:49 +0100 |
commit | a44b9e8bf7bd7ebcf603d54937ec6078ffa509e9 (patch) | |
tree | 56294698a4e837ade7eba59cacd6a79d159b3665 /org.eclipse.jgit.ssh.apache/src/org/eclipse | |
parent | 426d67848a0e739d69f43098f46ee00b34fa7d77 (diff) | |
download | jgit-a44b9e8bf7bd7ebcf603d54937ec6078ffa509e9.tar.gz jgit-a44b9e8bf7bd7ebcf603d54937ec6078ffa509e9.zip |
Support public key in IdentityFile
Public keys in the SSH configuration's "IdentityFile" are used for
example by Password Managers like KeePassXC
(https://keepassxc.org/docs/#faq-ssh-agent-auth-errors) or 1Password
(https://developer.1password.com/docs/ssh/agent/advanced/#match-key-with-host)
to match keys in the SSH agent with specific hosts.
Bug: jgit-25
Change-Id: I33d47057d9dd54d3d08ba5bb17f730435ac93dac
Diffstat (limited to 'org.eclipse.jgit.ssh.apache/src/org/eclipse')
-rw-r--r-- | org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java index eb55ec045b..b0b1028daa 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/JGitPublicKeyAuthentication.java @@ -48,9 +48,7 @@ import org.apache.sshd.client.config.hosts.HostConfigEntry; import org.apache.sshd.client.session.ClientSession; import org.apache.sshd.common.FactoryManager; import org.apache.sshd.common.NamedFactory; -import org.apache.sshd.common.config.keys.AuthorizedKeyEntry; import org.apache.sshd.common.config.keys.KeyUtils; -import org.apache.sshd.common.config.keys.PublicKeyEntryResolver; import org.apache.sshd.common.config.keys.u2f.SecurityKeyPublicKey; import org.apache.sshd.common.signature.Signature; import org.apache.sshd.common.signature.SignatureFactoriesManager; @@ -314,6 +312,8 @@ public class JGitPublicKeyAuthentication extends UserAuthPublicKey { private class KeyIterator extends UserAuthPublicKeyIterator { + private static final String PUB_KEY_SUFFIX = ".pub"; //$NON-NLS-1$ + public KeyIterator(ClientSession session, SignatureFactoriesManager manager) throws Exception { @@ -326,22 +326,53 @@ public class JGitPublicKeyAuthentication extends UserAuthPublicKey { return null; } return explicitFiles.stream().map(s -> { - try { - Path p = Paths.get(s + ".pub"); //$NON-NLS-1$ - if (Files.isRegularFile(p, LinkOption.NOFOLLOW_LINKS)) { - return AuthorizedKeyEntry.readAuthorizedKeys(p).get(0) - .resolvePublicKey(null, - PublicKeyEntryResolver.IGNORING); - } - } catch (InvalidPathException | IOException - | GeneralSecurityException e) { - log.warn("{}", //$NON-NLS-1$ - format(SshdText.get().cannotReadPublicKey, s), e); + // assume the explicit key is a public key + PublicKey publicKey = readPublicKey(s, false); + if (publicKey == null && !s.endsWith(PUB_KEY_SUFFIX)) { + // if this is not the case, try to lookup public key with + // same filename and extension .pub + publicKey = readPublicKey(s + PUB_KEY_SUFFIX, true); } - return null; + return publicKey; }).filter(Objects::nonNull).collect(Collectors.toList()); } + /** + * + * @param keyFile + * the path to a public key + * @param isDerived + * {@code false} in case the given {@code keyFile} is set in + * the SSH config as is, otherwise {@code false} + * @return the public key read from the key file + */ + private PublicKey readPublicKey(String keyFile, boolean isDerived) { + try { + Path p = Paths.get(keyFile); + if (Files.isRegularFile(p, LinkOption.NOFOLLOW_LINKS)) { + return KeyUtils.loadPublicKey(p); + } + // only warn about non-existing files in case the key file is + // not derived + if (!isDerived) { + log.warn("{}", //$NON-NLS-1$ + format(SshdText.get().cannotReadPublicKey, keyFile)); + } + } catch (InvalidPathException | IOException e) { + log.warn("{}", //$NON-NLS-1$ + format(SshdText.get().cannotReadPublicKey, keyFile), e); + } catch (GeneralSecurityException e) { + // ignore in case this is not a derived key path, as in most + // cases this specifies a private key + if (isDerived) { + log.warn("{}", //$NON-NLS-1$ + format(SshdText.get().cannotReadPublicKey, keyFile), + e); + } + } + return null; + } + @Override protected Iterable<KeyAgentIdentity> initializeAgentIdentities( ClientSession session) throws IOException { |