Skip to content

Commit

Permalink
New syntax: querytype=A accepts now also a list (like querytype=A,AAA…
Browse files Browse the repository at this point in the history
…A,MX). You can use the exclamation mark as before for inversion (querytype=!A) matches everything BUT type A queries. This has now been extended to be able to invert a list, too (like (querytype=!A,AAAA matches everything BUT A and AAAA queries)

Signed-off-by: DL6ER <[email protected]>
  • Loading branch information
DL6ER committed Jan 26, 2023
1 parent 8b9e6c6 commit 49e1c74
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 14 deletions.
34 changes: 25 additions & 9 deletions src/regex.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,33 @@ static bool compile_regex(const char *regexin, const enum regex_type regexid, co
// Analyze FTL-specific parts
while((part = strtok_r(NULL, FTL_REGEX_SEP, &saveptr)) != NULL)
{
char extra[17] = { 0 };
// options ";querytype=!AAAA" and ";querytype=AAAA"
if(sscanf(part, "querytype=%16s", extra))
char extra[64] = { 0 };
// options like
// - ";querytype=A" (only match type A queries)
// - ";querytype=!AAAA" (match everything but AAAA queries)
// - ";querytype=A,AAAA" (match only A and AAAA queries)
// - ";querytype=!A,AAAA" (match everything but A and AAAA queries)
if(sscanf(part, "querytype=%63s", extra))
{
// Warn if specified more than one querytype option
if(regex[index].ext.query_type != 0)
logg_regex_warning(regextype[regexid],
"Overwriting previous querytype setting",
dbidx, regexin);

// Check if the first letter is a "!"
// This means that the query type matching is inverted
bool inverted = false;
if(extra[0] == '!')
{
// Set inverted mode (will be applied
// after parsing all query types)
inverted = true;

// Remove the "!" from the string
memmove(extra, extra+1, strlen(extra));
}

// Split input string into individual query types
char *saveptr2 = NULL;
char *token = strtok_r(extra, ",", &saveptr2);
Expand All @@ -183,12 +200,6 @@ static bool compile_regex(const char *regexin, const enum regex_type regexid, co
regex[index].ext.query_type ^= 1 << type;
break;
}
// Check for INVERTED querytype
else if(token[0] == '!' && strcasecmp(token + 1u, querytypes[type]) == 0)
{
regex[index].ext.query_type ^= ~(1 << type);
break;
}
}
// Check if we found a valid query type
if(regex[index].ext.query_type == 0)
Expand All @@ -203,6 +214,11 @@ static bool compile_regex(const char *regexin, const enum regex_type regexid, co
// Get next token
token = strtok_r(NULL, ",", &saveptr2);
}

// Invert query types if requested
if(inverted)
regex[index].ext.query_type = ~regex[index].ext.query_type;

if(regex[index].ext.query_type != 0 && config.debug & DEBUG_REGEX)
{
logg(" Hint: This regex matches only specific query types:");
Expand Down
4 changes: 3 additions & 1 deletion test/gravity.db.sql
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,11 @@ INSERT INTO domainlist VALUES(11,3,'^regex-REPLYv6$;reply=fe80::1234',1,15599288
INSERT INTO domainlist VALUES(12,3,'^regex-REPLYv46$;reply=1.2.3.4;reply=fe80::1234',1,1559928803,1559928803,'');
INSERT INTO domainlist VALUES(13,3,'^regex-A$;querytype=A',1,1559928803,1559928803,'');
INSERT INTO domainlist VALUES(14,3,'^regex-notA$;querytype=!A',1,1559928803,1559928803,'');
INSERT INTO domainlist VALUES(15,3,'^regex-multiple.ftl$;querytype=ANY,HTTPS,SVCB;reply=refused',1,1559928803,1559928803,'');
INSERT INTO domainlist VALUES(16,3,'^regex-notMultiple.ftl$;querytype=!ANY,HTTPS,SVCB;reply=refused',1,1559928803,1559928803,'');

/* Other special domains */
INSERT INTO domainlist VALUES(15,1,'blacklisted-group-disabled.com',1,1559928803,1559928803,'Entry disabled by a group');
INSERT INTO domainlist VALUES(17,1,'blacklisted-group-disabled.com',1,1559928803,1559928803,'Entry disabled by a group');

INSERT INTO adlist VALUES(1,'https://hosts-file.net/ad_servers.txt',1,1559928803,1559928803,'Migrated from /etc/pihole/adlists.list',1559928803,2000,2,1);

Expand Down
10 changes: 10 additions & 0 deletions test/pdns/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,19 @@ pdnsutil add-record ftl. mx MX "50 ns1.ftl."

# SVCB + HTTPS
pdnsutil add-record ftl. svcb SVCB '1 port="80"'
pdnsutil add-record ftl. regex-multiple SVCB '1 port="80"'
pdnsutil add-record ftl. regex-notMultiple SVCB '1 port="80"'

# HTTPS
pdnsutil add-record ftl. https HTTPS '1 . alpn="h3,h2"'
pdnsutil add-record ftl. regex-multiple HTTPS '1 . alpn="h3,h2"'
pdnsutil add-record ftl. regex-notMultiple HTTPS '1 . alpn="h3,h2"'

# ANY
pdnsutil add-record ftl. regex-multiple A 192.168.3.12
pdnsutil add-record ftl. regex-multiple AAAA fe80::3f41
pdnsutil add-record ftl. regex-notMultiple A 192.168.3.12
pdnsutil add-record ftl. regex-notMultiple AAAA fe80::3f41

# Create reverse lookup zone
pdnsutil create-zone arpa ns1.ftl
Expand Down
44 changes: 40 additions & 4 deletions test/test_suite.bats
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
@test "Number of compiled regex filters as expected" {
run bash -c 'grep "Compiled [0-9]* whitelist" /var/log/pihole/FTL.log'
printf "%s\n" "${lines[@]}"
[[ ${lines[0]} == *"Compiled 2 whitelist and 9 blacklist regex filters"* ]]
[[ ${lines[0]} == *"Compiled 2 whitelist and 11 blacklist regex filters"* ]]
}

@test "Blacklisted domain is blocked" {
Expand Down Expand Up @@ -196,7 +196,7 @@
[[ ${lines[0]} == "2" ]]
run bash -c "grep -c 'Regex blacklist ([[:digit:]]*, DB ID [[:digit:]]*) .* NOT ENABLED for client 127.0.0.4' /var/log/pihole/FTL.log"
printf "%s\n" "${lines[@]}"
[[ ${lines[0]} == "9" ]]
[[ ${lines[0]} == "11" ]]
}

@test "Client 5: Client is recognized by MAC address" {
Expand Down Expand Up @@ -228,7 +228,7 @@
[[ ${lines[0]} == "2" ]]
run bash -c "grep -c 'Regex blacklist ([[:digit:]]*, DB ID [[:digit:]]*) .* NOT ENABLED for client 127.0.0.5' /var/log/pihole/FTL.log"
printf "%s\n" "${lines[@]}"
[[ ${lines[0]} == "9" ]]
[[ ${lines[0]} == "11" ]]
}

@test "Client 6: Client is recognized by interface name" {
Expand Down Expand Up @@ -266,7 +266,7 @@
[[ ${lines[0]} == "2" ]]
run bash -c "grep -c 'Regex blacklist ([[:digit:]]*, DB ID [[:digit:]]*) .* NOT ENABLED for client 127.0.0.6' /var/log/pihole/FTL.log"
printf "%s\n" "${lines[@]}"
[[ ${lines[0]} == "9" ]]
[[ ${lines[0]} == "11" ]]
}

@test "Normal query (A) is not blocked" {
Expand Down Expand Up @@ -1082,6 +1082,42 @@
[[ "${lines[@]}" == *"- HTTPS"* ]]
}

@test "Regex Test 52: Option \";querytype=ANY,HTTPS,SVCB;reply=refused\" working as expected (ONLY matching ANY, HTTPS or SVCB queries)" {
run bash -c 'dig A regex-multiple.ftl @127.0.0.1'
printf "dig A: %s\n" "${lines[@]}"
[[ "${lines[@]}" == *"status: NOERROR"* ]]
run bash -c 'dig AAAA regex-multiple.ftl @127.0.0.1'
printf "dig AAAA: %s\n" "${lines[@]}"
[[ "${lines[@]}" == *"status: NOERROR"* ]]
run bash -c 'dig SVCB regex-multiple.ftl @127.0.0.1'
printf "dig SVCB: %s\n" "${lines[@]}"
[[ "${lines[@]}" == *"status: REFUSED"* ]]
run bash -c 'dig HTTPS regex-multiple.ftl @127.0.0.1'
printf "dig HTTPS: %s\n" "${lines[@]}"
[[ "${lines[@]}" == *"status: REFUSED"* ]]
run bash -c 'dig ANY regex-multiple.ftl @127.0.0.1'
printf "dig ANY: %s\n" "${lines[@]}"
[[ "${lines[@]}" == *"status: REFUSED"* ]]
}

@test "Regex Test 53: Option \";querytype=!ANY,HTTPS,SVCB;reply=refused\" working as expected (NOT matching ANY, HTTPS or SVCB queries)" {
run bash -c 'dig A regex-notMultiple.ftl @127.0.0.1'
printf "dig A: %s\n" "${lines[@]}"
[[ "${lines[@]}" == *"status: REFUSED"* ]]
run bash -c 'dig AAAA regex-notMultiple.ftl @127.0.0.1'
printf "dig AAAA: %s\n" "${lines[@]}"
[[ "${lines[@]}" == *"status: REFUSED"* ]]
run bash -c 'dig SVCB regex-notMultiple.ftl @127.0.0.1'
printf "dig SVCB: %s\n" "${lines[@]}"
[[ "${lines[@]}" == *"status: NOERROR"* ]]
run bash -c 'dig HTTPS regex-notMultiple.ftl @127.0.0.1'
printf "dig HTTPS: %s\n" "${lines[@]}"
[[ "${lines[@]}" == *"status: NOERROR"* ]]
run bash -c 'dig ANY regex-notMultiple.ftl @127.0.0.1'
printf "dig ANY: %s\n" "${lines[@]}"
[[ "${lines[@]}" == *"status: NOERROR"* ]]
}

# x86_64-musl is built on busybox which has a slightly different
# variant of ls displaying three, instead of one, spaces between the
# user and group names.
Expand Down

0 comments on commit 49e1c74

Please sign in to comment.