diff --git a/src/ngircd/client.h b/src/ngircd/client.h index 63406f20..75b99b27 100644 --- a/src/ngircd/client.h +++ b/src/ngircd/client.h @@ -26,6 +26,7 @@ #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_GOTPASS_2813 256 /* client did send PASS, RFC 2813 style */ #define CLIENT_TYPE int diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index 5a68d5e8..e709612a 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -81,7 +81,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req ) /* 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 ...", + LogDebug("Connection %d: got PASS command (RFC 1459) ...", Client_Conn(Client)); } else if ((Client_Type(Client) == CLIENT_UNKNOWN || Client_Type(Client) == CLIENT_UNKNOWNSERVER) && @@ -89,7 +89,7 @@ IRC_PASS( CLIENT *Client, REQUEST *Req ) /* 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) ...", + LogDebug("Connection %d: got PASS command (RFC 2813, new server link) ...", Client_Conn(Client)); } else if (Client_Type(Client) == CLIENT_UNKNOWN || Client_Type(Client) == CLIENT_UNKNOWNSERVER) { @@ -103,7 +103,6 @@ IRC_PASS( CLIENT *Client, REQUEST *Req ) } Client_SetPassword(Client, Req->argv[0]); - Client_SetType(Client, CLIENT_GOTPASS); /* Protocol version */ if (Req->argc >= 2 && strlen(Req->argv[1]) >= 4) { @@ -119,8 +118,12 @@ IRC_PASS( CLIENT *Client, REQUEST *Req ) Req->argv[1][2] = c2; Req->argv[1][4] = c4; - } else + + Client_SetType(Client, CLIENT_GOTPASS_2813); + } else { protohigh = protolow = 0; + Client_SetType(Client, CLIENT_GOTPASS); + } /* Protocol type, see doc/Protocol.txt */ if (Req->argc >= 2 && strlen(Req->argv[1]) > 4) @@ -185,7 +188,6 @@ GLOBAL bool IRC_NICK( CLIENT *Client, REQUEST *Req ) { CLIENT *intr_c, *target, *c; - CONN_ID conn; char *nick, *user, *hostname, *modes, *info; int token, hops; @@ -340,15 +342,6 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) token = atoi(Req->argv[1]); modes = ""; info = Req->argv[0]; - - conn = Client_Conn(Client); - if (conn != NONE && - !(Conn_Options(conn) & CONN_RFC1459)) { - Log(LOG_INFO, - "Switching connection %d (\"%s\") to RFC 1459 compatibility mode.", - conn, Client_ID(Client)); - Conn_SetOption(conn, CONN_RFC1459); - } } /* Nick ueberpruefen */ diff --git a/src/ngircd/irc-server.c b/src/ngircd/irc-server.c index d342ffab..f1b817c0 100644 --- a/src/ngircd/irc-server.c +++ b/src/ngircd/irc-server.c @@ -14,8 +14,6 @@ #include "portab.h" -static char UNUSED id[] = "$Id: irc-server.c,v 1.46 2007/11/21 12:16:36 alex Exp $"; - #include "imp.h" #include #include @@ -26,6 +24,7 @@ static char UNUSED id[] = "$Id: irc-server.c,v 1.46 2007/11/21 12:16:36 alex Exp #include "defines.h" #include "resolve.h" #include "conn.h" +#include "conn-func.h" #include "conn-zip.h" #include "conf.h" #include "client.h" @@ -64,7 +63,8 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req ) return IRC_WriteStrClient(Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID(Client), Req->command); - if (Client_Type(Client) == CLIENT_GOTPASS) { + if (Client_Type(Client) == CLIENT_GOTPASS || + Client_Type(Client) == CLIENT_GOTPASS_2813) { /* We got a PASS command from the peer, and now a SERVER * command: the peer tries to register itself as a server. */ LogDebug("Connection %d: got SERVER command (new server link) ...", @@ -124,7 +124,18 @@ IRC_SERVER( CLIENT *Client, REQUEST *Req ) /* Mark this connection as belonging to an configured server */ Conf_SetServer(i, con); - + + /* Check protocol level */ + if (Client_Type(Client) == CLIENT_GOTPASS) { + /* We got a "simple" PASS command, so the peer is + * using the protocol as defined in RFC 1459. */ + if (! (Conn_Options(con) & CONN_RFC1459)) + Log(LOG_INFO, + "Switching connection %d (\"%s\") to RFC 1459 compatibility mode.", + con, Client_ID(Client)); + Conn_SetOption(con, CONN_RFC1459); + } + Client_SetType(Client, CLIENT_UNKNOWNSERVER); #ifdef ZLIB diff --git a/src/ngircd/numeric.c b/src/ngircd/numeric.c index dd24016b..d22bf3ae 100644 --- a/src/ngircd/numeric.c +++ b/src/ngircd/numeric.c @@ -1,6 +1,6 @@ /* * ngIRCd -- The Next Generation IRC Daemon - * Copyright (c)2001-2007 Alexander Barton (alex@barton.de) + * Copyright (c)2001-2008 Alexander Barton (alex@barton.de) * * 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 @@ -13,8 +13,6 @@ #include "portab.h" -static char UNUSED id[] = "$Id: numeric.c,v 1.1 2007/11/21 12:20:32 alex Exp $"; - #include "imp.h" #include #include @@ -26,6 +24,7 @@ static char UNUSED id[] = "$Id: numeric.c,v 1.1 2007/11/21 12:20:32 alex Exp $"; #include "conn.h" #include "conf.h" #include "conn.h" +#include "conn-func.h" #include "client.h" #include "channel.h" #include "irc-write.h" @@ -78,10 +77,27 @@ Announce_Server(CLIENT * Client, CLIENT * Server) static bool Announce_User(CLIENT * Client, CLIENT * User) { - return IRC_WriteStrClient(Client, "NICK %s %d %s %s %d +%s :%s", - Client_ID(User), Client_Hops(User) + 1, Client_User(User), - Client_Hostname(User), Client_MyToken(Client_Introducer(User)), - Client_Modes(User), Client_Info(User)); + CONN_ID conn; + conn = Client_Conn(Client); + if (Conn_Options(conn) & CONN_RFC1459) { + /* RFC 1459 mode: separate NICK and USER commands */ + if (! Conn_WriteStr(conn, "NICK %s :%d", + Client_ID(User), Client_Hops(User) + 1)) + return DISCONNECTED; + return Conn_WriteStr(conn, ":%s USER %s %s %s :%s", + Client_ID(User), Client_User(User), + Client_Hostname(User), + Client_ID(Client_Introducer(User)), + Client_Info(User)); + + } else { + /* RFC 2813 mode: one combined NICK command */ + return IRC_WriteStrClient(Client, "NICK %s %d %s %s %d +%s :%s", + Client_ID(User), Client_Hops(User) + 1, + Client_User(User), Client_Hostname(User), + Client_MyToken(Client_Introducer(User)), + Client_Modes(User), Client_Info(User)); + } } /* Announce_User */