From 10652023491570647fce037c6d633dfc3027f169 Mon Sep 17 00:00:00 2001 From: bol-van Date: Thu, 6 Mar 2025 15:11:43 +0300 Subject: [PATCH] nfqws,tpws: ^ prefix in hostlist disables subdomain matches --- nfq/desync.c | 2 +- nfq/hostlist.c | 51 ++++++++++++++++++++++++++++++++++--------------- nfq/hostlist.h | 6 +++--- nfq/nfqws.c | 2 +- nfq/pools.c | 27 ++++++++++++++++---------- nfq/pools.h | 29 +++++++++++++++------------- tpws/hostlist.c | 51 ++++++++++++++++++++++++++++++++++--------------- tpws/hostlist.h | 6 +++--- tpws/pools.c | 27 ++++++++++++++++---------- tpws/pools.h | 29 +++++++++++++++------------- tpws/tamper.c | 2 +- tpws/tpws.c | 4 +--- 12 files changed, 148 insertions(+), 88 deletions(-) diff --git a/nfq/desync.c b/nfq/desync.c index 4b6d9fa..4a7b330 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -347,7 +347,7 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname { DLOG("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename); HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename); - if (!StrPoolAddStr(&dp->hostlist_auto->hostlist, hostname)) + if (!HostlistPoolAddStr(&dp->hostlist_auto->hostlist, hostname, 0)) { DLOG_ERR("StrPoolAddStr out of memory\n"); return; diff --git a/nfq/hostlist.c b/nfq/hostlist.c index 42564a6..3de71b7 100644 --- a/nfq/hostlist.c +++ b/nfq/hostlist.c @@ -4,7 +4,7 @@ #include "helpers.h" // inplace tolower() and add to pool -static bool addpool(strpool **hostlist, char **s, const char *end, int *ct) +static bool addpool(hostlist_pool **hostlist, char **s, const char *end, int *ct) { char *p=*s; @@ -17,10 +17,16 @@ static bool addpool(strpool **hostlist, char **s, const char *end, int *ct) else { // advance until eol lowering all chars - for (; pmod_sig,&fsig)) return true; // up to date - StrPoolDestroy(&hfile->hostlist); + HostlistPoolDestroy(&hfile->hostlist); if (!AppendHostList(&hfile->hostlist, hfile->filename)) { - StrPoolDestroy(&hfile->hostlist); + HostlistPoolDestroy(&hfile->hostlist); return false; } hfile->mod_sig=fsig; @@ -138,10 +144,10 @@ static bool LoadHostLists(struct hostlist_files_head *list) return bres; } -bool NonEmptyHostlist(strpool **hostlist) +bool NonEmptyHostlist(hostlist_pool **hostlist) { // add impossible hostname if the list is empty - return *hostlist ? true : StrPoolAddStrLen(hostlist, "@&()", 4); + return *hostlist ? true : HostlistPoolAddStrLen(hostlist, "@&()", 4, 0); } static void MakeAutolistsNonEmpty() @@ -164,19 +170,34 @@ bool LoadAllHostLists() -static bool SearchHostList(strpool *hostlist, const char *host) +static bool SearchHostList(hostlist_pool *hostlist, const char *host) { if (hostlist) { const char *p = host; - bool bInHostList; + const struct hostlist_pool *hp; + bool bHostFull=true; while (p) { - bInHostList = StrPoolCheckStr(hostlist, p); - DLOG("hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative"); - if (bInHostList) return true; + DLOG("hostlist check for %s : ", p); + hp = HostlistPoolGetStr(hostlist, p); + if (hp) + { + if ((hp->flags & HOSTLIST_POOL_FLAG_STRICT_MATCH) && !bHostFull) + { + DLOG("negative : strict_mismatch : %s != %s\n", p, host); + } + else + { + DLOG("positive\n"); + return true; + } + } + else + DLOG("negative\n"); p = strchr(p, '.'); if (p) p++; + bHostFull = false; } } return false; diff --git a/nfq/hostlist.h b/nfq/hostlist.h index 9676613..b11aa3f 100644 --- a/nfq/hostlist.h +++ b/nfq/hostlist.h @@ -4,10 +4,10 @@ #include "pools.h" #include "params.h" -bool AppendHostlistItem(strpool **hostlist, char *s); -bool AppendHostList(strpool **hostlist, const char *filename); +bool AppendHostlistItem(hostlist_pool **hostlist, char *s); +bool AppendHostList(hostlist_pool **hostlist, const char *filename); bool LoadAllHostLists(); -bool NonEmptyHostlist(strpool **hostlist); +bool NonEmptyHostlist(hostlist_pool **hostlist); // return : true = apply fooling, false = do not apply bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck); struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename); diff --git a/nfq/nfqws.c b/nfq/nfqws.c index 4f25518..4963481 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -901,7 +901,7 @@ static bool parse_split_pos_list(char *opt, struct proto_pos *splits, int splits return true; } -static bool parse_domain_list(char *opt, strpool **pp) +static bool parse_domain_list(char *opt, hostlist_pool **pp) { char *e,*p,c; diff --git a/nfq/pools.c b/nfq/pools.c index 4cce2f6..aca4024 100644 --- a/nfq/pools.c +++ b/nfq/pools.c @@ -31,6 +31,9 @@ free(elem); \ return false; \ } +#define ADD_HOSTLIST_POOL(etype, ppool, keystr, keystr_len, flg) \ + ADD_STR_POOL(etype,ppool,keystr,keystr_len); \ + elem->flags = flg; #undef uthash_nonfatal_oom @@ -42,27 +45,31 @@ static void ut_oom_recover(void *elem) } // for not zero terminated strings -bool StrPoolAddStrLen(strpool **pp, const char *s, size_t slen) +bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t slen, uint32_t flags) { - ADD_STR_POOL(strpool, pp, s, slen) + ADD_HOSTLIST_POOL(hostlist_pool, pp, s, slen, flags) return true; } // for zero terminated strings -bool StrPoolAddStr(strpool **pp, const char *s) +bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags) { - return StrPoolAddStrLen(pp, s, strlen(s)); + return HostlistPoolAddStrLen(pp, s, strlen(s), flags); } -bool StrPoolCheckStr(strpool *p, const char *s) +hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s) { - strpool *elem; + hostlist_pool *elem; HASH_FIND_STR(p, s, elem); - return elem != NULL; + return elem; +} +bool HostlistPoolCheckStr(hostlist_pool *p, const char *s) +{ + return !!HostlistPoolGetStr(p,s); } -void StrPoolDestroy(strpool **pp) +void HostlistPoolDestroy(hostlist_pool **pp) { - DESTROY_STR_POOL(strpool, pp) + DESTROY_STR_POOL(hostlist_pool, pp) } @@ -178,7 +185,7 @@ struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const static void hostlist_files_entry_destroy(struct hostlist_file *entry) { free(entry->filename); - StrPoolDestroy(&entry->hostlist); + HostlistPoolDestroy(&entry->hostlist); free(entry); } void hostlist_files_destroy(struct hostlist_files_head *head) diff --git a/nfq/pools.h b/nfq/pools.h index aeda63f..32190c1 100644 --- a/nfq/pools.h +++ b/nfq/pools.h @@ -12,15 +12,18 @@ #define HASH_FUNCTION HASH_BER #include "uthash.h" -typedef struct strpool { - char *str; /* key */ - UT_hash_handle hh; /* makes this structure hashable */ -} strpool; +#define HOSTLIST_POOL_FLAG_STRICT_MATCH 1 -void StrPoolDestroy(strpool **pp); -bool StrPoolAddStr(strpool **pp,const char *s); -bool StrPoolAddStrLen(strpool **pp,const char *s,size_t slen); -bool StrPoolCheckStr(strpool *p,const char *s); +typedef struct hostlist_pool { + char *str; /* key */ + uint32_t flags; /* custom data */ + UT_hash_handle hh; /* makes this structure hashable */ +} hostlist_pool; + +void HostlistPoolDestroy(hostlist_pool **pp); +bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags); +bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t slen, uint32_t flags); +hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s); struct str_list { char *str; @@ -29,10 +32,10 @@ struct str_list { LIST_HEAD(str_list_head, str_list); typedef struct hostfail_pool { - char *str; /* key */ - int counter; /* value */ - time_t expire; /* when to expire record (unixtime) */ - UT_hash_handle hh; /* makes this structure hashable */ + char *str; /* key */ + int counter; /* value */ + time_t expire; /* when to expire record (unixtime) */ + UT_hash_handle hh; /* makes this structure hashable */ } hostfail_pool; void HostFailPoolDestroy(hostfail_pool **pp); @@ -51,7 +54,7 @@ void strlist_destroy(struct str_list_head *head); struct hostlist_file { char *filename; file_mod_sig mod_sig; - strpool *hostlist; + hostlist_pool *hostlist; LIST_ENTRY(hostlist_file) next; }; LIST_HEAD(hostlist_files_head, hostlist_file); diff --git a/tpws/hostlist.c b/tpws/hostlist.c index e1c42bb..08a9d2f 100644 --- a/tpws/hostlist.c +++ b/tpws/hostlist.c @@ -4,7 +4,7 @@ #include "helpers.h" // inplace tolower() and add to pool -static bool addpool(strpool **hostlist, char **s, const char *end, int *ct) +static bool addpool(hostlist_pool **hostlist, char **s, const char *end, int *ct) { char *p=*s; @@ -17,10 +17,16 @@ static bool addpool(strpool **hostlist, char **s, const char *end, int *ct) else { // advance until eol lowering all chars - for (; pmod_sig,&fsig)) return true; // up to date - StrPoolDestroy(&hfile->hostlist); + HostlistPoolDestroy(&hfile->hostlist); if (!AppendHostList(&hfile->hostlist, hfile->filename)) { - StrPoolDestroy(&hfile->hostlist); + HostlistPoolDestroy(&hfile->hostlist); return false; } hfile->mod_sig=fsig; @@ -138,10 +144,10 @@ static bool LoadHostLists(struct hostlist_files_head *list) return bres; } -bool NonEmptyHostlist(strpool **hostlist) +bool NonEmptyHostlist(hostlist_pool **hostlist) { // add impossible hostname if the list is empty - return *hostlist ? true : StrPoolAddStrLen(hostlist, "@&()", 4); + return *hostlist ? true : HostlistPoolAddStrLen(hostlist, "@&()", 4, 0); } static void MakeAutolistsNonEmpty() @@ -164,19 +170,34 @@ bool LoadAllHostLists() -static bool SearchHostList(strpool *hostlist, const char *host) +static bool SearchHostList(hostlist_pool *hostlist, const char *host) { if (hostlist) { const char *p = host; - bool bInHostList; + const struct hostlist_pool *hp; + bool bHostFull=true; while (p) { - bInHostList = StrPoolCheckStr(hostlist, p); - VPRINT("hostlist check for %s : %s\n", p, bInHostList ? "positive" : "negative"); - if (bInHostList) return true; + VPRINT("hostlist check for %s : ", p); + hp = HostlistPoolGetStr(hostlist, p); + if (hp) + { + if ((hp->flags & HOSTLIST_POOL_FLAG_STRICT_MATCH) && !bHostFull) + { + VPRINT("negative : strict_mismatch : %s != %s\n", p, host); + } + else + { + VPRINT("positive\n"); + return true; + } + } + else + VPRINT("negative\n"); p = strchr(p, '.'); if (p) p++; + bHostFull = false; } } return false; diff --git a/tpws/hostlist.h b/tpws/hostlist.h index 9676613..b11aa3f 100644 --- a/tpws/hostlist.h +++ b/tpws/hostlist.h @@ -4,10 +4,10 @@ #include "pools.h" #include "params.h" -bool AppendHostlistItem(strpool **hostlist, char *s); -bool AppendHostList(strpool **hostlist, const char *filename); +bool AppendHostlistItem(hostlist_pool **hostlist, char *s); +bool AppendHostList(hostlist_pool **hostlist, const char *filename); bool LoadAllHostLists(); -bool NonEmptyHostlist(strpool **hostlist); +bool NonEmptyHostlist(hostlist_pool **hostlist); // return : true = apply fooling, false = do not apply bool HostlistCheck(const struct desync_profile *dp,const char *host, bool *excluded, bool bSkipReloadCheck); struct hostlist_file *RegisterHostlist(struct desync_profile *dp, bool bExclude, const char *filename); diff --git a/tpws/pools.c b/tpws/pools.c index 4cce2f6..aca4024 100644 --- a/tpws/pools.c +++ b/tpws/pools.c @@ -31,6 +31,9 @@ free(elem); \ return false; \ } +#define ADD_HOSTLIST_POOL(etype, ppool, keystr, keystr_len, flg) \ + ADD_STR_POOL(etype,ppool,keystr,keystr_len); \ + elem->flags = flg; #undef uthash_nonfatal_oom @@ -42,27 +45,31 @@ static void ut_oom_recover(void *elem) } // for not zero terminated strings -bool StrPoolAddStrLen(strpool **pp, const char *s, size_t slen) +bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t slen, uint32_t flags) { - ADD_STR_POOL(strpool, pp, s, slen) + ADD_HOSTLIST_POOL(hostlist_pool, pp, s, slen, flags) return true; } // for zero terminated strings -bool StrPoolAddStr(strpool **pp, const char *s) +bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags) { - return StrPoolAddStrLen(pp, s, strlen(s)); + return HostlistPoolAddStrLen(pp, s, strlen(s), flags); } -bool StrPoolCheckStr(strpool *p, const char *s) +hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s) { - strpool *elem; + hostlist_pool *elem; HASH_FIND_STR(p, s, elem); - return elem != NULL; + return elem; +} +bool HostlistPoolCheckStr(hostlist_pool *p, const char *s) +{ + return !!HostlistPoolGetStr(p,s); } -void StrPoolDestroy(strpool **pp) +void HostlistPoolDestroy(hostlist_pool **pp) { - DESTROY_STR_POOL(strpool, pp) + DESTROY_STR_POOL(hostlist_pool, pp) } @@ -178,7 +185,7 @@ struct hostlist_file *hostlist_files_add(struct hostlist_files_head *head, const static void hostlist_files_entry_destroy(struct hostlist_file *entry) { free(entry->filename); - StrPoolDestroy(&entry->hostlist); + HostlistPoolDestroy(&entry->hostlist); free(entry); } void hostlist_files_destroy(struct hostlist_files_head *head) diff --git a/tpws/pools.h b/tpws/pools.h index aeda63f..32190c1 100644 --- a/tpws/pools.h +++ b/tpws/pools.h @@ -12,15 +12,18 @@ #define HASH_FUNCTION HASH_BER #include "uthash.h" -typedef struct strpool { - char *str; /* key */ - UT_hash_handle hh; /* makes this structure hashable */ -} strpool; +#define HOSTLIST_POOL_FLAG_STRICT_MATCH 1 -void StrPoolDestroy(strpool **pp); -bool StrPoolAddStr(strpool **pp,const char *s); -bool StrPoolAddStrLen(strpool **pp,const char *s,size_t slen); -bool StrPoolCheckStr(strpool *p,const char *s); +typedef struct hostlist_pool { + char *str; /* key */ + uint32_t flags; /* custom data */ + UT_hash_handle hh; /* makes this structure hashable */ +} hostlist_pool; + +void HostlistPoolDestroy(hostlist_pool **pp); +bool HostlistPoolAddStr(hostlist_pool **pp, const char *s, uint32_t flags); +bool HostlistPoolAddStrLen(hostlist_pool **pp, const char *s, size_t slen, uint32_t flags); +hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s); struct str_list { char *str; @@ -29,10 +32,10 @@ struct str_list { LIST_HEAD(str_list_head, str_list); typedef struct hostfail_pool { - char *str; /* key */ - int counter; /* value */ - time_t expire; /* when to expire record (unixtime) */ - UT_hash_handle hh; /* makes this structure hashable */ + char *str; /* key */ + int counter; /* value */ + time_t expire; /* when to expire record (unixtime) */ + UT_hash_handle hh; /* makes this structure hashable */ } hostfail_pool; void HostFailPoolDestroy(hostfail_pool **pp); @@ -51,7 +54,7 @@ void strlist_destroy(struct str_list_head *head); struct hostlist_file { char *filename; file_mod_sig mod_sig; - strpool *hostlist; + hostlist_pool *hostlist; LIST_ENTRY(hostlist_file) next; }; LIST_HEAD(hostlist_files_head, hostlist_file); diff --git a/tpws/tamper.c b/tpws/tamper.c index c06613e..00b653d 100644 --- a/tpws/tamper.c +++ b/tpws/tamper.c @@ -433,7 +433,7 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname { VPRINT("auto hostlist (profile %d) : adding %s to %s\n", dp->n, hostname, dp->hostlist_auto->filename); HOSTLIST_DEBUGLOG_APPEND("%s : profile %d : client %s : proto %s : adding to %s", hostname, dp->n, client_ip_port, l7proto_str(l7proto), dp->hostlist_auto->filename); - if (!StrPoolAddStr(&dp->hostlist_auto->hostlist, hostname)) + if (!HostlistPoolAddStr(&dp->hostlist_auto->hostlist, hostname, 0)) { DLOG_ERR("StrPoolAddStr out of memory\n"); return; diff --git a/tpws/tpws.c b/tpws/tpws.c index a166264..30f6703 100644 --- a/tpws/tpws.c +++ b/tpws/tpws.c @@ -121,7 +121,6 @@ static bool test_list_files() struct hostlist_file *hfile; struct ipset_file *ifile; -printf("1\n"); LIST_FOREACH(hfile, ¶ms.hostlists, next) if (hfile->filename && !file_open_test(hfile->filename, O_RDONLY)) { @@ -136,7 +135,6 @@ printf("1\n"); DLOG_ERR("cannot access ipset file '%s'\n",ifile->filename); return false; } -printf("2\n"); return true; } @@ -535,7 +533,7 @@ static bool parse_pf_list(char *opt, struct port_filters_head *pfl) return true; } -static bool parse_domain_list(char *opt, strpool **pp) +static bool parse_domain_list(char *opt, hostlist_pool **pp) { char *e,*p,c;