Implement user mode 'C': require "same channel" to send message
authorAlexander Barton <alex@barton.de>
Mon, 16 Jan 2012 10:43:22 +0000 (11:43 +0100)
committerAlexander Barton <alex@barton.de>
Mon, 16 Jan 2012 10:43:22 +0000 (11:43 +0100)
If the target user of a PRIVMSG or NOTICE command has the user mode 'C'
set, it is required that both sender and receiver are on the same channel.

This prevents private flooding by completely unknown clients.

doc/Modes.txt
src/ngircd/defines.h
src/ngircd/irc-mode.c
src/ngircd/irc.c
src/ngircd/messages.h

index 20e927b6e681a9743b9ae0854001cdca2959556e..0b0e488f46b212a306ec7ba01e694bf87575fe22 100644 (file)
@@ -23,6 +23,7 @@ channels he is using at the moment.
 
   a    0.3.0   User is away.
   c    17      IRC operator wants to receive connect/disconnect NOTICEs.
+  C    19      Only users that share a channel are allowed to send messages.
   i    0.0.1   User is "invisible".
   o    0.0.1   User is IRC operator.
   r    0.0.1   User is restricted.
index e7a14ef88959069a67f7ecb8f53c7c03c5b2071f..9dc5e92d4f4ec074247bd9f2741a8e4431b3b79f 100644 (file)
 #endif
 
 /** Supported user modes. */
-#define USERMODES "aciorRswx"
+#define USERMODES "acCiorRswx"
 
 /** Supported channel modes. */
 #define CHANMODES "biIklmnoOPRstvz"
index c85faa04d626f42569fe83c2a7e852bdeb768062..3dd61e7ca2031ad6727c64579da300b86cd9a038 100644 (file)
@@ -214,6 +214,7 @@ Client_Mode( CLIENT *Client, REQUEST *Req, CLIENT *Origin, CLIENT *Target )
                /* Validate modes */
                x[0] = '\0';
                switch (*mode_ptr) {
+               case 'C': /* Only messages from clients sharing a channel */
                case 'i': /* Invisible */
                case 's': /* Server messages */
                case 'w': /* Wallops messages */
index 10e3e45656bdb1cc996ef0d92ad2c0a1cd8fab2f..2b94e33ac229b44cf509277c23944034bebf5a51 100644 (file)
@@ -349,6 +349,7 @@ static bool
 Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
 {
        CLIENT *cl, *from;
+       CL2CHAN *cl2chan;
        CHANNEL *chan;
        char *currentTarget = Req->argv[0];
        char *lastCurrentTarget = NULL;
@@ -485,6 +486,23 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
                        }
 #endif
 
+                       if (Client_HasMode(cl, 'C')) {
+                               cl2chan = Channel_FirstChannelOf(cl);
+                               while (cl2chan) {
+                                       chan = Channel_GetChannel(cl2chan);
+                                       if (Channel_IsMemberOf(chan, from))
+                                               break;
+                                       cl2chan = Channel_NextChannelOf(cl, cl2chan);
+                               }
+                               if (!cl2chan) {
+                                       if (SendErrors && !IRC_WriteStrClient(
+                                           from, ERR_NOTONSAMECHANNEL_MSG,
+                                           Client_ID(from), Client_ID(cl)))
+                                               return DISCONNECTED;
+                                       goto send_next_target;
+                               }
+                       }
+
                        if (SendErrors && (Client_Type(Client) != CLIENT_SERVER)
                            && strchr(Client_Modes(cl), 'a')) {
                                /* Target is away */
@@ -522,6 +540,7 @@ Send_Message(CLIENT * Client, REQUEST * Req, int ForceType, bool SendErrors)
                                return DISCONNECTED;
                }
 
+       send_next_target:
                currentTarget = strtok_r(NULL, ",", &lastCurrentTarget);
                if (currentTarget)
                        Conn_SetPenalty(Client_Conn(Client), 1);
index 0070e70159f46bd533624e953225854e23975812..6a784fe9eb97a98ebc8194bee63232e7893f6c82 100644 (file)
 #define ERR_CANTKILLSERVER_MSG         "483 %s :You can't kill a server!"
 #define ERR_RESTRICTED_MSG             "484 %s :Your connection is restricted"
 #define ERR_NOOPERHOST_MSG             "491 %s :Not configured for your host"
+#define ERR_NOTONSAMECHANNEL_MSG       "493 %s :You must share a common channel with %s"
 
 #define ERR_UMODEUNKNOWNFLAG_MSG       "501 %s :Unknown mode"
 #define ERR_UMODEUNKNOWNFLAG2_MSG      "501 %s :Unknown mode \"%c%c\""