X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fngircd%2Firc-login.c;h=9fca622ba0ea66422940e2d71dc2dff0d5f2eee4;hp=1915a6d75a6d8f6b0edb622a8ac4ef282818e145;hb=b8482fd3cfdb429aec75575958f4d5d4e9ae22df;hpb=15dfdaac823c5927b096b2980753a6198a6a7741 diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index 1915a6d7..9fca622b 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2012 Alexander Barton (alex@barton.de) and Contributors. + * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,15 +16,14 @@ * Login and logout */ -#include "imp.h" #include #include #include #include #include +#include #include "conn-func.h" -#include "class.h" #include "conf.h" #include "channel.h" #include "log.h" @@ -32,14 +31,11 @@ #include "messages.h" #include "parse.h" #include "irc.h" -#include "irc-info.h" #include "irc-macros.h" #include "irc-write.h" -#include "exp.h" #include "irc-login.h" -static void Kill_Nick PARAMS((char *Nick, char *Reason)); static void Change_Nick PARAMS((CLIENT * Origin, CLIENT * Target, char *NewNick, bool InformClient)); @@ -61,7 +57,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req ) /* Return an error if this is not a local client */ if (Client_Conn(Client) <= NONE) - return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG, + return IRC_WriteErrClient(Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID(Client), Req->command); if (Client_Type(Client) == CLIENT_UNKNOWN && Req->argc == 1) { @@ -81,13 +77,11 @@ IRC_PASS( CLIENT *Client, REQUEST *Req ) } else if (Client_Type(Client) == CLIENT_UNKNOWN || Client_Type(Client) == CLIENT_UNKNOWNSERVER) { /* Unregistered connection, but wrong number of arguments: */ - IRC_SetPenalty(Client, 2); - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); } else { /* Registered connection, PASS command is not allowed! */ - IRC_SetPenalty(Client, 2); - return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG, + return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG, Client_ID(Client)); } @@ -178,6 +172,7 @@ GLOBAL bool IRC_NICK( CLIENT *Client, REQUEST *Req ) { CLIENT *intr_c, *target, *c; + CHANNEL *chan; char *nick, *user, *hostname, *modes, *info; int token, hops; @@ -203,18 +198,16 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) if (Client_Type(Client) == CLIENT_SERVER) { target = Client_Search(Req->prefix); if (!target) - return IRC_WriteStrClient( Client, - ERR_NOSUCHNICK_MSG, - Client_ID( Client ), - Req->argv[0] ); + return IRC_WriteErrClient(Client, + ERR_NOSUCHNICK_MSG, + Client_ID(Client), + Req->argv[0]); } else { /* Is this a restricted client? */ - if (Client_HasMode(Client, 'r')) { - IRC_SetPenalty(Client, 2); - return IRC_WriteStrClient( Client, - ERR_RESTRICTED_MSG, - Client_ID( Client )); - } + if (Client_HasMode(Client, 'r')) + return IRC_WriteErrClient(Client, + ERR_RESTRICTED_MSG, + Client_ID(Client)); target = Client; } @@ -246,8 +239,12 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) #ifndef STRICT_RFC if (Conf_AuthPing) { +#ifdef HAVE_ARC4RANDOM + Conn_SetAuthPing(Client_Conn(Client), arc4random()); +#else Conn_SetAuthPing(Client_Conn(Client), rand()); - IRC_WriteStrClient(Client, "PING :%ld", +#endif + Conn_WriteStr(Client_Conn(Client), "PING :%ld", Conn_GetAuthPing(Client_Conn(Client))); LogDebug("Connection %d: sent AUTH PING %ld ...", Client_Conn(Client), @@ -263,6 +260,22 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) Client_SetType( Client, CLIENT_GOTNICK ); } else { /* Nickname change */ + + /* Check that the user isn't on any channels set +N */ + if(Client_Type(Client) == CLIENT_USER && + !Client_HasMode(Client, 'o')) { + chan = Channel_First(); + while (chan) { + if(Channel_HasMode(chan, 'N') && + Channel_IsMemberOf(chan, Client)) + return IRC_WriteErrClient(Client, + ERR_NONICKCHANGE_MSG, + Client_ID(Client), + Channel_Name(chan)); + chan = Channel_Next(chan); + } + } + Change_Nick(Client, target, Req->argv[0], Client_Type(Client) == CLIENT_USER ? true : false); IRC_SetPenalty(target, 2); @@ -275,7 +288,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) /* Bad number of parameters? */ if (Req->argc != 2 && Req->argc != 7) - return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + return IRC_WriteErrClient(Client, ERR_NEEDMOREPARAMS_MSG, Client_ID(Client), Req->command); if (Req->argc >= 7) { @@ -304,17 +317,21 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) * the new nick is already present on this server: * the new and the old one have to be disconnected now. */ - Log( LOG_ERR, "Server %s introduces already registered nick \"%s\"!", Client_ID( Client ), Req->argv[0] ); - Kill_Nick( Req->argv[0], "Nick collision" ); - return CONNECTED; + Log(LOG_ERR, + "Server %s introduces already registered nick \"%s\"!", + Client_ID(Client), Req->argv[0]); + return IRC_KillClient(Client, NULL, Req->argv[0], + "Nick collision"); } /* Find the Server this client is connected to */ intr_c = Client_GetFromToken(Client, token); if (!intr_c) { - Log( LOG_ERR, "Server %s introduces nick \"%s\" on unknown server!?", Client_ID( Client ), Req->argv[0] ); - Kill_Nick( Req->argv[0], "Unknown server" ); - return CONNECTED; + Log(LOG_ERR, + "Server %s introduces nick \"%s\" on unknown server!?", + Client_ID(Client), Req->argv[0]); + return IRC_KillClient(Client, NULL, Req->argv[0], + "Unknown server"); } c = Client_NewRemoteUser(intr_c, nick, hops, user, hostname, @@ -325,8 +342,8 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) Log(LOG_ALERT, "Can't create client structure! (on connection %d)", Client_Conn(Client)); - Kill_Nick(Req->argv[0], "Server error"); - return CONNECTED; + return IRC_KillClient(Client, NULL, Req->argv[0], + "Server error"); } /* RFC 2813: client is now fully registered, inform all the @@ -343,7 +360,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) return CONNECTED; } else - return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG, + return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG, Client_ID(Client)); } /* IRC_NICK */ @@ -362,8 +379,6 @@ IRC_SVSNICK(CLIENT *Client, REQUEST *Req) assert(Client != NULL); assert(Req != NULL); - _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 2) - /* Search the originator */ from = Client_Search(Req->prefix); if (!from) @@ -371,10 +386,9 @@ IRC_SVSNICK(CLIENT *Client, REQUEST *Req) /* Search the target */ target = Client_Search(Req->argv[0]); - if (!target || Client_Type(target) != CLIENT_USER) { - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + if (!target || Client_Type(target) != CLIENT_USER) + return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->argv[0]); - } if (Client_Conn(target) <= NONE) { /* We have to forward the message to the server handling @@ -470,7 +484,7 @@ IRC_USER(CLIENT * Client, REQUEST * Req) c = Client_Search(Req->prefix); if (!c) - return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG, + return IRC_WriteErrClient(Client, ERR_NOSUCHNICK_MSG, Client_ID(Client), Req->prefix); @@ -490,13 +504,11 @@ IRC_USER(CLIENT * Client, REQUEST * Req) return CONNECTED; } else if (Client_Type(Client) == CLIENT_USER) { /* Already registered connection */ - IRC_SetPenalty(Client, 2); - return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG, + return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG, Client_ID(Client)); } else { /* Unexpected/invalid connection state? */ - IRC_SetPenalty(Client, 2); - return IRC_WriteStrClient(Client, ERR_NOTREGISTERED_MSG, + return IRC_WriteErrClient(Client, ERR_NOTREGISTERED_MSG, Client_ID(Client)); } } /* IRC_USER */ @@ -523,16 +535,12 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req) assert(Req != NULL); if (Client_Type(Client) != CLIENT_GOTPASS && - Client_Type(Client) != CLIENT_SERVER) { - IRC_SetPenalty(Client, 2); - return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG, + Client_Type(Client) != CLIENT_SERVER) + return IRC_WriteErrClient(Client, ERR_ALREADYREGISTRED_MSG, Client_ID(Client)); - } - - _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 6) if (Client_Type(Client) != CLIENT_SERVER) - return IRC_WriteStrClient(Client, ERR_ERRONEUSNICKNAME_MSG, + return IRC_WriteErrClient(Client, ERR_ERRONEUSNICKNAME_MSG, Client_ID(Client), Req->argv[0]); nick = Req->argv[0]; @@ -545,19 +553,19 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req) c = Client_Search(nick); if(c) { /* Nickname collision: disconnect (KILL) both clients! */ - Log(LOG_ERR, "Server %s introduces already registered service \"%s\"!", + Log(LOG_ERR, + "Server %s introduces already registered service \"%s\"!", Client_ID(Client), nick); - Kill_Nick(nick, "Nick collision"); - return CONNECTED; + return IRC_KillClient(Client, NULL, nick, "Nick collision"); } /* Get the server to which the service is connected */ intr_c = Client_GetFromToken(Client, token); if (! intr_c) { - Log(LOG_ERR, "Server %s introduces service \"%s\" on unknown server!?", + Log(LOG_ERR, + "Server %s introduces service \"%s\" on unknown server!?", Client_ID(Client), nick); - Kill_Nick(nick, "Unknown server"); - return CONNECTED; + return IRC_KillClient(Client, NULL, nick, "Unknown server"); } /* Get user and host name */ @@ -586,10 +594,10 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req) if (! c) { /* Couldn't create client structure, so KILL the service to * keep network status consistent ... */ - Log(LOG_ALERT, "Can't create client structure! (on connection %d)", + Log(LOG_ALERT, + "Can't create client structure! (on connection %d)", Client_Conn(Client)); - Kill_Nick(nick, "Server error"); - return CONNECTED; + return IRC_KillClient(Client, NULL, nick, "Server error"); } Client_Introduce(Client, c, CLIENT_SERVICE); @@ -606,10 +614,8 @@ IRC_SERVICE(CLIENT *Client, REQUEST *Req) GLOBAL bool IRC_WEBIRC(CLIENT *Client, REQUEST *Req) { - _IRC_ARGC_EQ_OR_RETURN_(Client, Req, 4) - if (!Conf_WebircPwd[0] || strcmp(Req->argv[0], Conf_WebircPwd) != 0) - return IRC_WriteStrClient(Client, ERR_PASSWDMISMATCH_MSG, + return IRC_WriteErrClient(Client, ERR_PASSWDMISMATCH_MSG, Client_ID(Client)); LogDebug("Connection %d: got valid WEBIRC command: user=%s, host=%s, ip=%s", @@ -617,7 +623,12 @@ IRC_WEBIRC(CLIENT *Client, REQUEST *Req) Client_SetUser(Client, Req->argv[1], true); Client_SetOrigUser(Client, Req->argv[1]); - Client_SetHostname(Client, Req->argv[2]); + if (Conf_DNS) + Client_SetHostname(Client, Req->argv[2]); + else + Client_SetHostname(Client, Req->argv[3]); + Client_SetIPAText(Client, Req->argv[3]); + return CONNECTED; } /* IRC_WEBIRC */ @@ -632,13 +643,11 @@ GLOBAL bool IRC_QUIT( CLIENT *Client, REQUEST *Req ) { CLIENT *target; - char quitmsg[LINE_LEN]; + char quitmsg[COMMAND_LEN]; assert(Client != NULL); assert(Req != NULL); - _IRC_ARGC_LE_OR_RETURN_(Client, Req, 1) - if (Req->argc == 1) strlcpy(quitmsg, Req->argv[0], sizeof quitmsg); @@ -715,7 +724,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req) assert(Req != NULL); if (Req->argc < 1) - return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG, + return IRC_WriteErrClient(Client, ERR_NOORIGIN_MSG, Client_ID(Client)); #ifdef STRICT_RFC /* Don't ignore additional arguments when in "strict" mode */ @@ -727,7 +736,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req) target = Client_Search(Req->argv[1]); if (!target || Client_Type(target) != CLIENT_SERVER) - return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG, + return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG, Client_ID(Client), Req->argv[1]); if (target != Client_ThisServer()) { @@ -737,7 +746,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req) else from = Client; if (!from) - return IRC_WriteStrClient(Client, + return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG, Client_ID(Client), Req->prefix); @@ -755,7 +764,7 @@ IRC_PING(CLIENT *Client, REQUEST *Req) } else from = Client_ThisServer(); if (!from) - return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG, + return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG, Client_ID(Client), Req->prefix); Log(LOG_DEBUG, "Connection %d: got PING, sending PONG ...", @@ -795,7 +804,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req) /* Wrong number of arguments? */ if (Req->argc < 1) { if (Client_Type(Client) == CLIENT_USER) - return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG, + return IRC_WriteErrClient(Client, ERR_NOORIGIN_MSG, Client_ID(Client)); else return CONNECTED; @@ -808,7 +817,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req) if (Req->argc == 2 && Client_Type(Client) == CLIENT_SERVER) { target = Client_Search(Req->argv[0]); if (!target) - return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG, + return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG, Client_ID(Client), Req->argv[0]); from = Client_Search(Req->prefix); @@ -816,7 +825,7 @@ IRC_PONG(CLIENT *Client, REQUEST *Req) if (target != Client_ThisServer() && target != from) { /* Ok, we have to forward the message. */ if (!from) - return IRC_WriteStrClient(Client, + return IRC_WriteErrClient(Client, ERR_NOSUCHSERVER_MSG, Client_ID(Client), Req->prefix); @@ -840,14 +849,14 @@ IRC_PONG(CLIENT *Client, REQUEST *Req) if (auth_ping) { LogDebug("AUTH PONG: waiting for token \"%ld\", got \"%s\" ...", auth_ping, Req->argv[0]); - if (auth_ping == atoi(Req->argv[0])) { + if (auth_ping == atol(Req->argv[0])) { Conn_SetAuthPing(conn, 0); if (Client_Type(Client) == CLIENT_WAITAUTHPING) Login_User(Client); } else if (!IRC_WriteStrClient(Client, - "To connect, type /QUOTE PONG %ld", - auth_ping)) + "NOTICE %s :To connect, type /QUOTE PONG %ld", + Client_ID(Client), auth_ping)) return DISCONNECTED; } #endif @@ -866,31 +875,6 @@ IRC_PONG(CLIENT *Client, REQUEST *Req) return CONNECTED; } /* IRC_PONG */ -/** - * Kill all users with a specific nickname in the network. - * - * @param Nick Nickname. - * @param Reason Reason for the KILL. - */ -static void -Kill_Nick(char *Nick, char *Reason) -{ - REQUEST r; - - assert (Nick != NULL); - assert (Reason != NULL); - - 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); -} /* Kill_Nick */ - /** * Change the nickname of a client. *