mirror of https://github.com/pissnet/pissircd.git
202 lines
4.6 KiB
C
202 lines
4.6 KiB
C
/*
|
|
* webredir UnrealIRCd module
|
|
* (C) Copyright 2019 i <info@servx.org> and the UnrealIRCd team
|
|
*
|
|
* This module will 301-redirect any clients issuing GET's/POST's during pre-connect stage.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 1, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include "unrealircd.h"
|
|
|
|
CMD_FUNC(webredir);
|
|
|
|
ModuleHeader MOD_HEADER
|
|
= {
|
|
"webredir",
|
|
"1.0",
|
|
"Do 301 redirect for HEAD/GET/POST/PUT commands",
|
|
"UnrealIRCd Team",
|
|
"unrealircd-6",
|
|
};
|
|
|
|
struct {
|
|
char *url;
|
|
} cfg;
|
|
|
|
static int nowebredir = 1;
|
|
|
|
static void free_config(void);
|
|
static void init_config(void);
|
|
int webredir_config_posttest(int *errs);
|
|
int webredir_config_test(ConfigFile *, ConfigEntry *, int, int *);
|
|
int webredir_config_run(ConfigFile *, ConfigEntry *, int);
|
|
|
|
MOD_TEST()
|
|
{
|
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, webredir_config_test);
|
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGPOSTTEST, 0, webredir_config_posttest);
|
|
return MOD_SUCCESS;
|
|
}
|
|
|
|
MOD_INIT()
|
|
{
|
|
MARK_AS_OFFICIAL_MODULE(modinfo);
|
|
init_config();
|
|
CommandAdd(modinfo->handle, "HEAD", webredir, MAXPARA, CMD_UNREGISTERED);
|
|
CommandAdd(modinfo->handle, "GET", webredir, MAXPARA, CMD_UNREGISTERED);
|
|
CommandAdd(modinfo->handle, "POST", webredir, MAXPARA, CMD_UNREGISTERED);
|
|
CommandAdd(modinfo->handle, "PUT", webredir, MAXPARA, CMD_UNREGISTERED);
|
|
HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, webredir_config_run);
|
|
return MOD_SUCCESS;
|
|
}
|
|
|
|
MOD_LOAD()
|
|
{
|
|
if (SHOWCONNECTINFO)
|
|
{
|
|
config_warn("I'm disabling set::options::show-connect-info for you "
|
|
"as this setting is incompatible with the webredir module.");
|
|
SHOWCONNECTINFO = 0;
|
|
}
|
|
return MOD_SUCCESS;
|
|
}
|
|
|
|
MOD_UNLOAD()
|
|
{
|
|
free_config();
|
|
return MOD_SUCCESS;
|
|
}
|
|
|
|
static void init_config(void)
|
|
{
|
|
memset(&cfg, 0, sizeof(cfg));
|
|
}
|
|
|
|
static void free_config(void)
|
|
{
|
|
safe_free(cfg.url);
|
|
|
|
memset(&cfg, 0, sizeof(cfg)); /* needed! */
|
|
}
|
|
|
|
int webredir_config_posttest(int *errs)
|
|
{
|
|
int errors = 0;
|
|
|
|
if (nowebredir)
|
|
{
|
|
config_error("set::webredir is missing!");
|
|
errors++;
|
|
}
|
|
|
|
*errs = errors;
|
|
return errors ? -1 : 1;
|
|
}
|
|
|
|
int webredir_config_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
|
|
{
|
|
int errors = 0;
|
|
int has_url = 0;
|
|
ConfigEntry *cep;
|
|
|
|
if (type != CONFIG_SET)
|
|
return 0;
|
|
|
|
/* We are only interrested in set::webredir... */
|
|
if (!ce || !ce->name || strcmp(ce->name, "webredir"))
|
|
return 0;
|
|
|
|
nowebredir = 0;
|
|
for (cep = ce->items; cep; cep = cep->next)
|
|
{
|
|
if (!cep->value)
|
|
{
|
|
config_error("%s:%i: set::webredir::%s with no value",
|
|
cep->file->filename, cep->line_number, cep->name);
|
|
errors++;
|
|
}
|
|
else if (!strcmp(cep->name, "url"))
|
|
{
|
|
if (!*cep->value || strchr(cep->value, ' '))
|
|
{
|
|
config_error("%s:%i: set::webredir::%s with empty value",
|
|
cep->file->filename, cep->line_number, cep->name);
|
|
errors++;
|
|
}
|
|
if (!strstr(cep->value, "://") || !strcmp(cep->value, "https://..."))
|
|
{
|
|
config_error("%s:%i: set::webredir::url needs to be a valid URL",
|
|
cep->file->filename, cep->line_number);
|
|
errors++;
|
|
}
|
|
if (has_url)
|
|
{
|
|
config_warn_duplicate(cep->file->filename,
|
|
cep->line_number, "set::webredir::url");
|
|
continue;
|
|
}
|
|
has_url = 1;
|
|
}
|
|
else
|
|
{
|
|
config_error("%s:%i: unknown directive set::webredir::%s",
|
|
cep->file->filename, cep->line_number, cep->name);
|
|
errors++;
|
|
}
|
|
}
|
|
|
|
if (!has_url)
|
|
{
|
|
config_error_missing(ce->file->filename, ce->line_number,
|
|
"set::webredir::url");
|
|
errors++;
|
|
}
|
|
|
|
*errs = errors;
|
|
return errors ? -1 : 1;
|
|
}
|
|
|
|
int webredir_config_run(ConfigFile *cf, ConfigEntry *ce, int type)
|
|
{
|
|
ConfigEntry *cep;
|
|
|
|
if (type != CONFIG_SET)
|
|
return 0;
|
|
|
|
/* We are only interrested in set::webredir... */
|
|
if (!ce || !ce->name || strcmp(ce->name, "webredir"))
|
|
return 0;
|
|
|
|
for (cep = ce->items; cep; cep = cep->next)
|
|
{
|
|
if (!strcmp(cep->name, "url"))
|
|
{
|
|
safe_strdup(cfg.url, cep->value);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
CMD_FUNC(webredir)
|
|
{
|
|
if (!MyConnect(client))
|
|
return;
|
|
|
|
sendto_one(client, NULL, "HTTP/1.1 301 Moved Permanently");
|
|
sendto_one(client, NULL, "Location: %s\r\n\r\n", cfg.url);
|
|
dead_socket(client, "Connection closed");
|
|
}
|