Skip to content
This repository has been archived by the owner on Jun 24, 2021. It is now read-only.

Allow extensions to extend channel ban matching and add extensions/match_gatewayip #368

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions extensions/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ extension_LTLIBRARIES = \
spy_stats_p_notice.la \
spy_trace_notice.la \
drain.la \
match_gatewayip.la \
example_module.la

if HAVE_HYPERSCAN
Expand Down
2 changes: 1 addition & 1 deletion extensions/extb_canjoin.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static int eb_canjoin(const char *data, struct Client *client_p,
return EXTBAN_INVALID;
#endif
recurse = 1;
ret = is_banned(chptr2, client_p, NULL, NULL, NULL) == CHFL_BAN ? EXTBAN_MATCH : EXTBAN_NOMATCH;
ret = is_banned(chptr2, client_p, NULL, NULL, NULL, NULL) == CHFL_BAN ? EXTBAN_MATCH : EXTBAN_NOMATCH;
recurse = 0;
return ret;
}
2 changes: 1 addition & 1 deletion extensions/extb_hostmask.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ _moddeinit(void)
static int
eb_hostmask(const char *banstr, struct Client *client_p, struct Channel *chptr, long mode_type)
{
return client_matches_mask(client_p, banstr) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
return client_matches_mask(client_p, banstr, mode_type) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
}
53 changes: 53 additions & 0 deletions extensions/match_gatewayip.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (C) 2020 Ed Kellett
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/

#include <stdinc.h>
#include <modules.h>
#include <hook.h>
#include <match.h>
#include <channel.h>

static const char match_gatewayip_desc[] = "Consider .../ip.X.X.X.X hostnames in channel IP ban matching";

static void hook_match_client(void *);

mapi_hfn_list_av1 match_gatewayip_hfnlist[] = {
{ "match_client", hook_match_client },
{ NULL, NULL }
};

void hook_match_client(void *data_)
{
hook_data_match_client *data = data_;
const char *p;

if (data->mode_type != CHFL_BAN && data->mode_type != CHFL_QUIET)
return;

if (!IsDynSpoof(data->client))
return;

p = strstr(data->client->host, "/ip.");
if (p == NULL)
return;

matchset_append_ip(data->ms, "%s!%s@%s", data->client->name, data->client->username, p + 4);
}

DECLARE_MODULE_AV2(match_gatewayip, NULL, NULL, NULL, NULL, match_gatewayip_hfnlist, NULL, NULL, match_gatewayip_desc);
6 changes: 5 additions & 1 deletion include/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,13 @@ extern bool flood_attack_channel(int p_or_n, struct Client *source_p,
struct matchset;
extern int is_banned(struct Channel *chptr, struct Client *who,
struct membership *msptr, const struct matchset *ms,
const struct matchset *mexcept,
const char **);
extern int is_quieted(struct Channel *chptr, struct Client *who,
struct membership *msptr, const struct matchset *ms);
struct membership *msptr, const struct matchset *ms,
const struct matchset *mexcept);
extern int is_borq(struct Channel *chptr, struct Client *who,
struct membership *msptr);
extern int can_join(struct Client *source_p, struct Channel *chptr,
const char *key, const char **forward);

Expand Down
8 changes: 8 additions & 0 deletions include/hook.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ extern int h_conf_read_start;
extern int h_conf_read_end;
extern int h_outbound_msgbuf;
extern int h_rehash;
extern int h_match_client;

void init_hook(void);
int register_hook(const char *name);
Expand Down Expand Up @@ -168,4 +169,11 @@ typedef struct
bool signal;
} hook_data_rehash;

typedef struct
{
struct Client *client;
struct matchset *ms;
long mode_type;
} hook_data_match_client;

#endif
9 changes: 7 additions & 2 deletions include/match.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,21 @@ extern char *collapse(char *pattern);
extern char *collapse_esc(char *pattern);

struct matchset {
size_t hostn;
size_t ipn;
char host[2][NAMELEN + USERLEN + HOSTLEN + 6];
char ip[2][NAMELEN + USERLEN + HOSTIPLEN + 6];
};

struct Client;

void matchset_for_client(struct Client *who, struct matchset *m);
bool client_matches_mask(struct Client *who, const char *mask);
void matchset_for_client(struct Client *who, struct matchset *m, long mode_type);
bool client_matches_mask(struct Client *who, const char *mask, long mode_type);
bool matches_mask(const struct matchset *m, const char *mask);

void matchset_append_host(struct matchset *m, const char *fmt, ...);
void matchset_append_ip(struct matchset *m, const char *fmt, ...);

/*
* irccmp - case insensitive comparison of s1 and s2
*/
Expand Down
63 changes: 43 additions & 20 deletions ircd/channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,9 +537,10 @@ del_invite(struct Channel *chptr, struct Client *who)
static int
is_banned_list(struct Channel *chptr, rb_dlink_list *list,
struct Client *who, struct membership *msptr,
const struct matchset *ms, const char **forward)
const struct matchset *ms, const struct matchset *mexcept,
const char **forward)
{
struct matchset ms_;
struct matchset ms_, mexcept_;
rb_dlink_node *ptr;
struct Ban *actualBan = NULL;
struct Ban *actualExcept = NULL;
Expand All @@ -549,10 +550,16 @@ is_banned_list(struct Channel *chptr, rb_dlink_list *list,

if (ms == NULL)
{
matchset_for_client(who, &ms_);
matchset_for_client(who, &ms_, CHFL_BAN);
ms = &ms_;
}

if (mexcept == NULL)
{
matchset_for_client(who, &mexcept_, CHFL_EXCEPTION);
mexcept = &mexcept_;
}

RB_DLINK_FOREACH(ptr, list->head)
{
actualBan = ptr->data;
Expand All @@ -570,7 +577,7 @@ is_banned_list(struct Channel *chptr, rb_dlink_list *list,
actualExcept = ptr->data;

/* theyre exempted.. */
if (matches_mask(ms, actualExcept->banstr) ||
if (matches_mask(mexcept, actualExcept->banstr) ||
match_extban(actualExcept->banstr, who, chptr, CHFL_BAN))
{
/* cache the fact theyre not banned */
Expand Down Expand Up @@ -617,7 +624,7 @@ is_banned_list(struct Channel *chptr, rb_dlink_list *list,
*/
int
is_banned(struct Channel *chptr, struct Client *who, struct membership *msptr,
const struct matchset *ms, const char **forward)
const struct matchset *ms, const struct matchset *mexcept, const char **forward)
{
#if 0
if (chptr->last_checked_client != NULL &&
Expand All @@ -633,7 +640,7 @@ is_banned(struct Channel *chptr, struct Client *who, struct membership *msptr,

return chptr->last_checked_result;
#else
return is_banned_list(chptr, &chptr->banlist, who, msptr, ms, forward);
return is_banned_list(chptr, &chptr->banlist, who, msptr, ms, mexcept, forward);
#endif
}

Expand All @@ -646,7 +653,7 @@ is_banned(struct Channel *chptr, struct Client *who, struct membership *msptr,
*/
int
is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr,
const struct matchset *ms)
const struct matchset *ms, const struct matchset *mexcept)
{
#if 0
if (chptr->last_checked_client != NULL &&
Expand All @@ -662,10 +669,28 @@ is_quieted(struct Channel *chptr, struct Client *who, struct membership *msptr,

return chptr->last_checked_result;
#else
return is_banned_list(chptr, &chptr->quietlist, who, msptr, ms, NULL);
return is_banned_list(chptr, &chptr->quietlist, who, msptr, ms, mexcept, NULL);
#endif
}

int
is_borq(struct Channel *chptr, struct Client *who, struct membership *msptr)
{
struct matchset ms, mexcept;
int r;

if (!MyClient(who))
return 0;

matchset_for_client(who, &ms, CHFL_BAN);
matchset_for_client(who, &mexcept, CHFL_EXCEPTION);

if ((r = is_banned(chptr, who, msptr, &ms, &mexcept, NULL)))
return r;

return is_quieted(chptr, who, msptr, &ms, &mexcept);
}

/* can_join()
*
* input - client to check, channel to check for, key
Expand All @@ -679,7 +704,6 @@ can_join(struct Client *source_p, struct Channel *chptr, const char *key, const
rb_dlink_node *invite = NULL;
rb_dlink_node *ptr;
struct Ban *invex = NULL;
struct matchset ms;
int i = 0;
hook_data_channel moduledata;

Expand All @@ -689,9 +713,7 @@ can_join(struct Client *source_p, struct Channel *chptr, const char *key, const
moduledata.chptr = chptr;
moduledata.approved = 0;

matchset_for_client(source_p, &ms);

if((is_banned(chptr, source_p, NULL, &ms, forward)) == CHFL_BAN)
if((is_banned(chptr, source_p, NULL, NULL, NULL, forward)) == CHFL_BAN)
{
moduledata.approved = ERR_BANNEDFROMCHAN;
goto finish_join_check;
Expand All @@ -709,6 +731,9 @@ can_join(struct Client *source_p, struct Channel *chptr, const char *key, const

if(chptr->mode.mode & MODE_INVITEONLY)
{
struct matchset ms;
matchset_for_client(source_p, &ms, CHFL_INVEX);

RB_DLINK_FOREACH(invite, source_p->user->invited.head)
{
if(invite->data == chptr)
Expand Down Expand Up @@ -813,9 +838,11 @@ can_send(struct Channel *chptr, struct Client *source_p, struct membership *mspt
if(can_send_banned(msptr))
moduledata.approved = CAN_SEND_NO;
}
else if(is_banned(chptr, source_p, msptr, NULL, NULL) == CHFL_BAN
|| is_quieted(chptr, source_p, msptr, NULL) == CHFL_BAN)
moduledata.approved = CAN_SEND_NO;
else
{
if (is_borq(chptr, source_p, msptr) == CHFL_BAN)
moduledata.approved = CAN_SEND_NO;
}
}

if(is_chanop_voiced(msptr))
Expand Down Expand Up @@ -898,13 +925,10 @@ find_bannickchange_channel(struct Client *client_p)
struct Channel *chptr;
struct membership *msptr;
rb_dlink_node *ptr;
struct matchset ms;

if (!MyClient(client_p))
return NULL;

matchset_for_client(client_p, &ms);

RB_DLINK_FOREACH(ptr, client_p->user->channel.head)
{
msptr = ptr->data;
Expand All @@ -917,8 +941,7 @@ find_bannickchange_channel(struct Client *client_p)
if (can_send_banned(msptr))
return chptr;
}
else if (is_banned(chptr, client_p, msptr, &ms, NULL) == CHFL_BAN
|| is_quieted(chptr, client_p, msptr, &ms) == CHFL_BAN)
else if (is_borq(chptr, client_p, msptr) == CHFL_BAN)
return chptr;
}
return NULL;
Expand Down
2 changes: 2 additions & 0 deletions ircd/hook.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ int h_conf_read_start;
int h_conf_read_end;
int h_outbound_msgbuf;
int h_rehash;
int h_match_client;

void
init_hook(void)
Expand All @@ -95,6 +96,7 @@ init_hook(void)
h_conf_read_end = register_hook("conf_read_end");
h_outbound_msgbuf = register_hook("outbound_msgbuf");
h_rehash = register_hook("rehash");
h_match_client = register_hook("match_client");
}

/* grow_hooktable()
Expand Down
Loading