diff --git a/src/main/java/com/jcraft/jsch/OpenSSHConfig.java b/src/main/java/com/jcraft/jsch/OpenSSHConfig.java index aab20e09..76328a2e 100644 --- a/src/main/java/com/jcraft/jsch/OpenSSHConfig.java +++ b/src/main/java/com/jcraft/jsch/OpenSSHConfig.java @@ -188,6 +188,8 @@ class MyConfig implements Config { byte[] _host = Util.str2byte(host); if (hosts.size() > 1) { for (int i = 1; i < hosts.size(); i++) { + boolean anyPositivePatternMatches = false; + boolean anyNegativePatternMatches = false; String patterns[] = hosts.elementAt(i).split("[ \t]"); for (int j = 0; j < patterns.length; j++) { boolean negate = false; @@ -197,13 +199,17 @@ class MyConfig implements Config { foo = foo.substring(1).trim(); } if (Util.glob(Util.str2byte(foo), _host)) { - if (!negate) { - _configs.addElement(config.get(hosts.elementAt(i))); + if (negate) { + anyNegativePatternMatches = true; + } else { + anyPositivePatternMatches = true; } - } else if (negate) { - _configs.addElement(config.get(hosts.elementAt(i))); } } + + if (anyPositivePatternMatches && !anyNegativePatternMatches) { + _configs.addElement(config.get(hosts.elementAt(i))); + } } } } diff --git a/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java b/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java index 99567500..f40df771 100644 --- a/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java +++ b/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java @@ -88,4 +88,25 @@ void replaceKexAlgorithms() throws IOException { ConfigRepository.Config kex = parse.getConfig(""); assertEquals("diffie-hellman-group1-sha1", kex.getValue("kex")); } + + @Test + void parseFileWithNegations() throws IOException, URISyntaxException { + final String configFile = + Paths.get(ClassLoader.getSystemResource("config_with_negations").toURI()).toFile() + .getAbsolutePath(); + final OpenSSHConfig openSSHConfig = OpenSSHConfig.parseFile(configFile); + + assertUserEquals(openSSHConfig, "my.example.com", "u1"); + assertUserEquals(openSSHConfig, "my-jump.example.com", "jump-u1"); + assertUserEquals(openSSHConfig, "my-proxy.example.com", "proxy-u1"); + assertUserEquals(openSSHConfig, "my.example.org", "u2"); + } + + private void assertUserEquals(OpenSSHConfig openSSHConfig, String host, String expected) { + final ConfigRepository.Config config = openSSHConfig.getConfig(host); + assertNotNull(config); + String actual = config.getUser(); + assertEquals(expected, actual, String.format(Locale.ROOT, + "Expected user for host %s to be %s, but was %s", host, expected, actual)); + } } diff --git a/src/test/resources/config_with_negations b/src/test/resources/config_with_negations new file mode 100644 index 00000000..ff8ed382 --- /dev/null +++ b/src/test/resources/config_with_negations @@ -0,0 +1,11 @@ +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