mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-06-30 11:26:38 +02:00
Add support for ban exceptions, via /ELINE and via the config file.
Still need to fix some FIXME/TODO items and things haven't been fully tested yet, so server sync issues or crashes are still possible. Release notes will be updated another day as well..
This commit is contained in:
@@ -714,6 +714,7 @@ extern MODVAR void (*broadcast_md_globalvar)(ModDataInfo *mdi, ModData *md);
|
||||
extern MODVAR void (*broadcast_md_globalvar_cmd)(aClient *except, aClient *sender, char *varname, char *value);
|
||||
extern MODVAR int (*tkl_ip_hash)(char *ip);
|
||||
extern MODVAR int (*tkl_ip_hash_type)(int type);
|
||||
extern MODVAR int (*find_tkl_exception)(int ban_type, aClient *cptr);
|
||||
/* /Efuncs */
|
||||
|
||||
extern MODVAR aMotdFile opermotd, svsmotd, motd, botmotd, smotd, rules;
|
||||
|
||||
+2
-1
@@ -972,7 +972,7 @@ int hooktype_remote_nickchange(aClient *cptr, aClient *sptr, char *newnick);
|
||||
int hooktype_channel_create(aClient *sptr, aChannel *chptr);
|
||||
int hooktype_channel_destroy(aChannel *chptr, int *should_destroy);
|
||||
int hooktype_remote_chanmode(aClient *cptr, aClient *sptr, aChannel *chptr, char *modebuf, char *parabuf, time_t sendts, int samode);
|
||||
int hooktype_tkl_except(aClient *cptr, aTKline *tkl);
|
||||
int hooktype_tkl_except(aClient *cptr, int ban_type);
|
||||
int hooktype_umode_change(aClient *sptr, long setflags, long newflags);
|
||||
int hooktype_topic(aClient *cptr, aClient *sptr, aChannel *chptr, char *topic);
|
||||
int hooktype_rehash_complete(void);
|
||||
@@ -1245,6 +1245,7 @@ enum EfunctionType {
|
||||
EFUNC_FIND_TKL_BANEXCEPTION,
|
||||
EFUNC_FIND_TKL_NAMEBAN,
|
||||
EFUNC_FIND_TKL_SPAMFILTER,
|
||||
EFUNC_FIND_TKL_EXCEPTION,
|
||||
};
|
||||
|
||||
/* Module flags */
|
||||
|
||||
+3
-6
@@ -716,6 +716,9 @@ struct Server {
|
||||
#define TKL_SPAMF 0x0020
|
||||
#define TKL_NAME 0x0040
|
||||
#define TKL_EXCEPTION 0x0080
|
||||
/* these are not real tkl types, but only used for exceptions: */
|
||||
#define TKL_THROTTLE 0x1000
|
||||
#define TKL_BLACKLIST 0x2000
|
||||
|
||||
#define TKLIsServerBan(tkl) ((tkl)->type & (TKL_KILL|TKL_ZAP|TKL_SHUN))
|
||||
#define TKLIsServerBanType(tpe) ((tpe) & (TKL_KILL|TKL_ZAP|TKL_SHUN))
|
||||
@@ -1072,12 +1075,6 @@ struct _configflag_tld
|
||||
#define CRULE_ALL 0
|
||||
#define CRULE_AUTO 1
|
||||
|
||||
#define CONF_EXCEPT_BAN 1
|
||||
#define CONF_EXCEPT_TKL 2
|
||||
#define CONF_EXCEPT_THROTTLE 3
|
||||
#define CONF_EXCEPT_BLACKLIST 4
|
||||
|
||||
|
||||
struct _configitem {
|
||||
ConfigItem *prev, *next;
|
||||
ConfigFlag flag;
|
||||
|
||||
@@ -116,6 +116,7 @@ aTKline *(*find_tkl_serverban)(int type, char *usermask, char *hostmask, int sof
|
||||
aTKline *(*find_tkl_banexception)(int type, char *usermask, char *hostmask, int softban);
|
||||
aTKline *(*find_tkl_nameban)(int type, char *name, int hold);
|
||||
aTKline *(*find_tkl_spamfilter)(int type, char *match_string, unsigned short action, unsigned short target);
|
||||
int (*find_tkl_exception)(int ban_type, aClient *cptr);
|
||||
|
||||
Efunction *EfunctionAddMain(Module *module, EfunctionType eftype, int (*func)(), void (*vfunc)(), void *(*pvfunc)(), char *(*cfunc)())
|
||||
{
|
||||
@@ -352,4 +353,5 @@ void efunctions_init(void)
|
||||
efunc_init_function(EFUNC_FIND_TKL_BANEXCEPTION, find_tkl_banexception, NULL);
|
||||
efunc_init_function(EFUNC_FIND_TKL_NAMEBAN, find_tkl_nameban, NULL);
|
||||
efunc_init_function(EFUNC_FIND_TKL_SPAMFILTER, find_tkl_spamfilter, NULL);
|
||||
efunc_init_function(EFUNC_FIND_TKL_EXCEPTION, find_tkl_exception, NULL);
|
||||
}
|
||||
|
||||
@@ -977,7 +977,7 @@ refuse_client:
|
||||
|
||||
j = 1;
|
||||
|
||||
if (!Find_except(acptr, CONF_EXCEPT_THROTTLE))
|
||||
if (!find_tkl_exception(TKL_THROTTLE, acptr))
|
||||
{
|
||||
list_for_each_entry(acptr2, &unknown_list, lclient_node)
|
||||
{
|
||||
|
||||
+39
-347
@@ -2935,19 +2935,9 @@ ConfigItem_ban *Find_ban(aClient *sptr, char *host, short type)
|
||||
if (sptr)
|
||||
{
|
||||
if (match_user(ban->mask, sptr, MATCH_CHECK_REAL))
|
||||
{
|
||||
/* Person got a exception */
|
||||
// FIXME: this code is for the transition
|
||||
// it should not be called blindly like
|
||||
// we do now, since it would allow bypassing
|
||||
// of even qlines and such..
|
||||
// contact Syzop when in doubt :D
|
||||
if (Find_except(sptr, CONF_EXCEPT_BAN))
|
||||
return NULL;
|
||||
return ban;
|
||||
}
|
||||
}
|
||||
else if (match_simple(ban->mask, host)) /* We don't worry about exceptions */
|
||||
else if (match_simple(ban->mask, host))
|
||||
return ban;
|
||||
}
|
||||
}
|
||||
@@ -2969,14 +2959,9 @@ ConfigItem_ban *Find_banEx(aClient *sptr, char *host, short type, short type2)
|
||||
if (sptr)
|
||||
{
|
||||
if (match_user(ban->mask, sptr, MATCH_CHECK_REAL))
|
||||
{
|
||||
/* Person got a exception */
|
||||
if (Find_except(sptr, type))
|
||||
return NULL;
|
||||
return ban;
|
||||
}
|
||||
}
|
||||
else if (match_simple(ban->mask, host)) /* We don't worry about exceptions */
|
||||
else if (match_simple(ban->mask, host))
|
||||
return ban;
|
||||
}
|
||||
}
|
||||
@@ -5493,117 +5478,26 @@ int _test_allow_dcc(ConfigFile *conf, ConfigEntry *ce)
|
||||
return errors;
|
||||
}
|
||||
|
||||
void create_tkl_except_ii(char *mask, char *type)
|
||||
int _conf_except(ConfigFile *conf, ConfigEntry *ce)
|
||||
{
|
||||
ConfigItem_except *ca;
|
||||
NameValue *opf;
|
||||
ca = MyMallocEx(sizeof(ConfigItem_except));
|
||||
ca->mask = strdup(mask);
|
||||
|
||||
opf = config_binary_flags_search(ExceptTklFlags, type, ARRAY_SIZEOF(ExceptTklFlags));
|
||||
ca->type = opf->flag;
|
||||
ca->flag.type = CONF_EXCEPT_TKL;
|
||||
AddListItem(ca, conf_except);
|
||||
}
|
||||
|
||||
void create_tkl_except(char *mask, char *type)
|
||||
{
|
||||
if (!strcmp(type, "all"))
|
||||
{
|
||||
/* Special treatment */
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZEOF(ExceptTklFlags); i++)
|
||||
if (ExceptTklFlags[i].flag)
|
||||
create_tkl_except_ii(mask, ExceptTklFlags[i].name);
|
||||
}
|
||||
else
|
||||
create_tkl_except_ii(mask, type);
|
||||
}
|
||||
|
||||
int _conf_except(ConfigFile *conf, ConfigEntry *ce)
|
||||
{
|
||||
|
||||
ConfigEntry *cep;
|
||||
ConfigItem_except *ca;
|
||||
Hook *h;
|
||||
int value;
|
||||
|
||||
if (!strcmp(ce->ce_vardata, "ban")) {
|
||||
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||
{
|
||||
if (!strcmp(cep->ce_varname, "mask")) {
|
||||
ca = MyMallocEx(sizeof(ConfigItem_except));
|
||||
ca->mask = strdup(cep->ce_vardata);
|
||||
ca->flag.type = CONF_EXCEPT_BAN;
|
||||
AddListItem(ca, conf_except);
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
for (h = Hooks[HOOKTYPE_CONFIGRUN]; h; h = h->next)
|
||||
{
|
||||
value = (*(h->func.intfunc))(conf,ce,CONFIG_EXCEPT);
|
||||
if (value == 1)
|
||||
break;
|
||||
}
|
||||
else if (!strcmp(ce->ce_vardata, "throttle")) {
|
||||
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||
{
|
||||
if (!strcmp(cep->ce_varname, "mask")) {
|
||||
ca = MyMallocEx(sizeof(ConfigItem_except));
|
||||
ca->mask = strdup(cep->ce_vardata);
|
||||
ca->flag.type = CONF_EXCEPT_THROTTLE;
|
||||
AddListItem(ca, conf_except);
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else if (!strcmp(ce->ce_vardata, "tkl")) {
|
||||
ConfigEntry *mask = NULL, *type = NULL;
|
||||
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||
{
|
||||
if (!strcmp(cep->ce_varname, "mask"))
|
||||
mask = cep;
|
||||
else if (!strcmp(cep->ce_varname, "type"))
|
||||
type = cep;
|
||||
}
|
||||
if (type->ce_vardata)
|
||||
create_tkl_except(mask->ce_vardata, type->ce_vardata);
|
||||
else
|
||||
{
|
||||
ConfigEntry *cepp;
|
||||
for (cepp = type->ce_entries; cepp; cepp = cepp->ce_next)
|
||||
create_tkl_except(mask->ce_vardata, cepp->ce_varname);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(ce->ce_vardata, "blacklist")) {
|
||||
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||
{
|
||||
if (!strcmp(cep->ce_varname, "mask")) {
|
||||
ca = MyMallocEx(sizeof(ConfigItem_except));
|
||||
ca->mask = strdup(cep->ce_vardata);
|
||||
ca->flag.type = CONF_EXCEPT_BLACKLIST;
|
||||
AddListItem(ca, conf_except);
|
||||
}
|
||||
else {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
int value;
|
||||
for (h = Hooks[HOOKTYPE_CONFIGRUN]; h; h = h->next)
|
||||
{
|
||||
value = (*(h->func.intfunc))(conf,ce,CONFIG_EXCEPT);
|
||||
if (value == 1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _test_except(ConfigFile *conf, ConfigEntry *ce)
|
||||
int _test_except(ConfigFile *conf, ConfigEntry *ce)
|
||||
{
|
||||
ConfigEntry *cep;
|
||||
int errors = 0;
|
||||
int errors = 0;
|
||||
Hook *h;
|
||||
char has_mask = 0;
|
||||
int used = 0;
|
||||
|
||||
if (!ce->ce_vardata)
|
||||
{
|
||||
@@ -5612,243 +5506,41 @@ int _test_except(ConfigFile *conf, ConfigEntry *ce)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strcmp(ce->ce_vardata, "ban"))
|
||||
for (h = Hooks[HOOKTYPE_CONFIGTEST]; h; h = h->next)
|
||||
{
|
||||
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||
int value, errs = 0;
|
||||
if (h->owner && !(h->owner->flags & MODFLAG_TESTING)
|
||||
&& !(h->owner->options & MOD_OPT_PERM))
|
||||
continue;
|
||||
value = (*(h->func.intfunc))(conf,ce,CONFIG_EXCEPT,&errs);
|
||||
if (value == 2)
|
||||
used = 1;
|
||||
if (value == 1)
|
||||
{
|
||||
if (config_is_blankorempty(cep, "except ban"))
|
||||
{
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cep->ce_varname, "mask"))
|
||||
{
|
||||
if (has_mask)
|
||||
{
|
||||
config_warn_duplicate(cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum, "except ban::mask");
|
||||
continue;
|
||||
}
|
||||
has_mask = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
config_error_unknown(cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum, "except ban", cep->ce_varname);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
used = 1;
|
||||
break;
|
||||
}
|
||||
if (!has_mask)
|
||||
if (value == -1)
|
||||
{
|
||||
config_error_missing(ce->ce_fileptr->cf_filename, ce->ce_varlinenum,
|
||||
"except ban::mask");
|
||||
errors++;
|
||||
used = 1;
|
||||
errors += errs;
|
||||
break;
|
||||
}
|
||||
if (value == -2)
|
||||
{
|
||||
used = 1;
|
||||
errors += errs;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
else if (!strcmp(ce->ce_vardata, "throttle")) {
|
||||
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||
{
|
||||
if (config_is_blankorempty(cep, "except throttle"))
|
||||
{
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cep->ce_varname, "mask"))
|
||||
{
|
||||
has_mask = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
config_error_unknown(cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum, "except throttle", cep->ce_varname);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!has_mask)
|
||||
{
|
||||
config_error_missing(ce->ce_fileptr->cf_filename, ce->ce_varlinenum,
|
||||
"except throttle::mask");
|
||||
errors++;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
else if (!strcmp(ce->ce_vardata, "tkl")) {
|
||||
char has_type = 0;
|
||||
|
||||
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||
{
|
||||
if (!strcmp(cep->ce_varname, "mask"))
|
||||
{
|
||||
if (!cep->ce_vardata)
|
||||
{
|
||||
config_error_empty(cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum, "except tkl", "mask");
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
if (has_mask)
|
||||
{
|
||||
config_warn_duplicate(cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum, "except tkl::mask");
|
||||
continue;
|
||||
}
|
||||
has_mask = 1;
|
||||
}
|
||||
else if (!strcmp(cep->ce_varname, "type"))
|
||||
{
|
||||
if (has_type)
|
||||
{
|
||||
config_warn_duplicate(cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum, "except tkl::type");
|
||||
continue;
|
||||
}
|
||||
if (cep->ce_vardata)
|
||||
{
|
||||
if (!strcmp(cep->ce_vardata, "tkline") ||
|
||||
!strcmp(cep->ce_vardata, "tzline"))
|
||||
{
|
||||
config_error("%s:%i: except tkl of type %s is"
|
||||
" deprecated. Use except ban {}"
|
||||
" instead",
|
||||
cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum,
|
||||
cep->ce_vardata);
|
||||
errors++;
|
||||
}
|
||||
if (!config_binary_flags_search(ExceptTklFlags,
|
||||
cep->ce_vardata, ARRAY_SIZEOF(ExceptTklFlags)))
|
||||
{
|
||||
config_error("%s:%i: unknown except tkl type %s",
|
||||
cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum,
|
||||
cep->ce_vardata);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (cep->ce_entries)
|
||||
{
|
||||
ConfigEntry *cepp;
|
||||
for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
|
||||
{
|
||||
if (!strcmp(cepp->ce_varname, "tkline") ||
|
||||
!strcmp(cepp->ce_varname, "tzline"))
|
||||
{
|
||||
config_error("%s:%i: except tkl of type %s is"
|
||||
" deprecated. Use except ban {}"
|
||||
" instead",
|
||||
cepp->ce_fileptr->cf_filename,
|
||||
cepp->ce_varlinenum,
|
||||
cepp->ce_varname);
|
||||
errors++;
|
||||
}
|
||||
if (!config_binary_flags_search(ExceptTklFlags,
|
||||
cepp->ce_varname, ARRAY_SIZEOF(ExceptTklFlags)))
|
||||
{
|
||||
config_error("%s:%i: unknown except tkl type %s",
|
||||
cepp->ce_fileptr->cf_filename,
|
||||
cepp->ce_varlinenum,
|
||||
cepp->ce_varname);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
config_error_empty(cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum, "except tkl", "type");
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
has_type = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
config_error_unknown(cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum, "except tkl", cep->ce_varname);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!has_mask)
|
||||
{
|
||||
config_error("%s:%i: except tkl without mask item",
|
||||
ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
|
||||
return 1;
|
||||
}
|
||||
if (!has_type)
|
||||
{
|
||||
config_error("%s:%i: except tkl without type item",
|
||||
ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
|
||||
return 1;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
else if (!strcmp(ce->ce_vardata, "blacklist")) {
|
||||
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||
{
|
||||
if (config_is_blankorempty(cep, "except blacklist"))
|
||||
{
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(cep->ce_varname, "mask"))
|
||||
{
|
||||
has_mask = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
config_error_unknown(cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum, "except blacklist", cep->ce_varname);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!has_mask)
|
||||
{
|
||||
config_error_missing(ce->ce_fileptr->cf_filename, ce->ce_varlinenum,
|
||||
"except blacklist::mask");
|
||||
errors++;
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
else {
|
||||
int used = 0;
|
||||
for (h = Hooks[HOOKTYPE_CONFIGTEST]; h; h = h->next)
|
||||
{
|
||||
int value, errs = 0;
|
||||
if (h->owner && !(h->owner->flags & MODFLAG_TESTING)
|
||||
&& !(h->owner->options & MOD_OPT_PERM))
|
||||
continue;
|
||||
value = (*(h->func.intfunc))(conf,ce,CONFIG_EXCEPT,&errs);
|
||||
if (value == 2)
|
||||
used = 1;
|
||||
if (value == 1)
|
||||
{
|
||||
used = 1;
|
||||
break;
|
||||
}
|
||||
if (value == -1)
|
||||
{
|
||||
used = 1;
|
||||
errors += errs;
|
||||
break;
|
||||
}
|
||||
if (value == -2)
|
||||
{
|
||||
used = 1;
|
||||
errors += errs;
|
||||
}
|
||||
}
|
||||
if (!used) {
|
||||
config_error("%s:%i: unknown except type %s",
|
||||
ce->ce_fileptr->cf_filename, ce->ce_varlinenum,
|
||||
ce->ce_vardata);
|
||||
return 1;
|
||||
}
|
||||
if (!used)
|
||||
{
|
||||
config_error("%s:%i: unknown except type %s",
|
||||
ce->ce_fileptr->cf_filename, ce->ce_varlinenum,
|
||||
ce->ce_vardata);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -999,7 +999,7 @@ int throttle_can_connect(aClient *sptr)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
if (Find_except(sptr, CONF_EXCEPT_THROTTLE))
|
||||
if (find_tkl_exception(TKL_THROTTLE, sptr))
|
||||
return 2;
|
||||
if (b->count+1 > (THROTTLING_COUNT ? THROTTLING_COUNT : 3))
|
||||
return 0;
|
||||
|
||||
@@ -560,7 +560,7 @@ int blacklist_start_check(aClient *cptr)
|
||||
Blacklist *bl;
|
||||
|
||||
/* If the user is on 'except blacklist' then don't bother checking... */
|
||||
if (Find_except(cptr, CONF_EXCEPT_BLACKLIST))
|
||||
if (find_tkl_exception(TKL_BLACKLIST, cptr))
|
||||
return 0;
|
||||
|
||||
if (!BLUSER(cptr))
|
||||
|
||||
+6
-20
@@ -59,7 +59,7 @@ int stats_banversion(aClient *, char *);
|
||||
int stats_links(aClient *, char *);
|
||||
int stats_denylinkall(aClient *, char *);
|
||||
int stats_gline(aClient *, char *);
|
||||
int stats_exceptban(aClient *, char *);
|
||||
int stats_except(aClient *, char *);
|
||||
int stats_allow(aClient *, char *);
|
||||
int stats_command(aClient *, char *);
|
||||
int stats_oper(aClient *, char *);
|
||||
@@ -71,7 +71,6 @@ int stats_uline(aClient *, char *);
|
||||
int stats_vhost(aClient *, char *);
|
||||
int stats_mem(aClient *, char *);
|
||||
int stats_denylinkauto(aClient *, char *);
|
||||
int stats_exceptthrottle(aClient *, char *);
|
||||
int stats_denydcc(aClient *, char *);
|
||||
int stats_kline(aClient *, char *);
|
||||
int stats_banrealname(aClient *, char *);
|
||||
@@ -107,7 +106,7 @@ struct statstab StatsTable[] = {
|
||||
{ 'B', "banversion", stats_banversion, 0 },
|
||||
{ 'C', "link", stats_links, 0 },
|
||||
{ 'D', "denylinkall", stats_denylinkall, 0 },
|
||||
{ 'E', "exceptban", stats_exceptban, 0 },
|
||||
{ 'E', "except", stats_except, 0 },
|
||||
{ 'F', "denydcc", stats_denydcc, 0 },
|
||||
{ 'G', "gline", stats_gline, FLAGS_AS_PARA },
|
||||
{ 'H', "link", stats_links, 0 },
|
||||
@@ -129,7 +128,6 @@ struct statstab StatsTable[] = {
|
||||
{ 'Z', "mem", stats_mem, 0 },
|
||||
{ 'c', "link", stats_links, 0 },
|
||||
{ 'd', "denylinkauto", stats_denylinkauto, 0 },
|
||||
{ 'e', "exceptthrottle",stats_exceptthrottle, 0 },
|
||||
{ 'f', "spamfilter", stats_spamfilter, FLAGS_AS_PARA },
|
||||
{ 'g', "gline", stats_gline, FLAGS_AS_PARA },
|
||||
{ 'h', "link", stats_links, 0 },
|
||||
@@ -490,8 +488,10 @@ int stats_spamfilter(aClient *sptr, char *para)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stats_exceptban(aClient *sptr, char *para)
|
||||
int stats_except(aClient *sptr, char *para)
|
||||
{
|
||||
#if 0
|
||||
// FIXME: update numeric and send list to users ;)
|
||||
ConfigItem_except *excepts;
|
||||
for (excepts = conf_except; excepts; excepts = excepts->next)
|
||||
{
|
||||
@@ -500,6 +500,7 @@ int stats_exceptban(aClient *sptr, char *para)
|
||||
else if (excepts->flag.type == CONF_EXCEPT_TKL)
|
||||
sendnumeric(sptr, RPL_STATSEXCEPTTKL, tkl_typetochar(excepts->type), excepts->mask);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -924,15 +925,6 @@ int stats_denylinkauto(aClient *sptr, char *para)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stats_exceptthrottle(aClient *sptr, char *para)
|
||||
{
|
||||
ConfigItem_except *excepts;
|
||||
for (excepts = conf_except; excepts; excepts = excepts->next)
|
||||
if (excepts->flag.type == CONF_EXCEPT_THROTTLE)
|
||||
sendnumeric(sptr, RPL_STATSELINE, excepts->mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int stats_denydcc(aClient *sptr, char *para)
|
||||
{
|
||||
ConfigItem_deny_dcc *denytmp;
|
||||
@@ -976,12 +968,6 @@ int stats_kline(aClient *sptr, char *para)
|
||||
|
||||
tkl_stats(sptr, TKL_KILL, NULL);
|
||||
tkl_stats(sptr, TKL_ZAP, NULL);
|
||||
|
||||
for (excepts = conf_except; excepts; excepts = excepts->next)
|
||||
{
|
||||
if (excepts->flag.type == CONF_EXCEPT_BAN)
|
||||
sendnumeric(sptr, RPL_STATSKLINE, "E", excepts->mask, "");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+476
-74
@@ -28,6 +28,8 @@ int tkl_config_test_spamfilter(ConfigFile *, ConfigEntry *, int, int *);
|
||||
int tkl_config_run_spamfilter(ConfigFile *, ConfigEntry *, int);
|
||||
int tkl_config_test_ban(ConfigFile *, ConfigEntry *, int, int *);
|
||||
int tkl_config_run_ban(ConfigFile *, ConfigEntry *, int);
|
||||
int tkl_config_test_except(ConfigFile *, ConfigEntry *, int, int *);
|
||||
int tkl_config_run_except(ConfigFile *, ConfigEntry *, int);
|
||||
CMD_FUNC(m_gline);
|
||||
CMD_FUNC(m_shun);
|
||||
CMD_FUNC(m_tempshun);
|
||||
@@ -35,6 +37,7 @@ CMD_FUNC(m_gzline);
|
||||
CMD_FUNC(m_kline);
|
||||
CMD_FUNC(m_zline);
|
||||
CMD_FUNC(m_spamfilter);
|
||||
CMD_FUNC(m_eline);
|
||||
int m_tkl_line(aClient *cptr, aClient *sptr, int parc, char *parv[], char* type);
|
||||
int _tkl_hash(unsigned int c);
|
||||
char _tkl_typetochar(int type);
|
||||
@@ -76,6 +79,7 @@ aTKline *_find_tkl_serverban(int type, char *usermask, char *hostmask, int softb
|
||||
aTKline *_find_tkl_banexception(int type, char *usermask, char *hostmask, int softban);
|
||||
aTKline *_find_tkl_nameban(int type, char *name, int hold);
|
||||
aTKline *_find_tkl_spamfilter(int type, char *match_string, unsigned short action, unsigned short target);
|
||||
int _find_tkl_exception(int ban_type, aClient *cptr);
|
||||
|
||||
/* Externals (only for us :D) */
|
||||
extern int MODVAR spamf_ugly_vchanoverride;
|
||||
@@ -94,6 +98,7 @@ MOD_TEST(tkl)
|
||||
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, tkl_config_test_spamfilter);
|
||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, tkl_config_test_ban);
|
||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, tkl_config_test_except);
|
||||
EfunctionAdd(modinfo->handle, EFUNC_TKL_HASH, _tkl_hash);
|
||||
EfunctionAdd(modinfo->handle, EFUNC_TKL_TYPETOCHAR, TO_INTFUNC(_tkl_typetochar));
|
||||
EfunctionAdd(modinfo->handle, EFUNC_TKL_CHARTOTYPE, TO_INTFUNC(_tkl_chartotype));
|
||||
@@ -126,6 +131,7 @@ MOD_TEST(tkl)
|
||||
EfunctionAdd(modinfo->handle, EFUNC_TKL_IP_HASH_TYPE, _tkl_ip_hash_type);
|
||||
EfunctionAddVoid(modinfo->handle, EFUNC_SENDNOTICE_TKL_ADD, _sendnotice_tkl_add);
|
||||
EfunctionAddVoid(modinfo->handle, EFUNC_SENDNOTICE_TKL_DEL, _sendnotice_tkl_del);
|
||||
EfunctionAdd(modinfo->handle, EFUNC_FIND_TKL_EXCEPTION, _find_tkl_exception);
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -134,6 +140,7 @@ MOD_INIT(tkl)
|
||||
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_spamfilter);
|
||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_ban);
|
||||
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, tkl_config_run_except);
|
||||
CommandAdd(modinfo->handle, "GLINE", m_gline, 3, M_OPER);
|
||||
CommandAdd(modinfo->handle, "SHUN", m_shun, 3, M_OPER);
|
||||
CommandAdd(modinfo->handle, "TEMPSHUN", m_tempshun, 2, M_OPER);
|
||||
@@ -141,6 +148,7 @@ MOD_INIT(tkl)
|
||||
CommandAdd(modinfo->handle, "KLINE", m_kline, 3, M_OPER);
|
||||
CommandAdd(modinfo->handle, "GZLINE", m_gzline, 3, M_OPER);
|
||||
CommandAdd(modinfo->handle, "SPAMFILTER", m_spamfilter, 7, M_OPER);
|
||||
CommandAdd(modinfo->handle, "ELINE", m_eline, 4, M_OPER);
|
||||
CommandAdd(modinfo->handle, "TKL", _m_tkl, MAXPARA, M_OPER|M_SERVER);
|
||||
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||
return MOD_SUCCESS;
|
||||
@@ -577,6 +585,176 @@ int tkl_config_run_ban(ConfigFile *cf, ConfigEntry *ce, int configtype)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tkl_config_test_except(ConfigFile *cf, ConfigEntry *ce, int configtype, int *errs)
|
||||
{
|
||||
ConfigEntry *cep;
|
||||
ConfigItem_except *ca;
|
||||
Hook *h;
|
||||
char *bantypes = NULL;
|
||||
int errors = 0;
|
||||
|
||||
/* We are only interested in except { } blocks */
|
||||
if (configtype != CONFIG_EXCEPT)
|
||||
return 0;
|
||||
|
||||
/* These are the types that we handle */
|
||||
if (strcmp(ce->ce_vardata, "ban") && strcmp(ce->ce_vardata, "throttle") &&
|
||||
strcmp(ce->ce_vardata, "tkl") && strcmp(ce->ce_vardata, "blacklist") &&
|
||||
strcmp(ce->ce_vardata, "spamfilter"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!strcmp(ce->ce_vardata, "tkl"))
|
||||
{
|
||||
config_error("%s:%d: except tkl { } has been renamed to except ban { }",
|
||||
ce->ce_fileptr->cf_filename, ce->ce_varlinenum);
|
||||
config_status("Please rename your block in the configuration file.");
|
||||
*errs = 1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||
{
|
||||
if (!strcmp(cep->ce_varname, "mask"))
|
||||
{
|
||||
// TODO: verify mask, can be both a list or just 1 directly
|
||||
} else
|
||||
if (!strcmp(cep->ce_varname, "type"))
|
||||
{
|
||||
// TODO: verify type, can be both a list or just 1 directly
|
||||
} else {
|
||||
config_error_unknown(cep->ce_fileptr->cf_filename,
|
||||
cep->ce_varlinenum, "except", cep->ce_varname);
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
*errs = errors;
|
||||
return errors ? -1 : 1;
|
||||
}
|
||||
|
||||
void config_create_tkl_except(char *mask, char *bantypes)
|
||||
{
|
||||
char *usermask = NULL;
|
||||
char *hostmask = NULL;
|
||||
int soft = 0;
|
||||
char buf[256], *p;
|
||||
|
||||
if (*mask == '%')
|
||||
{
|
||||
soft = 1;
|
||||
mask++;
|
||||
}
|
||||
strlcpy(buf, mask, sizeof(buf));
|
||||
p = strchr(buf, '@');
|
||||
if (!p)
|
||||
{
|
||||
usermask = "*";
|
||||
hostmask = buf;
|
||||
} else {
|
||||
*p++ = '\0';
|
||||
usermask = buf;
|
||||
hostmask = p;
|
||||
}
|
||||
|
||||
if ((*usermask == ':') || (*hostmask == ':'))
|
||||
{
|
||||
config_error("Cannot add illegal ban '%s': for a given user@host neither"
|
||||
"user nor host may start with a : character (semicolon)", mask);
|
||||
return;
|
||||
}
|
||||
|
||||
tkl_add_banexception(TKL_EXCEPTION, usermask, hostmask, "Added in configuration file",
|
||||
"-config-", 0, TStime(), soft, bantypes, TKL_FLAG_CONFIG);
|
||||
}
|
||||
|
||||
void tkl_config_run_except_add_bantype(char *bantypes, size_t bantypeslen, char *name)
|
||||
{
|
||||
if (!strcmp(name, "kline"))
|
||||
strlcat(bantypes, "k", sizeof(bantypes));
|
||||
// etc etc.. but probably in a different way ;)
|
||||
}
|
||||
|
||||
int tkl_config_run_except(ConfigFile *cf, ConfigEntry *ce, int configtype)
|
||||
{
|
||||
ConfigEntry *cep, *cepp;
|
||||
ConfigItem_except *ca;
|
||||
Hook *h;
|
||||
char *default_bantypes = NULL;
|
||||
char bantypes[64];
|
||||
|
||||
/* We are only interested in except { } blocks */
|
||||
if (configtype != CONFIG_EXCEPT)
|
||||
return 0;
|
||||
|
||||
/* These are the types that we handle */
|
||||
if (strcmp(ce->ce_vardata, "ban") && strcmp(ce->ce_vardata, "throttle") &&
|
||||
strcmp(ce->ce_vardata, "blacklist") &&
|
||||
strcmp(ce->ce_vardata, "spamfilter"))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
*bantypes = '\0';
|
||||
|
||||
/* First configure all the types */
|
||||
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||
{
|
||||
if (!strcmp(cep->ce_varname, "type"))
|
||||
{
|
||||
if (cep->ce_entries)
|
||||
{
|
||||
/* type { x; y; z; }; */
|
||||
for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
|
||||
tkl_config_run_except_add_bantype(bantypes, sizeof(bantypes), cepp->ce_varname);
|
||||
} else
|
||||
if (cep->ce_vardata)
|
||||
{
|
||||
/* type x; */
|
||||
tkl_config_run_except_add_bantype(bantypes, sizeof(bantypes), cep->ce_vardata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!*bantypes)
|
||||
{
|
||||
/* Default setting if no 'type' is specified: */
|
||||
if (!strcmp(ce->ce_vardata, "ban"))
|
||||
strlcpy(bantypes, "kgzZs", sizeof(bantypes));
|
||||
else if (!strcmp(ce->ce_vardata, "throttle"))
|
||||
strlcpy(bantypes, "t", sizeof(bantypes));
|
||||
else if (!strcmp(ce->ce_vardata, "blacklist"))
|
||||
strlcpy(bantypes, "b", sizeof(bantypes));
|
||||
else if (!strcmp(ce->ce_vardata, "spamfilter"))
|
||||
strlcpy(bantypes, "f", sizeof(bantypes));
|
||||
else
|
||||
abort(); /* someone can't code */
|
||||
}
|
||||
|
||||
/* Now walk through all mask entries */
|
||||
for (cep = ce->ce_entries; cep; cep = cep->ce_next)
|
||||
{
|
||||
if (!strcmp(cep->ce_varname, "mask"))
|
||||
{
|
||||
if (cep->ce_entries)
|
||||
{
|
||||
/* mask { *@1.1.1.1; *@2.2.2.2; *@3.3.3.3; }; */
|
||||
for (cepp = cep->ce_entries; cepp; cepp = cepp->ce_next)
|
||||
config_create_tkl_except(cepp->ce_varname, bantypes);
|
||||
} else
|
||||
if (cep->ce_vardata)
|
||||
{
|
||||
/* mask *@1.1.1.1; */
|
||||
config_create_tkl_except(cep->ce_vardata, bantypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Return unique spamfilter id for aTKline */
|
||||
char *spamfilter_id(aTKline *tk)
|
||||
{
|
||||
@@ -614,7 +792,6 @@ CMD_FUNC(m_gline)
|
||||
}
|
||||
|
||||
return m_tkl_line(cptr, sptr, parc, parv, "G");
|
||||
|
||||
}
|
||||
|
||||
/** GZLINE - Global zline.
|
||||
@@ -891,7 +1068,7 @@ int ban_too_broad(char *usermask, char *hostmask)
|
||||
* This allows us doing some syntax checking and other helpful
|
||||
* things that are the same for many types of *LINES.
|
||||
*/
|
||||
int m_tkl_line(aClient *cptr, aClient *sptr, int parc, char *parv[], char* type)
|
||||
int m_tkl_line(aClient *cptr, aClient *sptr, int parc, char *parv[], char *type)
|
||||
{
|
||||
time_t secs;
|
||||
int whattodo = 0; /* 0 = add 1 = del */
|
||||
@@ -971,7 +1148,7 @@ int m_tkl_line(aClient *cptr, aClient *sptr, int parc, char *parv[], char* type)
|
||||
}
|
||||
if (*hostmask == ':')
|
||||
{
|
||||
sendnotice(sptr, "[error] For (weird) technical reasons you cannot start the host with a ':', sorry");
|
||||
sendnotice(sptr, "[error] For technical reasons you cannot start the host with a ':', sorry");
|
||||
return 0;
|
||||
}
|
||||
if (((*type == 'z') || (*type == 'Z')) && !whattodo)
|
||||
@@ -1088,6 +1265,217 @@ int m_tkl_line(aClient *cptr, aClient *sptr, int parc, char *parv[], char* type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eline_syntax(aClient *sptr)
|
||||
{
|
||||
sendnotice(sptr, " Syntax: /ELINE <user@host> <bantypes> <expiry-time> <reason>");
|
||||
sendnotice(sptr, "Valid bantypes are:");
|
||||
sendnotice(sptr, "k: K-Line g: G-Line");
|
||||
sendnotice(sptr, "z: Z-Line Z: Global Z-Line");
|
||||
sendnotice(sptr, "q: Q-Line");
|
||||
sendnotice(sptr, "s: Shun");
|
||||
sendnotice(sptr, "f: Spamfilter");
|
||||
sendnotice(sptr, "t: Throttling");
|
||||
sendnotice(sptr, "b: Blacklist checking");
|
||||
sendnotice(sptr, "Example: /ELINE *@unrealircd.org kgzZ 0 This user is exempt");
|
||||
sendnotice(sptr, "-");
|
||||
sendnotice(sptr, "To get a list of all current ELINEs, type: /STATS exceptban");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Check if any of the specified types require the
|
||||
* exception to be placed on *@ip rather than
|
||||
* user@host or *@host. For eg zlines.
|
||||
*/
|
||||
int eline_type_requires_ip(char *bantypes)
|
||||
{
|
||||
if (strchr(bantypes, 'z') || strchr(bantypes, 'Z') || strchr(bantypes, 't') || strchr(bantypes, 'b'))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
CMD_FUNC(m_eline)
|
||||
{
|
||||
time_t secs = 0;
|
||||
int add = 1;
|
||||
time_t i;
|
||||
aClient *acptr = NULL;
|
||||
char *mask = NULL;
|
||||
char mo[1024], mo2[1024];
|
||||
char *p, *usermask, *hostmask, *bantypes=NULL, *reason;
|
||||
char *tkllayer[11] = {
|
||||
me.name, /*0 server.name */
|
||||
NULL, /*1 +|- */
|
||||
NULL, /*2 E */
|
||||
NULL, /*3 user */
|
||||
NULL, /*4 host */
|
||||
NULL, /*5 set_by */
|
||||
"0", /*6 expire_at */
|
||||
"-", /*7 set_at */
|
||||
"-", /*8 ban types */
|
||||
"-", /*9 reason */
|
||||
NULL
|
||||
};
|
||||
struct tm *t;
|
||||
|
||||
if (IsServer(sptr))
|
||||
return 0;
|
||||
|
||||
if (!ValidatePermissionsForPath("server-ban:eline",sptr,NULL,NULL,NULL))
|
||||
{
|
||||
sendnumeric(sptr, ERR_NOPRIVILEGES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* For del we need at least:
|
||||
* ELINE -user@host
|
||||
* The 'add' case is checked later.
|
||||
*/
|
||||
if ((parc < 2) || BadPtr(parv[1]))
|
||||
return eline_syntax(sptr);
|
||||
|
||||
mask = parv[1];
|
||||
if (*mask == '-')
|
||||
{
|
||||
add = 0;
|
||||
mask++;
|
||||
}
|
||||
else if (*mask == '+')
|
||||
{
|
||||
add = 1;
|
||||
mask++;
|
||||
}
|
||||
|
||||
/* For add we need more:
|
||||
* ELINE user@host bantypes expiry :reason
|
||||
*/
|
||||
if (add)
|
||||
{
|
||||
if ((parc < 5) || BadPtr(parv[4]))
|
||||
return eline_syntax(sptr);
|
||||
bantypes = parv[2];
|
||||
reason = parv[4];
|
||||
}
|
||||
|
||||
if (strchr(mask, '!'))
|
||||
{
|
||||
sendnotice(sptr, "[error] Cannot have '!' in masks.");
|
||||
return 0;
|
||||
}
|
||||
if (*mask == ':')
|
||||
{
|
||||
sendnotice(sptr, "[error] Mask cannot start with a ':'.");
|
||||
return 0;
|
||||
}
|
||||
if (strchr(mask, ' '))
|
||||
return 0;
|
||||
|
||||
/* Check if it's a hostmask and legal .. */
|
||||
p = strchr(mask, '@');
|
||||
if (p)
|
||||
{
|
||||
if ((p == mask) || !p[1])
|
||||
{
|
||||
sendnotice(sptr, "Error: no user@host specified");
|
||||
return 0;
|
||||
}
|
||||
usermask = strtok(mask, "@");
|
||||
hostmask = strtok(NULL, "");
|
||||
if (BadPtr(hostmask)) {
|
||||
if (BadPtr(usermask)) {
|
||||
return 0;
|
||||
}
|
||||
hostmask = usermask;
|
||||
usermask = "*";
|
||||
}
|
||||
if (*hostmask == ':')
|
||||
{
|
||||
sendnotice(sptr, "[error] For technical reasons you cannot start the host with a ':', sorry");
|
||||
return 0;
|
||||
}
|
||||
if (add && eline_type_requires_ip(bantypes))
|
||||
{
|
||||
/* Trying to exempt a user from a (G)ZLINE,
|
||||
* make sure the user isn't specifying a host then.
|
||||
*/
|
||||
if (strcmp(usermask, "*"))
|
||||
{
|
||||
sendnotice(sptr, "ERROR: Ban exceptions with type z/Z/t/b need to be placed at \037*\037@ipmask, not \037user\037@ipmask. "
|
||||
"This is because checking (g)zlines, throttling and blacklists is done BEFORE any dns and ident lookups.");
|
||||
return -1;
|
||||
}
|
||||
for (p=hostmask; *p; p++)
|
||||
if (isalpha(*p) && !isxdigit(*p))
|
||||
{
|
||||
sendnotice(sptr, "ERROR: Ban exceptions with type z/Z/t/b need to be placed at *@\037ipmask\037, not *@\037hostmask\037. "
|
||||
"(so for example *@192.168.* is ok, but *@*.aol.com is not). "
|
||||
"This is because checking (g)zlines, throttling and blacklists is done BEFORE any dns and ident lookups.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's seemingly a nick .. let's see if we can find the user */
|
||||
if ((acptr = find_person(mask, NULL)))
|
||||
{
|
||||
usermask = "*";
|
||||
hostmask = GetIP(acptr);
|
||||
if (!hostmask)
|
||||
{
|
||||
sendnotice(sptr, "Could not get IP for user '%s'", acptr->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sendnumeric(sptr, ERR_NOSUCHNICK, mask);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (add)
|
||||
{
|
||||
secs = atime(parv[3]);
|
||||
if ((secs <= 0) && (*parv[3] != '0'))
|
||||
{
|
||||
sendnotice(sptr, "*** [error] The expiry time you specified is out of range!");
|
||||
return eline_syntax(sptr);
|
||||
}
|
||||
}
|
||||
|
||||
tkllayer[1] = add ? "+" : "-";
|
||||
tkllayer[2] = "E";
|
||||
tkllayer[3] = usermask;
|
||||
tkllayer[4] = hostmask;
|
||||
tkllayer[5] = make_nick_user_host(sptr->name, sptr->user->username, GetHost(sptr));
|
||||
|
||||
if (add)
|
||||
{
|
||||
/* Add ELINE */
|
||||
if (secs == 0)
|
||||
ircsnprintf(mo, sizeof(mo), "%lld", (long long)secs); /* "0" */
|
||||
else
|
||||
ircsnprintf(mo, sizeof(mo), "%lld", (long long)(secs + TStime()));
|
||||
ircsnprintf(mo2, sizeof(mo2), "%lld", (long long)TStime());
|
||||
tkllayer[6] = mo;
|
||||
tkllayer[7] = mo2;
|
||||
tkllayer[8] = bantypes;
|
||||
tkllayer[9] = reason;
|
||||
/* call the tkl layer .. */
|
||||
m_tkl(&me, &me, NULL, 10, tkllayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove ELINE */
|
||||
/* call the tkl layer .. */
|
||||
m_tkl(&me, &me, NULL, 10, tkllayer);
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Helper function for m_spamfilter, explaining usage. */
|
||||
int spamfilter_usage(aClient *sptr)
|
||||
{
|
||||
@@ -1447,6 +1835,49 @@ int _tkl_chartotype(char c)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
int tkl_banexception_chartotype(char c)
|
||||
{
|
||||
int ret = _tkl_chartotype(c);
|
||||
if (ret == 0)
|
||||
{
|
||||
if (c == 't')
|
||||
ret = TKL_THROTTLE;
|
||||
else if (c == 'b')
|
||||
ret = TKL_BLACKLIST;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int tkl_banexception_matches_type(aTKline *except, int bantype)
|
||||
{
|
||||
char *p;
|
||||
int extype;
|
||||
|
||||
if (!TKLIsBanException(except))
|
||||
abort();
|
||||
|
||||
for (p = except->ptr.banexception->bantypes; *p; p++)
|
||||
{
|
||||
extype = tkl_banexception_chartotype(*p);
|
||||
if ((extype & TKL_SPAMF) || (extype & TKL_SHUN) || (extype & TKL_NAME))
|
||||
{
|
||||
/* For spamfilter, shun and qline we don't care
|
||||
* whether they are global or not. That would only
|
||||
* be confusing to the admin.
|
||||
*/
|
||||
extype &= ~TKL_GLOBAL;
|
||||
if (bantype & extype)
|
||||
return 1;
|
||||
} else {
|
||||
/* Rest requires an exact match */
|
||||
if (bantype == extype)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Used for finding out which element of the tkl_ip hash table is used (primary element) */
|
||||
int _tkl_ip_hash(char *ip)
|
||||
{
|
||||
@@ -1972,31 +2403,44 @@ EVENT(tkl_check_expire)
|
||||
}
|
||||
}
|
||||
|
||||
/** Helper function for find_tkl_exception() */
|
||||
int find_tkl_exception_matcher(aClient *cptr, aTKline *tkl)
|
||||
/* This is just a helper function for find_tkl_exception() */
|
||||
static int find_tkl_exception_matcher(aClient *cptr, int ban_type, aTKline *except_tkl)
|
||||
{
|
||||
char uhost[NICKLEN+HOSTLEN+1];
|
||||
Hook *hook;
|
||||
|
||||
if (!TKLIsBanException(tkl))
|
||||
if (!TKLIsBanException(except_tkl))
|
||||
return 0;
|
||||
|
||||
snprintf(uhost, sizeof(uhost), "%s@%s", tkl->ptr.banexception->usermask, tkl->ptr.banexception->hostmask);
|
||||
if (!tkl_banexception_matches_type(except_tkl, ban_type))
|
||||
return 0;
|
||||
|
||||
// FIXME: check exception ban types!! (right now it always matches)
|
||||
snprintf(uhost, sizeof(uhost), "%s@%s",
|
||||
except_tkl->ptr.banexception->usermask, except_tkl->ptr.banexception->hostmask);
|
||||
|
||||
if (match_user(uhost, cptr, MATCH_CHECK_REAL))
|
||||
{
|
||||
if (!(tkl->ptr.banexception->subtype & TKL_SUBTYPE_SOFT))
|
||||
if (!(except_tkl->ptr.banexception->subtype & TKL_SUBTYPE_SOFT))
|
||||
return 1; /* hard ban exempt */
|
||||
if ((tkl->ptr.banexception->subtype & TKL_SUBTYPE_SOFT) && IsLoggedIn(cptr))
|
||||
if ((except_tkl->ptr.banexception->subtype & TKL_SUBTYPE_SOFT) && IsLoggedIn(cptr))
|
||||
return 1; /* soft ban exempt - only matches if user is logged in */
|
||||
}
|
||||
|
||||
return 0; /* not found */
|
||||
}
|
||||
|
||||
int find_tkl_exception(aTKline *ban_tkl, aClient *cptr)
|
||||
/** Search for TKL Exceptions for this user.
|
||||
* @param ban_type The ban type to check, normally ban_tkl->type.
|
||||
* @param cptr The user
|
||||
* @returns 1 if ban exempt, 0 if not.
|
||||
* @notes
|
||||
* If you have a TKL ban that matched, say, 'ban_tkl'.
|
||||
* Then you call this function like this:
|
||||
* if (find_tkl_exception(ban_tkl->type, cptr))
|
||||
* return 0; // User is exempt
|
||||
* [.. continue and ban the user..]
|
||||
*/
|
||||
int _find_tkl_exception(int ban_type, aClient *cptr)
|
||||
{
|
||||
aTKline *tkl, *ret;
|
||||
int index, index2;
|
||||
@@ -2012,7 +2456,7 @@ int find_tkl_exception(aTKline *ban_tkl, aClient *cptr)
|
||||
{
|
||||
for (tkl = tklines_ip_hash[index][index2]; tkl; tkl = tkl->next)
|
||||
{
|
||||
if (find_tkl_exception_matcher(cptr, tkl))
|
||||
if (find_tkl_exception_matcher(cptr, ban_type, tkl))
|
||||
return 1; /* exempt */
|
||||
}
|
||||
}
|
||||
@@ -2020,7 +2464,7 @@ int find_tkl_exception(aTKline *ban_tkl, aClient *cptr)
|
||||
/* If not banned (yet), then check regular entries.. */
|
||||
for (tkl = tklines[tkl_hash('e')]; tkl; tkl = tkl->next)
|
||||
{
|
||||
if (find_tkl_exception_matcher(cptr, tkl))
|
||||
if (find_tkl_exception_matcher(cptr, ban_type, tkl))
|
||||
return 1; /* exempt */
|
||||
}
|
||||
|
||||
@@ -2028,7 +2472,7 @@ int find_tkl_exception(aTKline *ban_tkl, aClient *cptr)
|
||||
|
||||
for (hook = Hooks[HOOKTYPE_TKL_EXCEPT]; hook; hook = hook->next)
|
||||
{
|
||||
if (hook->func.intfunc(cptr, tkl) > 0)
|
||||
if (hook->func.intfunc(cptr, ban_type) > 0)
|
||||
return 1; /* exempt by hook */
|
||||
}
|
||||
return 0; /* Not exempt */
|
||||
@@ -2056,7 +2500,7 @@ int find_tkline_match_matcher(aClient *cptr, int skip_soft, aTKline *tkl)
|
||||
((tkl->ptr.serverban->subtype & TKL_SUBTYPE_SOFT) && !IsLoggedIn(cptr)))
|
||||
{
|
||||
/* Found match. Now check for exception... */
|
||||
if (find_tkl_exception(tkl, cptr))
|
||||
if (find_tkl_exception(tkl->type, cptr))
|
||||
return 0; /* exempted */
|
||||
return 1; /* banned */
|
||||
}
|
||||
@@ -2142,7 +2586,6 @@ int _find_shun(aClient *cptr)
|
||||
ConfigItem_except *excepts;
|
||||
int match_type = 0;
|
||||
Hook *hook;
|
||||
int banned = 0;
|
||||
|
||||
if (IsServer(cptr) || IsMe(cptr))
|
||||
return -1;
|
||||
@@ -2169,39 +2612,15 @@ int _find_shun(aClient *cptr)
|
||||
((tkl->ptr.serverban->subtype & TKL_SUBTYPE_SOFT) && !IsLoggedIn(cptr)))
|
||||
{
|
||||
/* Found match. Now check for exception... */
|
||||
banned = 1;
|
||||
match_type = CONF_EXCEPT_TKL;
|
||||
for (excepts = conf_except; excepts; excepts = excepts->next)
|
||||
{
|
||||
if (excepts->flag.type != match_type || (match_type == CONF_EXCEPT_TKL &&
|
||||
excepts->type != tkl->type))
|
||||
continue;
|
||||
|
||||
if (match_user(excepts->mask, cptr, MATCH_CHECK_REAL))
|
||||
{
|
||||
banned = 0; /* exempt by except block */
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (hook = Hooks[HOOKTYPE_TKL_EXCEPT]; hook; hook = hook->next)
|
||||
{
|
||||
if (hook->func.intfunc(cptr, tkl) > 0)
|
||||
{
|
||||
banned = 0; /* exempt by hook */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (banned)
|
||||
break;
|
||||
if (find_tkl_exception(TKL_SHUN, cptr))
|
||||
return 1;
|
||||
SetShunned(cptr);
|
||||
return 2; /* Shunned */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!banned)
|
||||
return 1;
|
||||
|
||||
SetShunned(cptr);
|
||||
return 2;
|
||||
return 1; /* No match */
|
||||
}
|
||||
|
||||
/** Helper function for spamfilter_build_user_string().
|
||||
@@ -2351,20 +2770,15 @@ aTKline *_find_qline(aClient *cptr, char *name, int *ishold)
|
||||
if (points != 1)
|
||||
return NULL;
|
||||
|
||||
/* It's a services hold */
|
||||
/* It's a services hold (except bans don't override this) */
|
||||
if (tkl->ptr.nameban->hold)
|
||||
{
|
||||
*ishold = 1;
|
||||
return tkl;
|
||||
}
|
||||
|
||||
for (excepts = conf_except; excepts; excepts = excepts->next)
|
||||
{
|
||||
if (excepts->flag.type != CONF_EXCEPT_TKL || excepts->type != TKL_NAME)
|
||||
continue;
|
||||
if (match_user(excepts->mask, cptr, MATCH_CHECK_REAL))
|
||||
return NULL; /* exempt */
|
||||
}
|
||||
if (find_tkl_exception(TKL_NAME, cptr))
|
||||
return NULL; /* exempt */
|
||||
|
||||
return tkl;
|
||||
}
|
||||
@@ -2380,26 +2794,12 @@ aTKline *find_tkline_match_zap_matcher(aClient *cptr, aTKline *tkl)
|
||||
|
||||
if (match_user(tkl->ptr.serverban->hostmask, cptr, MATCH_CHECK_IP))
|
||||
{
|
||||
for (excepts = conf_except; excepts; excepts = excepts->next)
|
||||
{
|
||||
/* This used to be:
|
||||
* if (excepts->flag.type != CONF_EXCEPT_TKL || excepts->type != tkl->type)
|
||||
* It now checks for 'except ban', hope this is what most people want,
|
||||
* it is at least the same as in find_tkline_match, which is how it currently
|
||||
* is when a user is connected. -- Syzop/20081221
|
||||
*/
|
||||
if (excepts->flag.type != CONF_EXCEPT_BAN)
|
||||
continue;
|
||||
if (match_user(excepts->mask, cptr, MATCH_CHECK_IP))
|
||||
return NULL; /* exempt */
|
||||
}
|
||||
for (hook = Hooks[HOOKTYPE_TKL_EXCEPT]; hook; hook = hook->next)
|
||||
if (hook->func.intfunc(cptr, tkl) > 0)
|
||||
return NULL; /* exempt */
|
||||
|
||||
return tkl;
|
||||
if (find_tkl_exception(TKL_ZAP, cptr))
|
||||
return NULL; /* exempt */
|
||||
return tkl; /* banned */
|
||||
}
|
||||
return NULL;
|
||||
|
||||
return NULL; /* no match */
|
||||
}
|
||||
|
||||
/** Find matching (G)ZLINE, if any.
|
||||
@@ -2993,13 +3393,15 @@ void _sendnotice_tkl_add(aTKline *tkl)
|
||||
{
|
||||
if (tkl->expire_at != 0)
|
||||
{
|
||||
ircsnprintf(buf, sizeof(buf), "Exception added for %s%s@%s for types '%s' on %s GMT (from %s to expire at %s GMT: %s)",
|
||||
ircsnprintf(buf, sizeof(buf), "%s added for %s%s@%s for types '%s' on %s GMT (from %s to expire at %s GMT: %s)",
|
||||
tkl_type_str,
|
||||
(tkl->ptr.banexception->subtype & TKL_SUBTYPE_SOFT) ? "%" : "",
|
||||
tkl->ptr.banexception->usermask, tkl->ptr.banexception->hostmask,
|
||||
tkl->ptr.banexception->bantypes,
|
||||
set_at, tkl->set_by, expire_at, tkl->ptr.banexception->reason);
|
||||
} else {
|
||||
ircsnprintf(buf, sizeof(buf), "Permanent exception added for %s%s@%s for types '%s' on %s GMT (from %s: %s)",
|
||||
ircsnprintf(buf, sizeof(buf), "Permanent %s added for %s%s@%s for types '%s' on %s GMT (from %s: %s)",
|
||||
tkl_type_str,
|
||||
(tkl->ptr.banexception->subtype & TKL_SUBTYPE_SOFT) ? "%" : "",
|
||||
tkl->ptr.banexception->usermask, tkl->ptr.banexception->hostmask,
|
||||
tkl->ptr.banexception->bantypes,
|
||||
|
||||
Reference in New Issue
Block a user