From 4ba2dacf9df651a3d460e996b714b4b0511d1f62 Mon Sep 17 00:00:00 2001 From: Brian Middaugh <3270756+bmiddaugh@users.noreply.github.com> Date: Tue, 28 May 2024 12:29:25 -0700 Subject: [PATCH 1/4] Handle negated patterns according to ssh_config(5) Fixes #564 --- .../java/com/jcraft/jsch/OpenSSHConfig.java | 14 ++++++++++---- .../com/jcraft/jsch/OpenSSHConfigTest.java | 19 +++++++++++++++++++ src/test/resources/config_with_negations | 11 +++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/test/resources/config_with_negations 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..ba9a7477 100644 --- a/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java +++ b/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java @@ -88,4 +88,23 @@ 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("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 From 9b361e5ef3c187f3010bc8179f7a95262ed323bd Mon Sep 17 00:00:00 2001 From: Brian Middaugh <3270756+bmiddaugh@users.noreply.github.com> Date: Tue, 28 May 2024 14:22:28 -0700 Subject: [PATCH 2/4] Run maven formatter --- src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java b/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java index ba9a7477..d9b51619 100644 --- a/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java +++ b/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java @@ -92,7 +92,8 @@ void replaceKexAlgorithms() throws IOException { @Test void parseFileWithNegations() throws IOException, URISyntaxException { final String configFile = - Paths.get(ClassLoader.getSystemResource("config_with_negations").toURI()).toFile().getAbsolutePath(); + Paths.get(ClassLoader.getSystemResource("config_with_negations").toURI()).toFile() + .getAbsolutePath(); final OpenSSHConfig openSSHConfig = OpenSSHConfig.parseFile(configFile); assertUserEquals(openSSHConfig, "my.example.com", "u1"); @@ -105,6 +106,7 @@ private void assertUserEquals(OpenSSHConfig openSSHConfig, String host, String e final ConfigRepository.Config config = openSSHConfig.getConfig(host); assertNotNull(config); String actual = config.getUser(); - assertEquals(expected, actual, String.format("Expected user for host %s to be %s, but was %s", host, expected, actual)); + assertEquals(expected, actual, + String.format("Expected user for host %s to be %s, but was %s", host, expected, actual)); } } From 9a25dd59c422c21cfd6f313408922854f523c66b Mon Sep 17 00:00:00 2001 From: Brian Middaugh <3270756+bmiddaugh@users.noreply.github.com> Date: Tue, 28 May 2024 15:02:15 -0700 Subject: [PATCH 3/4] Don't use default locale for String.format call --- src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java b/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java index d9b51619..439d712b 100644 --- a/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java +++ b/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java @@ -107,6 +107,6 @@ private void assertUserEquals(OpenSSHConfig openSSHConfig, String host, String e assertNotNull(config); String actual = config.getUser(); assertEquals(expected, actual, - String.format("Expected user for host %s to be %s, but was %s", host, expected, actual)); + String.format(Locale.ROOT, "Expected user for host %s to be %s, but was %s", host, expected, actual)); } } From 955d64199437ef8065ce7fb6d743ff06e23acdf3 Mon Sep 17 00:00:00 2001 From: Brian Middaugh <3270756+bmiddaugh@users.noreply.github.com> Date: Wed, 29 May 2024 09:35:23 -0700 Subject: [PATCH 4/4] Run formatter --- src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java b/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java index 439d712b..f40df771 100644 --- a/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java +++ b/src/test/java/com/jcraft/jsch/OpenSSHConfigTest.java @@ -106,7 +106,7 @@ private void assertUserEquals(OpenSSHConfig openSSHConfig, String host, String e 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)); + assertEquals(expected, actual, String.format(Locale.ROOT, + "Expected user for host %s to be %s, but was %s", host, expected, actual)); } }