1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-06-29 11:16:37 +02:00
set::central-blocklist::spamreport and ::spamreport-enabled are now GONE.
We now require a normal spamreport block, just like for other spamreport
functionality. So, if you want to enable this feature, use:
spamreport unrealircd { type central-spamreport; }

See https://www.unrealircd.org/docs/Central_spamreport for all info.

You can use CBL with central spamreport or central spamreport without CBL.
All explained at that URL.
This commit is contained in:
Bram Matthys
2023-11-25 11:36:21 +01:00
parent d08160baca
commit 4da58dde41
6 changed files with 91 additions and 104 deletions
+4
View File
@@ -927,6 +927,8 @@ extern void (*crule_free)(CRuleNode **);
extern const char *(*crule_errstring)(int errcode);
extern void (*ban_act_set_reputation)(Client *client, BanAction *action);
extern const char *(*get_central_api_key)(void);
extern int (*central_spamreport)(Client *target);
extern int (*central_spamreport_enabled)(void);
/* /Efuncs */
/* TLS functions */
@@ -982,6 +984,8 @@ extern void cancel_ident_lookup_default_handler(Client *client);
extern int spamreport_default_handler(Client *client, const char *ip, NameValuePrioList *details, const char *spamreport_block);
extern void ban_act_set_reputation_default_handler(Client *client, BanAction *action);
extern const char *get_central_api_key_default_handler(void);
extern int central_spamreport_default_handler(Client *target);
extern int central_spamreport_enabled_default_handler(void);
/* End of default handlers for efunctions */
extern MODVAR MOTDFile opermotd, svsmotd, motd, botmotd, smotd, rules;
+2
View File
@@ -2685,6 +2685,8 @@ enum EfunctionType {
EFUNC_CRULE_ERRSTRING,
EFUNC_BAN_ACT_SET_REPUTATION,
EFUNC_GET_CENTRAL_API_KEY,
EFUNC_CENTRAL_SPAMREPORT,
EFUNC_CENTRAL_SPAMREPORT_ENABLED,
};
/* Module flags */
+4
View File
@@ -172,6 +172,8 @@ void (*crule_free)(CRuleNode **);
const char *(*crule_errstring)(int errcode);
void (*ban_act_set_reputation)(Client *client, BanAction *action);
const char *(*get_central_api_key)(void);
int (*central_spamreport)(Client *target);
int (*central_spamreport_enabled)(void);
Efunction *EfunctionAddMain(Module *module, EfunctionType eftype, int (*func)(), void (*vfunc)(), void *(*pvfunc)(), char *(*stringfunc)(), const char *(*conststringfunc)())
{
@@ -489,4 +491,6 @@ void efunctions_init(void)
efunc_init_function(EFUNC_CRULE_ERRSTRING, crule_errstring, NULL, EFUNC_FLAG_EARLY);
efunc_init_function(EFUNC_BAN_ACT_SET_REPUTATION, ban_act_set_reputation, ban_act_set_reputation_default_handler, 0);
efunc_init_function(EFUNC_GET_CENTRAL_API_KEY, get_central_api_key, get_central_api_key_default_handler, 0);
efunc_init_function(EFUNC_CENTRAL_SPAMREPORT, central_spamreport, central_spamreport_default_handler, 0);
efunc_init_function(EFUNC_CENTRAL_SPAMREPORT_ENABLED, central_spamreport_enabled, central_spamreport_enabled_default_handler, 0);
}
+10
View File
@@ -1897,6 +1897,16 @@ const char *get_central_api_key_default_handler(void)
return NULL;
}
int central_spamreport_default_handler(Client *target)
{
return 0;
}
int central_spamreport_enabled_default_handler(void)
{
return 0;
}
/** my_timegm: mktime()-like function which will use GMT/UTC.
* Strangely enough there is no standard function for this.
* On some *NIX OS's timegm() may be available, sometimes only
+19 -79
View File
@@ -58,7 +58,6 @@ struct cfgstruct {
char *api_key;
int max_downloads;
int blocklist_enabled;
int spamreport_enabled;
SecurityGroup *except;
ScoreAction *actions;
};
@@ -73,6 +72,7 @@ static struct reqstruct req;
CBLTransfer *cbltransfers = NULL;
/* Forward declarations */
int _central_spamreport(Client *client);
int cbl_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs);
int cbl_config_posttest(int *errs);
int cbl_config_run(ConfigFile *cf, ConfigEntry *ce, int type);
@@ -106,7 +106,6 @@ void set_tag(Client *client, const char *tag, int value);
CMD_OVERRIDE_FUNC(cbl_override);
CMD_OVERRIDE_FUNC(cbl_override_spamreport_gather);
CMD_OVERRIDE_FUNC(cbl_override_spamreport_cmd);
static void set_default_score_action(ScoreAction *action)
{
@@ -183,6 +182,7 @@ MOD_TEST()
MARK_AS_OFFICIAL_MODULE(modinfo);
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, cbl_config_test);
HookAdd(modinfo->handle, HOOKTYPE_CONFIGPOSTTEST, 0, cbl_config_posttest);
EfunctionAdd(modinfo->handle, EFUNC_CENTRAL_SPAMREPORT, _central_spamreport);
return MOD_SUCCESS;
}
@@ -245,7 +245,7 @@ MOD_LOAD()
do_command_overrides(modinfo);
/* Enable gathering of "last 10 lines" for SPAMREPORT, only if SPAMREPORT is enabled: */
if (cfg.spamreport_enabled)
if (central_spamreport_enabled())
{
CommandOverrideAdd(modinfo->handle, "NICK", -2, cbl_override_spamreport_gather);
CommandOverrideAdd(modinfo->handle, "PRIVMSG", -2, cbl_override_spamreport_gather);
@@ -255,8 +255,6 @@ MOD_LOAD()
CommandOverrideAdd(modinfo->handle, "KNOCK", -2, cbl_override_spamreport_gather);
}
CommandOverrideAdd(modinfo->handle, "SPAMREPORT", -2, cbl_override_spamreport_cmd);
EventAdd(modinfo->handle, "centralblocklist_timeout_evt", centralblocklist_timeout_evt, NULL, 1000, 0);
EventAdd(modinfo->handle, "centralblocklist_bundle_requests", centralblocklist_bundle_requests, NULL, 1000, 0);
return MOD_SUCCESS;
@@ -340,6 +338,12 @@ int cbl_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
} else
if (!strcmp(cep->name, "spamreport") || !strcmp(cep->name, "spamreport-enabled"))
{
config_error("%s:%i: set::central-blocklist::%s: This setting is deprecated. "
"Please remove this setting, and, if you wish to use spamreport, add a "
"spamreport unrealircd { type central-spamreport; } block in your main config. "
"See https://www.unrealircd.org/docs/Central_spamreport",
cep->file->filename, cep->line_number, cep->name);
errors++;
} else
if (!strcmp(cep->name, "blocklist") || !strcmp(cep->name, "blocklist-enabled"))
{
@@ -436,10 +440,6 @@ int cbl_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
{
safe_strdup(cfg.url, cep->value);
} else
if (!strcmp(cep->name, "spamreport") || !strcmp(cep->name, "spamreport-enabled"))
{
cfg.spamreport_enabled = config_checkval(cep->value, CFG_YESNO);
} else
if (!strcmp(cep->name, "blocklist-enabled"))
{
cfg.blocklist_enabled = config_checkval(cep->value, CFG_YESNO);
@@ -770,7 +770,7 @@ int cbl_is_handshake_finished(Client *client)
void cbl_allow(Client *client)
{
if (CBL(client))
CBL(client)->allowed_in = 2;
CBL(client)->allowed_in = 1;
if (is_handshake_finished(client))
register_user(client);
@@ -952,16 +952,13 @@ void cbl_download_complete(OutgoingWebRequest *request, OutgoingWebResponse *res
void cbl_mdata_free(ModData *m)
{
CBLUser *cbl = (CBLUser *)m->ptr;
int i;
if (cbl)
{
json_decref(cbl->handshake);
if (cbl->allowed_in == 2)
{
int i;
for (i = 0; i < SPAMREPORT_NUM_REMEMBERED_CMDS; i++)
safe_free(cbl->last_cmds[i]);
}
for (i = 0; i < SPAMREPORT_NUM_REMEMBERED_CMDS; i++)
safe_free(cbl->last_cmds[i]);
safe_free(cbl);
m->ptr = NULL;
}
@@ -1056,7 +1053,7 @@ EVENT(centralblocklist_bundle_requests)
/** Remember last # commands for SPAMREPORT */
CMD_OVERRIDE_FUNC(cbl_override_spamreport_gather)
{
if (MyUser(client) && CBL(client) && (CBL(client)->allowed_in == 2))
if (MyUser(client) && CBL(client))
{
char record_cmd = 1;
@@ -1078,7 +1075,7 @@ CMD_OVERRIDE_FUNC(cbl_override_spamreport_gather)
CALL_NEXT_COMMAND_OVERRIDE();
}
void cbl_spamreport(Client *from, Client *client)
int _central_spamreport(Client *client)
{
json_t *j, *requests, *data, *cmds, *item;
OutgoingWebRequest *w;
@@ -1090,7 +1087,7 @@ void cbl_spamreport(Client *from, Client *client)
int cnt = 0;
if (!MyUser(client) || !CBL(client))
return; /* Only possible if hot-loading */
return 0; /* Only possible if hot-loading */
num = downloads_in_progress();
if (num > cfg.max_downloads)
@@ -1098,7 +1095,7 @@ void cbl_spamreport(Client *from, Client *client)
unreal_log(ULOG_WARNING, "central-blocklist", "CENTRAL_BLOCKLIST_TOO_MANY_CONCURRENT_REQUESTS", NULL,
"Already $num_requests HTTP(S) requests in progress.",
log_data_integer("num_requests", num));
return;
return 0;
}
j = json_object();
@@ -1139,7 +1136,7 @@ void cbl_spamreport(Client *from, Client *client)
unreal_log(ULOG_WARNING, "central-blocklist", "CENTRAL_BLOCKLIST_BUG_SERIALIZE", client,
"Unable to serialize JSON request. Weird.");
json_decref(j);
return;
return 0;
}
json_decref(j);
@@ -1154,62 +1151,5 @@ void cbl_spamreport(Client *from, Client *client)
w->max_redirects = 1;
w->callback = download_complete_dontcare;
url_start_async(w);
}
CMD_OVERRIDE_FUNC(cbl_override_spamreport_cmd)
{
if (ValidatePermissionsForPath("server-ban:spamreport",client,NULL,NULL,NULL) &&
(parc > 1) &&
!((parc > 2) && strcasecmp(parv[2], "unrealircd"))
)
{
Client *target = find_user(parv[1], NULL);
if (target)
{
if (!MyUser(target))
{
/* Forward it to other server */
if (parc > 2)
{
sendto_one(target, NULL, ":%s SPAMREPORT %s %s",
client->id, parv[1], parv[2]);
} else {
sendto_one(target, NULL, ":%s SPAMREPORT %s",
client->id, parv[1]);
}
return;
} else {
/* My client. */
int n;
if (!cfg.spamreport_enabled)
{
if ((parc > 2) && !strcasecmp(parv[2], "unrealircd"))
{
sendnotice(client, "Spamreporting to UnrealIRCd is not enabled on this server. "
"To enable, add: set { central-blocklist { spamreport yes; } }");
return;
}
CALL_NEXT_COMMAND_OVERRIDE();
}
/* Report to UnrealIRCd first... */
sendnotice(client, "Sending spam report to UnrealIRCd...");
cbl_spamreport(client, target);
if ((parc > 2) && !strcasecmp(parv[2], "unrealircd"))
{
sendnotice(client, "Sending spam report to %d target(s)", 1);
return; /* We are done */
}
/* There may be more spamreport blocks: */
n = spamreport(target, target->ip, NULL, NULL);
if (n < 0)
n = 0;
sendnotice(client, "Sending spam report to %d target(s)", n + 1); /* +1 for unrealircd :D */
return;
}
}
}
CALL_NEXT_COMMAND_OVERRIDE();
return 1;
}
+52 -25
View File
@@ -20,14 +20,15 @@ ModuleHeader MOD_HEADER
typedef enum SpamreportType {
SPAMREPORT_TYPE_SIMPLE = 1,
SPAMREPORT_TYPE_DRONEBL = 2,
} SpamReportType;
SPAMREPORT_TYPE_CENTRAL_SPAMREPORT = 3,
} SpamreportType;
typedef struct Spamreport Spamreport;
struct Spamreport {
Spamreport *prev, *next;
char *name; /**< Name of the block, spamreport <this> { } */
char *url; /**< URL to use */
SpamReportType type;
SpamreportType type;
HttpMethod http_method;
NameValuePrioList *parameters;
SecurityGroup *except;
@@ -51,7 +52,9 @@ int tkl_config_run_spamreport(ConfigFile *, ConfigEntry *, int);
Spamreport *find_spamreport_block(const char *name);
void free_spamreport_blocks(void);
int _spamreport(Client *client, const char *ip, NameValuePrioList *details, const char *spamreport_block);
int _central_spamreport_enabled(void);
void spamreportcounters_free_all(ModData *m);
SpamreportType parse_spamreport_type(const char *s);
/* Variables */
Spamreport *spamreports = NULL;
@@ -61,6 +64,7 @@ MOD_TEST()
{
MARK_AS_OFFICIAL_MODULE(modinfo);
EfunctionAdd(modinfo->handle, EFUNC_SPAMREPORT, _spamreport);
EfunctionAdd(modinfo->handle, EFUNC_CENTRAL_SPAMREPORT_ENABLED, _central_spamreport_enabled);
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, tkl_config_test_spamreport);
return MOD_SUCCESS;
}
@@ -92,7 +96,7 @@ int tkl_config_test_spamreport(ConfigFile *cf, ConfigEntry *ce, int type, int *e
ConfigEntry *cep, *cepp;
int errors = 0;
char has_url=0, has_type=0, has_type_dronebl=0, has_http_method=0;
char has_dronebl_type=0, has_dronebl_rpckey=0;
char has_dronebl_type, has_dronebl_rpckey=0;
/* We are only interested in spamreport { } blocks */
if ((type != CONFIG_MAIN) || strcmp(ce->name, "spamreport"))
@@ -103,12 +107,6 @@ int tkl_config_test_spamreport(ConfigFile *cf, ConfigEntry *ce, int type, int *e
config_error("%s:%i: spamreport block has no name, should be like: spamfilter <name> { }",
ce->file->filename, ce->line_number);
errors++;
} else
if (!strcasecmp(ce->value, "unrealircd"))
{
config_error("%s:%i: spamreport block cannot be named 'unrealircd', is a reserved name.",
ce->file->filename, ce->line_number);
errors++;
}
for (cep = ce->items; cep; cep = cep->next)
@@ -160,15 +158,11 @@ int tkl_config_test_spamreport(ConfigFile *cf, ConfigEntry *ce, int type, int *e
cep->line_number, "spamreport::type");
continue;
}
has_type = 1;
if (!strcmp(cep->value, "simple"))
;
else if (!strcmp(cep->value, "dronebl"))
has_type_dronebl = 1;
else
has_type = parse_spamreport_type(cep->value);
if (!has_type)
{
config_error("%s:%i: spamreport::type: only 'simple' is supported at the moment",
cep->file->filename, cep->line_number);
config_error("%s:%i: spamreport::type: unknown type '%s', supported types are: simple, dronebl, central-spamreport.",
cep->file->filename, cep->line_number, cep->value);
errors++;
}
}
@@ -213,7 +207,11 @@ int tkl_config_test_spamreport(ConfigFile *cf, ConfigEntry *ce, int type, int *e
errors++;
}
if (has_type_dronebl)
if (has_type == SPAMREPORT_TYPE_CENTRAL_SPAMREPORT)
{
/* Nothing required */
} else
if (has_type == SPAMREPORT_TYPE_DRONEBL)
{
if (!has_dronebl_rpckey || !has_dronebl_type)
{
@@ -269,12 +267,14 @@ int tkl_config_run_spamreport(ConfigFile *cf, ConfigEntry *ce, int type)
}
else if (!strcmp(cep->name, "type"))
{
if (!strcmp(cep->value, "simple"))
s->type = SPAMREPORT_TYPE_SIMPLE;
else if (!strcmp(cep->value, "dronebl"))
s->type = SPAMREPORT_TYPE_DRONEBL;
else
abort();
s->type = parse_spamreport_type(cep->value);
if ((s->type == SPAMREPORT_TYPE_CENTRAL_SPAMREPORT) &&
!is_module_loaded("central-blocklist"))
{
config_warn("%s:%d: blacklist block with type 'central-spamreport' but the 'central-blocklist' module is not loaded.",
ce->file->filename, ce->line_number);
}
}
else if (!strcmp(cep->name, "http-method"))
{
@@ -344,6 +344,17 @@ Spamreport *find_spamreport_block(const char *name)
return NULL;
}
SpamreportType parse_spamreport_type(const char *s)
{
if (!strcmp(s, "simple"))
return SPAMREPORT_TYPE_SIMPLE;
else if (!strcmp(s, "dronebl"))
return SPAMREPORT_TYPE_DRONEBL;
else if (!strcmp(s, "central-spamreport"))
return SPAMREPORT_TYPE_CENTRAL_SPAMREPORT;
return 0;
}
/* Returns 1 if ratelimited (don't do the request), otherwise 0 */
int spamfilter_block_rate_limited(Spamreport *spamreport)
{
@@ -390,6 +401,16 @@ int spamfilter_block_rate_limited(Spamreport *spamreport)
return 0; /* All OK */
}
/** Return 1 if there is a spamreport { type central-spamreport; } block */
int _central_spamreport_enabled(void)
{
Spamreport *s;
for (s = spamreports; s; s = s->next)
if (s->type == SPAMREPORT_TYPE_CENTRAL_SPAMREPORT)
return 1;
return 0;
}
int _spamreport(Client *client, const char *ip, NameValuePrioList *details, const char *spamreport_block)
{
Spamreport *s;
@@ -421,7 +442,7 @@ int _spamreport(Client *client, const char *ip, NameValuePrioList *details, cons
s = find_spamreport_block(spamreport_block);
if (!s)
return -1; /* NOTFOUND */
return 0; /* NOTFOUND */
if (s->except && client && user_allowed_by_security_group(client, s->except))
return 0;
@@ -465,7 +486,13 @@ int _spamreport(Client *client, const char *ip, NameValuePrioList *details, cons
safe_free_nvplist(list); // frees all the duplicated lists
add_nvplist(&headers, 0, "Content-Type", "text/xml");
} else
if (s->type == SPAMREPORT_TYPE_CENTRAL_SPAMREPORT)
{
return central_spamreport(client);
} else
{
abort();
}
#ifdef DEBUGMODE
unreal_log(ULOG_DEBUG, "spamreport", "SPAMREPORT_SEND_REQUEST", NULL,