From 2ff0f728e578588b977e0db628b21aed86aceea4 Mon Sep 17 00:00:00 2001 From: Soner Tari Date: Sat, 2 Oct 2021 22:59:09 +0300 Subject: [PATCH] Use template macros for code reuse, and append to linked lists Add to the end of linked lists for correct list ordering, but btrees cannot obey this ordering. Also, update the unit tests accordingly. And fix compile with WITHOUT_USERAUTH. --- src/filter.c | 156 ++++++++++++++--------------------------- tests/check/filter.t.c | 136 +++++++++++++++++------------------ 2 files changed, 122 insertions(+), 170 deletions(-) diff --git a/src/filter.c b/src/filter.c index 09c895e..bde452a 100644 --- a/src/filter.c +++ b/src/filter.c @@ -32,6 +32,26 @@ #include "log.h" #include "util.h" +#define free_list(list, type) { \ + while (list) { \ + type *next = (list)->next; \ + free(list); \ + list = next; \ + }} + +#define append_list(list, value, type) { \ + type *l = *list; \ + while (l) { \ + if (!l->next) \ + break; \ + l = l->next; \ + } \ + if (l) \ + l->next = value; \ + else \ + *list = value; \ + } + #ifndef WITHOUT_USERAUTH void filter_userlist_free(userlist_t *ul) @@ -56,8 +76,8 @@ filter_userlist_copy(userlist_t *userlist, const char *argv0, userlist_t **ul) du->user = strdup(userlist->user); if (!du->user) return oom_return(argv0); - du->next = *ul; - *ul = du; + + append_list(ul, du, userlist_t) userlist = userlist->next; } @@ -142,8 +162,8 @@ filter_userlist_set(char *value, int line_num, userlist_t **list, const char *li ul->user = strdup(argv[argc]); if (!ul->user) return oom_return_na(); - ul->next = *list; - *list = ul; + + append_list(list, ul, userlist_t) } return 0; } @@ -276,6 +296,7 @@ filter_list_free(filter_list_t *list) free(list); } +#ifndef WITHOUT_USERAUTH #define free_keyword(p) { \ free(*p->keyword); \ filter_list_free(*p->list); \ @@ -309,6 +330,7 @@ filter_user_free(filter_user_t *user) #define free_user(p) { \ filter_user_free(*p); \ free(*p); } +#endif /* !WITHOUT_USERAUTH */ void filter_free(opts_t *opts) @@ -367,22 +389,6 @@ filter_free(opts_t *opts) opts->filter = NULL; } -static void -filter_macro_value_append(value_t **list, value_t *value) -{ - value_t *l = *list; - while (l) { - if (!l->next) - break; - l = l->next; - } - - if (l) - l->next = value; - else - *list = value; -} - int filter_macro_copy(macro_t *macro, const char *argv0, opts_t *opts) { @@ -407,35 +413,18 @@ filter_macro_copy(macro_t *macro, const char *argv0, opts_t *opts) if (!v->value) return oom_return(argv0); - filter_macro_value_append(&m->value, v); + append_list(&m->value, v, value_t) value = value->next; } - m->next = opts->macro; - opts->macro = m; + append_list(&opts->macro, m, macro_t) macro = macro->next; } return 0; } -static void -filter_rule_append(filter_rule_t **list, filter_rule_t *rule) -{ - filter_rule_t *l = *list; - while (l) { - if (!l->next) - break; - l = l->next; - } - - if (l) - l->next = rule; - else - *list = rule; -} - int filter_rules_copy(filter_rule_t *rule, const char *argv0, opts_t *opts) { @@ -497,7 +486,7 @@ filter_rules_copy(filter_rule_t *rule, const char *argv0, opts_t *opts) // The action field is not a pointer, hence the direct assignment (copy) r->action = rule->action; - filter_rule_append(&opts->filter_rules, r); + append_list(&opts->filter_rules, r, filter_rule_t) rule = rule->next; } @@ -690,18 +679,7 @@ out: filter_port_list_t *s = malloc(sizeof(filter_port_list_t)); \ memset(s, 0, sizeof(filter_port_list_t)); \ s->port = *p; \ - s->next = port; \ - port = s; } - -static void -filter_tmp_port_list_free(filter_port_list_t *port_list) -{ - while (port_list) { - filter_port_list_t *next = port_list->next; - free(port_list); - port_list = next; - } -} + append_list(&port, s, filter_port_list_t) } static char * filter_sites_str(filter_site_list_t *site_list) @@ -738,7 +716,7 @@ filter_sites_str(filter_site_list_t *site_list) ports_substring ? "\n port substring:" : "", STRORNONE(ports_substring)) < 0) { if (ports_exact) { free(ports_exact); - filter_tmp_port_list_free(port); + free_list(port, filter_port_list_t) } if (ports_substring) free(ports_substring); @@ -746,7 +724,7 @@ filter_sites_str(filter_site_list_t *site_list) } if (ports_exact) { free(ports_exact); - filter_tmp_port_list_free(port); + free_list(port, filter_port_list_t) } if (ports_substring) free(ports_substring); @@ -785,11 +763,7 @@ filter_list_sub_str(filter_site_list_t *list, char *old_s, const char *name) static void filter_tmp_site_list_free(filter_site_list_t **list) { - while (*list) { - filter_site_list_t *next = (*list)->next; - free(*list); - *list = next; - } + free_list(*list, filter_site_list_t) *list = NULL; } @@ -803,8 +777,7 @@ filter_list_str(filter_list_t *list) filter_site_list_t *s = malloc(sizeof(filter_site_list_t)); \ memset(s, 0, sizeof(filter_site_list_t)); \ s->site = *p; \ - s->next = site; \ - site = s; } + append_list(&site, s, filter_site_list_t) } if (list->ip_btree) { __kb_traverse(filter_site_p_t, list->ip_btree, build_site_list); @@ -902,19 +875,14 @@ filter_ip_btree_str(kbtree_t(ip) *ip_btree) filter_ip_list_t *i = malloc(sizeof(filter_ip_list_t)); \ memset(i, 0, sizeof(filter_ip_list_t)); \ i->ip = *p; \ - i->next = ip; \ - ip = i; } + append_list(&ip, i, filter_ip_list_t) } filter_ip_list_t *ip = NULL; __kb_traverse(filter_ip_p_t, ip_btree, build_ip_list); char *s = filter_ip_list_str(ip); - while (ip) { - filter_ip_list_t *next = ip->next; - free(ip); - ip = next; - } + free_list(ip, filter_ip_list_t) return s; } @@ -966,8 +934,7 @@ out: filter_user_list_t *u = malloc(sizeof(filter_user_list_t)); \ memset(u, 0, sizeof(filter_user_list_t)); \ u->user = *p; \ - u->next = user; \ - user = u; } + append_list(&user, u, filter_user_list_t) } static char * filter_user_btree_str(kbtree_t(user) *user_btree) @@ -980,11 +947,7 @@ filter_user_btree_str(kbtree_t(user) *user_btree) char *s = filter_user_list_str(user); - while (user) { - filter_user_list_t *next = user->next; - free(user); - user = next; - } + free_list(user, filter_user_list_t) return s; } @@ -1032,19 +995,14 @@ filter_keyword_btree_str(kbtree_t(keyword) *keyword_btree) filter_keyword_list_t *k = malloc(sizeof(filter_keyword_list_t)); \ memset(k, 0, sizeof(filter_keyword_list_t)); \ k->keyword = *p; \ - k->next = keyword; \ - keyword = k; } + append_list(&keyword, k, filter_keyword_list_t) } filter_keyword_list_t *keyword = NULL; __kb_traverse(filter_keyword_p_t, keyword_btree, build_keyword_list); char *s = filter_keyword_list_str(keyword); - while (keyword) { - filter_keyword_list_t *next = keyword->next; - free(keyword); - keyword = next; - } + free_list(keyword, filter_keyword_list_t) return s; } @@ -1106,11 +1064,7 @@ filter_userkeyword_btree_str(kbtree_t(user) *user_btree) char *s = filter_userkeyword_list_str(user); - while (user) { - filter_user_list_t *next = user->next; - free(user); - user = next; - } + free_list(user, filter_user_list_t) return s; } #endif /* !WITHOUT_USERAUTH */ @@ -1381,7 +1335,7 @@ filter_passsite_set(opts_t *opts, char *value, int line_num) rule->cn = 1; rule->action.pass = 1; - filter_rule_append(&opts->filter_rules, rule); + append_list(&opts->filter_rules, rule, filter_rule_t) #ifdef DEBUG_OPTS filter_rule_dbg_print(rule); @@ -1463,11 +1417,10 @@ filter_macro_set(opts_t *opts, char *value, int line_num) if (!v->value) return oom_return_na(); - filter_macro_value_append(¯o->value, v); + append_list(¯o->value, v, value_t) } - macro->next = opts->macro; - opts->macro = macro; + append_list(&opts->macro, macro, macro_t) #ifdef DEBUG_OPTS log_dbg_printf("Macro: %s = %s\n", macro->name, filter_value_str(macro->value)); @@ -1837,7 +1790,7 @@ filter_rule_translate(opts_t *opts, const char *name, int argc, char **argv, int rule->dstip = 1; } - filter_rule_append(&opts->filter_rules, rule); + append_list(&opts->filter_rules, rule, filter_rule_t) #ifdef DEBUG_OPTS filter_rule_dbg_print(rule); @@ -2498,8 +2451,7 @@ filter_ip_get(filter_t *filter, filter_rule_t *rule) ip_list->ip = ip; - ip_list->next = filter->ip_list; - filter->ip_list = ip_list; + append_list(&filter->ip_list, ip_list, filter_ip_list_t) } } return ip; @@ -2599,8 +2551,7 @@ filter_keyword_get(filter_t *filter, filter_user_t *user, filter_rule_t *rule) keyword_list->keyword = keyword; filter_keyword_list_t **list = user ? &user->keyword_list : &filter->keyword_list; - keyword_list->next = *list; - *list = keyword_list; + append_list(list, keyword_list, filter_keyword_list_t) } } return keyword; @@ -2691,8 +2642,7 @@ filter_user_get(filter_t *filter, filter_rule_t *rule) user_list->user = user; - user_list->next = filter->user_list; - filter->user_list = user_list; + append_list(&filter->user_list, user_list, filter_user_list_t) } } return user; @@ -2765,6 +2715,7 @@ filter_set(filter_rule_t *rule) } #ifdef DEBUG_OPTS +#ifndef WITHOUT_USERAUTH #define traverse_user(p) { if (cnt == 0) y = *p; ++cnt; } int cnt = 0; if (filter->user_btree) { @@ -2785,14 +2736,15 @@ filter_set(filter_rule_t *rule) if (cnt) fprintf(stderr, "keyword_exact first element: %s == %s\n", x2->keyword, y2->keyword); } -#define traverse_ip(p) { if (cnt == 0) y3 = *p; ++cnt; } +#endif /* !WITHOUT_USERAUTH */ +#define traverse_ip(p) { if (cnt2 == 0) y3 = *p; ++cnt2; } if (filter->ip_btree) { - cnt = 0; + int cnt2 = 0; filter_ip_p_t x3, y3 = NULL; __kb_traverse(filter_ip_p_t, filter->ip_btree, traverse_ip); __kb_get_first(filter_ip_p_t, filter->ip_btree, x3); - fprintf(stderr, "ip_exact # of elements from traversal: %d\n", cnt); - if (cnt) + fprintf(stderr, "ip_exact # of elements from traversal: %d\n", cnt2); + if (cnt2) fprintf(stderr, "ip_exact first element: %s == %s\n", x3->ip, y3->ip); } #endif /* DEBUG_OPTS */ diff --git a/tests/check/filter.t.c b/tests/check/filter.t.c index 77b64ab..3481b34 100644 --- a/tests/check/filter.t.c +++ b/tests/check/filter.t.c @@ -1505,17 +1505,17 @@ START_TEST(set_filter_rule_08) "keyword_filter_substr->\n" "all_user_filter->\n" "ip_filter_exact->\n" -" ip 0 192.168.0.2 (exact)= \n" +" ip 0 192.168.0.1 (exact)= \n" " ip exact: \n" -" 0: 192.168.0.3 (exact, action=||||match, log=|||||, precedence=1)\n" -" 1: 192.168.0.1 (exact, action=||||match, log=|||||, precedence=1)\n" +" 0: 192.168.0.2 (exact, action=divert|split|pass||, log=!connect|master|!cert|content|!pcap|mirror, precedence=2)\n" +" 1: 192.168.0.3 (exact, action=||||match, log=|||||, precedence=1)\n" +" ip 1 192.168.0.2 (exact)= \n" +" ip exact: \n" +" 0: 192.168.0.1 (exact, action=||||match, log=|||||, precedence=1)\n" +" 1: 192.168.0.3 (exact, action=||||match, log=|||||, precedence=1)\n" " ip substring: \n" " 0: 192.168.0. (substring, action=||||match, log=|||||, precedence=1)\n" " 1: (all_sites, substring, action=||||match, log=|||||, precedence=1)\n" -" ip 1 192.168.0.1 (exact)= \n" -" ip exact: \n" -" 0: 192.168.0.3 (exact, action=||||match, log=|||||, precedence=1)\n" -" 1: 192.168.0.2 (exact, action=divert|split|pass||, log=!connect|master|!cert|content|!pcap|mirror, precedence=2)\n" "ip_filter_substr->\n" "all_filter->\n"), "failed to translate rule: %s", s); free(s); @@ -1615,7 +1615,16 @@ START_TEST(set_filter_rule_09) "keyword_filter_substr->\n" "all_user_filter->\n" "ip_filter_exact->\n" -" ip 0 192.168.0.2 (exact)= \n" +" ip 0 192.168.0.1 (exact)= \n" +" ip exact: \n" +" 0: 192.168.0.2 (exact, action=||||, log=|||||, precedence=0)\n" +" port exact:\n" +" 0: 443 (exact, action=divert|split|pass||, log=!connect|master|!cert|content|!pcap|mirror, precedence=3)\n" +" 1: 192.168.0.3 (exact, action=||||match, log=|||||!mirror, precedence=2)\n" +" port exact:\n" +" 0: 443 (exact, action=||||match, log=|||||, precedence=2)\n" +" 1: 80 (exact, action=||||match, log=|||||, precedence=2)\n" +" ip 1 192.168.0.2 (exact)= \n" " ip exact: \n" " 0: 192.168.0.1 (exact, action=||||, log=|||||, precedence=0)\n" " port exact:\n" @@ -1623,15 +1632,6 @@ START_TEST(set_filter_rule_09) " port substring:\n" " 0: 80 (substring, action=||||match, log=|||||, precedence=2)\n" " 1: (all_ports, substring, action=||||match, log=|||||, precedence=2)\n" -" ip 1 192.168.0.1 (exact)= \n" -" ip exact: \n" -" 0: 192.168.0.3 (exact, action=||||match, log=|||||!mirror, precedence=2)\n" -" port exact:\n" -" 0: 80 (exact, action=||||match, log=|||||, precedence=2)\n" -" 1: 443 (exact, action=||||match, log=|||||, precedence=2)\n" -" 1: 192.168.0.2 (exact, action=||||, log=|||||, precedence=0)\n" -" port exact:\n" -" 0: 443 (exact, action=divert|split|pass||, log=!connect|master|!cert|content|!pcap|mirror, precedence=3)\n" "ip_filter_substr->\n" "all_filter->\n"), "failed to translate rule: %s", s); free(s); @@ -1721,17 +1721,17 @@ START_TEST(set_filter_rule_10) "userkeyword_filter_exact->\n" "userkeyword_filter_substr->\n" "user_filter_exact->\n" -" user 0 root (exact)= \n" +" user 0 daemon (exact)= \n" " sni exact: \n" -" 0: example2.com (exact, action=||||match, log=|||||, precedence=3)\n" -" 1: example.com (exact, action=divert|split|pass||, log=!connect|master|!cert|content|!pcap|mirror, precedence=4)\n" -" user 1 daemon (exact)= \n" -" sni exact: \n" -" 0: example3.com (exact, action=||||match, log=|||||, precedence=3)\n" -" 1: example.com (exact, action=||||match, log=|||||, precedence=3)\n" +" 0: example.com (exact, action=||||match, log=|||||, precedence=3)\n" +" 1: example3.com (exact, action=||||match, log=|||||, precedence=3)\n" " sni substring: \n" " 0: .example.com (substring, action=||||match, log=|||||, precedence=3)\n" " 1: (all_sites, substring, action=||||match, log=|||||, precedence=3)\n" +" user 1 root (exact)= \n" +" sni exact: \n" +" 0: example.com (exact, action=divert|split|pass||, log=!connect|master|!cert|content|!pcap|mirror, precedence=4)\n" +" 1: example2.com (exact, action=||||match, log=|||||, precedence=3)\n" "user_filter_substr->\n" "keyword_filter_exact->\n" "keyword_filter_substr->\n" @@ -1852,36 +1852,36 @@ START_TEST(set_filter_rule_11) s = filter_str(opts->filter); fail_unless(!strcmp(s, "filter=>\n" "userkeyword_filter_exact->\n" -" user 0 root (exact)=\n" +" user 0 daemon (exact)=\n" " keyword exact:\n" " keyword 0 desc (exact)= \n" " cn exact: \n" -" 0: example2.com (exact, action=||||match, log=|||||, precedence=4)\n" -" 1: example.com (exact, action=divert|split|pass||, log=!connect|master|!cert|content|!pcap|mirror, precedence=5)\n" -" user 1 daemon (exact)=\n" -" keyword exact:\n" -" keyword 0 desc2 (exact)= \n" -" cn exact: \n" -" 0: example4.com (exact, action=||||match, log=|||||, precedence=4)\n" -" keyword 1 desc (exact)= \n" -" cn exact: \n" -" 0: example3.com (exact, action=||||match, log=|||||, precedence=4)\n" -" 1: example.com (exact, action=||||match, log=|||||, precedence=4)\n" +" 0: example.com (exact, action=||||match, log=|||||, precedence=4)\n" +" 1: example3.com (exact, action=||||match, log=|||||, precedence=4)\n" " cn substring: \n" " 0: .example.com (substring, action=||||match, log=|||||, precedence=4)\n" " 1: (all_sites, substring, action=||||match, log=|||||, precedence=4)\n" +" keyword 1 desc2 (exact)= \n" +" cn exact: \n" +" 0: example4.com (exact, action=||||match, log=|||||, precedence=4)\n" +" user 1 root (exact)=\n" +" keyword exact:\n" +" keyword 0 desc (exact)= \n" +" cn exact: \n" +" 0: example.com (exact, action=divert|split|pass||, log=!connect|master|!cert|content|!pcap|mirror, precedence=5)\n" +" 1: example2.com (exact, action=||||match, log=|||||, precedence=4)\n" "userkeyword_filter_substr->\n" "user_filter_exact->\n" "user_filter_substr->\n" "keyword_filter_exact->\n" -" keyword 0 desc3 (exact)= \n" -" uri exact: \n" -" 0: example6.com (exact, action=||||match, log=|||||, precedence=3)\n" -" keyword 1 desc (exact)= \n" +" keyword 0 desc (exact)= \n" " cn exact: \n" " 0: example5.com (exact, action=||||match, log=|||||, precedence=3)\n" " host substring: \n" " 0: (all_sites, substring, action=||||match, log=|||||, precedence=3)\n" +" keyword 1 desc3 (exact)= \n" +" uri exact: \n" +" 0: example6.com (exact, action=||||match, log=|||||, precedence=3)\n" "keyword_filter_substr->\n" "all_user_filter->\n" "ip_filter_exact->\n" @@ -1958,26 +1958,26 @@ START_TEST(set_filter_rule_12) "keyword_filter_substr->\n" "all_user_filter->\n" "ip_filter_exact->\n" -" ip 0 192.168.0.2 (exact)= \n" +" ip 0 192.168.0.1 (exact)= \n" " ip exact: \n" -" 0: 192.168.0.4 (exact, action=||||, log=|||||, precedence=0)\n" +" 0: 192.168.0.3 (exact, action=||||, log=|||||, precedence=0)\n" " port exact:\n" -" 0: 80 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" -" 1: 443 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" -" 1: 192.168.0.3 (exact, action=||||, log=|||||, precedence=0)\n" +" 0: 443 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" +" 1: 80 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" +" 1: 192.168.0.4 (exact, action=||||, log=|||||, precedence=0)\n" " port exact:\n" -" 0: 80 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" -" 1: 443 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" -" ip 1 192.168.0.1 (exact)= \n" +" 0: 443 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" +" 1: 80 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" +" ip 1 192.168.0.2 (exact)= \n" " ip exact: \n" -" 0: 192.168.0.4 (exact, action=||||, log=|||||, precedence=0)\n" +" 0: 192.168.0.3 (exact, action=||||, log=|||||, precedence=0)\n" " port exact:\n" -" 0: 80 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" -" 1: 443 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" -" 1: 192.168.0.3 (exact, action=||||, log=|||||, precedence=0)\n" +" 0: 443 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" +" 1: 80 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" +" 1: 192.168.0.4 (exact, action=||||, log=|||||, precedence=0)\n" " port exact:\n" -" 0: 80 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" -" 1: 443 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" +" 0: 443 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" +" 1: 80 (exact, action=||||match, log=|!master|||!pcap|, precedence=3)\n" "ip_filter_substr->\n" "all_filter->\n"), "failed to translate rule: %s", s); free(s); @@ -2051,26 +2051,26 @@ START_TEST(set_filter_rule_13) s = filter_str(opts->filter); fail_unless(!strcmp(s, "filter=>\n" "userkeyword_filter_exact->\n" -" user 0 root (exact)=\n" +" user 0 daemon (exact)=\n" " keyword exact:\n" -" keyword 0 desc2 (exact)= \n" +" keyword 0 desc1 (exact)= \n" " sni exact: \n" -" 0: site2 (exact, action=||||match, log=connect|||content||, precedence=5)\n" -" 1: site1 (exact, action=||||match, log=connect|||content||, precedence=5)\n" -" keyword 1 desc1 (exact)= \n" +" 0: site1 (exact, action=||||match, log=connect|||content||, precedence=5)\n" +" 1: site2 (exact, action=||||match, log=connect|||content||, precedence=5)\n" +" keyword 1 desc2 (exact)= \n" " sni exact: \n" -" 0: site2 (exact, action=||||match, log=connect|||content||, precedence=5)\n" -" 1: site1 (exact, action=||||match, log=connect|||content||, precedence=5)\n" -" user 1 daemon (exact)=\n" +" 0: site1 (exact, action=||||match, log=connect|||content||, precedence=5)\n" +" 1: site2 (exact, action=||||match, log=connect|||content||, precedence=5)\n" +" user 1 root (exact)=\n" " keyword exact:\n" -" keyword 0 desc2 (exact)= \n" +" keyword 0 desc1 (exact)= \n" " sni exact: \n" -" 0: site2 (exact, action=||||match, log=connect|||content||, precedence=5)\n" -" 1: site1 (exact, action=||||match, log=connect|||content||, precedence=5)\n" -" keyword 1 desc1 (exact)= \n" +" 0: site1 (exact, action=||||match, log=connect|||content||, precedence=5)\n" +" 1: site2 (exact, action=||||match, log=connect|||content||, precedence=5)\n" +" keyword 1 desc2 (exact)= \n" " sni exact: \n" -" 0: site2 (exact, action=||||match, log=connect|||content||, precedence=5)\n" -" 1: site1 (exact, action=||||match, log=connect|||content||, precedence=5)\n" +" 0: site1 (exact, action=||||match, log=connect|||content||, precedence=5)\n" +" 1: site2 (exact, action=||||match, log=connect|||content||, precedence=5)\n" "userkeyword_filter_substr->\n" "user_filter_exact->\n" "user_filter_substr->\n"