0001-Revert-Removed-ngircd.patch 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. From bc5023fdba8091ab7eee29fe0deeca6843159743 Mon Sep 17 00:00:00 2001
  2. From: Alexander Barton <alex@barton.de>
  3. Date: Mon, 16 May 2011 18:23:01 +0200
  4. Subject: [PATCH 1/2] Revert "Removed ngircd as we've decided not to support it at this time"
  5. This reverts commit 605b5d57171d2f0fac56ee2ee3e1b1bbdadeb24f and re-enables
  6. the ngIRCd protocol module for Anope.
  7. ---
  8. modules/protocol/ngircd.cpp | 475 +++++++++++++++++++++++++++++++++++++++++++
  9. 1 files changed, 475 insertions(+), 0 deletions(-)
  10. create mode 100644 modules/protocol/ngircd.cpp
  11. diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
  12. new file mode 100644
  13. index 0000000..6e1f21f
  14. --- /dev/null
  15. +++ b/modules/protocol/ngircd.cpp
  16. @@ -0,0 +1,475 @@
  17. +/* ngIRCd IRCD functions
  18. + *
  19. + * (C) 2003-2011 Anope Team
  20. + * Contact us at team@anope.org
  21. + *
  22. + * Please read COPYING and README for further details.
  23. + *
  24. + * Based on the original code of Epona by Lara.
  25. + * Based on the original code of Services by Andy Church.
  26. + */
  27. +
  28. +#include "services.h"
  29. +#include "modules.h"
  30. +
  31. +IRCDVar myIrcd[] = {
  32. + {"ngIRCd", /* ircd name */
  33. + "+oi", /* Modes used by pseudoclients */
  34. + 0, /* SVSNICK */
  35. + 0, /* Vhost */
  36. + 0, /* Supports SNlines */
  37. + 0, /* Supports SQlines */
  38. + 0, /* Supports SZlines */
  39. + 0, /* Join 2 Message */
  40. + 0, /* Chan SQlines */
  41. + 1, /* Quit on Kill */
  42. + 0, /* vidents */
  43. + 0, /* svshold */
  44. + 0, /* time stamp on mode */
  45. + 0, /* UMODE */
  46. + 0, /* O:LINE */
  47. + 0, /* No Knock requires +i */
  48. + 0, /* Can remove User Channel Modes with SVSMODE */
  49. + 0, /* Sglines are not enforced until user reconnects */
  50. + 0, /* ts6 */
  51. + "$", /* TLD Prefix for Global */
  52. + 20, /* Max number of modes we can send per line */
  53. + 0, /* IRCd sends a SSL users certificate fingerprint */
  54. + }
  55. + ,
  56. + {NULL}
  57. +};
  58. +
  59. +/* PASS */
  60. +class ngIRCdProto : public IRCDProto
  61. +{
  62. + void SendAkill(User *u, const XLine *x)
  63. + {
  64. + if (SGLine && u == NULL)
  65. + for (Anope::insensitive_map<User *>::iterator it = UserListByNick.begin(); it != UserListByNick.end();)
  66. + {
  67. + u = it->second;
  68. + ++it;
  69. + if (SGLine->Check(u) != NULL)
  70. + break;
  71. + }
  72. + }
  73. +
  74. + void SendAkillDel(const XLine*) { }
  75. +
  76. + void SendGlobopsInternal(const BotInfo *source, const Anope::string &buf)
  77. + {
  78. + send_cmd(source ? source->nick : Config->ServerName, "WALLOPS :%s", buf.c_str());
  79. + }
  80. +
  81. + void SendJoin(BotInfo *user, Channel *c, const ChannelStatus *status)
  82. + {
  83. + send_cmd(user->nick, "JOIN %s", c->name.c_str());
  84. + if (status)
  85. + for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
  86. + if (status->HasFlag(ModeManager::ChannelModes[i]->Name))
  87. + c->SetMode(user, ModeManager::ChannelModes[i], user->nick, false);
  88. + }
  89. +
  90. + void SendSVSKillInternal(const BotInfo *source, const User *user, const Anope::string &buf)
  91. + {
  92. + send_cmd(source ? source->nick : Config->ServerName, "KILL %s :%s", user->nick.c_str(), buf.c_str());
  93. + }
  94. +
  95. + /* SERVER name hop descript */
  96. + void SendServer(const Server *server)
  97. + {
  98. + send_cmd("", "SERVER %s %d :%s", server->GetName().c_str(), server->GetHops(), server->GetDescription().c_str());
  99. + }
  100. +
  101. + void SendConnect()
  102. + {
  103. + send_cmd("", "PASS %s 0210-IRC+ Anope|%s:CLHSo P", uplink_server->password.c_str(), Anope::VersionShort().c_str());
  104. + /* Make myself known to myself in the serverlist */
  105. + SendServer(Me);
  106. + /* finish the enhanced server handshake and register the connection */
  107. + this->SendNumeric(Config->ServerName, 376, "*", ":End of MOTD command");
  108. + }
  109. +
  110. + // Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator
  111. + void SendClientIntroduction(const User *u, const Anope::string &modes)
  112. + {
  113. + EnforceQlinedNick(u->nick, "");
  114. + send_cmd(Config->ServerName, "NICK %s 1 %s %s 1 %s :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), modes.c_str(), u->realname.c_str());
  115. + }
  116. +
  117. + void SendPartInternal(const BotInfo *bi, const Channel *chan, const Anope::string &buf)
  118. + {
  119. + if (!buf.empty())
  120. + send_cmd(bi->nick, "PART %s :%s", chan->name.c_str(), buf.c_str());
  121. + else
  122. + send_cmd(bi->nick, "PART %s", chan->name.c_str());
  123. + }
  124. +
  125. + void SendModeInternal(const BotInfo *bi, const Channel *dest, const Anope::string &buf)
  126. + {
  127. + send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", dest->name.c_str(), buf.c_str());
  128. + }
  129. +
  130. + void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf)
  131. + {
  132. + send_cmd(bi ? bi->nick : Config->ServerName, "MODE %s %s", u->nick.c_str(), buf.c_str());
  133. + }
  134. +
  135. + void SendKickInternal(const BotInfo *bi, const Channel *chan, const User *user, const Anope::string &buf)
  136. + {
  137. + if (!buf.empty())
  138. + send_cmd(bi->nick, "KICK %s %s :%s", chan->name.c_str(), user->nick.c_str(), buf.c_str());
  139. + else
  140. + send_cmd(bi->nick, "KICK %s %s", chan->name.c_str(), user->nick.c_str());
  141. + }
  142. +
  143. + void SendNoticeChanopsInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf)
  144. + {
  145. + send_cmd(source ? source->nick : Config->s_ChanServ, "NOTICE @%s :%s", dest->name.c_str(), buf.c_str());
  146. + }
  147. +
  148. + /* INVITE */
  149. + void SendInvite(BotInfo *source, const Anope::string &chan, const Anope::string &nick)
  150. + {
  151. + send_cmd(source->nick, "INVITE %s %s", nick.c_str(), chan.c_str());
  152. + }
  153. +
  154. + void SendChannel(Channel *c)
  155. + {
  156. + Anope::string mlock_modes = get_mlock_modes(c->ci, true);
  157. + if (mlock_modes.empty())
  158. + mlock_modes = "+";
  159. + send_cmd(Config->ServerName, "CHANINFO %s %s", c->name.c_str(), mlock_modes.c_str());
  160. + }
  161. + void SendTopic(BotInfo *bi, Channel *c)
  162. + {
  163. + send_cmd(bi->nick, "TOPIC %s :%s", c->name.c_str(), c->topic.c_str());
  164. + }
  165. +};
  166. +
  167. +class ngIRCdIRCdMessage : public IRCdMessage
  168. +{
  169. + public:
  170. + bool OnSJoin(const Anope::string&, const std::vector<Anope::string>&) { return false; }
  171. +
  172. + /*
  173. + * Received: :dev.anope.de MODE #anope +b *!*@*aol*
  174. + */
  175. + bool OnMode(const Anope::string &source, const std::vector<Anope::string> &params)
  176. + {
  177. + if (params.size() < 2)
  178. + return true;
  179. +
  180. + Anope::string modes = params[1];
  181. + for (unsigned i = 2; i < params.size(); ++i)
  182. + modes += " " + params[i];
  183. +
  184. + if (params[0][0] == '#' || params[0][0] == '&')
  185. + do_cmode(source, params[0], modes, "");
  186. + else
  187. + do_umode(params[0], params[1]);
  188. +
  189. + return true;
  190. + }
  191. +
  192. + /*
  193. + Received: :DukeP_ NICK :test2
  194. + Received: :dev.anope.de NICK DukeP_ 1 ~DukePyro ip-2-201-236-154.web.vodafone.de 1 + :DukePyrolator
  195. + source = nickname on nickchange, servername on newuser
  196. + params[0] = nick
  197. + params[1] = <unknown>
  198. + params[2] = username
  199. + params[3] = host
  200. + params[4] = <unknown>
  201. + params[5] = modes
  202. + params[6] = info
  203. + */
  204. + bool OnNick(const Anope::string &source, const std::vector<Anope::string> &params)
  205. + {
  206. + if (params.size() == 1)
  207. + {
  208. + // we have a nickchange
  209. + do_nick(source, params[0], "", "", "", "", Anope::CurTime, "", "", "", "");
  210. + }
  211. + else if (params.size() == 7)
  212. + {
  213. + // a new user is connecting to the network
  214. + User *user = do_nick("", params[0], params[2], params[3], source, params[6], Anope::CurTime, "", "", "", params[5]);
  215. + if (user)
  216. + validate_user(user);
  217. + }
  218. + else
  219. + {
  220. + Log() << "Received NICK with invalid number of parameters. source = " << source << "param[0] = " << params[0] << "params.size() = " << params.size();
  221. + }
  222. + return true;
  223. + }
  224. +
  225. + bool OnServer(const Anope::string &source, const std::vector<Anope::string> &params)
  226. + {
  227. + if (params.size() == 3)
  228. + do_server("", params[0], 0, params[2], params[1]);
  229. + else
  230. + do_server(source, params[0], params[1].is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0, params[3], params[2]);
  231. + return true;
  232. + }
  233. +
  234. + bool OnTopic(const Anope::string &source, const std::vector<Anope::string> &params)
  235. + {
  236. + Channel *c = findchan(params[0]);
  237. + if (!c)
  238. + {
  239. + Log() << "TOPIC for nonexistant channel " << params[0];
  240. + return true;
  241. + }
  242. +
  243. + c->ChangeTopicInternal(source, params[1]);
  244. + return true;
  245. + }
  246. +
  247. + /*
  248. + * <@po||ux> DukeP: RFC 2813, 4.2.1: the JOIN command on server-server links
  249. + * separates the modes ("o") with ASCII 7, not space. And you can't see ASCII 7.
  250. + *
  251. + * if a user joins a new channel, the ircd sends <channelname>\7<umode>
  252. + */
  253. + bool OnJoin (const Anope::string &source, const std::vector<Anope::string> &params)
  254. + {
  255. + if (!params.empty())
  256. + {
  257. + size_t pos = params[0].find('\7');
  258. + if (pos != Anope::string::npos)
  259. + {
  260. + Anope::string channel = params[0].substr(0, pos);
  261. + Anope::string mode = '+' + params[0].substr(pos, params[0].length()) + " " + source;
  262. + do_join(source, channel, "");
  263. + do_cmode(source, channel, mode, "");
  264. + }
  265. + else
  266. + do_join(source, params[0], "");
  267. + }
  268. + return true;
  269. + }
  270. +};
  271. +
  272. +/*
  273. + * CHANINFO <chan> +<modes>
  274. + * CHANINFO <chan> +<modes> :<topic>
  275. + * CHANINFO <chan> +<modes> <key> <limit> :<topic>
  276. + */
  277. +bool event_chaninfo(const Anope::string &source, const std::vector<Anope::string> &params)
  278. +{
  279. +
  280. + Channel *c = findchan(params[0]);
  281. + if (!c)
  282. + c = new Channel(params[0]);
  283. +
  284. + Anope::string modes = params[1];
  285. +
  286. + if (params.size() == 3)
  287. + {
  288. + c->ChangeTopicInternal(source, params[2], Anope::CurTime);
  289. + }
  290. + else if (params.size() == 5)
  291. + {
  292. + for (size_t i = 0, end = params[1].length(); i < end; ++i)
  293. + {
  294. + switch(params[1][i])
  295. + {
  296. + case 'k':
  297. + modes += " " + params[2];
  298. + continue;
  299. + case 'l':
  300. + modes += " " + params[3];
  301. + continue;
  302. + }
  303. + }
  304. + c->ChangeTopicInternal(source, params[4], Anope::CurTime);
  305. + }
  306. +
  307. + c->SetModesInternal(NULL, modes);
  308. +
  309. + return true;
  310. +}
  311. +
  312. +/*
  313. + * Received: :dev.anope.de NJOIN #test :DukeP2,@DukeP
  314. + */
  315. +bool event_njoin(const Anope::string &source, const std::vector<Anope::string> &params)
  316. +{
  317. + Channel *c = findchan(params[0]);
  318. + commasepstream sep(params[1]);
  319. + Anope::string buf;
  320. +
  321. + if (!c)
  322. + {
  323. + c = new Channel(params[0], Anope::CurTime);
  324. + c->SetFlag(CH_SYNCING);
  325. + }
  326. +
  327. + while (sep.GetToken(buf))
  328. + {
  329. + std::list<ChannelMode *> Status;
  330. + char ch;
  331. +
  332. + /* Get prefixes from the nick */
  333. + while ((ch = ModeManager::GetStatusChar(buf[0])))
  334. + {
  335. + buf.erase(buf.begin());
  336. + ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
  337. + if (!cm)
  338. + {
  339. + Log() << "Received unknown mode prefix " << ch << " in NJOIN string.";
  340. + continue;
  341. + }
  342. + Status.push_back(cm);
  343. + }
  344. + User *u = finduser(buf);
  345. + if (!u)
  346. + {
  347. + Log(LOG_DEBUG) << "NJOIN for nonexistant user " << buf << " on " << c->name;
  348. + continue;
  349. + }
  350. +
  351. + EventReturn MOD_RESULT;
  352. + FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c));
  353. +
  354. + /* Add the user to the Channel */
  355. + c->JoinUser(u);
  356. +
  357. + /* Update their status internally on the channel
  358. + * This will enforce secureops etc on the user
  359. + */
  360. + for (std::list<ChannelMode *>::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it)
  361. + c->SetModeInternal(*it, buf);
  362. + /* Now set whatever modes this user is allowed to have on the channel */
  363. + chan_set_correct_modes(u, c, 1);
  364. +
  365. + /* Check to see if modules want the user to join, if they do
  366. + * check to see if they are allowed to join (CheckKick will kick/ban them)
  367. + * Don't trigger OnJoinChannel event then as the user will be destroyed
  368. + */
  369. + if (MOD_RESULT != EVENT_STOP && c->ci && c->ci->CheckKick(u))
  370. + continue;
  371. +
  372. + FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c));
  373. + } /* while */
  374. +
  375. + if (c->HasFlag(CH_SYNCING))
  376. + {
  377. + c->UnsetFlag(CH_SYNCING);
  378. + c->Sync();
  379. + }
  380. +
  381. + return true;
  382. +}
  383. +
  384. +bool event_kick(const Anope::string &source, const std::vector<Anope::string> &params)
  385. +{
  386. + if (params.size() > 2)
  387. + do_kick(source, params[0], params[1], params[2]);
  388. + return true;
  389. +}
  390. +
  391. +bool event_pass(const Anope::string &source, const std::vector<Anope::string> &params)
  392. +{
  393. + return true;
  394. +}
  395. +
  396. +bool event_005(const Anope::string &source, const std::vector<Anope::string> &params)
  397. +{
  398. + size_t pos;
  399. + Anope::string name, data;
  400. + for (unsigned i = 0, end = params.size(); i < end; ++i)
  401. + {
  402. + pos = params[i].find('=');
  403. + if (pos != Anope::string::npos)
  404. + {
  405. + name = params[i].substr(0, pos);
  406. + data = params[i].substr(pos+1, params[i].length());
  407. + if (name == "NICKLEN")
  408. + {
  409. + unsigned newlen = convertTo<unsigned>(data);
  410. + if (Config->NickLen != newlen)
  411. + {
  412. + Log() << "Config->NickLen changed from " << Config->NickLen << " to " << newlen;
  413. + Config->NickLen = newlen;
  414. + }
  415. + }
  416. + }
  417. + }
  418. + return true;
  419. +}
  420. +
  421. +bool event_442(const Anope::string &source, const std::vector<Anope::string> &params)
  422. +{
  423. + return true;
  424. +}
  425. +
  426. +bool event_376(const Anope::string &source, const std::vector<Anope::string> &params)
  427. +{
  428. + return true;
  429. +}
  430. +
  431. +
  432. +class ProtongIRCd : public Module
  433. +{
  434. + Message message_kick, message_pass, message_njoin, message_chaninfo, message_005,
  435. + message_442, message_376;
  436. +
  437. + ngIRCdProto ircd_proto;
  438. + ngIRCdIRCdMessage ircd_message;
  439. +
  440. + void AddModes()
  441. + {
  442. + /* Add user modes */
  443. + ModeManager::AddUserMode(new UserMode(UMODE_ADMIN, 'a'));
  444. + ModeManager::AddUserMode(new UserMode(UMODE_INVIS, 'i'));
  445. + ModeManager::AddUserMode(new UserMode(UMODE_OPER, 'o'));
  446. + ModeManager::AddUserMode(new UserMode(UMODE_RESTRICTED, 'r'));
  447. + ModeManager::AddUserMode(new UserMode(UMODE_SNOMASK, 's'));
  448. + ModeManager::AddUserMode(new UserMode(UMODE_WALLOPS, 'w'));
  449. + ModeManager::AddUserMode(new UserMode(UMODE_CLOAK, 'x'));
  450. +
  451. + /* b/e/I */
  452. + ModeManager::AddChannelMode(new ChannelModeBan(CMODE_BAN, 'b'));
  453. + ModeManager::AddChannelMode(new ChannelModeList(CMODE_INVITEOVERRIDE, 'I'));
  454. +
  455. + /* v/h/o/a/q */
  456. + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_VOICE, 'v', '+'));
  457. + ModeManager::AddChannelMode(new ChannelModeStatus(CMODE_OP, 'o', '@'));
  458. +
  459. + /* Add channel modes */
  460. + // channel modes: biIklmnoPstvz
  461. + ModeManager::AddChannelMode(new ChannelMode(CMODE_INVITE, 'i'));
  462. + ModeManager::AddChannelMode(new ChannelModeKey('k'));
  463. + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_LIMIT, 'l'));
  464. + ModeManager::AddChannelMode(new ChannelMode(CMODE_MODERATED, 'm'));
  465. + ModeManager::AddChannelMode(new ChannelMode(CMODE_NOEXTERNAL, 'n'));
  466. + ModeManager::AddChannelMode(new ChannelMode(CMODE_PERM, 'P'));
  467. + ModeManager::AddChannelMode(new ChannelMode(CMODE_SECRET, 's'));
  468. + ModeManager::AddChannelMode(new ChannelMode(CMODE_TOPIC, 't'));
  469. + ModeManager::AddChannelMode(new ChannelMode(CMODE_SSL, 'z'));
  470. + }
  471. +
  472. + public:
  473. + ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator),
  474. + message_kick("KICK", event_kick), message_pass("PASS", event_pass),
  475. + message_njoin("NJOIN", event_njoin), message_chaninfo("CHANINFO", event_chaninfo),
  476. + message_005("005", event_005), message_442("442", event_442), message_376("376", event_376)
  477. + {
  478. + this->SetAuthor("Anope");
  479. + this->SetType(PROTOCOL);
  480. +
  481. + Capab.SetFlag(CAPAB_QS);
  482. +
  483. + pmodule_ircd_var(myIrcd);
  484. + pmodule_ircd_proto(&this->ircd_proto);
  485. + pmodule_ircd_message(&this->ircd_message);
  486. +
  487. + this->AddModes();
  488. + }
  489. +};
  490. +
  491. +MODULE_INIT(ProtongIRCd)
  492. --
  493. 1.7.2.5