Commit Diff


commit - f8405b1a4f032a125372b03711f6bed1ecac2bd6
commit + c5beca8aabab6d1822f63e86e5db02649d7b1a41
blob - 2613a358e9ffcc046a31f10c9853685ace688945
blob + e75866811c3421358c79da33f3af4f15506e80b3
--- src/ngircd/defines.h
+++ src/ngircd/defines.h
@@ -178,13 +178,25 @@
 
 /* Defaults and limits for IRC commands */
 
-/** Default count of WHOWAS command replies */
-#define DEF_RPL_WHOWAS 5
+/** Max. number of LIST replies. */
+#define MAX_RPL_LIST 100
 
-/** Max. number of channel modes with arguments per MODE command */
+/** Max. number of channel modes with arguments per MODE command. */
 #define MAX_HNDL_MODES_ARG 5
 
+/** Max. number of WHO replies. */
+#define MAX_RPL_WHO 25
 
+/** Max. number of WHOIS replies. */
+#define MAX_RPL_WHOIS 10
+
+/** Default count of WHOWAS command replies. */
+#define DEF_RPL_WHOWAS 5
+
+/** Max count of WHOWAS command replies. */
+#define MAX_RPL_WHOWAS 25
+
+
 #endif
 
 /* -eof- */
blob - 94a8a4d723db07661fdcff9bb794dffe9654f6f7
blob + 52ba0930caac5c9ab89f189dd684fe65e7976529
--- src/ngircd/irc-channel.c
+++ src/ngircd/irc-channel.c
@@ -31,6 +31,7 @@
 #include "match.h"
 #include "messages.h"
 #include "parse.h"
+#include "irc.h"
 #include "irc-info.h"
 #include "irc-write.h"
 #include "conf.h"
@@ -602,6 +603,7 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
 	char *pattern;
 	CHANNEL *chan;
 	CLIENT *from, *target;
+	int count = 0;
 
 	assert(Client != NULL);
 	assert(Req != NULL);
@@ -654,12 +656,17 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
 				/* Gotcha! */
 				if (!strchr(Channel_Modes(chan), 's')
 				    || Channel_IsMemberOf(chan, from)) {
+					if (IRC_CheckListTooBig(from, count,
+								 MAX_RPL_LIST,
+								 "LIST"))
+						break;
 					if (!IRC_WriteStrClient(from,
 					     RPL_LIST_MSG, Client_ID(from),
 					     Channel_Name(chan),
 					     Channel_MemberCount(chan),
 					     Channel_Topic( chan )))
 						return DISCONNECTED;
+					count++;
 				}
 			}
 			chan = Channel_Next(chan);
@@ -672,6 +679,7 @@ IRC_LIST( CLIENT *Client, REQUEST *Req )
 			pattern = NULL;
 	}
 
+	IRC_SetPenalty(from, 2);
 	return IRC_WriteStrClient(from, RPL_LISTEND_MSG, Client_ID(from));
 } /* IRC_LIST */
 
blob - 8c87d9320789fa00b1b277fcece7171c6c2f1777
blob + fd4cbee4948c23870dd3a3c04da2c6e8b632b3da
--- src/ngircd/irc-info.c
+++ src/ngircd/irc-info.c
@@ -37,6 +37,7 @@
 #include "match.h"
 #include "tool.h"
 #include "parse.h"
+#include "irc.h"
 #include "irc-write.h"
 
 #include "exp.h"
@@ -833,6 +834,7 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool On
 	const char *chan_user_modes;
 	char flags[8];
 	CLIENT *c;
+	int count = 0;
 
 	assert( Client != NULL );
 	assert( Chan != NULL );
@@ -855,6 +857,9 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool On
 
 		is_visible = strchr(client_modes, 'i') == NULL;
 		if (is_member || is_visible) {
+			if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
+				break;
+
 			strcpy(flags, who_flags_status(client_modes));
 			if (is_ircop)
 				strlcat(flags, "*", sizeof(flags));
@@ -866,6 +871,7 @@ IRC_WHO_Channel(CLIENT *Client, CHANNEL *Chan, bool On
 			if (!write_whoreply(Client, c, Channel_Name(Chan),
 					    flags))
 				return DISCONNECTED;
+			count++;
 		}
 	}
 	return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client),
@@ -889,6 +895,7 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps)
 	CHANNEL *chan;
 	bool client_match, is_visible;
 	char flags[4];
+	int count = 0;
 
 	assert (Client != NULL);
 
@@ -939,13 +946,16 @@ IRC_WHO_Mask(CLIENT *Client, char *Mask, bool OnlyOps)
 		if (!is_visible)	/* target user is not visible */
 			continue;
 
+		if (IRC_CheckListTooBig(Client, count, MAX_RPL_WHO, "WHO"))
+			break;
+
 		strcpy(flags, who_flags_status(Client_Modes(c)));
 		if (strchr(Client_Modes(c), 'o'))
 			strlcat(flags, "*", sizeof(flags));
 
 		if (!write_whoreply(Client, c, "*", flags))
 			return DISCONNECTED;
-
+		count++;
 	}
 
 	return IRC_WriteStrClient(Client, RPL_ENDOFWHO_MSG, Client_ID(Client),
@@ -1182,7 +1192,7 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
 		 *  - no wildcards for remote clients
 		 *  - only one wildcard target per local client
 		 *
-		 *  also, at most ten matches are returned.
+		 *  Also, at most MAX_RPL_WHOIS matches are returned.
 		 */
 		if (!has_wildcards || is_remote) {
 			c = Client_Search(query);
@@ -1208,13 +1218,18 @@ IRC_WHOIS( CLIENT *Client, REQUEST *Req )
 		got_wildcard = true;
 		IRC_SetPenalty(Client, 3);
 
-		for (c = Client_First(); c && match_count < 10; c = Client_Next(c)) {
+		for (c = Client_First(); c; c = Client_Next(c)) {
+			if (IRC_CheckListTooBig(Client, match_count,
+					    MAX_RPL_WHOIS, "WHOIS"))
+				break;
+
 			if (Client_Type(c) != CLIENT_USER)
 				continue;
 			if (!MatchCaseInsensitive(query, Client_ID(c)))
 				continue;
 			if (!IRC_WHOIS_SendReply(Client, from, c))
 				return DISCONNECTED;
+
 			match_count++;
 		}
 
@@ -1310,7 +1325,7 @@ IRC_WHOWAS( CLIENT *Client, REQUEST *Req )
 	if (Req->argc > 1) {
 		max = atoi(Req->argv[1]);
 		if (max < 1)
-			max = MAX_WHOWAS;
+			max = MAX_RPL_WHOWAS;
 	}
 
 	/*