Class OpenSshConfigFile

  • All Implemented Interfaces:
    SshConfigStore

    public class OpenSshConfigFile
    extends java.lang.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:
    man ssh-config
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private java.io.File configFile
      The .ssh/config file we read and monitor for updates.
      private static java.lang.String DEFAULT_NAME
      "Host" name of the HostEntry for the default options before the first host block in a config file.
      private java.io.File home
      The user's home directory, as key files may be relative to here.
      private java.time.Instant lastModified
      Modification time of configFile when it was last loaded.
      private java.lang.String localUserName
      User name of the user on the host OS.
      private OpenSshConfigFile.State state
      State read from the config file, plus the cache.
    • Constructor Summary

      Constructors 
      Constructor Description
      OpenSshConfigFile​(java.io.File home, java.io.File config, java.lang.String localUserName)
      Creates a new OpenSshConfigFile that will read the config from file config use the given file home as "home" directory.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      private static java.lang.String dequote​(java.lang.String value)  
      static boolean flag​(java.lang.String value)
      Converts a ssh config flag value (yes/true/on - no/false/off) into an boolean.
      java.lang.String getLocalUserName()
      Retrieves the local user name as given in the constructor.
      private static boolean isHostMatch​(java.lang.String pattern, java.lang.String name)  
      OpenSshConfigFile.HostEntry lookup​(java.lang.String hostName, int port, java.lang.String userName)
      Locate the configuration for a specific host request.
      private java.util.Map<java.lang.String,​OpenSshConfigFile.HostEntry> parse​(java.io.BufferedReader reader)  
      private java.util.List<java.lang.String> parseList​(java.lang.String argument)
      Splits the argument into a list of whitespace-separated elements.
      private static boolean patternMatchesHost​(java.lang.String pattern, java.lang.String name)  
      static int positive​(java.lang.String value)
      Converts a positive value into an int.
      private OpenSshConfigFile.State refresh()  
      private static java.lang.String stripWhitespace​(java.lang.String value)  
      private java.lang.String toCacheKey​(java.lang.String hostName, int port, java.lang.String userName)  
      private static java.io.File toFile​(java.lang.String path, java.io.File home)  
      java.lang.String toString()
      protected java.lang.String validate​(java.lang.String key, java.lang.String value)
      Hook to perform validation on a single value, or to sanitize it.
      protected java.util.List<java.lang.String> validate​(java.lang.String key, java.util.List<java.lang.String> value)
      Hook to perform validation on values, or to sanitize them.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Field Detail

      • DEFAULT_NAME

        private static final java.lang.String DEFAULT_NAME
        "Host" name of the HostEntry for the default options before the first host block in a config file.
        See Also:
        Constant Field Values
      • home

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

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

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

        private java.time.Instant lastModified
        Modification time of configFile when it was last loaded.
    • Constructor Detail

      • OpenSshConfigFile

        public OpenSshConfigFile​(@NonNull
                                 java.io.File home,
                                 @NonNull
                                 java.io.File config,
                                 @NonNull
                                 java.lang.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 Detail

      • lookup

        @NonNull
        public OpenSshConfigFile.HostEntry lookup​(@NonNull
                                                  java.lang.String hostName,
                                                  int port,
                                                  java.lang.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.
      • toCacheKey

        @NonNull
        private java.lang.String toCacheKey​(@NonNull
                                            java.lang.String hostName,
                                            int port,
                                            java.lang.String userName)
      • parse

        private java.util.Map<java.lang.String,​OpenSshConfigFile.HostEntry> parse​(java.io.BufferedReader reader)
                                                                                 throws java.io.IOException
        Throws:
        java.io.IOException
      • parseList

        private java.util.List<java.lang.String> parseList​(java.lang.String argument)
        Splits the argument into a list of whitespace-separated elements. Elements containing whitespace must be quoted and will be de-quoted.
        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
      • validate

        protected java.lang.String validate​(java.lang.String key,
                                            java.lang.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 java.util.List<java.lang.String> validate​(java.lang.String key,
                                                            java.util.List<java.lang.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
      • isHostMatch

        private static boolean isHostMatch​(java.lang.String pattern,
                                           java.lang.String name)
      • patternMatchesHost

        private static boolean patternMatchesHost​(java.lang.String pattern,
                                                  java.lang.String name)
      • dequote

        private static java.lang.String dequote​(java.lang.String value)
      • stripWhitespace

        private static java.lang.String stripWhitespace​(java.lang.String value)
      • toFile

        private static java.io.File toFile​(java.lang.String path,
                                           java.io.File home)
      • positive

        public static int positive​(java.lang.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​(java.lang.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
      • getLocalUserName

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

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object