summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.ssh.apache.agent/resources/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.properties3
-rw-r--r--org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Factory.java24
-rw-r--r--org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/PageantConnector.java17
-rw-r--r--org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.java2
-rw-r--r--org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixDomainSocketConnector.java17
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/agent/ConnectorFactoryProvider.java26
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java6
-rw-r--r--org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/ConnectorFactory.java116
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java2
9 files changed, 199 insertions, 14 deletions
diff --git a/org.eclipse.jgit.ssh.apache.agent/resources/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.properties b/org.eclipse.jgit.ssh.apache.agent/resources/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.properties
index f884adc089..6fce083668 100644
--- a/org.eclipse.jgit.ssh.apache.agent/resources/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.properties
+++ b/org.eclipse.jgit.ssh.apache.agent/resources/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.properties
@@ -13,4 +13,5 @@ msgSendFailed=Sending {0} bytes to SSH agent failed; {0} bytes not written
msgSendFailed2=Sending {0} bytes to SSH agent failed: {1} - {2}
msgSharedMemoryFailed=Could not set up shared memory for communicating with Pageant
msgShortRead=Short read from SSH agent, expected {0} bytes, got {1} bytes; last read() returned {2}
-
+pageant=Pageant
+unixDefaultAgent=ssh-agent
diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Factory.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Factory.java
index 1cbf0e41b6..d7409b0c3c 100644
--- a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Factory.java
+++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Factory.java
@@ -11,6 +11,8 @@ package org.eclipse.jgit.internal.transport.sshd.agent.connector;
import java.io.File;
import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
import org.eclipse.jgit.transport.sshd.agent.Connector;
import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory;
@@ -41,4 +43,26 @@ public class Factory implements ConnectorFactory {
public String getName() {
return NAME;
}
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * This factory returns on Windows a
+ * {@link org.eclipse.jgit.transport.sshd.agent.ConnectorFactory.ConnectorDescriptor
+ * ConnectorDescriptor} for the internal name "pageant"; on Unix one for
+ * "SSH_AUTH_SOCK".
+ * </p>
+ */
+ @Override
+ public Collection<ConnectorDescriptor> getSupportedConnectors() {
+ return Collections.singleton(getDefaultConnector());
+ }
+
+ @Override
+ public ConnectorDescriptor getDefaultConnector() {
+ if (SystemReader.getInstance().isWindows()) {
+ return PageantConnector.DESCRIPTOR;
+ }
+ return UnixDomainSocketConnector.DESCRIPTOR;
+ }
}
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 59fe2fc246..b0e3bce724 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
@@ -12,12 +12,29 @@ package org.eclipse.jgit.internal.transport.sshd.agent.connector;
import java.io.IOException;
import org.eclipse.jgit.transport.sshd.agent.AbstractConnector;
+import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory.ConnectorDescriptor;
/**
* A connector using Pageant's shared memory IPC mechanism.
*/
public class PageantConnector extends AbstractConnector {
+ /**
+ * {@link ConnectorDescriptor} for the {@link PageantConnector}.
+ */
+ public static final ConnectorDescriptor DESCRIPTOR = new ConnectorDescriptor() {
+
+ @Override
+ public String getIdentityAgent() {
+ return "pageant"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String getDisplayName() {
+ return Texts.get().pageant;
+ }
+ };
+
private final PageantLibrary lib;
/**
diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.java
index 6b66261546..fb45b30dd2 100644
--- a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.java
+++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/Texts.java
@@ -42,5 +42,7 @@ public final class Texts extends TranslationBundle {
/***/ public String msgSendFailed2;
/***/ public String msgSharedMemoryFailed;
/***/ public String msgShortRead;
+ /***/ public String pageant;
+ /***/ public String unixDefaultAgent;
}
diff --git a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixDomainSocketConnector.java b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixDomainSocketConnector.java
index 4c698d974a..3b75f3a7da 100644
--- a/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixDomainSocketConnector.java
+++ b/org.eclipse.jgit.ssh.apache.agent/src/org/eclipse/jgit/internal/transport/sshd/agent/connector/UnixDomainSocketConnector.java
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.sshd.common.SshException;
import org.eclipse.jgit.transport.sshd.agent.AbstractConnector;
+import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory.ConnectorDescriptor;
import org.eclipse.jgit.util.StringUtils;
import org.eclipse.jgit.util.SystemReader;
import org.slf4j.Logger;
@@ -38,6 +39,22 @@ import com.sun.jna.platform.unix.LibCAPI;
*/
public class UnixDomainSocketConnector extends AbstractConnector {
+ /**
+ * {@link ConnectorDescriptor} for the {@link UnixDomainSocketConnector}.
+ */
+ public static final ConnectorDescriptor DESCRIPTOR = new ConnectorDescriptor() {
+
+ @Override
+ public String getIdentityAgent() {
+ return ENV_SSH_AUTH_SOCK;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return Texts.get().unixDefaultAgent;
+ }
+ };
+
private static final Logger LOG = LoggerFactory
.getLogger(UnixDomainSocketConnector.class);
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/agent/ConnectorFactoryProvider.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/agent/ConnectorFactoryProvider.java
index 9984f99763..aba7a76459 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/agent/ConnectorFactoryProvider.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/internal/transport/sshd/agent/ConnectorFactoryProvider.java
@@ -19,7 +19,7 @@ import org.eclipse.jgit.transport.sshd.agent.ConnectorFactory;
*/
public final class ConnectorFactoryProvider {
- private static final ConnectorFactory FACTORY = loadDefaultFactory();
+ private static volatile ConnectorFactory INSTANCE = loadDefaultFactory();
private static ConnectorFactory loadDefaultFactory() {
ServiceLoader<ConnectorFactory> loader = ServiceLoader
@@ -35,17 +35,27 @@ public final class ConnectorFactoryProvider {
}
- private ConnectorFactoryProvider() {
- // No instantiation
- }
-
/**
- * Retrieves the default {@link ConnectorFactory} obtained via the
- * {@link ServiceLoader}.
+ * Retrieves the currently set default {@link ConnectorFactory}.
*
* @return the {@link ConnectorFactory}, or {@code null} if none.
*/
public static ConnectorFactory getDefaultFactory() {
- return FACTORY;
+ return INSTANCE;
+ }
+
+ /**
+ * Sets the default {@link ConnectorFactory}.
+ *
+ * @param factory
+ * {@link ConnectorFactory} to use, or {@code null} to use the
+ * factory discovered via the {@link ServiceLoader}.
+ */
+ public static void setDefaultFactory(ConnectorFactory factory) {
+ INSTANCE = factory == null ? loadDefaultFactory() : factory;
+ }
+
+ private ConnectorFactoryProvider() {
+ // No instantiation
}
}
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
index 3364180099..58cf8e1ddd 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/SshdSessionFactory.java
@@ -56,7 +56,6 @@ import org.eclipse.jgit.internal.transport.sshd.JGitUserInteraction;
import org.eclipse.jgit.internal.transport.sshd.OpenSshServerKeyDatabase;
import org.eclipse.jgit.internal.transport.sshd.PasswordProviderWrapper;
import org.eclipse.jgit.internal.transport.sshd.SshdText;
-import org.eclipse.jgit.internal.transport.sshd.agent.ConnectorFactoryProvider;
import org.eclipse.jgit.internal.transport.sshd.agent.JGitSshAgentFactory;
import org.eclipse.jgit.transport.CredentialsProvider;
import org.eclipse.jgit.transport.SshConfigStore;
@@ -456,12 +455,15 @@ public class SshdSessionFactory extends SshSessionFactory implements Closeable {
/**
* Gets a {@link ConnectorFactory}. If this returns {@code null}, SSH agents
* are not supported.
+ * <p>
+ * The default implementation uses {@link ConnectorFactory#getDefault()}
+ * </p>
*
* @return the factory, or {@code null} if no SSH agent support is desired
* @since 6.0
*/
protected ConnectorFactory getConnectorFactory() {
- return ConnectorFactoryProvider.getDefaultFactory();
+ return ConnectorFactory.getDefault();
}
/**
diff --git a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/ConnectorFactory.java b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/ConnectorFactory.java
index b351d89ef5..da98ea7fe0 100644
--- a/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/ConnectorFactory.java
+++ b/org.eclipse.jgit.ssh.apache/src/org/eclipse/jgit/transport/sshd/agent/ConnectorFactory.java
@@ -11,8 +11,10 @@ package org.eclipse.jgit.transport.sshd.agent;
import java.io.File;
import java.io.IOException;
+import java.util.Collection;
import org.eclipse.jgit.annotations.NonNull;
+import org.eclipse.jgit.internal.transport.sshd.agent.ConnectorFactoryProvider;
/**
* A factory for creating {@link Connector}s. This is a service provider
@@ -25,13 +27,44 @@ import org.eclipse.jgit.annotations.NonNull;
public interface ConnectorFactory {
/**
+ * Retrieves the currently set default {@link ConnectorFactory}. This is the
+ * factory that is used unless overridden by the
+ * {@link org.eclipse.jgit.transport.sshd.SshdSessionFactory}.
+ *
+ * @return the current default factory; may be {@code null} if none is set
+ * and the {@link java.util.ServiceLoader} cannot find any suitable
+ * implementation
+ */
+ static ConnectorFactory getDefault() {
+ return ConnectorFactoryProvider.getDefaultFactory();
+ }
+
+ /**
+ * Sets a default {@link ConnectorFactory}. This is the factory that is used
+ * unless overridden by the
+ * {@link org.eclipse.jgit.transport.sshd.SshdSessionFactory}.
+ * <p>
+ * If no default factory is set programmatically, an implementation is
+ * discovered via the {@link java.util.ServiceLoader}.
+ * </p>
+ *
+ * @param factory
+ * {@link ConnectorFactory} to set, or {@code null} to revert to
+ * the default behavior of using the
+ * {@link java.util.ServiceLoader}.
+ */
+ static void setDefault(ConnectorFactory factory) {
+ ConnectorFactoryProvider.setDefaultFactory(factory);
+ }
+
+ /**
* Creates a new {@link Connector}.
*
* @param identityAgent
* identifies the wanted agent connection; if {@code null}, the
* factory is free to provide a {@link Connector} to a default
- * agent. The value will typically come from the IdentityAgent
- * setting in ~/.ssh/config.
+ * agent. The value will typically come from the
+ * {@code IdentityAgent} setting in {@code ~/.ssh/config}.
* @param homeDir
* the current local user's home directory as configured in the
* {@link org.eclipse.jgit.transport.sshd.SshdSessionFactory}
@@ -58,4 +91,83 @@ public interface ConnectorFactory {
*/
String getName();
+ /**
+ * {@link ConnectorDescriptor}s describe available {@link Connector}s a
+ * {@link ConnectorFactory} may provide.
+ * <p>
+ * A {@link ConnectorFactory} may support connecting to different SSH
+ * agents. Agents are identified by name; a user can choose a specific agent
+ * for instance via the {@code IdentityAgent} setting in
+ * {@code ~/.ssh/config}.
+ * </p>
+ * <p>
+ * OpenSSH knows two built-in names: "none" for not using any agent, and
+ * "SSH_AUTH_SOCK" for using an agent that communicates over a Unix domain
+ * socket given by the value of environment variable {@code SSH_AUTH_SOCK}.
+ * Other agents can be specified in OpenSSH by specifying the socket file
+ * directly. (The "standard" OpenBSD OpenSSH knows only this communication
+ * mechanism.) "SSH_AUTH_SOCK" is also the default in OpenBSD OpenSSH if
+ * nothing is configured.
+ * </p>
+ * <p>
+ * A particular {@link ConnectorFactory} may support more communication
+ * mechanisms or different agents. For instance, a factory on Windows might
+ * support Pageant, Win32-OpenSSH, or even git bash ssh-agent, and might
+ * accept internal names like "pageant", "openssh", "SSH_AUTH_SOCK" in
+ * {@link ConnectorFactory#create(String, File)} to choose among them.
+ * </p>
+ * The {@link ConnectorDescriptor} interface and the
+ * {@link ConnectorFactory#getSupportedConnectors()} and
+ * {@link ConnectorFactory#getDefaultConnector()} methods provide a way for
+ * code using a {@link ConnectorFactory} to learn what the factory supports
+ * and thus implement some way by which a user can influence the default
+ * behavior if {@code IdentityAgent} is not set or
+ * {@link ConnectorFactory#create(String, File)} is called with
+ * {@code identityAgent == null}.
+ */
+ interface ConnectorDescriptor {
+
+ /**
+ * Retrieves the internal name of a supported {@link Connector}. The
+ * internal name is the one a user can specify for instance in the
+ * {@code IdentityAgent} setting in {@code ~/.ssh/config} to select the
+ * connector.
+ *
+ * @return the internal name; not empty
+ */
+ @NonNull
+ String getIdentityAgent();
+
+ /**
+ * Retrieves a display name for a {@link Connector}, suitable for
+ * showing in a UI.
+ *
+ * @return the display name; properly localized and not empty
+ */
+ @NonNull
+ String getDisplayName();
+ }
+
+ /**
+ * Tells which kinds of SSH agents this {@link ConnectorFactory} supports.
+ * <p>
+ * An implementation of this method should document the possible values it
+ * returns.
+ * </p>
+ *
+ * @return an immutable collection of {@link ConnectorDescriptor}s,
+ * including {@link #getDefaultConnector()} and not including a
+ * descriptor for internal name "none"
+ */
+ @NonNull
+ Collection<ConnectorDescriptor> getSupportedConnectors();
+
+ /**
+ * Tells what kind of {@link Connector} this {@link ConnectorFactory}
+ * creates if {@link ConnectorFactory#create(String, File)} is called with
+ * {@code identityAgent == null}.
+ *
+ * @return a {@link ConnectorDescriptor} for the default connector
+ */
+ ConnectorDescriptor getDefaultConnector();
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
index e216a56ac6..1e98a56f79 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
@@ -36,7 +36,7 @@ import org.eclipse.jgit.util.SystemReader;
*/
public abstract class SshSessionFactory {
- private static SshSessionFactory INSTANCE = loadSshSessionFactory();
+ private static volatile SshSessionFactory INSTANCE = loadSshSessionFactory();
private static SshSessionFactory loadSshSessionFactory() {
ServiceLoader<SshSessionFactory> loader = ServiceLoader.load(SshSessionFactory.class);