1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-01 08:16:38 +02:00

Add security-group::rule support, see https://www.unrealircd.org/docs/Crule

This commit is contained in:
Bram Matthys
2023-07-16 12:06:34 +02:00
parent 59c6c99ba3
commit b272b6700a
5 changed files with 60 additions and 5 deletions
+1
View File
@@ -921,6 +921,7 @@ extern MODVAR int (*spamreport)(Client *client, const char *ip, NameValuePrioLis
extern MODVAR int (*crule_test)(const char *rule);
extern MODVAR CRuleNode *(*crule_parse)(const char *rule);
extern int (*crule_eval)(crule_context *context, CRuleNode *rule);
#define safe_crule_free(x) do { if (x) crule_free(&x); } while(0)
extern void (*crule_free)(CRuleNode **);
extern const char *(*crule_errstring)(int errcode);
/* /Efuncs */
+4
View File
@@ -2157,6 +2157,8 @@ struct SecurityGroup {
NameList *ip;
ConfigItem_mask *mask;
NameList *security_group;
char *prettyrule; /* ::rule as a string */
CRuleNode *rule; /**< parsed crule */
NameValuePrioList *extended;
/* Exclude */
int exclude_identified;
@@ -2168,6 +2170,8 @@ struct SecurityGroup {
NameList *exclude_ip;
ConfigItem_mask *exclude_mask;
NameList *exclude_security_group;
char *exclude_prettyrule; /* ::exclude-rule as a string */
CRuleNode *exclude_rule; /**< parsed crule */
NameValuePrioList *exclude_extended;
/* Settings */
DynamicSetBlock settings;
+1 -1
View File
@@ -181,7 +181,7 @@ void server_config_free(void)
{
d_next = d->next;
unreal_delete_masks(d->mask);
crule_free(&d->rule);
safe_crule_free(d->rule);
safe_free(d->prettyrule);
safe_free(d->reason);
DelListItem(d, conf_deny_link);
+1 -2
View File
@@ -2945,8 +2945,7 @@ void _free_tkl(TKL *tkl)
safe_free(tkl->ptr.spamfilter->tkl_reason);
if (tkl->ptr.spamfilter->match)
unreal_delete_match(tkl->ptr.spamfilter->match);
if (tkl->ptr.spamfilter->rule)
crule_free(&tkl->ptr.spamfilter->rule);
safe_crule_free(tkl->ptr.spamfilter->rule);
safe_free_all_ban_actions(tkl->ptr.spamfilter->action);
safe_free(tkl->ptr.spamfilter->prettyrule);
safe_free(tkl->ptr.spamfilter->id);
+53 -2
View File
@@ -249,6 +249,18 @@ int test_match_item(ConfigFile *conf, ConfigEntry *cep, int *errors)
if (!strcmp(cep->name, "security-group") || !strcmp(cep->name, "exclude-security-group"))
{
} else
if (!strcmp(cep->name, "rule") || !strcmp(cep->name, "exclude-rule"))
{
int val = crule_test(cep->value);
if (val)
{
config_error("%s:%i: rule contains an invalid expression: %s",
cep->file->filename,
cep->line_number,
crule_errstring(val));
errors++;
}
} else
{
/* Let's see if an extended server ban exists for this item... */
Extban *extban;
@@ -418,6 +430,11 @@ int conf_match_item(ConfigFile *conf, ConfigEntry *cep, SecurityGroup **block)
{
unreal_add_names(&s->security_group, cep);
}
else if (!strcmp(cep->name, "rule"))
{
safe_strdup(s->prettyrule, cep->value);
s->rule = crule_parse(s->prettyrule);
}
else if (!strcmp(cep->name, "exclude-webirc"))
s->exclude_webirc = config_checkval(cep->value, CFG_YESNO);
else if (!strcmp(cep->name, "exclude-websocket"))
@@ -441,6 +458,11 @@ int conf_match_item(ConfigFile *conf, ConfigEntry *cep, SecurityGroup **block)
{
unreal_add_names(&s->security_group, cep);
}
else if (!strcmp(cep->name, "exclude-rule"))
{
safe_strdup(s->exclude_prettyrule, cep->value);
s->exclude_rule = crule_parse(s->exclude_prettyrule);
}
else
{
/* Let's see if an extended server ban exists for this item... this needs to be LAST! */
@@ -599,6 +621,10 @@ void free_security_group(SecurityGroup *s)
unreal_delete_masks(s->exclude_mask);
free_entire_name_list(s->security_group);
free_entire_name_list(s->exclude_security_group);
safe_crule_free(s->rule);
safe_crule_free(s->exclude_rule);
safe_free(s->prettyrule);
safe_free(s->exclude_prettyrule);
free_entire_name_list(s->ip);
free_entire_name_list(s->exclude_ip);
free_nvplist(s->extended);
@@ -621,6 +647,16 @@ SecurityGroup *duplicate_security_group(SecurityGroup *s)
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);
if (s->prettyrule)
{
safe_strdup(n->prettyrule, s->prettyrule);
n->rule = crule_parse(n->prettyrule);
}
if (s->exclude_prettyrule)
{
safe_strdup(n->exclude_prettyrule, s->exclude_prettyrule);
n->exclude_rule = crule_parse(n->exclude_prettyrule);
}
n->ip = duplicate_name_list(s->exclude_ip);
n->extended = duplicate_nvplist(s->extended);
n->exclude_extended = duplicate_nvplist(s->exclude_extended);
@@ -746,6 +782,17 @@ int user_allowed_by_security_group_list(Client *client, NameList *l)
return 0;
}
/** Helper for security-group::rule and mask::rule */
int user_allowed_by_rule(Client *client, CRuleNode *rule)
{
crule_context context;
memset(&context, 0, sizeof(context));
context.client = client;
return crule_eval(&context, rule);
}
/** Returns 1 if the user is OK as far as the security-group is concerned.
* @param client The client to check
* @param s The security-group to check against
@@ -799,10 +846,12 @@ int user_allowed_by_security_group(Client *client, SecurityGroup *s)
goto user_not_allowed;
if (s->exclude_ip && unreal_match_iplist(client, s->exclude_ip))
goto user_not_allowed;
if (s->exclude_security_group && user_allowed_by_security_group_list(client, s->exclude_security_group))
if (s->exclude_rule && user_allowed_by_rule(client, s->exclude_rule))
goto user_not_allowed;
if (s->exclude_extended && user_matches_extended_list(client, s->exclude_extended))
goto user_not_allowed;
if (s->exclude_security_group && user_allowed_by_security_group_list(client, s->exclude_security_group))
goto user_not_allowed;
/* Then process INCLUSION criteria... */
if (s->identified && IsLoggedIn(client))
@@ -829,10 +878,12 @@ int user_allowed_by_security_group(Client *client, SecurityGroup *s)
goto user_allowed;
if (s->ip && unreal_match_iplist(client, s->ip))
goto user_allowed;
if (s->security_group && user_allowed_by_security_group_list(client, s->security_group))
if (s->rule && user_allowed_by_rule(client, s->rule))
goto user_allowed;
if (s->extended && user_matches_extended_list(client, s->extended))
goto user_allowed;
if (s->security_group && user_allowed_by_security_group_list(client, s->security_group))
goto user_allowed;
user_not_allowed:
recursion_security_group--;