mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-09 17:43:12 +02:00
- 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.
- Misc fix for disabling extban chains, should've done stuff in our autoconf
stuff instead of hacking configure directly :P .
This commit is contained in:
@@ -1827,3 +1827,24 @@
|
||||
- set::level-on-join now also supports voice, halfop, protect and owner.
|
||||
Requested by katsklaw (#0003852). Partial patch provided by katsklaw and
|
||||
morpheus_pl.
|
||||
- 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.
|
||||
- Misc fix for disabling extban chains, should've done stuff in our autoconf
|
||||
stuff instead of hacking configure directly :P .
|
||||
|
||||
@@ -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 "
|
||||
@@ -275,6 +278,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=""
|
||||
@@ -304,6 +336,7 @@ SHUNNOTICES=""
|
||||
NOOPEROVERRIDE=""
|
||||
DISABLEUSERMOD=""
|
||||
OPEROVERRIDEVERIFY=""
|
||||
DISABLEEXTBANSTACKING=""
|
||||
EXTRAPARA=""
|
||||
if [ "`eval echo -n 'a'`" = "-n a" ] ; then
|
||||
c="\c"
|
||||
@@ -852,6 +885,7 @@ SHUNNOTICES="$SHUNNOTICES"
|
||||
NOOPEROVERRIDE="$NOOPEROVERRIDE"
|
||||
DISABLEUSERMOD="$DISABLEUSERMOD"
|
||||
OPEROVERRIDEVERIFY="$OPEROVERRIDEVERIFY"
|
||||
DISABLEEXTBANSTACKING="$DISABLEEXTBANSTACKING"
|
||||
EXTRAPARA="$EXTRAPARA"
|
||||
ADVANCED="$ADVANCED"
|
||||
__EOF__
|
||||
|
||||
@@ -393,6 +393,8 @@ AC_ARG_WITH(disableusermod, [AC_HELP_STRING([--with-disableusermod], [Disable /s
|
||||
AC_DEFINE(DISABLE_USERMOD))
|
||||
AC_ARG_WITH(operoverride-verify, [AC_HELP_STRING([--with-operoverride-verify], [Require opers to invite themselves to +s/+p channels])],
|
||||
AC_DEFINE(OPEROVERRIDE_VERIFY))
|
||||
AC_ARG_WITH(disable-extendedban-stacking, [AC_HELP_STRING([--with-disable-extendedban-stacking], [Disable extended ban stacking])],
|
||||
AC_DEFINE(DISABLE_STACKED_EXTBANS))
|
||||
AC_ARG_WITH(system-tre, [AC_HELP_STRING([--with-system-tre], [Use the system tre package instead of bundled, discovered using pkg-config])], [], [with_system_tre=no ])
|
||||
AC_ARG_WITH(system-cares, [AC_HELP_STRING([--with-system-cares], [Use the system c-ares (at least version 1.6.0) package instead of bundled c-ares, discovered using pkg-config])], [], [with_system_cares=no ])
|
||||
CHECK_SSL
|
||||
|
||||
@@ -1305,6 +1305,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
|
||||
--with-system-tre Use the system tre package instead of bundled,
|
||||
discovered using pkg-config
|
||||
--with-system-cares Use the system c-ares (at least version 1.6.0)
|
||||
@@ -12340,6 +12342,15 @@ _ACEOF
|
||||
fi
|
||||
|
||||
|
||||
# Check whether --with-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 --with-system-tre was given.
|
||||
if test "${with_system_tre+set}" = set; then
|
||||
withval=$with_system_tre;
|
||||
|
||||
@@ -191,6 +191,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 *);
|
||||
|
||||
@@ -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
@@ -459,6 +459,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
|
||||
@@ -482,7 +522,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;
|
||||
@@ -507,6 +548,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]);
|
||||
@@ -524,10 +566,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]);
|
||||
@@ -542,6 +589,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 */
|
||||
}
|
||||
|
||||
+113
-1
@@ -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,10 +267,54 @@ 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
|
||||
}
|
||||
|
||||
#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.
|
||||
@@ -301,6 +349,60 @@ 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)
|
||||
{
|
||||
#if (USERLEN + NICKLEN + HOSTLEN + 32) > 256
|
||||
#error "wtf?"
|
||||
#endif
|
||||
static char retbuf[256];
|
||||
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. -- aquanight */
|
||||
/* I don't know why it's 80, but I like a limit anyway. A ban of 500 characters can never be good... -- Syzop */
|
||||
if (strlen(para) > 80)
|
||||
{
|
||||
strlcpy(retbuf, para, 128);
|
||||
return retbuf;
|
||||
}
|
||||
return para;
|
||||
}
|
||||
else
|
||||
{
|
||||
return extban_conv_param_nuh(para);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Realname bans - conv_param */
|
||||
char *extban_moder_conv_param(char *para)
|
||||
{
|
||||
@@ -335,13 +437,23 @@ 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.conv_param = extban_conv_param_nuh_or_extban;
|
||||
req.is_ok = extban_is_ok_nuh_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.conv_param = extban_conv_param_nuh_or_extban;
|
||||
req.is_ok = extban_is_ok_nuh_extban;
|
||||
#endif
|
||||
req.is_banned = extban_moden_is_banned;
|
||||
ExtbanAdd(NULL, req);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user