1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-10 21:23:12 +02:00

Add spamreport::type dronebl, actually reports to unrealircd.org atm for testing

This commit is contained in:
Bram Matthys
2023-07-08 18:13:14 +02:00
parent 84786cc005
commit bee2853ded
+104 -27
View File
@@ -13,14 +13,20 @@ ModuleHeader MOD_HEADER
"unrealircd-6",
};
/* Structs */
/* Enums and structs */
typedef enum SpamreportType {
SPAMREPORT_TYPE_SIMPLE = 1,
SPAMREPORT_TYPE_DRONEBL = 2,
} SpamReportType;
typedef struct Spamreport Spamreport;
struct Spamreport {
Spamreport *prev, *next;
char *name; /**< Name of the block, spamreport <this> { } */
char *url; /**< URL to use */
int type;
SpamReportType type;
HttpMethod http_method;
NameValuePrioList *parameters;
SecurityGroup *except;
int rate_limit_num;
int rate_limit_per;
@@ -66,9 +72,10 @@ MOD_UNLOAD()
/** Test a spamreport { } block in the configuration file */
int tkl_config_test_spamreport(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
{
ConfigEntry *cep;
ConfigEntry *cep, *cepp;
int errors = 0;
char has_url=0, has_type=0, has_http_method=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;
/* We are only interested in spamreport { } blocks */
if ((type != CONFIG_MAIN) || strcmp(ce->name, "spamreport"))
@@ -86,6 +93,22 @@ int tkl_config_test_spamreport(ConfigFile *cf, ConfigEntry *ce, int type, int *e
if (!strcmp(cep->name, "except"))
{
test_match_block(cf, cep, &errors);
} else
if (!strcmp(cep->name, "parameters"))
{
for (cepp = cep->items; cepp; cepp = cepp->next)
{
if (!cepp->value)
{
config_error_empty(cepp->file->filename, cepp->line_number,
"spamreport::parameters", cepp->name);
errors++;
}
else if (!strcmp(cepp->name, "rpckey"))
has_dronebl_rpckey = 1;
else if (!strcmp(cepp->name, "type"))
has_dronebl_type = 1;
}
}
else if (!cep->value)
{
@@ -113,7 +136,11 @@ int tkl_config_test_spamreport(ConfigFile *cf, ConfigEntry *ce, int type, int *e
continue;
}
has_type = 1;
if (strcmp(cep->value, "simple"))
if (!strcmp(cep->value, "simple"))
;
else if (!strcmp(cep->value, "dronebl"))
has_type_dronebl = 1;
else
{
config_error("%s:%i: spamreport::type: only 'simple' is supported at the moment",
cep->file->filename, cep->line_number);
@@ -151,22 +178,33 @@ int tkl_config_test_spamreport(ConfigFile *cf, ConfigEntry *ce, int type, int *e
}
}
if (!has_url)
{
config_error_missing(ce->file->filename, ce->line_number, "spamreport::url");
errors++;
}
if (!has_type)
{
config_error_missing(ce->file->filename, ce->line_number, "spamreport::type");
errors++;
}
if (!has_http_method)
if (has_type_dronebl)
{
config_error_missing(ce->file->filename, ce->line_number, "spamreport::http-method");
errors++;
if (!has_dronebl_rpckey || !has_dronebl_type)
{
config_error("%s:%i: spamreport: type dronebl used, missing spamreport::parameters: rpckey and/or type",
ce->file->filename, ce->line_number);
errors++;
}
} else
{
if (!has_url)
{
config_error_missing(ce->file->filename, ce->line_number, "spamreport::url");
errors++;
}
if (!has_http_method)
{
config_error_missing(ce->file->filename, ce->line_number, "spamreport::http-method");
errors++;
}
}
*errs = errors;
@@ -194,7 +232,12 @@ int tkl_config_run_spamreport(ConfigFile *cf, ConfigEntry *ce, int type)
}
else if (!strcmp(cep->name, "type"))
{
// TODO
if (!strcmp(cep->value, "simple"))
s->type = SPAMREPORT_TYPE_SIMPLE;
else if (!strcmp(cep->value, "dronebl"))
s->type = SPAMREPORT_TYPE_DRONEBL;
else
abort();
}
else if (!strcmp(cep->name, "http-method"))
{
@@ -207,12 +250,20 @@ int tkl_config_run_spamreport(ConfigFile *cf, ConfigEntry *ce, int type)
{
// TODO
}
else if (!strcmp(cep->name, "parameters"))
{
for (cepp = cep->items; cepp; cepp = cepp->next)
add_nvplist(&s->parameters, 0, cepp->name, cepp->value);
}
else if (!strcmp(cep->name, "except"))
{
conf_match_block(cf, cep, &s->except);
}
}
if (s->type == SPAMREPORT_TYPE_DRONEBL)
s->http_method = HTTP_METHOD_POST;
AddListItem(s, spamreports);
return 1;
}
@@ -222,6 +273,8 @@ void free_spamreport_block(Spamreport *s)
DelListItem(s, spamreports);
safe_free(s->name);
safe_free(s->url);
safe_free_nvplist(s->parameters);
free_security_group(s->except);
safe_free(s);
}
@@ -249,8 +302,9 @@ Spamreport *find_spamreport_block(const char *name)
int report_spam(Client *client, const char *ip, NameValuePrioList *details, Spamreport *s)
{
NameValuePrioList *list;
char url[512];
char urlbuf[512];
char bodybuf[512];
char *url = NULL;
char *body = NULL;
if (s == NULL)
@@ -265,18 +319,41 @@ int report_spam(Client *client, const char *ip, NameValuePrioList *details, Spam
return 0;
// NOTE: 'except' is bypassed for manual SPAMREPORT with an ip and no client.
list = duplicate_nvplist(details);
add_nvplist(&list, -1, "ip", ip);
buildvarstring_nvp(s->url, url, sizeof(url), list);
safe_free_nvplist(list);
if (s->http_method == HTTP_METHOD_POST)
if (s->type == SPAMREPORT_TYPE_SIMPLE)
{
body = strchr(url, '?');
if (body)
*body++ = '\0';
}
NameValuePrioList *list = NULL;
list = duplicate_nvplist(details);
add_nvplist(&list, -1, "ip", ip);
buildvarstring_nvp(s->url, urlbuf, sizeof(urlbuf), list, BUILDVARSTRING_URLENCODE);
url = urlbuf;
safe_free_nvplist(list);
if (s->http_method == HTTP_METHOD_POST)
{
body = strchr(url, '?');
if (body)
*body++ = '\0';
}
} else
if (s->type == SPAMREPORT_TYPE_DRONEBL)
{
NameValuePrioList *list = NULL;
NameValuePrioList *list2 = NULL;
url = "https://www.unrealircd.org/spamreport.php";
list = duplicate_nvplist(details);
duplicate_nvplist_append(s->parameters, &list);
add_nvplist(&list, -1, "ip", ip);
buildvarstring_nvp("rpckey=$rpckey&action=add&ip=$ip&type=$type", bodybuf, sizeof(bodybuf), list, BUILDVARSTRING_URLENCODE);
body = bodybuf;
safe_free_nvplist(list); // frees all the duplicated lists
} else
abort();
#ifdef DEBUGMODE
unreal_log(ULOG_DEBUG, "spamreport", "SPAMREPORT_SEND_REQUEST", NULL,
"Calling url '$url' with body '$body'",
log_data_string("url", url),
log_data_string("body", (body ? body : "")));
#endif
url_start_async(url, s->http_method, body, 0, 0, download_complete_dontcare, NULL, url, 3);
return 1;
}