unrealircd

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

hideserver.c (10496B)

      1 /*
      2  * hideserver.c - Hide certain or all servers from /MAP & /LINKS
      3  *
      4  * Note that this module simple hides servers. It does not truly
      5  * increase security. Use as you wish.
      6  *
      7  * (C) Copyright 2003-2004 AngryWolf <angrywolf@flashmail.com>
      8  * (C) Copyright 2016 Bram Matthys <syzop@vulnscan.org>
      9  *
     10  * This program is free software; you can redistribute it and/or modify
     11  * it under the terms of the GNU General Public License as published by
     12  * the Free Software Foundation; either version 1, or (at your option)
     13  * any later version.
     14  *
     15  * This program is distributed in the hope that it will be useful,
     16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     18  * GNU General Public License for more details.
     19  *
     20  * You should have received a copy of the GNU General Public License
     21  * along with this program; if not, write to the Free Software
     22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     23  */
     24 
     25 #include "unrealircd.h"
     26 
     27 CMD_OVERRIDE_FUNC(override_map);
     28 CMD_OVERRIDE_FUNC(override_links);
     29 static int cb_test(ConfigFile *, ConfigEntry *, int, int *);
     30 static int cb_conf(ConfigFile *, ConfigEntry *, int);
     31 
     32 ConfigItem_ulines *HiddenServers;
     33 
     34 static struct
     35 {
     36 	unsigned	disable_map : 1;
     37 	unsigned	disable_links : 1;
     38 	char		*map_deny_message;
     39 	char		*links_deny_message;
     40 } Settings;
     41 
     42 static ModuleInfo	*MyModInfo;
     43 #define MyMod		MyModInfo->handle
     44 #define SAVE_MODINFO	MyModInfo = modinfo;
     45 
     46 static int lmax = 0;
     47 static int umax = 0;
     48 
     49 static int dcount(int n)
     50 {
     51    int cnt = 0;
     52 
     53    while (n != 0)
     54    {
     55 	   n = n/10;
     56 	   cnt++;
     57    }
     58 
     59    return cnt;
     60 }
     61 
     62 ModuleHeader MOD_HEADER
     63   = {
     64 	"hideserver",
     65 	"5.0",
     66 	"Hide servers from /MAP & /LINKS",
     67 	"UnrealIRCd Team",
     68 	"unrealircd-6",
     69     };
     70 
     71 static void InitConf()
     72 {
     73 	memset(&Settings, 0, sizeof Settings);
     74 }
     75 
     76 static void FreeConf()
     77 {
     78 	ConfigItem_ulines	*h, *next;
     79 
     80 	safe_free(Settings.map_deny_message);
     81 	safe_free(Settings.links_deny_message);
     82 
     83 	for (h = HiddenServers; h; h = next)
     84 	{
     85 		next = h->next;
     86 		DelListItem(h, HiddenServers);
     87 		safe_free(h->servername);
     88 		safe_free(h);
     89 	}
     90 }
     91 
     92 MOD_TEST()
     93 {
     94 	SAVE_MODINFO
     95 	HookAdd(modinfo->handle, HOOKTYPE_CONFIGTEST, 0, cb_test);
     96 
     97 	return MOD_SUCCESS;
     98 }
     99 
    100 MOD_INIT()
    101 {
    102 	MARK_AS_OFFICIAL_MODULE(modinfo);
    103 	SAVE_MODINFO
    104 	HiddenServers = NULL;
    105 	InitConf();
    106 
    107 	HookAdd(modinfo->handle, HOOKTYPE_CONFIGRUN, 0, cb_conf);
    108 
    109 	return MOD_SUCCESS;
    110 }
    111 
    112 MOD_LOAD()
    113 {
    114 	if (!CommandOverrideAdd(MyMod, "MAP", 0, override_map))
    115 		return MOD_FAILED;
    116 
    117 	if (!CommandOverrideAdd(MyMod, "LINKS", 0, override_links))
    118 		return MOD_FAILED;
    119 
    120 	return MOD_SUCCESS;
    121 }
    122 
    123 MOD_UNLOAD()
    124 {
    125 	FreeConf();
    126 
    127 	return MOD_SUCCESS;
    128 }
    129 
    130 static int cb_test(ConfigFile *cf, ConfigEntry *ce, int type, int *errs)
    131 {
    132 	ConfigEntry *cep;
    133 	int errors = 0;
    134 
    135 	if (type == CONFIG_MAIN)
    136 	{
    137 		if (!strcmp(ce->name, "hideserver"))
    138 		{
    139 			for (cep = ce->items; cep; cep = cep->next)
    140 			{
    141 				if (!strcmp(cep->name, "hide"))
    142 				{
    143 					/* No checking needed */
    144 				}
    145 				else if (!cep->value)
    146 				{
    147 					config_error("%s:%i: %s::%s without value",
    148 						cep->file->filename,
    149 						cep->line_number,
    150 						ce->name, cep->name);
    151 					errors++;
    152 					continue;
    153 				}
    154 				else if (!strcmp(cep->name, "disable-map"))
    155 					;
    156 				else if (!strcmp(cep->name, "disable-links"))
    157 					;
    158 				else if (!strcmp(cep->name, "map-deny-message"))
    159 					;
    160 				else if (!strcmp(cep->name, "links-deny-message"))
    161 					;
    162 				else
    163 				{
    164 					config_error("%s:%i: unknown directive hideserver::%s",
    165 						cep->file->filename, cep->line_number, cep->name);
    166 					errors++;
    167 				}
    168 			}
    169 			*errs = errors;
    170 			return errors ? -1 : 1;
    171 		}
    172 	}
    173 
    174 	return 0;
    175 }
    176 
    177 static int cb_conf(ConfigFile *cf, ConfigEntry *ce, int type)
    178 {
    179 	ConfigEntry		*cep, *cepp;
    180 	ConfigItem_ulines	*ca;
    181 
    182 	if (type == CONFIG_MAIN)
    183 	{
    184 		if (!strcmp(ce->name, "hideserver"))
    185 		{
    186 			for (cep = ce->items; cep; cep = cep->next)
    187 			{
    188 				if (!strcmp(cep->name, "disable-map"))
    189 					Settings.disable_map = config_checkval(cep->value, CFG_YESNO);
    190 				else if (!strcmp(cep->name, "disable-links"))
    191 					Settings.disable_links = config_checkval(cep->value, CFG_YESNO);
    192 				else if (!strcmp(cep->name, "map-deny-message"))
    193 				{
    194 					safe_strdup(Settings.map_deny_message, cep->value);
    195 				}
    196 				else if (!strcmp(cep->name, "links-deny-message"))
    197 				{
    198 					safe_strdup(Settings.links_deny_message, cep->value);
    199 				}
    200 				else if (!strcmp(cep->name, "hide"))
    201 				{
    202 					for (cepp = cep->items; cepp; cepp = cepp->next)
    203 					{
    204 						if (!strcasecmp(cepp->name, me.name))
    205 							continue;
    206 
    207 						ca = safe_alloc(sizeof(ConfigItem_ulines));
    208 						safe_strdup(ca->servername, cepp->name);
    209 						AddListItem(ca, HiddenServers);
    210 					}
    211 				}
    212 			}
    213 
    214 			return 1;
    215 		}
    216 	}
    217 
    218 	return 0;
    219 }
    220 
    221 ConfigItem_ulines *FindHiddenServer(char *servername)
    222 {
    223 	ConfigItem_ulines *h;
    224 
    225 	for (h = HiddenServers; h; h = h->next)
    226 		if (!strcasecmp(servername, h->servername))
    227 			break;
    228 
    229 	return h;
    230 }
    231 
    232 /*
    233  * New /MAP format -Potvin
    234  * dump_map function.
    235  */
    236 static void dump_map(Client *client, Client *server, char *mask, int prompt_length, int length)
    237 {
    238 	static char prompt[64];
    239 	char *p = &prompt[prompt_length];
    240 	int  cnt = 0;
    241 	Client *acptr;
    242 
    243 	*p = '\0';
    244 
    245 	if (prompt_length > 60)
    246 		sendnumeric(client, RPL_MAPMORE, prompt, length, server->name);
    247 	else
    248 	{
    249 		char tbuf[256];
    250 		char sid[10];
    251 		int len = length - strlen(server->name) + 1;
    252 
    253 		if (len < 0)
    254 			len = 0;
    255 		if (len > 255)
    256 			len = 255;
    257 
    258 		tbuf[len--] = '\0';
    259 		while (len >= 0)
    260 			tbuf[len--] = '-';
    261 		if (IsOper(client))
    262 			snprintf(sid, sizeof(sid), " [%s]", server->id);
    263 		sendnumeric(client, RPL_MAP, prompt, server->name, tbuf, umax,
    264 			server->server->users, (double)(lmax < 10) ? 4 : (lmax == 100) ? 6 : 5,
    265 			(server->server->users * 100.0 / irccounts.clients),
    266 			IsOper(client) ? sid : "");
    267 		cnt = 0;
    268 	}
    269 
    270 	if (prompt_length > 0)
    271 	{
    272 		p[-1] = ' ';
    273 		if (p[-2] == '`')
    274 			p[-2] = ' ';
    275 	}
    276 	if (prompt_length > 60)
    277 		return;
    278 
    279 	strcpy(p, "|-");
    280 
    281 	list_for_each_entry(acptr, &global_server_list, client_node)
    282 	{
    283 		if (acptr->uplink != server ||
    284  		    (IsULine(acptr) && HIDE_ULINES && !ValidatePermissionsForPath("server:info:map:ulines",client,NULL,NULL,NULL)))
    285 			continue;
    286 		if (FindHiddenServer(acptr->name))
    287 			break;
    288 		SetMap(acptr);
    289 		cnt++;
    290 	}
    291 
    292 	list_for_each_entry(acptr, &global_server_list, client_node)
    293 	{
    294 		if (IsULine(acptr) && HIDE_ULINES && !ValidatePermissionsForPath("server:info:map:ulines",client,NULL,NULL,NULL))
    295 			continue;
    296 		if (FindHiddenServer(acptr->name))
    297 			break;
    298 		if (acptr->uplink != server)
    299 			continue;
    300 		if (!IsMap(acptr))
    301 			continue;
    302 		if (--cnt == 0)
    303 			*p = '`';
    304 		dump_map(client, acptr, mask, prompt_length + 2, length - 2);
    305 	}
    306 
    307 	if (prompt_length > 0)
    308 		p[-1] = '-';
    309 }
    310 
    311 void dump_flat_map(Client *client, Client *server, int length)
    312 {
    313 	char buf[4];
    314 	char tbuf[256];
    315 	Client *acptr;
    316 	int cnt = 0, len = 0, hide_ulines;
    317 
    318 	hide_ulines = (HIDE_ULINES && !ValidatePermissionsForPath("server:info:map:ulines",client,NULL,NULL,NULL)) ? 1 : 0;
    319 
    320 	len = length - strlen(server->name) + 3;
    321 	if (len < 0)
    322 		len = 0;
    323 	if (len > 255)
    324 		len = 255;
    325 
    326 	tbuf[len--] = '\0';
    327 	while (len >= 0)
    328 		tbuf[len--] = '-';
    329 
    330 	sendnumeric(client, RPL_MAP, "", server->name, tbuf, umax, server->server->users,
    331 		(lmax < 10) ? 4 : (lmax == 100) ? 6 : 5,
    332 		(server->server->users * 100.0 / irccounts.clients), "");
    333 
    334 	list_for_each_entry(acptr, &global_server_list, client_node)
    335 	{
    336 		if ((IsULine(acptr) && hide_ulines) || (acptr == server))
    337 			continue;
    338 		if (FindHiddenServer(acptr->name))
    339 			break;
    340 		cnt++;
    341 	}
    342 
    343 	strcpy(buf, "|-");
    344 	list_for_each_entry(acptr, &global_server_list, client_node)
    345 	{
    346 		if ((IsULine(acptr) && hide_ulines) || (acptr == server))
    347 			continue;
    348 		if (FindHiddenServer(acptr->name))
    349 			break;
    350 		if (--cnt == 0)
    351 			*buf = '`';
    352 
    353 		len = length - strlen(acptr->name) + 1;
    354 		if (len < 0)
    355 			len = 0;
    356 		if (len > 255)
    357 			len = 255;
    358 
    359 		tbuf[len--] = '\0';
    360 		while (len >= 0)
    361 			tbuf[len--] = '-';
    362 
    363 		sendnumeric(client, RPL_MAP, buf, acptr->name, tbuf, umax, acptr->server->users,
    364 			(lmax < 10) ? 4 : (lmax == 100) ? 6 : 5,
    365 			(acptr->server->users * 100.0 / irccounts.clients), "");
    366 	}
    367 }
    368 
    369 /*
    370 ** New /MAP format. -Potvin
    371 ** cmd_map (NEW)
    372 **
    373 **      parv[1] = server mask
    374 **/
    375 CMD_OVERRIDE_FUNC(override_map)
    376 {
    377 	Client *acptr;
    378 	int longest = strlen(me.name);
    379 	float avg_users = 0.0;
    380 
    381 	umax = 0;
    382 	lmax = 0;
    383 
    384 	if (parc < 2)
    385 		parv[1] = "*";
    386 	
    387 	if (IsOper(client))
    388 	{
    389 		CALL_NEXT_COMMAND_OVERRIDE();
    390 		return;
    391 	}
    392 
    393 	if (Settings.disable_map)
    394 	{
    395 		if (Settings.map_deny_message)
    396 			sendnotice(client, "%s", Settings.map_deny_message);
    397 		else
    398 			sendnumeric(client, RPL_MAPEND);
    399 		return;
    400 	}
    401 
    402 	list_for_each_entry(acptr, &global_server_list, client_node)
    403 	{
    404 		int perc = 0;
    405 		if (FindHiddenServer(acptr->name))
    406 			break;
    407 		perc = (acptr->server->users * 100 / irccounts.clients);
    408 		if ((strlen(acptr->name) + acptr->hopcount * 2) > longest)
    409 			longest = strlen(acptr->name) + acptr->hopcount * 2;
    410 		if (lmax < perc)
    411 			lmax = perc;
    412 		if (umax < dcount(acptr->server->users))
    413 			umax = dcount(acptr->server->users);
    414 	}
    415 
    416 	if (longest > 60)
    417 		longest = 60;
    418 	longest += 2;
    419 
    420 	if (FLAT_MAP && !ValidatePermissionsForPath("server:info:map:real-map",client,NULL,NULL,NULL))
    421 		dump_flat_map(client, &me, longest);
    422 	else
    423 		dump_map(client, &me, "*", 0, longest);
    424 
    425 	avg_users = irccounts.clients * 1.0 / irccounts.servers;
    426 	sendnumeric(client, RPL_MAPUSERS, irccounts.servers, (irccounts.servers > 1 ? "s" : ""), irccounts.clients,
    427 		(irccounts.clients > 1 ? "s" : ""), avg_users);
    428 	sendnumeric(client, RPL_MAPEND);
    429 }
    430 
    431 CMD_OVERRIDE_FUNC(override_links)
    432 {
    433 	Client *acptr;
    434 	int flat = (FLAT_MAP && !IsOper(client)) ? 1 : 0;
    435 
    436 	if (IsOper(client))
    437 	{
    438 		CALL_NEXT_COMMAND_OVERRIDE();
    439 		return;
    440 	}
    441 
    442 	if (Settings.disable_links)
    443 	{
    444 		if (Settings.links_deny_message)
    445 			sendnotice(client, "%s", Settings.links_deny_message);
    446 		else
    447 			sendnumeric(client, RPL_ENDOFLINKS, "*");
    448 		return;
    449 	}
    450 
    451 	list_for_each_entry(acptr, &global_server_list, client_node)
    452 	{
    453 		/* Some checks */
    454 		if (HIDE_ULINES && IsULine(acptr) && !ValidatePermissionsForPath("server:info:map:ulines",client,NULL,NULL,NULL))
    455 			continue;
    456 		if (FindHiddenServer(acptr->name))
    457 			continue;
    458 		if (flat)
    459 			sendnumeric(client, RPL_LINKS, acptr->name, me.name,
    460 			    1, (acptr->info[0] ? acptr->info : "(Unknown Location)"));
    461 		else
    462 			sendnumeric(client, RPL_LINKS, acptr->name, acptr->uplink ? acptr->uplink->name : me.name,
    463 			    acptr->hopcount, (acptr->info[0] ? acptr->info : "(Unknown Location)"));
    464 	}
    465 
    466 	sendnumeric(client, RPL_ENDOFLINKS, "*");
    467 }