commit c5beca8aabab6d1822f63e86e5db02649d7b1a41 from: Alexander Barton date: Fri Jan 06 19:06:25 2012 UTC Limit list replies of LIST, WHO, WHOIS, and MAX_RPL_WHOWAS Introduce new #define's MAX_RPL_LIST(100), MAX_RPL_WHO(25), MAX_RPL_WHOIS(10), and MAX_RPL_WHOWAS(25). 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; } /*