irc-login.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. /*
  2. * ngIRCd -- The Next Generation IRC Daemon
  3. * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de)
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. * Please read the file COPYING, README and AUTHORS for more information.
  10. *
  11. * Login and logout
  12. */
  13. #include "portab.h"
  14. static char UNUSED id[] = "$Id: irc-login.c,v 1.49 2005/09/01 10:51:24 alex Exp $";
  15. #include "imp.h"
  16. #include <assert.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <strings.h>
  21. #include "ngircd.h"
  22. #include "resolve.h"
  23. #include "conn-func.h"
  24. #include "conf.h"
  25. #include "client.h"
  26. #include "channel.h"
  27. #include "log.h"
  28. #include "messages.h"
  29. #include "parse.h"
  30. #include "irc.h"
  31. #include "irc-info.h"
  32. #include "irc-write.h"
  33. #include "cvs-version.h"
  34. #include "exp.h"
  35. #include "irc-login.h"
  36. static bool Hello_User PARAMS(( CLIENT *Client ));
  37. static void Kill_Nick PARAMS(( char *Nick, char *Reason ));
  38. GLOBAL bool
  39. IRC_PASS( CLIENT *Client, REQUEST *Req )
  40. {
  41. assert( Client != NULL );
  42. assert( Req != NULL );
  43. /* Fehler liefern, wenn kein lokaler Client */
  44. if( Client_Conn( Client ) <= NONE ) return IRC_WriteStrClient( Client, ERR_UNKNOWNCOMMAND_MSG, Client_ID( Client ), Req->command );
  45. if(( Client_Type( Client ) == CLIENT_UNKNOWN ) && ( Req->argc == 1))
  46. {
  47. /* noch nicht registrierte unbekannte Verbindung */
  48. Log( LOG_DEBUG, "Connection %d: got PASS command ...", Client_Conn( Client ));
  49. /* Passwort speichern */
  50. Client_SetPassword( Client, Req->argv[0] );
  51. Client_SetType( Client, CLIENT_GOTPASS );
  52. return CONNECTED;
  53. }
  54. else if((( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER )) && (( Req->argc == 3 ) || ( Req->argc == 4 )))
  55. {
  56. char c2, c4, *type, *impl, *serverver, *flags, *ptr, *ircflags;
  57. int protohigh, protolow;
  58. /* noch nicht registrierte Server-Verbindung */
  59. Log( LOG_DEBUG, "Connection %d: got PASS command (new server link) ...", Client_Conn( Client ));
  60. /* Passwort speichern */
  61. Client_SetPassword( Client, Req->argv[0] );
  62. /* Protokollversion ermitteln */
  63. if( strlen( Req->argv[1] ) >= 4 )
  64. {
  65. c2 = Req->argv[1][2];
  66. c4 = Req->argv[1][4];
  67. Req->argv[1][4] = '\0';
  68. protolow = atoi( &Req->argv[1][2] );
  69. Req->argv[1][2] = '\0';
  70. protohigh = atoi( Req->argv[1] );
  71. Req->argv[1][2] = c2;
  72. Req->argv[1][4] = c4;
  73. }
  74. else protohigh = protolow = 0;
  75. /* Protokoll-Typ */
  76. if( strlen( Req->argv[1] ) > 4 ) type = &Req->argv[1][4];
  77. else type = NULL;
  78. /* IRC-Flags (nach RFC 2813) */
  79. if( Req->argc >= 4 ) ircflags = Req->argv[3];
  80. else ircflags = "";
  81. /* Implementation, Version und ngIRCd-Flags */
  82. impl = Req->argv[2];
  83. ptr = strchr( impl, '|' );
  84. if( ptr ) *ptr = '\0';
  85. if( type && ( strcmp( type, PROTOIRCPLUS ) == 0 ))
  86. {
  87. /* auf der anderen Seite laeuft ein Server, der
  88. * ebenfalls das IRC+-Protokoll versteht */
  89. serverver = ptr + 1;
  90. flags = strchr( serverver, ':' );
  91. if( flags )
  92. {
  93. *flags = '\0';
  94. flags++;
  95. }
  96. else flags = "";
  97. Log( LOG_INFO, "Peer announces itself as %s-%s using protocol %d.%d/IRC+ (flags: \"%s\").", impl, serverver, protohigh, protolow, flags );
  98. }
  99. else
  100. {
  101. /* auf der anderen Seite laeuft ein Server, der
  102. * nur das Originalprotokoll unterstuetzt */
  103. serverver = "";
  104. if( strchr( ircflags, 'Z' )) flags = "Z";
  105. else flags = "";
  106. Log( LOG_INFO, "Peer announces itself as \"%s\" using protocol %d.%d (flags: \"%s\").", impl, protohigh, protolow, flags );
  107. }
  108. Client_SetType( Client, CLIENT_GOTPASSSERVER );
  109. Client_SetFlags( Client, flags );
  110. return CONNECTED;
  111. }
  112. else if(( Client_Type( Client ) == CLIENT_UNKNOWN ) || ( Client_Type( Client ) == CLIENT_UNKNOWNSERVER ))
  113. {
  114. /* Falsche Anzahl Parameter? */
  115. return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
  116. }
  117. else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
  118. } /* IRC_PASS */
  119. /**
  120. * IRC "NICK" command.
  121. * This function implements the IRC command "NICK" which is used to register
  122. * with the server, to change already registered nicknames and to introduce
  123. * new users which are connected to other servers.
  124. */
  125. GLOBAL bool
  126. IRC_NICK( CLIENT *Client, REQUEST *Req )
  127. {
  128. CLIENT *intr_c, *target, *c;
  129. char *modes;
  130. assert( Client != NULL );
  131. assert( Req != NULL );
  132. #ifndef STRICT_RFC
  133. /* Some IRC clients, for example BitchX, send the NICK and USER
  134. * commands in the wrong order ... */
  135. if( Client_Type( Client ) == CLIENT_UNKNOWN
  136. || Client_Type( Client ) == CLIENT_GOTPASS
  137. || Client_Type( Client ) == CLIENT_GOTNICK
  138. || Client_Type( Client ) == CLIENT_GOTUSER
  139. || Client_Type( Client ) == CLIENT_USER
  140. || ( Client_Type( Client ) == CLIENT_SERVER && Req->argc == 1 ))
  141. #else
  142. if( Client_Type( Client ) == CLIENT_UNKNOWN
  143. || Client_Type( Client ) == CLIENT_GOTPASS
  144. || Client_Type( Client ) == CLIENT_GOTNICK
  145. || Client_Type( Client ) == CLIENT_USER
  146. || ( Client_Type( Client ) == CLIENT_SERVER && Req->argc == 1 ))
  147. #endif
  148. {
  149. /* User registration or change of nickname */
  150. /* Wrong number of arguments? */
  151. if( Req->argc != 1 )
  152. return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG,
  153. Client_ID( Client ),
  154. Req->command );
  155. /* Search "target" client */
  156. if( Client_Type( Client ) == CLIENT_SERVER )
  157. {
  158. target = Client_Search( Req->prefix );
  159. if( ! target )
  160. return IRC_WriteStrClient( Client,
  161. ERR_NOSUCHNICK_MSG,
  162. Client_ID( Client ),
  163. Req->argv[0] );
  164. }
  165. else
  166. {
  167. /* Is this a restricted client? */
  168. if( Client_HasMode( Client, 'r' ))
  169. return IRC_WriteStrClient( Client,
  170. ERR_RESTRICTED_MSG,
  171. Client_ID( Client ));
  172. target = Client;
  173. }
  174. #ifndef STRICT_RFC
  175. /* If the clients tries to change to its own nickname we won't
  176. * do anything. This is how the original ircd behaves and some
  177. * clients (for example Snak) expect it to be like this.
  178. * But I doubt that this is "really the right thing" ... */
  179. if( strcmp( Client_ID( target ), Req->argv[0] ) == 0 )
  180. return CONNECTED;
  181. #endif
  182. /* Check that the new nickname is available. Special case:
  183. * the client only changes from/to upper to lower case. */
  184. if( strcasecmp( Client_ID( target ), Req->argv[0] ) != 0 )
  185. {
  186. if( ! Client_CheckNick( target, Req->argv[0] ))
  187. return CONNECTED;
  188. }
  189. if(( Client_Type( target ) != CLIENT_USER )
  190. && ( Client_Type( target ) != CLIENT_SERVER ))
  191. {
  192. /* New client */
  193. Log( LOG_DEBUG, "Connection %d: got valid NICK command ...",
  194. Client_Conn( Client ));
  195. /* Register new nickname of this client */
  196. Client_SetID( target, Req->argv[0] );
  197. /* If we received a valid USER command already then
  198. * register the new client! */
  199. if( Client_Type( Client ) == CLIENT_GOTUSER )
  200. return Hello_User( Client );
  201. else
  202. Client_SetType( Client, CLIENT_GOTNICK );
  203. }
  204. else
  205. {
  206. /* Nickname change */
  207. if( Client_Conn( target ) > NONE )
  208. {
  209. /* Local client */
  210. Log( LOG_INFO,
  211. "User \"%s\" changed nick (connection %d): \"%s\" -> \"%s\".",
  212. Client_Mask( target ), Client_Conn( target ),
  213. Client_ID( target ), Req->argv[0] );
  214. }
  215. else
  216. {
  217. /* Remote client */
  218. Log( LOG_DEBUG,
  219. "User \"%s\" changed nick: \"%s\" -> \"%s\".",
  220. Client_Mask( target ), Client_ID( target ),
  221. Req->argv[0] );
  222. }
  223. /* Inform all users and servers (which have to know)
  224. * of this nickname change */
  225. if( Client_Type( Client ) == CLIENT_USER )
  226. IRC_WriteStrClientPrefix( Client, Client,
  227. "NICK :%s",
  228. Req->argv[0] );
  229. IRC_WriteStrServersPrefix( Client, target,
  230. "NICK :%s", Req->argv[0] );
  231. IRC_WriteStrRelatedPrefix( target, target, false,
  232. "NICK :%s", Req->argv[0] );
  233. /* Register old nickname for WHOWAS queries */
  234. Client_RegisterWhowas( target );
  235. /* Save new nickname */
  236. Client_SetID( target, Req->argv[0] );
  237. IRC_SetPenalty( target, 2 );
  238. }
  239. return CONNECTED;
  240. }
  241. else if( Client_Type( Client ) == CLIENT_SERVER )
  242. {
  243. /* Server introduces new client */
  244. /* Falsche Anzahl Parameter? */
  245. if( Req->argc != 7 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
  246. /* Nick ueberpruefen */
  247. c = Client_Search( Req->argv[0] );
  248. if( c )
  249. {
  250. /* Der neue Nick ist auf diesem Server bereits registriert:
  251. * sowohl der neue, als auch der alte Client muessen nun
  252. * disconnectiert werden. */
  253. Log( LOG_ERR, "Server %s introduces already registered nick \"%s\"!", Client_ID( Client ), Req->argv[0] );
  254. Kill_Nick( Req->argv[0], "Nick collision" );
  255. return CONNECTED;
  256. }
  257. /* Server, zu dem der Client connectiert ist, suchen */
  258. intr_c = Client_GetFromToken( Client, atoi( Req->argv[4] ));
  259. if( ! intr_c )
  260. {
  261. Log( LOG_ERR, "Server %s introduces nick \"%s\" on unknown server!?", Client_ID( Client ), Req->argv[0] );
  262. Kill_Nick( Req->argv[0], "Unknown server" );
  263. return CONNECTED;
  264. }
  265. /* Neue Client-Struktur anlegen */
  266. c = Client_NewRemoteUser( intr_c, Req->argv[0], atoi( Req->argv[1] ), Req->argv[2], Req->argv[3], atoi( Req->argv[4] ), Req->argv[5] + 1, Req->argv[6], true);
  267. if( ! c )
  268. {
  269. /* Eine neue Client-Struktur konnte nicht angelegt werden.
  270. * Der Client muss disconnectiert werden, damit der Netz-
  271. * status konsistent bleibt. */
  272. Log( LOG_ALERT, "Can't create client structure! (on connection %d)", Client_Conn( Client ));
  273. Kill_Nick( Req->argv[0], "Server error" );
  274. return CONNECTED;
  275. }
  276. modes = Client_Modes( c );
  277. if( *modes ) Log( LOG_DEBUG, "User \"%s\" (+%s) registered (via %s, on %s, %d hop%s).", Client_Mask( c ), modes, Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
  278. else Log( LOG_DEBUG, "User \"%s\" registered (via %s, on %s, %d hop%s).", Client_Mask( c ), Client_ID( Client ), Client_ID( intr_c ), Client_Hops( c ), Client_Hops( c ) > 1 ? "s": "" );
  279. /* Andere Server, ausser dem Introducer, informieren */
  280. IRC_WriteStrServersPrefix( Client, Client, "NICK %s %d %s %s %d %s :%s", Req->argv[0], atoi( Req->argv[1] ) + 1, Req->argv[2], Req->argv[3], Client_MyToken( intr_c ), Req->argv[5], Req->argv[6] );
  281. return CONNECTED;
  282. }
  283. else return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
  284. } /* IRC_NICK */
  285. GLOBAL bool
  286. IRC_USER( CLIENT *Client, REQUEST *Req )
  287. {
  288. #ifdef IDENTAUTH
  289. char *ptr;
  290. #endif
  291. assert( Client != NULL );
  292. assert( Req != NULL );
  293. #ifndef STRICT_RFC
  294. if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS || Client_Type( Client ) == CLIENT_UNKNOWN )
  295. #else
  296. if( Client_Type( Client ) == CLIENT_GOTNICK || Client_Type( Client ) == CLIENT_GOTPASS )
  297. #endif
  298. {
  299. /* Wrong number of parameters? */
  300. if( Req->argc != 4 ) return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
  301. /* User name */
  302. #ifdef IDENTAUTH
  303. ptr = Client_User( Client );
  304. if( ! ptr || ! *ptr || *ptr == '~' ) Client_SetUser( Client, Req->argv[0], false );
  305. #else
  306. Client_SetUser( Client, Req->argv[0], false );
  307. #endif
  308. /* "Real name" or user info text: Don't set it to the empty string, the original ircd
  309. * can't deal with such "real names" (e. g. "USER user * * :") ... */
  310. if( *Req->argv[3] ) Client_SetInfo( Client, Req->argv[3] );
  311. else Client_SetInfo( Client, "-" );
  312. Log( LOG_DEBUG, "Connection %d: got valid USER command ...", Client_Conn( Client ));
  313. if( Client_Type( Client ) == CLIENT_GOTNICK ) return Hello_User( Client );
  314. else Client_SetType( Client, CLIENT_GOTUSER );
  315. return CONNECTED;
  316. }
  317. else if( Client_Type( Client ) == CLIENT_USER || Client_Type( Client ) == CLIENT_SERVER || Client_Type( Client ) == CLIENT_SERVICE )
  318. {
  319. return IRC_WriteStrClient( Client, ERR_ALREADYREGISTRED_MSG, Client_ID( Client ));
  320. }
  321. else return IRC_WriteStrClient( Client, ERR_NOTREGISTERED_MSG, Client_ID( Client ));
  322. } /* IRC_USER */
  323. GLOBAL bool
  324. IRC_QUIT( CLIENT *Client, REQUEST *Req )
  325. {
  326. CLIENT *target;
  327. char quitmsg[LINE_LEN];
  328. assert( Client != NULL );
  329. assert( Req != NULL );
  330. /* Wrong number of arguments? */
  331. if( Req->argc > 1 )
  332. return IRC_WriteStrClient( Client, ERR_NEEDMOREPARAMS_MSG, Client_ID( Client ), Req->command );
  333. if (Req->argc == 1)
  334. strlcpy(quitmsg, Req->argv[0], sizeof quitmsg);
  335. if ( Client_Type( Client ) == CLIENT_SERVER )
  336. {
  337. /* Server */
  338. target = Client_Search( Req->prefix );
  339. if( ! target )
  340. {
  341. /* Den Client kennen wir nicht (mehr), also nichts zu tun. */
  342. Log( LOG_WARNING, "Got QUIT from %s for unknown client!?", Client_ID( Client ));
  343. return CONNECTED;
  344. }
  345. Client_Destroy( target, "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true);
  346. return CONNECTED;
  347. }
  348. else
  349. {
  350. if (Req->argc == 1 && quitmsg[0] != '\"') {
  351. /* " " to avoid confusion */
  352. strlcpy(quitmsg, "\"", sizeof quitmsg);
  353. strlcat(quitmsg, Req->argv[0], sizeof quitmsg-1);
  354. strlcat(quitmsg, "\"", sizeof quitmsg );
  355. }
  356. /* User, Service, oder noch nicht registriert */
  357. Conn_Close( Client_Conn( Client ), "Got QUIT command.", Req->argc == 1 ? quitmsg : NULL, true);
  358. return DISCONNECTED;
  359. }
  360. } /* IRC_QUIT */
  361. GLOBAL bool
  362. IRC_PING(CLIENT *Client, REQUEST *Req)
  363. {
  364. CLIENT *target, *from;
  365. assert(Client != NULL);
  366. assert(Req != NULL);
  367. /* Wrong number of arguments? */
  368. if (Req->argc < 1)
  369. return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
  370. Client_ID(Client));
  371. #ifdef STRICT_RFC
  372. /* Don't ignore additional arguments when in "strict" mode */
  373. if (Req->argc > 2)
  374. return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
  375. Client_ID(Client), Req->command);
  376. #endif
  377. if (Req->argc > 1) {
  378. /* A target has been specified ... */
  379. target = Client_Search(Req->argv[1]);
  380. if (!target || Client_Type(target) != CLIENT_SERVER)
  381. return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
  382. Client_ID(Client), Req->argv[1]);
  383. if (target != Client_ThisServer()) {
  384. /* Ok, we have to forward the PING */
  385. if (Client_Type(Client) == CLIENT_SERVER)
  386. from = Client_Search(Req->prefix);
  387. else
  388. from = Client;
  389. if (!from)
  390. return IRC_WriteStrClient(Client,
  391. ERR_NOSUCHSERVER_MSG,
  392. Client_ID(Client), Req->prefix);
  393. return IRC_WriteStrClientPrefix(target, from,
  394. "PING %s :%s", Req->argv[0],
  395. Req->argv[1] );
  396. }
  397. }
  398. if (Client_Type(Client) == CLIENT_SERVER) {
  399. if (Req->prefix)
  400. from = Client_Search(Req->prefix);
  401. else
  402. from = Client;
  403. } else
  404. from = Client_ThisServer();
  405. if (!from)
  406. return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
  407. Client_ID(Client), Req->prefix);
  408. Log(LOG_DEBUG, "Connection %d: got PING, sending PONG ...",
  409. Client_Conn(Client));
  410. #ifdef STRICT_RFC
  411. return IRC_WriteStrClient(Client, "PONG %s :%s",
  412. Client_ID(from), Client_ID(Client));
  413. #else
  414. /* Some clients depend on the argument being returned in the PONG
  415. * reply (not mentioned in any RFC, though) */
  416. return IRC_WriteStrClient(Client, "PONG %s :%s",
  417. Client_ID(from), Req->argv[0]);
  418. #endif
  419. } /* IRC_PING */
  420. GLOBAL bool
  421. IRC_PONG(CLIENT *Client, REQUEST *Req)
  422. {
  423. CLIENT *target, *from;
  424. char *s;
  425. assert(Client != NULL);
  426. assert(Req != NULL);
  427. /* Wrong number of arguments? */
  428. if (Req->argc < 1)
  429. return IRC_WriteStrClient(Client, ERR_NOORIGIN_MSG,
  430. Client_ID(Client));
  431. if (Req->argc > 2)
  432. return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
  433. Client_ID(Client), Req->command);
  434. /* Forward? */
  435. if (Req->argc == 2 && Client_Type(Client) == CLIENT_SERVER) {
  436. target = Client_Search(Req->argv[0]);
  437. if (!target)
  438. return IRC_WriteStrClient(Client, ERR_NOSUCHSERVER_MSG,
  439. Client_ID(Client), Req->argv[0]);
  440. from = Client_Search(Req->prefix);
  441. if (target != Client_ThisServer() && target != from) {
  442. /* Ok, we have to forward the message. */
  443. if (!from)
  444. return IRC_WriteStrClient(Client,
  445. ERR_NOSUCHSERVER_MSG,
  446. Client_ID(Client), Req->prefix);
  447. if (Client_Type(Client_NextHop(target)) != CLIENT_SERVER)
  448. s = Client_ID(from);
  449. else
  450. s = Req->argv[0];
  451. return IRC_WriteStrClientPrefix(target, from,
  452. "PONG %s :%s", s, Req->argv[1]);
  453. }
  454. }
  455. /* The connection timestamp has already been updated when the data has
  456. * been read from so socket, so we don't need to update it here. */
  457. if (Client_Conn(Client) > NONE)
  458. Log(LOG_DEBUG,
  459. "Connection %d: received PONG. Lag: %ld seconds.",
  460. Client_Conn(Client),
  461. time(NULL) - Conn_LastPing(Client_Conn(Client)));
  462. else
  463. Log(LOG_DEBUG,
  464. "Connection %d: received PONG.", Client_Conn(Client));
  465. return CONNECTED;
  466. } /* IRC_PONG */
  467. static bool
  468. Hello_User( CLIENT *Client )
  469. {
  470. #ifdef CVSDATE
  471. char ver[12], vertxt[30];
  472. #endif
  473. assert( Client != NULL );
  474. /* Check password ... */
  475. if( strcmp( Client_Password( Client ), Conf_ServerPwd ) != 0 )
  476. {
  477. /* Bad password! */
  478. Log( LOG_ERR, "User \"%s\" rejected (connection %d): Bad password!", Client_Mask( Client ), Client_Conn( Client ));
  479. Conn_Close( Client_Conn( Client ), NULL, "Bad password", true);
  480. return DISCONNECTED;
  481. }
  482. Log( LOG_NOTICE, "User \"%s\" registered (connection %d).", Client_Mask( Client ), Client_Conn( Client ));
  483. /* Inform other servers */
  484. IRC_WriteStrServers( NULL, "NICK %s 1 %s %s 1 +%s :%s", Client_ID( Client ), Client_User( Client ), Client_Hostname( Client ), Client_Modes( Client ), Client_Info( Client ));
  485. /* Welcome :-) */
  486. if( ! IRC_WriteStrClient( Client, RPL_WELCOME_MSG, Client_ID( Client ), Client_Mask( Client ))) return false;
  487. /* Version and system type */
  488. #ifdef CVSDATE
  489. strlcpy( ver, CVSDATE, sizeof( ver ));
  490. strncpy( ver + 4, ver + 5, 2 );
  491. strncpy( ver + 6, ver + 8, 3 );
  492. snprintf( vertxt, sizeof( vertxt ), "%s(%s)", PACKAGE_VERSION, ver );
  493. if( ! IRC_WriteStrClient( Client, RPL_YOURHOST_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), vertxt, TARGET_CPU, TARGET_VENDOR, TARGET_OS )) return false;
  494. #else
  495. if( ! IRC_WriteStrClient( Client, RPL_YOURHOST_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), PACKAGE_VERSION, TARGET_CPU, TARGET_VENDOR, TARGET_OS )) return false;
  496. #endif
  497. if( ! IRC_WriteStrClient( Client, RPL_CREATED_MSG, Client_ID( Client ), NGIRCd_StartStr )) return false;
  498. #ifdef CVSDATE
  499. if( ! IRC_WriteStrClient( Client, RPL_MYINFO_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), vertxt, USERMODES, CHANMODES )) return false;
  500. #else
  501. if( ! IRC_WriteStrClient( Client, RPL_MYINFO_MSG, Client_ID( Client ), Client_ID( Client_ThisServer( )), PACKAGE_VERSION, USERMODES, CHANMODES )) return false;
  502. #endif
  503. /* Features */
  504. if( ! IRC_WriteStrClient( Client, RPL_ISUPPORT_MSG, Client_ID( Client ), CLIENT_NICK_LEN - 1,
  505. COMMAND_LEN - 23, CLIENT_AWAY_LEN - 1, Conf_MaxJoins )) return DISCONNECTED;
  506. Client_SetType( Client, CLIENT_USER );
  507. if( ! IRC_Send_LUSERS( Client )) return DISCONNECTED;
  508. if( ! IRC_Show_MOTD( Client )) return DISCONNECTED;
  509. /* Suspend the client for a second ... */
  510. IRC_SetPenalty( Client, 1 );
  511. return CONNECTED;
  512. } /* Hello_User */
  513. static void
  514. Kill_Nick( char *Nick, char *Reason )
  515. {
  516. REQUEST r;
  517. assert( Nick != NULL );
  518. assert( Reason != NULL );
  519. r.prefix = (char *)Client_ThisServer( );
  520. r.argv[0] = Nick;
  521. r.argv[1] = Reason;
  522. r.argc = 2;
  523. Log( LOG_ERR, "User(s) with nick \"%s\" will be disconnected: %s", Nick, Reason );
  524. IRC_KILL( Client_ThisServer( ), &r );
  525. } /* Kill_Nick */
  526. /* -eof- */