From 2771061cd6f45025ae0cbf740830c81ddd428236 Mon Sep 17 00:00:00 2001 From: Jonathan Cobb Date: Wed, 22 Jul 2020 08:17:48 -0400 Subject: [PATCH] rename fqdn to host, use separate referer_host and referer_url --- .../java/bubble/abp/BubbleBlockCondition.java | 22 +++++++++++++---- .../bubble/abp/BubbleBlockConditionField.java | 2 +- .../abp/BubbleBlockConditionOperation.java | 9 +++++-- .../java/bubble/abp/spec/BlockListTest.java | 24 ++++++++++++------- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/main/java/bubble/abp/BubbleBlockCondition.java b/src/main/java/bubble/abp/BubbleBlockCondition.java index a3c9811..662da90 100644 --- a/src/main/java/bubble/abp/BubbleBlockCondition.java +++ b/src/main/java/bubble/abp/BubbleBlockCondition.java @@ -7,6 +7,8 @@ import lombok.experimental.Accessors; import lombok.extern.slf4j.Slf4j; import static org.cobbzilla.util.daemon.ZillaRuntime.shortError; +import static org.cobbzilla.util.http.HttpSchemes.SCHEME_HTTP; +import static org.cobbzilla.util.http.HttpSchemes.SCHEME_HTTPS; @NoArgsConstructor @Accessors(chain=true) @Slf4j public class BubbleBlockCondition { @@ -44,13 +46,25 @@ public class BubbleBlockCondition { public boolean matches(String fqdn, String path, String contentType, String referer) { switch (field) { - case fqdn: return operation.matches(fqdn, value); - case path: return operation.matches(path, value); - case url: return operation.matches(fqdn + path, value); + case host: return operation.matches(fqdn, value); + case path: return operation.matches(path, value); + case url: return operation.matches(fqdn + path, value); case content_type: return operation.matches(contentType, value); - case referer: return operation.matches(referer, value); + case referer_host: return operation.matches(toFqdn(referer), value); + case referer_url: return operation.matches(referer, value); default: log.warn("matches: invalid field: "+field); } return false; } + + private String toFqdn(String referer) { + if (referer.startsWith(SCHEME_HTTPS)) { + referer = referer.substring(SCHEME_HTTPS.length()); + } else if (referer.startsWith(SCHEME_HTTP)) { + referer = referer.substring(SCHEME_HTTP.length()); + } + final int slashPos = referer.indexOf("/"); + return slashPos == -1 ? referer : referer.substring(0, slashPos); + } + } diff --git a/src/main/java/bubble/abp/BubbleBlockConditionField.java b/src/main/java/bubble/abp/BubbleBlockConditionField.java index 41f9cf5..8b24a36 100644 --- a/src/main/java/bubble/abp/BubbleBlockConditionField.java +++ b/src/main/java/bubble/abp/BubbleBlockConditionField.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonCreator; public enum BubbleBlockConditionField { - fqdn, path, url, referer, content_type; + host, path, url, referer_host, referer_url, content_type; @JsonCreator public static BubbleBlockConditionField fromString (String v) { return valueOf(v.toLowerCase()); } diff --git a/src/main/java/bubble/abp/BubbleBlockConditionOperation.java b/src/main/java/bubble/abp/BubbleBlockConditionOperation.java index c470986..bc34c1e 100644 --- a/src/main/java/bubble/abp/BubbleBlockConditionOperation.java +++ b/src/main/java/bubble/abp/BubbleBlockConditionOperation.java @@ -2,6 +2,7 @@ package bubble.abp; import com.fasterxml.jackson.annotation.JsonCreator; import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.cobbzilla.util.collection.ExpirationEvictionPolicy; import org.cobbzilla.util.collection.ExpirationMap; @@ -9,7 +10,7 @@ import java.util.regex.Pattern; import static java.util.regex.Pattern.CASE_INSENSITIVE; -@AllArgsConstructor +@AllArgsConstructor @Slf4j public enum BubbleBlockConditionOperation { eq (String::equalsIgnoreCase), @@ -29,6 +30,10 @@ public enum BubbleBlockConditionOperation { @JsonCreator public static BubbleBlockConditionOperation fromString (String v) { return valueOf(v.toLowerCase()); } - public boolean matches(String input, String value) { return comparison.matches(input, value); } + public boolean matches(String input, String value) { + final boolean matches = comparison.matches(input, value); + if (log.isDebugEnabled()) log.debug("matches: "+input+" "+this+" "+value+" -> "+matches); + return matches; + } } diff --git a/src/test/java/bubble/abp/spec/BlockListTest.java b/src/test/java/bubble/abp/spec/BlockListTest.java index c676df7..6c65b1e 100644 --- a/src/test/java/bubble/abp/spec/BlockListTest.java +++ b/src/test/java/bubble/abp/spec/BlockListTest.java @@ -160,22 +160,28 @@ public class BlockListTest { } public static final String[][] CONDITIONAL_SPECS = { - {"~foo.bar.com~[\"referer ne bar.com\"]", "foo.com", "foo.com", ALLOW}, - {"~foo.bar.com~[\"referer ne bar.com\"]", "bar.com", "bar.com", ALLOW}, - {"~foo.bar.com~[\"referer ne bar.com\"]", "foo.bar.com", "bar.com", ALLOW}, - {"~foo.bar.com~[\"referer ne bar.com\"]", "foo.bar.com", "foo.com", BLOCK}, - {"~foo.bar.com~[\"referer ne bar.com\"]", "bar.com", "foo.com", ALLOW} - // todo: add more tests for other operators, regex_find vs regex_exact, multiple conditions, etc +// rule // fqdn // referer // expect +{"~foo.bar.com~[\"referer_host ne bar.com\"]", "foo.com", "foo.com", ALLOW}, +{"~foo.bar.com~[\"referer_host ne bar.com\"]", "bar.com", "bar.com", ALLOW}, +{"~foo.bar.com~[\"referer_host ne bar.com\"]", "foo.bar.com", "bar.com", ALLOW}, +{"~foo.bar.com~[\"referer_host ne bar.com\"]", "foo.bar.com", "foo.com", BLOCK}, +{"~foo.bar.com~[\"referer_host ne bar.com\"]", "bar.com", "foo.com", ALLOW}, + +{"~foo.bar.com~[\"referer_host ne bar.com\", \"referer_host ne www.bar.com\"]", "foo.bar.com", "bar.com", ALLOW}, +{"~foo.bar.com~[\"referer_host ne bar.com\", \"referer_host ne www.bar.com\"]", "foo.bar.com", "www.bar.com", ALLOW}, +{"~foo.bar.com~[\"referer_host ne bar.com\", \"referer_host ne www.bar.com\"]", "foo.bar.com", "baz.com", BLOCK} +// todo: add more tests for other operators, regex_find vs regex_exact, more conditions, etc }; @Test public void testConditionalMatches () throws Exception { - final BlockList blockList = new BlockList(); for (String[] test : CONDITIONAL_SPECS) { - blockList.addToBlacklist(BlockSpec.parse(test[0])); + final BlockList blockList = new BlockList(); + final String line = test[0]; + blockList.addToBlacklist(BlockSpec.parse(line)); final BlockDecisionType expected = BlockDecisionType.fromString(test[3]); final String fqdn = test[1]; final String referer = test[2]; - assertEquals("expected "+expected+" for test: fqdn="+fqdn+", referer="+referer, + assertEquals("expected "+expected+" for test: fqdn="+fqdn+", referer="+referer+" for line: "+line, expected, blockList.getDecision(fqdn, "/", null, referer, true).getDecisionType()); }