diff --git a/docs/changes.txt b/docs/changes.txt index 2481023..92669dd 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -213,3 +213,4 @@ v0.8.1 * winws2: --wf-raw-filter * nfqws2: conntrack_feed * winws2: use windivert bulk mode +* nfqws2: template free import diff --git a/nfq2/desync.c b/nfq2/desync.c index 423d607..1686dd6 100644 --- a/nfq2/desync.c +++ b/nfq2/desync.c @@ -955,8 +955,6 @@ static uint8_t desync( lua_pushf_ctrack(params.L, ctrack, tpos, bIncoming); lua_pushf_int(params.L, "profile_n", dp->n); if (dp->name) lua_pushf_str(params.L, "profile_name", dp->name); - if (dp->n_tpl) lua_pushf_int(params.L, "template_n", dp->n_tpl); - if (dp->name_tpl) lua_pushf_str(params.L, "template_name", dp->name_tpl); if (dp->cookie) lua_pushf_str(params.L, "cookie", dp->cookie); lua_pushf_bool(params.L, "outgoing", !bIncoming); lua_pushf_str(params.L, "ifin", (ifin && *ifin) ? ifin : NULL); diff --git a/nfq2/lua.c b/nfq2/lua.c index 3b59d83..44b98a3 100644 --- a/nfq2/lua.c +++ b/nfq2/lua.c @@ -651,7 +651,7 @@ static int luacall_hash(lua_State *L) static int luacall_aes(lua_State *L) { - // aes_gcm(bEncrypt, key, in) returns out + // aes(bEncrypt, key, in) returns out lua_check_argc(L,"aes",3); LUA_STACK_GUARD_ENTER(L) @@ -3714,7 +3714,7 @@ static bool lua_file_open_test(const char *filename, bool *b_gzip, char *fname) if (b_gzip) *b_gzip = is_gzip(F); fclose(F); } - return !!F; + return F; } bool lua_test_init_script_files(void) diff --git a/nfq2/nfqws.c b/nfq2/nfqws.c index 938dd56..da60cdf 100644 --- a/nfq2/nfqws.c +++ b/nfq2/nfqws.c @@ -1178,7 +1178,7 @@ bool lua_call_param_add(char *opt, struct str2_list_head *args) *p = c; if (!arg->str2) return false; } - return !!arg->str1; + return arg->str1; } struct func_list *parse_lua_call(char *opt, struct func_list_head *flist) @@ -1343,6 +1343,19 @@ static void LuaDesyncDebug(struct desync_profile *dp, const char *entity) } } +static bool deny_proto_filters(struct desync_profile *dp) +{ + // if any filter is set - deny all unset + if (!LIST_EMPTY(&dp->pf_tcp) || !LIST_EMPTY(&dp->pf_udp) || !LIST_EMPTY(&dp->icf) || !LIST_EMPTY(&dp->ipf)) + { + return port_filters_deny_if_empty(&dp->pf_tcp) && + port_filters_deny_if_empty(&dp->pf_udp) && + icmp_filters_deny_if_empty(&dp->icf) && + ipp_filters_deny_if_empty(&dp->ipf); + } + return true; +} + #ifdef __CYGWIN__ static bool wf_make_pf(char *opt, const char *l4, const char *portname, char *buf, size_t len) @@ -2383,6 +2396,7 @@ int main(int argc, char **argv) DLOG_ERR("auto hostlist fail threshold must be within 1..20\n"); exit_clean(1); } + dp->b_hostlist_auto_fail_threshold = true; break; case IDX_HOSTLIST_AUTO_FAIL_TIME: dp->hostlist_auto_fail_time = (uint8_t)atoi(optarg); @@ -2391,6 +2405,7 @@ int main(int argc, char **argv) DLOG_ERR("auto hostlist fail time is not valid\n"); exit_clean(1); } + dp->b_hostlist_auto_fail_time = true; break; case IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD: dp->hostlist_auto_retrans_threshold = (uint8_t)atoi(optarg); @@ -2399,21 +2414,27 @@ int main(int argc, char **argv) DLOG_ERR("auto hostlist fail threshold must be within 2..10\n"); exit_clean(1); } + dp->b_hostlist_auto_retrans_threshold = true; break; case IDX_HOSTLIST_AUTO_RETRANS_MAXSEQ: dp->hostlist_auto_retrans_maxseq = (uint32_t)atoi(optarg); + dp->b_hostlist_auto_retrans_maxseq = true; break; case IDX_HOSTLIST_AUTO_INCOMING_MAXSEQ: dp->hostlist_auto_incoming_maxseq = (uint32_t)atoi(optarg); + dp->b_hostlist_auto_incoming_maxseq = true; break; case IDX_HOSTLIST_AUTO_RETRANS_RESET: dp->hostlist_auto_retrans_reset = !optarg || !!atoi(optarg); + dp->b_hostlist_auto_retrans_reset = true; break; case IDX_HOSTLIST_AUTO_UDP_OUT: dp->hostlist_auto_udp_out = atoi(optarg); + dp->b_hostlist_auto_udp_out = true; break; case IDX_HOSTLIST_AUTO_UDP_IN: dp->hostlist_auto_udp_in = atoi(optarg); + dp->b_hostlist_auto_udp_in = true; break; case IDX_HOSTLIST_AUTO_DEBUG: { @@ -2501,19 +2522,12 @@ int main(int argc, char **argv) DLOG_ERR("template '%s' not found\n", optarg); exit_clean(1); } - if (!dp_list_copy(dp, &tpl->dp)) + if (!dp_copy(dp, &tpl->dp)) { DLOG_ERR("could not copy template\n"); exit_clean(1); } dp->n = desync_profile_count; - free(dp->name_tpl); - if (tpl->dp.name && !(dp->name_tpl = strdup(tpl->dp.name))) - { - DLOG_ERR("out of memory\n"); - exit_clean(1); - } - dp->n_tpl = tpl->dp.n; } break; @@ -2523,6 +2537,7 @@ int main(int argc, char **argv) DLOG_ERR("bad value for --filter-l3\n"); exit_clean(1); } + dp->b_filter_l3 = true; break; case IDX_FILTER_TCP: if (!parse_pf_list(optarg, &dp->pf_tcp)) @@ -2530,11 +2545,6 @@ int main(int argc, char **argv) DLOG_ERR("Invalid port filter : %s\n", optarg); exit_clean(1); } - // deny others if not set - if (!port_filters_deny_if_empty(&dp->pf_udp) || - !icmp_filters_deny_if_empty(&dp->icf) || - !ipp_filters_deny_if_empty(&dp->ipf)) - exit_clean(1); break; case IDX_FILTER_UDP: if (!parse_pf_list(optarg, &dp->pf_udp)) @@ -2542,11 +2552,6 @@ int main(int argc, char **argv) DLOG_ERR("Invalid port filter : %s\n", optarg); exit_clean(1); } - // deny others if not set - if (!port_filters_deny_if_empty(&dp->pf_tcp) || - !icmp_filters_deny_if_empty(&dp->icf) || - !ipp_filters_deny_if_empty(&dp->ipf)) - exit_clean(1); break; case IDX_FILTER_ICMP: if (!parse_icf_list(optarg, &dp->icf)) @@ -2554,11 +2559,6 @@ int main(int argc, char **argv) DLOG_ERR("Invalid icmp filter : %s\n", optarg); exit_clean(1); } - // deny others if not set - if (!port_filters_deny_if_empty(&dp->pf_tcp) || - !port_filters_deny_if_empty(&dp->pf_udp) || - !ipp_filters_deny_if_empty(&dp->ipf)) - exit_clean(1); break; case IDX_FILTER_IPP: if (!parse_ipp_list(optarg, &dp->ipf)) @@ -2566,11 +2566,6 @@ int main(int argc, char **argv) DLOG_ERR("Invalid ip protocol filter : %s\n", optarg); exit_clean(1); } - // deny others if not set - if (!port_filters_deny_if_empty(&dp->pf_tcp) || - !port_filters_deny_if_empty(&dp->pf_udp) || - !icmp_filters_deny_if_empty(&dp->icf)) - exit_clean(1); break; case IDX_FILTER_L7: if (!parse_l7_list(optarg, &dp->filter_l7)) @@ -2578,6 +2573,7 @@ int main(int argc, char **argv) DLOG_ERR("Invalid l7 filter : %s\n", optarg); exit_clean(1); } + dp->b_filter_l7 = true; break; #ifdef HAS_FILTER_SSID case IDX_FILTER_SSID: @@ -2935,6 +2931,7 @@ int main(int argc, char **argv) DLOG_ERR("could not make '%s' accessible. auto hostlist file may not be writable after privilege drop\n", dp->hostlist_auto->filename); } + if (!deny_proto_filters(dp)) exit_clean(1); LuaDesyncDebug(dp,"profile"); } LIST_FOREACH(dpl, ¶ms.desync_templates, next) diff --git a/nfq2/params.c b/nfq2/params.c index 83ea997..a73b4b1 100644 --- a/nfq2/params.c +++ b/nfq2/params.c @@ -361,7 +361,6 @@ void dp_init(struct desync_profile *dp) static void dp_clear_dynamic(struct desync_profile *dp) { free(dp->name); - free(dp->name_tpl); free(dp->cookie); hostlist_collection_destroy(&dp->hl_collection); @@ -415,18 +414,39 @@ struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head) return entry; } -bool dp_list_copy(struct desync_profile *to, const struct desync_profile *from) +#define DP_COPY_SIMPLE(v) if (from->b_##v) to->v=from->v; +bool dp_copy(struct desync_profile *to, const struct desync_profile *from) { - // clear everything in target - dp_clear(to); - // first copy all simple type values - *to = *from; - // prepare empty dynamic structures - dp_init_dynamic(to); + DP_COPY_SIMPLE(hostlist_auto_fail_threshold) + DP_COPY_SIMPLE(hostlist_auto_fail_time) + DP_COPY_SIMPLE(hostlist_auto_retrans_threshold) + DP_COPY_SIMPLE(hostlist_auto_retrans_maxseq) + DP_COPY_SIMPLE(hostlist_auto_incoming_maxseq) + DP_COPY_SIMPLE(hostlist_auto_retrans_reset) + DP_COPY_SIMPLE(hostlist_auto_udp_out) + DP_COPY_SIMPLE(hostlist_auto_udp_in) + DP_COPY_SIMPLE(filter_l7) + if (from->b_filter_l3) + { + to->filter_ipv4 = from->filter_ipv4; + to->filter_ipv6 = from->filter_ipv6; + } + // copy dynamic structures - if (from->name && !(to->name = strdup(from->name))) return false; - if (from->name_tpl && !(to->name_tpl = strdup(from->name_tpl))) return false; - if (from->cookie && !(to->cookie = strdup(from->cookie))) return false; + if (from->cookie) + { + free(to->cookie); + if (!(to->cookie = strdup(from->cookie))) return false; + } + if (from->hostlist_auto) + { + if (to->hostlist_auto) + { + DLOG_ERR("autohostlist replacement is not supported\n"); + return false; + } + to->hostlist_auto = from->hostlist_auto; + } if ( #ifdef HAS_FILTER_SSID !strlist_copy(&to->filter_ssid, &from->filter_ssid) || @@ -435,8 +455,13 @@ bool dp_list_copy(struct desync_profile *to, const struct desync_profile *from) !ipset_collection_copy(&to->ips_collection, &from->ips_collection) || !ipset_collection_copy(&to->ips_collection_exclude, &from->ips_collection_exclude) || !hostlist_collection_copy(&to->hl_collection, &from->hl_collection) || - !hostlist_collection_copy(&to->hl_collection_exclude, &from->hl_collection_exclude)) + !hostlist_collection_copy(&to->hl_collection_exclude, &from->hl_collection_exclude) || + !port_filters_copy(&to->pf_tcp, &from->pf_tcp) || + !port_filters_copy(&to->pf_udp, &from->pf_udp) || + !icmp_filters_copy(&to->icf, &from->icf) || + !ipp_filters_copy(&to->ipf, &from->ipf)) { + DLOG_ERR("dynamic structure copy failed\n"); return false; } return true; diff --git a/nfq2/params.h b/nfq2/params.h index f9b034d..81c3776 100644 --- a/nfq2/params.h +++ b/nfq2/params.h @@ -57,8 +57,6 @@ struct desync_profile { unsigned int n; // number of the profile char *name; // optional malloced name string - unsigned int n_tpl; // number of imported template - char *name_tpl; // imported template name char *cookie; // optional malloced string bool filter_ipv4,filter_ipv6; @@ -90,6 +88,13 @@ struct desync_profile time_t hostlist_auto_last_purge; struct func_list_head lua_desync; + + // was option set ? + bool b_hostlist_auto_fail_threshold, b_hostlist_auto_fail_time,b_hostlist_auto_retrans_threshold; + bool b_hostlist_auto_retrans_maxseq, b_hostlist_auto_incoming_maxseq, b_hostlist_auto_retrans_reset; + bool b_hostlist_auto_udp_out, b_hostlist_auto_udp_in; + bool b_filter_l3, b_filter_l7; + }; #define PROFILE_NAME(dp) ((dp)->name ? (dp)->name : "noname") @@ -104,7 +109,7 @@ struct desync_profile_list { LIST_HEAD(desync_profile_list_head, desync_profile_list); struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head); void dp_list_move(struct desync_profile_list_head *target, struct desync_profile_list *dpl); -bool dp_list_copy(struct desync_profile *to, const struct desync_profile *from); +bool dp_copy(struct desync_profile *to, const struct desync_profile *from); struct desync_profile_list *dp_list_search_name(struct desync_profile_list_head *head, const char *name); void dp_entry_destroy(struct desync_profile_list *entry); void dp_list_destroy(struct desync_profile_list_head *head); diff --git a/nfq2/pools.c b/nfq2/pools.c index 4f9dac3..54cb529 100644 --- a/nfq2/pools.c +++ b/nfq2/pools.c @@ -68,7 +68,7 @@ hostlist_pool *HostlistPoolGetStr(hostlist_pool *p, const char *s) } bool HostlistPoolCheckStr(hostlist_pool *p, const char *s) { - return !!HostlistPoolGetStr(p,s); + return HostlistPoolGetStr(p,s); } void HostlistPoolDestroy(hostlist_pool **pp) @@ -539,7 +539,7 @@ static bool ipset_kavl_add(struct kavl_bit_elem **ipset, const void *a, uint8_t bool ipset4Check(const struct kavl_bit_elem *ipset, const struct in_addr *a, uint8_t preflen) { - return !!kavl_bit_get(ipset,a,preflen); + return kavl_bit_get(ipset,a,preflen); } bool ipset4Add(struct kavl_bit_elem **ipset, const struct in_addr *a, uint8_t preflen) { @@ -567,7 +567,7 @@ void ipset4Print(struct kavl_bit_elem *ipset) bool ipset6Check(const struct kavl_bit_elem *ipset, const struct in6_addr *a, uint8_t preflen) { - return !!kavl_bit_get(ipset,a,preflen); + return kavl_bit_get(ipset,a,preflen); } bool ipset6Add(struct kavl_bit_elem **ipset, const struct in6_addr *a, uint8_t preflen) { @@ -723,16 +723,35 @@ bool ipset_collection_is_empty(const struct ipset_collection_head *head) } -bool port_filter_add(struct port_filters_head *head, const port_filter *pf) +static struct port_filter_item *port_filter_entry_alloc(const port_filter *pf) { struct port_filter_item *entry = malloc(sizeof(struct port_filter_item)); - if (entry) - { - entry->pf = *pf; - LIST_INSERT_HEAD(head, entry, next); - } + if (entry) entry->pf = *pf; return entry; } +bool port_filter_add(struct port_filters_head *head, const port_filter *pf) +{ + struct port_filter_item *entry = port_filter_entry_alloc(pf); + if (entry) LIST_INSERT_HEAD(head, entry, next); + return entry; +} +static struct port_filter_item *port_filter_entry_copy(const struct port_filter_item *pfi) +{ + return port_filter_entry_alloc(&pfi->pf); +} +bool port_filters_copy(struct port_filters_head *to, const struct port_filters_head *from) +{ + struct port_filter_item *tail, *item, *entry; + + LIST_TAIL(to, tail, item); + LIST_FOREACH(item, from, next) + { + if (!(entry = port_filter_entry_copy(item))) return false; + LIST_INSERT_TAIL(to, tail, entry, next); + tail = tail ? LIST_NEXT(tail, next) : LIST_FIRST(to); + } + return true; +} void port_filters_destroy(struct port_filters_head *head) { struct port_filter_item *entry; @@ -762,16 +781,35 @@ bool port_filters_deny_if_empty(struct port_filters_head *head) } -bool icmp_filter_add(struct icmp_filters_head *head, const icmp_filter *icf) +static struct icmp_filter_item *icmp_filter_entry_alloc(const icmp_filter *icf) { struct icmp_filter_item *entry = malloc(sizeof(struct icmp_filter_item)); - if (entry) - { - entry->icf = *icf; - LIST_INSERT_HEAD(head, entry, next); - } + if (entry) entry->icf = *icf; return entry; } +bool icmp_filter_add(struct icmp_filters_head *head, const icmp_filter *icf) +{ + struct icmp_filter_item *entry = icmp_filter_entry_alloc(icf); + if (entry) LIST_INSERT_HEAD(head, entry, next); + return entry; +} +static struct icmp_filter_item *icmp_filter_entry_copy(const struct icmp_filter_item *ifi) +{ + return icmp_filter_entry_alloc(&ifi->icf); +} +bool icmp_filters_copy(struct icmp_filters_head *to, const struct icmp_filters_head *from) +{ + struct icmp_filter_item *tail, *item, *entry; + + LIST_TAIL(to, tail, item); + LIST_FOREACH(item, from, next) + { + if (!(entry = icmp_filter_entry_copy(item))) return false; + LIST_INSERT_TAIL(to, tail, entry, next); + tail = tail ? LIST_NEXT(tail, next) : LIST_FIRST(to); + } + return true; +} void icmp_filters_destroy(struct icmp_filters_head *head) { struct icmp_filter_item *entry; @@ -801,16 +839,35 @@ bool icmp_filters_deny_if_empty(struct icmp_filters_head *head) } -bool ipp_filter_add(struct ipp_filters_head *head, const ipp_filter *ipp) +static struct ipp_filter_item *ipp_filter_entry_alloc(const ipp_filter *ipp) { struct ipp_filter_item *entry = malloc(sizeof(struct ipp_filter_item)); - if (entry) - { - entry->ipp = *ipp; - LIST_INSERT_HEAD(head, entry, next); - } + if (entry) entry->ipp = *ipp; return entry; } +bool ipp_filter_add(struct ipp_filters_head *head, const ipp_filter *ipp) +{ + struct ipp_filter_item *entry = ipp_filter_entry_alloc(ipp); + if (entry) LIST_INSERT_HEAD(head, entry, next); + return entry; +} +static struct ipp_filter_item *ipp_filter_entry_copy(const struct ipp_filter_item *ifi) +{ + return ipp_filter_entry_alloc(&ifi->ipp); +} +bool ipp_filters_copy(struct ipp_filters_head *to, const struct ipp_filters_head *from) +{ + struct ipp_filter_item *tail, *item, *entry; + + LIST_TAIL(to, tail, item); + LIST_FOREACH(item, from, next) + { + if (!(entry = ipp_filter_entry_copy(item))) return false; + LIST_INSERT_TAIL(to, tail, entry, next); + tail = tail ? LIST_NEXT(tail, next) : LIST_FIRST(to); + } + return true; +} void ipp_filters_destroy(struct ipp_filters_head *head) { struct ipp_filter_item *entry; diff --git a/nfq2/pools.h b/nfq2/pools.h index b91d36e..3cda4bc 100644 --- a/nfq2/pools.h +++ b/nfq2/pools.h @@ -186,6 +186,7 @@ struct port_filter_item { }; LIST_HEAD(port_filters_head, port_filter_item); bool port_filter_add(struct port_filters_head *head, const port_filter *pf); +bool port_filters_copy(struct port_filters_head *to, const struct port_filters_head *from); void port_filters_destroy(struct port_filters_head *head); bool port_filters_match(const struct port_filters_head *head, uint16_t port); bool port_filters_deny_if_empty(struct port_filters_head *head); @@ -196,6 +197,7 @@ struct icmp_filter_item { }; LIST_HEAD(icmp_filters_head, icmp_filter_item); bool icmp_filter_add(struct icmp_filters_head *head, const icmp_filter *icf); +bool icmp_filters_copy(struct icmp_filters_head *to, const struct icmp_filters_head *from); void icmp_filters_destroy(struct icmp_filters_head *head); bool icmp_filters_match(const struct icmp_filters_head *head, uint8_t type, uint8_t code); bool icmp_filters_deny_if_empty(struct icmp_filters_head *head); @@ -206,6 +208,7 @@ struct ipp_filter_item { }; LIST_HEAD(ipp_filters_head, ipp_filter_item); bool ipp_filter_add(struct ipp_filters_head *head, const ipp_filter *ipp); +bool ipp_filters_copy(struct ipp_filters_head *to, const struct ipp_filters_head *from); void ipp_filters_destroy(struct ipp_filters_head *head); bool ipp_filters_match(const struct ipp_filters_head *head, uint8_t proto); bool ipp_filters_deny_if_empty(struct ipp_filters_head *head); diff --git a/nfq2/protocol.c b/nfq2/protocol.c index c9d8c44..3c4c889 100644 --- a/nfq2/protocol.c +++ b/nfq2/protocol.c @@ -316,7 +316,7 @@ bool HttpFindHost(uint8_t **pHost,uint8_t *buf,size_t bs) *pHost = FindHostIn(buf, bs); if (*pHost) (*pHost)++; } - return !!*pHost; + return *pHost; } bool IsHttpReply(const uint8_t *data, size_t len) @@ -1151,7 +1151,7 @@ static bool quic_derive_initial_secret(const quic_cid_t *cid, uint8_t *client_in } bool QUICIsLongHeader(const uint8_t *data, size_t len) { - return len>=9 && !!(*data & 0x80); + return len>=9 && (*data & 0x80); } uint32_t QUICExtractVersion(const uint8_t *data, size_t len) {