commit - 641045249cb4c11244b772012dc5b36005c89517
commit + d9325e803010d9a305182a4216bfbde168094dfa
blob - 73716fe261d5d5a4942d2d24d02672fcff2f74cd
blob + edaefd61cfc119fbd26de3a26d55eb65bc0146d0
--- src/ngircd/irc-login.c
+++ src/ngircd/irc-login.c
* @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 */
blob - 8dd9bf74f2897b954c337a1f028cdecbf1cdb64f
blob + 69dd61a797994886c63bf0426a6d4434192a993c
--- src/ngircd/irc.c
+++ src/ngircd/irc.c
/**
- * 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 )
{
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->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( );
- }
+ if (Req->argc != 2)
+ return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+ Client_ID(Client), Req->command);
- 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] );
- }
+ /* Get prefix (origin); use the client if no prefix is given. */
+ if (Req->prefix)
+ prefix = Client_Search(Req->prefix);
+ else
+ prefix = Client;
- /* 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] );
+ /* 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())
+ 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: 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 );
blob - 72e3430998b301d4011b9b55175e1a91d41875a6
blob + be3c864dc26f0683e5d39a6a6254ba4f84bdeab8
--- src/ngircd/parse.c
+++ src/ngircd/parse.c
/* 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;