mwiede / jsch

fork of the popular jsch library
Other
662 stars 124 forks source link

OpenSSHConfig.parse does not handle negated patterns as specified in ssh_config(5) #564

Closed bmiddaugh closed 3 weeks ago

bmiddaugh commented 1 month ago

Expected: Negated patterns in an openssh config file should not produce a positive result by themselves Actual: Negated patterns in an openssh config file can produce a positive result by themselves

The man page for ssh_config specifies under the PATTERNS section that negated matches should not produce a positive result by themselves:

     A pattern-list is a comma-separated list of patterns.  Patterns within pattern-lists may be negated by preceding them with an exclamation mark (‘!’).  For example, to allow a key to be used from anywhere
     within an organization except from the "dialup" pool, the following entry (in authorized_keys) could be used:

           from="!*.dialup.example.com,*.example.com"

     Note that a negated match will never produce a positive result by itself.  For example, attempting to match "host3" against the following pattern-list will fail:

           from="!host1,!host2"

     The solution here is to include a term that will yield a positive match, such as a wildcard:

           from="!host1,!host2,*"

More specifically, the real behavior of the openssh client is to produce a positive result only when:

  1. At least one positive pattern matches, and
  2. No negative patterns match

I verified this with ssh -G on MacOS 14.4.1 and the following ssh config file:

Host *.example.com !*-jump.example.com !*-proxy.example.com
    User u1

Host *-jump.example.com
    User jump-u1

Host *-proxy.example.com
    User proxy-u1

Host *.example.org
    User u2

The results were as follows:

$ ssh -G -F ./src/test/resources/config_with_negations my.example.com | grep 'user '
user u1
$ ssh -G -F ./src/test/resources/config_with_negations my-jump.example.com | grep 'user '
user jump-u1
$ ssh -G -F ./src/test/resources/config_with_negations my-proxy.example.com | grep 'user '
user proxy-u1
$ ssh -G -F ./src/test/resources/config_with_negations my.example.org | grep 'user '
user u2

The config returned by OpenSSH.parse will instead result in "u1" for any given host name: one of the two negated patterns will always end up producing a positive match on its own. This behavior can make it tricky to have jsch and other ssh clients share a config file.