From: Alexander Barton Date: Wed, 28 Nov 2018 13:13:09 +0000 (+0100) Subject: Implement new configuration option "MaxPenaltyTime" (#251) X-Git-Tag: rel-25~4 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=commitdiff_plain;h=456eea6f1896528dad344ed2c254fd07bdc3a4b1 Implement new configuration option "MaxPenaltyTime" (#251) This option configures the 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 higher than 1 rarely make sense. Disabling (or reducing) penalties can greatly speed up "make check" runs for example, see below, but are mostly a debugging feature and normally not meant to be used on production systems! Some example timings running "make check" from my macOS workstation: - MaxPenaltyTime not set: 4:41,79s - "MaxPenaltyTime = 1": 3:14,71s - "MaxPenaltyTime = 0": 25,46s Closes #249. --- diff --git a/doc/sample-ngircd.conf.tmpl b/doc/sample-ngircd.conf.tmpl index 3f9ba088..bd2d4080 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 b8d4ddd9..0c0cd349 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 3a796f03..3f2e0154 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); @@ -765,6 +766,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; @@ -1641,6 +1643,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) { @@ -2281,6 +2289,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 7203b86a..4b73b547 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 ed58f728..72d38b86 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 5cb7db7c..ab240a7c 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 0d24c4a4..40d881d4 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