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

First go at multi actions...

This commit is contained in:
Bram Matthys
2023-07-06 11:48:38 +02:00
parent 0af88581d3
commit 656ea105da
17 changed files with 446 additions and 232 deletions
+1 -1
View File
@@ -104,7 +104,7 @@ struct Configuration {
char *channel_command_prefix;
long handshake_data_flood_amount;
long handshake_data_flood_ban_time;
int handshake_data_flood_ban_action;
BanAction *handshake_data_flood_ban_action;
struct ChMode modes_on_join;
int modes_on_join_set;
char *level_on_join;
+18 -6
View File
@@ -732,10 +732,22 @@ extern void ExtbanDel(Extban *);
extern void extban_init(void);
extern char *trim_str(char *str, int len);
extern MODVAR char *ban_realhost, *ban_virthost, *ban_ip;
extern BanAction banact_stringtoval(const char *s);
extern const char *banact_valtostring(BanAction val);
extern BanAction banact_chartoval(char c);
extern char banact_valtochar(BanAction val);
extern BanAction *parse_ban_action_config(ConfigEntry *ce);
extern int test_ban_action_config(ConfigEntry *ce);
extern void free_single_ban_action(BanAction *action);
extern void free_all_ban_actions(BanAction *actions);
#define safe_free_all_ban_actions(x) do { free_all_ban_actions(x); x = NULL; } while(0)
#define safe_free_single_ban_action(x) do { free_single_ban_action(x); x = NULL; } while(0)
BanAction *duplicate_ban_actions(BanAction *actions);
extern BanActionValue banact_stringtoval(const char *s);
extern const char *banact_valtostring(BanActionValue val);
extern BanActionValue banact_chartoval(char c);
extern char banact_valtochar(BanActionValue val);
extern BanAction *banact_value_to_struct(BanActionValue val);
extern int only_actions_of_type(BanAction *actions, BanActionValue what);
extern int has_actions_of_type(BanAction *actions, BanActionValue what);
extern int only_soft_actions(BanAction *actions);
extern const char *ban_actions_to_string(BanAction *actions);
extern int spamfilter_gettargets(const char *s, Client *client);
extern char *spamfilter_target_inttostring(int v);
extern char *our_strcasestr(const char *haystack, const char *needle);
@@ -806,7 +818,7 @@ extern MODVAR TKL *(*tkl_add_banexception)(int type, const char *usermask, const
time_t expire_at, time_t set_at, int soft, const char *bantypes, int flags);
extern MODVAR TKL *(*tkl_add_nameban)(int type, const char *name, int hold, const char *reason, const char *setby,
time_t expire_at, time_t set_at, int flags);
extern MODVAR TKL *(*tkl_add_spamfilter)(int type, unsigned short target, unsigned short action, Match *match, const char *setby,
extern MODVAR TKL *(*tkl_add_spamfilter)(int type, unsigned short target, BanAction *action, Match *match, const char *setby,
time_t expire_at, time_t set_at,
time_t spamf_tkl_duration, const char *spamf_tkl_reason,
int flags);
@@ -827,7 +839,7 @@ extern MODVAR TKL *(*find_tkline_match_zap)(Client *cptr);
extern MODVAR void (*tkl_stats)(Client *cptr, int type, const char *para, int *cnt);
extern MODVAR void (*tkl_sync)(Client *client);
extern MODVAR void (*cmd_tkl)(Client *client, MessageTag *recv_mtags, int parc, const char *parv[]);
extern MODVAR int (*place_host_ban)(Client *client, BanAction action, const char *reason, long duration);
extern MODVAR int (*place_host_ban)(Client *client, BanAction *actions, const char *reason, long duration);
extern MODVAR int (*match_spamfilter)(Client *client, const char *str_in, int type, const char *cmd, const char *target, int flags, TKL **rettk);
extern MODVAR int (*match_spamfilter_mtags)(Client *client, MessageTag *mtags, const char *cmd);
extern MODVAR int (*join_viruschan)(Client *client, TKL *tk, int type);
+2 -2
View File
@@ -2099,12 +2099,12 @@ int hooktype_sasl_result(Client *client, int success);
* This is called for automated bans such as spamfilter hits, flooding, etc.
* This hook can be used to prevent the ban, or as used by the authprompt to delay it.
* @param client The client that should be banned
* @param action The TKL type, such as BAN_ACT_GLINE
* @param action The actions to take, one of BAN_ACT_*
* @param reason The ban reason
* @param duration The duration of the ban, 0 for permanent ban
* @return The magic value 99 is used to exempt the user (=do not ban!), otherwise the ban is added.
*/
int hooktype_place_host_ban(Client *client, int action, const char *reason, long duration);
int hooktype_place_host_ban(Client *client, BanActionValue action, const char *reason, long duration);
/** Called when a TKL ban is hit by this user (function prototype for HOOKTYPE_FIND_TKLINE_MATCH).
* This is called when an existing TKL entry is hit by the user.
+20 -5
View File
@@ -1111,7 +1111,7 @@ struct Secret {
#define SPAMFLAG_NOWARN 0x0001
/* Ban actions. These must be ordered by severity (!) */
typedef enum BanAction {
typedef enum BanActionValue {
BAN_ACT_GZLINE =1100,
BAN_ACT_GLINE =1000,
BAN_ACT_SOFT_GLINE = 950,
@@ -1132,7 +1132,22 @@ typedef enum BanAction {
BAN_ACT_SOFT_BLOCK = 150,
BAN_ACT_WARN = 100,
BAN_ACT_SOFT_WARN = 50,
} BanAction;
BAN_ACT_SET = 40,
} BanActionValue;
typedef enum VarActionValue {
VAR_ACT_SET = 1,
VAR_ACT_INCREASE = 2,
} VarActionValue;
typedef struct BanAction BanAction;
struct BanAction {
BanAction *prev, *next;
BanActionValue action;
char *var;
int value;
VarActionValue var_action;
};
#define IsSoftBanAction(x) ((x == BAN_ACT_SOFT_GLINE) || (x == BAN_ACT_SOFT_KLINE) || \
(x == BAN_ACT_SOFT_SHUN) || (x == BAN_ACT_SOFT_KILL) || \
@@ -1159,7 +1174,7 @@ struct NameBan {
/** Spamfilter sub-struct of TKL entry (Spamfilter) */
struct Spamfilter {
unsigned short target;
BanAction action; /**< Ban action, see BAN_ACT* */
BanAction *action; /**< Ban action */
Match *match; /**< Spamfilter matcher */
char *tkl_reason; /**< Reason to use for bans placed by this spamfilter, escaped by unreal_encodespace(). */
time_t tkl_duration; /**< Duration of bans placed by this spamfilter */
@@ -1940,8 +1955,8 @@ struct ConfigItem_link {
struct ConfigItem_ban {
ConfigItem_ban *prev, *next;
ConfigFlag_ban flag;
char *mask, *reason;
unsigned short action;
char *mask, *reason;
BanAction *action;
};
struct ConfigItem_deny_dcc {
+2 -2
View File
@@ -55,7 +55,7 @@ TKL *(*tkl_add_serverban)(int type, const char *usermask, const char *hostmask,
time_t expire_at, time_t set_at, int soft, int flags);
TKL *(*tkl_add_nameban)(int type, const char *name, int hold, const char *reason, const char *setby,
time_t expire_at, time_t set_at, int flags);
TKL *(*tkl_add_spamfilter)(int type, unsigned short target, unsigned short action, Match *match, const char *setby,
TKL *(*tkl_add_spamfilter)(int type, unsigned short target, BanAction *action, Match *match, const char *setby,
time_t expire_at, time_t set_at,
time_t spamf_tkl_duration, const char *spamf_tkl_reason,
int flags);
@@ -72,7 +72,7 @@ TKL *(*find_tkline_match_zap)(Client *client);
void (*tkl_stats)(Client *client, int type, const char *para, int *cnt);
void (*tkl_sync)(Client *client);
void (*cmd_tkl)(Client *client, MessageTag *mtags, int parc, const char *parv[]);
int (*place_host_ban)(Client *client, BanAction action, const char *reason, long duration);
int (*place_host_ban)(Client *client, BanAction *action, const char *reason, long duration);
int (*match_spamfilter)(Client *client, const char *str_in, int type, const char *cmd, const char *target, int flags, TKL **rettk);
int (*match_spamfilter_mtags)(Client *client, MessageTag *mtags, const char *cmd);
int (*join_viruschan)(Client *client, TKL *tk, int type);
+10 -19
View File
@@ -1648,6 +1648,7 @@ void free_iConf(Configuration *i)
safe_free(i->helpchan);
safe_free(i->stats_server);
safe_free(i->sasl_server);
safe_free_all_ban_actions(i->handshake_data_flood_ban_action);
// anti-flood:
for (f = i->floodsettings; f; f = f_next)
{
@@ -1710,7 +1711,8 @@ void config_setdefaultsettings(Configuration *i)
/* - everyone */
i->throttle_count = 3; i->throttle_period = 60; /* throttle protection: max 3 per 60s */
i->handshake_data_flood_amount = 4096;
i->handshake_data_flood_ban_action = BAN_ACT_ZLINE;
i->handshake_data_flood_ban_action = safe_alloc(sizeof(BanAction));
i->handshake_data_flood_ban_action->action = BAN_ACT_ZLINE;
i->handshake_data_flood_ban_time = 600;
// (targetflood is in the targetflood module)
/* - known-users */
@@ -2462,6 +2464,7 @@ void config_rehash()
{
safe_free(ban_ptr->mask);
safe_free(ban_ptr->reason);
free_all_ban_actions(ban_ptr->action);
DelListItem(ban_ptr, conf_ban);
safe_free(ban_ptr);
}
@@ -6901,7 +6904,7 @@ int _conf_ban(ConfigFile *conf, ConfigEntry *ce)
else if (!strcmp(cep->name, "reason"))
safe_strdup(ca->reason, cep->value);
else if (!strcmp(cep->name, "action"))
ca->action = banact_stringtoval(cep->value);
ca->action = parse_ban_action_config(cep);
}
AddListItem(ca, conf_ban);
return 0;
@@ -7000,13 +7003,7 @@ int _test_ban(ConfigFile *conf, ConfigEntry *ce)
cep->line_number, "ban::action");
}
has_action = 1;
if (!banact_stringtoval(cep->value))
{
config_error("%s:%i: ban::action has unknown action type '%s'",
cep->file->filename, cep->line_number,
cep->value);
errors++;
}
errors += test_ban_action_config(cep);
}
}
@@ -7800,8 +7797,8 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
tempiConf.handshake_data_flood_amount = config_checkval(cep4->value, CFG_SIZE);
else if (!strcmp(cep4->name, "ban-time"))
tempiConf.handshake_data_flood_ban_time = config_checkval(cep4->value, CFG_TIME);
else if (!strcmp(cep4->name, "ban-action"))
tempiConf.handshake_data_flood_ban_action = banact_stringtoval(cep4->value);
else if (!strcmp(cep4->name, "ban-action") || !strcmp(cep4->name, "action"))
tempiConf.handshake_data_flood_ban_action = parse_ban_action_config(cep4);
}
}
else if (!strcmp(ceppp->name, "away-flood"))
@@ -8718,16 +8715,10 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
errors++;
}
} else
if (!strcmp(cep4->name, "ban-action"))
if (!strcmp(cep4->name, "ban-action") || !strcmp(cep4->name, "action"))
{
CheckNull(cep4);
if (!banact_stringtoval(cep4->value))
{
config_error("%s:%i: set::anti-flood::handshake-data-flood::ban-action has unknown action type '%s'",
cep4->file->filename, cep4->line_number,
cep4->value);
errors++;
}
errors += test_ban_action_config(cep4);
} else
if (!strcmp(cep4->name, "ban-time"))
{
+1 -1
View File
@@ -571,7 +571,7 @@ void json_expand_tkl(json_t *root, const char *key, TKL *tkl, int detail)
{
json_object_set_new(j, "name", json_string_unreal(tkl->ptr.spamfilter->match->str));
json_object_set_new(j, "match_type", json_string_unreal(unreal_match_method_valtostr(tkl->ptr.spamfilter->match->type)));
json_object_set_new(j, "ban_action", json_string_unreal(banact_valtostring(tkl->ptr.spamfilter->action)));
json_object_set_new(j, "ban_action", json_string_unreal(ban_actions_to_string(tkl->ptr.spamfilter->action)));
json_object_set_new(j, "ban_duration", json_integer(tkl->ptr.spamfilter->tkl_duration));
json_object_set_new(j, "ban_duration_string", json_string_unreal(pretty_time_val_r(buf, sizeof(buf), tkl->ptr.spamfilter->tkl_duration)));
json_object_set_new(j, "spamfilter_targets", json_string_unreal(spamfilter_target_inttostring(tkl->ptr.spamfilter->target)));
+192 -4
View File
@@ -79,6 +79,7 @@ static BanActTable banacttable[] = {
{ BAN_ACT_SOFT_VIRUSCHAN,'V', "soft-viruschan" },
{ BAN_ACT_WARN, 'w', "warn" },
{ BAN_ACT_SOFT_WARN, 'W', "soft-warn" },
{ BAN_ACT_SET, '1', "set" },
{ 0, 0, 0 }
};
@@ -781,8 +782,100 @@ int valid_vhost(const char *userhost)
/*|| BAN ACTION ROUTINES FOLLOW ||*/
int test_ban_action_config_helper(ConfigEntry *ce, const char *name, const char *value)
{
int errors = 0;
BanActionValue action;
action = banact_stringtoval(name);
if (!action)
{
config_error("%s:%d: unknown action: %s",
ce->file->filename, ce->line_number, name);
errors++;
} else
{
// TODO: parse values
}
return errors;
}
/** Test an action item in the config.
* @param ce The config entry to parse
* @returns Number of errors, so 0 means OK.
*/
int test_ban_action_config(ConfigEntry *ce)
{
ConfigEntry *cep;
int errors = 0;
if (ce->items && !ce->value)
{
/* action { xxx; } */
for (cep = ce->items; cep; cep = cep->next)
errors += test_ban_action_config_helper(cep, cep->name, cep->value);
} else
if (!ce->value)
{
config_error("%s:%d: action has no value", ce->file->filename, ce->line_number);
errors++;
} else
{
/* action xxx; */
errors += test_ban_action_config_helper(ce, ce->value, NULL);
}
return errors;
}
BanAction *parse_ban_action_config_helper(const char *name, const char *value)
{
int errors = 0;
BanAction *action = safe_alloc(sizeof(BanAction));
action->action = banact_stringtoval(name);
if (!action->action)
abort(); /* impossible, is config tested earlier */
// TODO: parse values
return action;
}
/** Parse an action item in the config.
* @param ce The config entry to parse
* @returns BanAction item (can be more than one, in the linked list)
*/
BanAction *parse_ban_action_config(ConfigEntry *ce)
{
ConfigEntry *cep;
BanAction *action_list = NULL;
BanAction *action;
if (ce->items && !ce->value)
{
/* action { xxx; } */
for (cep = ce->items; cep; cep = cep->next)
{
action = parse_ban_action_config_helper(cep->name, cep->value);
if (action)
AppendListItem(action, action_list);
}
} else
if (ce->value)
{
/* action xxx; */
action = parse_ban_action_config_helper(ce->value, NULL);
if (action)
AppendListItem(action, action_list);
}
return action_list;
}
/** Converts a banaction string (eg: "kill") to an integer value (eg: BAN_ACT_KILL) */
BanAction banact_stringtoval(const char *s)
BanActionValue banact_stringtoval(const char *s)
{
BanActTable *b;
@@ -793,7 +886,7 @@ BanAction banact_stringtoval(const char *s)
}
/** Converts a banaction character (eg: 'K') to an integer value (eg: BAN_ACT_KILL) */
BanAction banact_chartoval(char c)
BanActionValue banact_chartoval(char c)
{
BanActTable *b;
@@ -804,7 +897,7 @@ BanAction banact_chartoval(char c)
}
/** Converts a banaction value (eg: BAN_ACT_KILL) to a character value (eg: 'k') */
char banact_valtochar(BanAction val)
char banact_valtochar(BanActionValue val)
{
BanActTable *b;
@@ -815,7 +908,7 @@ char banact_valtochar(BanAction val)
}
/** Converts a banaction value (eg: BAN_ACT_KLINE) to a string (eg: "kline") */
const char *banact_valtostring(BanAction val)
const char *banact_valtostring(BanActionValue val)
{
BanActTable *b;
@@ -825,6 +918,12 @@ const char *banact_valtostring(BanAction val)
return "UNKNOWN";
}
BanAction *banact_value_to_struct(BanActionValue val)
{
BanAction *action = safe_alloc(sizeof(BanAction));
action->action = val;
return action;
}
/*|| BAN TARGET ROUTINES FOLLOW ||*/
/** Extract target flags from string 's'. */
@@ -2729,3 +2828,92 @@ const char *command_issued_by_rpc(MessageTag *mtags)
return m->value;
return NULL;
}
/** Check if action is only of type 'what', eg if they are all BAN_ACT_WARN */
int only_actions_of_type(BanAction *actions, BanActionValue what)
{
for (; actions; actions = actions->next)
if (actions->action != what)
return 0;
return 1;
}
/** Check if action 'what' is in any of 'actions' */
int has_actions_of_type(BanAction *actions, BanActionValue what)
{
for (; actions; actions = actions->next)
if (actions->action == what)
return 1;
return 0;
}
/** Check if only soft ban actions */
int only_soft_actions(BanAction *actions)
{
for (; actions; actions = actions->next)
if (!IsSoftBanAction(actions->action))
return 0;
return 1;
}
/** Turn a linked list BanAction * into a string of actions.
* Returns something like "gline" or "set, gline"
*/
const char *ban_actions_to_string(BanAction *actions)
{
static char buf[512];
const char *s;
BanAction *action;
*buf = '\0';
for (action = actions; action; action = action->next)
{
s = banact_valtostring(action->action);
if (!s)
s = "???";
strlcat(buf, s, sizeof(buf));
strlcat(buf, ", ", sizeof(buf));
}
/* Cut off trailing ", " */
if (*buf)
buf[strlen(buf)-2] = '\0';
return buf;
}
void free_single_ban_action(BanAction *action)
{
safe_free(action->var);
safe_free(action);
}
void free_all_ban_actions(BanAction *actions)
{
BanAction *next;
for (; actions; actions = next)
{
next = actions->next;
free_single_ban_action(actions);
}
}
/** Duplicate an entire BanAction linked list (deep copy) */
BanAction *duplicate_ban_actions(BanAction *actions)
{
BanAction *newlist = NULL;
BanAction *action, *n;
for (action = actions; action; action = action->next)
{
n = safe_alloc(sizeof(BanAction));
// This matches the struct.h order:
n->action = action->action;
safe_strdup(n->var, action->var);
n->value = action->value;
n->var_action = action->var_action;
/* And add to the list, maintain action ordering */
AppendListItem(n, newlist);
}
return newlist;
}
+16 -17
View File
@@ -57,7 +57,7 @@ ModuleHeader MOD_HEADER
struct {
int score;
BanAction ban_action;
BanAction *ban_action;
char *ban_reason;
long ban_time;
SecurityGroup *except;
@@ -685,24 +685,25 @@ CMD_OVERRIDE_FUNC(override_msg)
score = lookalikespam_score(text, NULL, 0);
if ((score >= cfg.score) && !find_tkl_exception(TKL_ANTIMIXEDUTF8, client))
{
/* Re-run with a log buffer... */
char logbuf[512];
int retval;
/* Re-run with a log buffer and log... */
logbuf[0] = '\0';
lookalikespam_score(text, logbuf, sizeof(logbuf));
/* And log... */
unreal_log(ULOG_INFO, "antimixedutf8", "ANTIMIXEDUTF8_HIT", client,
"[antimixedutf8] Client $client.details hit score $score -- taking action. Mixed scripts detected: $scripts",
log_data_integer("score", score),
log_data_string("scripts", logbuf));
if ((cfg.ban_action == BAN_ACT_BLOCK) ||
((cfg.ban_action == BAN_ACT_SOFT_BLOCK) && !IsLoggedIn(client)))
/* Take the action */
retval = place_host_ban(client, cfg.ban_action, cfg.ban_reason, cfg.ban_time);
if (retval == 1)
return;
if (retval == BAN_ACT_BLOCK)
{
sendnotice(client, "%s", cfg.ban_reason);
return;
} else {
if (place_host_ban(client, cfg.ban_action, cfg.ban_reason, cfg.ban_time))
return;
/* a return value of 0 means the user is exempted, so fallthrough.. */
}
}
@@ -749,7 +750,7 @@ static void init_config(void)
/* Default values */
cfg.score = 10;
safe_strdup(cfg.ban_reason, "Possible mixed character spam");
cfg.ban_action = BAN_ACT_BLOCK;
cfg.ban_action = banact_value_to_struct(BAN_ACT_BLOCK);
cfg.ban_time = 60 * 60 * 4; /* irrelevant for block, but some default for others */
}
@@ -757,6 +758,7 @@ static void free_config(void)
{
safe_free(cfg.ban_reason);
free_security_group(cfg.except);
safe_free_all_ban_actions(cfg.ban_action);
memset(&cfg, 0, sizeof(cfg)); /* needed! */
}
@@ -792,12 +794,7 @@ int antimixedutf8_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *er
} else
if (!strcmp(cep->name, "ban-action"))
{
if (!banact_stringtoval(cep->value))
{
config_error("%s:%i: set::antimixedutf8::ban-action: unknown action '%s'",
cep->file->filename, cep->line_number, cep->value);
errors++;
}
errors += test_ban_action_config(cep);
} else
if (!strcmp(cep->name, "ban-reason"))
{
@@ -838,7 +835,9 @@ int antimixedutf8_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
} else
if (!strcmp(cep->name, "ban-action"))
{
cfg.ban_action = banact_stringtoval(cep->value);
if (cfg.ban_action)
safe_free_all_ban_actions(cfg.ban_action);
cfg.ban_action = parse_ban_action_config(cep);
} else
if (!strcmp(cep->name, "ban-reason"))
{
+11 -16
View File
@@ -499,7 +499,7 @@ struct {
struct {
int threshold;
BanAction ban_action;
BanAction *ban_action;
char *ban_reason;
long ban_time;
int convert_to_lowercase;
@@ -563,6 +563,7 @@ static void free_config(void)
{
safe_free(cfg.ban_reason);
free_security_group(cfg.except);
safe_free_all_ban_actions(cfg.ban_action);
memset(&cfg, 0, sizeof(cfg)); /* needed! */
}
@@ -612,13 +613,8 @@ int antirandom_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
} else
if (!strcmp(cep->name, "ban-action"))
{
if (!banact_stringtoval(cep->value))
{
config_error("%s:%i: set::antirandom::ban-action: unknown action '%s'",
cep->file->filename, cep->line_number, cep->value);
errors++;
} else
req.ban_action = 1;
req.ban_action = 1;
errors += test_ban_action_config(cep);
} else
if (!strcmp(cep->name, "ban-reason"))
{
@@ -678,7 +674,7 @@ int antirandom_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
} else
if (!strcmp(cep->name, "ban-action"))
{
cfg.ban_action = banact_stringtoval(cep->value);
cfg.ban_action = parse_ban_action_config(cep);
} else
if (!strcmp(cep->name, "ban-reason"))
{
@@ -870,21 +866,20 @@ int antirandom_preconnect(Client *client)
score = get_spam_score(client);
if (score > cfg.threshold)
{
if (cfg.ban_action == BAN_ACT_WARN)
if (has_actions_of_type(cfg.ban_action, BAN_ACT_WARN))
{
unreal_log(ULOG_INFO, "antirandom", "ANTIRANDOM_DENIED_USER", client,
"[antirandom] would have denied access to user with score $score: $client.details:$client.user.realname",
log_data_integer("score", score));
return HOOK_CONTINUE;
}
if (cfg.show_failedconnects)
} else
if (cfg.show_failedconnects) // FIXME: this is not entirely correct, with like soft actions or var setting, etc!
{
unreal_log(ULOG_INFO, "antirandom", "ANTIRANDOM_DENIED_USER", client,
"[antirandom] denied access to user with score $score: $client.details:$client.user.realname",
log_data_integer("score", score));
}
place_host_ban(client, cfg.ban_action, cfg.ban_reason, cfg.ban_time);
return HOOK_DENY;
if (place_host_ban(client, cfg.ban_action, cfg.ban_reason, cfg.ban_time))
return HOOK_DENY;
}
return HOOK_CONTINUE;
}
@@ -911,7 +906,7 @@ static int is_exempt(Client *client)
return 1;
/* Soft ban and logged in? */
if (IsSoftBanAction(cfg.ban_action) && IsLoggedIn(client))
if (only_soft_actions(cfg.ban_action) && IsLoggedIn(client))
return 1;
return 0;
+10 -17
View File
@@ -64,7 +64,7 @@ struct Blacklist {
char *name;
BlacklistBackendType backend_type;
BlacklistBackend *backend;
int action;
BanAction *action;
long ban_time;
char *reason;
SecurityGroup *except;
@@ -80,7 +80,7 @@ struct BLUser {
int is_ipv6;
int refcnt;
/* The following save_* fields are used by softbans: */
int save_action;
BanAction *save_action;
long save_tkltime;
char *save_opernotice;
char *save_reason;
@@ -237,6 +237,7 @@ void delete_blacklist_block(Blacklist *e)
safe_free(e->name);
safe_free(e->reason);
safe_free_all_ban_actions(e->action);
free_security_group(e->except);
safe_free(e);
@@ -379,12 +380,7 @@ int blacklist_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
continue;
}
has_action = 1;
if (!banact_stringtoval(cep->value))
{
config_error("%s:%i: blacklist::action has unknown action type '%s'",
cep->file->filename, cep->line_number, cep->value);
errors++;
}
errors += test_ban_action_config(cep);
}
else if (!strcmp(cep->name, "ban-time"))
{
@@ -467,8 +463,6 @@ int blacklist_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
d = safe_alloc(sizeof(Blacklist));
safe_strdup(d->name, ce->value);
/* set some defaults */
d->action = BAN_ACT_KILL;
safe_strdup(d->reason, "Your IP is on a DNS Blacklist");
d->ban_time = 3600;
/* assume dns for now ;) */
@@ -529,7 +523,7 @@ int blacklist_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
}
else if (!strcmp(cep->name, "action"))
{
d->action = banact_stringtoval(cep->value);
d->action = parse_ban_action_config(cep);
}
else if (!strcmp(cep->name, "ban-time"))
{
@@ -692,6 +686,7 @@ void blacklist_free_bluser_if_able(BLUser *bl)
safe_free(bl->save_opernotice);
safe_free(bl->save_reason);
free_all_ban_actions(bl->save_action);
safe_free(bl);
}
@@ -747,7 +742,7 @@ int blacklist_parse_reply(struct hostent *he, int entry)
* from blacklist_preconnect() for softbans that need to be delayed
* as to give the user the opportunity to do SASL Authentication.
*/
int blacklist_action(Client *client, char *opernotice, BanAction ban_action, char *ban_reason, long ban_time,
int blacklist_action(Client *client, char *opernotice, BanAction *ban_action, char *ban_reason, long ban_time,
char *blacklist, char *blacklist_dns_name, int blacklist_dns_reply)
{
unreal_log_raw(ULOG_INFO, "blacklist", "BLACKLIST_HIT", client,
@@ -755,11 +750,9 @@ int blacklist_action(Client *client, char *opernotice, BanAction ban_action, cha
log_data_string("blacklist_name", blacklist),
log_data_string("blacklist_dns_name", blacklist_dns_name),
log_data_integer("blacklist_dns_reply", blacklist_dns_reply),
log_data_string("ban_action", banact_valtostring(ban_action)),
log_data_string("ban_action", ban_actions_to_string(ban_action)),
log_data_string("ban_reason", ban_reason),
log_data_integer("ban_time", ban_time));
if (ban_action == BAN_ACT_WARN)
return 0;
return place_host_ban(client, ban_action, ban_reason, ban_time);
}
@@ -797,10 +790,10 @@ void blacklist_hit(Client *client, Blacklist *bl, int reply)
buildvarstring(bl->reason, banbuf, sizeof(banbuf), name, value);
if (IsSoftBanAction(bl->action) && blu)
if (only_soft_actions(bl->action) && blu)
{
/* For soft bans, delay the action until later (so user can do SASL auth) */
blu->save_action = bl->action;
blu->save_action = duplicate_ban_actions(bl->action);
blu->save_tkltime = bl->ban_time;
safe_strdup(blu->save_opernotice, opernotice);
safe_strdup(blu->save_reason, banbuf);
+1 -5
View File
@@ -616,14 +616,10 @@ int ban_version(Client *client, const char *text)
if ((ban = find_ban(NULL, ctcp_reply, CONF_BAN_VERSION)))
{
if (IsSoftBanAction(ban->action) && IsLoggedIn(client))
return 0; /* soft ban does not apply to us, we are logged in */
if (find_tkl_exception(TKL_BAN_VERSION, client))
return 0; /* we are exempt */
place_host_ban(client, ban->action, ban->reason, BAN_VERSION_TKL_TIME);
return 1;
return place_host_ban(client, ban->action, ban->reason, BAN_VERSION_TKL_TIME);
}
return 0;
+3 -2
View File
@@ -1051,8 +1051,9 @@ int _register_user(Client *client)
spamfilter_build_user_string(spamfilter_user, client->name, client);
if (match_spamfilter(client, spamfilter_user, SPAMF_USER, NULL, NULL, 0, &savetkl))
{
if (savetkl && ((savetkl->ptr.spamfilter->action == BAN_ACT_VIRUSCHAN) ||
(savetkl->ptr.spamfilter->action == BAN_ACT_SOFT_VIRUSCHAN)))
if (savetkl &&
(has_actions_of_type(savetkl->ptr.spamfilter->action, BAN_ACT_VIRUSCHAN) ||
has_actions_of_type(savetkl->ptr.spamfilter->action, BAN_ACT_SOFT_VIRUSCHAN)))
{
/* 'viruschan' action:
* Continue with registering the client, and at the end
+6 -5
View File
@@ -100,9 +100,10 @@ RPC_CALL_FUNC(rpc_spamfilter_list)
/* Shared code for selecting a spamfilter, for .add/.del/get */
int spamfilter_select_criteria(Client *client, json_t *request, json_t *params, const char **name, int *match_type,
int *targets, char *targetbuf, size_t targetbuflen, BanAction *action, char *actionbuf)
int *targets, char *targetbuf, size_t targetbuflen, BanActionValue *action, char *actionbuf)
{
const char *str;
int actval;
*name = json_object_get_string(params, "name");
if (!*name)
@@ -161,7 +162,7 @@ RPC_CALL_FUNC(rpc_spamfilter_get)
int type = TKL_SPAMF|TKL_GLOBAL;
const char *name;
TKL *tkl;
BanAction action;
BanActionValue action;
int match_type = 0;
int targets = 0;
char targetbuf[64];
@@ -193,7 +194,7 @@ RPC_CALL_FUNC(rpc_spamfilter_add)
time_t ban_duration = 0;
TKL *tkl;
Match *m;
BanAction action;
BanActionValue action;
int match_type = 0;
int targets = 0;
char targetbuf[64];
@@ -246,7 +247,7 @@ RPC_CALL_FUNC(rpc_spamfilter_add)
return;
}
tkl = tkl_add_spamfilter(type, targets, action, m, set_by, 0, TStime(),
tkl = tkl_add_spamfilter(type, targets, banact_value_to_struct(action), m, set_by, 0, TStime(),
ban_duration, reason, 0);
if (!tkl)
@@ -270,7 +271,7 @@ RPC_CALL_FUNC(rpc_spamfilter_del)
const char *name;
const char *set_by;
TKL *tkl;
BanAction action;
BanActionValue action;
int match_type = 0;
int targets = 0;
char targetbuf[64];
+1 -1
View File
@@ -868,7 +868,7 @@ int stats_set(Client *client, const char *para)
sendtxtnumeric(client, "link::bind-ip: %s", LINK_BINDIP);
sendtxtnumeric(client, "anti-flood::connect-flood: %d per %s", THROTTLING_COUNT, pretty_time_val(THROTTLING_PERIOD));
sendtxtnumeric(client, "anti-flood::handshake-data-flood::amount: %ld bytes", iConf.handshake_data_flood_amount);
sendtxtnumeric(client, "anti-flood::handshake-data-flood::ban-action: %s", banact_valtostring(iConf.handshake_data_flood_ban_action));
sendtxtnumeric(client, "anti-flood::handshake-data-flood::ban-action: %s", banact_valtostring(iConf.handshake_data_flood_ban_action->action));
sendtxtnumeric(client, "anti-flood::handshake-data-flood::ban-time: %s", pretty_time_val(iConf.handshake_data_flood_ban_time));
/* set::anti-flood */
+149 -126
View File
@@ -68,7 +68,7 @@ TKL *_tkl_add_banexception(int type, char *usermask, char *hostmask, SecurityGro
time_t expire_at, time_t set_at, int soft, char *bantypes, int flags);
TKL *_tkl_add_nameban(int type, char *name, int hold, char *reason, char *set_by,
time_t expire_at, time_t set_at, int flags);
TKL *_tkl_add_spamfilter(int type, unsigned short target, BanAction action, Match *match, char *set_by,
TKL *_tkl_add_spamfilter(int type, unsigned short target, BanAction *action, Match *match, char *set_by,
time_t expire_at, time_t set_at,
time_t spamf_tkl_duration, char *spamf_tkl_reason,
int flags);
@@ -88,7 +88,7 @@ TKL *_find_tkline_match_zap(Client *client);
void _tkl_stats(Client *client, int type, const char *para, int *cnt);
void _tkl_sync(Client *client);
CMD_FUNC(_cmd_tkl);
int _place_host_ban(Client *client, BanAction action, char *reason, long duration);
int _place_host_ban(Client *client, BanAction *action, char *reason, long duration);
int _match_spamfilter(Client *client, const char *str_in, int type, const char *cmd, const char *target, int flags, TKL **rettk);
int _match_spamfilter_mtags(Client *client, MessageTag *mtags, char *cmd);
int check_mtag_spamfilters_present(void);
@@ -97,13 +97,13 @@ void _spamfilter_build_user_string(char *buf, char *nick, Client *client);
int _match_user(const char *rmask, Client *client, int options);
int _unreal_match_iplist(Client *client, NameList *l);
int _match_user_extended_server_ban(const char *banstr, Client *client);
void ban_target_to_tkl_layer(BanTarget ban_target, BanAction action, Client *client, const char **tkl_username, const char **tkl_hostname);
void ban_target_to_tkl_layer(BanTarget ban_target, BanActionValue action, Client *client, const char **tkl_username, const char **tkl_hostname);
int _tkl_ip_hash(char *ip);
int _tkl_ip_hash_type(int type);
TKL *_find_tkl_serverban(int type, char *usermask, char *hostmask, int softban);
TKL *_find_tkl_banexception(int type, char *usermask, char *hostmask, int softban);
TKL *_find_tkl_nameban(int type, char *name, int hold);
TKL *_find_tkl_spamfilter(int type, char *match_string, BanAction action, unsigned short target);
TKL *_find_tkl_spamfilter(int type, char *match_string, BanActionValue action, unsigned short target);
int _find_tkl_exception(int ban_type, Client *client);
int _server_ban_parse_mask(Client *client, int add, char type, const char *str, char **usermask_out, char **hostmask_out, int *soft, const char **error);
int _server_ban_exception_parse_mask(Client *client, int add, const char *bantypes, const char *str, char **usermask_out, char **hostmask_out, int *soft, const char **error);
@@ -317,14 +317,25 @@ int tkl_config_test_spamfilter(ConfigFile *cf, ConfigEntry *ce, int type, int *e
}
continue;
}
if (!cep->value)
else if (!strcmp(cep->name, "action"))
{
if (has_action)
{
config_warn_duplicate(cep->file->filename,
cep->line_number, "spamfilter::action");
continue;
}
has_action = 1;
errors += test_ban_action_config(cep);
}
else if (!cep->value)
{
config_error_empty(cep->file->filename, cep->line_number,
"spamfilter", cep->name);
errors++;
continue;
}
if (!strcmp(cep->name, "reason"))
else if (!strcmp(cep->name, "reason"))
{
if (has_reason)
{
@@ -346,22 +357,6 @@ int tkl_config_test_spamfilter(ConfigFile *cf, ConfigEntry *ce, int type, int *e
has_match = 1;
match = cep->value;
}
else if (!strcmp(cep->name, "action"))
{
if (has_action)
{
config_warn_duplicate(cep->file->filename,
cep->line_number, "spamfilter::action");
continue;
}
has_action = 1;
if (!banact_stringtoval(cep->value))
{
config_error("%s:%i: spamfilter::action has unknown action type '%s'",
cep->file->filename, cep->line_number, cep->value);
errors++;
}
}
else if (!strcmp(cep->name, "ban-time"))
{
if (has_bantime)
@@ -482,7 +477,8 @@ int tkl_config_run_spamfilter(ConfigFile *cf, ConfigEntry *ce, int type)
char *word = NULL;
time_t bantime = tempiConf.spamfilter_ban_time;
char *banreason = tempiConf.spamfilter_ban_reason;
int action = 0, target = 0;
BanAction *action;
int target = 0;
int match_type = 0;
Match *m;
@@ -508,7 +504,7 @@ int tkl_config_run_spamfilter(ConfigFile *cf, ConfigEntry *ce, int type)
}
else if (!strcmp(cep->name, "action"))
{
action = banact_stringtoval(cep->value);
action = parse_ban_action_config(cep);
}
else if (!strcmp(cep->name, "reason"))
{
@@ -1556,7 +1552,7 @@ int _server_ban_parse_mask(Client *client, int add, char type, const char *str,
Client *acptr;
if ((acptr = find_user(mask, NULL)))
{
BanAction action = BAN_ACT_KLINE; // just a dummy default
BanActionValue action = BAN_ACT_KLINE; // just a dummy default
if ((type == 'z') || (type == 'Z'))
action = BAN_ACT_ZLINE; // to indicate zline (no hostname, no dns, etc)
ban_target_to_tkl_layer(iConf.manual_ban_target, action, acptr, (const char **)&usermask, (const char **)&hostmask);
@@ -1897,7 +1893,7 @@ int _server_ban_exception_parse_mask(Client *client, int add, const char *bantyp
Client *acptr;
if ((acptr = find_user(mask, NULL)))
{
BanAction action = BAN_ACT_KLINE; // just a dummy default
BanActionValue action = BAN_ACT_KLINE; // just a dummy default
if (add && eline_type_requires_ip(bantypes))
action = BAN_ACT_ZLINE; // to indicate zline (no hostname, no dns, etc)
ban_target_to_tkl_layer(iConf.manual_ban_target, action, acptr, (const char **)&usermask, (const char **)&hostmask);
@@ -2115,7 +2111,7 @@ void spamfilter_del_by_id(Client *client, const char *id)
/* Spamfilter found. Now fill the tkllayer */
tkllayer[1] = "-";
tkllayer[3] = spamfilter_target_inttostring(tk->ptr.spamfilter->target); /* target(s) */
mo[0] = banact_valtochar(tk->ptr.spamfilter->action);
mo[0] = banact_valtochar(tk->ptr.spamfilter->action->action);
mo[1] = '\0';
tkllayer[4] = mo; /* action */
tkllayer[5] = make_nick_user_host(client->name, client->user->username, GetHost(client));
@@ -2589,7 +2585,7 @@ TKL *tkl_find_head(char type, char *hostmask, TKL *def)
* @returns The TKL entry, or NULL in case of a problem,
* such as a regex failing to compile, memory problem, ..
*/
TKL *_tkl_add_spamfilter(int type, unsigned short target, BanAction action, Match *match, char *set_by,
TKL *_tkl_add_spamfilter(int type, unsigned short target, BanAction *action, Match *match, char *set_by,
time_t expire_at, time_t set_at,
time_t tkl_duration, char *tkl_reason,
int flags)
@@ -3675,7 +3671,7 @@ int tkl_stats_matcher(Client *client, int type, const char *para, TKLFlag *tklfl
(tkl->type & TKL_GLOBAL) ? 'F' : 'f',
unreal_match_method_valtostr(tkl->ptr.spamfilter->match->type),
spamfilter_target_inttostring(tkl->ptr.spamfilter->target),
banact_valtostring(tkl->ptr.spamfilter->action),
banact_valtostring(tkl->ptr.spamfilter->action->action),
(tkl->expire_at != 0) ? (long long)(tkl->expire_at - TStime()) : 0,
(long long)(TStime() - tkl->set_at),
(long long)tkl->ptr.spamfilter->tkl_duration,
@@ -3841,7 +3837,7 @@ void tkl_sync_send_entry(int add, Client *sender, Client *to, TKL *tkl)
add ? '+' : '-',
typ,
spamfilter_target_inttostring(tkl->ptr.spamfilter->target),
banact_valtochar(tkl->ptr.spamfilter->action),
banact_valtochar(tkl->ptr.spamfilter->action->action),
tkl->set_by,
(long long)tkl->expire_at, (long long)tkl->set_at,
(long long)tkl->ptr.spamfilter->tkl_duration, tkl->ptr.spamfilter->tkl_reason,
@@ -3991,7 +3987,7 @@ TKL *_find_tkl_nameban(int type, char *name, int hold)
}
/** Find a spamfilter TKL - only used to prevent duplicates and for deletion */
TKL *_find_tkl_spamfilter(int type, char *match_string, BanAction action, unsigned short target)
TKL *_find_tkl_spamfilter(int type, char *match_string, BanActionValue action, unsigned short target)
{
char tpe = tkl_typetochar(type);
TKL *tkl;
@@ -4003,7 +3999,7 @@ TKL *_find_tkl_spamfilter(int type, char *match_string, BanAction action, unsign
{
if ((type == tkl->type) &&
!strcmp(match_string, tkl->ptr.spamfilter->match->str) &&
(action == tkl->ptr.spamfilter->action) &&
(action == tkl->ptr.spamfilter->action->action) &&
(target == tkl->ptr.spamfilter->target))
{
return tkl;
@@ -4102,7 +4098,7 @@ void _tkl_added(Client *client, TKL *tkl)
sendnotice_tkl_add(tkl);
/* spamfilter 'warn' action is special */
if ((tkl->type & TKL_SPAMF) && (tkl->ptr.spamfilter->action == BAN_ACT_WARN) && (tkl->ptr.spamfilter->target & SPAMF_USER))
if ((tkl->type & TKL_SPAMF) && (tkl->ptr.spamfilter->action->action == BAN_ACT_WARN) && (tkl->ptr.spamfilter->target & SPAMF_USER))
spamfilter_check_users(tkl);
/* Ban checking executes during run loop for efficiency */
@@ -4283,7 +4279,7 @@ CMD_FUNC(cmd_tkl_add)
Match *m; /* compiled match_string */
time_t tkl_duration;
const char *tkl_reason;
BanAction action;
BanActionValue action;
unsigned short target;
/* helper variables */
char *err;
@@ -4348,7 +4344,7 @@ CMD_FUNC(cmd_tkl_add)
log_data_string("spamfilter_regex_error", err));
return;
}
tkl = tkl_add_spamfilter(type, target, action, m, set_by, expire_at, set_at,
tkl = tkl_add_spamfilter(type, target, banact_value_to_struct(action), m, set_by, expire_at, set_at,
tkl_duration, tkl_reason, 0);
}
} else
@@ -4458,7 +4454,7 @@ CMD_FUNC(cmd_tkl_del)
{
const char *match_string;
unsigned short target;
BanAction action;
BanActionValue action;
if (parc < 9)
{
@@ -4588,7 +4584,7 @@ CMD_FUNC(_cmd_tkl)
}
/** Configure the username/hostname TKL layer based on the BAN_TARGET_* configuration */
void ban_target_to_tkl_layer(BanTarget ban_target, BanAction action, Client *client, const char **tkl_username, const char **tkl_hostname)
void ban_target_to_tkl_layer(BanTarget ban_target, BanActionValue action, Client *client, const char **tkl_username, const char **tkl_hostname)
{
static char username[USERLEN+1];
static char hostname[HOSTLEN+8];
@@ -4649,100 +4645,125 @@ void ban_target_to_tkl_layer(BanTarget ban_target, BanAction action, Client *cli
* @param reason The ban reason.
* @param duration The ban duration in seconds.
* @note This function assumes that client is a locally connected user.
* @retval 1 if action is taken, 0 if user is exempted.
* @retval 0 user is exempt or no action needs to be taken for other reasons (eg only var setting)
* @retval 1 user is banned/shunned/killed/whatever, caller usually returns
* @retval BAN_ACT_BLOCK the user was not banned/shunned/killed but should be "blocked"
* @note Be sure to check IsDead(client) if return value is 1 and you are
* considering to continue processing.
*/
int _place_host_ban(Client *client, BanAction action, char *reason, long duration)
int _place_host_ban(Client *client, BanAction *actions, char *reason, long duration)
{
/* If this is a soft action and the user is logged in, then the ban does not apply.
* NOTE: Actually in such a case it would be better if place_host_ban() would not
* be called at all. Or at least, the caller should not take any action
* (eg: the message should be delivered, the user may connect, etc..)
* The following is more like secondary protection in case the caller forgets...
*/
if (IsSoftBanAction(action) && IsLoggedIn(client))
return 0;
BanAction *action;
int retval = 0;
switch(action)
for (action = actions; action; action = action->next)
{
case BAN_ACT_TEMPSHUN:
/* We simply mark this connection as shunned and do not add a ban record */
unreal_log(ULOG_INFO, "tkl", "TKL_ADD_TEMPSHUN", &me,
"Temporary shun added on user $target.details [reason: $shun_reason] [by: $client]",
log_data_string("shun_reason", reason),
log_data_client("target", client));
SetShunned(client);
return 1;
case BAN_ACT_GZLINE:
case BAN_ACT_GLINE:
case BAN_ACT_SOFT_GLINE:
case BAN_ACT_ZLINE:
case BAN_ACT_KLINE:
case BAN_ACT_SOFT_KLINE:
case BAN_ACT_SHUN:
case BAN_ACT_SOFT_SHUN:
/* If this is a soft action and the user is logged in, then the ban does not apply. */
if (IsSoftBanAction(action->action) && IsLoggedIn(client))
return 0;
switch(action->action)
{
char ip[128], user[USERLEN+3], mo[100], mo2[100];
const char *tkllayer[9] = {
me.name, /*0 server.name */
"+", /*1 +|- */
"?", /*2 type */
"*", /*3 user */
NULL, /*4 host */
NULL,
NULL, /*6 expire_at */
NULL, /*7 set_at */
NULL /*8 reason */
};
ban_target_to_tkl_layer(iConf.automatic_ban_target, action, client, &tkllayer[3], &tkllayer[4]);
/* For soft bans we need to prefix the % in the username */
if (IsSoftBanAction(action))
case BAN_ACT_WARN:
/* No action taken by us */
break;
case BAN_ACT_TEMPSHUN:
/* We simply mark this connection as shunned and do not add a ban record */
unreal_log(ULOG_INFO, "tkl", "TKL_ADD_TEMPSHUN", &me,
"Temporary shun added on user $target.details [reason: $shun_reason] [by: $client]",
log_data_string("shun_reason", reason),
log_data_client("target", client));
SetShunned(client);
retval = 1;
break;
case BAN_ACT_GZLINE:
case BAN_ACT_GLINE:
case BAN_ACT_SOFT_GLINE:
case BAN_ACT_ZLINE:
case BAN_ACT_KLINE:
case BAN_ACT_SOFT_KLINE:
case BAN_ACT_SHUN:
case BAN_ACT_SOFT_SHUN:
{
char tmp[USERLEN+3];
snprintf(tmp, sizeof(tmp), "%%%s", tkllayer[3]);
strlcpy(user, tmp, sizeof(user));
tkllayer[3] = user;
char ip[128], user[USERLEN+3], mo[100], mo2[100];
const char *tkllayer[9] = {
me.name, /*0 server.name */
"+", /*1 +|- */
"?", /*2 type */
"*", /*3 user */
NULL, /*4 host */
NULL,
NULL, /*6 expire_at */
NULL, /*7 set_at */
NULL /*8 reason */
};
ban_target_to_tkl_layer(iConf.automatic_ban_target, action->action, client, &tkllayer[3], &tkllayer[4]);
/* For soft bans we need to prefix the % in the username */
if (IsSoftBanAction(action->action))
{
char tmp[USERLEN+3];
snprintf(tmp, sizeof(tmp), "%%%s", tkllayer[3]);
strlcpy(user, tmp, sizeof(user));
tkllayer[3] = user;
}
if ((action->action == BAN_ACT_KLINE) || (action->action == BAN_ACT_SOFT_KLINE))
tkllayer[2] = "k";
else if (action->action == BAN_ACT_ZLINE)
tkllayer[2] = "z";
else if (action->action == BAN_ACT_GZLINE)
tkllayer[2] = "Z";
else if ((action->action == BAN_ACT_GLINE) || (action->action == BAN_ACT_SOFT_GLINE))
tkllayer[2] = "G";
else if ((action->action == BAN_ACT_SHUN) || (action->action == BAN_ACT_SOFT_SHUN))
tkllayer[2] = "s";
tkllayer[5] = me.name;
if (!duration)
strlcpy(mo, "0", sizeof(mo)); /* perm */
else
ircsnprintf(mo, sizeof(mo), "%lld", (long long)(duration + TStime()));
ircsnprintf(mo2, sizeof(mo2), "%lld", (long long)TStime());
tkllayer[6] = mo;
tkllayer[7] = mo2;
tkllayer[8] = reason;
cmd_tkl(&me, NULL, 9, tkllayer);
RunHookReturnInt(HOOKTYPE_PLACE_HOST_BAN, !=99, client, action->action, reason, duration);
if ((action->action == BAN_ACT_SHUN) || (action->action == BAN_ACT_SOFT_SHUN))
{
find_shun(client);
retval = 1;
break;
} /* else.. */
retval = find_tkline_match(client, 0);
break;
}
if ((action == BAN_ACT_KLINE) || (action == BAN_ACT_SOFT_KLINE))
tkllayer[2] = "k";
else if (action == BAN_ACT_ZLINE)
tkllayer[2] = "z";
else if (action == BAN_ACT_GZLINE)
tkllayer[2] = "Z";
else if ((action == BAN_ACT_GLINE) || (action == BAN_ACT_SOFT_GLINE))
tkllayer[2] = "G";
else if ((action == BAN_ACT_SHUN) || (action == BAN_ACT_SOFT_SHUN))
tkllayer[2] = "s";
tkllayer[5] = me.name;
if (!duration)
strlcpy(mo, "0", sizeof(mo)); /* perm */
else
ircsnprintf(mo, sizeof(mo), "%lld", (long long)(duration + TStime()));
ircsnprintf(mo2, sizeof(mo2), "%lld", (long long)TStime());
tkllayer[6] = mo;
tkllayer[7] = mo2;
tkllayer[8] = reason;
cmd_tkl(&me, NULL, 9, tkllayer);
RunHookReturnInt(HOOKTYPE_PLACE_HOST_BAN, !=99, client, action, reason, duration);
if ((action == BAN_ACT_SHUN) || (action == BAN_ACT_SOFT_SHUN))
{
find_shun(client);
return 1;
} /* else.. */
return find_tkline_match(client, 0);
case BAN_ACT_BLOCK:
/* We don't actively do something, but we do indicate it is blocked */
if (retval != 1)
retval = BAN_ACT_BLOCK;
break;
case BAN_ACT_SOFT_BLOCK:
if (!IsLoggedIn(client))
{
if (retval != 1)
retval = BAN_ACT_BLOCK;
}
break;
case BAN_ACT_SOFT_KILL:
case BAN_ACT_KILL:
default:
RunHookReturnInt(HOOKTYPE_PLACE_HOST_BAN, !=99, client, action->action, reason, duration);
exit_client(client, NULL, reason);
retval = 1;
break;
}
case BAN_ACT_SOFT_KILL:
case BAN_ACT_KILL:
default:
RunHookReturnInt(HOOKTYPE_PLACE_HOST_BAN, !=99, client, action, reason, duration);
exit_client(client, NULL, reason);
return 1;
if (IsDead(client))
break; /* stop processing actions */
}
return 0; /* no action taken (weird) */
return retval;
}
/** This function compares two spamfilters ('one' and 'two') and will return
@@ -4901,13 +4922,13 @@ int _match_spamfilter(Client *client, const char *str_in, int target, const char
if (!(tkl->ptr.spamfilter->target & target))
continue;
if ((flags & SPAMFLAG_NOWARN) && (tkl->ptr.spamfilter->action == BAN_ACT_WARN))
if ((flags & SPAMFLAG_NOWARN) && only_actions_of_type(tkl->ptr.spamfilter->action, BAN_ACT_WARN))
continue;
/* If the action is 'soft' (for non-logged in users only) then
* don't bother running the spamfilter if the user is logged in.
*/
if (IsSoftBanAction(tkl->ptr.spamfilter->action) && IsLoggedIn(client))
if (IsLoggedIn(client) && only_soft_actions(tkl->ptr.spamfilter->action))
continue;
#ifdef SPAMFILTER_DETECTSLOW
@@ -4950,6 +4971,8 @@ int _match_spamfilter(Client *client, const char *str_in, int target, const char
if (!winner_tkl && destination && target_is_spamexcept(destination))
return 0; /* No problem! */
// TODO: if (only_actions_of_type(tkl->ptr.spamfilter->action, BAN_ACT_SET)) then don't show the warning unless debugging or something :)
unreal_log(ULOG_INFO, "tkl", "SPAMFILTER_MATCH", client,
"[Spamfilter] $client.details matches filter '$tkl': [cmd: $command$_space$destination: '$str'] [reason: $tkl.reason] [action: $tkl.ban_action]",
log_data_tkl("tkl", tkl),
@@ -4985,7 +5008,7 @@ int _match_spamfilter(Client *client, const char *str_in, int target, const char
/* Spamfilter matched, take action: */
reason = unreal_decodespace(tkl->ptr.spamfilter->tkl_reason);
if ((tkl->ptr.spamfilter->action == BAN_ACT_BLOCK) || (tkl->ptr.spamfilter->action == BAN_ACT_SOFT_BLOCK))
if ((tkl->ptr.spamfilter->action->action == BAN_ACT_BLOCK) || (tkl->ptr.spamfilter->action->action == BAN_ACT_SOFT_BLOCK))
{
switch(target)
{
@@ -5038,13 +5061,13 @@ int _match_spamfilter(Client *client, const char *str_in, int target, const char
}
return 1;
} else
if ((tkl->ptr.spamfilter->action == BAN_ACT_WARN) || (tkl->ptr.spamfilter->action == BAN_ACT_SOFT_WARN))
if ((tkl->ptr.spamfilter->action->action == BAN_ACT_WARN) || (tkl->ptr.spamfilter->action->action == BAN_ACT_SOFT_WARN))
{
if ((target != SPAMF_USER) && (target != SPAMF_QUIT))
sendnumeric(client, RPL_SPAMCMDFWD, cmd, reason);
return 0;
} else
if ((tkl->ptr.spamfilter->action == BAN_ACT_DCCBLOCK) || (tkl->ptr.spamfilter->action == BAN_ACT_SOFT_DCCBLOCK))
if ((tkl->ptr.spamfilter->action->action == BAN_ACT_DCCBLOCK) || (tkl->ptr.spamfilter->action->action == BAN_ACT_SOFT_DCCBLOCK))
{
if (target == SPAMF_DCC)
{
@@ -5054,7 +5077,7 @@ int _match_spamfilter(Client *client, const char *str_in, int target, const char
}
return 1;
} else
if ((tkl->ptr.spamfilter->action == BAN_ACT_VIRUSCHAN) || (tkl->ptr.spamfilter->action == BAN_ACT_SOFT_VIRUSCHAN))
if ((tkl->ptr.spamfilter->action->action == BAN_ACT_VIRUSCHAN) || (tkl->ptr.spamfilter->action->action == BAN_ACT_SOFT_VIRUSCHAN))
{
if (IsVirus(client)) /* Already tagged */
return 0;
+3 -3
View File
@@ -430,7 +430,7 @@ int write_tkline(UnrealDB *db, const char *tmpfname, TKL *tkl)
{
char *match_type = unreal_match_method_valtostr(tkl->ptr.spamfilter->match->type);
char *target = spamfilter_target_inttostring(tkl->ptr.spamfilter->target);
char action = banact_valtochar(tkl->ptr.spamfilter->action);
char action = banact_valtochar(tkl->ptr.spamfilter->action->action);
W_SAFE(unrealdb_write_str(db, match_type));
W_SAFE(unrealdb_write_str(db, tkl->ptr.spamfilter->match->str));
@@ -699,7 +699,7 @@ int read_tkldb(void)
/* Action */
R_SAFE(unrealdb_read_char(db, &c));
tkl->ptr.spamfilter->action = banact_chartoval(c);
tkl->ptr.spamfilter->action = banact_value_to_struct(banact_chartoval(c));
if (!tkl->ptr.spamfilter->action)
{
config_warn("[tkldb] Spamfilter '%s' without valid action (%c) -- spamfilter entry not added",
@@ -712,7 +712,7 @@ int read_tkldb(void)
tkl->ptr.spamfilter->tkl_duration = v;
if (find_tkl_spamfilter(tkl->type, tkl->ptr.spamfilter->match->str,
tkl->ptr.spamfilter->action,
tkl->ptr.spamfilter->action->action,
tkl->ptr.spamfilter->target))
{
do_not_add = 1;