diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2021-12-02 16:56:34 +0100 |
---|---|---|
committer | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2021-12-02 16:56:34 +0100 |
commit | 959bf31ebc57a18bd60209279278cd86e1779905 (patch) | |
tree | 1773cb6b08af01d897c83f9508732f2ca2bdef3e /security-utils | |
parent | 482a30d82ab06a8f8ddfbc1d3e1222daa0b3389f (diff) |
Support glob pattern for URIs with '/' as boundary
Diffstat (limited to 'security-utils')
-rw-r--r-- | security-utils/src/main/java/com/yahoo/security/tls/policy/RequiredPeerCredential.java | 2 | ||||
-rw-r--r-- | security-utils/src/main/java/com/yahoo/security/tls/policy/UriGlobPattern.java (renamed from security-utils/src/main/java/com/yahoo/security/tls/policy/UriPattern.java) | 24 | ||||
-rw-r--r-- | security-utils/src/test/java/com/yahoo/security/tls/authz/PeerAuthorizerTest.java | 8 | ||||
-rw-r--r-- | security-utils/src/test/java/com/yahoo/security/tls/policy/UriGlobPatternTest.java | 34 |
4 files changed, 49 insertions, 19 deletions
diff --git a/security-utils/src/main/java/com/yahoo/security/tls/policy/RequiredPeerCredential.java b/security-utils/src/main/java/com/yahoo/security/tls/policy/RequiredPeerCredential.java index 3bdc35c6a2f..4c96a2935f8 100644 --- a/security-utils/src/main/java/com/yahoo/security/tls/policy/RequiredPeerCredential.java +++ b/security-utils/src/main/java/com/yahoo/security/tls/policy/RequiredPeerCredential.java @@ -28,7 +28,7 @@ public class RequiredPeerCredential { case SAN_DNS: return new HostGlobPattern(pattern); case SAN_URI: - return new UriPattern(pattern); + return new UriGlobPattern(pattern); default: throw new IllegalArgumentException("Unknown field: " + field); } diff --git a/security-utils/src/main/java/com/yahoo/security/tls/policy/UriPattern.java b/security-utils/src/main/java/com/yahoo/security/tls/policy/UriGlobPattern.java index 7c36244d781..006ca83a403 100644 --- a/security-utils/src/main/java/com/yahoo/security/tls/policy/UriPattern.java +++ b/security-utils/src/main/java/com/yahoo/security/tls/policy/UriGlobPattern.java @@ -8,26 +8,22 @@ import java.util.Objects; * * @author bjorncs */ -class UriPattern implements RequiredPeerCredential.Pattern { +class UriGlobPattern implements RequiredPeerCredential.Pattern { - private final String pattern; + private final GlobPattern globPattern; - UriPattern(String pattern) { - this.pattern = pattern; + UriGlobPattern(String globPattern) { + this.globPattern = new GlobPattern(globPattern, new char[] {'/'}); } - @Override public String asString() { return pattern; } + @Override public String asString() { return globPattern.asString(); } - @Override - public boolean matches(String fieldValue) { - // Only exact match is supported (unlike for host names) - return fieldValue.equals(pattern); - } + @Override public boolean matches(String fieldValue) { return globPattern.matches(fieldValue); } @Override public String toString() { return "UriPattern{" + - "pattern='" + pattern + '\'' + + "pattern='" + globPattern + '\'' + '}'; } @@ -35,12 +31,12 @@ class UriPattern implements RequiredPeerCredential.Pattern { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - UriPattern that = (UriPattern) o; - return Objects.equals(pattern, that.pattern); + UriGlobPattern that = (UriGlobPattern) o; + return Objects.equals(globPattern, that.globPattern); } @Override public int hashCode() { - return Objects.hash(pattern); + return Objects.hash(globPattern); } } diff --git a/security-utils/src/test/java/com/yahoo/security/tls/authz/PeerAuthorizerTest.java b/security-utils/src/test/java/com/yahoo/security/tls/authz/PeerAuthorizerTest.java index 518ec08d38e..fdfed781286 100644 --- a/security-utils/src/test/java/com/yahoo/security/tls/authz/PeerAuthorizerTest.java +++ b/security-utils/src/test/java/com/yahoo/security/tls/authz/PeerAuthorizerTest.java @@ -102,17 +102,17 @@ public class PeerAuthorizerTest { } @Test - public void can_exact_match_policy_with_san_uri_pattern() { + public void can_match_policy_with_san_uri_pattern() { RequiredPeerCredential cnRequirement = createRequiredCredential(CN, "*.matching.cn"); - RequiredPeerCredential sanUriRequirement = createRequiredCredential(SAN_URI, "myscheme://my/exact/uri"); + RequiredPeerCredential sanUriRequirement = createRequiredCredential(SAN_URI, "myscheme://my/*/uri"); PeerAuthorizer authorizer = createPeerAuthorizer(createPolicy(POLICY_1, createRoles(ROLE_1), cnRequirement, sanUriRequirement)); - AuthorizationResult result = authorizer.authorizePeer(createCertificate("foo.matching.cn", singletonList("foo.irrelevant.san"), singletonList("myscheme://my/exact/uri"))); + AuthorizationResult result = authorizer.authorizePeer(createCertificate("foo.matching.cn", singletonList("foo.irrelevant.san"), singletonList("myscheme://my/matching/uri"))); assertAuthorized(result); assertThat(result.assumedRoles()).extracting(Role::name).containsOnly(ROLE_1); assertThat(result.matchedPolicies()).containsOnly(POLICY_1); - assertUnauthorized(authorizer.authorizePeer(createCertificate("foo.matching.cn", emptyList(), singletonList("myscheme://my/nonmatching/uri")))); + assertUnauthorized(authorizer.authorizePeer(createCertificate("foo.matching.cn", emptyList(), singletonList("myscheme://my/nonmatching/url")))); } private static X509Certificate createCertificate(String subjectCn, List<String> sanDns, List<String> sanUri) { diff --git a/security-utils/src/test/java/com/yahoo/security/tls/policy/UriGlobPatternTest.java b/security-utils/src/test/java/com/yahoo/security/tls/policy/UriGlobPatternTest.java new file mode 100644 index 00000000000..98f8119b40e --- /dev/null +++ b/security-utils/src/test/java/com/yahoo/security/tls/policy/UriGlobPatternTest.java @@ -0,0 +1,34 @@ +package com.yahoo.security.tls.policy;// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * @author bjorncs + */ +class UriGlobPatternTest { + + @Test + void matches_correctly() { + assertMatches("scheme://hostname/*", "scheme://hostname/mypath"); + assertMatches("scheme://hostname/*/segment2", "scheme://hostname/segment1/segment2"); + assertMatches("scheme://hostname/segment1/*", "scheme://hostname/segment1/segment2"); + assertNotMatches("scheme://hostname/*", "scheme://hostname/segment1/segment2"); + assertMatches("scheme://*/segment1/segment2", "scheme://hostname/segment1/segment2"); + assertMatches("scheme://*.name/", "scheme://host.name/"); + assertNotMatches("scheme://*", "scheme://hostname/"); + } + + private void assertMatches(String pattern, String value) { + assertTrue(new UriGlobPattern(pattern).matches(value), + () -> String.format("Expected '%s' to match '%s'", pattern, value)); + } + + private void assertNotMatches(String pattern, String value) { + assertFalse(new UriGlobPattern(pattern).matches(value), + () -> String.format("Expected '%s' to not match '%s'", pattern, value)); + } + +}
\ No newline at end of file |