00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "module.h"
00015 #include "nickserv.h"
00016
00017 class NickServCollide;
00018 class NickServRelease;
00019
00020 typedef std::map<Anope::string, NickServCollide *> nickservcollides_map;
00021 typedef std::map<Anope::string, NickServRelease *> nickservreleases_map;
00022
00023 static nickservcollides_map NickServCollides;
00024 static nickservreleases_map NickServReleases;
00025
00028 class NickServCollide : public Timer
00029 {
00030 dynamic_reference<User> u;
00031 Anope::string nick;
00032
00033 public:
00038 NickServCollide(User *user, time_t delay) : Timer(delay), u(user), nick(u->nick)
00039 {
00040
00041 nickservcollides_map::iterator nit = NickServCollides.find(user->nick);
00042 if (nit != NickServCollides.end())
00043 delete nit->second;
00044
00045 NickServCollides.insert(std::make_pair(nick, this));
00046 }
00047
00050 virtual ~NickServCollide()
00051 {
00052 NickServCollides.erase(this->nick);
00053 }
00054
00058 void Tick(time_t t) anope_override
00059 {
00060 if (!u)
00061 return;
00062
00063 NickAlias *na = findnick(u->nick);
00064 if (!na || u->Account() == na->nc || u->timestamp > this->GetSetTime())
00065 return;
00066
00067 u->Collide(na);
00068 }
00069 };
00070
00071 class MyNickServService : public NickServService
00072 {
00073 public:
00074 MyNickServService(Module *m) : NickServService(m) { }
00075
00076 void Validate(User *u) anope_override
00077 {
00078 NickAlias *na = findnick(u->nick);
00079 if (!na)
00080 return;
00081 const BotInfo *NickServ = findbot(Config->NickServ);
00082
00083 if (na->nc->HasFlag(NI_SUSPENDED))
00084 {
00085 u->SendMessage(NickServ, NICK_X_SUSPENDED, u->nick.c_str());
00086 u->Collide(na);
00087 return;
00088 }
00089
00090 if (!(u->Account() == na->nc) && !u->fingerprint.empty() && na->nc->FindCert(u->fingerprint))
00091 {
00092 u->SendMessage(NickServ, _("SSL Fingerprint accepted, you are now identified."));
00093 Log(u) << "automatically identified for account " << na->nc->display << " using a valid SSL fingerprint.";
00094 u->Identify(na);
00095 return;
00096 }
00097
00098 if (!na->nc->HasFlag(NI_SECURE) && u->IsRecognized())
00099 {
00100 na->last_seen = Anope::CurTime;
00101 Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost();
00102 na->last_usermask = last_usermask;
00103 na->last_realname = u->realname;
00104 return;
00105 }
00106
00107 if (Config->NoNicknameOwnership)
00108 return;
00109
00110 if (u->IsRecognized(false) || !na->nc->HasFlag(NI_KILL_IMMED))
00111 {
00112 if (na->nc->HasFlag(NI_SECURE))
00113 u->SendMessage(NickServ, NICK_IS_SECURE, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str());
00114 else
00115 u->SendMessage(NickServ, NICK_IS_REGISTERED, Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str());
00116 }
00117
00118 if (na->nc->HasFlag(NI_KILLPROTECT) && !u->IsRecognized(false))
00119 {
00120 if (na->nc->HasFlag(NI_KILL_IMMED))
00121 {
00122 u->SendMessage(NickServ, FORCENICKCHANGE_NOW);
00123 u->Collide(na);
00124 }
00125 else if (na->nc->HasFlag(NI_KILL_QUICK))
00126 {
00127 u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), duration(Config->NSKillQuick, u->Account()).c_str());
00128 new NickServCollide(u, Config->NSKillQuick);
00129 }
00130 else
00131 {
00132 u->SendMessage(NickServ, _("If you do not change within %s, I will change your nick."), duration(Config->NSKill, u->Account()).c_str());
00133 new NickServCollide(u, Config->NSKill);
00134 }
00135 }
00136
00137 }
00138 };
00139
00140 class ExpireCallback : public CallBack
00141 {
00142 public:
00143 ExpireCallback(Module *owner) : CallBack(owner, Config->ExpireTimeout, Anope::CurTime, true) { }
00144
00145 void Tick(time_t) anope_override
00146 {
00147 if (noexpire || readonly)
00148 return;
00149
00150 for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; )
00151 {
00152 NickAlias *na = it->second;
00153 ++it;
00154
00155 User *u = finduser(na->nick);
00156 if (u && (na->nc->HasFlag(NI_SECURE) ? u->IsIdentified(true) : u->IsRecognized()))
00157 na->last_seen = Anope::CurTime;
00158
00159 bool expire = false;
00160
00161 if (na->nc->HasFlag(NI_UNCONFIRMED))
00162 if (Config->NSUnconfirmedExpire && Anope::CurTime - na->time_registered >= Config->NSUnconfirmedExpire)
00163 expire = true;
00164 if (Config->NSExpire && Anope::CurTime - na->last_seen >= Config->NSExpire)
00165 expire = true;
00166 if (na->HasFlag(NS_NO_EXPIRE))
00167 expire = false;
00168
00169 FOREACH_MOD(I_OnPreNickExpire, OnPreNickExpire(na, expire));
00170
00171 if (expire)
00172 {
00173 Anope::string extra;
00174 if (na->nc->HasFlag(NI_SUSPENDED))
00175 extra = "suspended ";
00176 Log(LOG_NORMAL, "expire") << "Expiring " << extra << "nickname " << na->nick << " (group: " << na->nc->display << ") (e-mail: " << (na->nc->email.empty() ? "none" : na->nc->email) << ")";
00177 FOREACH_MOD(I_OnNickExpire, OnNickExpire(na));
00178 na->destroy();
00179 }
00180 }
00181 }
00182 };
00183
00184 class NickServCore : public Module
00185 {
00186 MyNickServService mynickserv;
00187 ExpireCallback expires;
00188
00189 public:
00190 NickServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), mynickserv(this), expires(this)
00191 {
00192 this->SetAuthor("Anope");
00193
00194 if (!findbot(Config->NickServ))
00195 throw ModuleException("No bot named " + Config->NickServ);
00196
00197 Implementation i[] = { I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, I_OnNickIdentify, I_OnNickGroup,
00198 I_OnNickUpdate, I_OnUserNickChange, I_OnPreHelp, I_OnPostHelp, I_OnUserConnect };
00199 ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
00200 }
00201
00202 void OnDelNick(NickAlias *na) anope_override
00203 {
00204 User *u = finduser(na->nick);
00205 if (u && u->Account() == na->nc)
00206 {
00207 ircdproto->SendLogout(u);
00208 u->RemoveMode(findbot(Config->NickServ), UMODE_REGISTERED);
00209 u->Logout();
00210 }
00211 }
00212
00213 void OnDelCore(NickCore *nc) anope_override
00214 {
00215 Log(findbot(Config->NickServ), "nick") << "deleting nickname group " << nc->display;
00216
00217
00218
00219
00220 for (std::list<User *>::iterator it = nc->Users.begin(); it != nc->Users.end();)
00221 {
00222 User *user = *it++;
00223 ircdproto->SendLogout(user);
00224 user->RemoveMode(findbot(Config->NickServ), UMODE_REGISTERED);
00225 user->Logout();
00226 FOREACH_MOD(I_OnNickLogout, OnNickLogout(user));
00227 }
00228 nc->Users.clear();
00229 }
00230
00231 void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) anope_override
00232 {
00233 Log(LOG_NORMAL, "nick", findbot(Config->NickServ)) << "Changing " << nc->display << " nickname group display to " << newdisplay;
00234 }
00235
00236 void OnNickIdentify(User *u) anope_override
00237 {
00238 const BotInfo *NickServ = findbot(Config->NickServ);
00239
00240 if (!Config->NoNicknameOwnership)
00241 {
00242 const NickAlias *this_na = findnick(u->nick);
00243 if (this_na && this_na->nc == u->Account() && u->Account()->HasFlag(NI_UNCONFIRMED) == false)
00244 u->SetMode(NickServ, UMODE_REGISTERED);
00245 }
00246
00247 if (Config->NSModeOnID)
00248 for (UChannelList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
00249 {
00250 ChannelContainer *cc = *it;
00251 Channel *c = cc->chan;
00252 if (c)
00253 chan_set_correct_modes(u, c, 1, true);
00254 }
00255
00256 if (!Config->NSModesOnID.empty())
00257 u->SetModes(NickServ, "%s", Config->NSModesOnID.c_str());
00258
00259 if (Config->NSForceEmail && u->Account()->email.empty())
00260 {
00261 u->SendMessage(NickServ, _("You must now supply an e-mail for your nick.\n"
00262 "This e-mail will allow you to retrieve your password in\n"
00263 "case you forget it."));
00264 u->SendMessage(NickServ, _("Type \002%s%s SET EMAIL \037e-mail\037\002 in order to set your e-mail.\n"
00265 "Your privacy is respected; this e-mail won't be given to\n"
00266 "any third-party person."), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str());
00267 }
00268
00269 if (u->Account()->HasFlag(NI_UNCONFIRMED))
00270 {
00271 u->SendMessage(NickServ, _("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you when you registered."));
00272 const NickAlias *this_na = findnick(u->Account()->display);
00273 time_t time_registered = Anope::CurTime - this_na->time_registered;
00274 if (Config->NSUnconfirmedExpire > time_registered)
00275 u->SendMessage(NickServ, _("Your account will expire, if not confirmed, in %s"), duration(Config->NSUnconfirmedExpire - time_registered).c_str());
00276 }
00277 }
00278
00279 void OnNickGroup(User *u, NickAlias *target) anope_override
00280 {
00281 if (target->nc->HasFlag(NI_UNCONFIRMED) == false)
00282 u->SetMode(findbot(Config->NickServ), UMODE_REGISTERED);
00283 }
00284
00285 void OnNickUpdate(User *u) anope_override
00286 {
00287 for (UChannelList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
00288 {
00289 ChannelContainer *cc = *it;
00290 Channel *c = cc->chan;
00291 if (c)
00292 chan_set_correct_modes(u, c, 1, false);
00293 }
00294 }
00295
00296 void OnUserNickChange(User *u, const Anope::string &oldnick) anope_override
00297 {
00298 const NickAlias *na = findnick(u->nick);
00299 const BotInfo *NickServ = findbot(Config->NickServ);
00300
00301 if (!na || na->nc != u->Account())
00302 {
00303
00304 u->RemoveMode(NickServ, UMODE_REGISTERED);
00305
00306 this->mynickserv.Validate(u);
00307 }
00308 else
00309 {
00310
00311 ircdproto->SendLogin(u);
00312 if (!Config->NoNicknameOwnership && na->nc == u->Account() && na->nc->HasFlag(NI_UNCONFIRMED) == false)
00313 u->SetMode(NickServ, UMODE_REGISTERED);
00314 Log(NickServ) << u->GetMask() << " automatically identified for group " << u->Account()->display;
00315 }
00316 }
00317
00318 void OnUserModeSet(User *u, UserModeName Name) anope_override
00319 {
00320 if (Name == UMODE_REGISTERED && !u->IsIdentified())
00321 u->RemoveMode(findbot(Config->NickServ), Name);
00322 }
00323
00324 EventReturn OnPreHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
00325 {
00326 if (!params.empty() || source.c || source.service->nick != Config->NickServ)
00327 return EVENT_CONTINUE;
00328 source.Reply(_("\002%s\002 allows you to \"register\" a nickname and\n"
00329 "prevent others from using it. The following\n"
00330 "commands allow for registration and maintenance of\n"
00331 "nicknames; to use them, type \002%s%s \037command\037\002.\n"
00332 "For more information on a specific command, type\n"
00333 "\002%s%s %s \037command\037\002.\n "), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), Config->UseStrictPrivMsgString.c_str(), Config->NickServ.c_str(), source.command.c_str());
00334 return EVENT_CONTINUE;
00335 }
00336
00337 void OnPostHelp(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override
00338 {
00339 if (!params.empty() || source.c || source.service->nick != Config->NickServ)
00340 return;
00341 if (source.IsServicesOper())
00342 source.Reply(_(" \n"
00343 "Services Operators can also drop any nickname without needing\n"
00344 "to identify for the nick, and may view the access list for\n"
00345 "any nickname."));
00346 if (Config->NSExpire >= 86400)
00347 source.Reply(_(" \n"
00348 "Nicknames that are not used anymore are subject to \n"
00349 "the automatic expiration, i.e. they will be deleted\n"
00350 "after %d days if not used."), Config->NSExpire / 86400);
00351 source.Reply(_(" \n"
00352 "\002NOTICE:\002 This service is intended to provide a way for\n"
00353 "IRC users to ensure their identity is not compromised.\n"
00354 "It is \002NOT\002 intended to facilitate \"stealing\" of\n"
00355 "nicknames or other malicious actions. Abuse of %s\n"
00356 "will result in, at minimum, loss of the abused\n"
00357 "nickname(s)."), Config->NickServ.c_str());
00358 }
00359
00360 void OnUserConnect(dynamic_reference<User> &u, bool &exempt) anope_override
00361 {
00362 if (!Config->NoNicknameOwnership && !Config->NSUnregisteredNotice.empty() && u && !findnick(u->nick))
00363 u->SendMessage(findbot(Config->NickServ), Config->NSUnregisteredNotice);
00364 }
00365 };
00366
00367 MODULE_INIT(NickServCore)
00368