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

Chained extbans support.

This commit is contained in:
aquanight
2007-05-13 23:09:24 +00:00
parent ee3c5683db
commit 2c7a3f2e66
7 changed files with 236 additions and 2 deletions
+19
View File
@@ -1669,3 +1669,22 @@ MOTDs
- Removed class.h and minor references to aClass. Patched by WolfSage
- Changed all references to 'class' to 'cclass' (connection class) - to
avoid some keyword confusion and other wacky ideas
- Added support for "chained" extbans. Put simply this allows extban combinations
such as ~q:~c:#test to only silence users on #test, for example. This feature
is enabled by default, but can be disabled during ./Config -advanced. Module
support for this feature must note the following:
- For is_ok function, the extban can either assign extban_is_ok_nuh_extban, which
will deal checking a chained extban (including checking for restricted extbans),
or it can call that function from its own is_ok routine. For the latter case,
remember to pass only the mask part of your ban format (ie, don't just pass para as
otherwise it'll just call your is_ok again).
- For conv_param function, the extban can either assign extban_conv_param_nuh_or_extban,
which will automatically call conv_param for a chained extban, or pretty up a n!u@h mask.
- For is_banned, the extban should call ban_check_mask with the mask part of the parameter.
This will automatically call is_banned for a stacked extban, or match against a n!u@h. n!u@h
is checked against the current user (ie, with the info in the globals ban_ip, etc), so things
can get weird if you call this outside a normal ban check.
Modules must keep in mind that chained extban support is not available (and neither are the three
functions above) if DISABLE_STACKED_EXTBANS is #defined (this is controled by Config). Modules will
not compile/load if they try to use them anyway.
This change should not break extban modules, and should need some more extensive testing.
+34
View File
@@ -41,6 +41,9 @@ fi
if [ "$OPEROVERRIDEVERIFY" = "1" ] ; then
ARG="$ARG--with-operoverride-verify "
fi
if [ "$DISABLEEXTBANSTACKING" = "1" ]; then
ARG="$ARG--with-disable-extendedban-stacking ";
fi
fi
if [ "$NOSPOOF" = "1" ] ; then
ARG="$ARG--enable-nospoof "
@@ -274,6 +277,35 @@ while [ -z "$TEST" ] ; do
esac
done
TEST=""
while [ -z "$TEST" ] ; do
if [ "$DISABLEEXTBANSTACKING" = "1" ] ; then
TEST="Yes"
else
TEST="No"
fi
echo ""
echo "Do you want to disable extended ban stacking (~q:~c:#test, etc) support?"
echo $n "[$TEST] -> $c"
read cc
if [ -z "$cc" ] ; then
cc=$TEST
fi
case "$cc" in
[Yy]*)
DISABLEEXTBANSTACKING="1"
;;
[Nn]*)
DISABLEEXTBANSTACKING="0"
;;
*)
echo ""
echo "You must enter either Yes or No"
TEST=""
;;
esac
done
}
c=""
n=""
@@ -302,6 +334,7 @@ SHUNNOTICES=""
NOOPEROVERRIDE=""
DISABLEUSERMOD=""
OPEROVERRIDEVERIFY=""
DISABLEEXTBANSTACKING=""
EXTRAPARA=""
if [ "`eval echo -n 'a'`" = "-n a" ] ; then
c="\c"
@@ -838,6 +871,7 @@ SHUNNOTICES="$SHUNNOTICES"
NOOPEROVERRIDE="$NOOPEROVERRIDE"
DISABLEUSERMOD="$DISABLEUSERMOD"
OPEROVERRIDEVERIFY="$OPEROVERRIDEVERIFY"
DISABLEEXTBANSTACKING="$DISABLEEXTBANSTACKING"
EXTRAPARA="$EXTRAPARA"
ADVANCED="$ADVANCED"
__EOF__
Vendored
+11
View File
@@ -874,6 +874,8 @@ Optional Packages:
--with-disableusermod Disable /set* and /chg*
--with-operoverride-verify
Require opers to invite themselves to +s/+p channels
--with-disable-extendedban-stacking
Disable extended ban stacking (~q:~c:#chan) support
Some influential environment variables:
CC C compiler command
@@ -12025,6 +12027,15 @@ _ACEOF
fi;
# Check whether --with-disable-extendedban-stacking or --without-disable-extendedban-stacking was given.
if test "${with_disable_extendedban_stacking+set}" = set; then
withval="$with_disable_extendedban_stacking"
cat >>confdefs.h <<\_ACEOF
#define DISABLE_STACKED_EXTBANS 1
_ACEOF
fi;
# Check whether --enable-ssl or --disable-ssl was given.
if test "${enable_ssl+set}" = set; then
enableval="$enable_ssl"
+5
View File
@@ -186,6 +186,11 @@ extern long get_access(aClient *, aChannel *);
extern int is_chan_op(aClient *, aChannel *);
extern int has_voice(aClient *, aChannel *);
extern int is_chanowner(aClient *, aChannel *);
#ifndef DISABLE_EXTBAN_STACKING
extern int ban_check_mask(aClient *, aChannel *, char *, int, int);
extern int extban_is_ok_nuh_extban(aClient *, aChannel *, char *, int, int, int);
extern char* extban_conv_param_nuh_extban(char *);
#endif
extern Ban *is_banned(aClient *, aChannel *, int);
extern Ban *is_banned_with_nick(aClient *, aChannel *, int, char *);
extern int parse_help(aClient *, char *, char *);
+3
View File
@@ -240,6 +240,9 @@
/* Define if you want to disable /set* and /chg* */
#undef DISABLE_USERMOD
/* Define to disable extended ban stacking (~q:~c:#chan, etc) */
#undef DISABLE_STACKED_EXTBANS
/* Define if your system prepends an underscore to symbols */
#undef UNDERSCORE
+52 -1
View File
@@ -447,6 +447,46 @@ inline Ban *is_banned(aClient *sptr, aChannel *chptr, int type)
return is_banned_with_nick(sptr, chptr, type, sptr->name);
}
#ifndef DISABLE_STACKED_EXTBANS
/** ban_check_mask - Checks if the current user in ban checking (ban_ip, etc) matches the specified n!u@h mask -or- run an extended ban.
* @param sptr Client to check (can be remote client)
* @param chptr Channel to check
* @param banstr Mask string to check user
* @param type Type of ban to check for (BANCHK_*)
* @param no_extbans 0 to check extbans, nonzero to disable extban checking.
* @returns Nonzero if the mask/extban succeeds. Zero if it doesn't.
* @comments This is basically extracting the mask and extban check from is_banned_with_nick, but with being a bit more strict in what an extban is.
* Strange things could happen if this is called outside standard ban checking.
*/
inline int ban_check_mask(aClient* sptr, aChannel* chptr, char* banstr, int type, int no_extbans)
{
Extban *extban = NULL;
if (!no_extbans && banstr[0] == '~' && banstr[1] != '\0' && banstr[2] == ':')
{
/* Is an extended ban. */
extban = findmod_by_bantype(banstr[1]);
if (!extban)
{
return 0;
}
else
{
return extban->is_banned(sptr, chptr, banstr, type);
}
}
else
{
/* Is a n!u@h mask. */
return (
(match(banstr, ban_realhost) == 0) || /* nick!user@realhost */
(!BadPtr(ban_virthost) && (match(banstr, ban_virthost) == 0)) || /* nick!user@virthost - if he's been sethost/chghost/vhost */
(!BadPtr(ban_ip) && (match(banstr, ban_ip) == 0)) || /* nick!user@IP (1.2.3.4, 1234:5678::90AB:CDEF, ::ffff:1.2.3.4, etc) */
(!BadPtr(ban_cloakhost) && (match(banstr, ban_cloakhost) == 0)) /* nick!user@cloakhost - if +x */
);
}
}
#endif
/** is_banned_with_nick - Check if a user is banned on a channel.
* @param sptr Client to check (can be remote client)
* @param chptr Channel to check
@@ -470,7 +510,8 @@ Ban *is_banned_with_nick(aClient *sptr, aChannel *chptr, int type, char *nick)
ban_realhost = realhost;
ban_ip = ban_virthost = ban_cloakhost = NULL;
/* Might it be possible in the future to include the possiblity for SupportNICKIP(sptr->from), SupportCLK(sptr->from)? -- aquanight */
if (MyConnect(sptr))
{
mine = 1;
@@ -495,6 +536,7 @@ Ban *is_banned_with_nick(aClient *sptr, aChannel *chptr, int type, char *nick)
*/
for (tmp = chptr->banlist; tmp; tmp = tmp->next)
{
#ifdef DISABLE_STACKED_EXTBANS
if (*tmp->banstr == '~')
{
extban = findmod_by_bantype(tmp->banstr[1]);
@@ -512,10 +554,15 @@ Ban *is_banned_with_nick(aClient *sptr, aChannel *chptr, int type, char *nick)
} else
continue;
}
#else
if (!ban_check_mask(sptr, chptr, tmp->banstr, type, 0))
continue;
#endif
/* Ban found, now check for +e */
for (tmp2 = chptr->exlist; tmp2; tmp2 = tmp2->next)
{
#ifdef DISABLE_STACKED_EXTBANS
if (*tmp2->banstr == '~')
{
extban = findmod_by_bantype(tmp2->banstr[1]);
@@ -530,6 +577,10 @@ Ban *is_banned_with_nick(aClient *sptr, aChannel *chptr, int type, char *nick)
(mine && (match(tmp2->banstr, cloakhost) == 0)) )
return NULL;
}
#else
if (!ban_check_mask(sptr, chptr, tmp2->banstr, type, 0))
return NULL;
#endif
}
break; /* ban found and not on except */
}
+112 -1
View File
@@ -251,7 +251,11 @@ char *ban = banin + 3;
if (type != BANCHK_MSG)
return 0;
#ifdef DISABLE_STACKED_EXTBANS
return extban_is_banned_helper(ban);
#else
return ban_check_mask(sptr, chptr, ban, type, 0);
#endif
}
int extban_moden_is_banned(aClient *sptr, aChannel *chptr, char *banin, int type)
@@ -263,8 +267,12 @@ char *ban = banin + 3;
if (has_voice(sptr, chptr))
return 0;
#ifdef DISABLE_STACKED_EXTBANS
return extban_is_banned_helper(ban);
#else
return ban_check_mask(sptr, chptr, ban, type, 0);
#endif
}
int extban_modej_is_banned(aClient* sptr, aChannel* chptr, char* banin, int type)
@@ -274,9 +282,52 @@ char* ban = banin + 3;
if (type != BANCHK_JOIN)
return 0;
#ifdef DISABLE_STACKED_EXTBANS
return extban_is_banned_helper(ban);
#else
return ban_check_mask(sptr, chptr, ban, type, 0);
#endif
}
#ifndef DISABLE_STACKED_EXTBANS
/** General is_ok for n!u@h stuff that also deals with recursive extbans.
*/
int extban_is_ok_nuh_extban(aClient* sptr, aChannel* chptr, char* para, int checkt, int what, int what2)
{
char* mask = (para + 3);
Extban* p = NULL;
/* Mostly copied from clean_ban_mask - but note MyClient checks aren't needed here: extban->is_ok() according to m_mode isn't called for nonlocal. */
if ((*mask == '~') && mask[1] && (mask[2] == ':'))
{
/* We can be sure RESTRICT_EXTENDEDBANS is not *. Else this extended ban wouldn't be happening at all. */
if (what == EXBCHK_PARAM && RESTRICT_EXTENDEDBANS && !IsAnOper(sptr))
{
if (strchr(RESTRICT_EXTENDEDBANS, mask[1]))
{
sendnotice(sptr, "Setting/removing of extended bantypes '%s' has been disabled.", RESTRICT_EXTENDEDBANS);
return 0; /* Fail */
}
}
p = findmod_by_bantype(mask[1]);
if (!p)
{
if (what == MODE_DEL)
{
return 1; /* Always allow killing unknowns. */
}
return 0; /* Don't add unknown extbans. */
}
/* Now we have to ask the stacked extban if it's ok. */
if (p->is_ok)
{
return p->is_ok(sptr, chptr, mask, checkt, what, what2);
}
}
return 1; /* Either not an extban, or extban has NULL is_ok. Good to go. */
}
#endif
/** Some kind of general conv_param routine,
* to ensure the parameter is nick!user@host.
* most of the code is just copied from clean_ban_mask.
@@ -311,6 +362,51 @@ char pfix[8];
return retbuf;
}
#ifndef DISABLE_STACKED_EXTBANS
/** conv_param to deal with stacked extbans.
*/
char* extban_conv_param_nuh_or_extban(char* para)
{
static char retbuf[USERLEN + NICKLEN + HOSTLEN + 32];
char* mask;
char tmpbuf[USERLEN + NICKLEN + HOSTLEN + 32];
char bantype = para[1];
char* ret = NULL;
Extban* p = NULL;
if (para[3] == '~' && para[4] && para[5] == ':')
{
strncpyzt(tmpbuf, para, sizeof(tmpbuf));
mask = tmpbuf + 3;
/* Already did restrict-extended bans check. */
p = findmod_by_bantype(mask[1]);
if (!p)
{
/* Handling unknown bantypes in is_ok. Assume that it's ok here. */
return para;
}
if (p->conv_param)
{
if (ret = p->conv_param(mask))
{
ircsprintf(retbuf, "~%c:%s", bantype, ret); /* Make sure our extban prefix sticks. */
return retbuf;
}
else
{
return NULL; /* Fail. */
}
}
/* I honestly don't know what the deal is with the 80 char cap in clean_ban_mask is about. So I'm leaving it out here. */
return para;
}
else
{
return extban_conv_param_nuh(para);
}
}
#endif
/** Realname bans - conv_param */
char *extban_moder_conv_param(char *para)
{
@@ -345,19 +441,34 @@ void extban_init(void)
memset(&req, 0, sizeof(ExtbanInfo));
req.flag = 'q';
#ifdef DISABLE_STACKED_EXTBANS
req.conv_param = extban_conv_param_nuh;
#else
req.is_ok = extban_is_ok_nuh_extban;
req.conv_param = extban_conv_param_nuh_or_extban;
#endif
req.is_banned = extban_modeq_is_banned;
ExtbanAdd(NULL, req);
memset(&req, 0, sizeof(ExtbanInfo));
req.flag = 'n';
#ifdef DISABLE_STACKED_EXTBANS
req.conv_param = extban_conv_param_nuh;
#else
req.is_ok = extban_is_ok_nuh_extban;
req.conv_param = extban_conv_param_nuh_or_extban;
#endif
req.is_banned = extban_moden_is_banned;
ExtbanAdd(NULL, req);
memset(&req, 0, sizeof(ExtbanInfo));
req.flag = 'j';
#ifdef DISABLE_STACKED_EXTBANS
req.conv_param = extban_conv_param_nuh;
#else
req.is_ok = extban_is_ok_nuh_extban;
req.conv_param = extban_conv_param_nuh_or_extban;
#endif
req.is_banned = extban_modej_is_banned;
ExtbanAdd(NULL, req);