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 }