X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fngircd%2Fconf.c;h=e46dcfee43669644091285586fd956b9c9a6c94c;hb=a78c7b3898e8f2b037fb42aac599ed8f8ec9bd58;hp=3966dc908a1afff2bf5a95901c8cff6427b91524;hpb=bcefdef1eaed14d3156b7fb5b9ad6d3b7078efcf;p=ngircd-alex.git diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index 3966dc90..e46dcfee 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2013 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 @@ -18,6 +18,7 @@ #include "imp.h" #include +#include #include #ifdef PROTOTYPES # include @@ -34,9 +35,6 @@ #include #include -#ifdef HAVE_CTYPE_H -# include -#endif #include "array.h" #include "ngircd.h" @@ -56,6 +54,7 @@ static CONF_SERVER New_Server; static int New_Server_Idx; static char Conf_MotdFile[FNAME_LEN]; +static char Conf_HelpFile[FNAME_LEN]; static void Set_Defaults PARAMS(( bool InitServers )); static bool Read_Config PARAMS(( bool TestOnly, bool IsStarting )); @@ -106,6 +105,30 @@ ConfSSL_Init(void) free(Conf_SSLOptions.DHFile); Conf_SSLOptions.DHFile = NULL; array_free_wipe(&Conf_SSLOptions.KeyFilePassword); + + array_free(&Conf_SSLOptions.ListenPorts); +} + +/** + * Check if the current configuration uses/requires SSL. + * + * @returns true if SSL is used and should be initialized. + */ +GLOBAL bool +Conf_SSLInUse(void) +{ + int i; + + /* SSL listen ports configured? */ + if (array_bytes(&Conf_SSLOptions.ListenPorts)) + return true; + + for (i = 0; i < MAX_SERVERS; i++) { + if (Conf_Server[i].port > 0 + && Conf_Server[i].SSLConnect) + return true; + } + return false; } /** @@ -316,6 +339,7 @@ Conf_Test( void ) printf(" AdminInfo1 = %s\n", Conf_ServerAdmin1); printf(" AdminInfo2 = %s\n", Conf_ServerAdmin2); printf(" AdminEMail = %s\n", Conf_ServerAdminMail); + printf(" HelpFile = %s\n", Conf_HelpFile); printf(" Info = %s\n", Conf_ServerInfo); printf(" Listen = %s\n", Conf_ListenAddress); if (Using_MotdFile) { @@ -346,10 +370,12 @@ Conf_Test( void ) puts("[LIMITS]"); printf(" ConnectRetry = %d\n", Conf_ConnectRetry); - printf(" MaxConnections = %ld\n", Conf_MaxConnections); + printf(" IdleTimeout = %d\n", Conf_IdleTimeout); + printf(" MaxConnections = %d\n", Conf_MaxConnections); printf(" MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP); printf(" MaxJoins = %d\n", Conf_MaxJoins > 0 ? Conf_MaxJoins : -1); printf(" MaxNickLength = %u\n", Conf_MaxNickLength - 1); + printf(" MaxListSize = %d\n", Conf_MaxListSize); printf(" PingTimeout = %d\n", Conf_PingTimeout); printf(" PongTimeout = %d\n", Conf_PongTimeout); puts(""); @@ -372,6 +398,7 @@ Conf_Test( void ) printf(" MorePrivacy = %s\n", yesno_to_str(Conf_MorePrivacy)); printf(" NoticeAuth = %s\n", yesno_to_str(Conf_NoticeAuth)); 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)); @@ -479,8 +506,12 @@ Conf_UnsetServer( CONN_ID Idx ) * require the next attempt to be delayed. */ Conf_Server[i].lasttry = t - Conf_ConnectRetry + RECONNECT_DELAY; - } else - Conf_Server[i].lasttry = t; + } else { + /* "Short" connection, enforce "ConnectRetry" + * but randomize it a little bit: 15 seconds. */ + Conf_Server[i].lasttry = + t + rand() / (RAND_MAX / 15); + } } } } @@ -488,7 +519,7 @@ Conf_UnsetServer( CONN_ID Idx ) /** * Set connection information for specified configured server. */ -GLOBAL void +GLOBAL bool Conf_SetServer( int ConfServer, CONN_ID Idx ) { assert( ConfServer > NONE ); @@ -496,13 +527,15 @@ Conf_SetServer( int ConfServer, CONN_ID Idx ) if (Conf_Server[ConfServer].conn_id > NONE && Conf_Server[ConfServer].conn_id != Idx) { - Log(LOG_ALERT, - "Trying to update connection index for already registered server \"%s\": %d/%d - ignored.", - Conf_Server[ConfServer].name, - Conf_Server[ConfServer].conn_id, Idx); - return; + Log(LOG_ERR, + "Connection %d: Server configuration of \"%s\" already in use by connection %d!", + Idx, Conf_Server[ConfServer].name, + Conf_Server[ConfServer].conn_id); + Conn_Close(Idx, NULL, "Server configuration already in use", true); + return false; } Conf_Server[ConfServer].conn_id = Idx; + return true; } /** @@ -636,11 +669,11 @@ Conf_AddServer(const char *Name, UINT16 Port, const char *Host, } /** - * Check if the given nick name is reserved for services on a particular server. + * Check if the given nickname is reserved for services on a particular server. * * @param ConfServer The server index to check. - * @param Nick The nick name to check. - * @returns true if the given nick name belongs to an "IRC service". + * @param Nick The nickname to check. + * @returns true if the given nickname belongs to an "IRC service". */ GLOBAL bool Conf_NickIsService(int ConfServer, const char *Nick) @@ -653,11 +686,11 @@ Conf_NickIsService(int ConfServer, const char *Nick) } /** - * Check if the given nick name is blocked for "normal client" use. + * 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 nick name to check. - * @returns true if the given nick name belongs to an "IRC service". + * @param Nick The nickname to check. + * @returns true if the given nickname belongs to an "IRC service". */ GLOBAL bool Conf_NickIsBlocked(const char *Nick) @@ -691,19 +724,25 @@ Set_Defaults(bool InitServers) PACKAGE_NAME, PACKAGE_VERSION); free(Conf_ListenAddress); Conf_ListenAddress = NULL; + array_free(&Conf_ListenPorts); array_free(&Conf_Motd); + array_free(&Conf_Helptext); strlcpy(Conf_MotdFile, SYSCONFDIR, sizeof(Conf_MotdFile)); strlcat(Conf_MotdFile, MOTD_FILE, sizeof(Conf_MotdFile)); + strlcpy(Conf_HelpFile, DOCDIR, sizeof(Conf_HelpFile)); + strlcat(Conf_HelpFile, HELP_FILE, sizeof(Conf_HelpFile)); strcpy(Conf_ServerPwd, ""); strlcpy(Conf_PidFile, PID_FILE, sizeof(Conf_PidFile)); Conf_UID = Conf_GID = 0; /* Limits */ Conf_ConnectRetry = 60; + Conf_IdleTimeout = 0; Conf_MaxConnections = 0; Conf_MaxConnectionsIP = 5; Conf_MaxJoins = 10; Conf_MaxNickLength = CLIENT_NICK_LEN_DEFAULT; + Conf_MaxListSize = 100; Conf_PingTimeout = 120; Conf_PongTimeout = 20; @@ -715,7 +754,8 @@ Set_Defaults(bool InitServers) strlcpy(Conf_Chroot, CHROOT_DIR, sizeof(Conf_Chroot)); strcpy(Conf_CloakHost, ""); strcpy(Conf_CloakHostModeX, ""); - strcpy(Conf_CloakHostSalt, ngt_RandomStr(random, RANDOM_SALT_LEN)); + strlcpy(Conf_CloakHostSalt, ngt_RandomStr(random, RANDOM_SALT_LEN), + sizeof(Conf_CloakHostSalt)); Conf_CloakUserToNick = false; Conf_ConnectIPv4 = true; #ifdef WANT_IPV6 @@ -732,6 +772,7 @@ Set_Defaults(bool InitServers) Conf_MorePrivacy = false; Conf_NoticeAuth = false; Conf_OperCanMode = false; + Conf_OperChanPAutoOp = true; Conf_OperServerMode = false; #ifdef PAM Conf_PAM = true; @@ -772,39 +813,44 @@ no_listenports(void) } /** - * Read MOTD ("message of the day") file. + * Read contents of a text file into an array. + * + * This function is used to read the MOTD and help text file, for exampe. * * @param filename Name of the file to read. + * @return true, when the file has been read in. */ -static void -Read_Motd(const char *filename) +static bool +Read_TextFile(const char *Filename, const char *Name, array *Destination) { char line[127]; FILE *fp; + int line_no = 1; - if (*filename == '\0') - return; + if (*Filename == '\0') + return false; - fp = fopen(filename, "r"); + fp = fopen(Filename, "r"); if (!fp) { - Config_Error(LOG_WARNING, "Can't read MOTD file \"%s\": %s", - filename, strerror(errno)); - return; + Config_Error(LOG_ERR, "Can't read %s file \"%s\": %s", + Name, Filename, strerror(errno)); + return false; } - array_free(&Conf_Motd); - Using_MotdFile = true; - + array_free(Destination); while (fgets(line, (int)sizeof line, fp)) { - ngt_TrimLastChr( line, '\n'); + ngt_TrimLastChr(line, '\n'); /* add text including \0 */ - if (!array_catb(&Conf_Motd, line, strlen(line) + 1)) { - Log(LOG_WARNING, "Cannot add MOTD text: %s", strerror(errno)); + if (!array_catb(Destination, line, strlen(line) + 1)) { + Log(LOG_ERR, "Cannot read/add \"%s\", line %d: %s", + Filename, line_no, strerror(errno)); break; } + line_no++; } fclose(fp); + return true; } /** @@ -1025,8 +1071,16 @@ Read_Config(bool TestOnly, bool IsStarting) } /* No MOTD phrase configured? (re)try motd file. */ - if (array_bytes(&Conf_Motd) == 0) - Read_Motd(Conf_MotdFile); + if (array_bytes(&Conf_Motd) == 0) { + if (Read_TextFile(Conf_MotdFile, "MOTD", &Conf_Motd)) + Using_MotdFile = true; + } + + /* Try to read ngIRCd help text file. */ + (void)Read_TextFile(Conf_HelpFile, "help text", &Conf_Helptext); + if (!array_bytes(&Conf_Helptext)) + Config_Error(LOG_WARNING, + "No help text available, HELP command will be of limited use."); #ifdef SSL_SUPPORT /* Make sure that all SSL-related files are readable */ @@ -1063,7 +1117,7 @@ Check_ArgIsTrue(const char *Arg) * * @param Line Line number in configuration file. * @raram Arg Input string. - * @returns New configured maximum nick name length. + * @returns New configured maximum nickname length. */ static unsigned int Handle_MaxNickLength(int Line, const char *Arg) @@ -1180,6 +1234,7 @@ CheckLegacyGlobalOption(int Line, char *Var, char *Arg) || strcasecmp(Var, "ConnectIPv4") == 0 || strcasecmp(Var, "ConnectIPv6") == 0 || strcasecmp(Var, "OperCanUseMode") == 0 + || strcasecmp(Var, "OperChanPAutoOp") == 0 || strcasecmp(Var, "OperServerMode") == 0 || strcasecmp(Var, "PredefChannelsOnly") == 0 || strcasecmp(Var, "SyslogFacility") == 0 @@ -1188,6 +1243,7 @@ CheckLegacyGlobalOption(int Line, char *Var, char *Arg) return "[Options]"; } if (strcasecmp(Var, "ConnectRetry") == 0 + || strcasecmp(Var, "IdleTimeout") == 0 || strcasecmp(Var, "MaxConnections") == 0 || strcasecmp(Var, "MaxConnectionsIP") == 0 || strcasecmp(Var, "MaxJoins") == 0 @@ -1292,6 +1348,12 @@ Handle_GLOBAL( int Line, char *Var, char *Arg ) Config_Error_TooLong(Line, Var); return; } + if (strcasecmp(Var, "HelpFile") == 0) { + len = strlcpy(Conf_HelpFile, Arg, sizeof(Conf_HelpFile)); + if (len >= sizeof(Conf_HelpFile)) + Config_Error_TooLong(Line, Var); + return; + } if (strcasecmp(Var, "Listen") == 0) { if (Conf_ListenAddress) { Config_Error(LOG_ERR, @@ -1431,8 +1493,14 @@ Handle_LIMITS(int Line, char *Var, char *Arg) } return; } + if (strcasecmp(Var, "IdleTimeout") == 0) { + Conf_IdleTimeout = atoi(Arg); + if (!Conf_IdleTimeout && strcmp(Arg, "0")) + Config_Error_NaN(Line, Var); + return; + } if (strcasecmp(Var, "MaxConnections") == 0) { - Conf_MaxConnections = atol(Arg); + Conf_MaxConnections = atoi(Arg); if (!Conf_MaxConnections && strcmp(Arg, "0")) Config_Error_NaN(Line, Var); return; @@ -1453,6 +1521,12 @@ Handle_LIMITS(int Line, char *Var, char *Arg) Conf_MaxNickLength = Handle_MaxNickLength(Line, Arg); return; } + if (strcasecmp(Var, "MaxListSize") == 0) { + Conf_MaxListSize = atoi(Arg); + if (!Conf_MaxListSize && strcmp(Arg, "0")) + Config_Error_NaN(Line, Var); + return; + } if (strcasecmp(Var, "PingTimeout") == 0) { Conf_PingTimeout = atoi(Arg); if (Conf_PingTimeout < 5) { @@ -1555,6 +1629,10 @@ Handle_OPTIONS(int Line, char *Var, char *Arg) Conf_OperCanMode = Check_ArgIsTrue(Arg); return; } + if (strcasecmp(Var, "OperChanPAutoOp") == 0) { + Conf_OperChanPAutoOp = Check_ArgIsTrue(Arg); + return; + } if (strcasecmp(Var, "OperServerMode") == 0) { Conf_OperServerMode = Check_ArgIsTrue(Arg); return; @@ -1911,6 +1989,13 @@ Validate_Config(bool Configtest, bool Rehash) bool config_valid = true; char *ptr; + /* Emit a warning when the config file is not a full path name */ + if (NGIRCd_ConfFile[0] && NGIRCd_ConfFile[0] != '/') { + Config_Error(LOG_WARNING, + "Not specifying a full path name to \"%s\" can cause problems when rehashing the server!", + NGIRCd_ConfFile); + } + /* Validate configured server name, see RFC 2812 section 2.3.1 */ ptr = Conf_ServerName; do {