Skip to content

Commit

Permalink
also run filters against pre-reg NICK
Browse files Browse the repository at this point in the history
  • Loading branch information
jesopo committed Feb 2, 2024
1 parent e5fe33f commit abc23d5
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 15 deletions.
49 changes: 39 additions & 10 deletions extensions/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
#include "operhash.h"
#include "inline/stringops.h"
#include "msgbuf.h"
#include "hostmask.h"
#include "s_conf.h"

#include <hs_common.h>
#include <hs_runtime.h>
Expand All @@ -56,7 +58,8 @@ static const char filter_desc[] = "Filter messages using a precompiled Hyperscan
static void filter_msg_user(void *data);
static void filter_msg_channel(void *data);
static void filter_client_quit(void *data);
static void filter_client_nick(void *data);
static void filter_client_nick_set(void *data);
static void filter_client_nick_change(void *data);
static void on_client_exit(void *data);

static void mo_setfilter(struct MsgBuf *, struct Client *, struct Client *, int, const char **);
Expand Down Expand Up @@ -94,7 +97,8 @@ mapi_hfn_list_av1 filter_hfnlist[] = {
{ "privmsg_user", filter_msg_user },
{ "privmsg_channel", filter_msg_channel },
{ "client_quit", filter_client_quit },
{ "local_nick_change", filter_client_nick },
{ "local_nick_set_approve", filter_client_nick_set },
{ "local_nick_change_approve", filter_client_nick_change },
{ "client_exit", on_client_exit },
{ NULL, NULL }
};
Expand Down Expand Up @@ -353,21 +357,21 @@ unsigned match_message(const char *prefix,
snprintf(check_buffer, sizeof check_buffer, "%s:%s!%s@%s#%c %s%s%s :%s",
prefix,
#if FILTER_NICK
source->name,
source ? source->name : "*",
#else
"*",
#endif
#if FILTER_USER
source->username,
source ? source->username : "*",
#else
"*",
#endif
#if FILTER_HOST
source->host,
source ? source->host : "*",
#else
"*",
#endif
source->user && source->user->suser[0] != '\0' ? '1' : '0',
source && source->user && source->user->suser[0] != '\0' ? '1' : '0',
command,
target ? " " : "",
target ? target : "",
Expand Down Expand Up @@ -486,17 +490,17 @@ filter_client_quit(void *data_)
}

void
filter_client_nick(void *data_)
filter_client_nick_change(void *data_)
{
hook_cdata *data = data_;
hook_data_nick_approval *data = data_;
struct Client *s = data->client;
if (IsOper(s)) {
return;
}

unsigned r = match_message("0", s, "NICK", NULL, data->arg2);
unsigned r = match_message("0", s, "NICK", NULL, data->nick);
if (r & ACT_DROP) {
data->arg2 = NULL;
data->approved = 0;
}
if (r & ACT_ALARM) {
sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
Expand All @@ -508,6 +512,31 @@ filter_client_nick(void *data_)
}
}

void
filter_client_nick_set(void *data_)
{
hook_data_nick_approval *data = data_;
struct Client *s = data->client;
struct sockaddr *addr = (void *)&s->localClient->ip;

if(find_conf_by_address(
NULL, NULL, NULL, addr, CONF_EXEMPTDLINE | 1, GET_SS_FAMILY(addr), NULL, NULL))
return;

unsigned r = match_message("0", NULL, "NICK", NULL, data->nick);
if (r & ACT_DROP) {
data->approved = 0;
}
if (r & ACT_ALARM) {
sendto_realops_snomask(SNO_GENERAL, L_ALL | L_NETWIDE,
"FILTER:REGISTER: %s@%s",
s->id, s->sockhost);
}
if (r & ACT_KILL) {
exit_client(NULL, s, s, FILTER_EXIT_MSG);
}
}

void
on_client_exit(void *data_)
{
Expand Down
8 changes: 8 additions & 0 deletions include/hook.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,14 @@ typedef struct
int del;
} hook_data_cap_change;

typedef struct
{
struct Client *client;
const void *nick;
int approved;
} hook_data_nick_approval;


enum message_type {
MESSAGE_TYPE_NOTICE,
MESSAGE_TYPE_PRIVMSG,
Expand Down
33 changes: 28 additions & 5 deletions modules/core/m_nick.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ static void perform_nick_collides(struct Client *, struct Client *,
static void perform_nickchange_collides(struct Client *, struct Client *,
struct Client *, int, const char **, time_t, const char *);

static int h_local_nick_set_approve;
static int h_local_nick_change;
static int h_local_nick_change_approve;
static int h_remote_nick_change;

struct Message nick_msgtab = {
Expand All @@ -103,7 +105,9 @@ mapi_clist_av1 nick_clist[] = { &nick_msgtab, &uid_msgtab, &euid_msgtab,
&save_msgtab, NULL };

mapi_hlist_av1 nick_hlist[] = {
{ "local_nick_set_approve", &h_local_nick_set_approve },
{ "local_nick_change", &h_local_nick_change },
{ "local_nick_change_approve", &h_local_nick_change_approve },
{ "remote_nick_change", &h_remote_nick_change },
{ NULL, NULL }
};
Expand All @@ -121,6 +125,7 @@ mr_nick(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
{
struct Client *target_p;
char nick[NICKLEN];
hook_data_nick_approval hook_approve;

if (strlen(client_p->id) == 3 || (source_p->preClient && !EmptyString(source_p->preClient->id)))
{
Expand Down Expand Up @@ -161,6 +166,18 @@ mr_nick(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
return;
}

hook_approve.client = source_p;
hook_approve.nick = nick;
hook_approve.approved = 1;
call_hook(h_local_nick_set_approve, &hook_approve);

if (!hook_approve.approved) {
/* send the same error they'd get if this nick was RESV */
sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME),
me.name, EmptyString(source_p->name) ? "*" : source_p->name, nick);
return;
}

if((target_p = find_named_client(nick)) == NULL)
set_initial_nick(client_p, source_p, nick);
else if(source_p == target_p)
Expand Down Expand Up @@ -622,6 +639,7 @@ change_local_nick(struct Client *client_p, struct Client *source_p,
struct Channel *chptr;
char note[NICKLEN + 10];
int samenick;
hook_data_nick_approval hook_approve;
hook_cdata hook_info;

if (dosend)
Expand Down Expand Up @@ -666,17 +684,22 @@ change_local_nick(struct Client *client_p, struct Client *source_p,
invalidate_bancache_user(source_p);
}

hook_info.client = source_p;
hook_info.arg1 = source_p->name;
hook_info.arg2 = nick;
call_hook(h_local_nick_change, &hook_info);
hook_approve.client = source_p;
hook_approve.nick = nick;
hook_approve.approved = 1;
call_hook(h_local_nick_change_approve, &hook_approve);

if (!hook_info.arg2) {
if (!hook_approve.approved) {
sendto_one(source_p, form_str(ERR_ERRONEUSNICKNAME),
me.name, EmptyString(source_p->name) ? "*" : source_p->name, nick);
return;
}

hook_info.client = source_p;
hook_info.arg1 = source_p->name;
hook_info.arg2 = nick;
call_hook(h_local_nick_change, &hook_info);

sendto_realops_snomask(SNO_NCHANGE, L_ALL,
"Nick change: From %s to %s [%s@%s]",
source_p->name, nick, source_p->username, source_p->host);
Expand Down

0 comments on commit abc23d5

Please sign in to comment.