unrealircd

- supernets unrealircd source & configuration
git clone git://git.acid.vegas/unrealircd.git
Log | Files | Refs | Archive | README | LICENSE

server_ban_exception.c (8094B)

      1 /* server_ban_exception.* RPC calls
      2  * (C) Copyright 2022-.. Bram Matthys (Syzop) and the UnrealIRCd team
      3  * License: GPLv2 or later
      4  */
      5 
      6 #include "unrealircd.h"
      7 
      8 ModuleHeader MOD_HEADER
      9 = {
     10 	"rpc/server_ban_exception",
     11 	"1.0.1",
     12 	"server_ban_exception.* RPC calls",
     13 	"UnrealIRCd Team",
     14 	"unrealircd-6",
     15 };
     16 
     17 /* Forward declarations */
     18 RPC_CALL_FUNC(rpc_server_ban_exception_list);
     19 RPC_CALL_FUNC(rpc_server_ban_exception_get);
     20 RPC_CALL_FUNC(rpc_server_ban_exception_del);
     21 RPC_CALL_FUNC(rpc_server_ban_exception_add);
     22 
     23 MOD_INIT()
     24 {
     25 	RPCHandlerInfo r;
     26 
     27 	MARK_AS_OFFICIAL_MODULE(modinfo);
     28 
     29 	memset(&r, 0, sizeof(r));
     30 	r.method = "server_ban_exception.list";
     31 	r.loglevel = ULOG_DEBUG;
     32 	r.call = rpc_server_ban_exception_list;
     33 	if (!RPCHandlerAdd(modinfo->handle, &r))
     34 	{
     35 		config_error("[rpc/server_ban_exception] Could not register RPC handler");
     36 		return MOD_FAILED;
     37 	}
     38 	r.method = "server_ban_exception.get";
     39 	r.loglevel = ULOG_DEBUG;
     40 	r.call = rpc_server_ban_exception_get;
     41 	if (!RPCHandlerAdd(modinfo->handle, &r))
     42 	{
     43 		config_error("[rpc/server_ban_exception] Could not register RPC handler");
     44 		return MOD_FAILED;
     45 	}
     46 	r.method = "server_ban_exception.del";
     47 	r.call = rpc_server_ban_exception_del;
     48 	if (!RPCHandlerAdd(modinfo->handle, &r))
     49 	{
     50 		config_error("[rpc/server_ban_exception] Could not register RPC handler");
     51 		return MOD_FAILED;
     52 	}
     53 	r.method = "server_ban_exception.add";
     54 	r.call = rpc_server_ban_exception_add;
     55 	if (!RPCHandlerAdd(modinfo->handle, &r))
     56 	{
     57 		config_error("[rpc/server_ban_exception] Could not register RPC handler");
     58 		return MOD_FAILED;
     59 	}
     60 
     61 	return MOD_SUCCESS;
     62 }
     63 
     64 MOD_LOAD()
     65 {
     66 	return MOD_SUCCESS;
     67 }
     68 
     69 MOD_UNLOAD()
     70 {
     71 	return MOD_SUCCESS;
     72 }
     73 
     74 RPC_CALL_FUNC(rpc_server_ban_exception_list)
     75 {
     76 	json_t *result, *list, *item;
     77 	int index, index2;
     78 	TKL *tkl;
     79 
     80 	result = json_object();
     81 	list = json_array();
     82 	json_object_set_new(result, "list", list);
     83 
     84 	for (index = 0; index < TKLIPHASHLEN1; index++)
     85 	{
     86 		for (index2 = 0; index2 < TKLIPHASHLEN2; index2++)
     87 		{
     88 			for (tkl = tklines_ip_hash[index][index2]; tkl; tkl = tkl->next)
     89 			{
     90 				if (TKLIsBanException(tkl))
     91 				{
     92 					item = json_object();
     93 					json_expand_tkl(item, NULL, tkl, 1);
     94 					json_array_append_new(list, item);
     95 				}
     96 			}
     97 		}
     98 	}
     99 	for (index = 0; index < TKLISTLEN; index++)
    100 	{
    101 		for (tkl = tklines[index]; tkl; tkl = tkl->next)
    102 		{
    103 			if (TKLIsBanException(tkl))
    104 			{
    105 				item = json_object();
    106 				json_expand_tkl(item, NULL, tkl, 1);
    107 				json_array_append_new(list, item);
    108 			}
    109 		}
    110 	}
    111 
    112 	rpc_response(client, request, result);
    113 	json_decref(result);
    114 }
    115 
    116 /** Shared code for selecting a server ban, for .add/.del/.get */
    117 int server_ban_exception_select_criteria(Client *client, json_t *request, json_t *params, int add,
    118                                const char **name,
    119                                const char **exception_types,
    120                                char **usermask,
    121                                char **hostmask,
    122                                int *soft)
    123 {
    124 	const char *error;
    125 
    126 	*name = json_object_get_string(params, "name");
    127 	if (!*name)
    128 	{
    129 		rpc_error(client, request, JSON_RPC_ERROR_INVALID_PARAMS, "Missing parameter: 'name'");
    130 		return 0;
    131 	}
    132 
    133 	if (add)
    134 	{
    135 		*exception_types = json_object_get_string(params, "exception_types");
    136 		if (!*exception_types)
    137 		{
    138 			rpc_error(client, request, JSON_RPC_ERROR_INVALID_PARAMS, "Missing parameter: 'exception_types'");
    139 			return 0;
    140 		}
    141 	} else {
    142 		*exception_types = NULL;
    143 	}
    144 
    145 	if (!server_ban_exception_parse_mask(client, add, *exception_types, *name, usermask, hostmask, soft, &error))
    146 	{
    147 		rpc_error_fmt(client, request, JSON_RPC_ERROR_INVALID_PARAMS, "Error: %s", error);
    148 		return 0;
    149 	}
    150 
    151 	return 1;
    152 }
    153 
    154 RPC_CALL_FUNC(rpc_server_ban_exception_get)
    155 {
    156 	json_t *result, *list, *item;
    157 	const char *name, *exception_types;
    158 	char *usermask, *hostmask;
    159 	int soft;
    160 	TKL *tkl;
    161 
    162 	if (!server_ban_exception_select_criteria(client, request, params, 0,
    163 	                                &name, &exception_types,
    164 	                                &usermask, &hostmask, &soft))
    165 	{
    166 		return;
    167 	}
    168 
    169 	if (!(tkl = find_tkl_banexception(TKL_EXCEPTION|TKL_GLOBAL, usermask, hostmask, soft)) &&
    170 	    !(tkl = find_tkl_banexception(TKL_EXCEPTION, usermask, hostmask, soft)))
    171 	{
    172 		rpc_error(client, request, JSON_RPC_ERROR_NOT_FOUND, "Ban exception not found");
    173 		return;
    174 	}
    175 
    176 	result = json_object();
    177 	json_expand_tkl(result, "tkl", tkl, 1);
    178 	rpc_response(client, request, result);
    179 	json_decref(result);
    180 }
    181 
    182 RPC_CALL_FUNC(rpc_server_ban_exception_del)
    183 {
    184 	json_t *result, *list, *item;
    185 	const char *name, *exception_types;
    186 	const char *set_by;
    187 	const char *error;
    188 	char *usermask, *hostmask;
    189 	int soft;
    190 	TKL *tkl;
    191 	const char *tkllayer[11];
    192 
    193 	if (!server_ban_exception_select_criteria(client, request, params, 0,
    194 	                                &name, &exception_types,
    195 	                                &usermask, &hostmask, &soft))
    196 	{
    197 		return;
    198 	}
    199 
    200 	if (!(tkl = find_tkl_banexception(TKL_EXCEPTION|TKL_GLOBAL, usermask, hostmask, soft)) &&
    201 	    !(tkl = find_tkl_banexception(TKL_EXCEPTION, usermask, hostmask, soft)))
    202 	{
    203 		rpc_error(client, request, JSON_RPC_ERROR_NOT_FOUND, "Ban exception not found");
    204 		return;
    205 	}
    206 
    207 	OPTIONAL_PARAM_STRING("set_by", set_by);
    208 	if (!set_by)
    209 		set_by = client->name;
    210 
    211 	result = json_object();
    212 	json_expand_tkl(result, "tkl", tkl, 1);
    213 
    214 	tkllayer[1] = "-";
    215 	tkllayer[2] = "E";
    216 	tkllayer[3] = usermask;
    217 	tkllayer[4] = hostmask;
    218 	tkllayer[5] = set_by;
    219 	tkllayer[6] = "0";
    220 	tkllayer[7] = "-";
    221 	tkllayer[8] = "-";
    222 	tkllayer[9] = "-";
    223 	tkllayer[10] = NULL;
    224 	cmd_tkl(&me, NULL, 6, tkllayer);
    225 
    226 	if (!find_tkl_banexception(TKL_EXCEPTION|TKL_GLOBAL, usermask, hostmask, soft) &&
    227 	    !find_tkl_banexception(TKL_EXCEPTION, usermask, hostmask, soft))
    228 	{
    229 		rpc_response(client, request, result);
    230 	} else {
    231 		/* Actually this may not be an internal error, it could be an
    232 		 * incorrect request, such as asking to remove a config-based ban.
    233 		 */
    234 		rpc_error(client, request, JSON_RPC_ERROR_INTERNAL_ERROR, "Unable to remove item");
    235 	}
    236 	json_decref(result);
    237 }
    238 
    239 RPC_CALL_FUNC(rpc_server_ban_exception_add)
    240 {
    241 	json_t *result, *list, *item;
    242 	const char *name, *exception_types;
    243 	const char *set_by;
    244 	const char *error;
    245 	char *usermask, *hostmask;
    246 	int soft;
    247 	TKL *tkl;
    248 	const char *reason;
    249 	const char *str;
    250 	time_t tkl_expire_at;
    251 	time_t tkl_set_at = TStime();
    252 
    253 	if (!server_ban_exception_select_criteria(client, request, params, 1,
    254 	                                &name, &exception_types,
    255 	                                &usermask, &hostmask, &soft))
    256 	{
    257 		return;
    258 	}
    259 
    260 	// FIXME: where is set_by? is this missing in others as well? :p -> OPTIONAL!
    261 
    262 	REQUIRE_PARAM_STRING("reason", reason);
    263 
    264 	/* Duration / expiry time */
    265 	if ((str = json_object_get_string(params, "duration_string")))
    266 	{
    267 		tkl_expire_at = config_checkval(str, CFG_TIME);
    268 		if (tkl_expire_at > 0)
    269 			tkl_expire_at = TStime() + tkl_expire_at;
    270 	} else
    271 	if ((str = json_object_get_string(params, "expire_at")))
    272 	{
    273 		tkl_expire_at = server_time_to_unix_time(str);
    274 	} else
    275 	{
    276 		/* Never expire */
    277 		tkl_expire_at = 0;
    278 	}
    279 
    280 	OPTIONAL_PARAM_STRING("set_by", set_by);
    281 	if (!set_by)
    282 		set_by = client->name;
    283 
    284 	if ((tkl_expire_at != 0) && (tkl_expire_at < TStime()))
    285 	{
    286 		rpc_error_fmt(client, request, JSON_RPC_ERROR_INVALID_PARAMS, "Error: the specified expiry time is before current time (before now)");
    287 		return;
    288 	}
    289 
    290 	if (find_tkl_banexception(TKL_EXCEPTION|TKL_GLOBAL, usermask, hostmask, soft) ||
    291 	    find_tkl_banexception(TKL_EXCEPTION, usermask, hostmask, soft))
    292 	{
    293 		rpc_error(client, request, JSON_RPC_ERROR_ALREADY_EXISTS, "A ban exception with that mask already exists");
    294 		return;
    295 	}
    296 
    297 	tkl = tkl_add_banexception(TKL_EXCEPTION|TKL_GLOBAL, usermask, hostmask,
    298 	                           NULL, reason,
    299 	                           set_by, tkl_expire_at, tkl_set_at,
    300 	                           soft, exception_types, 0);
    301 
    302 	if (!tkl)
    303 	{
    304 		rpc_error(client, request, JSON_RPC_ERROR_INTERNAL_ERROR, "Unable to add item");
    305 		return;
    306 	}
    307 
    308 	tkl_added(client, tkl);
    309 
    310 	result = json_object();
    311 	json_expand_tkl(result, "tkl", tkl, 1);
    312 	rpc_response(client, request, result);
    313 	json_decref(result);
    314 }