This is an automated email from the ASF dual-hosted git repository. twolf pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
The following commit(s) were added to refs/heads/master by this push: new b54d4d1 [SSHD-1218] Provide the IdentityAgent setting to the SshAgentFactory b54d4d1 is described below commit b54d4d15899426ef607a44b3e3e4ebc56183aa93 Author: Thomas Wolf <tw...@apache.org> AuthorDate: Thu Oct 28 23:49:57 2021 +0200 [SSHD-1218] Provide the IdentityAgent setting to the SshAgentFactory Set an attribute on the ClientSession. Since commit 14b4ec07, the factory gets passed the session when creating an SshAgent and can thus obtain this value from the session. It needs to know this value to be able to connect to the correct SSH agent. Also change the handling of SSH agents when IdentitiesOnly is set. Do not hard-code skipping an agent completely if the value is true. The value is also available via the ClientSession; hence just let the factory decide what it should do in that case. This is more flexible for users of the library. --- .../sshd/client/config/hosts/HostConfigEntry.java | 18 ++++++++++++++++++ .../main/java/org/apache/sshd/client/SshClient.java | 17 +++++++++-------- .../sshd/client/auth/pubkey/UserAuthPublicKey.java | 11 +++++++++-- .../client/auth/pubkey/UserAuthPublicKeyIterator.java | 8 +++----- 4 files changed, 39 insertions(+), 15 deletions(-) diff --git a/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java b/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java index 88f8d93..31a62c2 100644 --- a/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java +++ b/sshd-common/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java @@ -87,6 +87,24 @@ public class HostConfigEntry extends HostPatternsHolder implements MutableUserHo public static final boolean DEFAULT_EXCLUSIVE_IDENTITIES = false; /** + * The IdentityAgent configuration. If not set in the {@link HostConfigEntry}, the value of this + * {@link #getProperty(String) property} is {@code null}, which means that a default SSH agent is to be used, if it + * is running. Other values defined by OpenSSH are: + * <ul> + * <dl> + * <dt>none</dt> + * <dd>No SHH agent is to be used at all, even if one is running.</dd> + * <dt>SSH_AUTH_SOCK</dt> + * <dd>The SSH agent listening on the Unix domain socket given by the environment variable {@code SSH_AUTH_SOCK} + * shall be used. If the environment variable is not set, no SSH agent is used.</dd> + * <dt><em>other</em></dt> + * <dd>For OpenSSH, the value shall resolve to the file name of a Unix domain socket to use to connect to an SSH + * agent.</dd> + * </dl> + */ + public static final String IDENTITY_AGENT = "IdentityAgent"; + + /** * A case <U>insensitive</U> {@link NavigableSet} of the properties that receive special handling */ public static final NavigableSet<String> EXPLICIT_PROPERTIES = Collections.unmodifiableNavigableSet( diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java index 3329658..047c9e2 100644 --- a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java +++ b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java @@ -581,7 +581,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa .createLocalPortForwardingTracker(SshdSocketAddress.LOCALHOST_ADDRESS, address); SshdSocketAddress bound = tracker.getBoundAddress(); ConnectFuture f4 = doConnect(hostConfig.getUsername(), bound.toInetSocketAddress(), - context, localAddress, keys, !hostConfig.isIdentitiesOnly()); + context, localAddress, keys, hostConfig); f4.addListener(f5 -> { if (f5.isConnected()) { ClientSession clientSession = f5.getClientSession(); @@ -614,14 +614,14 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa return connectFuture; } else { return doConnect(hostConfig.getUsername(), new InetSocketAddress(host, port), - context, localAddress, keys, !hostConfig.isIdentitiesOnly()); + context, localAddress, keys, hostConfig); } } protected ConnectFuture doConnect( String username, SocketAddress targetAddress, AttributeRepository context, SocketAddress localAddress, - KeyIdentityProvider identities, boolean useDefaultIdentities) + KeyIdentityProvider identities, HostConfigEntry hostConfig) throws IOException { if (connector == null) { throw new IllegalStateException( @@ -630,7 +630,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa ConnectFuture connectFuture = new DefaultConnectFuture(username + "@" + targetAddress, null); SshFutureListener<IoConnectFuture> listener = createConnectCompletionListener( - connectFuture, username, targetAddress, identities, useDefaultIdentities); + connectFuture, username, targetAddress, identities, hostConfig); IoConnectFuture connectingFuture = connector.connect(targetAddress, context, localAddress); connectingFuture.addListener(listener); return connectFuture; @@ -692,7 +692,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa protected SshFutureListener<IoConnectFuture> createConnectCompletionListener( ConnectFuture connectFuture, String username, SocketAddress address, - KeyIdentityProvider identities, boolean useDefaultIdentities) { + KeyIdentityProvider identities, HostConfigEntry hostConfig) { return new SshFutureListener<IoConnectFuture>() { @Override @SuppressWarnings("synthetic-access") @@ -712,8 +712,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa } else { IoSession ioSession = future.getSession(); try { - onConnectOperationComplete(ioSession, connectFuture, username, address, identities, - useDefaultIdentities); + onConnectOperationComplete(ioSession, connectFuture, username, address, identities, hostConfig); } catch (IOException | GeneralSecurityException | RuntimeException e) { warn("operationComplete({}@{}) failed ({}) to signal completion of session={}: {}", username, address, e.getClass().getSimpleName(), ioSession, e.getMessage(), e); @@ -733,12 +732,14 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa protected void onConnectOperationComplete( IoSession ioSession, ConnectFuture connectFuture, String username, - SocketAddress address, KeyIdentityProvider identities, boolean useDefaultIdentities) + SocketAddress address, KeyIdentityProvider identities, HostConfigEntry hostConfig) throws IOException, GeneralSecurityException { AbstractClientSession session = (AbstractClientSession) AbstractSession.getSession(ioSession); session.setUsername(username); session.setConnectAddress(address); + boolean useDefaultIdentities = !hostConfig.isIdentitiesOnly(); session.setAttribute(UserAuthPublicKey.USE_DEFAULT_IDENTITIES, Boolean.valueOf(useDefaultIdentities)); + session.setAttribute(UserAuthPublicKey.IDENTITY_AGENT, hostConfig.getProperty(HostConfigEntry.IDENTITY_AGENT)); if (useDefaultIdentities) { setupDefaultSessionIdentities(session, identities); diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKey.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKey.java index 6ec8da5..6d6971d 100644 --- a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKey.java +++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKey.java @@ -59,11 +59,18 @@ public class UserAuthPublicKey extends AbstractUserAuth implements SignatureFact public static final String NAME = UserAuthPublicKeyFactory.NAME; /** - * Is set on a {@link ClientSession} when it is created; if {@link Boolean#FALSE}, no agent or default identities - * shall be used. + * Is set on a {@link ClientSession} when it is created; if {@link Boolean#FALSE}, no default identities shall be + * used. */ public static final AttributeKey<Boolean> USE_DEFAULT_IDENTITIES = new AttributeKey<>(); + /** + * Is set on a {@link ClientSession} when it is created; contains the value of the {@code IdentityAgent} SSH config + * setting. May be {@code null} if not specified in the + * {@link org.apache.sshd.client.config.hosts.HostConfigEntry#IDENTITY_AGENT HostConfigEntry}. + */ + public static final AttributeKey<String> IDENTITY_AGENT = new AttributeKey<>(); + protected final Deque<String> currentAlgorithms = new LinkedList<>(); protected Iterator<PublicKeyIdentity> keys; diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java index 7240f55..970aa7d 100644 --- a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java +++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java @@ -56,11 +56,9 @@ public class UserAuthPublicKeyIterator extends AbstractKeyPairIterator<PublicKey try { Collection<Iterable<? extends PublicKeyIdentity>> identities = new ArrayList<>(2); - if (Boolean.TRUE.equals(session.getAttribute(UserAuthPublicKey.USE_DEFAULT_IDENTITIES))) { - Iterable<? extends PublicKeyIdentity> agentIds = initializeAgentIdentities(session); - if (agentIds != null) { - identities.add(agentIds); - } + Iterable<? extends PublicKeyIdentity> agentIds = initializeAgentIdentities(session); + if (agentIds != null) { + identities.add(agentIds); } Iterable<? extends PublicKeyIdentity> sessionIds = initializeSessionIdentities(session, signatureFactories);