summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlexander Barton <alex@barton.de>2012-01-06 17:27:29 +0100
committerAlexander Barton <alex@barton.de>2012-01-06 17:27:29 +0100
commit98493077a2d044aa08ee5cb4bd7054579e30fb57 (patch)
tree5ed0491414555f07c712e7c8a54365bf6b86ab88
parent1fa2af5b3a95cad24c3e8b56ee7e57aa5084bfdb (diff)
downloadngircd-98493077a2d044aa08ee5cb4bd7054579e30fb57.tar.gz
ngircd-98493077a2d044aa08ee5cb4bd7054579e30fb57.zip
channel modes: only handle MAX_CMODES_ARG modes with arguments
Limit the MODE command to handle a maximum of MAX_CMODES_ARG (5) channel
modes that require an argument (+Ibkl) per call.

Please note: Further modes that require arguments are silently ignored
and end the handling of any further modes.
This is similar to the behavior of ircd2.11 (silently ignores but seems
to handle other modes) as well as ircd-seven (silently ignores but handles
some(!) other modes) ...
-rw-r--r--src/ngircd/defines.h5
-rw-r--r--src/ngircd/irc-mode.c8
2 files changed, 11 insertions, 2 deletions
diff --git a/src/ngircd/defines.h b/src/ngircd/defines.h
index 4bcb6aff..b894dbc7 100644
--- a/src/ngircd/defines.h
+++ b/src/ngircd/defines.h
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2010 Alexander Barton (alex@barton.de)
+ * Copyright (c)2001-2012 Alexander Barton (alex@barton.de)
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -32,6 +32,9 @@
 #define MAX_WHOWAS 64			/* Max. number of WHOWAS items */
 #define DEFAULT_WHOWAS 5		/* default count for WHOWAS command */
 
+#define MAX_CMODES_ARG 5		/* Max. number of channel modes with
+					 * arguments per MODE command */
+
 #define CONNECTION_POOL 100		/* Size of default connection pool */
 
 #define CLIENT_ID_LEN 64		/* Max. length of an IRC ID; see RFC
diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c
index 01f87621..9afe9078 100644
--- a/src/ngircd/irc-mode.c
+++ b/src/ngircd/irc-mode.c
@@ -375,7 +375,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 	char the_modes[COMMAND_LEN], the_args[COMMAND_LEN], x[2],
 	    argadd[CLIENT_PASS_LEN], *mode_ptr;
 	bool connected, set, skiponce, retval, onchannel, modeok, use_servermode;
-	int mode_arg, arg_arg;
+	int mode_arg, arg_arg, mode_arg_count = 0;
 	CLIENT *client;
 	long l;
 	size_t len;
@@ -491,6 +491,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 					Client_ID(Origin), Channel_Name(Channel));
 			break;
 		case 'k': /* Channel key */
+			if (mode_arg_count++ >= MAX_CMODES_ARG)
+				break;
 			if (!set) {
 				if (modeok)
 					x[0] = *mode_ptr;
@@ -525,6 +527,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 			}
 			break;
 		case 'l': /* Member limit */
+			if (mode_arg_count++ >= MAX_CMODES_ARG)
+				break;
 			if (!set) {
 				if (modeok)
 					x[0] = *mode_ptr;
@@ -635,6 +639,8 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel)
 		/* --- Channel lists --- */
 		case 'I': /* Invite lists */
 		case 'b': /* Ban lists */
+			if (mode_arg_count++ >= MAX_CMODES_ARG)
+				break;
 			if (arg_arg > mode_arg) {
 				/* modify list */
 				if (modeok) {