ngircd

Free, portable and lightweight Internet Relay Chat server http://ngircd.barton.de/
Log | Files | Refs | README | LICENSE

commit 456eea6f1896528dad344ed2c254fd07bdc3a4b1
parent 7690716e4fa8ac3ae9b513f4adba685f9e2c0e1f
Author: Alexander Barton <alex@barton.de>
Date:   Wed, 28 Nov 2018 14:13:09 +0100

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.
Diffstat:
Mdoc/sample-ngircd.conf.tmpl | 6++++++
Mman/ngircd.conf.5.tmpl | 6++++++
Msrc/ngircd/conf.c | 13+++++++++++++
Msrc/ngircd/conf.h | 3+++
Msrc/ngircd/conn-func.c | 9+++++++++
Msrc/testsuite/ngircd-test1.conf | 1+
Msrc/testsuite/ngircd-test2.conf | 1+
7 files changed, 39 insertions(+), 0 deletions(-)

diff --git 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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -12,6 +12,7 @@ [Limits] MaxConnectionsIP = 0 MaxJoins = 4 + MaxPenaltyTime = 1 [Options] OperCanUseMode = yes