]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/conf.c
Slightly reoder startup steps, and enhance logging
[ngircd-alex.git] / src / ngircd / conf.c
index 372b14c0d05b87a5226c1fb531cada52681fa91d..59a8ef9e7e3821d1683fa40f44727ac601ec94b5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ngIRCd -- The Next Generation IRC Daemon
- * Copyright (c)2001-2013 Alexander Barton (alex@barton.de) and Contributors.
+ * Copyright (c)2001-2019 Alexander Barton (alex@barton.de) and Contributors.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,9 +16,7 @@
  * Configuration management (reading, parsing & validation)
  */
 
-#include "imp.h"
 #include <assert.h>
-#include <ctype.h>
 #include <errno.h>
 #ifdef PROTOTYPES
 #      include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 #include <strings.h>
+#include <time.h>
 #include <unistd.h>
 #include <pwd.h>
 #include <grp.h>
 #include <sys/types.h>
-#include <unistd.h>
 #include <dirent.h>
 
-#include "array.h"
 #include "ngircd.h"
 #include "conn.h"
 #include "channel.h"
-#include "defines.h"
 #include "log.h"
 #include "match.h"
-#include "tool.h"
 
-#include "exp.h"
 #include "conf.h"
 
 
@@ -94,10 +88,10 @@ static void Init_Server_Struct PARAMS(( CONF_SERVER *Server ));
 #endif
 
 #ifdef HAVE_LIBSSL
-#define DEFAULT_CIPHERS                "HIGH:!aNULL:@STRENGTH"
+#define DEFAULT_CIPHERS                "HIGH:!aNULL:@STRENGTH:!SSLv3"
 #endif
 #ifdef HAVE_LIBGNUTLS
-#define DEFAULT_CIPHERS                "SECURE128"
+#define DEFAULT_CIPHERS                "SECURE128:-VERS-SSL3.0"
 #endif
 
 #ifdef SSL_SUPPORT
@@ -369,9 +363,9 @@ Conf_Test( void )
                printf("  MotdPhrase = %s\n", array_bytes(&Conf_Motd)
                       ? (const char*) array_start(&Conf_Motd) : "");
        }
-#ifndef PAM
-       printf("  Password = %s\n", Conf_ServerPwd);
-#endif
+       printf("  Network = %s\n", Conf_Network);
+       if (!Conf_PAM)
+               printf("  Password = %s\n", Conf_ServerPwd);
        printf("  PidFile = %s\n", Conf_PidFile);
        printf("  Ports = ");
        ports_puts(&Conf_ListenPorts);
@@ -394,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);
@@ -418,13 +413,14 @@ Conf_Test( void )
 #endif
        printf("  IncludeDir = %s\n", Conf_IncludeDir);
        printf("  MorePrivacy = %s\n", yesno_to_str(Conf_MorePrivacy));
-       printf("  NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth));
+       printf("  NoticeBeforeRegistration = %s\n", yesno_to_str(Conf_NoticeBeforeRegistration));
        printf("  OperCanUseMode = %s\n", yesno_to_str(Conf_OperCanMode));
        printf("  OperChanPAutoOp = %s\n", yesno_to_str(Conf_OperChanPAutoOp));
        printf("  OperServerMode = %s\n", yesno_to_str(Conf_OperServerMode));
 #ifdef PAM
        printf("  PAM = %s\n", yesno_to_str(Conf_PAM));
        printf("  PAMIsOptional = %s\n", yesno_to_str(Conf_PAMIsOptional));
+       printf("  PAMServiceName = %s\n", Conf_PAMServiceName);
 #endif
 #ifndef STRICT_RFC
        printf("  RequireAuthPing = %s\n", yesno_to_str(Conf_AuthPing));
@@ -624,6 +620,7 @@ Conf_EnablePassiveServer(const char *Name)
                    && (Conf_Server[i].port > 0)) {
                        /* BINGO! Enable server */
                        Conf_Server[i].flags &= ~CONF_SFLAG_DISABLED;
+                       Conf_Server[i].lasttry = 0;
                        return true;
                }
        }
@@ -715,7 +712,6 @@ Conf_NickIsService(int ConfServer, const char *Nick)
 /**
  * Check if the given nickname is blocked for "normal client" use.
  *
- * @param ConfServer The server index or NONE to check all configured servers.
  * @param Nick The nickname to check.
  * @returns true if the given nickname belongs to an "IRC service".
  */
@@ -749,6 +745,7 @@ Set_Defaults(bool InitServers)
        strcpy(Conf_ServerAdminMail, "");
        snprintf(Conf_ServerInfo, sizeof Conf_ServerInfo, "%s %s",
                 PACKAGE_NAME, PACKAGE_VERSION);
+       strcpy(Conf_Network, "");
        free(Conf_ListenAddress);
        Conf_ListenAddress = NULL;
        array_free(&Conf_ListenPorts);
@@ -769,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;
@@ -801,7 +799,7 @@ Set_Defaults(bool InitServers)
 #endif
        strcpy(Conf_IncludeDir, "");
        Conf_MorePrivacy = false;
-       Conf_NoticeAuth = false;
+       Conf_NoticeBeforeRegistration = false;
        Conf_OperCanMode = false;
        Conf_OperChanPAutoOp = true;
        Conf_OperServerMode = false;
@@ -811,8 +809,9 @@ Set_Defaults(bool InitServers)
        Conf_PAM = false;
 #endif
        Conf_PAMIsOptional = false;
-#ifdef SYSLOG
+       strcpy(Conf_PAMServiceName, "ngircd");
        Conf_ScrubCTCP = false;
+#ifdef SYSLOG
 #ifdef LOG_LOCAL5
        Conf_SyslogFacility = LOG_LOCAL5;
 #else
@@ -847,7 +846,7 @@ no_listenports(void)
  *
  * This function is used to read the MOTD and help text file, for example.
  *
- * @param filename     Name of the file to read.
+ * @param Filename     Name of the file to read.
  * @return             true, when the file has been read in.
  */
 static bool
@@ -889,9 +888,9 @@ Read_TextFile(const char *Filename, const char *Name, array *Destination)
  * Please note that this function uses exit(1) on fatal errors and therefore
  * can result in ngIRCd terminating!
  *
- * @param ngircd_starting      Flag indicating if ngIRCd is starting or not.
- * @returns                    true when the configuration file has been read
- *                             successfully; false otherwise.
+ * @param IsStarting   Flag indicating if ngIRCd is starting or not.
+ * @returns            true when the configuration file has been read
+ *                     successfully; false otherwise.
  */
 static bool
 Read_Config(bool TestOnly, bool IsStarting)
@@ -903,6 +902,8 @@ Read_Config(bool TestOnly, bool IsStarting)
        FILE *fd;
        DIR *dh;
 
+       Log(LOG_INFO, "Using configuration file \"%s\" ...", NGIRCd_ConfFile);
+
        /* Open configuration file */
        fd = fopen( NGIRCd_ConfFile, "r" );
        if( ! fd ) {
@@ -1052,9 +1053,13 @@ Read_Config(bool TestOnly, bool IsStarting)
 }
 
 /**
- * ...
+ * Read in and handle a configuration file.
+ *
+ * @param File Name of the configuration file.
+ * @param fd File descriptor already opened for reading.
  */
-static void Read_Config_File(const char *File, FILE *fd)
+static void
+Read_Config_File(const char *File, FILE *fd)
 {
        char section[LINE_LEN], str[LINE_LEN], *var, *arg, *ptr;
        int i, line = 0;
@@ -1063,7 +1068,7 @@ static void Read_Config_File(const char *File, FILE *fd)
        /* Read configuration file */
        section[0] = '\0';
        while (true) {
-               if (!fgets(str, LINE_LEN, fd))
+               if (!fgets(str, sizeof(str), fd))
                        break;
                ngt_TrimStr(str);
                line++;
@@ -1072,6 +1077,12 @@ static void Read_Config_File(const char *File, FILE *fd)
                if (str[0] == ';' || str[0] == '#' || str[0] == '\0')
                        continue;
 
+               if (strlen(str) >= sizeof(str) - 1) {
+                       Config_Error(LOG_WARNING, "%s, line %d too long!",
+                                    File, line);
+                       continue;
+               }
+
                /* Is this the beginning of a new section? */
                if ((str[0] == '[') && (str[strlen(str) - 1] == ']')) {
                        strlcpy(section, str, sizeof(section));
@@ -1403,6 +1414,7 @@ Handle_GLOBAL(const char *File, int Line, char *Var, char *Arg )
        struct group *grp;
        size_t len;
        const char *section;
+       char *ptr;
 
        assert(File != NULL);
        assert(Line > 0);
@@ -1474,7 +1486,7 @@ Handle_GLOBAL(const char *File, int Line, char *Var, char *Arg )
                len = strlen(Arg);
                if (len == 0)
                        return;
-               if (len >= LINE_LEN) {
+               if (len >= 127) {
                        Config_Error_TooLong(File, Line, Var);
                        return;
                }
@@ -1485,6 +1497,19 @@ Handle_GLOBAL(const char *File, int Line, char *Var, char *Arg )
                Using_MotdFile = false;
                return;
        }
+       if (strcasecmp(Var, "Network") == 0) {
+               len = strlcpy(Conf_Network, Arg, sizeof(Conf_Network));
+               if (len >= sizeof(Conf_Network))
+                       Config_Error_TooLong(File, Line, Var);
+               ptr = strchr(Conf_Network, ' ');
+               if (ptr) {
+                       Config_Error(LOG_WARNING,
+                                    "%s, line %d: \"Network\" can't contain spaces!",
+                                    File, Line);
+                       *ptr = '\0';
+               }
+               return;
+       }
        if(strcasecmp(Var, "Password") == 0) {
                len = strlcpy(Conf_ServerPwd, Arg, sizeof(Conf_ServerPwd));
                if (len >= sizeof(Conf_ServerPwd))
@@ -1620,6 +1645,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) {
@@ -1777,7 +1808,19 @@ Handle_OPTIONS(const char *File, int Line, char *Var, char *Arg)
                return;
        }
        if (strcasecmp(Var, "NoticeAuth") == 0) {
-               Conf_NoticeAuth = Check_ArgIsTrue(Arg);
+               /*
+                * TODO: This section and support for "NoticeAuth" variable
+                * could be removed starting with ngIRCd release 24 (one
+                * release after marking it "deprecated") ...
+                */
+               Config_Error(LOG_WARNING,
+                            "%s, line %d (section \"Options\"): \"%s\" is deprecated, please use \"NoticeBeforeRegistration\"!",
+                            File, Line, Var);
+               Conf_NoticeBeforeRegistration = Check_ArgIsTrue(Arg);
+               return;
+       }
+       if (strcasecmp(Var, "NoticeBeforeRegistration") == 0) {
+               Conf_NoticeBeforeRegistration = Check_ArgIsTrue(Arg);
                return;
        }
        if (strcasecmp(Var, "OperCanUseMode") == 0) {
@@ -1801,6 +1844,12 @@ Handle_OPTIONS(const char *File, int Line, char *Var, char *Arg)
                Conf_PAMIsOptional = Check_ArgIsTrue(Arg);
                return;
        }
+       if (strcasecmp(Var, "PAMServiceName") == 0) {
+               len = strlcpy(Conf_PAMServiceName, Arg, sizeof(Conf_PAMServiceName));
+               if (len >= sizeof(Conf_PAMServiceName))
+                       Config_Error_TooLong(File, Line, Var);
+               return;
+       }
        if (strcasecmp(Var, "PredefChannelsOnly") == 0) {
                /*
                 * TODO: This section and support for "PredefChannelsOnly"
@@ -2237,11 +2286,16 @@ Validate_Config(bool Configtest, bool Rehash)
        }
 
 #ifdef PAM
-       if (Conf_ServerPwd[0])
+       if (Conf_PAM && Conf_ServerPwd[0])
                Config_Error(LOG_ERR,
                             "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++) {