about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ngircd/conf.c148
-rw-r--r--src/ngircd/conf.h9
-rw-r--r--src/ngircd/parse.c45
3 files changed, 148 insertions, 54 deletions
diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c
index c9479972..4991918d 100644
--- a/src/ngircd/conf.c
+++ b/src/ngircd/conf.c
@@ -89,6 +89,8 @@ static void Init_Server_Struct PARAMS(( CONF_SERVER *Server ));
 
 #ifdef SSL_SUPPORT
 
+static void Handle_SSL PARAMS(( int Line, char *Var, char *Ark ));
+
 struct SSLOptions Conf_SSLOptions;
 
 /**
@@ -121,6 +123,9 @@ CheckFileReadable(const char *Var, const char *Filename)
 {
 	FILE *fp;
 
+	if (!Filename)
+		return;
+
 	fp = fopen(Filename, "r");
 	if (fp)
 		fclose(fp);
@@ -375,18 +380,7 @@ Conf_Test( void )
 #ifndef STRICT_RFC
 	printf("  RequireAuthPing = %s\n", yesno_to_str(Conf_AuthPing));
 #endif
-#ifdef SSL_SUPPORT
-	printf("  SSLCertFile = %s\n", Conf_SSLOptions.CertFile);
-	printf("  SSLDHFile = %s\n", Conf_SSLOptions.DHFile);
-	printf("  SSLKeyFile = %s\n", Conf_SSLOptions.KeyFile);
-	if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
-		puts("  SSLKeyFilePassword = <secret>");
-	else
-		puts("  SSLKeyFilePassword = ");
-	array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
-	printf("  SSLPorts = ");
-	ports_puts(&Conf_SSLOptions.ListenPorts);
-#endif
+	printf("  ScrubCTCP = %s\n", yesno_to_str(Conf_ScrubCTCP));
 #ifdef SYSLOG
 	printf("  SyslogFacility = %s\n",
 	       ngt_SyslogFacilityName(Conf_SyslogFacility));
@@ -394,6 +388,24 @@ Conf_Test( void )
 	printf("  WebircPassword = %s\n", Conf_WebircPwd);
 	puts("");
 
+#ifdef SSL_SUPPORT
+	puts("[SSL]");
+	printf("  CertFile = %s\n", Conf_SSLOptions.CertFile
+					? Conf_SSLOptions.CertFile : "");
+	printf("  DHFile = %s\n", Conf_SSLOptions.DHFile
+					? Conf_SSLOptions.DHFile : "");
+	printf("  KeyFile = %s\n", Conf_SSLOptions.KeyFile
+					? Conf_SSLOptions.KeyFile : "");
+	if (array_bytes(&Conf_SSLOptions.KeyFilePassword))
+		puts("  KeyFilePassword = <secret>");
+	else
+		puts("  KeyFilePassword = ");
+	array_free_wipe(&Conf_SSLOptions.KeyFilePassword);
+	printf("  Ports = ");
+	ports_puts(&Conf_SSLOptions.ListenPorts);
+	puts("");
+#endif
+
 	opers_puts();
 
 	for( i = 0; i < MAX_SERVERS; i++ ) {
@@ -689,6 +701,7 @@ Set_Defaults(bool InitServers)
 #endif
 	Conf_PredefChannelsOnly = false;
 #ifdef SYSLOG
+	Conf_ScrubCTCP = false;
 #ifdef LOG_LOCAL5
 	Conf_SyslogFacility = LOG_LOCAL5;
 #else
@@ -846,7 +859,8 @@ Read_Config( bool ngircd_starting )
 			strlcpy( section, str, sizeof( section ));
 			if (strcasecmp(section, "[GLOBAL]") == 0 ||
 			    strcasecmp(section, "[LIMITS]") == 0 ||
-			    strcasecmp(section, "[OPTIONS]") == 0)
+			    strcasecmp(section, "[OPTIONS]") == 0 ||
+			    strcasecmp(section, "[SSL]") == 0)
 				continue;
 
 			if( strcasecmp( section, "[SERVER]" ) == 0 ) {
@@ -905,6 +919,10 @@ Read_Config( bool ngircd_starting )
 			Handle_LIMITS(line, var, arg);
 		else if(strcasecmp(section, "[OPTIONS]") == 0)
 			Handle_OPTIONS(line, var, arg);
+#ifdef SSL_SUPPORT
+		else if(strcasecmp(section, "[SSL]") == 0)
+			Handle_SSL(line, var, arg);
+#endif
 		else if(strcasecmp(section, "[OPERATOR]") == 0)
 			Handle_OPERATOR(line, var, arg);
 		else if(strcasecmp(section, "[SERVER]") == 0)
@@ -951,9 +969,9 @@ Read_Config( bool ngircd_starting )
 
 #ifdef SSL_SUPPORT
 	/* Make sure that all SSL-related files are readable */
-	CheckFileReadable("SSLCertFile", Conf_SSLOptions.CertFile);
-	CheckFileReadable("SSLDHFile", Conf_SSLOptions.DHFile);
-	CheckFileReadable("SSLKeyFile", Conf_SSLOptions.KeyFile);
+	CheckFileReadable("CertFile", Conf_SSLOptions.CertFile);
+	CheckFileReadable("DHFile", Conf_SSLOptions.DHFile);
+	CheckFileReadable("KeyFile", Conf_SSLOptions.KeyFile);
 #endif
 
 	return true;
@@ -1099,13 +1117,6 @@ CheckLegacyGlobalOption(int Line, char *Var, char *Arg)
 	    || strcasecmp(Var, "OperCanUseMode") == 0
 	    || strcasecmp(Var, "OperServerMode") == 0
 	    || strcasecmp(Var, "PredefChannelsOnly") == 0
-#ifdef SSL_SUPPORT
-	    || strcasecmp(Var, "SSLCertFile") == 0
-	    || strcasecmp(Var, "SSLDHFile") == 0
-	    || strcasecmp(Var, "SSLKeyFile") == 0
-	    || strcasecmp(Var, "SSLKeyFilePassword") == 0
-	    || strcasecmp(Var, "SSLPorts") == 0
-#endif
 	    || strcasecmp(Var, "SyslogFacility") == 0
 	    || strcasecmp(Var, "WebircPassword") == 0) {
 		Handle_OPTIONS(Line, Var, Arg);
@@ -1121,6 +1132,16 @@ CheckLegacyGlobalOption(int Line, char *Var, char *Arg)
 		Handle_LIMITS(Line, Var, Arg);
 		return "[Limits]";
 	}
+#ifdef SSL_SUPPORT
+	if (strcasecmp(Var, "SSLCertFile") == 0
+	    || strcasecmp(Var, "SSLDHFile") == 0
+	    || strcasecmp(Var, "SSLKeyFile") == 0
+	    || strcasecmp(Var, "SSLKeyFilePassword") == 0
+	    || strcasecmp(Var, "SSLPorts") == 0) {
+		Handle_SSL(Line, Var + 3, Arg);
+		return "[SSL]";
+	}
+#endif
 
 	return NULL;
 }
@@ -1301,9 +1322,16 @@ Handle_GLOBAL( int Line, char *Var, char *Arg )
 		/** TODO: This function and support for these options in the
 		 * [Global] section could be removed starting with ngIRCd
 		 * release 19 (one release after marking it "deprecated"). */
-		Config_Error(LOG_WARNING,
-			     "%s, line %d (section \"Global\"): \"%s\" is deprecated here, move it to %s!",
-			     NGIRCd_ConfFile, Line, Var, section);
+		if (strncasecmp(Var, "SSL", 3) == 0) {
+			Config_Error(LOG_WARNING,
+				     "%s, line %d (section \"Global\"): \"%s\" is deprecated here, move it to %s and rename to \"%s\"!",
+				     NGIRCd_ConfFile, Line, Var, section,
+				     Var + 3);
+		} else {
+			Config_Error(LOG_WARNING,
+				     "%s, line %d (section \"Global\"): \"%s\" is deprecated here, move it to %s!",
+				     NGIRCd_ConfFile, Line, Var, section);
+		}
 		return;
 	}
 
@@ -1465,53 +1493,77 @@ Handle_OPTIONS(int Line, char *Var, char *Arg)
 		return;
 	}
 #endif
+	if (strcasecmp(Var, "ScrubCTCP") == 0) {
+		Conf_ScrubCTCP = Check_ArgIsTrue(Arg);
+		return;
+	}
+#ifdef SYSLOG
+	if (strcasecmp(Var, "SyslogFacility") == 0) {
+		Conf_SyslogFacility = ngt_SyslogFacilityID(Arg,
+							   Conf_SyslogFacility);
+		return;
+	}
+#endif
+	if (strcasecmp(Var, "WebircPassword") == 0) {
+		len = strlcpy(Conf_WebircPwd, Arg, sizeof(Conf_WebircPwd));
+		if (len >= sizeof(Conf_WebircPwd))
+			Config_Error_TooLong(Line, Var);
+		return;
+	}
+
+	Config_Error_Section(Line, Var, "Options");
+}
+
 #ifdef SSL_SUPPORT
-	if (strcasecmp(Var, "SSLCertFile") == 0) {
+
+/**
+ * Handle variable in [SSL] configuration section.
+ *
+ * @param Line	Line numer in configuration file.
+ * @param Var	Variable name.
+ * @param Arg	Variable argument.
+ */
+static void
+Handle_SSL(int Line, char *Var, char *Arg)
+{
+	assert(Line > 0);
+	assert(Var != NULL);
+	assert(Arg != NULL);
+
+	if (strcasecmp(Var, "CertFile") == 0) {
 		assert(Conf_SSLOptions.CertFile == NULL);
 		Conf_SSLOptions.CertFile = strdup_warn(Arg);
 		return;
 	}
-	if (strcasecmp(Var, "SSLDHFile") == 0) {
+	if (strcasecmp(Var, "DHFile") == 0) {
 		assert(Conf_SSLOptions.DHFile == NULL);
 		Conf_SSLOptions.DHFile = strdup_warn(Arg);
 		return;
 	}
-	if (strcasecmp(Var, "SSLKeyFile") == 0) {
+	if (strcasecmp(Var, "KeyFile") == 0) {
 		assert(Conf_SSLOptions.KeyFile == NULL);
 		Conf_SSLOptions.KeyFile = strdup_warn(Arg);
 		return;
 	}
-	if (strcasecmp(Var, "SSLKeyFilePassword") == 0) {
+	if (strcasecmp(Var, "KeyFilePassword") == 0) {
 		assert(array_bytes(&Conf_SSLOptions.KeyFilePassword) == 0);
 		if (!array_copys(&Conf_SSLOptions.KeyFilePassword, Arg))
 			Config_Error(LOG_ERR,
-				     "%s, line %d (section \"Global\"): Could not copy %s: %s!",
+				     "%s, line %d (section \"SSL\"): Could not copy %s: %s!",
 				     NGIRCd_ConfFile, Line, Var,
 				     strerror(errno));
 		return;
 	}
-	if (strcasecmp(Var, "SSLPorts") == 0) {
+	if (strcasecmp(Var, "Ports") == 0) {
 		ports_parse(&Conf_SSLOptions.ListenPorts, Line, Arg);
 		return;
 	}
-#endif
-#ifdef SYSLOG
-	if (strcasecmp(Var, "SyslogFacility") == 0) {
-		Conf_SyslogFacility = ngt_SyslogFacilityID(Arg,
-							   Conf_SyslogFacility);
-		return;
-	}
-#endif
-	if (strcasecmp(Var, "WebircPassword") == 0) {
-		len = strlcpy(Conf_WebircPwd, Arg, sizeof(Conf_WebircPwd));
-		if (len >= sizeof(Conf_WebircPwd))
-			Config_Error_TooLong(Line, Var);
-		return;
-	}
 
-	Config_Error_Section(Line, Var, "Options");
+	Config_Error_Section(Line, Var, "SSL");
 }
 
+#endif
+
 /**
  * Handle variable in [Operator] configuration section.
  *
@@ -1848,7 +1900,7 @@ Validate_Config(bool Configtest, bool Rehash)
 #ifdef PAM
 	if (Conf_ServerPwd[0])
 		Config_Error(LOG_ERR,
-			     "This server uses PAM, \"Password\" will be ignored!");
+			     "This server uses PAM, \"Password\" in [Global] section will be ignored!");
 #endif
 
 #ifdef DEBUG
diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h
index c2af692a..afc0afaa 100644
--- a/src/ngircd/conf.h
+++ b/src/ngircd/conf.h
@@ -175,15 +175,18 @@ GLOBAL bool Conf_DNS;
 /** Enable IDENT lookups, even when compiled with support for it */
 GLOBAL bool Conf_Ident;
 
-/** Enable all usage of PAM, even when compiled with support for it */
-GLOBAL bool Conf_PAM;
-
 /** Enable "more privacy" mode and "censor" some user-related information */
 GLOBAL bool Conf_MorePrivacy;
 
 /** Enable NOTICE AUTH messages on connect */
 GLOBAL bool Conf_NoticeAuth;
 
+/** Enable all usage of PAM, even when compiled with support for it */
+GLOBAL bool Conf_PAM;
+
+/** Disable all CTCP commands except for /me ? */
+GLOBAL bool Conf_ScrubCTCP;
+
 /*
  * try to connect to remote systems using the ipv6 protocol,
  * if they have an ipv6 address? (default yes)
diff --git a/src/ngircd/parse.c b/src/ngircd/parse.c
index c2603918..72e34309 100644
--- a/src/ngircd/parse.c
+++ b/src/ngircd/parse.c
@@ -47,6 +47,7 @@
 #include "numeric.h"
 
 #include "exp.h"
+#include "conf.h"
 
 struct _NUMERIC {
 	int numeric;
@@ -124,6 +125,8 @@ static bool Validate_Args PARAMS(( CONN_ID Idx, REQUEST *Req, bool *Closed ));
 
 static bool Handle_Request PARAMS(( CONN_ID Idx, REQUEST *Req ));
 
+static bool ScrubCTCP PARAMS((char *Request));
+
 /**
  * Return the pointer to the global "IRC command structure".
  * This structure, an array of type "COMMAND" describes all the IRC commands
@@ -174,8 +177,10 @@ Parse_Request( CONN_ID Idx, char *Request )
 	/* remove leading & trailing whitespace */
 	ngt_TrimStr( Request );
 
-	if( Request[0] == ':' )
-	{
+	if (Conf_ScrubCTCP && ScrubCTCP(Request))
+		return true;
+
+	if (Request[0] == ':') {
 		/* Prefix */
 		req.prefix = Request + 1;
 		ptr = strchr( Request, ' ' );
@@ -459,7 +464,6 @@ Handle_Numeric(CLIENT *client, REQUEST *Req)
 	return IRC_WriteStrClientPrefix(target, prefix, "%s", str);
 }
 
-
 static bool
 Handle_Request( CONN_ID Idx, REQUEST *Req )
 {
@@ -525,4 +529,39 @@ Handle_Request( CONN_ID Idx, REQUEST *Req )
 } /* Handle_Request */
 
 
+/**
+ * Check if incoming messages contains CTCP commands and should be dropped.
+ *
+ * @param Request NULL terminated incoming command.
+ * @returns true, when the message should be dropped.
+ */
+static bool
+ScrubCTCP(char *Request)
+{
+	static const char me_cmd[] = "ACTION ";
+	static const char ctcp_char = 0x1;
+	bool dropCommand = false;
+	char *ptr = Request;
+	char *ptrEnd = strchr(Request, '\0');
+
+	if (Request[0] == ':' && ptrEnd > ptr)
+		ptr++;
+
+	while (ptr != ptrEnd && *ptr != ':')
+		ptr++;
+
+	if ((ptrEnd - ptr) > 1) {
+		ptr++;
+		if (*ptr == ctcp_char) {
+			dropCommand = true;
+			ptr++;
+			/* allow /me commands */
+			if ((size_t)(ptrEnd - ptr) >= strlen(me_cmd)
+			    && !strncmp(ptr, me_cmd, strlen(me_cmd)))
+				dropCommand = false;
+		}
+	}
+	return dropCommand;
+}
+
 /* -eof- */