repo: ngircd
action: commit
revision: 
path_from: 
revision_from: 2981fe9eb707b340107b5131018805ee2a469950:
path_to: 
revision_to: 
git.thebackupbox.net
ngircd
git clone git://git.thebackupbox.net/ngircd
commit 2981fe9eb707b340107b5131018805ee2a469950
Author: Alexander Barton 
Date:   Wed Nov 5 21:41:01 2003 +0000

    New configuration option "MaxConnectionsIP".

diff --git a/ChangeLog b/ChangeLog
index 904d609aabdef6b67ce2a4198534ec7f4962afba..
index ..7e173e3c56bb12f1e43a0b492568d055a6e9b450 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,10 @@

 ngIRCd CVS-HEAD

+  - New configuration variable "MaxConnectionsIP" to limit the number of
+    simultaneous connections from a single IP that the server will accept.
+    This configuration options lowers the risk of denial of service attacks
+    (DoS), the default is 5 connections per client IP.
   - Fixed build problems under Mac OS X 10.3.
   - Use "-pipe" when compiling with gcc, speeds things up a little :-)
   - Added new configuration variable "Listen" to bind all listening
@@ -468,4 +472,4 @@ ngIRCd 0.0.1, 31.12.2001


 -- 
-$Id: ChangeLog,v 1.213 2003/11/04 00:41:06 alex Exp $
+$Id: ChangeLog,v 1.214 2003/11/05 21:41:01 alex Exp $
diff --git a/NEWS b/NEWS
index c55b2b4eb6f52c94bbcfa8ec2f37ecdd028faae5..
index ..20f861c52eb7e8e69825d35be05b996507f7b333 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,10 @@

 ngIRCd CVS-HEAD

+  - New configuration variable "MaxConnectionsIP" to limit the number of
+    simultaneous connections from a single IP that the server will accept.
+    This configuration options lowers the risk of denial of service attacks
+    (DoS), the default is 5 connections per client IP.
   - Added new configuration variable "Listen" to bind all listening
     sockets of the server to a single IP address.

@@ -170,4 +174,4 @@ ngIRCd 0.0.1, 31.12.2001


 -- 
-$Id: NEWS,v 1.58 2003/09/11 12:05:28 alex Exp $
+$Id: NEWS,v 1.59 2003/11/05 21:41:01 alex Exp $
diff --git a/doc/sample-ngircd.conf b/doc/sample-ngircd.conf
index 354b54efa7b3fa8cf2789fe9af911023138f1062..
index ..0e4439309a9c16c7e9519a471c916d8ba7096df4 100644
--- a/doc/sample-ngircd.conf
+++ b/doc/sample-ngircd.conf
@@ -1,4 +1,4 @@
-# $Id: sample-ngircd.conf,v 1.23 2003/09/11 12:05:28 alex Exp $
+# $Id: sample-ngircd.conf,v 1.24 2003/11/05 21:41:02 alex Exp $

 #
 # This is a sample configuration file for the ngIRCd, which must adept to
@@ -76,6 +76,10 @@
 	# Maximum number of simultaneous connection the server is allowed
 	# to accept (<=0: unlimited):
 	;MaxConnections = -1
+	
+	# Maximum number of simultaneous connections from a single IP address
+	# the server will accept (<=0: unlimited):
+	;MaxConnectionsIP = 5

 	# Maximum number of channels a user can be member of (<=0: no limit):
 	;MaxJoins = 10
diff --git a/man/ngircd.conf.5 b/man/ngircd.conf.5
index 773287a7ee09fb43c0e995a1dfab77f38b448389..
index ..d1cf47e2d60a24a006b0f9d36ee3ea90783a1876 100644
--- a/man/ngircd.conf.5
+++ b/man/ngircd.conf.5
@@ -1,5 +1,5 @@
 .\"
-.\" $Id: ngircd.conf.5,v 1.11 2003/09/11 12:05:28 alex Exp $
+.\" $Id: ngircd.conf.5,v 1.12 2003/11/05 21:41:02 alex Exp $
 .\"
 .TH ngircd.conf 5 "Mai 2003" ngircd "ngIRCd Manual"
 .SH NAME
@@ -118,6 +118,11 @@ not(!) channel-operators? Default: no.
 Maximum number of simultaneous connection the server is allowed to accept
 (<=0: unlimited). Default: -1.
 .TP
+\fBMaxConnectionsIP\fR
+Maximum number of simultaneous connections from a single IP address that
+the server will accept (<=0: unlimited). This configuration options lowers
+the risk of denial of service attacks (DoS). Default: 5.
+.TP
 \fBMaxJoins\fR
 Maximum number of channels a user can be member of (<=0: no limit).
 Default: 10.
diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c
index 0abb3c81531c40d791cef63ddc41113f3b1d2b1f..
index ..d17168c3348e731c75433478947f91084beb8f3a 100644
--- a/src/ngircd/conf.c
+++ b/src/ngircd/conf.c
@@ -14,7 +14,7 @@

 #include "portab.h"

-static char UNUSED id[] = "$Id: conf.c,v 1.60 2003/09/11 12:05:28 alex Exp $";
+static char UNUSED id[] = "$Id: conf.c,v 1.61 2003/11/05 21:41:02 alex Exp $";

 #include "imp.h"
 #include 
@@ -133,6 +133,8 @@ Conf_Test( VOID )
 	printf( "  OperCanUseMode = %s\n", Conf_OperCanMode == TRUE ? "yes" : "no" );
 	if( Conf_MaxConnections > 0 ) printf( "  MaxConnections = %ld\n", Conf_MaxConnections );
 	else printf( "  MaxConnections = -1\n" );
+	if( Conf_MaxConnectionsIP > 0 ) printf( "  MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP );
+	else printf( "  MaxConnectionsIP = -1\n" );
 	if( Conf_MaxJoins > 0 ) printf( "  MaxJoins = %d\n", Conf_MaxJoins );
 	else printf( "  MaxJoins = -1\n" );
 	puts( "" );
@@ -356,6 +358,7 @@ Set_Defaults( BOOLEAN InitServers )
 	Conf_OperCanMode = FALSE;

 	Conf_MaxConnections = -1;
+	Conf_MaxConnectionsIP = 5;
 	Conf_MaxJoins = 10;

 	/* Initialize server configuration structures */
@@ -691,6 +694,16 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
 		Conf_MaxConnections = atol( Arg );
 		return;
 	}
+	if( strcasecmp( Var, "MaxConnectionsIP" ) == 0 )
+	{
+		/* Maximum number of simoultanous connections from one IP. Values <= 0 are equal to "no limit". */
+#ifdef HAVE_ISDIGIT
+		if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MaxConnectionsIP\" is not a number!", NGIRCd_ConfFile, Line );
+		else
+#endif
+		Conf_MaxConnectionsIP = atoi( Arg );
+		return;
+	}
 	if( strcasecmp( Var, "MaxJoins" ) == 0 )
 	{
 		/* Maximum number of channels a user can join. Values <= 0 are equal to "no limit". */
@@ -707,8 +720,8 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg )
 		if( strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress )) >= sizeof( Conf_ListenAddress ))
 		{
 			Config_Error( LOG_WARNING, "%s, line %d: Value of \"Listen\" too long!", NGIRCd_ConfFile, Line );
-			return;
 		}
+		return;
 	}

 	Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var );
diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h
index 15a7093d433bb08b7033ab2135fdbf691fd47c5c..
index ..b900610b71fa838627e413a3c3bda680cf4ec668 100644
--- a/src/ngircd/conf.h
+++ b/src/ngircd/conf.h
@@ -8,7 +8,7 @@
  * (at your option) any later version.
  * Please read the file COPYING, README and AUTHORS for more information.
  *
- * $Id: conf.h,v 1.27 2003/09/11 12:05:28 alex Exp $
+ * $Id: conf.h,v 1.28 2003/11/05 21:41:02 alex Exp $
  *
  * Configuration management (header)
  */
@@ -110,6 +110,9 @@ GLOBAL LONG Conf_MaxConnections;
 /* Maximum number of channels a user can join */
 GLOBAL INT Conf_MaxJoins;

+/* Maximum number of connections per IP address */
+GLOBAL INT Conf_MaxConnectionsIP;
+

 GLOBAL VOID Conf_Init PARAMS((VOID ));
 GLOBAL VOID Conf_Rehash PARAMS((VOID ));
diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c
index 56824594e98fc22629b26f8296663b796ba78fb0..
index ..2c65f26e1f52204cffd87e16b60407d482326c6c 100644
--- a/src/ngircd/conn.c
+++ b/src/ngircd/conn.c
@@ -16,7 +16,7 @@

 #include "portab.h"

-static char UNUSED id[] = "$Id: conn.c,v 1.125 2003/09/11 12:05:28 alex Exp $";
+static char UNUSED id[] = "$Id: conn.c,v 1.126 2003/11/05 21:41:02 alex Exp $";

 #include "imp.h"
 #include 
@@ -87,6 +87,7 @@ LOCAL BOOLEAN Init_Socket PARAMS(( INT Sock ));
 LOCAL VOID New_Server PARAMS(( INT Server, CONN_ID Idx ));
 LOCAL VOID Read_Resolver_Result PARAMS(( INT r_fd ));
 LOCAL VOID Simple_Message PARAMS(( INT Sock, CHAR *Msg ));
+LOCAL INT Count_Connections PARAMS(( struct sockaddr_in addr ));

 LOCAL fd_set My_Listeners;
 LOCAL fd_set My_Sockets;
@@ -904,7 +905,7 @@ New_Connection( INT Sock )
 	CONN_ID idx;
 	CLIENT *c;
 	POINTER *ptr;
-	LONG new_size;
+	LONG new_size, cnt;

 	assert( Sock > NONE );

@@ -932,6 +933,17 @@ New_Connection( INT Sock )

 	/* Socket initialisieren */
 	Init_Socket( new_sock );
+	
+	/* Check IP-based connection limit */
+	cnt = Count_Connections( new_addr );
+	if(( Conf_MaxConnectionsIP > 0 ) && ( cnt >= Conf_MaxConnectionsIP ))
+	{
+		/* Access denied, too many connections from this IP! */
+		Log( LOG_ERR, "Refused connection from %s: too may connections (%ld) from this IP!", inet_ntoa( new_addr.sin_addr ), cnt);
+		Simple_Message( new_sock, "ERROR :Connection refused, too many connections from your IP!" );
+		close( new_sock );
+		return;
+	}

 	/* Freie Connection-Struktur suchen */
 	for( idx = 0; idx < Pool_Size; idx++ ) if( My_Connections[idx].sock == NONE ) break;
@@ -1599,4 +1611,18 @@ Simple_Message( INT Sock, CHAR *Msg )
 } /* Simple_Error */


+LOCAL INT
+Count_Connections( struct sockaddr_in addr_in )
+{
+	INT i, cnt;
+	
+	cnt = 0;
+	for( i = 0; i < Pool_Size; i++ )
+	{
+		if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].addr.sin_addr.s_addr == addr_in.sin_addr.s_addr )) cnt++;
+	}
+	return cnt;
+} /* Count_Connections */
+
+
 /* -eof- */

-----END OF PAGE-----