1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-04 04:03:13 +02:00

Add security-group::server-port and similary in match item, to match

users by server port (eg 6667, 6697, 8000, etc).

This also adds security-group::exclude-server-port for consistency.

And in crules the function server_port() returns the server port number,
so you can use rule 'server_port()>6690' for example.

Note that for remote clients this will only work after previous
commit (b2d0ec1af3) is loaded on all
servers, otherwise all remote clients are seen as having a server_port
of zero (0). Though you probably usually only care about this on local
users anyway.
This commit is contained in:
Bram Matthys
2025-09-14 17:25:34 +02:00
parent b2d0ec1af3
commit 817abc4101
5 changed files with 42 additions and 0 deletions
+1
View File
@@ -1207,6 +1207,7 @@ 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 NameList *find_name_list_integer(NameList *list, int v);
extern int minimum_msec_since_last_run(struct timeval *tv_old, long minimum);
extern int unrl_utf8_validate(const char *str, const char **end);
extern char *unrl_utf8_make_valid(const char *str, char *outputbuf, size_t outputbuflen, int strict_length_check);
+2
View File
@@ -2242,6 +2242,7 @@ struct SecurityGroup {
int tls;
NameList *ip;
ConfigItem_mask *mask;
NameList *server_port;
NameList *security_group;
char *prettyrule; /* ::rule as a string */
CRuleNode *rule; /**< parsed crule */
@@ -2256,6 +2257,7 @@ struct SecurityGroup {
int exclude_tls;
NameList *exclude_ip;
ConfigItem_mask *exclude_mask;
NameList *exclude_server_port;
NameList *exclude_security_group;
char *exclude_prettyrule; /* ::exclude-rule as a string */
CRuleNode *exclude_rule; /**< parsed crule */
+10
View File
@@ -618,6 +618,16 @@ NameList *find_name_list_match(NameList *list, const char *name)
return NULL;
}
/** Find an entry in a NameList - argument is an integer.
* @ingroup ListFunctions
*/
NameList *find_name_list_integer(NameList *list, int v)
{
char buf[32];
snprintf(buf, sizeof(buf), "%d", v);
return find_name_list(list, buf);
}
NameValuePrioList *add_nvplist(NameValuePrioList **lst, int priority, const char *name, const char *value)
{
va_list vl;
+10
View File
@@ -145,6 +145,7 @@ static int crule_match_asn(crule_context *, int, void **);
static int crule_match_certfp(crule_context *, int, void **);
static int crule_match_realname(crule_context *, int, void **);
static int crule_unicode_count(crule_context *, int, void **);
static int crule_server_port(crule_context *, int, void **);
/* parsing function prototypes - local! */
static int crule_gettoken(crule_token *next_tokp, const char **str);
@@ -206,6 +207,7 @@ struct crule_funclistent crule_funclist[] = {
{"match_certfp", 1, crule_match_certfp},
{"match_realname", 1, crule_match_realname},
{"unicode_count", 1, crule_unicode_count},
{"server_port", 0, crule_server_port},
{"", 0, NULL} /* this must be here to mark end of list */
};
@@ -566,6 +568,14 @@ static int crule_unicode_count(crule_context *context, int numargs, void *crulea
return 0;
}
static int crule_server_port(crule_context *context, int numargs, void *crulearg[])
{
if (context && context->client)
return get_server_port(context->client);
return 0;
}
/** Evaluate a connection rule.
* @param[in] rule Rule to evalute.
* @return Non-zero if the rule allows the connection, zero otherwise.
+19
View File
@@ -246,6 +246,9 @@ int test_match_item(ConfigFile *conf, ConfigEntry *cep, int *errors)
if (!strcmp(cep->name, "ip") || !strcmp(cep->name, "exclude-ip"))
{
} else
if (!strcmp(cep->name, "server-port") || !strcmp(cep->name, "exclude-server-port"))
{
} else
if (!strcmp(cep->name, "security-group") || !strcmp(cep->name, "exclude-security-group"))
{
} else
@@ -437,6 +440,10 @@ int conf_match_item(ConfigFile *conf, ConfigEntry *cep, SecurityGroup **block)
{
unreal_add_names(&s->ip, cep);
}
else if (!strcmp(cep->name, "server-port"))
{
unreal_add_names(&s->server_port, cep);
}
else if (!strcmp(cep->name, "security-group"))
{
unreal_add_names(&s->security_group, cep);
@@ -473,6 +480,10 @@ int conf_match_item(ConfigFile *conf, ConfigEntry *cep, SecurityGroup **block)
{
unreal_add_names(&s->exclude_ip, cep);
}
else if (!strcmp(cep->name, "exclude-server-port"))
{
unreal_add_names(&s->exclude_server_port, cep);
}
else if (!strcmp(cep->name, "exclude-security-group"))
{
unreal_add_names(&s->exclude_security_group, cep);
@@ -657,6 +668,8 @@ void free_security_group(SecurityGroup *s)
safe_free(s->exclude_prettyrule);
free_entire_name_list(s->ip);
free_entire_name_list(s->exclude_ip);
free_entire_name_list(s->server_port);
free_entire_name_list(s->exclude_server_port);
free_nvplist(s->extended);
free_nvplist(s->exclude_extended);
free_nvplist(s->printable_list);
@@ -691,6 +704,8 @@ SecurityGroup *duplicate_security_group(SecurityGroup *s)
}
n->ip = duplicate_name_list(s->ip);
n->exclude_ip = duplicate_name_list(s->exclude_ip);
n->server_port = duplicate_name_list(s->server_port);
n->exclude_server_port = duplicate_name_list(s->exclude_server_port);
n->extended = duplicate_nvplist(s->extended);
n->exclude_extended = duplicate_nvplist(s->exclude_extended);
n->printable_list = duplicate_nvplist(s->printable_list);
@@ -876,6 +891,8 @@ int user_allowed_by_security_group_context(Client *client, SecurityGroup *s, cru
goto user_not_allowed;
if (s->exclude_ip && unreal_match_iplist(client, s->exclude_ip))
goto user_not_allowed;
if (s->exclude_server_port && find_name_list_integer(s->exclude_server_port, get_server_port(client)))
goto user_not_allowed;
if (s->exclude_rule && crule_eval(context, s->exclude_rule))
goto user_not_allowed;
if (s->exclude_extended && user_matches_extended_list(client, s->exclude_extended))
@@ -925,6 +942,8 @@ int user_allowed_by_security_group_context(Client *client, SecurityGroup *s, cru
goto user_allowed;
if (s->ip && unreal_match_iplist(client, s->ip))
goto user_allowed;
if (s->server_port && find_name_list_integer(s->server_port, get_server_port(client)))
goto user_allowed;
if (s->rule && crule_eval(context, s->rule))
goto user_allowed;
if (s->extended && user_matches_extended_list(client, s->extended))