#include <dirent.h>
#include <netdb.h>
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
#include "ngircd.h"
#include "conn.h"
#include "channel.h"
free(Conf_SSLOptions.CertFile);
Conf_SSLOptions.CertFile = NULL;
+ free(Conf_SSLOptions.CAFile);
+ Conf_SSLOptions.CAFile = NULL;
+
+ free(Conf_SSLOptions.CRLFile);
+ Conf_SSLOptions.CRLFile = NULL;
+
free(Conf_SSLOptions.DHFile);
Conf_SSLOptions.DHFile = NULL;
array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
#ifdef SSL_SUPPORT
puts("[SSL]");
+ printf(" CAFile = %s\n", Conf_SSLOptions.CAFile
+ ? Conf_SSLOptions.CAFile : "");
printf(" CertFile = %s\n", Conf_SSLOptions.CertFile
? Conf_SSLOptions.CertFile : "");
printf(" CipherList = %s\n", Conf_SSLOptions.CipherList ?
Conf_SSLOptions.CipherList : DEFAULT_CIPHERS);
+ printf(" CRLFile = %s\n", Conf_SSLOptions.CRLFile
+ ? Conf_SSLOptions.CRLFile : "");
printf(" DHFile = %s\n", Conf_SSLOptions.DHFile
? Conf_SSLOptions.DHFile : "");
printf(" KeyFile = %s\n", Conf_SSLOptions.KeyFile
printf( " Host = %s\n", Conf_Server[i].host );
printf( " Port = %u\n", (unsigned int)Conf_Server[i].port );
#ifdef SSL_SUPPORT
- printf( " SSLConnect = %s\n", yesno_to_str(Conf_Server[i].SSLConnect));
+ printf(" SSLConnect = %s\n",
+ yesno_to_str(Conf_Server[i].SSLConnect));
+ printf(" SSLVerify = %s\n",
+ yesno_to_str(Conf_Server[i].SSLVerify));
#endif
printf( " MyPassword = %s\n", Conf_Server[i].pwd_in );
printf( " PeerPassword = %s\n", Conf_Server[i].pwd_out );
struct dirent *entry;
int i, n;
FILE *fd;
- DIR *dh;
+ DIR *dh = NULL;
+
+ if (!NGIRCd_ConfFile[0]) {
+ /* No configuration file name explicitly given on the command
+ * line, use defaults but ignore errors when this file can't be
+ * read later on. */
+ strlcpy(file, SYSCONFDIR, sizeof(file));
+ strlcat(file, CONFIG_FILE, sizeof(file));
+ ptr = file;
+ } else
+ ptr = NGIRCd_ConfFile;
- Config_Error(LOG_INFO, "Using configuration file \"%s\" ...", NGIRCd_ConfFile);
+ Config_Error(LOG_INFO, "Using %s configuration file \"%s\" ...",
+ !NGIRCd_ConfFile[0] ? "default" : "specified", ptr);
/* Open configuration file */
- fd = fopen( NGIRCd_ConfFile, "r" );
- if( ! fd ) {
- /* No configuration file found! */
- Config_Error( LOG_ALERT, "Can't read configuration \"%s\": %s",
- NGIRCd_ConfFile, strerror( errno ));
- if (!IsStarting)
- return false;
- Config_Error( LOG_ALERT, "%s exiting due to fatal errors!", PACKAGE_NAME );
- exit( 1 );
+ fd = fopen(ptr, "r");
+ if (!fd) {
+ if (NGIRCd_ConfFile[0]) {
+ Config_Error(LOG_ALERT,
+ "Can't read specified configuration file \"%s\": %s",
+ ptr, strerror(errno));
+ if (IsStarting) {
+ Config_Error(LOG_ALERT,
+ "%s exiting due to fatal errors!",
+ PACKAGE_NAME);
+ exit(1);
+ }
+ }
+ Config_Error(LOG_WARNING,
+ "Can't read default configuration file \"%s\": %s - Ignored.",
+ ptr, strerror(errno));
}
opers_free();
Set_Defaults(IsStarting);
- if (TestOnly)
+ if (TestOnly && fd)
Config_Error(LOG_INFO,
- "Reading configuration from \"%s\" ...",
- NGIRCd_ConfFile );
+ "Reading configuration from \"%s\" ...", ptr);
/* Clean up server configuration structure: mark all already
* configured servers as "once" so that they are deleted
ConfSSL_Init();
#endif
- Read_Config_File(NGIRCd_ConfFile, fd);
- fclose(fd);
+ if (fd) {
+ Read_Config_File(ptr, fd);
+ fclose(fd);
+ }
if (Conf_IncludeDir[0]) {
+ /* Include directory was set in the main configuration file. So
+ * use it and show errors. */
dh = opendir(Conf_IncludeDir);
if (!dh)
Config_Error(LOG_ALERT,
"Can't open include directory \"%s\": %s",
Conf_IncludeDir, strerror(errno));
- } else {
+ } else if (!NGIRCd_ConfFile[0]) {
+ /* No include dir set in the configuration file used (if any)
+ * but no config file explicitly specified either: so use the
+ * default include path here as well! */
strlcpy(Conf_IncludeDir, SYSCONFDIR, sizeof(Conf_IncludeDir));
strlcat(Conf_IncludeDir, CONFIG_DIR, sizeof(Conf_IncludeDir));
dh = opendir(Conf_IncludeDir);
Conf_SSLOptions.CipherList = strdup_warn(Arg);
return;
}
+ if (strcasecmp(Var, "CAFile") == 0) {
+ assert(Conf_SSLOptions.CAFile == NULL);
+ Conf_SSLOptions.CAFile = strdup_warn(Arg);
+ return;
+ }
+ if (strcasecmp(Var, "CRLFile") == 0) {
+ assert(Conf_SSLOptions.CRLFile == NULL);
+ Conf_SSLOptions.CRLFile = strdup_warn(Arg);
+ return;
+ }
Config_Error_Section(File, Line, Var, "SSL");
}
if( strcasecmp( Var, "SSLConnect" ) == 0 ) {
New_Server.SSLConnect = Check_ArgIsTrue(Arg);
return;
- }
+ }
+ if (strcasecmp(Var, "SSLVerify") == 0) {
+ New_Server.SSLVerify = Check_ArgIsTrue(Arg);
+ return;
+ }
#endif
if( strcasecmp( Var, "Group" ) == 0 ) {
/* Server group */
struct hostent *h;
bool config_valid = true;
char *ptr;
+#ifdef HAVE_SETRLIMIT
+ struct rlimit rlim;
+ long fd_lim_old;
+#endif
/* Emit a warning when the config file is not a full path name */
if (NGIRCd_ConfFile[0] && NGIRCd_ConfFile[0] != '/') {
if (!Conf_ServerName[0] || !strchr(Conf_ServerName, '.')) {
config_valid = false;
Config_Error(LOG_ALERT,
- "No (valid) server name configured in \"%s\" (section 'Global': 'Name')!",
- NGIRCd_ConfFile);
+ "No (valid) server name configured (section 'Global': 'Name')!");
if (!Configtest && !Rehash) {
Config_Error(LOG_ALERT,
"%s exiting due to fatal errors!",
/* No administrative contact configured! */
config_valid = false;
Config_Error(LOG_ALERT,
- "No administrator email address configured in \"%s\" ('AdminEMail')!",
- NGIRCd_ConfFile);
+ "No administrator email address configured ('AdminEMail')!");
if (!Configtest) {
Config_Error(LOG_ALERT,
"%s exiting due to fatal errors!",
"Maximum penalty increase ('MaxPenaltyTime') is set to %ld, this is not recommended!",
Conf_MaxPenaltyTime);
+#ifdef HAVE_SETRLIMIT
+ if(getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
+ LogDebug("Current file descriptor limit is %ld, maximum %ld. \"MaxConnections\" is %ld.",
+ (long)rlim.rlim_cur, (long)rlim.rlim_max,
+ Conf_MaxConnections);
+ fd_lim_old = rlim.rlim_cur;
+ /* Don't request "infinite" file descriptors, use a limit! */
+ if (rlim.rlim_max != RLIM_INFINITY && rlim.rlim_max < MAX_FD_LIMIT)
+ rlim.rlim_cur = rlim.rlim_max;
+ else
+ rlim.rlim_cur = MAX_FD_LIMIT;
+ if ((long)rlim.rlim_cur != fd_lim_old) {
+ /* Try to adjust the current file descriptor limit: */
+ LogDebug("Trying to upgrade \"soft\" file descriptor limit: %ld -> %ld ...",
+ fd_lim_old, (long)rlim.rlim_cur);
+ if(setrlimit(RLIMIT_NOFILE, &rlim) != 0)
+ Config_Error(LOG_ERR, "Failed to adjust file descriptor limit from %ld to %ld: %s",
+ fd_lim_old, (long)rlim.rlim_cur,
+ strerror(errno));
+ }
+ /* Check the (updated?) file descriptor limit: */
+ getrlimit(RLIMIT_NOFILE, &rlim);
+ if (rlim.rlim_cur != RLIM_INFINITY
+ && (long)rlim.rlim_cur <= (long)Conf_MaxConnections) {
+ Config_Error(LOG_WARNING,
+ "Current file descriptor limit (%ld) is not higher than configured \"MaxConnections\" (%ld)!",
+ (long)rlim.rlim_cur, Conf_MaxConnections);
+ } else if (!Configtest) {
+ if (Conf_MaxConnections > 0)
+ Log(LOG_INFO,
+ "File descriptor limit is %ld; \"MaxConnections\" is set to %ld.",
+ (long)rlim.rlim_cur, Conf_MaxConnections);
+ else
+ Log(LOG_INFO,
+ "File descriptor limit is %ld; \"MaxConnections\" is not set.",
+ (long)rlim.rlim_cur);
+ }
+ } else
+ Config_Error(LOG_ERR, "Failed to get file descriptor limit: %s",
+ strerror(errno));
+#endif
+
servers = servers_once = 0;
for (i = 0; i < MAX_SERVERS; i++) {
if (Conf_Server[i].name[0]) {
Proc_InitStruct(&Server->res_stat);
Server->conn_id = NONE;
memset(&Server->bind_addr, 0, sizeof(Server->bind_addr));
+
+#ifdef SSL_SUPPORT
+ /* Verify SSL connections by default! */
+ Server->SSLVerify = true;
+#endif
}
/* -eof- */