Class OpenSshConfigFile

java.lang.Object
org.eclipse.jgit.internal.transport.ssh.OpenSshConfigFile
All Implemented Interfaces:
SshConfigStore

public class OpenSshConfigFile extends Object implements SshConfigStore
Fairly complete configuration parser for the openssh ~/.ssh/config file.

Both JSch 0.1.54 and Apache MINA sshd 2.1.0 have parsers for this, but both are buggy. Therefore we implement our own parser to read an openssh configuration file.

Limitations compared to the full openssh 7.5 parser:

  • This parser does not handle Match or Include keywords.
  • This parser does not do host name canonicalization.

Note that openssh's readconf.c is a validating parser; this parser does not validate entries.

This config does %-substitutions for the following tokens:

  • %% - single %
  • %C - short-hand for %l%h%p%r.
  • %d - home directory path
  • %h - remote host name
  • %L - local host name without domain
  • %l - FQDN of the local host
  • %n - host name as specified in lookup(String, int, String)
  • %p - port number; if not given in lookup(String, int, String) replaced only if set in the config
  • %r - remote user name; if not given in lookup(String, int, String) replaced only if set in the config
  • %u - local user name

%i is not handled; Java has no concept of a "user ID". %T is always replaced by NONE.

See Also:
  • Field Details

    • home

      private final File home
      The user's home directory, as key files may be relative to here.
    • configFile

      private final File configFile
      The .ssh/config file we read and monitor for updates.
    • localUserName

      private final String localUserName
      User name of the user on the host OS.
    • lastModified

      private Instant lastModified
      Modification time of configFile when it was last loaded.
    • state

      private OpenSshConfigFile.State state
      State read from the config file, plus the cache.
  • Constructor Details

    • OpenSshConfigFile

      public OpenSshConfigFile(@NonNull File home, @NonNull File config, @NonNull String localUserName)
      Creates a new OpenSshConfigFile that will read the config from file config use the given file home as "home" directory.
      Parameters:
      home - user's home directory for the purpose of ~ replacement
      config - file to load.
      localUserName - user name of the current user on the local host OS
  • Method Details

    • lookup

      @NonNull public OpenSshConfigFile.HostEntry lookup(@NonNull String hostName, int port, String userName)
      Locate the configuration for a specific host request.
      Specified by:
      lookup in interface SshConfigStore
      Parameters:
      hostName - the name the user has supplied to the SSH tool. This may be a real host name, or it may just be a "Host" block in the configuration file.
      port - the user supplied; <= 0 if none
      userName - the user supplied, may be null or empty if none given
      Returns:
      the configuration for the requested name.
    • lookupDefault

      @NonNull public OpenSshConfigFile.HostEntry lookupDefault(@NonNull String hostName, int port, String userName)
      Description copied from interface: SshConfigStore
      Locate the configuration for a specific host request and if the configuration has no values for SshConstants.HOST_NAME, SshConstants.PORT, SshConstants.USER, or SshConstants.CONNECTION_ATTEMPTS, fill those values with defaults from the arguments:
      ssh config key value from argument
      HostName hostName
      Port port > 0 ? port : 22
      User userName
      ConnectionAttempts 1
      Specified by:
      lookupDefault in interface SshConfigStore
      Parameters:
      hostName - host name to look up
      port - port number; <= 0 if none
      userName - the user name, may be null or empty if none given
      Returns:
      the configuration for the requested name.
    • lookup

      private OpenSshConfigFile.HostEntry lookup(@NonNull String hostName, int port, String userName, boolean fillDefaults)
    • toCacheKey

      @NonNull private String toCacheKey(@NonNull String hostName, int port, String userName)
    • refresh

      private OpenSshConfigFile.State refresh()
    • parse

      Throws:
      IOException
    • parseList

      private static List<String> parseList(String argument)
      Splits the argument into a list of whitespace-separated elements. Elements containing whitespace must be quoted and will be de-quoted. Backslash-escapes are handled for quotes and blanks.
      Parameters:
      argument - argument part of the configuration line as read from the config file
      Returns:
      a List of elements, possibly empty and possibly containing empty elements, but not containing null
    • parseToken

      private static int parseToken(String argument, int from, int to, List<String> result)
      Parses a token up to the next whitespace not inside a string quoted by single or double quotes. Inside a string, quotes can be escaped by backslash characters. Outside of a string, "\ " can be used to include a space in a token; inside a string "\ " is taken literally as '\' followed by ' '.
      Parameters:
      argument - to parse the token out of
      from - index at the beginning of the token
      to - index one after the last character to look at
      result - a list collecting tokens to which the parsed token is added
      Returns:
      the index after the token
    • validate

      protected String validate(String key, String value)
      Hook to perform validation on a single value, or to sanitize it. If this throws an (unchecked) exception, parsing of the file is abandoned.
      Parameters:
      key - of the entry
      value - as read from the config file
      Returns:
      the validated and possibly sanitized value
    • validate

      protected List<String> validate(String key, List<String> value)
      Hook to perform validation on values, or to sanitize them. If this throws an (unchecked) exception, parsing of the file is abandoned.
      Parameters:
      key - of the entry
      value - list of arguments as read from the config file
      Returns:
      a List of values, possibly empty and possibly containing empty elements, but not containing null
    • patternMatchesHost

      private static boolean patternMatchesHost(String pattern, String name)
    • stripWhitespace

      private static String stripWhitespace(String value)
    • toFile

      private static File toFile(String path, File home)
    • positive

      public static int positive(String value)
      Converts a positive value into an int.
      Parameters:
      value - to convert
      Returns:
      the value, or -1 if it wasn't a positive integral value
    • flag

      public static boolean flag(String value)
      Converts a ssh config flag value (yes/true/on - no/false/off) into an boolean.
      Parameters:
      value - to convert
      Returns:
      true if value is "yes", "on", or "true"; false otherwise
    • timeSpec

      public static int timeSpec(String value)
      Converts an OpenSSH time value into a number of seconds. The format is defined by OpenSSH as a sequence of (positive) integers with suffixes for seconds, minutes, hours, days, and weeks.
      Parameters:
      value - to convert
      Returns:
      the parsed value as a number of seconds, or -1 if the value is not a valid OpenSSH time value
      See Also:
    • getLocalUserName

      public String getLocalUserName()
      Retrieves the local user name as given in the constructor.
      Returns:
      the user name
    • toString

      public String toString()
      Overrides:
      toString in class Object