From 4efc6a396af3f5a112dc87e708d339b51f376c1d Mon Sep 17 00:00:00 2001 From: Thomas Wolf Date: Sun, 26 Dec 2021 14:36:48 +0100 Subject: [PATCH] sshd: support IdentityAgent config Handle the 'none' value, and change the value to select Pageant to something that looks like an absolute UNC path name to avoid it's handled as an relative path name. Bug: 577053 Change-Id: I4ccf047abbc1def50e2782319e4fa7c744069401 Signed-off-by: Thomas Wolf --- .../agent/connector/PageantConnector.java | 5 ++++- .../sshd/agent/JGitSshAgentFactory.java | 22 +++++++++++++------ .../transport/ssh/OpenSshConfigFileTest.java | 8 +++++++ .../transport/ssh/OpenSshConfigFile.java | 2 +- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/PageantConnector.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/PageantConnector.java index b0e3bce72..19684ecb9 100644 --- a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/PageantConnector.java +++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/PageantConnector.java @@ -26,7 +26,10 @@ public class PageantConnector extends AbstractConnector { @Override public String getIdentityAgent() { - return "pageant"; //$NON-NLS-1$ + // This must be an absolute Windows path name to avoid that + // OpenSshConfigFile treats it as a relative path name. Use an UNC + // name on localhost, like for pipes. + return "\\\\.\\pageant"; //$NON-NLS-1$ } @Override diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/agent/JGitSshAgentFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/agent/JGitSshAgentFactory.java index ac40dd492..a0ffd540f 100644 --- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/agent/JGitSshAgentFactory.java +++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/agent/JGitSshAgentFactory.java @@ -17,11 +17,14 @@ import org.apache.sshd.agent.SshAgent; import org.apache.sshd.agent.SshAgentFactory; import org.apache.sshd.agent.SshAgentServer; +import org.apache.sshd.client.config.hosts.HostConfigEntry; import org.apache.sshd.common.FactoryManager; import org.apache.sshd.common.channel.ChannelFactory; import org.apache.sshd.common.session.ConnectionService; import org.apache.sshd.common.session.Session; import org.eclipse.jgit.annotations.NonNull; +import org.eclipse.jgit.internal.transport.sshd.JGitClientSession; +import org.eclipse.jgit.transport.SshConstants; import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory; /** @@ -50,19 +53,24 @@ public JGitSshAgentFactory(@NonNull ConnectorFactory factory, @Override public List getChannelForwardingFactories( FactoryManager manager) { - // No agent forwarding supported yet. + // No agent forwarding supported. return Collections.emptyList(); } @Override public SshAgent createClient(Session session, FactoryManager manager) throws IOException { - // sshd 2.8.0 will pass us the session here. At that point, we can get - // the HostConfigEntry and extract and handle the IdentityAgent setting. - // For now, pass null to let the ConnectorFactory do its default - // behavior (Pageant on Windows, SSH_AUTH_SOCK on Unixes with the - // jgit-builtin factory). - return new SshAgentClient(factory.create(null, homeDir)); + String identityAgent = null; + if (session instanceof JGitClientSession) { + HostConfigEntry hostConfig = ((JGitClientSession) session) + .getHostConfigEntry(); + identityAgent = hostConfig.getProperty(SshConstants.IDENTITY_AGENT, + null); + } + if (SshConstants.NONE.equals(identityAgent)) { + return null; + } + return new SshAgentClient(factory.create(identityAgent, homeDir)); } @Override diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFileTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFileTest.java index 11741b41a..9c5cd16f9 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFileTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFileTest.java @@ -562,6 +562,14 @@ public void testEnVarSubstitution() throws Exception { h.getValue(SshConstants.IDENTITY_AGENT)); } + @Test + public void testIdentityAgentNone() throws Exception { + config("Host orcz\nIdentityAgent none\n"); + HostConfig h = lookup("orcz"); + assertEquals(SshConstants.NONE, + h.getValue(SshConstants.IDENTITY_AGENT)); + } + @Test public void testNegativeMatch() throws Exception { config("Host foo.bar !foobar.baz *.baz\n" + "Port 29418\n"); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java index 648d4a182..4e8048baa 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/transport/ssh/OpenSshConfigFile.java @@ -871,7 +871,7 @@ void substitute(String originalHostName, int port, String userName, if (options != null) { // HOSTNAME already done above String value = options.get(SshConstants.IDENTITY_AGENT); - if (value != null) { + if (value != null && !SshConstants.NONE.equals(value)) { value = r.substitute(value, Replacer.DEFAULT_TOKENS, true); value = toFile(value, home).getPath(); options.put(SshConstants.IDENTITY_AGENT, value);