Use kbtree BST for exact match in site and port 'to' fields

So, for 'to' fields too, we use two separate data structures: binary
search trees (BST) for exact match and linked lists for substring match.

Now all 'from' and 'to' fields in filtering rules use these two data
structures.

To repeat, filtering rules should be written with exact matches instead
of substring matches, as much as possible. Because BST search must be
much faster than substring search over linked lists.

To repeat, we have modifed kbtree to support complex data structures in
from fields.

Also, update the unit tests accordingly.
pull/48/head
Soner Tari 3 years ago
parent 15991dfb93
commit 4f36a21c78

@ -197,61 +197,101 @@ filter_rules_free(opts_t *opts)
opts->filter_rules = NULL;
}
#define free_port(p) { \
free(*p->port); \
free(*p); }
static void
filter_port_btree_free(kbtree_t(port) *port_btree)
{
if (port_btree) {
__kb_traverse(filter_port_p_t, port_btree, free_port);
__kb_destroy(port_btree);
}
}
static void
filter_port_free(filter_port_t *port)
filter_port_list_free(filter_port_list_t *port)
{
while (port) {
filter_port_t *p = port->next;
free(port->port);
free(port);
filter_port_list_t *p = port->next;
free_port(&port)
port = p;
}
}
static filter_site_t *
filter_site_free(filter_site_t *site)
#define free_site(p) { \
free(*p->site); \
filter_port_btree_free(*p->port_btree); \
filter_port_list_free(*p->port_list); \
free(*p); }
static filter_site_list_t *
filter_site_free(filter_site_list_t *site_list)
{
filter_site_t *s = site->next;
free(site->site);
filter_port_free(site->port);
free(site);
filter_site_list_t *s = site_list->next;
free_site(&site_list->site)
free(site_list);
return s;
}
static void
filter_list_free(filter_list_t *list)
{
while (list->ip)
list->ip = filter_site_free(list->ip);
while (list->sni)
list->sni = filter_site_free(list->sni);
while (list->cn)
list->cn = filter_site_free(list->cn);
while (list->host)
list->host = filter_site_free(list->host);
while (list->uri)
list->uri = filter_site_free(list->uri);
if (list->ip_btree) {
__kb_traverse(filter_site_p_t, list->ip_btree, free_site);
__kb_destroy(list->ip_btree);
}
while (list->ip_list)
list->ip_list = filter_site_free(list->ip_list);
if (list->sni_btree) {
__kb_traverse(filter_site_p_t, list->sni_btree, free_site);
__kb_destroy(list->sni_btree);
}
while (list->sni_list)
list->sni_list = filter_site_free(list->sni_list);
if (list->cn_btree) {
__kb_traverse(filter_site_p_t, list->cn_btree, free_site);
__kb_destroy(list->cn_btree);
}
while (list->cn_list)
list->cn_list = filter_site_free(list->cn_list);
if (list->host_btree) {
__kb_traverse(filter_site_p_t, list->host_btree, free_site);
__kb_destroy(list->host_btree);
}
while (list->host_list)
list->host_list = filter_site_free(list->host_list);
if (list->uri_btree) {
__kb_traverse(filter_site_p_t, list->uri_btree, free_site);
__kb_destroy(list->uri_btree);
}
while (list->uri_list)
list->uri_list = filter_site_free(list->uri_list);
free(list);
}
#define free_keyword(p) { \
free(*p->keyword); \
filter_list_free(*p->list); \
free(*p); }
static void
filter_keyword_list_free(filter_keyword_list_t *list)
{
while (list) {
free(list->keyword->keyword);
filter_list_free(list->keyword->list);
filter_keyword_list_t *keyword = list->next;
free_keyword(&list->keyword)
free(list);
list = keyword;
}
}
#define free_keyword(p) { \
free(*p->keyword); \
filter_list_free(*p->list); \
free(*p); }
static void
filter_user_free(filter_user_t *user)
{
@ -438,7 +478,7 @@ filter_rules_copy(filter_rule_t *rule, const char *argv0, opts_t *opts)
return oom_return(argv0);
}
r->all_sites = rule->all_sites;
r->exact = rule->exact;
r->exact_site = rule->exact_site;
if (rule->port) {
r->port = strdup(rule->port);
@ -563,7 +603,7 @@ filter_rule_str(filter_rule_t *rule)
#ifndef WITHOUT_USERAUTH
STRORNONE(rule->user), STRORNONE(rule->keyword),
#endif /* !WITHOUT_USERAUTH */
rule->exact ? "site" : "", rule->exact_port ? "port" : "", rule->exact_ip ? "ip" : "",
rule->exact_site ? "site" : "", rule->exact_port ? "port" : "", rule->exact_ip ? "ip" : "",
#ifndef WITHOUT_USERAUTH
rule->exact_user ? "user" : "", rule->exact_keyword ? "keyword" : "",
#endif /* !WITHOUT_USERAUTH */
@ -607,33 +647,33 @@ out:
}
static char *
filter_port_str(filter_port_t *port)
filter_port_str(filter_port_list_t *port_list)
{
char *s = NULL;
int count = 0;
while (port) {
while (port_list) {
char *p;
if (asprintf(&p, "%s\n %d: %s (%s%s, action=%s|%s|%s|%s|%s, log=%s|%s|%s|%s|%s"
#ifndef WITHOUT_MIRROR
"|%s"
#endif /* !WITHOUT_MIRROR */
", precedence=%d)", STRORNONE(s), count,
port->port, port->all_ports ? "all_ports, " : "", port->exact ? "exact" : "substring",
port->action.divert ? "divert" : "", port->action.split ? "split" : "", port->action.pass ? "pass" : "", port->action.block ? "block" : "", port->action.match ? "match" : "",
port->action.log_connect ? (port->action.log_connect == 1 ? "!connect" : "connect") : "", port->action.log_master ? (port->action.log_master == 1 ? "!master" : "master") : "",
port->action.log_cert ? (port->action.log_cert == 1 ? "!cert" : "cert") : "", port->action.log_content ? (port->action.log_content == 1 ? "!content" : "content") : "",
port->action.log_pcap ? (port->action.log_pcap == 1 ? "!pcap" : "pcap") : "",
port_list->port->port, port_list->port->all_ports ? "all_ports, " : "", port_list->port->exact ? "exact" : "substring",
port_list->port->action.divert ? "divert" : "", port_list->port->action.split ? "split" : "", port_list->port->action.pass ? "pass" : "", port_list->port->action.block ? "block" : "", port_list->port->action.match ? "match" : "",
port_list->port->action.log_connect ? (port_list->port->action.log_connect == 1 ? "!connect" : "connect") : "", port_list->port->action.log_master ? (port_list->port->action.log_master == 1 ? "!master" : "master") : "",
port_list->port->action.log_cert ? (port_list->port->action.log_cert == 1 ? "!cert" : "cert") : "", port_list->port->action.log_content ? (port_list->port->action.log_content == 1 ? "!content" : "content") : "",
port_list->port->action.log_pcap ? (port_list->port->action.log_pcap == 1 ? "!pcap" : "pcap") : "",
#ifndef WITHOUT_MIRROR
port->action.log_mirror ? (port->action.log_mirror == 1 ? "!mirror" : "mirror") : "",
port_list->port->action.log_mirror ? (port_list->port->action.log_mirror == 1 ? "!mirror" : "mirror") : "",
#endif /* !WITHOUT_MIRROR */
port->action.precedence) < 0) {
port_list->port->action.precedence) < 0) {
goto err;
}
if (s)
free(s);
s = p;
port = port->next;
port_list = port_list->next;
count++;
}
goto out;
@ -646,41 +686,74 @@ out:
return s;
}
#define build_port_list(p) { \
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;
}
}
static char *
filter_sites_str(filter_site_t *site)
filter_sites_str(filter_site_list_t *site_list)
{
char *s = NULL;
int count = 0;
while (site) {
char *ports = filter_port_str(site->port);
while (site_list) {
filter_port_list_t *port = NULL;
if (site_list->site->port_btree)
__kb_traverse(filter_port_p_t, site_list->site->port_btree, build_port_list);
char *ports_exact = filter_port_str(port);
char *ports_substring = filter_port_str(site_list->site->port_list);
char *p;
if (asprintf(&p, "%s\n %d: %s (%s%s, action=%s|%s|%s|%s|%s, log=%s|%s|%s|%s|%s"
#ifndef WITHOUT_MIRROR
"|%s"
#endif /* !WITHOUT_MIRROR */
", precedence=%d)%s%s", STRORNONE(s), count,
site->site, site->all_sites ? "all_sites, " : "", site->exact ? "exact" : "substring",
site->action.divert ? "divert" : "", site->action.split ? "split" : "", site->action.pass ? "pass" : "", site->action.block ? "block" : "", site->action.match ? "match" : "",
site->action.log_connect ? (site->action.log_connect == 1 ? "!connect" : "connect") : "", site->action.log_master ? (site->action.log_master == 1 ? "!master" : "master") : "",
site->action.log_cert ? (site->action.log_cert == 1 ? "!cert" : "cert") : "", site->action.log_content ? (site->action.log_content == 1 ? "!content" : "content") : "",
site->action.log_pcap ? (site->action.log_pcap == 1 ? "!pcap" : "pcap") : "",
", precedence=%d)%s%s%s%s",
STRORNONE(s), count,
site_list->site->site, site_list->site->all_sites ? "all_sites, " : "", site_list->site->exact ? "exact" : "substring",
site_list->site->action.divert ? "divert" : "", site_list->site->action.split ? "split" : "", site_list->site->action.pass ? "pass" : "", site_list->site->action.block ? "block" : "", site_list->site->action.match ? "match" : "",
site_list->site->action.log_connect ? (site_list->site->action.log_connect == 1 ? "!connect" : "connect") : "", site_list->site->action.log_master ? (site_list->site->action.log_master == 1 ? "!master" : "master") : "",
site_list->site->action.log_cert ? (site_list->site->action.log_cert == 1 ? "!cert" : "cert") : "", site_list->site->action.log_content ? (site_list->site->action.log_content == 1 ? "!content" : "content") : "",
site_list->site->action.log_pcap ? (site_list->site->action.log_pcap == 1 ? "!pcap" : "pcap") : "",
#ifndef WITHOUT_MIRROR
site->action.log_mirror ? (site->action.log_mirror == 1 ? "!mirror" : "mirror") : "",
site_list->site->action.log_mirror ? (site_list->site->action.log_mirror == 1 ? "!mirror" : "mirror") : "",
#endif /* !WITHOUT_MIRROR */
site->action.precedence,
ports ? "\n port:" : "", STRORNONE(ports)) < 0) {
if (ports)
free(ports);
site_list->site->action.precedence,
ports_exact ? "\n port exact:" : "", STRORNONE(ports_exact),
ports_substring ? "\n port substring:" : "", STRORNONE(ports_substring)) < 0) {
if (ports_exact) {
free(ports_exact);
filter_tmp_port_list_free(port);
}
if (ports_substring)
free(ports_substring);
goto err;
}
if (ports)
free(ports);
if (ports_exact) {
free(ports_exact);
filter_tmp_port_list_free(port);
}
if (ports_substring)
free(ports_substring);
if (s)
free(s);
s = p;
site = site->next;
site_list = site_list->next;
count++;
}
goto out;
@ -694,63 +767,95 @@ out:
}
static char *
filter_list_str(filter_list_t *list)
filter_list_sub_str(filter_site_list_t *list, char *old_s, const char *name)
{
char *p = NULL;
char *op = NULL;
// @todo Handle oom, don't use STRORNONE()
char *s = filter_sites_str(list->ip);
if (asprintf(&p, " ip: %s", STRORNONE(s)) < 0) {
goto err;
char *new_s = NULL;
char *s = filter_sites_str(list);
if (asprintf(&new_s, "%s%s %s: %s", STRORNONE(old_s), old_s ? "\n" : "", name, STRORNONE(s)) < 0) {
// @todo Handle oom, and don't just use STRORNONE()
new_s = NULL;
}
if (s)
free(s);
op = p;
if (old_s)
free(old_s);
return new_s;
}
s = filter_sites_str(list->sni);
if (asprintf(&p, "%s\n sni: %s", op, STRORNONE(s)) < 0) {
goto err;
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;
}
if (s)
free(s);
free(op);
op = p;
*list = NULL;
}
s = filter_sites_str(list->cn);
if (asprintf(&p, "%s\n cn: %s", op, STRORNONE(s)) < 0) {
goto err;
static char *
filter_list_str(filter_list_t *list)
{
char *s = NULL;
filter_site_list_t *site = NULL;
#define build_site_list(p) { \
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; }
if (list->ip_btree) {
__kb_traverse(filter_site_p_t, list->ip_btree, build_site_list);
s = filter_list_sub_str(site, s, "ip exact");
filter_tmp_site_list_free(&site);
}
if (s)
free(s);
free(op);
op = p;
s = filter_sites_str(list->host);
if (asprintf(&p, "%s\n host: %s", op, STRORNONE(s)) < 0) {
goto err;
if (list->ip_list) {
s = filter_list_sub_str(list->ip_list, s, "ip substring");
}
if (s)
free(s);
free(op);
op = p;
s = filter_sites_str(list->uri);
if (asprintf(&p, "%s\n uri: %s", op, STRORNONE(s)) < 0) {
goto err;
if (list->sni_btree) {
__kb_traverse(filter_site_p_t, list->sni_btree, build_site_list);
s = filter_list_sub_str(site, s, "sni exact");
filter_tmp_site_list_free(&site);
}
goto out;
err:
if (p) {
free(p);
p = NULL;
if (list->sni_list) {
s = filter_list_sub_str(list->sni_list, s, "sni substring");
}
out:
if (s)
free(s);
if (op)
free(op);
return p;
if (list->cn_btree) {
__kb_traverse(filter_site_p_t, list->cn_btree, build_site_list);
s = filter_list_sub_str(site, s, "cn exact");
filter_tmp_site_list_free(&site);
}
if (list->cn_list) {
s = filter_list_sub_str(list->cn_list, s, "cn substring");
}
if (list->host_btree) {
__kb_traverse(filter_site_p_t, list->host_btree, build_site_list);
s = filter_list_sub_str(site, s, "host exact");
filter_tmp_site_list_free(&site);
}
if (list->host_list) {
s = filter_list_sub_str(list->host_list, s, "host substring");
}
if (list->uri_btree) {
__kb_traverse(filter_site_p_t, list->uri_btree, build_site_list);
s = filter_list_sub_str(site, s, "uri exact");
filter_tmp_site_list_free(&site);
}
if (list->uri_list) {
s = filter_list_sub_str(list->uri_list, s, "uri substring");
}
return s;
}
static char *
@ -763,7 +868,8 @@ filter_ip_list_str(filter_ip_list_t *ip_list)
char *list = filter_list_str(ip_list->ip->list);
char *p;
if (asprintf(&p, "%s%s ip %d %s= \n%s", STRORNONE(s), s ? "\n" : "", count, ip_list->ip->ip, STRORNONE(list)) < 0) {
if (asprintf(&p, "%s%s ip %d %s (%s)= \n%s", STRORNONE(s), s ? "\n" : "",
count, ip_list->ip->ip, ip_list->ip->exact ? "exact" : "substring", STRORNONE(list)) < 0) {
if (list)
free(list);
goto err;
@ -832,7 +938,8 @@ filter_user_list_str(filter_user_list_t *user)
// It is possible to have users without any filter rule,
// but the user exists because it has keyword filters
if (list) {
if (asprintf(&p, "%s%s user %d %s= \n%s", STRORNONE(s), s ? "\n" : "", count, user->user->user, list) < 0) {
if (asprintf(&p, "%s%s user %d %s (%s)= \n%s", STRORNONE(s), s ? "\n" : "",
count, user->user->user, user->user->exact ? "exact" : "substring", list) < 0) {
free(list);
goto err;
}
@ -891,7 +998,8 @@ filter_keyword_list_str(filter_keyword_list_t *keyword)
char *list = filter_list_str(keyword->keyword->list);
char *p;
if (asprintf(&p, "%s%s keyword %d %s= \n%s", STRORNONE(s), s ? "\n" : "", count, keyword->keyword->keyword, STRORNONE(list)) < 0) {
if (asprintf(&p, "%s%s keyword %d %s (%s)= \n%s", STRORNONE(s), s ? "\n" : "",
count, keyword->keyword->keyword, keyword->keyword->exact ? "exact" : "substring", STRORNONE(list)) < 0) {
if (list)
free(list);
goto err;
@ -955,7 +1063,11 @@ filter_userkeyword_list_str(filter_user_list_t *user)
char *list_substr = filter_keyword_list_str(user->user->keyword_list);
char *p = NULL;
if (asprintf(&p, "%s%s user %d %s=\n exact=\n%s\n substring=\n%s", STRORNONE(s), s ? "\n" : "", count, user->user->user, STRORNONE(list_exact), STRORNONE(list_substr)) < 0) {
if (asprintf(&p, "%s%s user %d %s (%s)=%s%s%s%s", STRORNONE(s), s ? "\n" : "",
count, user->user->user, user->user->exact ? "exact" : "substring",
list_exact ? "\n keyword exact:\n" : "", STRORNONE(list_exact),
list_substr ? "\n keyword substring:\n" : "", STRORNONE(list_substr)
) < 0) {
if (list_exact)
free(list_exact);
if (list_substr)
@ -1125,7 +1237,7 @@ filter_rule_dbg_print(filter_rule_t *rule)
#ifndef WITHOUT_USERAUTH
STRORNONE(rule->user), STRORNONE(rule->keyword),
#endif /* !WITHOUT_USERAUTH */
rule->exact ? "site" : "", rule->exact_port ? "port" : "", rule->exact_ip ? "ip" : "",
rule->exact_site ? "site" : "", rule->exact_port ? "port" : "", rule->exact_ip ? "ip" : "",
#ifndef WITHOUT_USERAUTH
rule->exact_user ? "user" : "", rule->exact_keyword ? "keyword" : "",
#endif /* !WITHOUT_USERAUTH */
@ -1189,14 +1301,14 @@ filter_passsite_set(opts_t *opts, char *value, int line_num)
}
if (argv[0][len - 1] == '*') {
rule->exact = 0;
rule->exact_site = 0;
len--;
argv[0][len] = '\0';
// site == "*" ?
if (len == 0)
rule->all_sites = 1;
} else {
rule->exact = 1;
rule->exact_site = 1;
}
rule->site = strdup(argv[0]);
@ -1381,14 +1493,14 @@ filter_site_set(filter_rule_t *rule, const char *site, int line_num)
return oom_return_na();
if (rule->site[len - 1] == '*') {
rule->exact = 0;
rule->exact_site = 0;
len--;
rule->site[len] = '\0';
// site == "*" ?
if (len == 0)
rule->all_sites = 1;
} else {
rule->exact = 1;
rule->exact_site = 1;
}
// redundant?
@ -1997,170 +2109,280 @@ filter_rule_set(opts_t *opts, const char *name, char *value, int line_num)
}
static filter_port_t *
filter_port_find(filter_port_t *port, filter_rule_t *rule)
filter_port_btree_exact_match(kbtree_t(port) *port_btree, char *p)
{
while (port) {
if ((port->exact == rule->exact_port) && !strcmp(port->port, rule->port))
if (!port_btree)
return NULL;
filter_port_t **port = kb_get(port, port_btree, p);
return port ? *port : NULL;
}
static filter_port_t *
filter_port_list_substring_match(filter_port_list_t *list, char *p)
{
while (list) {
if (strstr(p, list->port->port))
break;
list = list->next;
}
return list ? list->port : NULL;
}
filter_port_t *
filter_port_find(filter_site_t *site, char *p)
{
filter_port_t *port = filter_port_btree_exact_match(site->port_btree, p);
if (port)
return port;
return filter_port_list_substring_match(site->port_list, p);
}
static filter_port_t *
filter_port_list_exact_match(filter_port_list_t *list, char *p)
{
while (list) {
if (!strcmp(list->port->port, p))
break;
port = port->next;
list = list->next;
}
return port;
return list ? list->port : NULL;
}
static filter_port_t *
filter_rule_port_find(filter_site_t *site, filter_rule_t *rule)
{
if (rule->exact_port)
return filter_port_btree_exact_match(site->port_btree, rule->port);
else
return filter_port_list_exact_match(site->port_list, rule->port);
}
static int NONNULL(1,2) WUNRES
filter_port_add(filter_port_t **port, filter_rule_t *rule)
filter_port_add(filter_site_t *site, filter_rule_t *rule)
{
filter_port_t *p = filter_port_find(*port, rule);
if (!p) {
p = malloc(sizeof(filter_port_t));
if (!p)
filter_port_t *port = filter_rule_port_find(site, rule);
if (!port) {
port = malloc(sizeof(filter_port_t));
if (!port)
return oom_return_na();
memset(p, 0, sizeof(filter_port_t));
p->port = strdup(rule->port);
if (!p->port)
memset(port, 0, sizeof(filter_port_t));
port->port = strdup(rule->port);
if (!port->port)
return oom_return_na();
// all_ports should be at the end of the port list, it has the lowest precedence
filter_port_t *prev = NULL;
filter_port_t *l = *port;
while (l) {
if (l->all_ports)
break;
prev = l;
l = l->next;
}
if (rule->exact_port) {
if (!site->port_btree)
if (!(site->port_btree = kb_init(port, KB_DEFAULT_SIZE)))
return oom_return_na();
if (prev) {
p->next = prev->next;
prev->next = p;
kb_put(port, site->port_btree, port);
}
else {
if (*port)
p->next = *port;
*port = p;
filter_port_list_t *port_list = malloc(sizeof(filter_port_list_t));
if (!port_list)
return oom_return_na();
memset(port_list, 0, sizeof(filter_port_list_t));
port_list->port = port;
// all_ports should be at the end of the port list, it has the lowest precedence
filter_port_list_t *prev = NULL;
filter_port_list_t *l = site->port_list;
while (l) {
if (l->port->all_ports)
break;
prev = l;
l = l->next;
}
if (prev) {
port_list->next = prev->next;
prev->next = port_list;
}
else {
if (site->port_list)
port_list->next = site->port_list;
site->port_list = port_list;
}
}
}
port->all_ports = rule->all_ports;
port->exact = rule->exact_port;
// Do not override the specs of port rules at higher precedence
// precedence can only go up not down
if (rule->action.precedence >= p->action.precedence) {
p->all_ports = rule->all_ports;
p->exact = rule->exact_port;
if (rule->action.precedence >= port->action.precedence) {
// Multiple rules can set an action for the same port, hence the bit-wise OR
p->action.divert |= rule->action.divert;
p->action.split |= rule->action.split;
p->action.pass |= rule->action.pass;
p->action.block |= rule->action.block;
p->action.match |= rule->action.match;
port->action.divert |= rule->action.divert;
port->action.split |= rule->action.split;
port->action.pass |= rule->action.pass;
port->action.block |= rule->action.block;
port->action.match |= rule->action.match;
// Multiple log actions can be set for the same port
// Multiple rules can enable/disable or don't change a log action for the same port
// 0: don't change, 1: disable, 2: enable
if (rule->action.log_connect)
p->action.log_connect = rule->action.log_connect;
port->action.log_connect = rule->action.log_connect;
if (rule->action.log_master)
p->action.log_master = rule->action.log_master;
port->action.log_master = rule->action.log_master;
if (rule->action.log_cert)
p->action.log_cert = rule->action.log_cert;
port->action.log_cert = rule->action.log_cert;
if (rule->action.log_content)
p->action.log_content = rule->action.log_content;
port->action.log_content = rule->action.log_content;
if (rule->action.log_pcap)
p->action.log_pcap = rule->action.log_pcap;
port->action.log_pcap = rule->action.log_pcap;
#ifndef WITHOUT_MIRROR
if (rule->action.log_mirror)
p->action.log_mirror = rule->action.log_mirror;
port->action.log_mirror = rule->action.log_mirror;
#endif /* !WITHOUT_MIRROR */
p->action.precedence = rule->action.precedence;
port->action.precedence = rule->action.precedence;
}
return 0;
}
filter_site_t *
filter_site_btree_exact_match(kbtree_t(site) *site_btree, char *s)
{
if (!site_btree)
return NULL;
filter_site_t **site = kb_get(site, site_btree, s);
return site ? *site : NULL;
}
filter_site_t *
filter_site_list_substring_match(filter_site_list_t *list, char *s)
{
while (list) {
if (strstr(s, list->site->site))
break;
list = list->next;
}
return list ? list->site : NULL;
}
filter_site_t *
filter_site_find(kbtree_t(site) *site_btree, filter_site_list_t *list, char *s)
{
filter_site_t *site = filter_site_btree_exact_match(site_btree, s);
if (site)
return site;
return filter_site_list_substring_match(list, s);
}
static filter_site_t *
filter_site_find(filter_site_t *site, filter_rule_t *rule)
filter_site_list_exact_match(filter_site_list_t *list, char *s)
{
while (site) {
if ((site->exact == rule->exact) && !strcmp(site->site, rule->site))
while (list) {
if (!strcmp(list->site->site, s))
break;
site = site->next;
list = list->next;
}
return site;
return list ? list->site : NULL;
}
static int NONNULL(1,2) WUNRES
filter_site_add(filter_site_t **site, filter_rule_t *rule)
static filter_site_t *
filter_rule_site_find(kbtree_t(site) *site_btree, filter_site_list_t *list, filter_rule_t *rule)
{
filter_site_t *s = filter_site_find(*site, rule);
if (!s) {
s = malloc(sizeof(filter_site_t));
if (!s)
if (rule->exact_site)
return filter_site_btree_exact_match(site_btree, rule->site);
else
return filter_site_list_exact_match(list, rule->site);
}
static int NONNULL(3) WUNRES
filter_site_add(kbtree_t(site) **site_btree, filter_site_list_t **site_list, filter_rule_t *rule)
{
filter_site_t *site = filter_rule_site_find(*site_btree, *site_list, rule);
if (!site) {
site = malloc(sizeof(filter_site_t));
if (!site)
return oom_return_na();
memset(s, 0, sizeof(filter_site_t));
s->site = strdup(rule->site);
if (!s->site)
memset(site, 0, sizeof(filter_site_t));
site->site = strdup(rule->site);
if (!site->site)
return oom_return_na();
// all_sites should be at the end of the site list, it has the lowest precedence
filter_site_t *prev = NULL;
filter_site_t *l = *site;
while (l) {
if (l->all_sites)
break;
prev = l;
l = l->next;
}
if (rule->exact_site) {
if (!*site_btree)
if (!(*site_btree = kb_init(site, KB_DEFAULT_SIZE)))
return oom_return_na();
if (prev) {
s->next = prev->next;
prev->next = s;
kb_put(site, *site_btree, site);
}
else {
if (*site)
s->next = *site;
*site = s;
filter_site_list_t *list = malloc(sizeof(filter_site_list_t));
if (!list)
return oom_return_na();
memset(list, 0, sizeof(filter_site_list_t));
list->site = site;
// all_sites should be at the end of the site list, it has the lowest precedence
filter_site_list_t *prev = NULL;
filter_site_list_t *l = *site_list;
while (l) {
if (l->site->all_sites)
break;
prev = l;
l = l->next;
}
if (prev) {
list->next = prev->next;
prev->next = list;
}
else {
if (*site_list)
list->next = *site_list;
*site_list = list;
}
}
}
s->all_sites = rule->all_sites;
s->exact = rule->exact;
site->all_sites = rule->all_sites;
site->exact = rule->exact_site;
// Do not override the specs of a site with a port rule
// Port rule is added as a new port under the same site
// hence 'if else', not just 'if'
if (rule->port) {
if (filter_port_add(&s->port, rule) == -1)
if (filter_port_add(site, rule) == -1)
return -1;
}
// Do not override the specs of site rules at higher precedence
// precedence can only go up not down
else if (rule->action.precedence >= s->action.precedence) {
else if (rule->action.precedence >= site->action.precedence) {
// Multiple rules can set an action for the same site, hence the bit-wise OR
s->action.divert |= rule->action.divert;
s->action.split |= rule->action.split;
s->action.pass |= rule->action.pass;
s->action.block |= rule->action.block;
s->action.match |= rule->action.match;
site->action.divert |= rule->action.divert;
site->action.split |= rule->action.split;
site->action.pass |= rule->action.pass;
site->action.block |= rule->action.block;
site->action.match |= rule->action.match;
// Multiple log actions can be set for the same site
// Multiple rules can enable/disable or don't change a log action for the same site
// 0: don't change, 1: disable, 2: enable
if (rule->action.log_connect)
s->action.log_connect = rule->action.log_connect;
site->action.log_connect = rule->action.log_connect;
if (rule->action.log_master)
s->action.log_master = rule->action.log_master;
site->action.log_master = rule->action.log_master;
if (rule->action.log_cert)
s->action.log_cert = rule->action.log_cert;
site->action.log_cert = rule->action.log_cert;
if (rule->action.log_content)
s->action.log_content = rule->action.log_content;
site->action.log_content = rule->action.log_content;
if (rule->action.log_pcap)
s->action.log_pcap = rule->action.log_pcap;
site->action.log_pcap = rule->action.log_pcap;
#ifndef WITHOUT_MIRROR
if (rule->action.log_mirror)
s->action.log_mirror = rule->action.log_mirror;
site->action.log_mirror = rule->action.log_mirror;
#endif /* !WITHOUT_MIRROR */
s->action.precedence = rule->action.precedence;
site->action.precedence = rule->action.precedence;
}
return 0;
}
@ -2169,23 +2391,23 @@ static int
filter_sitelist_add(filter_list_t *list, filter_rule_t *rule)
{
if (rule->dstip) {
if (filter_site_add(&list->ip, rule) == -1)
if (filter_site_add(&list->ip_btree, &list->ip_list, rule) == -1)
return -1;
}
if (rule->sni) {
if (filter_site_add(&list->sni, rule) == -1)
if (filter_site_add(&list->sni_btree, &list->sni_list, rule) == -1)
return -1;
}
if (rule->cn) {
if (filter_site_add(&list->cn, rule) == -1)
if (filter_site_add(&list->cn_btree, &list->cn_list, rule) == -1)
return -1;
}
if (rule->host) {
if (filter_site_add(&list->host, rule) == -1)
if (filter_site_add(&list->host_btree, &list->host_list, rule) == -1)
return -1;
}
if (rule->uri) {
if (filter_site_add(&list->uri, rule) == -1)
if (filter_site_add(&list->uri_btree, &list->uri_list, rule) == -1)
return -1;
}
return 0;
@ -2259,6 +2481,8 @@ filter_ip_get(filter_t *filter, filter_rule_t *rule)
if (!ip->ip)
return oom_return_na_null();
ip->exact = rule->exact_ip;
if (rule->exact_ip) {
if (!filter->ip_btree)
if (!(filter->ip_btree = kb_init(ip, KB_DEFAULT_SIZE)))
@ -2350,6 +2574,8 @@ filter_keyword_get(filter_t *filter, filter_user_t *user, filter_rule_t *rule)
if (!keyword->keyword)
return oom_return_na_null();
keyword->exact = rule->exact_keyword;
if (rule->exact_keyword) {
if (user) {
if (!user->keyword_btree)
@ -2448,6 +2674,8 @@ filter_user_get(filter_t *filter, filter_rule_t *rule)
if (!user->user)
return oom_return_na_null();
user->exact = rule->exact_user;
if (rule->exact_user) {
if (!filter->user_btree)
if (!(filter->user_btree = kb_init(user, KB_DEFAULT_SIZE)))
@ -2543,9 +2771,9 @@ filter_set(filter_rule_t *rule)
filter_user_p_t x, y = NULL;
__kb_traverse(filter_user_p_t, filter->user_btree, traverse_user);
__kb_get_first(filter_user_p_t, filter->user_btree, x);
printf("user_exact # of elements from traversal: %d\n", cnt);
fprintf(stderr, "user_exact # of elements from traversal: %d\n", cnt);
if (cnt)
printf("user_exact first element: %s == %s\n", x->user, y->user);
fprintf(stderr, "user_exact first element: %s == %s\n", x->user, y->user);
}
#define traverse_keyword(p) { if (cnt == 0) y2 = *p; ++cnt; }
if (filter->keyword_btree) {
@ -2553,9 +2781,9 @@ filter_set(filter_rule_t *rule)
filter_keyword_p_t x2, y2 = NULL;
__kb_traverse(filter_keyword_p_t, filter->keyword_btree, traverse_keyword);
__kb_get_first(filter_keyword_p_t, filter->keyword_btree, x2);
printf("keyword_exact # of elements from traversal: %d\n", cnt);
fprintf(stderr, "keyword_exact # of elements from traversal: %d\n", cnt);
if (cnt)
printf("keyword_exact first element: %s == %s\n", x2->keyword, y2->keyword);
fprintf(stderr, "keyword_exact first element: %s == %s\n", x2->keyword, y2->keyword);
}
#define traverse_ip(p) { if (cnt == 0) y3 = *p; ++cnt; }
if (filter->ip_btree) {
@ -2563,9 +2791,9 @@ filter_set(filter_rule_t *rule)
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);
printf("ip_exact # of elements from traversal: %d\n", cnt);
fprintf(stderr, "ip_exact # of elements from traversal: %d\n", cnt);
if (cnt)
printf("ip_exact first element: %s == %s\n", x3->ip, y3->ip);
fprintf(stderr, "ip_exact first element: %s == %s\n", x3->ip, y3->ip);
}
#endif /* DEBUG_OPTS */
return filter;

@ -91,13 +91,13 @@ typedef struct filter_action {
typedef struct filter_rule {
// from: source filter
unsigned int all_conns : 1; /* 1 to apply to all src ips and users */
unsigned int all_conns : 1; /* 1 to apply to all src ips and users */
#ifndef WITHOUT_USERAUTH
unsigned int all_users : 1; /* 1 to apply to all users */
unsigned int all_users : 1; /* 1 to apply to all users */
char *user;
unsigned int exact_user : 1; /* 1 for exact, 0 for substring match */
unsigned int exact_user : 1; /* 1 for exact, 0 for substring match */
char *keyword;
unsigned int exact_keyword : 1; /* 1 for exact, 0 for substring match */
@ -109,7 +109,7 @@ typedef struct filter_rule {
// to: target filter
char *site;
unsigned int all_sites : 1; /* 1 to match all sites == '*' */
unsigned int exact : 1; /* 1 for exact, 0 for substring match */
unsigned int exact_site : 1; /* 1 for exact, 0 for substring match */
// Used with dstip filters only, i.e. if the site is an ip address
// This is not for the src ip in the 'from' part of rules
@ -132,36 +132,63 @@ typedef struct filter_rule {
typedef struct filter_port {
char *port;
unsigned int all_ports : 1;
unsigned int exact : 1;
unsigned int exact : 1; /* used in debug logging only */
struct filter_action action;
struct filter_port *next;
} filter_port_t;
typedef const char *str_t;
#define getk_port(a) (a)->port
typedef filter_port_t *filter_port_p_t;
KBTREE_INIT(port, filter_port_p_t, kb_str_cmp, str_t, getk_port)
typedef struct filter_port_list {
struct filter_port *port;
struct filter_port_list *next;
} filter_port_list_t;
typedef struct filter_site {
char *site;
unsigned int all_sites : 1;
unsigned int exact : 1;
unsigned int exact : 1; /* used in debug logging only */
// Used with dstip filters only, i.e. if the site is an ip address
struct filter_port *port;
kbtree_t(port) *port_btree;
struct filter_port_list *port_list;
struct filter_action action;
struct filter_site *next;
} filter_site_t;
#define getk_site(a) (a)->site
typedef filter_site_t *filter_site_p_t;
KBTREE_INIT(site, filter_site_p_t, kb_str_cmp, str_t, getk_site)
typedef struct filter_site_list {
struct filter_site *site;
struct filter_site_list *next;
} filter_site_list_t;
typedef struct filter_list {
struct filter_site *ip;
struct filter_site *sni;
struct filter_site *cn;
struct filter_site *host;
struct filter_site *uri;
kbtree_t(site) *ip_btree;
struct filter_site_list *ip_list;
kbtree_t(site) *sni_btree;
struct filter_site_list *sni_list;
kbtree_t(site) *cn_btree;
struct filter_site_list *cn_list;
kbtree_t(site) *host_btree;
struct filter_site_list *host_list;
kbtree_t(site) *uri_btree;
struct filter_site_list *uri_list;
} filter_list_t;
typedef struct filter_ip {
char *ip;
unsigned int exact : 1; /* used in debug logging only */
struct filter_list *list;
} filter_ip_t;
@ -173,11 +200,10 @@ typedef struct filter_ip_list {
#ifndef WITHOUT_USERAUTH
typedef struct filter_keyword {
char *keyword;
unsigned int exact : 1; /* used in debug logging only */
struct filter_list *list;
} filter_keyword_t;
typedef const char *str_t;
#define getk_keyword(a) (a)->keyword
typedef filter_keyword_t *filter_keyword_p_t;
KBTREE_INIT(keyword, filter_keyword_p_t, kb_str_cmp, str_t, getk_keyword)
@ -189,6 +215,7 @@ typedef struct filter_keyword_list {
typedef struct filter_user {
char *user;
unsigned int exact : 1; /* used in debug logging only */
struct filter_list *list;
kbtree_t(keyword) *keyword_btree;
struct filter_keyword_list *keyword_list;
@ -210,17 +237,17 @@ KBTREE_INIT(ip, filter_ip_p_t, kb_str_cmp, str_t, getk_ip)
typedef struct filter {
#ifndef WITHOUT_USERAUTH
kbtree_t(user) *user_btree; // exact
struct filter_user_list *user_list; // substring
kbtree_t(user) *user_btree; /* exact */
struct filter_user_list *user_list; /* substring */
kbtree_t(keyword) *keyword_btree; // exact
struct filter_keyword_list *keyword_list; // substring
kbtree_t(keyword) *keyword_btree; /* exact */
struct filter_keyword_list *keyword_list; /* substring */
struct filter_list *all_user;
#endif /* !WITHOUT_USERAUTH */
kbtree_t(ip) *ip_btree; // exact
struct filter_ip_list *ip_list; // substring
kbtree_t(ip) *ip_btree; /* exact */
struct filter_ip_list *ip_list; /* substring */
struct filter_list *all;
} filter_t;
@ -246,6 +273,12 @@ char *filter_str(filter_t *);
int filter_passsite_set(opts_t *, char *, int) WUNRES;
int filter_macro_set(opts_t *, char *, int) WUNRES;
filter_port_t *filter_port_find(filter_site_t *, char *) NONNULL(1,2);
filter_site_t *filter_site_btree_exact_match(kbtree_t(site) *, char *);
filter_site_t *filter_site_list_substring_match(filter_site_list_t *, char *);
filter_site_t *filter_site_find(kbtree_t(site) *, filter_site_list_t *, char *) NONNULL(3) WUNRES;
filter_ip_t *filter_ip_find(filter_t *, char *) NONNULL(1,2);
#ifndef WITHOUT_USERAUTH
filter_keyword_t *filter_keyword_find(filter_t *, filter_user_t *, char *) NONNULL(1,3);

@ -386,60 +386,76 @@ protohttp_filter_request_header_line(const char *line, protohttp_ctx_t *http_ctx
return (char*)line;
}
static int NONNULL(1,2)
protohttp_filter_match_host(pxy_conn_ctx_t *ctx, filter_site_t *site)
static filter_action_t * NONNULL(1,2)
protohttp_filter_match_host(pxy_conn_ctx_t *ctx, filter_list_t *list)
{
protohttp_ctx_t *http_ctx = ctx->protoctx->arg;
filter_site_t *site = filter_site_find(list->host_btree, list->host_list, http_ctx->http_host);
if (!site)
return NULL;
#ifndef WITHOUT_USERAUTH
log_fine_va("Found site: %s for %s:%s, %s:%s, %s, %s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(http_ctx->http_host));
#else /* WITHOUT_USERAUTH */
log_fine_va("Found site: %s for %s:%s, %s:%s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(http_ctx->http_host));
#endif /* WITHOUT_USERAUTH */
if (site->action.precedence < ctx->filter_precedence) {
log_finest_va("Rule precedence lower than conn filter precedence %d < %d: %s, %s", site->action.precedence, ctx->filter_precedence, site->site, http_ctx->http_host);
return 0;
return NULL;
}
if (site->all_sites) {
#ifdef DEBUG_PROXY
if (site->all_sites)
log_finest_va("Match all host: %s, %s", site->site, http_ctx->http_host);
return 1;
}
else if (site->exact) {
if (http_ctx->http_host && !strcmp(http_ctx->http_host, site->site)) {
log_finest_va("Match exact with host: %s, %s", site->site, http_ctx->http_host);
return 1;
}
} else {
if (http_ctx->http_host && strstr(http_ctx->http_host, site->site)) {
log_finest_va("Match substring in host: %s, %s", site->site, http_ctx->http_host);
return 1;
}
}
return 0;
else if (site->exact)
log_finest_va("Match exact with host: %s, %s", site->site, http_ctx->http_host);
else
log_finest_va("Match substring in host: %s, %s", site->site, http_ctx->http_host);
#endif /* DEBUG_PROXY */
return &site->action;
}
static int NONNULL(1,2)
protohttp_filter_match_uri(pxy_conn_ctx_t *ctx, filter_site_t *site)
static filter_action_t * NONNULL(1,2)
protohttp_filter_match_uri(pxy_conn_ctx_t *ctx, filter_list_t *list)
{
protohttp_ctx_t *http_ctx = ctx->protoctx->arg;
filter_site_t *site = filter_site_find(list->uri_btree, list->uri_list, http_ctx->http_uri);
if (!site)
return NULL;
#ifndef WITHOUT_USERAUTH
log_fine_va("Found site: %s for %s:%s, %s:%s, %s, %s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(http_ctx->http_uri));
#else /* WITHOUT_USERAUTH */
log_fine_va("Found site: %s for %s:%s, %s:%s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(http_ctx->http_uri));
#endif /* WITHOUT_USERAUTH */
if (site->action.precedence < ctx->filter_precedence) {
log_finest_va("Rule precedence lower than conn filter precedence %d < %d: %s, %s", site->action.precedence, ctx->filter_precedence, site->site, http_ctx->http_uri);
return 0;
return NULL;
}
if (site->all_sites) {
#ifdef DEBUG_PROXY
if (site->all_sites)
log_finest_va("Match all uri: %s, %s", site->site, http_ctx->http_uri);
return 1;
}
else if (site->exact) {
if (!strcmp(http_ctx->http_uri, site->site)) {
log_finest_va("Match exact with uri: %s, %s", site->site, http_ctx->http_uri);
return 1;
}
} else {
if (strstr(http_ctx->http_uri, site->site)) {
log_finest_va("Match substring in uri: %s, %s", site->site, http_ctx->http_uri);
return 1;
}
}
return 0;
else if (site->exact)
log_finest_va("Match exact with uri: %s, %s", site->site, http_ctx->http_uri);
else
log_finest_va("Match substring in uri: %s, %s", site->site, http_ctx->http_uri);
#endif /* DEBUG_PROXY */
return &site->action;
}
static unsigned int NONNULL(1,2)
@ -448,21 +464,9 @@ protohttp_filter(pxy_conn_ctx_t *ctx, filter_list_t *list)
protohttp_ctx_t *http_ctx = ctx->protoctx->arg;
if (http_ctx->http_host) {
filter_site_t *site = list->host;
while (site) {
if (protohttp_filter_match_host(ctx, site)) {
#ifndef WITHOUT_USERAUTH
log_fine_va("Found site: %s for %s:%s, %s:%s, %s, %s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(http_ctx->http_host));
#else /* WITHOUT_USERAUTH */
log_fine_va("Found site: %s for %s:%s, %s:%s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(http_ctx->http_host));
#endif /* WITHOUT_USERAUTH */
return pxyconn_set_filter_action(ctx, site->action, site->site);
}
site = site->next;
filter_action_t *action;
if ((action = protohttp_filter_match_host(ctx, list))) {
return pxyconn_set_filter_action(ctx, action, http_ctx->http_host);
}
#ifndef WITHOUT_USERAUTH
log_finest_va("No filter match with host: %s:%s, %s:%s, %s, %s, %s, %s",
@ -476,21 +480,9 @@ protohttp_filter(pxy_conn_ctx_t *ctx, filter_list_t *list)
}
if (http_ctx->http_uri) {
filter_site_t *site = list->uri;
while (site) {
if (protohttp_filter_match_uri(ctx, site)) {
#ifndef WITHOUT_USERAUTH
log_fine_va("Found site: %s for %s:%s, %s:%s, %s, %s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(http_ctx->http_uri));
#else /* WITHOUT_USERAUTH */
log_fine_va("Found site: %s for %s:%s, %s:%s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(http_ctx->http_uri));
#endif /* WITHOUT_USERAUTH */
return pxyconn_set_filter_action(ctx, site->action, site->site);
}
site = site->next;
filter_action_t *action;
if ((action = protohttp_filter_match_uri(ctx, list))) {
return pxyconn_set_filter_action(ctx, action, http_ctx->http_uri);
}
#ifndef WITHOUT_USERAUTH
log_finest_va("No filter match with uri: %s:%s, %s:%s, %s, %s, %s, %s",

@ -590,121 +590,117 @@ protossl_srccert_create(pxy_conn_ctx_t *ctx)
return cert;
}
static int NONNULL(1,2)
protossl_filter_match_sni(pxy_conn_ctx_t *ctx, filter_site_t *site)
static filter_action_t * NONNULL(1,2)
protossl_filter_match_sni(pxy_conn_ctx_t *ctx, filter_list_t *list)
{
filter_site_t *site = filter_site_find(list->sni_btree, list->sni_list, ctx->sslctx->sni);
if (!site)
return NULL;
#ifndef WITHOUT_USERAUTH
log_fine_va("Found site: %s for %s:%s, %s:%s, %s, %s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(ctx->sslctx->sni));
#else /* WITHOUT_USERAUTH */
log_fine_va("Found site: %s for %s:%s, %s:%s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->sslctx->sni));
#endif /* WITHOUT_USERAUTH */
if (site->action.precedence < ctx->filter_precedence) {
log_finest_va("Rule precedence lower than conn filter precedence %d < %d: %s, %s", site->action.precedence, ctx->filter_precedence, site->site, ctx->sslctx->sni);
return 0;
return NULL;
}
if (site->all_sites) {
#ifdef DEBUG_PROXY
if (site->all_sites)
log_finest_va("Match all sni: %s, %s", site->site, ctx->sslctx->sni);
return 1;
}
else if (site->exact) {
if (!strcmp(ctx->sslctx->sni, site->site)) {
log_finest_va("Match exact with sni: %s, %s", site->site, ctx->sslctx->sni);
return 1;
}
} else {
if (strstr(ctx->sslctx->sni, site->site)) {
log_finest_va("Match substring in sni: %s, %s", site->site, ctx->sslctx->sni);
return 1;
}
}
return 0;
else if (site->exact)
log_finest_va("Match exact with sni: %s, %s", site->site, ctx->sslctx->sni);
else
log_finest_va("Match substring in sni: %s, %s", site->site, ctx->sslctx->sni);
#endif /* DEBUG_PROXY */
return &site->action;
}
static int NONNULL(1,2)
protossl_filter_match_cn(pxy_conn_ctx_t *ctx, filter_site_t *site)
static filter_action_t * NONNULL(1,2)
protossl_filter_match_cn(pxy_conn_ctx_t *ctx, filter_list_t *list)
{
if (site->action.precedence < ctx->filter_precedence) {
log_finest_va("Rule precedence lower than conn filter precedence %d < %d: %s, %s", site->action.precedence, ctx->filter_precedence, site->site, ctx->sslctx->ssl_names);
return 0;
}
filter_site_t *site = NULL;
if (site->all_sites) {
log_finest_va("Match all common names: %s, %s", site->site, ctx->sslctx->ssl_names);
return 1;
}
else if (site->exact) {
// Avoid multithreading issues by copying the site arg to a local var
// site arg is from the spec filter, which may be being used by other threads
// ballpark figures
#define MAX_CN_LEN 2048
#define MAX_CN_TOKENS 50
size_t len = strlen(site->site);
int argc = 0;
char *p, *last = NULL;
// Common names are separated by slashes
char _site[len + 3];
memcpy(_site + 1, site->site, len);
_site[0] = '/';
_site[len + 1] = '/';
_site[len + 2] = '\0';
len += 2;
size_t len = strlen(ctx->sslctx->ssl_names);
// Skip the first slash
char *s = _site + 1;
if (len > MAX_CN_LEN) {
log_err_level_printf(LOG_WARNING, "Skip too long common names, max len %d: %s\n", MAX_CN_LEN, ctx->sslctx->ssl_names);
return NULL;
}
// Replace the last slash with null
_site[len - 1] = '\0';
// strtok_r() modifies the string param, so copy ssl_names to a local var and pass it to strtok_r()
char _cn[len + 1];
memcpy(_cn, ctx->sslctx->ssl_names, len);
_cn[len] = '\0';
// Single common name: "example.com"
if (!strcmp(ctx->sslctx->ssl_names, s)) {
log_finest_va("Match exact with single common name: %s", ctx->sslctx->ssl_names);
return 1;
for ((p = strtok_r(_cn, "/", &last));
p;
(p = strtok_r(NULL, "/", &last))) {
if (argc < MAX_CN_TOKENS) {
site = filter_site_btree_exact_match(list->cn_btree, p);
if (site) {
log_finest_va("Match exact with common name: %s, %s", p, ctx->sslctx->ssl_names);
break;
}
}
// Restore the slash at the end
_site[len - 1] = '/';
// First common name: "example.com/"
if (strstr(ctx->sslctx->ssl_names, s) == ctx->sslctx->ssl_names) {
log_finest_va("Match exact with the first common name: %s, %s", ctx->sslctx->ssl_names, s);
return 1;
else {
log_err_level_printf(LOG_WARNING, "Too many tokens in common names, max tokens %d: %s\n", MAX_CN_TOKENS, ctx->sslctx->ssl_names);
break;
}
}
// Middle common name: "/example.com/"
if (strstr(ctx->sslctx->ssl_names, _site)) {
log_finest_va("Match exact with a middle common name: %s, %s", ctx->sslctx->ssl_names, _site);
return 1;
}
if (!site) {
site = filter_site_list_substring_match(list->cn_list, ctx->sslctx->ssl_names);
if (site)
log_finest_va("Match substring in common names: %s, %s", site->site, ctx->sslctx->ssl_names);
}
// Replace the last slash with null
_site[len - 1] = '\0';
if (!site)
return NULL;
// Last common name: "/example.com"
if (strstr(ctx->sslctx->ssl_names, _site) == ctx->sslctx->ssl_names + strlen(ctx->sslctx->ssl_names) - strlen(_site)) {
log_finest_va("Match exact with the last common name: %s, %s", ctx->sslctx->ssl_names, _site);
return 1;
}
} else {
if (strstr(ctx->sslctx->ssl_names, site->site)) {
log_finest_va("Match substring in common names: %s, %s", site->site, ctx->sslctx->ssl_names);
return 1;
}
#ifndef WITHOUT_USERAUTH
log_fine_va("Found site: %s for %s:%s, %s:%s, %s, %s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(ctx->sslctx->ssl_names));
#else /* WITHOUT_USERAUTH */
log_fine_va("Found site: %s for %s:%s, %s:%s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->sslctx->ssl_names));
#endif /* WITHOUT_USERAUTH */
if (site->action.precedence < ctx->filter_precedence) {
log_finest_va("Rule precedence lower than conn filter precedence %d < %d: %s, %s", site->action.precedence, ctx->filter_precedence, site->site, ctx->sslctx->ssl_names);
return NULL;
}
return 0;
if (site->all_sites)
log_finest_va("Match all common names: %s, %s", site->site, ctx->sslctx->ssl_names);
return &site->action;
}
static unsigned int NONNULL(1,2)
protossl_filter(pxy_conn_ctx_t *ctx, filter_list_t *list)
{
if (ctx->sslctx->sni) {
filter_site_t *site = list->sni;
while (site) {
if (protossl_filter_match_sni(ctx, site)) {
#ifndef WITHOUT_USERAUTH
log_fine_va("Found site: %s for %s:%s, %s:%s, %s, %s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(ctx->sslctx->sni));
#else /* WITHOUT_USERAUTH */
log_fine_va("Found site: %s for %s:%s, %s:%s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->sslctx->sni));
#endif /* WITHOUT_USERAUTH */
return pxyconn_set_filter_action(ctx, site->action, site->site);
}
site = site->next;
filter_action_t *action;
if ((action = protossl_filter_match_sni(ctx, list))) {
return pxyconn_set_filter_action(ctx, action, ctx->sslctx->sni);
}
#ifndef WITHOUT_USERAUTH
log_finest_va("No filter match with sni: %s:%s, %s:%s, %s, %s, %s, %s",
@ -718,21 +714,9 @@ protossl_filter(pxy_conn_ctx_t *ctx, filter_list_t *list)
}
if (ctx->sslctx->ssl_names) {
filter_site_t *site = list->cn;
while (site) {
if (protossl_filter_match_cn(ctx, site)) {
#ifndef WITHOUT_USERAUTH
log_fine_va("Found site: %s for %s:%s, %s:%s, %s, %s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->user), STRORDASH(ctx->desc), STRORDASH(ctx->sslctx->ssl_names));
#else /* WITHOUT_USERAUTH */
log_fine_va("Found site: %s for %s:%s, %s:%s, %s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str),
STRORDASH(ctx->sslctx->ssl_names));
#endif /* WITHOUT_USERAUTH */
return pxyconn_set_filter_action(ctx, site->action, site->site);
}
site = site->next;
filter_action_t *action;
if ((action = protossl_filter_match_cn(ctx, list))) {
return pxyconn_set_filter_action(ctx, action, ctx->sslctx->ssl_names);
}
#ifndef WITHOUT_USERAUTH
log_finest_va("No filter match with common names: %s:%s, %s:%s, %s, %s, %s, %s",

@ -516,71 +516,56 @@ prototcp_filter_match_port(pxy_conn_ctx_t *ctx, filter_port_t *port)
return 0;
}
if (port->all_ports) {
#ifdef DEBUG_PROXY
if (port->all_ports)
log_finest_va("Match all dst ports: %s, %s", port->port, ctx->dstport_str);
return 1;
}
else if (port->exact) {
if (!strcmp(ctx->dstport_str, port->port)) {
log_finest_va("Match exact with port: %s, %s", port->port, ctx->dstport_str);
return 1;
}
}
else {
if (strstr(ctx->dstport_str, port->port)) {
log_finest_va("Match substring in dst port: %s, %s", port->port, ctx->dstport_str);
return 1;
}
}
return 0;
else if (port->exact)
log_finest_va("Match exact with port: %s, %s", port->port, ctx->dstport_str);
else
log_finest_va("Match substring in dst port: %s, %s", port->port, ctx->dstport_str);
#endif /* DEBUG_PROXY */
return 1;
}
static filter_action_t * NONNULL(1,2)
prototcp_filter_match_ip(pxy_conn_ctx_t *ctx, filter_site_t *site)
prototcp_filter_match_ip(pxy_conn_ctx_t *ctx, filter_list_t *list)
{
filter_site_t *site = filter_site_find(list->ip_btree, list->ip_list, ctx->dsthost_str);
if (!site)
return NULL;
log_fine_va("Found site: %s for %s:%s, %s:%s", site->site,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str));
// Port spec determines the precedence of a site rule, unless the rule does not have any port
if (!site->port && (site->action.precedence < ctx->filter_precedence)) {
if (!site->port_list && (site->action.precedence < ctx->filter_precedence)) {
log_finest_va("Rule precedence lower than conn filter precedence %d < %d: %s, %s", site->action.precedence, ctx->filter_precedence, site->site, ctx->dsthost_str);
return NULL;
}
filter_action_t *action = NULL;
filter_action_t *action = &site->action;
if (site->all_sites) {
#ifdef DEBUG_PROXY
if (site->all_sites)
log_finest_va("Match all dst: %s, %s", site->site, ctx->dsthost_str);
action = &site->action;
}
else if (site->exact) {
if (!strcmp(ctx->dsthost_str, site->site)) {
log_finest_va("Match exact with dst: %s, %s", site->site, ctx->dsthost_str);
action = &site->action;
}
}
else {
if (strstr(ctx->dsthost_str, site->site)) {
log_finest_va("Match substring in dst: %s, %s", site->site, ctx->dsthost_str);
action = &site->action;
}
}
else if (site->exact)
log_finest_va("Match exact with dst: %s, %s", site->site, ctx->dsthost_str);
else
log_finest_va("Match substring in dst: %s, %s", site->site, ctx->dsthost_str);
#endif /* DEBUG_PROXY */
if (action) {
log_fine_va("Found site: %s for %s:%s, %s:%s", site->site,
filter_port_t *port = filter_port_find(site, ctx->dstport_str);
if (port) {
log_fine_va("Found port: %s for %s:%s, %s:%s", port->port,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str));
if (site->port) {
filter_port_t *port = site->port;
while (port) {
if (prototcp_filter_match_port(ctx, port)) {
log_fine_va("Found port: %s for %s:%s, %s:%s", port->port,
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str));
return &port->action;
}
port = port->next;
}
log_finest_va("No filter match with port: %s:%s, %s:%s",
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str));
}
if (prototcp_filter_match_port(ctx, port))
return &port->action;
}
else
log_finest_va("No filter match with port: %s:%s, %s:%s",
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str));
return action;
}
@ -588,13 +573,10 @@ static unsigned int NONNULL(1,2)
prototcp_dsthost_filter(pxy_conn_ctx_t *ctx, filter_list_t *list)
{
if (ctx->dsthost_str) {
filter_site_t *site = list->ip;
while (site) {
filter_action_t *action = prototcp_filter_match_ip(ctx, site);
if (action)
return pxyconn_set_filter_action(ctx, *action, site->site);
site = site->next;
}
filter_action_t *action;
if ((action = prototcp_filter_match_ip(ctx, list)))
return pxyconn_set_filter_action(ctx, action, ctx->dsthost_str);
log_finest_va("No filter match with ip: %s:%s, %s:%s",
STRORDASH(ctx->srchost_str), STRORDASH(ctx->srcport_str), STRORDASH(ctx->dsthost_str), STRORDASH(ctx->dstport_str));
}

@ -2007,63 +2007,63 @@ pxyconn_apply_deferred_block_action(pxy_conn_ctx_t *ctx)
}
unsigned int
pxyconn_set_filter_action(pxy_conn_ctx_t *ctx, filter_action_t a, UNUSED char *site)
pxyconn_set_filter_action(pxy_conn_ctx_t *ctx, filter_action_t *a, UNUSED char *site)
{
unsigned int action = FILTER_ACTION_NONE;
if (a.divert) {
log_fine_va("Filter divert action for %s, precedence %d", site, a.precedence);
if (a->divert) {
log_fine_va("Filter divert action for %s, precedence %d", site, a->precedence);
action = FILTER_ACTION_DIVERT;
}
else if (a.split) {
log_fine_va("Filter split action for %s, precedence %d", site, a.precedence);
else if (a->split) {
log_fine_va("Filter split action for %s, precedence %d", site, a->precedence);
action = FILTER_ACTION_SPLIT;
}
else if (a.pass) {
else if (a->pass) {
// Ignore pass action if already in passthrough mode
if (!ctx->pass) {
log_fine_va("Filter pass action for %s, precedence %d", site, a.precedence);
log_fine_va("Filter pass action for %s, precedence %d", site, a->precedence);
action = FILTER_ACTION_PASS;
}
}
else if (a.block) {
log_fine_va("Filter block action for %s, precedence %d", site, a.precedence);
else if (a->block) {
log_fine_va("Filter block action for %s, precedence %d", site, a->precedence);
action = FILTER_ACTION_BLOCK;
}
else if (a.match) {
log_fine_va("Filter match action for %s, precedence %d", site, a.precedence);
else if (a->match) {
log_fine_va("Filter match action for %s, precedence %d", site, a->precedence);
action = FILTER_ACTION_MATCH;
}
// Multiple log actions can be defined, hence no 'else'
// 0: don't change, 1: disable, 2: enable
if (a.log_connect) {
log_fine_va("Filter %s connect log for %s, precedence %d", a.log_connect % 2 ? "disable" : "enable", site, a.precedence);
action |= (a.log_connect % 2) ? FILTER_LOG_NOCONNECT : FILTER_LOG_CONNECT;
if (a->log_connect) {
log_fine_va("Filter %s connect log for %s, precedence %d", a->log_connect % 2 ? "disable" : "enable", site, a->precedence);
action |= (a->log_connect % 2) ? FILTER_LOG_NOCONNECT : FILTER_LOG_CONNECT;
}
if (a.log_master) {
log_fine_va("Filter %s master log for %s, precedence %d", a.log_master % 2 ? "disable" : "enable", site, a.precedence);
action |= (a.log_master % 2) ? FILTER_LOG_NOMASTER : FILTER_LOG_MASTER;
if (a->log_master) {
log_fine_va("Filter %s master log for %s, precedence %d", a->log_master % 2 ? "disable" : "enable", site, a->precedence);
action |= (a->log_master % 2) ? FILTER_LOG_NOMASTER : FILTER_LOG_MASTER;
}
if (a.log_cert) {
log_fine_va("Filter %s cert log for %s, precedence %d", a.log_cert % 2 ? "disable" : "enable", site, a.precedence);
action |= (a.log_cert % 2) ? FILTER_LOG_NOCERT : FILTER_LOG_CERT;
if (a->log_cert) {
log_fine_va("Filter %s cert log for %s, precedence %d", a->log_cert % 2 ? "disable" : "enable", site, a->precedence);
action |= (a->log_cert % 2) ? FILTER_LOG_NOCERT : FILTER_LOG_CERT;
}
if (a.log_content) {
log_fine_va("Filter %s content log for %s, precedence %d", a.log_content % 2 ? "disable" : "enable", site, a.precedence);
action |= (a.log_content % 2) ? FILTER_LOG_NOCONTENT : FILTER_LOG_CONTENT;
if (a->log_content) {
log_fine_va("Filter %s content log for %s, precedence %d", a->log_content % 2 ? "disable" : "enable", site, a->precedence);
action |= (a->log_content % 2) ? FILTER_LOG_NOCONTENT : FILTER_LOG_CONTENT;
}
if (a.log_pcap) {
log_fine_va("Filter %s pcap log for %s, precedence %d", a.log_pcap % 2 ? "disable" : "enable", site, a.precedence);
action |= (a.log_pcap % 2) ? FILTER_LOG_NOPCAP : FILTER_LOG_PCAP;
if (a->log_pcap) {
log_fine_va("Filter %s pcap log for %s, precedence %d", a->log_pcap % 2 ? "disable" : "enable", site, a->precedence);
action |= (a->log_pcap % 2) ? FILTER_LOG_NOPCAP : FILTER_LOG_PCAP;
}
#ifndef WITHOUT_MIRROR
if (a.log_mirror) {
log_fine_va("Filter %s mirror log for %s, precedence %d", a.log_mirror % 2 ? "disable" : "enable", site, a.precedence);
action |= (a.log_mirror % 2) ? FILTER_LOG_NOMIRROR : FILTER_LOG_MIRROR;
if (a->log_mirror) {
log_fine_va("Filter %s mirror log for %s, precedence %d", a->log_mirror % 2 ? "disable" : "enable", site, a->precedence);
action |= (a->log_mirror % 2) ? FILTER_LOG_NOMIRROR : FILTER_LOG_MIRROR;
}
#endif /* !WITHOUT_MIRROR */
action |= a.precedence;
action |= a->precedence;
return action;
}

@ -446,7 +446,7 @@ void pxy_classify_user(pxy_conn_ctx_t *) NONNULL(1);
void pxy_userauth(pxy_conn_ctx_t *) NONNULL(1);
#endif /* !WITHOUT_USERAUTH */
int pxyconn_apply_deferred_block_action(pxy_conn_ctx_t *) NONNULL(1) WUNRES;
unsigned int pxyconn_set_filter_action(pxy_conn_ctx_t *, filter_action_t, UNUSED char *) NONNULL(1,3) WUNRES;
unsigned int pxyconn_set_filter_action(pxy_conn_ctx_t *, filter_action_t *, UNUSED char *) NONNULL(1,2,3) WUNRES;
unsigned int pxyconn_filter(pxy_conn_ctx_t *, proto_filter_func_t) NONNULL(1) WUNRES;
void pxy_conn_setup(evutil_socket_t, struct sockaddr *, int,
pxy_thrmgr_ctx_t *, proxyspec_t *, global_t *,

@ -1360,55 +1360,60 @@ START_TEST(set_filter_rule_07)
s = filter_rule_str(opts->filter_rules);
fail_unless(!strcmp(s,
"filter rule 0: site=, substring, port=, , ip=, user=, keyword=, all=conns||sites|, action=divert||||, log=|||||, apply to=dstip|sni|cn|host|uri, precedence=0\n"
"filter rule 1: site=, substring, port=, , ip=, user=, keyword=, all=conns||sites|, action=|split|||, log=|||||, apply to=dstip|sni|cn|host|uri, precedence=0\n"
"filter rule 2: site=, substring, port=, , ip=, user=, keyword=, all=conns||sites|, action=||pass||, log=|||||, apply to=dstip|sni|cn|host|uri, precedence=0\n"
"filter rule 3: site=, substring, port=, , ip=, user=, keyword=, all=|users|sites|, action=|||block|, log=|||||, apply to=dstip|sni|cn|host|uri, precedence=1\n"
"filter rule 4: site=, substring, port=, , ip=, user=, keyword=desc, all=|users|sites|, action=||||match, log=|||||, apply to=dstip|sni|cn|host|uri, precedence=2\n"
"filter rule 5: site=, substring, port=, , ip=, user=, keyword=, all=conns||sites|, action=||||match, log=connect|master|cert|content|pcap|mirror, apply to=dstip|sni|cn|host|uri, precedence=1"),
"filter rule 0: site=, port=, ip=, user=, keyword=, exact=||||, all=conns||sites|, action=divert||||, log=|||||, apply to=dstip|sni|cn|host|uri, precedence=0\n"
"filter rule 1: site=, port=, ip=, user=, keyword=, exact=||||, all=conns||sites|, action=|split|||, log=|||||, apply to=dstip|sni|cn|host|uri, precedence=0\n"
"filter rule 2: site=, port=, ip=, user=, keyword=, exact=||||, all=conns||sites|, action=||pass||, log=|||||, apply to=dstip|sni|cn|host|uri, precedence=0\n"
"filter rule 3: site=, port=, ip=, user=, keyword=, exact=||||, all=|users|sites|, action=|||block|, log=|||||, apply to=dstip|sni|cn|host|uri, precedence=1\n"
"filter rule 4: site=, port=, ip=, user=, keyword=desc, exact=||||keyword, all=|users|sites|, action=||||match, log=|||||, apply to=dstip|sni|cn|host|uri, precedence=2\n"
"filter rule 5: site=, port=, ip=, user=, keyword=, exact=||||, all=conns||sites|, action=||||match, log=connect|master|cert|content|pcap|mirror, apply to=dstip|sni|cn|host|uri, precedence=1"),
"failed to parse rule: %s", s);
free(s);
close(2);
opts->filter = filter_set(opts->filter_rules);
s = filter_str(opts->filter);
fail_unless(!strcmp(s, "filter=>\n"
"userkeyword_filter->\n"
"user_filter->\n"
"keyword_filter->\n"
" keyword 0 desc= \n"
" ip: \n"
"userkeyword_filter_exact->\n"
"userkeyword_filter_substr->\n"
"user_filter_exact->\n"
"user_filter_substr->\n"
"keyword_filter_exact->\n"
" keyword 0 desc (exact)= \n"
" ip substring: \n"
" 0: (all_sites, substring, action=||||match, log=|||||, precedence=2)\n"
" sni: \n"
" sni substring: \n"
" 0: (all_sites, substring, action=||||match, log=|||||, precedence=2)\n"
" cn: \n"
" cn substring: \n"
" 0: (all_sites, substring, action=||||match, log=|||||, precedence=2)\n"
" host: \n"
" host substring: \n"
" 0: (all_sites, substring, action=||||match, log=|||||, precedence=2)\n"
" uri: \n"
" uri substring: \n"
" 0: (all_sites, substring, action=||||match, log=|||||, precedence=2)\n"
"keyword_filter_substr->\n"
"all_user_filter->\n"
" ip: \n"
" ip substring: \n"
" 0: (all_sites, substring, action=|||block|, log=|||||, precedence=1)\n"
" sni: \n"
" sni substring: \n"
" 0: (all_sites, substring, action=|||block|, log=|||||, precedence=1)\n"
" cn: \n"
" cn substring: \n"
" 0: (all_sites, substring, action=|||block|, log=|||||, precedence=1)\n"
" host: \n"
" host substring: \n"
" 0: (all_sites, substring, action=|||block|, log=|||||, precedence=1)\n"
" uri: \n"
" uri substring: \n"
" 0: (all_sites, substring, action=|||block|, log=|||||, precedence=1)\n"
"ip_filter->\n"
"ip_filter_exact->\n"
"ip_filter_substr->\n"
"all_filter->\n"
" ip: \n"
" ip substring: \n"
" 0: (all_sites, substring, action=divert|split|pass||match, log=connect|master|cert|content|pcap|mirror, precedence=1)\n"
" sni: \n"
" sni substring: \n"
" 0: (all_sites, substring, action=divert|split|pass||match, log=connect|master|cert|content|pcap|mirror, precedence=1)\n"
" cn: \n"
" cn substring: \n"
" 0: (all_sites, substring, action=divert|split|pass||match, log=connect|master|cert|content|pcap|mirror, precedence=1)\n"
" host: \n"
" host substring: \n"
" 0: (all_sites, substring, action=divert|split|pass||match, log=connect|master|cert|content|pcap|mirror, precedence=1)\n"
" uri: \n"
" uri substring: \n"
" 0: (all_sites, substring, action=divert|split|pass||match, log=connect|master|cert|content|pcap|mirror, precedence=1)\n"), "failed to translate rule: %s", s);
free(s);
@ -1475,56 +1480,44 @@ START_TEST(set_filter_rule_08)
s = filter_rule_str(opts->filter_rules);
fail_unless(!strcmp(s,
"filter rule 0: site=192.168.0.2, exact, port=, , ip=192.168.0.1, user=, keyword=, all=|||, action=divert||||, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 1: site=192.168.0.2, exact, port=, , ip=192.168.0.1, user=, keyword=, all=|||, action=|split|||, log=connect|master|cert|content|pcap|mirror, apply to=dstip||||, precedence=2\n"
"filter rule 2: site=192.168.0.2, exact, port=, , ip=192.168.0.1, user=, keyword=, all=|||, action=||pass||, log=!connect||!cert||!pcap|, apply to=dstip||||, precedence=2\n"
"filter rule 3: site=192.168.0.2, exact, port=, , ip=192.168.0.1, user=, keyword=, all=|||, action=|||block|, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 4: site=192.168.0.3, exact, port=, , ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 5: site=192.168.0.1, exact, port=, , ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 6: site=, substring, port=, , ip=192.168.0.2, user=, keyword=, all=||sites|, action=||||match, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 7: site=192.168.0., substring, port=, , ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 8: site=192.168.0.3, exact, port=, , ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=1"),
"filter rule 0: site=192.168.0.2, port=, ip=192.168.0.1, user=, keyword=, exact=site||ip||, all=|||, action=divert||||, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 1: site=192.168.0.2, port=, ip=192.168.0.1, user=, keyword=, exact=site||ip||, all=|||, action=|split|||, log=connect|master|cert|content|pcap|mirror, apply to=dstip||||, precedence=2\n"
"filter rule 2: site=192.168.0.2, port=, ip=192.168.0.1, user=, keyword=, exact=site||ip||, all=|||, action=||pass||, log=!connect||!cert||!pcap|, apply to=dstip||||, precedence=2\n"
"filter rule 3: site=192.168.0.2, port=, ip=192.168.0.1, user=, keyword=, exact=site||ip||, all=|||, action=|||block|, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 4: site=192.168.0.3, port=, ip=192.168.0.1, user=, keyword=, exact=site||ip||, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 5: site=192.168.0.1, port=, ip=192.168.0.2, user=, keyword=, exact=site||ip||, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 6: site=, port=, ip=192.168.0.2, user=, keyword=, exact=||ip||, all=||sites|, action=||||match, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 7: site=192.168.0., port=, ip=192.168.0.2, user=, keyword=, exact=||ip||, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=1\n"
"filter rule 8: site=192.168.0.3, port=, ip=192.168.0.2, user=, keyword=, exact=site||ip||, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=1"),
"failed to parse rule: %s", s);
free(s);
close(2);
opts->filter = filter_set(opts->filter_rules);
s = filter_str(opts->filter);
fail_unless(!strcmp(s, "filter=>\n"
"userkeyword_filter->\n"
"user_filter->\n"
"keyword_filter->\n"
"userkeyword_filter_exact->\n"
"userkeyword_filter_substr->\n"
"user_filter_exact->\n"
"user_filter_substr->\n"
"keyword_filter_exact->\n"
"keyword_filter_substr->\n"
"all_user_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
"ip_filter->\n"
" ip 0 192.168.0.2= \n"
" ip: \n"
" 0: 192.168.0.1 (exact, action=||||match, log=|||||, precedence=1)\n"
" 1: 192.168.0. (substring, action=||||match, log=|||||, precedence=1)\n"
" 2: 192.168.0.3 (exact, action=||||match, log=|||||, precedence=1)\n"
" 3: (all_sites, substring, action=||||match, log=|||||, precedence=1)\n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
" ip 1 192.168.0.1= \n"
" ip: \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"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
"all_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"), "failed to translate rule: %s", s);
"ip_filter_exact->\n"
" ip 0 192.168.0.2 (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"
" 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);
opts_free(opts);
@ -1596,63 +1589,51 @@ START_TEST(set_filter_rule_09)
s = filter_rule_str(opts->filter_rules);
fail_unless(!strcmp(s,
"filter rule 0: site=192.168.0.2, exact, port=443, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=divert||||, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 1: site=192.168.0.2, exact, port=443, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=|split|||, log=connect|master|cert|content|pcap|mirror, apply to=dstip||||, precedence=3\n"
"filter rule 2: site=192.168.0.2, exact, port=443, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=||pass||, log=!connect||!cert||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 3: site=192.168.0.2, exact, port=443, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=|||block|, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 4: site=192.168.0.3, exact, port=, , ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=|||||!mirror, apply to=dstip||||, precedence=2\n"
"filter rule 5: site=192.168.0.3, exact, port=443, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 6: site=192.168.0.3, exact, port=80, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 7: site=192.168.0.1, exact, port=443, exact_port, ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 8: site=192.168.0.1, exact, port=, substring_port, ip=192.168.0.2, user=, keyword=, all=|||ports, action=||||match, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 9: site=192.168.0.1, exact, port=80, substring_port, ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=2"),
"filter rule 0: site=192.168.0.2, port=443, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=divert||||, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 1: site=192.168.0.2, port=443, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=|split|||, log=connect|master|cert|content|pcap|mirror, apply to=dstip||||, precedence=3\n"
"filter rule 2: site=192.168.0.2, port=443, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=||pass||, log=!connect||!cert||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 3: site=192.168.0.2, port=443, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=|||block|, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 4: site=192.168.0.3, port=, ip=192.168.0.1, user=, keyword=, exact=site||ip||, all=|||, action=||||match, log=|||||!mirror, apply to=dstip||||, precedence=2\n"
"filter rule 5: site=192.168.0.3, port=443, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 6: site=192.168.0.3, port=80, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 7: site=192.168.0.1, port=443, ip=192.168.0.2, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 8: site=192.168.0.1, port=, ip=192.168.0.2, user=, keyword=, exact=site||ip||, all=|||ports, action=||||match, log=|||||, apply to=dstip||||, precedence=2\n"
"filter rule 9: site=192.168.0.1, port=80, ip=192.168.0.2, user=, keyword=, exact=site||ip||, all=|||, action=||||match, log=|||||, apply to=dstip||||, precedence=2"),
"failed to parse rule: %s", s);
free(s);
close(2);
opts->filter = filter_set(opts->filter_rules);
s = filter_str(opts->filter);
fail_unless(!strcmp(s, "filter=>\n"
"userkeyword_filter->\n"
"user_filter->\n"
"keyword_filter->\n"
"userkeyword_filter_exact->\n"
"userkeyword_filter_substr->\n"
"user_filter_exact->\n"
"user_filter_substr->\n"
"keyword_filter_exact->\n"
"keyword_filter_substr->\n"
"all_user_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
"ip_filter->\n"
" ip 0 192.168.0.2= \n"
" ip: \n"
"ip_filter_exact->\n"
" ip 0 192.168.0.2 (exact)= \n"
" ip exact: \n"
" 0: 192.168.0.1 (exact, action=||||, log=|||||, precedence=0)\n"
" port:\n"
" port exact:\n"
" 0: 443 (exact, action=||||match, log=|||||, precedence=2)\n"
" 1: 80 (substring, action=||||match, log=|||||, precedence=2)\n"
" 2: (all_ports, substring, action=||||match, log=|||||, precedence=2)\n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
" ip 1 192.168.0.1= \n"
" ip: \n"
" 0: 192.168.0.2 (exact, action=||||, log=|||||, precedence=0)\n"
" port:\n"
" 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"
" 1: 192.168.0.3 (exact, action=||||match, log=|||||!mirror, precedence=2)\n"
" port:\n"
" 0: 443 (exact, action=||||match, log=|||||, precedence=2)\n"
" 1: 80 (exact, action=||||match, log=|||||, precedence=2)\n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
"all_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"), "failed to translate rule: %s", s);
"ip_filter_substr->\n"
"all_filter->\n"), "failed to translate rule: %s", s);
free(s);
opts_free(opts);
@ -1720,56 +1701,44 @@ START_TEST(set_filter_rule_10)
s = filter_rule_str(opts->filter_rules);
fail_unless(!strcmp(s,
"filter rule 0: site=example.com, exact, port=, , ip=, user=root, keyword=, all=|||, action=divert||||, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 1: site=example.com, exact, port=, , ip=, user=root, keyword=, all=|||, action=|split|||, log=connect|master|cert|content|pcap|mirror, apply to=|sni|||, precedence=4\n"
"filter rule 2: site=example.com, exact, port=, , ip=, user=root, keyword=, all=|||, action=||pass||, log=!connect||!cert||!pcap|, apply to=|sni|||, precedence=4\n"
"filter rule 3: site=example.com, exact, port=, , ip=, user=root, keyword=, all=|||, action=|||block|, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 4: site=example2.com, exact, port=, , ip=, user=root, keyword=, all=|||, action=||||match, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 5: site=example.com, exact, port=, , ip=, user=daemon, keyword=, all=|||, action=||||match, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 6: site=, substring, port=, , ip=, user=daemon, keyword=, all=||sites|, action=||||match, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 7: site=.example.com, substring, port=, , ip=, user=daemon, keyword=, all=|||, action=||||match, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 8: site=example3.com, exact, port=, , ip=, user=daemon, keyword=, all=|||, action=||||match, log=|||||, apply to=|sni|||, precedence=3"),
"filter rule 0: site=example.com, port=, ip=, user=root, keyword=, exact=site|||user|, all=|||, action=divert||||, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 1: site=example.com, port=, ip=, user=root, keyword=, exact=site|||user|, all=|||, action=|split|||, log=connect|master|cert|content|pcap|mirror, apply to=|sni|||, precedence=4\n"
"filter rule 2: site=example.com, port=, ip=, user=root, keyword=, exact=site|||user|, all=|||, action=||pass||, log=!connect||!cert||!pcap|, apply to=|sni|||, precedence=4\n"
"filter rule 3: site=example.com, port=, ip=, user=root, keyword=, exact=site|||user|, all=|||, action=|||block|, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 4: site=example2.com, port=, ip=, user=root, keyword=, exact=site|||user|, all=|||, action=||||match, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 5: site=example.com, port=, ip=, user=daemon, keyword=, exact=site|||user|, all=|||, action=||||match, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 6: site=, port=, ip=, user=daemon, keyword=, exact=|||user|, all=||sites|, action=||||match, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 7: site=.example.com, port=, ip=, user=daemon, keyword=, exact=|||user|, all=|||, action=||||match, log=|||||, apply to=|sni|||, precedence=3\n"
"filter rule 8: site=example3.com, port=, ip=, user=daemon, keyword=, exact=site|||user|, all=|||, action=||||match, log=|||||, apply to=|sni|||, precedence=3"),
"failed to parse rule: %s", s);
free(s);
close(2);
opts->filter = filter_set(opts->filter_rules);
s = filter_str(opts->filter);
fail_unless(!strcmp(s, "filter=>\n"
"userkeyword_filter->\n"
"user_filter->\n"
" user 0 daemon= \n"
" ip: \n"
" sni: \n"
" 0: example.com (exact, action=||||match, log=|||||, precedence=3)\n"
" 1: .example.com (substring, action=||||match, log=|||||, precedence=3)\n"
" 2: example3.com (exact, action=||||match, log=|||||, precedence=3)\n"
" 3: (all_sites, substring, action=||||match, log=|||||, precedence=3)\n"
" cn: \n"
" host: \n"
" uri: \n"
" user 1 root= \n"
" ip: \n"
" sni: \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"
" cn: \n"
" host: \n"
" uri: \n"
"keyword_filter->\n"
"userkeyword_filter_exact->\n"
"userkeyword_filter_substr->\n"
"user_filter_exact->\n"
" user 0 root (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"
" sni substring: \n"
" 0: .example.com (substring, action=||||match, log=|||||, precedence=3)\n"
" 1: (all_sites, substring, action=||||match, log=|||||, precedence=3)\n"
"user_filter_substr->\n"
"keyword_filter_exact->\n"
"keyword_filter_substr->\n"
"all_user_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
"ip_filter->\n"
"all_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"), "failed to translate rule: %s", s);
"ip_filter_exact->\n"
"ip_filter_substr->\n"
"all_filter->\n"), "failed to translate rule: %s", s);
free(s);
opts_free(opts);
@ -1861,84 +1830,63 @@ START_TEST(set_filter_rule_11)
s = filter_rule_str(opts->filter_rules);
fail_unless(!strcmp(s,
"filter rule 0: site=example.com, exact, port=, , ip=, user=root, keyword=desc, all=|||, action=divert||||, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 1: site=example.com, exact, port=, , ip=, user=root, keyword=desc, all=|||, action=|split|||, log=connect|master|cert|content|pcap|mirror, apply to=||cn||, precedence=5\n"
"filter rule 2: site=example.com, exact, port=, , ip=, user=root, keyword=desc, all=|||, action=||pass||, log=!connect||!cert||!pcap|, apply to=||cn||, precedence=5\n"
"filter rule 3: site=example.com, exact, port=, , ip=, user=root, keyword=desc, all=|||, action=|||block|, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 4: site=example2.com, exact, port=, , ip=, user=root, keyword=desc, all=|||, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 5: site=example.com, exact, port=, , ip=, user=daemon, keyword=desc, all=|||, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 6: site=, substring, port=, , ip=, user=daemon, keyword=desc, all=||sites|, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 7: site=.example.com, substring, port=, , ip=, user=daemon, keyword=desc, all=|||, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 8: site=example3.com, exact, port=, , ip=, user=daemon, keyword=desc, all=|||, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 9: site=example4.com, exact, port=, , ip=, user=daemon, keyword=desc2, all=|||, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 10: site=example5.com, exact, port=, , ip=, user=, keyword=desc, all=|users||, action=||||match, log=|||||, apply to=||cn||, precedence=3\n"
"filter rule 11: site=, substring, port=, , ip=, user=, keyword=desc, all=|users|sites|, action=||||match, log=|||||, apply to=|||host|, precedence=3\n"
"filter rule 12: site=example6.com, exact, port=, , ip=, user=, keyword=desc3, all=|users||, action=||||match, log=|||||, apply to=||||uri, precedence=3"),
"filter rule 0: site=example.com, port=, ip=, user=root, keyword=desc, exact=site|||user|keyword, all=|||, action=divert||||, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 1: site=example.com, port=, ip=, user=root, keyword=desc, exact=site|||user|keyword, all=|||, action=|split|||, log=connect|master|cert|content|pcap|mirror, apply to=||cn||, precedence=5\n"
"filter rule 2: site=example.com, port=, ip=, user=root, keyword=desc, exact=site|||user|keyword, all=|||, action=||pass||, log=!connect||!cert||!pcap|, apply to=||cn||, precedence=5\n"
"filter rule 3: site=example.com, port=, ip=, user=root, keyword=desc, exact=site|||user|keyword, all=|||, action=|||block|, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 4: site=example2.com, port=, ip=, user=root, keyword=desc, exact=site|||user|keyword, all=|||, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 5: site=example.com, port=, ip=, user=daemon, keyword=desc, exact=site|||user|keyword, all=|||, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 6: site=, port=, ip=, user=daemon, keyword=desc, exact=|||user|keyword, all=||sites|, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 7: site=.example.com, port=, ip=, user=daemon, keyword=desc, exact=|||user|keyword, all=|||, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 8: site=example3.com, port=, ip=, user=daemon, keyword=desc, exact=site|||user|keyword, all=|||, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 9: site=example4.com, port=, ip=, user=daemon, keyword=desc2, exact=site|||user|keyword, all=|||, action=||||match, log=|||||, apply to=||cn||, precedence=4\n"
"filter rule 10: site=example5.com, port=, ip=, user=, keyword=desc, exact=site||||keyword, all=|users||, action=||||match, log=|||||, apply to=||cn||, precedence=3\n"
"filter rule 11: site=, port=, ip=, user=, keyword=desc, exact=||||keyword, all=|users|sites|, action=||||match, log=|||||, apply to=|||host|, precedence=3\n"
"filter rule 12: site=example6.com, port=, ip=, user=, keyword=desc3, exact=site||||keyword, all=|users||, action=||||match, log=|||||, apply to=||||uri, precedence=3"),
"failed to parse rule: %s", s);
free(s);
close(2);
opts->filter = filter_set(opts->filter_rules);
s = filter_str(opts->filter);
fail_unless(!strcmp(s, "filter=>\n"
"userkeyword_filter->\n"
" user 0 daemon=\n"
" keyword 0 desc2= \n"
" ip: \n"
" sni: \n"
" cn: \n"
"userkeyword_filter_exact->\n"
" user 0 root (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"
" host: \n"
" uri: \n"
" keyword 1 desc= \n"
" ip: \n"
" sni: \n"
" cn: \n"
" 0: example.com (exact, action=||||match, log=|||||, precedence=4)\n"
" 1: .example.com (substring, action=||||match, log=|||||, precedence=4)\n"
" 2: example3.com (exact, action=||||match, log=|||||, precedence=4)\n"
" 3: (all_sites, substring, action=||||match, log=|||||, precedence=4)\n"
" host: \n"
" uri: \n"
" user 1 root=\n"
" keyword 0 desc= \n"
" ip: \n"
" sni: \n"
" cn: \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"
" host: \n"
" uri: \n"
"user_filter->\n"
"keyword_filter->\n"
" keyword 0 desc3= \n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \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"
" cn substring: \n"
" 0: .example.com (substring, action=||||match, log=|||||, precedence=4)\n"
" 1: (all_sites, substring, 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= \n"
" ip: \n"
" sni: \n"
" cn: \n"
" keyword 1 desc (exact)= \n"
" cn exact: \n"
" 0: example5.com (exact, action=||||match, log=|||||, precedence=3)\n"
" host: \n"
" host substring: \n"
" 0: (all_sites, substring, action=||||match, log=|||||, precedence=3)\n"
" uri: \n"
"keyword_filter_substr->\n"
"all_user_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
"ip_filter->\n"
"all_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"), "failed to translate rule: %s", s);
"ip_filter_exact->\n"
"ip_filter_substr->\n"
"all_filter->\n"), "failed to translate rule: %s", s);
free(s);
opts_free(opts);
@ -1978,73 +1926,60 @@ START_TEST(set_filter_rule_12)
s = filter_rule_str(opts->filter_rules);
fail_unless(!strcmp(s,
"filter rule 0: site=192.168.0.3, exact, port=80, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 1: site=192.168.0.3, exact, port=80, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 2: site=192.168.0.3, exact, port=443, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 3: site=192.168.0.3, exact, port=443, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 4: site=192.168.0.4, exact, port=80, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 5: site=192.168.0.4, exact, port=80, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 6: site=192.168.0.4, exact, port=443, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 7: site=192.168.0.4, exact, port=443, exact_port, ip=192.168.0.1, user=, keyword=, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 8: site=192.168.0.3, exact, port=80, exact_port, ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 9: site=192.168.0.3, exact, port=80, exact_port, ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 10: site=192.168.0.3, exact, port=443, exact_port, ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 11: site=192.168.0.3, exact, port=443, exact_port, ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 12: site=192.168.0.4, exact, port=80, exact_port, ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 13: site=192.168.0.4, exact, port=80, exact_port, ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 14: site=192.168.0.4, exact, port=443, exact_port, ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 15: site=192.168.0.4, exact, port=443, exact_port, ip=192.168.0.2, user=, keyword=, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3"),
"filter rule 0: site=192.168.0.3, port=80, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 1: site=192.168.0.3, port=80, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 2: site=192.168.0.3, port=443, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 3: site=192.168.0.3, port=443, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 4: site=192.168.0.4, port=80, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 5: site=192.168.0.4, port=80, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 6: site=192.168.0.4, port=443, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 7: site=192.168.0.4, port=443, ip=192.168.0.1, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 8: site=192.168.0.3, port=80, ip=192.168.0.2, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 9: site=192.168.0.3, port=80, ip=192.168.0.2, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 10: site=192.168.0.3, port=443, ip=192.168.0.2, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 11: site=192.168.0.3, port=443, ip=192.168.0.2, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 12: site=192.168.0.4, port=80, ip=192.168.0.2, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 13: site=192.168.0.4, port=80, ip=192.168.0.2, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3\n"
"filter rule 14: site=192.168.0.4, port=443, ip=192.168.0.2, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=|!master||||, apply to=dstip||||, precedence=3\n"
"filter rule 15: site=192.168.0.4, port=443, ip=192.168.0.2, user=, keyword=, exact=site|port|ip||, all=|||, action=||||match, log=||||!pcap|, apply to=dstip||||, precedence=3"),
"failed to parse rule: %s", s);
free(s);
close(2);
opts->filter = filter_set(opts->filter_rules);
s = filter_str(opts->filter);
fail_unless(!strcmp(s, "filter=>\n"
"userkeyword_filter->\n"
"user_filter->\n"
"keyword_filter->\n"
"userkeyword_filter_exact->\n"
"userkeyword_filter_substr->\n"
"user_filter_exact->\n"
"user_filter_substr->\n"
"keyword_filter_exact->\n"
"keyword_filter_substr->\n"
"all_user_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
"ip_filter->\n"
" ip 0 192.168.0.2= \n"
" ip: \n"
" 0: 192.168.0.3 (exact, action=||||, log=|||||, precedence=0)\n"
" port:\n"
"ip_filter_exact->\n"
" ip 0 192.168.0.2 (exact)= \n"
" ip exact: \n"
" 0: 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"
" 1: 192.168.0.4 (exact, action=||||, log=|||||, precedence=0)\n"
" port:\n"
" 1: 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"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
" ip 1 192.168.0.1= \n"
" ip: \n"
" 0: 192.168.0.3 (exact, action=||||, log=|||||, precedence=0)\n"
" port:\n"
" ip 1 192.168.0.1 (exact)= \n"
" ip exact: \n"
" 0: 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"
" 1: 192.168.0.4 (exact, action=||||, log=|||||, precedence=0)\n"
" port:\n"
" 1: 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"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
"all_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"), "failed to translate rule: %s", s);
"ip_filter_substr->\n"
"all_filter->\n"), "failed to translate rule: %s", s);
free(s);
opts_free(opts);
@ -2075,7 +2010,9 @@ START_TEST(set_filter_rule_13)
// check errors out if we add all log actions to the macro:
// "../../src/check_pack.c:306: Message string too long"
// so use 3 log actions only
s = strdup("$logs connect content mirror");
// Also, the compiler gives:
// warning: string length 4186 is greater than the length 4095 ISO C99 compilers are required to support [-Woverlength-strings]
s = strdup("$logs connect content");
rv = filter_macro_set(opts, s, 0);
fail_unless(rv == 0, "failed to set macro");
free(s);
@ -2089,87 +2026,60 @@ START_TEST(set_filter_rule_13)
s = filter_rule_str(opts->filter_rules);
fail_unless(!strcmp(s,
"filter rule 0: site=site1, exact, port=, , ip=, user=root, keyword=desc1, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 1: site=site1, exact, port=, , ip=, user=root, keyword=desc1, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 2: site=site1, exact, port=, , ip=, user=root, keyword=desc1, all=|||, action=||||match, log=|||||mirror, apply to=|sni|||, precedence=5\n"
"filter rule 3: site=site2, exact, port=, , ip=, user=root, keyword=desc1, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 4: site=site2, exact, port=, , ip=, user=root, keyword=desc1, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 5: site=site2, exact, port=, , ip=, user=root, keyword=desc1, all=|||, action=||||match, log=|||||mirror, apply to=|sni|||, precedence=5\n"
"filter rule 6: site=site1, exact, port=, , ip=, user=root, keyword=desc2, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 7: site=site1, exact, port=, , ip=, user=root, keyword=desc2, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 8: site=site1, exact, port=, , ip=, user=root, keyword=desc2, all=|||, action=||||match, log=|||||mirror, apply to=|sni|||, precedence=5\n"
"filter rule 9: site=site2, exact, port=, , ip=, user=root, keyword=desc2, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 10: site=site2, exact, port=, , ip=, user=root, keyword=desc2, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 11: site=site2, exact, port=, , ip=, user=root, keyword=desc2, all=|||, action=||||match, log=|||||mirror, apply to=|sni|||, precedence=5\n"
"filter rule 12: site=site1, exact, port=, , ip=, user=daemon, keyword=desc1, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 13: site=site1, exact, port=, , ip=, user=daemon, keyword=desc1, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 14: site=site1, exact, port=, , ip=, user=daemon, keyword=desc1, all=|||, action=||||match, log=|||||mirror, apply to=|sni|||, precedence=5\n"
"filter rule 15: site=site2, exact, port=, , ip=, user=daemon, keyword=desc1, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 16: site=site2, exact, port=, , ip=, user=daemon, keyword=desc1, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 17: site=site2, exact, port=, , ip=, user=daemon, keyword=desc1, all=|||, action=||||match, log=|||||mirror, apply to=|sni|||, precedence=5\n"
"filter rule 18: site=site1, exact, port=, , ip=, user=daemon, keyword=desc2, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 19: site=site1, exact, port=, , ip=, user=daemon, keyword=desc2, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 20: site=site1, exact, port=, , ip=, user=daemon, keyword=desc2, all=|||, action=||||match, log=|||||mirror, apply to=|sni|||, precedence=5\n"
"filter rule 21: site=site2, exact, port=, , ip=, user=daemon, keyword=desc2, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 22: site=site2, exact, port=, , ip=, user=daemon, keyword=desc2, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 23: site=site2, exact, port=, , ip=, user=daemon, keyword=desc2, all=|||, action=||||match, log=|||||mirror, apply to=|sni|||, precedence=5"),
"filter rule 0: site=site1, port=, ip=, user=root, keyword=desc1, exact=site|||user|keyword, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 1: site=site1, port=, ip=, user=root, keyword=desc1, exact=site|||user|keyword, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 2: site=site2, port=, ip=, user=root, keyword=desc1, exact=site|||user|keyword, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 3: site=site2, port=, ip=, user=root, keyword=desc1, exact=site|||user|keyword, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 4: site=site1, port=, ip=, user=root, keyword=desc2, exact=site|||user|keyword, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 5: site=site1, port=, ip=, user=root, keyword=desc2, exact=site|||user|keyword, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 6: site=site2, port=, ip=, user=root, keyword=desc2, exact=site|||user|keyword, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 7: site=site2, port=, ip=, user=root, keyword=desc2, exact=site|||user|keyword, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 8: site=site1, port=, ip=, user=daemon, keyword=desc1, exact=site|||user|keyword, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 9: site=site1, port=, ip=, user=daemon, keyword=desc1, exact=site|||user|keyword, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 10: site=site2, port=, ip=, user=daemon, keyword=desc1, exact=site|||user|keyword, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 11: site=site2, port=, ip=, user=daemon, keyword=desc1, exact=site|||user|keyword, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 12: site=site1, port=, ip=, user=daemon, keyword=desc2, exact=site|||user|keyword, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 13: site=site1, port=, ip=, user=daemon, keyword=desc2, exact=site|||user|keyword, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5\n"
"filter rule 14: site=site2, port=, ip=, user=daemon, keyword=desc2, exact=site|||user|keyword, all=|||, action=||||match, log=connect|||||, apply to=|sni|||, precedence=5\n"
"filter rule 15: site=site2, port=, ip=, user=daemon, keyword=desc2, exact=site|||user|keyword, all=|||, action=||||match, log=|||content||, apply to=|sni|||, precedence=5"),
"failed to parse rule: %s", s);
free(s);
close(2);
opts->filter = filter_set(opts->filter_rules);
s = filter_str(opts->filter);
fail_unless(!strcmp(s, "filter=>\n"
"userkeyword_filter->\n"
" user 0 daemon=\n"
" keyword 0 desc2= \n"
" ip: \n"
" sni: \n"
" 0: site1 (exact, action=||||match, log=connect|||content||mirror, precedence=5)\n"
" 1: site2 (exact, action=||||match, log=connect|||content||mirror, precedence=5)\n"
" cn: \n"
" host: \n"
" uri: \n"
" keyword 1 desc1= \n"
" ip: \n"
" sni: \n"
" 0: site1 (exact, action=||||match, log=connect|||content||mirror, precedence=5)\n"
" 1: site2 (exact, action=||||match, log=connect|||content||mirror, precedence=5)\n"
" cn: \n"
" host: \n"
" uri: \n"
" user 1 root=\n"
" keyword 0 desc2= \n"
" ip: \n"
" sni: \n"
" 0: site1 (exact, action=||||match, log=connect|||content||mirror, precedence=5)\n"
" 1: site2 (exact, action=||||match, log=connect|||content||mirror, precedence=5)\n"
" cn: \n"
" host: \n"
" uri: \n"
" keyword 1 desc1= \n"
" ip: \n"
" sni: \n"
" 0: site1 (exact, action=||||match, log=connect|||content||mirror, precedence=5)\n"
" 1: site2 (exact, action=||||match, log=connect|||content||mirror, precedence=5)\n"
" cn: \n"
" host: \n"
" uri: \n"
"user_filter->\n"
"keyword_filter->\n"
"userkeyword_filter_exact->\n"
" user 0 root (exact)=\n"
" keyword exact:\n"
" keyword 0 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"
" keyword 1 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"
" user 1 daemon (exact)=\n"
" keyword exact:\n"
" keyword 0 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"
" keyword 1 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"
"userkeyword_filter_substr->\n"
"user_filter_exact->\n"
"user_filter_substr->\n"
"keyword_filter_exact->\n"
"keyword_filter_substr->\n"
"all_user_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"
"ip_filter->\n"
"all_filter->\n"
" ip: \n"
" sni: \n"
" cn: \n"
" host: \n"
" uri: \n"), "failed to translate rule: %s", s);
"ip_filter_exact->\n"
"ip_filter_substr->\n"
"all_filter->\n"), "failed to translate rule: %s", s);
free(s);
opts_free(opts);

@ -650,7 +650,7 @@ START_TEST(opts_set_passsite_01)
ps = filter_rule_str(opts->filter_rules);
#ifndef WITHOUT_USERAUTH
fail_unless(!strcmp(ps, "filter rule 0: site=example.com, exact, port=, , ip=, user=, keyword=, all=conns|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=1"), "failed parsing passite example.com: %s", ps);
fail_unless(!strcmp(ps, "filter rule 0: site=example.com, port=, ip=, user=, keyword=, exact=site||||, all=conns|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=1"), "failed parsing passite example.com: %s", ps);
#else /* WITHOUT_USERAUTH */
fail_unless(!strcmp(ps, "filter rule 0: site=example.com, exact, ip=, all=conns|, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=1"), "failed parsing passite example.com: %s", ps);
#endif /* WITHOUT_USERAUTH */
@ -680,7 +680,7 @@ START_TEST(opts_set_passsite_02)
ps = filter_rule_str(opts->filter_rules);
#ifndef WITHOUT_USERAUTH
fail_unless(!strcmp(ps, "filter rule 0: site=example.com, exact, port=, , ip=192.168.0.1, user=, keyword=, all=|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=2"), "failed parsing passite example.com 192.168.0.1: %s", ps);
fail_unless(!strcmp(ps, "filter rule 0: site=example.com, port=, ip=192.168.0.1, user=, keyword=, exact=site||||, all=|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=2"), "failed parsing passite example.com 192.168.0.1: %s", ps);
#else /* WITHOUT_USERAUTH */
fail_unless(!strcmp(ps, "filter rule 0: site=example.com, exact, ip=192.168.0.1, all=|, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=2"), "failed parsing passite example.com 192.168.0.1: %s", ps);
#endif /* !WITHOUT_USERAUTH */
@ -710,7 +710,7 @@ START_TEST(opts_set_passsite_03)
fail_unless(!opts->filter_rules->next, "next set");
ps = filter_rule_str(opts->filter_rules);
fail_unless(!strcmp(ps, "filter rule 0: site=example.com, exact, port=, , ip=, user=root, keyword=, all=|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=3"), "failed parsing passite example.com root: %s", ps);
fail_unless(!strcmp(ps, "filter rule 0: site=example.com, port=, ip=, user=root, keyword=, exact=site||||, all=|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=3"), "failed parsing passite example.com root: %s", ps);
free(ps);
opts_free(opts);
@ -737,7 +737,7 @@ START_TEST(opts_set_passsite_04)
fail_unless(!opts->filter_rules->next, "next set");
ps = filter_rule_str(opts->filter_rules);
fail_unless(!strcmp(ps, "filter rule 0: site=*.google.com, exact, port=, , ip=, user=, keyword=android, all=|users||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=3"), "failed parsing passite *.google.com * android: %s", ps);
fail_unless(!strcmp(ps, "filter rule 0: site=*.google.com, port=, ip=, user=, keyword=android, exact=site||||, all=|users||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=3"), "failed parsing passite *.google.com * android: %s", ps);
free(ps);
opts_free(opts);
@ -792,11 +792,11 @@ START_TEST(opts_set_passsite_05)
fail_unless(opts->filter_rules->next->next->next, "next->next->next not set");
fail_unless(opts->filter_rules->next->next->next->next, "next->next->next->next not set");
fail_unless(!opts->filter_rules->next->next->next->next->next, "next->next->next->next->next set");
fail_unless(!strcmp(ps, "filter rule 0: site=example.com, exact, port=, , ip=, user=, keyword=, all=conns|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=1\n"
"filter rule 1: site=example.com, exact, port=, , ip=, user=, keyword=, all=|users||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=2\n"
"filter rule 2: site=example.com, exact, port=, , ip=192.168.0.1, user=, keyword=, all=|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=2\n"
"filter rule 3: site=example.com, exact, port=, , ip=, user=root, keyword=, all=|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=3\n"
"filter rule 4: site=*.google.com, exact, port=, , ip=, user=, keyword=android, all=|users||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=3"),
fail_unless(!strcmp(ps, "filter rule 0: site=example.com, port=, ip=, user=, keyword=, exact=site||||, all=conns|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=1\n"
"filter rule 1: site=example.com, port=, ip=, user=, keyword=, exact=site||||, all=|users||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=2\n"
"filter rule 2: site=example.com, port=, ip=192.168.0.1, user=, keyword=, exact=site||||, all=|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=2\n"
"filter rule 3: site=example.com, port=, ip=, user=root, keyword=, exact=site||||, all=|||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=3\n"
"filter rule 4: site=*.google.com, port=, ip=, user=, keyword=android, exact=site||||, all=|users||, action=||pass||, log=|||||, apply to=|sni|cn||, precedence=3"),
"failed parsing multiple passites: %s", ps);
#else /* WITHOUT_USERAUTH */
fail_unless(!opts->filter_rules->next->next->next, "next->next->next set");

Loading…
Cancel
Save