JGitSshConfig.java

  1. /*
  2.  * Copyright (C) 2018, 2020 Thomas Wolf <thomas.wolf@paranor.ch> and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */
  10. package org.eclipse.jgit.internal.transport.sshd;

  11. import static org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile.flag;
  12. import static org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile.positive;

  13. import java.io.IOException;
  14. import java.net.SocketAddress;
  15. import java.util.Map;
  16. import java.util.TreeMap;

  17. import org.apache.sshd.client.config.hosts.HostConfigEntry;
  18. import org.apache.sshd.client.config.hosts.HostConfigEntryResolver;
  19. import org.apache.sshd.common.AttributeRepository;
  20. import org.apache.sshd.common.util.net.SshdSocketAddress;
  21. import org.eclipse.jgit.transport.SshConfigStore;
  22. import org.eclipse.jgit.transport.SshConstants;
  23. import org.eclipse.jgit.transport.SshSessionFactory;

  24. /**
  25.  * A bridge between a JGit {@link SshConfigStore} and the Apache MINA sshd
  26.  * {@link HostConfigEntryResolver}.
  27.  */
  28. public class JGitSshConfig implements HostConfigEntryResolver {

  29.     private final SshConfigStore configFile;

  30.     /**
  31.      * Creates a new {@link JGitSshConfig} that will read the config from the
  32.      * given {@link SshConfigStore}.
  33.      *
  34.      * @param store
  35.      *            to use
  36.      */
  37.     public JGitSshConfig(SshConfigStore store) {
  38.         configFile = store;
  39.     }

  40.     @Override
  41.     public HostConfigEntry resolveEffectiveHost(String host, int port,
  42.             SocketAddress localAddress, String username, String proxyJump,
  43.             AttributeRepository attributes) throws IOException {
  44.         SshConfigStore.HostConfig entry = configFile == null
  45.                 ? SshConfigStore.EMPTY_CONFIG
  46.                 : configFile.lookup(host, port, username);
  47.         JGitHostConfigEntry config = new JGitHostConfigEntry();
  48.         // Apache MINA conflates all keys, even multi-valued ones, in one map
  49.         // and puts multiple values separated by commas in one string. See
  50.         // the javadoc on HostConfigEntry.
  51.         Map<String, String> allOptions = new TreeMap<>(
  52.                 String.CASE_INSENSITIVE_ORDER);
  53.         allOptions.putAll(entry.getOptions());
  54.         // And what if a value contains a comma??
  55.         entry.getMultiValuedOptions().entrySet().stream()
  56.                 .forEach(e -> allOptions.put(e.getKey(),
  57.                         String.join(",", e.getValue()))); //$NON-NLS-1$
  58.         config.setProperties(allOptions);
  59.         // The following is an extension from JGitHostConfigEntry
  60.         config.setMultiValuedOptions(entry.getMultiValuedOptions());
  61.         // Also make sure the underlying properties are set
  62.         String hostName = entry.getValue(SshConstants.HOST_NAME);
  63.         if (hostName == null || hostName.isEmpty()) {
  64.             hostName = host;
  65.         }
  66.         config.setHostName(hostName);
  67.         config.setProperty(SshConstants.HOST_NAME, hostName);
  68.         config.setHost(SshdSocketAddress.isIPv6Address(hostName) ? "" : hostName); //$NON-NLS-1$
  69.         String user = username != null && !username.isEmpty() ? username
  70.                 : entry.getValue(SshConstants.USER);
  71.         if (user == null || user.isEmpty()) {
  72.             user = SshSessionFactory.getLocalUserName();
  73.         }
  74.         config.setUsername(user);
  75.         config.setProperty(SshConstants.USER, user);
  76.         int p = port >= 0 ? port : positive(entry.getValue(SshConstants.PORT));
  77.         config.setPort(p >= 0 ? p : SshConstants.SSH_DEFAULT_PORT);
  78.         config.setProperty(SshConstants.PORT,
  79.                 Integer.toString(config.getPort()));
  80.         config.setIdentities(entry.getValues(SshConstants.IDENTITY_FILE));
  81.         config.setIdentitiesOnly(
  82.                 flag(entry.getValue(SshConstants.IDENTITIES_ONLY)));
  83.         return config;
  84.     }

  85. }