]> arthur.barton.de Git - ngircd-alex.git/commitdiff
Implement new configuration option "MaxPenaltyTime" (#251)
authorAlexander Barton <alex@barton.de>
Wed, 28 Nov 2018 13:13:09 +0000 (14:13 +0100)
committerGitHub <noreply@github.com>
Wed, 28 Nov 2018 13:13:09 +0000 (14:13 +0100)
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.

doc/sample-ngircd.conf.tmpl
man/ngircd.conf.5.tmpl
src/ngircd/conf.c
src/ngircd/conf.h
src/ngircd/conn-func.c
src/testsuite/ngircd-test1.conf
src/testsuite/ngircd-test2.conf

index 3f9ba0884dee843eb494a59c98f397e6bb26f5cb..bd2d4080117b5efa49338c9e69554998cb1ed5b2 100644 (file)
        # maximum nickname length!
        ;MaxNickLength = 9
 
        # 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
        # Maximum number of channels returned in response to a /list
        # command (0: unlimited):
        ;MaxListSize = 100
index b8d4ddd956048c759a6b40af8d43167c323df6a6..0c0cd3494c84c9686e5f4754e994c5052472e9d8 100644 (file)
@@ -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
 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
 \fBMaxListSize\fR (number)
 Maximum number of channels returned in response to a LIST command. Default: 100.
 .TP
index 3a796f038c00ead7b6a650d320a90a57f875e7f1..3f2e01546dc69779d4cf8d22b748a9d45e0993ba 100644 (file)
@@ -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("  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);
        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_MaxConnectionsIP = 5;
        Conf_MaxJoins = 10;
        Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT;
+       Conf_MaxPenaltyTime = -1;
        Conf_MaxListSize = 100;
        Conf_PingTimeout = 120;
        Conf_PongTimeout = 20;
        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;
        }
                        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) {
        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
 
                             "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++) {
 #ifdef DEBUG
        servers = servers_once = 0;
        for (i = 0; i < MAX_SERVERS; i++) {
index 7203b86a3b630ce559a6693d7af26234cd1fa84d..4b73b547f8759e5eefc80e4a8e5de236ba3bcc9d 100644 (file)
@@ -239,6 +239,9 @@ GLOBAL unsigned int Conf_MaxNickLength;
 /** Maximum number of channels returned to /list */
 GLOBAL int Conf_MaxListSize;
 
 /** 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 */
 #ifndef STRICT_RFC
 
 /** Require "AUTH PING-PONG" on login */
index ed58f7280254bfad8b647fe57c2383253cbcd3c4..72d38b8621ff559c9c93903989e7c091b018be79 100644 (file)
@@ -26,6 +26,7 @@
 #endif
 #include "conn.h"
 
 #endif
 #include "conn.h"
 
+#include "conf.h"
 #include "conn-func.h"
 
 /**
 #include "conn-func.h"
 
 /**
@@ -97,6 +98,14 @@ Conn_SetPenalty(CONN_ID Idx, time_t Seconds)
        assert(Idx > NONE);
        assert(Seconds >= 0);
 
        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;
        t = time(NULL);
        if (My_Connections[Idx].delaytime < t)
                My_Connections[Idx].delaytime = t;
index 5cb7db7c7ad45dab1c4fc28e80e8527eb1872e8b..ab240a7c4aa285fb68c55923fb49458031207504 100644 (file)
@@ -12,6 +12,7 @@
 [Limits]
        MaxConnectionsIP = 0
        MaxJoins = 4
 [Limits]
        MaxConnectionsIP = 0
        MaxJoins = 4
+       MaxPenaltyTime = 1
 
 [Options]
        OperCanUseMode = yes
 
 [Options]
        OperCanUseMode = yes
index 0d24c4a45abf2f3f51863df0a8570968b6024c6c..40d881d483a84a0c726c3d27f689530c561cb37b 100644 (file)
@@ -12,6 +12,7 @@
 [Limits]
        MaxConnectionsIP = 0
        MaxJoins = 4
 [Limits]
        MaxConnectionsIP = 0
        MaxJoins = 4
+       MaxPenaltyTime = 1
 
 [Options]
        OperCanUseMode = yes
 
 [Options]
        OperCanUseMode = yes