summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.ssh.apache/src/org/eclipse
diff options
context:
space:
mode:
authorKonrad Windszus <konrad_w@gmx.de>2024-02-20 14:30:39 +0100
committerKonrad Windszus <konrad_w@gmx.de>2024-02-22 13:35:49 +0100
commita44b9e8bf7bd7ebcf603d54937ec6078ffa509e9 (patch)
tree56294698a4e837ade7eba59cacd6a79d159b3665 /org.eclipse.jgit.ssh.apache/src/org/eclipse
parent426d67848a0e739d69f43098f46ee00b34fa7d77 (diff)
downloadjgit-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.java59
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 {