mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-09 21:33:12 +02:00
RPC: remove tkl, split this up.. starting with server_ban.
Currently available: * server_ban.list * server_ban.get with params: name="*@1.2.3.4", type="kline" This also adds server_ban_parse_mask() which is now used by both GLINE/etc and the RPC API to parse the same way and convey the same error messages.
This commit is contained in:
@@ -30,4 +30,4 @@ loadmodule "rpc/rpc";
|
||||
/* Now the actual RPC call handlers */
|
||||
loadmodule "rpc/user";
|
||||
loadmodule "rpc/channel";
|
||||
loadmodule "rpc/tkl";
|
||||
loadmodule "rpc/server_ban";
|
||||
|
||||
@@ -745,6 +745,7 @@ extern MODVAR int (*register_user)(Client *client);
|
||||
extern MODVAR int (*tkl_hash)(unsigned int c);
|
||||
extern MODVAR char (*tkl_typetochar)(int type);
|
||||
extern MODVAR int (*tkl_chartotype)(char c);
|
||||
extern MODVAR char (*tkl_configtypetochar)(const char *name);
|
||||
extern MODVAR const char *(*tkl_type_string)(TKL *tk);
|
||||
extern MODVAR const char *(*tkl_type_config_string)(TKL *tk);
|
||||
extern MODVAR TKL *(*tkl_add_serverban)(int type, const char *usermask, const char *hostmask, const char *reason, const char *setby,
|
||||
@@ -817,6 +818,7 @@ extern MODVAR void (*broadcast_md_globalvar_cmd)(Client *except, Client *sender,
|
||||
extern MODVAR int (*tkl_ip_hash)(const char *ip);
|
||||
extern MODVAR int (*tkl_ip_hash_type)(int type);
|
||||
extern MODVAR int (*find_tkl_exception)(int ban_type, Client *cptr);
|
||||
extern MODVAR 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);
|
||||
extern MODVAR int (*del_silence)(Client *client, const char *mask);
|
||||
extern MODVAR int (*add_silence)(Client *client, const char *mask, int senderr);
|
||||
extern MODVAR int (*is_silenced)(Client *client, Client *acptr);
|
||||
|
||||
@@ -2464,6 +2464,7 @@ enum EfunctionType {
|
||||
EFUNC_PARSE_MESSAGE_TAGS,
|
||||
EFUNC_MTAGS_TO_STRING,
|
||||
EFUNC_TKL_CHARTOTYPE,
|
||||
EFUNC_TKL_CONFIGTYPETOCHAR,
|
||||
EFUNC_TKL_TYPE_STRING,
|
||||
EFUNC_TKL_TYPE_CONFIG_STRING,
|
||||
EFUNC_CAN_SEND_TO_CHANNEL,
|
||||
@@ -2483,6 +2484,7 @@ enum EfunctionType {
|
||||
EFUNC_FIND_TKL_NAMEBAN,
|
||||
EFUNC_FIND_TKL_SPAMFILTER,
|
||||
EFUNC_FIND_TKL_EXCEPTION,
|
||||
EFUNC_SERVER_BAN_PARSE_MASK,
|
||||
EFUNC_ADD_SILENCE,
|
||||
EFUNC_DEL_SILENCE,
|
||||
EFUNC_IS_SILENCED,
|
||||
|
||||
@@ -46,6 +46,7 @@ int (*register_user)(Client *client);
|
||||
int (*tkl_hash)(unsigned int c);
|
||||
char (*tkl_typetochar)(int type);
|
||||
int (*tkl_chartotype)(char c);
|
||||
char (*tkl_configtypetochar)(const char *name);
|
||||
const char *(*tkl_type_string)(TKL *tk);
|
||||
const char *(*tkl_type_config_string)(TKL *tk);
|
||||
char *(*tkl_uhost)(TKL *tkl, char *buf, size_t buflen, int options);
|
||||
@@ -119,6 +120,7 @@ TKL *(*find_tkl_banexception)(int type, const char *usermask, const char *hostma
|
||||
TKL *(*find_tkl_nameban)(int type, const char *name, int hold);
|
||||
TKL *(*find_tkl_spamfilter)(int type, const char *match_string, unsigned short 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 (*is_silenced)(Client *client, Client *acptr);
|
||||
int (*del_silence)(Client *client, const char *mask);
|
||||
int (*add_silence)(Client *client, const char *mask, int senderr);
|
||||
@@ -381,6 +383,7 @@ void efunctions_init(void)
|
||||
efunc_init_function(EFUNC_PARSE_MESSAGE_TAGS, parse_message_tags, &parse_message_tags_default_handler);
|
||||
efunc_init_function(EFUNC_MTAGS_TO_STRING, mtags_to_string, &mtags_to_string_default_handler);
|
||||
efunc_init_function(EFUNC_TKL_CHARTOTYPE, tkl_chartotype, NULL);
|
||||
efunc_init_function(EFUNC_TKL_CONFIGTYPETOCHAR, tkl_configtypetochar, NULL);
|
||||
efunc_init_function(EFUNC_TKL_TYPE_STRING, tkl_type_string, NULL);
|
||||
efunc_init_function(EFUNC_TKL_TYPE_CONFIG_STRING, tkl_type_config_string, NULL);
|
||||
efunc_init_function(EFUNC_CAN_SEND_TO_CHANNEL, can_send_to_channel, NULL);
|
||||
@@ -398,6 +401,7 @@ void efunctions_init(void)
|
||||
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);
|
||||
efunc_init_function(EFUNC_SERVER_BAN_PARSE_MASK, server_ban_parse_mask, NULL);
|
||||
efunc_init_function(EFUNC_ADD_SILENCE, add_silence, add_silence_default_handler);
|
||||
efunc_init_function(EFUNC_DEL_SILENCE, del_silence, del_silence_default_handler);
|
||||
efunc_init_function(EFUNC_IS_SILENCED, is_silenced, is_silenced_default_handler);
|
||||
|
||||
@@ -32,7 +32,7 @@ INCLUDES = ../../include/channel.h \
|
||||
../../include/version.h ../../include/whowas.h
|
||||
|
||||
R_MODULES= \
|
||||
rpc.so user.so channel.so tkl.so
|
||||
rpc.so user.so channel.so server_ban.so
|
||||
|
||||
MODULES=$(R_MODULES)
|
||||
MODULEFLAGS=@MODULEFLAGS@
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/* server_ban.* RPC calls
|
||||
* (C) Copyright 2022-.. Bram Matthys (Syzop) and the UnrealIRCd team
|
||||
* License: GPLv2 or later
|
||||
*/
|
||||
|
||||
#include "unrealircd.h"
|
||||
|
||||
ModuleHeader MOD_HEADER
|
||||
= {
|
||||
"rpc/server_ban",
|
||||
"1.0.0",
|
||||
"server_ban.* RPC calls",
|
||||
"UnrealIRCd Team",
|
||||
"unrealircd-6",
|
||||
};
|
||||
|
||||
/* Forward declarations */
|
||||
RPC_CALL_FUNC(rpc_server_ban_list);
|
||||
RPC_CALL_FUNC(rpc_server_ban_get);
|
||||
|
||||
MOD_INIT()
|
||||
{
|
||||
RPCHandlerInfo r;
|
||||
|
||||
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||
|
||||
memset(&r, 0, sizeof(r));
|
||||
r.method = "server_ban.list";
|
||||
r.call = rpc_server_ban_list;
|
||||
if (!RPCHandlerAdd(modinfo->handle, &r))
|
||||
{
|
||||
config_error("[rpc/server_ban] Could not register RPC handler");
|
||||
return MOD_FAILED;
|
||||
}
|
||||
r.method = "server_ban.get";
|
||||
r.call = rpc_server_ban_get;
|
||||
if (!RPCHandlerAdd(modinfo->handle, &r))
|
||||
{
|
||||
config_error("[rpc/server_ban] Could not register RPC handler");
|
||||
return MOD_FAILED;
|
||||
}
|
||||
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
MOD_LOAD()
|
||||
{
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
MOD_UNLOAD()
|
||||
{
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
#define RPC_USER_LIST_EXPAND_NONE 0
|
||||
#define RPC_USER_LIST_EXPAND_SELECT 1
|
||||
#define RPC_USER_LIST_EXPAND_ALL 2
|
||||
|
||||
// TODO: right now returns everything for everyone,
|
||||
// give the option to return a list of names only or
|
||||
// certain options (hence the placeholder #define's above)
|
||||
RPC_CALL_FUNC(rpc_server_ban_list)
|
||||
{
|
||||
json_t *result, *list, *item;
|
||||
int index, index2;
|
||||
TKL *tkl;
|
||||
|
||||
result = json_object();
|
||||
list = json_array();
|
||||
json_object_set_new(result, "list", list);
|
||||
|
||||
for (index = 0; index < TKLIPHASHLEN1; index++)
|
||||
{
|
||||
for (index2 = 0; index2 < TKLIPHASHLEN2; index2++)
|
||||
{
|
||||
for (tkl = tklines_ip_hash[index][index2]; tkl; tkl = tkl->next)
|
||||
{
|
||||
if (TKLIsServerBan(tkl))
|
||||
{
|
||||
item = json_object();
|
||||
json_expand_tkl(item, NULL, tkl, 1);
|
||||
json_array_append_new(list, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (index = 0; index < TKLISTLEN; index++)
|
||||
{
|
||||
for (tkl = tklines[index]; tkl; tkl = tkl->next)
|
||||
{
|
||||
if (TKLIsServerBan(tkl))
|
||||
{
|
||||
item = json_object();
|
||||
json_expand_tkl(item, NULL, tkl, 1);
|
||||
json_array_append_new(list, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rpc_response(client, request, result);
|
||||
json_decref(result);
|
||||
}
|
||||
|
||||
RPC_CALL_FUNC(rpc_server_ban_get)
|
||||
{
|
||||
json_t *result, *list, *item;
|
||||
const char *name, *type_name;
|
||||
const char *error;
|
||||
char *usermask, *hostmask;
|
||||
int soft;
|
||||
TKL *tkl;
|
||||
char tkl_type_char;
|
||||
int tkl_type_int;
|
||||
|
||||
name = json_object_get_string(params, "name");
|
||||
if (!name)
|
||||
{
|
||||
rpc_error(client, NULL, JSON_RPC_ERROR_INVALID_PARAMS, "Missing parameter: 'name'");
|
||||
return;
|
||||
}
|
||||
|
||||
type_name = json_object_get_string(params, "type");
|
||||
if (!type_name)
|
||||
{
|
||||
rpc_error(client, NULL, JSON_RPC_ERROR_INVALID_PARAMS, "Missing parameter: 'type'");
|
||||
return;
|
||||
}
|
||||
|
||||
tkl_type_char = tkl_configtypetochar(type_name);
|
||||
if (!tkl_type_char)
|
||||
{
|
||||
rpc_error_fmt(client, NULL, JSON_RPC_ERROR_INVALID_PARAMS, "Invalid type: '%s'", type_name);
|
||||
return;
|
||||
}
|
||||
tkl_type_int = tkl_chartotype(tkl_type_char);
|
||||
|
||||
if (!server_ban_parse_mask(client, 0, tkl_type_int, name, &usermask, &hostmask, &soft, &error))
|
||||
{
|
||||
rpc_error_fmt(client, NULL, JSON_RPC_ERROR_INVALID_PARAMS, "Error: %s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(tkl = find_tkl_serverban(tkl_type_int, usermask, hostmask, soft)))
|
||||
{
|
||||
rpc_error(client, NULL, JSON_RPC_ERROR_NOT_FOUND, "Ban not found");
|
||||
return;
|
||||
}
|
||||
|
||||
result = json_object();
|
||||
json_expand_tkl(result, "tkl", tkl, 1);
|
||||
rpc_response(client, request, result);
|
||||
json_decref(result);
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
/* tkl.* RPC calls
|
||||
* (C) Copyright 2022-.. Bram Matthys (Syzop) and the UnrealIRCd team
|
||||
* License: GPLv2 or later
|
||||
*/
|
||||
|
||||
#include "unrealircd.h"
|
||||
|
||||
ModuleHeader MOD_HEADER
|
||||
= {
|
||||
"rpc/tkl",
|
||||
"1.0.0",
|
||||
"tkl.* RPC calls",
|
||||
"UnrealIRCd Team",
|
||||
"unrealircd-6",
|
||||
};
|
||||
|
||||
/* Forward declarations */
|
||||
RPC_CALL_FUNC(rpc_tkl_list);
|
||||
|
||||
MOD_INIT()
|
||||
{
|
||||
RPCHandlerInfo r;
|
||||
|
||||
MARK_AS_OFFICIAL_MODULE(modinfo);
|
||||
|
||||
memset(&r, 0, sizeof(r));
|
||||
r.method = "tkl.list";
|
||||
r.call = rpc_tkl_list;
|
||||
if (!RPCHandlerAdd(modinfo->handle, &r))
|
||||
{
|
||||
config_error("[rpc/tkl] Could not register RPC handler");
|
||||
return MOD_FAILED;
|
||||
}
|
||||
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
MOD_LOAD()
|
||||
{
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
MOD_UNLOAD()
|
||||
{
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
#define RPC_USER_LIST_EXPAND_NONE 0
|
||||
#define RPC_USER_LIST_EXPAND_SELECT 1
|
||||
#define RPC_USER_LIST_EXPAND_ALL 2
|
||||
|
||||
// TODO: right now returns everything for everyone,
|
||||
// give the option to return a list of names only or
|
||||
// certain options (hence the placeholder #define's above)
|
||||
RPC_CALL_FUNC(rpc_tkl_list)
|
||||
{
|
||||
json_t *result, *list, *item;
|
||||
int index, index2;
|
||||
TKL *tkl;
|
||||
|
||||
result = json_object();
|
||||
list = json_array();
|
||||
json_object_set_new(result, "list", list);
|
||||
|
||||
for (index = 0; index < TKLIPHASHLEN1; index++)
|
||||
{
|
||||
for (index2 = 0; index2 < TKLIPHASHLEN2; index2++)
|
||||
{
|
||||
for (tkl = tklines_ip_hash[index][index2]; tkl; tkl = tkl->next)
|
||||
{
|
||||
item = json_object();
|
||||
json_expand_tkl(item, NULL, tkl, 1);
|
||||
json_array_append_new(list, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (index = 0; index < TKLISTLEN; index++)
|
||||
{
|
||||
for (tkl = tklines[index]; tkl; tkl = tkl->next)
|
||||
{
|
||||
item = json_object();
|
||||
json_expand_tkl(item, NULL, tkl, 1);
|
||||
json_array_append_new(list, item);
|
||||
}
|
||||
}
|
||||
|
||||
rpc_response(client, request, result);
|
||||
json_decref(result);
|
||||
}
|
||||
+189
-129
@@ -55,6 +55,7 @@ void cmd_tkl_line(Client *client, int parc, const char *parv[], char *type);
|
||||
int _tkl_hash(unsigned int c);
|
||||
char _tkl_typetochar(int type);
|
||||
int _tkl_chartotype(char c);
|
||||
char _tkl_configtypetochar(const char *name);
|
||||
int tkl_banexception_chartotype(char c);
|
||||
char *_tkl_type_string(TKL *tk);
|
||||
char *_tkl_type_config_string(TKL *tk);
|
||||
@@ -103,6 +104,7 @@ TKL *_find_tkl_banexception(int type, char *usermask, char *hostmask, int softba
|
||||
TKL *_find_tkl_nameban(int type, char *name, int hold);
|
||||
TKL *_find_tkl_spamfilter(int type, char *match_string, BanAction 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);
|
||||
static void add_default_exempts(void);
|
||||
int parse_extended_server_ban(const char *mask_in, Client *client, char **error, int skip_checking, char *buf1, size_t buf1len, char *buf2, size_t buf2len);
|
||||
|
||||
@@ -171,6 +173,7 @@ MOD_TEST()
|
||||
#endif
|
||||
EfunctionAdd(modinfo->handle, EFUNC_TKL_TYPETOCHAR, TO_INTFUNC(_tkl_typetochar));
|
||||
EfunctionAdd(modinfo->handle, EFUNC_TKL_CHARTOTYPE, TO_INTFUNC(_tkl_chartotype));
|
||||
EfunctionAdd(modinfo->handle, EFUNC_TKL_CONFIGTYPETOCHAR, TO_INTFUNC(_tkl_configtypetochar));
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
@@ -208,6 +211,7 @@ MOD_TEST()
|
||||
EfunctionAdd(modinfo->handle, EFUNC_FIND_TKL_EXCEPTION, _find_tkl_exception);
|
||||
EfunctionAddString(modinfo->handle, EFUNC_TKL_UHOST, _tkl_uhost);
|
||||
EfunctionAdd(modinfo->handle, EFUNC_UNREAL_MATCH_IPLIST, _unreal_match_iplist);
|
||||
EfunctionAdd(modinfo->handle, EFUNC_SERVER_BAN_PARSE_MASK, TO_INTFUNC(_server_ban_parse_mask));
|
||||
return MOD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1339,6 +1343,175 @@ fail_parse_extended_server_ban:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Parse a server ban request such as 'blah@blah.com' or '~account:EvilUser'
|
||||
* @param client Client requesting the operation (can be NULL)
|
||||
* @param add Set to 1 for add ban, 0 for remove ban
|
||||
* @param type TKL type (character), see 2nd column of tkl_types[], eg 'G' for gline.
|
||||
* @param str The input string
|
||||
* @param usermask_out Will be set to the TKL usermask
|
||||
* @param hostmask_out Will be set to the TKL hostmask
|
||||
* @param soft Will be set to 1 if it's a softban, otherwise 0
|
||||
* @param error On failure, this will contain the error string
|
||||
* @retval 1 Success: usermask_out, hostmask_out and soft are set appropriately.
|
||||
* @retval 0 Failed: error is set appropriately
|
||||
*/
|
||||
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)
|
||||
{
|
||||
static char maskbuf[512];
|
||||
char mask1buf[BUFSIZE], mask2buf[BUFSIZE];
|
||||
char *hostmask = NULL, *usermask = NULL;
|
||||
char *mask, *p;
|
||||
|
||||
/* Set defaults */
|
||||
*usermask_out = *hostmask_out = NULL;
|
||||
*soft = 0;
|
||||
|
||||
strlcpy(maskbuf, str, sizeof(maskbuf));
|
||||
mask = maskbuf;
|
||||
|
||||
if ((*mask != '~') && strchr(mask, '!'))
|
||||
{
|
||||
*error = "Cannot have '!' in masks.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*mask == ':')
|
||||
{
|
||||
*error = "Mask cannot start with a ':'.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strchr(mask, ' '))
|
||||
{
|
||||
*error = "Mask may not contain spaces";
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check if it's a softban */
|
||||
if (*mask == '%')
|
||||
{
|
||||
*soft = 1;
|
||||
if (!strchr("kGs", type))
|
||||
{
|
||||
*error = "The %% prefix (soft ban) is only available for KLINE, GLINE and SHUN. "
|
||||
"For technical reasons this will not work for (G)ZLINE.";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if it's an extended server ban */
|
||||
if (is_extended_server_ban(mask))
|
||||
{
|
||||
char *err;
|
||||
|
||||
if (!parse_extended_server_ban(mask, client, &err, 0, mask1buf, sizeof(mask1buf), mask2buf, sizeof(mask2buf)))
|
||||
{
|
||||
/* If adding, reject it */
|
||||
if (add)
|
||||
{
|
||||
*error = err;
|
||||
return 0;
|
||||
} else
|
||||
{
|
||||
/* Always allow any removal attempt... */
|
||||
char *p;
|
||||
char save;
|
||||
p = strchr(mask, ':');
|
||||
p++;
|
||||
save = *p;
|
||||
*p = '\0';
|
||||
strlcpy(mask1buf, mask, sizeof(mask1buf));
|
||||
*p = save;
|
||||
strlcpy(mask2buf, p, sizeof(mask2buf));
|
||||
/* fallthrough */
|
||||
}
|
||||
}
|
||||
if (add && ((type == 'z') || (type == 'Z')))
|
||||
{
|
||||
*error = "(G)Zlines must be placed at *@\037IPMASK\037. "
|
||||
"Extended server bans don't work here because (g)zlines are processed "
|
||||
"BEFORE dns and ident lookups are done and before reading any client data. "
|
||||
"If you want to use extended server bans then use a KLINE/GLINE instead.";
|
||||
return 0;
|
||||
}
|
||||
usermask = mask1buf; /* eg ~S: */
|
||||
hostmask = mask2buf; /* eg 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef */
|
||||
} else
|
||||
{
|
||||
/* Check if it's a hostmask and legal .. */
|
||||
p = strchr(mask, '@');
|
||||
if (p) {
|
||||
if ((p == mask) || !p[1])
|
||||
{
|
||||
*error = "No user@host specified";
|
||||
return 0;
|
||||
}
|
||||
usermask = strtok(mask, "@");
|
||||
hostmask = strtok(NULL, "");
|
||||
if (BadPtr(hostmask))
|
||||
{
|
||||
if (BadPtr(usermask))
|
||||
{
|
||||
*error = "Invalid mask";
|
||||
return 0;
|
||||
}
|
||||
hostmask = usermask;
|
||||
usermask = "*";
|
||||
}
|
||||
if (*hostmask == ':')
|
||||
{
|
||||
*error = "For technical reasons you cannot start the host with a ':', sorry";
|
||||
return 0;
|
||||
}
|
||||
if (add && ((type == 'z') || (type == 'Z')))
|
||||
{
|
||||
/* It's a (G)ZLINE, make sure the user isn't specyfing a HOST.
|
||||
* Just a warning in 3.2.3, but an error in 3.2.4.
|
||||
*/
|
||||
if (strcmp(usermask, "*"))
|
||||
{
|
||||
*error = "(G)Zlines must be placed at \037*\037@ipmask, not \037user\037@ipmask. This is "
|
||||
"because (g)zlines are processed BEFORE dns and ident lookups are done. "
|
||||
"If you want to use usermasks, use a KLINE/GLINE instead.";
|
||||
return 0;
|
||||
}
|
||||
for (p=hostmask; *p; p++)
|
||||
{
|
||||
if (isalpha(*p) && !isxdigit(*p))
|
||||
{
|
||||
*error = "ERROR: (g)zlines must be placed at *@\037IPMASK\037, not *@\037HOSTMASK\037 "
|
||||
"(so for example *@192.168.* is ok, but *@*.aol.com is not). "
|
||||
"This is because (g)zlines are processed BEFORE dns and ident lookups are done. "
|
||||
"If you want to use hostmasks instead of ipmasks, use a KLINE/GLINE instead.";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's seemingly a nick .. let's see if we can find the user */
|
||||
Client *acptr;
|
||||
if ((acptr = find_user(mask, NULL)))
|
||||
{
|
||||
BanAction 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
*error = "Nickname not found";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Success! */
|
||||
*usermask_out = usermask;
|
||||
*hostmask_out = hostmask;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Intermediate layer between user functions such as KLINE/GLINE
|
||||
* and the TKL layer (cmd_tkl).
|
||||
@@ -1348,14 +1521,12 @@ fail_parse_extended_server_ban:
|
||||
void cmd_tkl_line(Client *client, int parc, const char *parv[], char *type)
|
||||
{
|
||||
time_t secs;
|
||||
int add = 1;
|
||||
int add = 1, soft;
|
||||
time_t i;
|
||||
Client *acptr = NULL;
|
||||
char maskbuf[BUFSIZE];
|
||||
char *mask;
|
||||
const char *mask;
|
||||
const char *error;
|
||||
char mo[64], mo2[64];
|
||||
char mask1buf[BUFSIZE];
|
||||
char mask2buf[BUFSIZE];
|
||||
char *p, *usermask, *hostmask;
|
||||
const char *tkllayer[10] = {
|
||||
me.name, /*0 server.name */
|
||||
@@ -1374,8 +1545,8 @@ void cmd_tkl_line(Client *client, int parc, const char *parv[], char *type)
|
||||
if ((parc == 1) || BadPtr(parv[1]))
|
||||
return; /* shouldn't happen */
|
||||
|
||||
strlcpy(maskbuf, parv[1], sizeof(maskbuf));
|
||||
mask = maskbuf;
|
||||
mask = parv[1];
|
||||
|
||||
if (*mask == '-')
|
||||
{
|
||||
add = 0;
|
||||
@@ -1387,131 +1558,11 @@ void cmd_tkl_line(Client *client, int parc, const char *parv[], char *type)
|
||||
mask++;
|
||||
}
|
||||
|
||||
if ((*mask != '~') && strchr(mask, '!'))
|
||||
if (!server_ban_parse_mask(client, add, *type, mask, &usermask, &hostmask, &soft, &error))
|
||||
{
|
||||
sendnotice(client, "[error] Cannot have '!' in masks.");
|
||||
sendnotice(client, "[ERROR] %s", error);
|
||||
return;
|
||||
}
|
||||
if (*mask == ':')
|
||||
{
|
||||
sendnotice(client, "[error] Mask cannot start with a ':'.");
|
||||
return;
|
||||
}
|
||||
if (strchr(mask, ' '))
|
||||
return;
|
||||
|
||||
/* Check if it's a softban */
|
||||
if (*mask == '%')
|
||||
{
|
||||
if (!strchr("kGs", *type))
|
||||
{
|
||||
sendnotice(client, "The %% prefix (soft ban) is only available for KLINE, GLINE and SHUN."
|
||||
"For technical reasons this will not work for (G)ZLINE.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if it's an extended server ban */
|
||||
if (is_extended_server_ban(mask))
|
||||
{
|
||||
char *err;
|
||||
|
||||
if (!parse_extended_server_ban(mask, client, &err, 0, mask1buf, sizeof(mask1buf), mask2buf, sizeof(mask2buf)))
|
||||
{
|
||||
/* If adding, reject it */
|
||||
if (add)
|
||||
{
|
||||
sendnotice(client, "ERROR: %s", err);
|
||||
return;
|
||||
} else
|
||||
{
|
||||
/* Always allow any removal attempt... */
|
||||
char *p;
|
||||
char save;
|
||||
p = strchr(mask, ':');
|
||||
p++;
|
||||
save = *p;
|
||||
*p = '\0';
|
||||
strlcpy(mask1buf, mask, sizeof(mask1buf));
|
||||
*p = save;
|
||||
strlcpy(mask2buf, p, sizeof(mask2buf));
|
||||
/* fallthrough */
|
||||
}
|
||||
}
|
||||
if (add && ((*type == 'z') || (*type == 'Z')))
|
||||
{
|
||||
sendnotice(client, "ERROR: (g)zlines must be placed at *@\037IPMASK\037. "
|
||||
"Extended server bans don't work here because (g)zlines are processed"
|
||||
"BEFORE dns and ident lookups are done and before reading any client data. "
|
||||
"If you want to use extended server bans then use a KLINE/GLINE instead.");
|
||||
return;
|
||||
}
|
||||
usermask = mask1buf; /* eg ~S: */
|
||||
hostmask = mask2buf; /* eg 1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef */
|
||||
} else
|
||||
{
|
||||
/* Check if it's a hostmask and legal .. */
|
||||
p = strchr(mask, '@');
|
||||
if (p) {
|
||||
if ((p == mask) || !p[1])
|
||||
{
|
||||
sendnotice(client, "Error: no user@host specified");
|
||||
return;
|
||||
}
|
||||
usermask = strtok(mask, "@");
|
||||
hostmask = strtok(NULL, "");
|
||||
if (BadPtr(hostmask)) {
|
||||
if (BadPtr(usermask)) {
|
||||
return;
|
||||
}
|
||||
hostmask = usermask;
|
||||
usermask = "*";
|
||||
}
|
||||
if (*hostmask == ':')
|
||||
{
|
||||
sendnotice(client, "[error] For technical reasons you cannot start the host with a ':', sorry");
|
||||
return;
|
||||
}
|
||||
if (add && ((*type == 'z') || (*type == 'Z')))
|
||||
{
|
||||
/* It's a (G)ZLINE, make sure the user isn't specyfing a HOST.
|
||||
* Just a warning in 3.2.3, but an error in 3.2.4.
|
||||
*/
|
||||
if (strcmp(usermask, "*"))
|
||||
{
|
||||
sendnotice(client, "ERROR: (g)zlines must be placed at \037*\037@ipmask, not \037user\037@ipmask. This is "
|
||||
"because (g)zlines are processed BEFORE dns and ident lookups are done. "
|
||||
"If you want to use usermasks, use a KLINE/GLINE instead.");
|
||||
return;
|
||||
}
|
||||
for (p=hostmask; *p; p++)
|
||||
if (isalpha(*p) && !isxdigit(*p))
|
||||
{
|
||||
sendnotice(client, "ERROR: (g)zlines must be placed at *@\037IPMASK\037, not *@\037HOSTMASK\037 "
|
||||
"(so for example *@192.168.* is ok, but *@*.aol.com is not). "
|
||||
"This is because (g)zlines are processed BEFORE dns and ident lookups are done. "
|
||||
"If you want to use hostmasks instead of ipmasks, use a KLINE/GLINE instead.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* It's seemingly a nick .. let's see if we can find the user */
|
||||
if ((acptr = find_user(mask, NULL)))
|
||||
{
|
||||
BanAction 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendnumeric(client, ERR_NOSUCHNICK, mask);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (add && ban_too_broad(usermask, hostmask))
|
||||
{
|
||||
@@ -2201,6 +2252,15 @@ int _tkl_chartotype(char c)
|
||||
return 0;
|
||||
}
|
||||
|
||||
char _tkl_configtypetochar(const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i=0; tkl_types[i].config_name; i++)
|
||||
if (!strcmp(tkl_types[i].config_name, name))
|
||||
return tkl_types[i].letter;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tkl_banexception_chartotype(char c)
|
||||
{
|
||||
int i;
|
||||
|
||||
Reference in New Issue
Block a user