diff --git a/doc/sample-ngircd.conf.tmpl b/doc/sample-ngircd.conf.tmpl index 3f9ba0884..bd2d40801 100644 --- a/doc/sample-ngircd.conf.tmpl +++ b/doc/sample-ngircd.conf.tmpl @@ -117,6 +117,12 @@ # maximum nickname length! ;MaxNickLength = 9 + # Maximum penalty time increase in seconds, per penalty event. Set to -1 + # for no limit (the default), 0 to disable penalties altogether. The + # daemon doesn't use penalty increases higher than 2 seconds during + # normal operation, so values greater than 1 rarely make sense. + ;MaxPenaltyTime = -1 + # Maximum number of channels returned in response to a /list # command (0: unlimited): ;MaxListSize = 100 diff --git a/man/ngircd.conf.5.tmpl b/man/ngircd.conf.5.tmpl index b8d4ddd95..0c0cd3494 100644 --- a/man/ngircd.conf.5.tmpl +++ b/man/ngircd.conf.5.tmpl @@ -201,6 +201,12 @@ Maximum length of an user nickname (Default: 9, as in RFC 2812). Please note that all servers in an IRC network MUST use the same maximum nickname length! .TP +\fBMaxPenaltyTime\fR (number) +Maximum penalty time increase in seconds, per penalty event. Set to -1 for no +limit (the default), 0 to disable penalties altogether. ngIRCd doesn't use +penalty increases higher than 2 seconds during normal operation, so values +greater than 1 rarely make sense. +.TP \fBMaxListSize\fR (number) Maximum number of channels returned in response to a LIST command. Default: 100. .TP diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index 01ec3c095..947516e4c 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -388,6 +388,7 @@ Conf_Test( void ) printf(" MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP); printf(" MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1); printf(" MaxNickLength = %u\n", Conf_MaxNickLength - 1); + printf(" MaxPenaltyTime = %ld\n", Conf_MaxPenaltyTime); printf(" MaxListSize = %d\n", Conf_MaxListSize); printf(" PingTimeout = %d\n", Conf_PingTimeout); printf(" PongTimeout = %d\n", Conf_PongTimeout); @@ -766,6 +767,7 @@ Set_Defaults(bool InitServers) Conf_MaxConnectionsIP = 5; Conf_MaxJoins = 10; Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT; + Conf_MaxPenaltyTime = -1; Conf_MaxListSize = 100; Conf_PingTimeout = 120; Conf_PongTimeout = 20; @@ -1642,6 +1644,12 @@ Handle_LIMITS(const char *File, int Line, char *Var, char *Arg) Config_Error_NaN(File, Line, Var); return; } + if (strcasecmp(Var, "MaxPenaltyTime") == 0) { + Conf_MaxPenaltyTime = atol(Arg); + if (Conf_MaxPenaltyTime < -1) + Conf_MaxPenaltyTime = -1; /* "unlimited" */ + return; + } if (strcasecmp(Var, "PingTimeout") == 0) { Conf_PingTimeout = atoi(Arg); if (Conf_PingTimeout < 5) { @@ -2282,6 +2290,11 @@ Validate_Config(bool Configtest, bool Rehash) "This server uses PAM, \"Password\" in [Global] section will be ignored!"); #endif + if (Conf_MaxPenaltyTime != -1) + Config_Error(LOG_WARNING, + "Maximum penalty increase ('MaxPenaltyTime') is set to %ld, this is not recommended!", + Conf_MaxPenaltyTime); + #ifdef DEBUG servers = servers_once = 0; for (i = 0; i < MAX_SERVERS; i++) { diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h index 7203b86a3..4b73b547f 100644 --- a/src/ngircd/conf.h +++ b/src/ngircd/conf.h @@ -239,6 +239,9 @@ GLOBAL unsigned int Conf_MaxNickLength; /** Maximum number of channels returned to /list */ GLOBAL int Conf_MaxListSize; +/** Maximium seconds to add per "penalty". -1 = unlimited. */ +GLOBAL time_t Conf_MaxPenaltyTime; + #ifndef STRICT_RFC /** Require "AUTH PING-PONG" on login */ diff --git a/src/ngircd/conn-func.c b/src/ngircd/conn-func.c index b6e82849b..dad6ca2cc 100644 --- a/src/ngircd/conn-func.c +++ b/src/ngircd/conn-func.c @@ -26,6 +26,7 @@ #endif #include "conn.h" +#include "conf.h" #include "conn-func.h" /** @@ -97,6 +98,14 @@ Conn_SetPenalty(CONN_ID Idx, time_t Seconds) assert(Idx > NONE); assert(Seconds >= 0); + /* Limit new penalty to maximum configured, when less than 10 seconds. * + The latter is used to limit brute force attacks, therefore we don't * + want to limit that! */ + if (Conf_MaxPenaltyTime >= 0 + && Seconds > Conf_MaxPenaltyTime + && Seconds < 10) + Seconds = Conf_MaxPenaltyTime; + t = time(NULL); if (My_Connections[Idx].delaytime < t) My_Connections[Idx].delaytime = t; diff --git a/src/testsuite/ngircd-test1.conf b/src/testsuite/ngircd-test1.conf index 5cb7db7c7..ab240a7c4 100644 --- a/src/testsuite/ngircd-test1.conf +++ b/src/testsuite/ngircd-test1.conf @@ -12,6 +12,7 @@ [Limits] MaxConnectionsIP = 0 MaxJoins = 4 + MaxPenaltyTime = 1 [Options] OperCanUseMode = yes diff --git a/src/testsuite/ngircd-test2.conf b/src/testsuite/ngircd-test2.conf index 0d24c4a45..40d881d48 100644 --- a/src/testsuite/ngircd-test2.conf +++ b/src/testsuite/ngircd-test2.conf @@ -12,6 +12,7 @@ [Limits] MaxConnectionsIP = 0 MaxJoins = 4 + MaxPenaltyTime = 1 [Options] OperCanUseMode = yes