]> arthur.barton.de Git - ngircd-alex.git/blobdiff - src/ngircd/parse.c
Include CAP command even when using "strict RFC mode"
[ngircd-alex.git] / src / ngircd / parse.c
index c2603918ff430643d045d8e5d95bdfcca43eec8f..e9c5d53a3f584bc2fda3a13cc5625e63ca37e3c7 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "imp.h"
 #include "irc.h"
+#include "irc-cap.h"
 #include "irc-channel.h"
 #include "irc-info.h"
 #include "irc-login.h"
@@ -47,6 +48,7 @@
 #include "numeric.h"
 
 #include "exp.h"
+#include "conf.h"
 
 struct _NUMERIC {
        int numeric;
@@ -58,10 +60,12 @@ static COMMAND My_Commands[] =
 {
        { "ADMIN", IRC_ADMIN, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "AWAY", IRC_AWAY, CLIENT_USER, 0, 0, 0 },
+       { "CAP", IRC_CAP, 0xFFFF, 0, 0, 0 },
        { "CONNECT", IRC_CONNECT, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "DIE", IRC_DIE, CLIENT_USER, 0, 0, 0 },
        { "DISCONNECT", IRC_DISCONNECT, CLIENT_USER, 0, 0, 0 },
        { "ERROR", IRC_ERROR, 0xFFFF, 0, 0, 0 },
+       { "GLINE", IRC_xLINE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "HELP", IRC_HELP, CLIENT_USER, 0, 0, 0 },
        { "INFO", IRC_INFO, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "INVITE", IRC_INVITE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
@@ -69,6 +73,7 @@ static COMMAND My_Commands[] =
        { "JOIN", IRC_JOIN, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "KICK", IRC_KICK, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "KILL", IRC_KILL, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
+       { "KLINE", IRC_xLINE, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "LINKS", IRC_LINKS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "LIST", IRC_LIST, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "LUSERS", IRC_LUSERS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
@@ -106,9 +111,11 @@ static COMMAND My_Commands[] =
        { "WHO", IRC_WHO, CLIENT_USER, 0, 0, 0 },
        { "WHOIS", IRC_WHOIS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
        { "WHOWAS", IRC_WHOWAS, CLIENT_USER|CLIENT_SERVER, 0, 0, 0 },
+
 #ifdef IRCPLUS
        { "CHANINFO", IRC_CHANINFO, CLIENT_SERVER, 0, 0, 0 },
 #endif
+
 #ifndef STRICT_RFC
        { "GET",  IRC_QUIT_HTTP, CLIENT_UNKNOWN, 0, 0, 0 },
        { "POST", IRC_QUIT_HTTP, CLIENT_UNKNOWN, 0, 0, 0 },
@@ -124,6 +131,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 +183,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, ' ' );
@@ -320,13 +331,21 @@ Validate_Prefix( CONN_ID Idx, REQUEST *Req, bool *Closed )
        /* check if the client named in the prefix is expected
         * to come from that direction */
        if (Client_NextHop(c) != client) {
-               Log(LOG_ERR,
-                   "Spoofed prefix \"%s\" from \"%s\" (connection %d, command \"%s\")!",
-                   Req->prefix, Client_Mask(Conn_GetClient(Idx)), Idx,
-                   Req->command);
-               Conn_Close(Idx, NULL, "Spoofed prefix", true);
-               *Closed = true;
+               if (Client_Type(c) != CLIENT_SERVER) {
+                       Log(LOG_ERR,
+                           "Spoofed prefix \"%s\" from \"%s\" (connection %d, command \"%s\")!",
+                           Req->prefix, Client_Mask(Conn_GetClient(Idx)), Idx,
+                           Req->command);
+                       Conn_Close(Idx, NULL, "Spoofed prefix", true);
+                       *Closed = true;
+               } else {
+                       Log(LOG_INFO,
+                           "Ignoring spoofed prefix \"%s\" from \"%s\" (connection %d, command \"%s\").",
+                           Req->prefix, Client_Mask(Conn_GetClient(Idx)), Idx,
+                           Req->command);
+               }
                return false;
+
        }
 
        return true;
@@ -459,7 +478,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 +543,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- */