diff --git a/ChangeLog b/ChangeLog index 27d8fc1a..1c920678 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,7 @@ ngIRCd HEAD + - Allow PASS syntax defined in RFC 1459 for server links, too. - Enhanced ISUPPORT message (005 numeric). ngIRCd 0.10.0 (2006-10-01) @@ -665,4 +666,4 @@ ngIRCd 0.0.1, 31.12.2001 -- -$Id: ChangeLog,v 1.305 2006/10/01 19:03:05 alex Exp $ +$Id: ChangeLog,v 1.306 2006/10/01 19:05:00 alex Exp $ diff --git a/src/ngircd/client.h b/src/ngircd/client.h index 73de52b5..a7f81664 100644 --- a/src/ngircd/client.h +++ b/src/ngircd/client.h @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: client.h,v 1.42 2006/04/23 10:37:27 fw Exp $ + * $Id: client.h,v 1.43 2006/10/01 19:05:02 alex Exp $ * * Client management (header) */ @@ -23,10 +23,9 @@ #define CLIENT_GOTNICK 4 /* client did send NICK */ #define CLIENT_GOTUSER 8 /* client did send USER */ #define CLIENT_USER 16 /* client is an IRC user */ -#define CLIENT_UNKNOWNSERVER 32 /* unregistered server connection */ -#define CLIENT_GOTPASSSERVER 64 /* client did send PASS in "server style" */ -#define CLIENT_SERVER 128 /* client is a server */ -#define CLIENT_SERVICE 256 /* client is a service */ +#define CLIENT_SERVER 32 /* client is a server */ +#define CLIENT_SERVICE 64 /* client is a service */ +#define CLIENT_UNKNOWNSERVER 128 /* unregistered server connection */ #define CLIENT_TYPE int diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index 6516086a..ccdbc8e3 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-login.c,v 1.51 2006/10/01 19:03:05 alex Exp $"; +static char UNUSED id[] = "$Id: irc-login.c,v 1.52 2006/10/01 19:05:02 alex Exp $"; #include "imp.h" #include @@ -45,101 +45,120 @@ static bool Hello_User PARAMS(( CLIENT *Client )); static void Kill_Nick PARAMS(( char *Nick, char *Reason )); +/** + * Handler for the IRC command "PASS". + * See RFC 2813 section 4.1.1, and RFC 2812 section 3.1.1. + */ GLOBAL bool IRC_PASS( CLIENT *Client, REQUEST *Req ) { + char *type, *orig_flags; + int protohigh, protolow; + assert( Client != NULL ); assert( Req != NULL ); - /* Fehler liefern, wenn kein lokaler Client */ - if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command ); + /* Return an error if this is not a local client */ + if (Client_Conn(Client) <= NONE) + return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG, + Client_ID(Client), Req->command); - if(( Client_Type( Client ) == CLIENT_UNKNOWN ) && ( Req->argc == 1)) - { - /* noch nicht registrierte unbekannte Verbindung */ - Log( LOG_DEBUG, "Connection %d: got PASS command ...", Client_Conn( Client )); - - /* Passwort speichern */ - Client_SetPassword( Client, Req->argv[0] ); - - Client_SetType( Client, CLIENT_GOTPASS ); - return CONNECTED; + if (Client_Type(Client) == CLIENT_UNKNOWN && Req->argc == 1) { + /* Not yet registered "unknown" connection, PASS with one + * argument: either a regular client, service, or server + * using the old RFC 1459 section 4.1.1 syntax. */ + LogDebug("Connection %d: got PASS command ...", + Client_Conn(Client)); + } else if ((Client_Type(Client) == CLIENT_UNKNOWN || + Client_Type(Client) == CLIENT_UNKNOWNSERVER) && + (Req->argc == 3 || Req->argc == 4)) { + /* Not yet registered "unknown" connection or outgoing server + * link, PASS with three or four argument: server using the + * RFC 2813 section 4.1.1 syntax. */ + LogDebug("Connection %d: got PASS command (new server link) ...", + Client_Conn(Client)); + } else if (Client_Type(Client) == CLIENT_UNKNOWN || + Client_Type(Client) == CLIENT_UNKNOWNSERVER) { + /* Unregistered connection, but wrong number of arguments: */ + return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG, + Client_ID(Client), Req->command); + } else { + /* Registered connection, PASS command is not allowed! */ + return IRC_WriteStrClient(Client, ERR_ALREADYREGISTRED_MSG, + Client_ID(Client)); } - else if((( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER )) && (( Req->argc == 3 ) || ( Req->argc == 4 ))) - { - char c2, c4, *type, *impl, *serverver, *flags, *ptr, *ircflags; - int protohigh, protolow; - /* noch nicht registrierte Server-Verbindung */ - Log( LOG_DEBUG, "Connection %d: got PASS command (new server link) ...", Client_Conn( Client )); + Client_SetPassword(Client, Req->argv[0]); + Client_SetType(Client, CLIENT_GOTPASS); - /* Passwort speichern */ - Client_SetPassword( Client, Req->argv[0] ); + /* Protocol version */ + if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) { + int c2, c4; - /* Protokollversion ermitteln */ - if( strlen( Req->argv[1] ) >= 4 ) - { - c2 = Req->argv[1][2]; - c4 = Req->argv[1][4]; + c2 = Req->argv[1][2]; + c4 = Req->argv[1][4]; - Req->argv[1][4] = '\0'; - protolow = atoi( &Req->argv[1][2] ); - Req->argv[1][2] = '\0'; - protohigh = atoi( Req->argv[1] ); + Req->argv[1][4] = '\0'; + protolow = atoi(&Req->argv[1][2]); + Req->argv[1][2] = '\0'; + protohigh = atoi(Req->argv[1]); - Req->argv[1][2] = c2; - Req->argv[1][4] = c4; - } - else protohigh = protolow = 0; + Req->argv[1][2] = c2; + Req->argv[1][4] = c4; + } else + protohigh = protolow = 0; - /* Protokoll-Typ */ - if( strlen( Req->argv[1] ) > 4 ) type = &Req->argv[1][4]; - else type = NULL; + /* Protocol type, see doc/Protocol.txt */ + if (Req->argc >= 2 && strlen(Req->argv[1]) > 4) + type = &Req->argv[1][4]; + else + type = NULL; + + /* Protocol flags/options */ + if (Req->argc >= 4) + orig_flags = Req->argv[3]; + else + orig_flags = ""; - /* IRC-Flags (nach RFC 2813) */ - if( Req->argc >= 4 ) ircflags = Req->argv[3]; - else ircflags = ""; + /* Implementation, version and IRC+ flags */ + if (Req->argc >= 3) { + char *impl, *ptr, *serverver, *flags; + int _unused_var; - /* Implementation, Version und ngIRCd-Flags */ impl = Req->argv[2]; - ptr = strchr( impl, '|' ); - if( ptr ) *ptr = '\0'; + ptr = strchr(impl, '|'); + if (ptr) + *ptr = '\0'; - if( type && ( strcmp( type, PROTOIRCPLUS ) == 0 )) - { - /* auf der anderen Seite laeuft ein Server, der - * ebenfalls das IRC+-Protokoll versteht */ + if (type && strcmp(type, PROTOIRCPLUS) == 0) { + /* The peer seems to be a server which supports the + * IRC+ protocol (see doc/Protocol.txt). */ serverver = ptr + 1; - flags = strchr( serverver, ':' ); - if( flags ) - { + flags = strchr(serverver, ':'); + if (flags) { *flags = '\0'; flags++; - } - else flags = ""; - Log( LOG_INFO, "Peer announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").", impl, serverver, protohigh, protolow, flags ); - } - else - { - /* auf der anderen Seite laeuft ein Server, der - * nur das Originalprotokoll unterstuetzt */ + } else + flags = ""; + Log(LOG_INFO, + "Peer announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").", + impl, serverver, protohigh, protolow, flags); + } else { + /* The peer seems to be a server supporting the + * "original" IRC protocol (RFC 2813). */ serverver = ""; - if( strchr( ircflags, 'Z' )) flags = "Z"; - else flags = ""; - Log( LOG_INFO, "Peer announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").", impl, protohigh, protolow, flags ); + if (strchr(orig_flags, 'Z')) + flags = "Z"; + else + flags = ""; + Log(LOG_INFO, + "Peer announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").", + impl, protohigh, protolow, flags); } - - Client_SetType( Client, CLIENT_GOTPASSSERVER ); - Client_SetFlags( Client, flags ); - - return CONNECTED; + Client_SetFlags(Client, flags); } - else if(( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER )) - { - /* Falsche Anzahl Parameter? */ - return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command ); - } - else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client )); + + return CONNECTED; } /* IRC_PASS */ diff --git a/src/ngircd/irc-server.c b/src/ngircd/irc-server.c index 2c153064..b8681b9c 100644 --- a/src/ngircd/irc-server.c +++ b/src/ngircd/irc-server.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-server.c,v 1.39 2006/04/30 21:31:43 alex Exp $"; +static char UNUSED id[] = "$Id: irc-server.c,v 1.40 2006/10/01 19:05:02 alex Exp $"; #include "imp.h" #include @@ -41,6 +41,10 @@ static char UNUSED id[] = "$Id: irc-server.c,v 1.39 2006/04/30 21:31:43 alex Exp #include "irc-server.h" +/** + * Handler for the IRC command "SERVER". + * See RFC 2813 section 4.1.2. + */ GLOBAL bool IRC_SERVER( CLIENT *Client, REQUEST *Req ) { @@ -55,13 +59,17 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req ) assert( Client != NULL ); assert( Req != NULL ); - /* Fehler liefern, wenn kein lokaler Client */ - if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command ); + /* Return an error if this is not a local client */ + if (Client_Conn(Client) <= NONE) + return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG, + Client_ID(Client), Req->command); - if( Client_Type( Client ) == CLIENT_GOTPASSSERVER ) - { - /* Verbindung soll als Server-Server-Verbindung registriert werden */ - Log( LOG_DEBUG, "Connection %d: got SERVER command (new server link) ...", Client_Conn( Client )); + if (Client_Type(Client) == CLIENT_GOTPASS) { + /* We got a PASS command from the peer, and now a SERVER + * command: the peer tries to register itself as a server. */ + Log(LOG_DEBUG, + "Connection %d: got SERVER command (new server link) ...", + Client_Conn(Client)); /* Falsche Anzahl Parameter? */ if(( Req->argc != 2 ) && ( Req->argc != 3 )) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );