]> arthur.barton.de Git - ngircd-alex.git/commitdiff
Merge branch 'bug113-SrvPrefix'
authorAlexander Barton <alex@barton.de>
Tue, 9 Aug 2011 08:16:56 +0000 (10:16 +0200)
committerAlexander Barton <alex@barton.de>
Tue, 9 Aug 2011 08:16:56 +0000 (10:16 +0200)
* bug113-SrvPrefix:
  Slightly change (and document!) IRC_KILL() calling convention
  Spoofed prefixes: close connection on non-server links only

src/ngircd/irc-login.c
src/ngircd/irc.c
src/ngircd/parse.c

index 73716fe261d5d5a4942d2d24d02672fcff2f74cd..edaefd61cfc119fbd26de3a26d55eb65bc0146d0 100644 (file)
@@ -1102,20 +1102,22 @@ Hello_User_PostAuth(CLIENT *Client)
  * @param Reason       Reason for the KILL.
  */
 static void
-Kill_Nick( char *Nick, char *Reason )
+Kill_Nick(char *Nick, char *Reason)
 {
        REQUEST r;
 
-       assert( Nick != NULL );
-       assert( Reason != NULL );
+       assert (Nick != NULL);
+       assert (Reason != NULL);
 
-       r.prefix = (char *)Client_ThisServer( );
+       r.prefix = NULL;
        r.argv[0] = Nick;
        r.argv[1] = Reason;
        r.argc = 2;
 
-       Log( LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s", Nick, Reason );
-       IRC_KILL( Client_ThisServer( ), &r );
+       Log(LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s",
+           Nick, Reason);
+
+       IRC_KILL(Client_ThisServer(), &r);
 } /* Kill_Nick */
 
 
index 8dd9bf74f2897b954c337a1f028cdecbf1cdb64f..69dd61a797994886c63bf0426a6d4434192a993c 100644 (file)
@@ -63,13 +63,21 @@ IRC_ERROR( CLIENT *Client, REQUEST *Req )
 
 
 /**
- * Kill client on request.
+ * Handler for the IRC "KILL" command.
+ *
  * This function implements the IRC command "KILL" wich is used to selectively
  * disconnect clients. It can be used by IRC operators and servers, for example
- * to "solve" nick collisions after netsplits.
+ * to "solve" nick collisions after netsplits. See RFC 2812 section 3.7.1.
+ *
  * Please note that this function is also called internally, without a real
  * KILL command being received over the network! Client is Client_ThisServer()
- * in this case. */
+ * in this case, and the prefix in Req is NULL.
+ *
+ * @param Client       The client from which this command has been received
+ *                     or Client_ThisServer() when generated interanlly.
+ * @param Req          Request structure with prefix and all parameters.
+ * @returns            CONNECTED or DISCONNECTED.
+ */
 GLOBAL bool
 IRC_KILL( CLIENT *Client, REQUEST *Req )
 {
@@ -77,55 +85,47 @@ IRC_KILL( CLIENT *Client, REQUEST *Req )
        char reason[COMMAND_LEN], *msg;
        CONN_ID my_conn, conn;
 
-       assert( Client != NULL );
-       assert( Req != NULL );
+       assert (Client != NULL);
+       assert (Req != NULL);
 
-       if(( Client_Type( Client ) != CLIENT_SERVER ) &&
-          ( ! Client_OperByMe( Client )))
-       {
-               /* The originator of the KILL is neither an IRC operator of
-                * this server nor a server. */
-               return IRC_WriteStrClient( Client, ERR_NOPRIVILEGES_MSG,
-                                          Client_ID( Client ));
-       }
+       if (Client_Type(Client) != CLIENT_SERVER && !Client_OperByMe(Client))
+               return IRC_WriteStrClient(Client, ERR_NOPRIVILEGES_MSG,
+                                         Client_ID(Client));
 
-       if( Req->argc != 2 )
-       {
-               /* This command requires exactly 2 parameters! */
-               return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG,
-                                          Client_ID( Client ), Req->command );
-       }
+       if (Req->argc != 2)
+               return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+                                         Client_ID(Client), Req->command);
 
-       if( Req->prefix ) prefix = Client_Search( Req->prefix );
-       else prefix = Client;
-       if( ! prefix )
-       {
-               Log( LOG_WARNING, "Got KILL with invalid prefix: \"%s\"!",
-                    Req->prefix );
-               prefix = Client_ThisServer( );
+       /* Get prefix (origin); use the client if no prefix is given. */
+       if (Req->prefix)
+               prefix = Client_Search(Req->prefix);
+       else
+               prefix = Client;
+
+       /* Log a warning message and use this server as origin when the
+        * prefix (origin) is invalid. */
+       if (!prefix) {
+               Log(LOG_WARNING, "Got KILL with invalid prefix: \"%s\"!",
+                   Req->prefix );
+               prefix = Client_ThisServer();
        }
 
-       if( Client != Client_ThisServer( ))
-       {
-               /* This is a "real" KILL received from the network. */
-               Log( LOG_NOTICE|LOG_snotice, "Got KILL command from \"%s\" for \"%s\": %s",
-                    Client_Mask( prefix ), Req->argv[0], Req->argv[1] );
-       }
+       if (Client != Client_ThisServer())
+               Log(LOG_NOTICE|LOG_snotice,
+                   "Got KILL command from \"%s\" for \"%s\": %s",
+                   Client_Mask(prefix), Req->argv[0], Req->argv[1]);
 
-       /* Build reason string */
-       if( Client_Type( Client ) == CLIENT_USER )
-       {
-               /* Prefix the "reason" if the originator is a regular user,
-                * so users can't spoof KILLs of servers. */
-               snprintf( reason, sizeof( reason ), "KILLed by %s: %s",
-                         Client_ID( Client ), Req->argv[1] );
-       }
+       /* Build reason string: Prefix the "reason" if the originator is a
+        * regular user, so users can't spoof KILLs of servers. */
+       if (Client_Type(Client) == CLIENT_USER)
+               snprintf(reason, sizeof(reason), "KILLed by %s: %s",
+                        Client_ID(Client), Req->argv[1]);
        else
-               strlcpy( reason, Req->argv[1], sizeof( reason ));
+               strlcpy(reason, Req->argv[1], sizeof(reason));
 
        /* Inform other servers */
-       IRC_WriteStrServersPrefix( Client, prefix, "KILL %s :%s",
-                                  Req->argv[0], reason );
+       IRC_WriteStrServersPrefix(Client, prefix, "KILL %s :%s",
+                                 Req->argv[0], reason);
 
        /* Save ID of this connection */
        my_conn = Client_Conn( Client );
index 72e3430998b301d4011b9b55175e1a91d41875a6..be3c864dc26f0683e5d39a6a6254ba4f84bdeab8 100644 (file)
@@ -325,13 +325,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;