From 995d28cacb80e129e0b8ffbfdbe8d92916b8d97b Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Fri, 26 May 2023 16:15:09 +0200 Subject: [PATCH] Add duplicate_security_group() function, and also: unreal_duplicate_masks() duplicate_nvplist() duplicate_name_list() And use this for when proxy::type is web, to duplicate the exact criteria to the ban exception as mentioned in previous commit. --- include/h.h | 4 ++++ src/conf.c | 36 ++++++++++++------------------------ src/list.c | 22 ++++++++++++++++++++++ src/securitygroup.c | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 24 deletions(-) diff --git a/include/h.h b/include/h.h index bf7f9c578..f5fecbbc9 100644 --- a/include/h.h +++ b/include/h.h @@ -1147,6 +1147,7 @@ extern int read_str(FILE *fd, char **x); extern void _free_entire_name_list(NameList *n); extern void _add_name_list(NameList **list, const char *name); extern void _del_name_list(NameList **list, const char *name); +extern NameList *duplicate_name_list(NameList *e); extern NameList *find_name_list(NameList *list, const char *name); extern NameList *find_name_list_match(NameList *list, const char *name); extern int minimum_msec_since_last_run(struct timeval *tv_old, long minimum); @@ -1205,6 +1206,7 @@ extern void add_nvplist_numeric_fmt(NameValuePrioList **lst, int priority, const extern NameValuePrioList *find_nvplist(NameValuePrioList *list, const char *name); extern const char *get_nvplist(NameValuePrioList *list, const char *name); extern void free_nvplist(NameValuePrioList *lst); +extern NameValuePrioList *duplicate_nvplist(NameValuePrioList *e); extern void unreal_add_name_values(NameValuePrioList **n, const char *name, ConfigEntry *ce); extern const char *namevalue(NameValuePrioList *n); extern const char *namevalue_nospaces(NameValuePrioList *n); @@ -1239,6 +1241,7 @@ extern void json_expand_tkl(json_t *j, const char *key, TKL *tkl, int detail); extern MODVAR SecurityGroup *securitygroups; extern void unreal_delete_masks(ConfigItem_mask *m); extern void unreal_add_masks(ConfigItem_mask **head, ConfigEntry *ce); +extern ConfigItem_mask *unreal_duplicate_masks(ConfigItem_mask *existing); extern int unreal_mask_match(Client *acptr, ConfigItem_mask *m); extern int unreal_mask_match_string(const char *name, ConfigItem_mask *m); extern int test_match_item(ConfigFile *conf, ConfigEntry *cep, int *errors); @@ -1249,6 +1252,7 @@ extern int security_group_exists(const char *name); extern SecurityGroup *add_security_group(const char *name, int order); extern SecurityGroup *find_security_group(const char *name); extern void free_security_group(SecurityGroup *s); +extern SecurityGroup *duplicate_security_group(SecurityGroup *s); extern void set_security_group_defaults(void); extern int user_allowed_by_security_group(Client *client, SecurityGroup *s); extern int user_allowed_by_security_group_name(Client *client, const char *secgroupname); diff --git a/src/conf.c b/src/conf.c index 5e5d83e0f..0e3e42348 100644 --- a/src/conf.c +++ b/src/conf.c @@ -4403,13 +4403,7 @@ int _test_proxy(ConfigFile *conf, ConfigEntry *ce) for (cep = ce->items; cep; cep = cep->next) { - if (!cep->value) - { - config_error_empty(cep->file->filename, cep->line_number, - "proxy", cep->name); - errors++; - continue; - } + /* This one can have no value so needs to be at the top */ if (!strcmp(cep->name, "mask") || !strcmp(cep->name, "match")) { if (cep->value || cep->items) @@ -4417,8 +4411,14 @@ int _test_proxy(ConfigFile *conf, ConfigEntry *ce) has_mask = 1; test_match_block(conf, cep, &errors); } - } - else if (!strcmp(cep->name, "password")) + } else + if (!cep->value) + { + config_error_empty(cep->file->filename, cep->line_number, + "proxy", cep->name); + errors++; + } else + if (!strcmp(cep->name, "password")) { if (has_password) { @@ -4510,21 +4510,9 @@ int _conf_proxy(ConfigFile *conf, ConfigEntry *ce) */ if (proxy->type == PROXY_WEB) { - ConfigItem_mask *m; - NameList *n; - for (m = proxy->mask->mask; m; m = m->next) - { - tkl_add_banexception(TKL_EXCEPTION, "*", m->mask, NULL, "proxy { } block", - "-config-", 0, TStime(), 0, "bcd", TKL_FLAG_CONFIG); - } - for (n = proxy->mask->ip; n; n = n->next) - { - char ip[64]; - if (strchr(n->name, '*') || strchr(n->name, '?')) - continue; /* we are not this advanced yet ;) */ - tkl_add_banexception(TKL_EXCEPTION, "*", n->name, NULL, "proxy { } block", - "-config-", 0, TStime(), 0, "bcd", TKL_FLAG_CONFIG); - } + SecurityGroup *sg = duplicate_security_group(proxy->mask); + tkl_add_banexception(TKL_EXCEPTION, "-", "-", sg, "proxy { } block", + "-config-", 0, TStime(), 0, "bcd", TKL_FLAG_CONFIG); } return 1; diff --git a/src/list.c b/src/list.c index da95d1765..d2e7a1c1a 100644 --- a/src/list.c +++ b/src/list.c @@ -559,6 +559,18 @@ void _free_entire_name_list(NameList *n) } } +NameList *duplicate_name_list(NameList *e) +{ + NameList *ret = NULL; + + if (e == NULL) + return NULL; + + for (; e; e = e->next) + add_name_list(ret, e->name); + return ret; +} + void _del_name_list(NameList **list, const char *name) { NameList *e = find_name_list(*list, name); @@ -660,6 +672,16 @@ void free_nvplist(NameValuePrioList *lst) } } +NameValuePrioList *duplicate_nvplist(NameValuePrioList *e) +{ + NameValuePrioList *n = NULL; + + for (; e; e = e->next) + add_nvplist(&n, e->priority, e->name, e->value); + + return n; +} + #define nv_find_by_name(stru, name) do_nv_find_by_name(stru, name, ARRAY_SIZEOF((stru))) long do_nv_find_by_name(NameValue *table, const char *cmd, int numelements) diff --git a/src/securitygroup.c b/src/securitygroup.c index 372520807..d885819b1 100644 --- a/src/securitygroup.c +++ b/src/securitygroup.c @@ -61,6 +61,20 @@ void unreal_add_masks(ConfigItem_mask **head, ConfigEntry *ce) } } +ConfigItem_mask *unreal_duplicate_masks(ConfigItem_mask *existing) +{ + ConfigItem_mask *ret = NULL; + ConfigItem_mask *n; + + for (; existing; existing = existing->next) + { + n = safe_alloc(sizeof(ConfigItem_mask)); + safe_strdup(n->mask, existing->mask); + AddListItem(n, ret); + } + return ret; +} + /** Check if a client matches any of the masks in the mask list. * The following rules apply: * - If you have only negating entries, like '!abc' and '!def', then @@ -576,6 +590,8 @@ void free_security_group(SecurityGroup *s) { if (s == NULL) return; + // IMPORTANT: if you add anything here, + // then also update duplicate_security_group() !!!! unreal_delete_masks(s->mask); unreal_delete_masks(s->exclude_mask); free_entire_name_list(s->security_group); @@ -589,6 +605,27 @@ void free_security_group(SecurityGroup *s) safe_free(s); } +/** Duplicate a SecurityGroup struct */ +SecurityGroup *duplicate_security_group(SecurityGroup *s) +{ + SecurityGroup *n; + + if (s == NULL) + return NULL; + + n = safe_alloc(sizeof(SecurityGroup)); + n->mask = unreal_duplicate_masks(s->mask); + n->exclude_mask = unreal_duplicate_masks(s->exclude_mask); + n->security_group = duplicate_name_list(s->security_group); + n->exclude_security_group = duplicate_name_list(s->exclude_security_group); + n->ip = duplicate_name_list(s->exclude_ip); + n->extended = duplicate_nvplist(s->extended); + n->exclude_extended = duplicate_nvplist(s->exclude_extended); + n->printable_list = duplicate_nvplist(s->printable_list); + // not duplicated since it makes no sense: s->settings + return n; +} + /** Initialize the default security-group blocks */ void set_security_group_defaults(void) {