diff options
author | Adam <Adam@anope.org> | 2011-03-05 17:23:22 -0500 |
---|---|---|
committer | Adam <Adam@anope.org> | 2011-03-05 17:23:22 -0500 |
commit | 6fe2d8af973dfb0c81f513e56488e39a4eea2fbf (patch) | |
tree | 432b93053ef56d1ff98b3193d5768a4ca16d3785 | |
parent | 90e5d0feaa1646c28cfce45dbde1a914a6f1d62c (diff) |
Removed nickrequests, instead have unconfirmed registrations. Also made ns_resetpass allow remote-id to get past things such as kill immed.
41 files changed, 365 insertions, 618 deletions
diff --git a/data/example.conf b/data/example.conf index 243dcb725..c797a2f84 100644 --- a/data/example.conf +++ b/data/example.conf @@ -940,6 +940,12 @@ nickserv forceemail = yes /* + * Require users who change their email address to confirm they + * own it. + */ + confirmemailchanges = no + + /* * Require an e-mail to be sent to the user before they can register their nick. */ #emailregistration = yes @@ -1018,12 +1024,12 @@ nickserv #forbidexpire = 90d /* - * The length of time a user gets to enter the confirmation code which has been e-mailed - * to them before the nick will be released for general use again. + * The length of time a user using an unconfirmed account has + * before the account will be released for general use again. * * This directive is only required if the e-mail registration option is enabled. */ - #preregexpire = 1d + #unconfirmedexpire = 1d /* * The maximum number of nicks allowed in a group. diff --git a/data/mysql/tables.sql b/data/mysql/tables.sql index 2cda6384e..b3cf06a00 100644 --- a/data/mysql/tables.sql +++ b/data/mysql/tables.sql @@ -291,21 +291,6 @@ CREATE TABLE IF NOT EXISTS `anope_ns_core_metadata` ( -- -------------------------------------------------------- -- --- Table structure for table `anope_ns_request` --- - -CREATE TABLE IF NOT EXISTS `anope_ns_request` ( - `nick` varchar(255) NOT NULL DEFAULT '', - `passcode` text NOT NULL, - `password` text NOT NULL, - `email` text NOT NULL, - `requested` int(10) unsigned NOT NULL DEFAULT '0', - PRIMARY KEY (`nick`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; - --- -------------------------------------------------------- - --- -- Table structure for table `anope_os_akills` -- diff --git a/docs/Changes b/docs/Changes index d23343937..9125a6258 100644 --- a/docs/Changes +++ b/docs/Changes @@ -2,11 +2,17 @@ Anope Version 1.9.4 -------------------- A Automatically set channel founder to the user with the highest access if there is no successor A /chanserv clone command to copy settings from one channel to another. +A /chanserv mode command A Ability for users to delete their own access in channels -A Ability for users with registrations pending to drop their registrations with /nickserv drop A Added support for Plexus 3 A Readded in support for /cs op/deop/etc to op/deop you in all channels A Added support for ngIRCd +A Added LDAP support +A Added live SQL support +A Added support for learning tracking/storing/locking all modes at runtime +A Added m_alias +A Added support for XMLRPC queries +A Added /botserv set msg F Changed the GHOST command to not allow ghosting unidentified users if the RECOVER command exists F Some failed logic in /operserv exception that prevents proper exceptions from being added F Fixed the anope_os_sxlines MySQL table and code to work after restarting diff --git a/docs/Changes.conf b/docs/Changes.conf index c8c9c9719..70e97bb46 100644 --- a/docs/Changes.conf +++ b/docs/Changes.conf @@ -1,5 +1,6 @@ Anope Version 1.9.4 ------------------- +** ADDED CONFIGURATION DIRECTIVES ** memoserv:modules added ms_ignore chanserv:modules added cs_clone and cs_mode nickserv:suspendexpire and nickserv:forbidexpire added @@ -7,10 +8,16 @@ chanserv:suspendexpire and chanserv:forbidexpire added module added cs_entrymsg nickserv:modules added ns_ajoin options:nomlock added +log:target added globops +nickserv:confirmemailchanges added + +** MODIFIED CONFIGURATION DIRECTIVES ** +operserv:notifications removed osglobal, osmode, oskick, osakill, ossnline, ossqline, osszline, osnoop, osjupe, getpass, setpass, forbid, drop +renamed nickserv:preregexpire to nickserv:unconfirmedexpire + +** DELETED CONFIGURATION DIRECTIVES ** opertype:commands removed operserv/umode operserv:modules removed os_umode -operserv:notifications removed osglobal, osmode, oskick, osakill, ossnline, ossqline, osszline, osnoop, osjupe, getpass, setpass, forbid, drop -log:target added globops Anope Version 1.9.3 ------------------ diff --git a/include/account.h b/include/account.h index b4a792caf..8615083b9 100644 --- a/include/account.h +++ b/include/account.h @@ -5,15 +5,12 @@ class NickAlias; class NickCore; -class NickRequest; typedef unordered_map_namespace::unordered_map<Anope::string, NickAlias *, ci::hash, std::equal_to<ci::string> > nickalias_map; typedef unordered_map_namespace::unordered_map<Anope::string, NickCore *, ci::hash, std::equal_to<ci::string> > nickcore_map; -typedef unordered_map_namespace::unordered_map<Anope::string, NickRequest *, ci::hash, std::equal_to<ci::string> > nickrequest_map; extern CoreExport nickalias_map NickAliasList; extern CoreExport nickcore_map NickCoreList; -extern CoreExport nickrequest_map NickRequestList; /* NickServ nickname structures. */ @@ -85,6 +82,9 @@ enum NickCoreFlag NI_AUTOOP, /* This nickcore is forbidden, which means the nickalias for it is aswell */ NI_FORBIDDEN, + /* If set means the nick core does not have their email addrses confirmed. + */ + NI_UNCONFIRMED, NI_END }; @@ -92,22 +92,7 @@ enum NickCoreFlag const Anope::string NickCoreFlagStrings[] = { "BEGIN", "KILLPROTECT", "SECURE", "MSG", "MEMO_HARDMAX", "MEMO_SIGNON", "MEMO_RECEIVE", "PRIVATE", "HIDE_EMAIL", "HIDE_MASK", "HIDE_QUIT", "KILL_QUICK", "KILL_IMMED", - "MEMO_MAIL", "HIDE_STATUS", "SUSPENDED", "AUTOOP", "FORBIDDEN", "" -}; - -class CoreExport NickRequest : public Extensible -{ - public: - NickRequest(const Anope::string &nickname); - - ~NickRequest(); - - Anope::string nick; - Anope::string passcode; - Anope::string password; - Anope::string email; - time_t requested; - time_t lastmail; /* Unsaved */ + "MEMO_MAIL", "HIDE_STATUS", "SUSPENDED", "AUTOOP", "FORBIDDEN", "UNCONFIRMED", "" }; class NickCore; diff --git a/include/anope.h b/include/anope.h index ec1d083a5..8153c976f 100644 --- a/include/anope.h +++ b/include/anope.h @@ -336,7 +336,7 @@ namespace Anope * @param ... any number of parameters * @return a Anope::string */ - extern CoreExport string printf(const char *fmt, ...); + extern CoreExport string printf(const Anope::string &fmt, ...); /** Return the last error, uses errno/GetLastError() to determin this * @return An error message diff --git a/include/config.h b/include/config.h index ef71933ec..f4844ded3 100644 --- a/include/config.h +++ b/include/config.h @@ -601,10 +601,12 @@ class CoreExport ServerConfig time_t NSSuspendExpire; /* How long before forbidden nicks expire */ time_t NSForbidExpire; - /* Time before NickRequests expire */ - time_t NSRExpire; + /* Time before unconfirmed nicks expire */ + time_t NSUnconfirmedExpire; /* Force email when registering */ bool NSForceEmail; + /* Force users to validate new email addresses */ + bool NSConfirmEmailChanges; /* Max number of nicks in a group */ unsigned NSMaxAliases; /* Max number of allowed strings on the access list */ diff --git a/include/extern.h b/include/extern.h index 1e88fbbc7..d670ad331 100644 --- a/include/extern.h +++ b/include/extern.h @@ -232,8 +232,6 @@ E size_t strlcpy(char *, const char *, size_t); #ifndef HAVE_STRLCAT E size_t strlcat(char *, const char *, size_t); #endif -E const char *merge_args(int argc, char **argv); -E const char *merge_args(int argc, const char **argv); E time_t dotime(const Anope::string &s); E Anope::string duration(NickCore *nc, time_t seconds); @@ -277,7 +275,6 @@ E void SetDefaultMLock(ServerConfig *config); /**** nickserv.c ****/ -E NickRequest *findrequestnick(const Anope::string &nick); E void get_aliases_stats(long &count, long &mem); E void get_core_stats(long &count, long &mem); E void change_core_display(NickCore *nc); @@ -287,7 +284,6 @@ E int do_setmodes(User *u); E void ns_init(); E int validate_user(User *u); E void expire_nicks(); -E void expire_requests(); E NickAlias *findnick(const Anope::string &nick); E NickCore *findcore(const Anope::string &nick); E bool is_on_access(const User *u, const NickCore *nc); diff --git a/include/language.h b/include/language.h index c27c99087..5e2cdf9e8 100644 --- a/include/language.h +++ b/include/language.h @@ -61,7 +61,6 @@ #define NICK_RECOVERED "User claiming your nick has been killed.\n" \ "\002%R%s RELEASE %s\002 to get it back before %s timeout." #define NICK_REQUESTED "This nick has already been requested, please check your e-mail address for the pass code" -#define NICK_IS_PREREG "This nick is awaiting an e-mail verification code before completing registration." #define NICK_CONFIRM_INVALID "Invalid passcode has been entered, please check the e-mail again, and retry" #define CHAN_NOT_ALLOWED_TO_JOIN "You are not permitted to be on this channel." #define CHAN_X_INVALID "Channel %s is not a valid channel." diff --git a/include/mail.h b/include/mail.h index c62bfb3be..31f35d92d 100644 --- a/include/mail.h +++ b/include/mail.h @@ -3,7 +3,6 @@ #include "anope.h" -extern CoreExport bool Mail(User *u, NickRequest *nr, BotInfo *service, const Anope::string &subject, const Anope::string &message); extern CoreExport bool Mail(User *u, NickCore *nc, BotInfo *service, const Anope::string &subject, const Anope::string &message); extern CoreExport bool Mail(NickCore *nc, const Anope::string &subject, const Anope::string &message); extern CoreExport bool MailValidate(const Anope::string &email); diff --git a/include/modules.h b/include/modules.h index 5b78584d1..8367b084f 100644 --- a/include/modules.h +++ b/include/modules.h @@ -561,14 +561,6 @@ class CoreExport Module : public Extensible */ virtual EventReturn OnDatabaseReadMetadata(NickAlias *na, const Anope::string &key, const std::vector<Anope::string> ¶ms) { return EVENT_CONTINUE; } - /** Called when nickrequest metadata is read from the database - * @param nr The nickrequest - * @parm key The metadata key - * @param params The params from the database - * @return EVENT_CONTINUE to let other modules decide, EVENT_STOP to stop processing - */ - virtual EventReturn OnDatabaseReadMetadata(NickRequest *nr, const Anope::string &key, const std::vector<Anope::string> ¶ms) { return EVENT_CONTINUE; } - /** Called when botinfo metadata is read from the database * @param bi The botinfo * @param key The metadata key @@ -597,12 +589,6 @@ class CoreExport Module : public Extensible */ virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), NickAlias *na) { } - /** Called when we are wrting metadata for a nickrequest - * @param WriteMetata A callback function used to insert the metadata - * @param nr The nick request - */ - virtual void OnDatabaseWriteMetadata(void (*WriteMetadata)(const Anope::string &, const Anope::string &), NickRequest *nr) { } - /** Called when we are writing metadata for a botinfo * @param WriteMetata A callback function used to insert the metadata * @param bi The botinfo @@ -884,16 +870,6 @@ class CoreExport Module : public Extensible */ virtual void OnChangeCoreDisplay(NickCore *nc, const Anope::string &newdisplay) { } - /** called from ns_register.c, after the NickRequest have been created - * @param nr pointer to the NickRequest - */ - virtual void OnMakeNickRequest(NickRequest *nr) { } - - /** called on delnickrequest() - * @param nr pointer to the NickRequest - */ - virtual void OnDelNickRequest(NickRequest *nr) { } - /** called from NickCore::ClearAccess() * @param nc pointer to the NickCore */ @@ -1082,7 +1058,7 @@ enum Implementation I_OnPreNickExpire, I_OnNickExpire, I_OnNickForbidden, I_OnNickGroup, I_OnNickLogout, I_OnNickIdentify, I_OnNickDrop, I_OnNickRegister, I_OnNickSuspended, I_OnNickUnsuspended, I_OnDelNick, I_OnDelCore, I_OnChangeCoreDisplay, - I_OnDelNickRequest, I_OnMakeNickRequest, I_OnNickClearAccess, I_OnNickAddAccess, I_OnNickEraseAccess, + I_OnNickClearAccess, I_OnNickAddAccess, I_OnNickEraseAccess, I_OnNickInfo, I_OnFindNick, I_OnFindCore, /* ChanServ */ diff --git a/include/services.h b/include/services.h index 58c512d0b..cc2bdf331 100644 --- a/include/services.h +++ b/include/services.h @@ -448,7 +448,6 @@ template<typename T> inline T convertTo(const Anope::string &s, bool failIfLefto class User; class NickCore; class NickAlias; -class NickRequest; class BotInfo; class ChannelInfo; class Channel; @@ -879,7 +878,6 @@ struct MailInfo FILE *pipe; User *sender; NickCore *recipient; - NickRequest *recip; }; /*************************************************************************/ diff --git a/modules/core/cs_register.cpp b/modules/core/cs_register.cpp index 34cdc50df..1f1c6e9b2 100644 --- a/modules/core/cs_register.cpp +++ b/modules/core/cs_register.cpp @@ -32,12 +32,10 @@ class CommandCSRegister : public Command Channel *c = findchan(chan); if (readonly) - { source.Reply(_("Sorry, channel registration is temporarily disabled.")); - return MOD_CONT; - } - - if (chan[0] == '&') + else if (u->Account()->HasFlag(NI_UNCONFIRMED)) + source.Reply(_("You must confirm your account before you can register a channel.")); + else if (chan[0] == '&') source.Reply(_("Local channels cannot be registered.")); else if (chan[0] != '#') source.Reply(_(CHAN_SYMBOL_REQUIRED)); diff --git a/modules/core/db_plain.cpp b/modules/core/db_plain.cpp index f47f3156a..4dbf864de 100644 --- a/modules/core/db_plain.cpp +++ b/modules/core/db_plain.cpp @@ -22,7 +22,6 @@ enum MDType MD_NONE, MD_NC, MD_NA, - MD_NR, MD_BI, MD_CH }; @@ -52,7 +51,6 @@ static void ReadDatabase(Module *m = NULL) NickCore *nc = NULL; NickAlias *na = NULL; - NickRequest *nr = NULL; BotInfo *bi = NULL; ChannelInfo *ci = NULL; @@ -100,11 +98,6 @@ static void ReadDatabase(Module *m = NULL) na = findnick(params[2]); Type = MD_NA; } - else if (params[0].equals_ci("NR")) - { - nr = findrequestnick(params[1]); - Type = MD_NR; - } else if (params[0].equals_ci("BI")) { bi = findbot(params[1]); @@ -149,20 +142,6 @@ static void ReadDatabase(Module *m = NULL) Log() << "[db_plain]: " << ex.GetReason(); } } - else if (Type == MD_NR && nr) - { - try - { - if (m) - m->OnDatabaseReadMetadata(nr, key, params); - else - FOREACH_RESULT(I_OnDatabaseReadMetadata, OnDatabaseReadMetadata(nr, key, params)); - } - catch (const DatabaseException &ex) - { - Log() << "[db_plain]: " << ex.GetReason(); - } - } else if (Type == MD_BI && bi) { try @@ -292,17 +271,6 @@ static void LoadNickAlias(const std::vector<Anope::string> ¶ms) Log(LOG_DEBUG_2) << "[db_plain}: Loaded nickalias for " << na->nick; } -static void LoadNickRequest(const std::vector<Anope::string> ¶ms) -{ - NickRequest *nr = new NickRequest(params[0]); - nr->passcode = params[1]; - nr->password = params[2]; - nr->email = params[3]; - nr->requested = params[4].is_pos_number_only() ? convertTo<time_t>(params[4]) : 0; - - Log(LOG_DEBUG_2) << "[db_plain]: Loaded nickrequest for " << nr->nick; -} - static void LoadBotInfo(const std::vector<Anope::string> ¶ms) { BotInfo *bi = findbot(params[0]); @@ -480,8 +448,6 @@ class DBPlain : public Module LoadNickCore(otherparams); else if (key.equals_ci("NA")) LoadNickAlias(otherparams); - else if (key.equals_ci("NR")) - LoadNickRequest(otherparams); else if (key.equals_ci("BI")) LoadBotInfo(otherparams); else if (key.equals_ci("CH")) @@ -765,15 +731,6 @@ class DBPlain : public Module db_buffer << "VER 2" << endl; - for (nickrequest_map::const_iterator it = NickRequestList.begin(), it_end = NickRequestList.end(); it != it_end; ++it) - { - NickRequest *nr = it->second; - - db_buffer << "NR " << nr->nick << " " << nr->passcode << " " << nr->password << " " << nr->email << " " << nr->requested << endl; - - FOREACH_MOD(I_OnDatabaseWriteMetadata, OnDatabaseWriteMetadata(WriteMetadata, nr)); - } - for (nickcore_map::const_iterator nit = NickCoreList.begin(), nit_end = NickCoreList.end(); nit != nit_end; ++nit) { NickCore *nc = nit->second; diff --git a/modules/core/ns_drop.cpp b/modules/core/ns_drop.cpp index e7edcd79a..33a18009d 100644 --- a/modules/core/ns_drop.cpp +++ b/modules/core/ns_drop.cpp @@ -36,30 +36,7 @@ class CommandNSDrop : public Command NickAlias *na = findnick((u->Account() && !nick.empty() ? nick : u->nick)); if (!na) { - NickRequest *nr = findrequestnick(u->Account() && !nick.empty() ? nick : u->nick); - if (nr && u->Account() && u->Account()->IsServicesOper()) - { - Log(LOG_ADMIN, u, this) << "to drop nickname " << nr->nick << " (email: " << nr->email << ")"; - delete nr; - source.Reply(_("Nickname \002%s\002 has been dropped."), nick.c_str()); - } - else if (nr && !nick.empty()) - { - int res = enc_check_password(nick, nr->password); - if (res) - { - Log(LOG_COMMAND, u, this) << "to drop nick request " << nr->nick; - source.Reply(_("Nickname \002%s\002 has been dropped."), nr->nick.c_str()); - delete nr; - } - else if (bad_password(u)) - return MOD_STOP; - else - source.Reply(_(PASSWORD_INCORRECT)); - } - else - source.Reply(_(NICK_NOT_REGISTERED)); - + source.Reply(_(NICK_NOT_REGISTERED)); return MOD_CONT; } diff --git a/modules/core/ns_getpass.cpp b/modules/core/ns_getpass.cpp index fdd5f2cd0..b034e2ba4 100644 --- a/modules/core/ns_getpass.cpp +++ b/modules/core/ns_getpass.cpp @@ -27,18 +27,9 @@ class CommandNSGetPass : public Command const Anope::string &nick = params[0]; Anope::string tmp_pass; NickAlias *na; - NickRequest *nr = NULL; if (!(na = findnick(nick))) - { - if ((nr = findrequestnick(nick))) - { - Log(LOG_ADMIN, u, this) << "for " << nr->nick; - source.Reply(_("Passcode for %s is \002%s\002."), nick.c_str(), nr->passcode.c_str()); - } - else - source.Reply(_(NICK_X_NOT_REGISTERED), nick.c_str()); - } + source.Reply(_(NICK_X_NOT_REGISTERED), nick.c_str()); else if (na->HasFlag(NS_FORBIDDEN)) source.Reply(_(NICK_X_FORBIDDEN), na->nick.c_str()); else if (Config->NSSecureAdmins && na->nc->IsServicesOper()) diff --git a/modules/core/ns_group.cpp b/modules/core/ns_group.cpp index 4ab1d112c..e09a4325a 100644 --- a/modules/core/ns_group.cpp +++ b/modules/core/ns_group.cpp @@ -29,12 +29,6 @@ class CommandNSGroup : public Command const Anope::string &nick = params[0]; Anope::string pass = params[1]; - if (Config->NSEmailReg && findrequestnick(u->nick)) - { - source.Reply(_(NICK_REQUESTED)); - return MOD_CONT; - } - if (readonly) { source.Reply(_("Sorry, nickname grouping is temporarily disabled.")); @@ -121,7 +115,8 @@ class CommandNSGroup : public Command u->Login(na->nc); FOREACH_MOD(I_OnNickGroup, OnNickGroup(u, target)); ircdproto->SetAutoIdentificationToken(u); - u->SetMode(NickServ, UMODE_REGISTERED); + if (target->nc->HasFlag(NI_UNCONFIRMED) == false) + u->SetMode(NickServ, UMODE_REGISTERED); Log(LOG_COMMAND, u, this) << "makes " << u->nick << " join group of " << target->nick << " (" << target->nc->display << ") (email: " << (!target->nc->email.empty() ? target->nc->email : "none") << ")"; source.Reply(_("You are now in the group of \002%s\002."), target->nick.c_str()); diff --git a/modules/core/ns_identify.cpp b/modules/core/ns_identify.cpp index 45b189ca6..074adbb76 100644 --- a/modules/core/ns_identify.cpp +++ b/modules/core/ns_identify.cpp @@ -31,13 +31,7 @@ class CommandNSIdentify : public Command NickAlias *na = findnick(nick), *this_na = findnick(u->nick); if (!na) - { - NickRequest *nr = findrequestnick(nick); - if (nr) - source.Reply(_(NICK_IS_PREREG)); - else - source.Reply(_(NICK_NOT_REGISTERED)); - } + source.Reply(_(NICK_NOT_REGISTERED)); else if (na->HasFlag(NS_FORBIDDEN)) source.Reply(_(NICK_X_FORBIDDEN), na->nick.c_str()); else if (na->nc->HasFlag(NI_SUSPENDED)) @@ -72,7 +66,7 @@ class CommandNSIdentify : public Command ircdproto->SendAccountLogin(u, u->Account()); ircdproto->SetAutoIdentificationToken(u); - if (this_na && this_na->nc == na->nc) + if (this_na && this_na->nc == na->nc && this_na->nc->HasFlag(NI_UNCONFIRMED) == false) u->SetMode(NickServ, UMODE_REGISTERED); u->UpdateHost(); @@ -86,7 +80,7 @@ class CommandNSIdentify : public Command FOREACH_MOD(I_OnNickIdentify, OnNickIdentify(u)); - if (Config->NSForceEmail && u->Account() && u->Account()->email.empty()) + if (Config->NSForceEmail && u->Account()->email.empty()) { source.Reply(_("You must now supply an e-mail for your nick.\n" "This e-mail will allow you to retrieve your password in\n" @@ -96,6 +90,14 @@ class CommandNSIdentify : public Command "any third-party person."), NickServ->nick.c_str()); } + if (u->Account()->HasFlag(NI_UNCONFIRMED)) + { + source.Reply(_("Your email address is not confirmed. To confirm it, follow the instructions that were emailed to you when you registered.")); + time_t time_registered = Anope::CurTime - na->time_registered; + if (Config->NSUnconfirmedExpire > time_registered) + source.Reply(_("Your account will expire, if not confirmed, in %s"), duration(u->Account(), Config->NSUnconfirmedExpire - time_registered).c_str()); + } + check_memos(u); } } diff --git a/modules/core/ns_info.cpp b/modules/core/ns_info.cpp index 52326ddb6..0ac50d471 100644 --- a/modules/core/ns_info.cpp +++ b/modules/core/ns_info.cpp @@ -44,14 +44,7 @@ class CommandNSInfo : public Command if (!na) { - NickRequest *nr = findrequestnick(nick); - if (nr) - { - source.Reply(_(NICK_IS_PREREG)); - if (has_auspex) - source.Reply(_(" E-mail address: %s"), nr->email.c_str()); - } - else if (nickIsServices(nick, true)) + if (nickIsServices(nick, true)) source.Reply(_("Nick \002%s\002 is part of this Network's Services."), nick.c_str()); else source.Reply(_(NICK_X_NOT_REGISTERED), nick.c_str()); @@ -120,11 +113,11 @@ class CommandNSInfo : public Command Anope::string optbuf; - CheckOptStr(optbuf, NI_KILLPROTECT, GetString(u->Account(), _("Protection")).c_str(), na->nc); - CheckOptStr(optbuf, NI_SECURE, GetString(u->Account(), _("Security")).c_str(), na->nc); - CheckOptStr(optbuf, NI_PRIVATE, GetString(u->Account(), _("Private")).c_str(), na->nc); - CheckOptStr(optbuf, NI_MSG, GetString(u->Account(), _("Message mode")).c_str(), na->nc); - CheckOptStr(optbuf, NI_AUTOOP, GetString(u->Account(), _("Auto-op")).c_str(), na->nc); + CheckOptStr(optbuf, NI_KILLPROTECT, _("Protection"), na->nc); + CheckOptStr(optbuf, NI_SECURE, _("Security"), na->nc); + CheckOptStr(optbuf, NI_PRIVATE, _("Private"), na->nc); + CheckOptStr(optbuf, NI_MSG, _("Message mode"), na->nc); + CheckOptStr(optbuf, NI_AUTOOP, _("Auto-op"), na->nc); source.Reply(_(NICK_INFO_OPTIONS), optbuf.empty() ? _("None") : optbuf.c_str()); @@ -136,13 +129,21 @@ class CommandNSInfo : public Command source.Reply(_("This nickname is currently suspended")); } - if (na->HasFlag(NS_NO_EXPIRE)) - source.Reply(_("This nickname will not expire.")); + if (na->nc->HasFlag(NI_UNCONFIRMED) == false) + { + if (na->HasFlag(NS_NO_EXPIRE)) + source.Reply(_("This nickname will not expire.")); + else + source.Reply(_("Expires on: %s"), do_strftime(na->last_seen + Config->NSExpire).c_str()); + } else - source.Reply(_("Expires on: %s"), do_strftime(na->last_seen + Config->NSExpire).c_str()); + source.Reply(_("Expires on: %s"), do_strftime(na->time_registered + Config->NSUnconfirmedExpire).c_str()); } FOREACH_MOD(I_OnNickInfo, OnNickInfo(source, na, show_hidden)); + + if (na->nc->HasFlag(NI_UNCONFIRMED)) + source.Reply(_("This nickname is unconfirmed.")); } return MOD_CONT; } diff --git a/modules/core/ns_list.cpp b/modules/core/ns_list.cpp index 1ecbad3d3..fb8673069 100644 --- a/modules/core/ns_list.cpp +++ b/modules/core/ns_list.cpp @@ -97,67 +97,53 @@ class CommandNSList : public Command mync = u->Account(); source.Reply(_(LIST_HEADER), pattern.c_str()); - if (!unconfirmed) + for (nickalias_map::const_iterator it = NickAliasList.begin(), it_end = NickAliasList.end(); it != it_end; ++it) { - for (nickalias_map::const_iterator it = NickAliasList.begin(), it_end = NickAliasList.end(); it != it_end; ++it) - { - NickAlias *na = it->second; - - /* Don't show private and forbidden nicks to non-services admins. */ - if (na->HasFlag(NS_FORBIDDEN) && !is_servadmin) - continue; - if (na->nc->HasFlag(NI_PRIVATE) && !is_servadmin && na->nc != mync) - continue; - if (forbidden && !na->HasFlag(NS_FORBIDDEN)) + NickAlias *na = it->second; + + /* Don't show private and forbidden nicks to non-services admins. */ + if (na->HasFlag(NS_FORBIDDEN) && !is_servadmin) + continue; + else if (na->nc->HasFlag(NI_PRIVATE) && !is_servadmin && na->nc != mync) + continue; + else if (forbidden && !na->HasFlag(NS_FORBIDDEN)) + continue; + else if (nsnoexpire && !na->HasFlag(NS_NO_EXPIRE)) continue; - else if (nsnoexpire && !na->HasFlag(NS_NO_EXPIRE)) - continue; - else if (suspended && !na->nc->HasFlag(NI_SUSPENDED)) - continue; - - /* We no longer compare the pattern against the output buffer. - * Instead we build a nice nick!user@host buffer to compare. - * The output is then generated separately. -TheShadow */ - snprintf(buf, sizeof(buf), "%s!%s", na->nick.c_str(), !na->last_usermask.empty() && !na->HasFlag(NS_FORBIDDEN) ? na->last_usermask.c_str() : "*@*"); - if (na->nick.equals_ci(pattern) || Anope::Match(buf, pattern)) - { - if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= Config->NSListMax) - { - if (is_servadmin && na->HasFlag(NS_NO_EXPIRE)) - noexpire_char = '!'; - else - noexpire_char = ' '; - if (na->nc->HasFlag(NI_HIDE_MASK) && !is_servadmin && na->nc != mync) - snprintf(buf, sizeof(buf), "%-20s [Hostname Hidden]", na->nick.c_str()); - else if (na->HasFlag(NS_FORBIDDEN)) - snprintf(buf, sizeof(buf), "%-20s [Forbidden]", na->nick.c_str()); - else if (na->nc->HasFlag(NI_SUSPENDED)) - snprintf(buf, sizeof(buf), "%-20s [Suspended]", na->nick.c_str()); - else - snprintf(buf, sizeof(buf), "%-20s %s", na->nick.c_str(), na->last_usermask.c_str()); - source.Reply(" %c%s", noexpire_char, buf); - } - ++count; - } - } - } - - if (unconfirmed || is_servadmin) - { - noexpire_char = ' '; - - for (nickrequest_map::const_iterator it = NickRequestList.begin(), it_end = NickRequestList.end(); it != it_end; ++it) + else if (suspended && !na->nc->HasFlag(NI_SUSPENDED)) + continue; + else if (unconfirmed && na->nc->HasFlag(NI_UNCONFIRMED)) + continue; + + /* We no longer compare the pattern against the output buffer. + * Instead we build a nice nick!user@host buffer to compare. + * The output is then generated separately. -TheShadow */ + snprintf(buf, sizeof(buf), "%s!%s", na->nick.c_str(), !na->last_usermask.empty() && !na->HasFlag(NS_FORBIDDEN) ? na->last_usermask.c_str() : "*@*"); + if (na->nick.equals_ci(pattern) || Anope::Match(buf, pattern)) { - NickRequest *nr = it->second; - - snprintf(buf, sizeof(buf), "%s!*@*", nr->nick.c_str()); - if ((nr->nick.equals_ci(pattern) || Anope::Match(buf, pattern)) && ++nnicks <= Config->NSListMax) + if (((count + 1 >= from && count + 1 <= to) || (!from && !to)) && ++nnicks <= Config->NSListMax) { - snprintf(buf, sizeof(buf), "%-20s [UNCONFIRMED]", nr->nick.c_str()); + if (is_servadmin && na->HasFlag(NS_NO_EXPIRE)) + noexpire_char = '!'; + else + noexpire_char = ' '; + if (na->nc->HasFlag(NI_HIDE_MASK) && !is_servadmin && na->nc != mync) + snprintf(buf, sizeof(buf), "%-20s [Hostname Hidden]", na->nick.c_str()); + else if (na->HasFlag(NS_FORBIDDEN)) + snprintf(buf, sizeof(buf), "%-20s [Forbidden]", na->nick.c_str()); + else if (na->nc->HasFlag(NI_SUSPENDED)) + snprintf(buf, sizeof(buf), "%-20s [Suspended]", na->nick.c_str()); + else if (na->nc->HasFlag(NI_UNCONFIRMED)) + snprintf(buf, sizeof(buf), "%-20s [Unconfirmed]", na->nick.c_str()); + else + snprintf(buf, sizeof(buf), "%-20s %s", na->nick.c_str(), na->last_usermask.c_str()); source.Reply(" %c%s", noexpire_char, buf); } + ++count; } } + + source.Reply(_("End of list - %d/%d matches shown."), nnicks > Config->NSListMax ? Config->NSListMax : nnicks, nnicks); return MOD_CONT; } diff --git a/modules/core/ns_register.cpp b/modules/core/ns_register.cpp index d7867896c..d336f1f4d 100644 --- a/modules/core/ns_register.cpp +++ b/modules/core/ns_register.cpp @@ -13,147 +13,67 @@ #include "module.h" -static bool SendRegmail(User *u, NickRequest *nr); +static bool SendRegmail(User *u, NickAlias *na); class CommandNSConfirm : public Command { - protected: - CommandReturn ActuallyConfirmNick(CommandSource &source, NickRequest *nr, bool force) + public: + CommandNSConfirm() : Command("CONFIRM", 1, 2) { - User *u = source.u; - NickAlias *na = new NickAlias(nr->nick, new NickCore(nr->nick)); - Anope::string tmp_pass; - - na->nc->pass = nr->password; - - if (force) - { - na->last_usermask = "*@*"; - na->last_realname = "unknown"; - } - else - { - Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost(); - na->last_usermask = last_usermask; - na->last_realname = u->realname; - if (Config->NSAddAccessOnReg) - na->nc->AddAccess(create_mask(u)); - } - - if (!nr->email.empty()) - na->nc->email = nr->email; - - if (!force) - { - u->Login(na->nc); - Log(LOG_COMMAND, u, this) << "to register " << nr->nick << " (email: " << (!nr->email.empty() ? nr->email : "none") << ")"; - if (Config->NSAddAccessOnReg) - source.Reply(_("Nickname \002%s\002 registered under your account: %s"), u->nick.c_str(), na->nc->GetAccess(0).c_str()); - else - source.Reply(_("Nickname \002%s\002 registered."), u->nick.c_str()); - delete nr; - - ircdproto->SendAccountLogin(u, u->Account()); - ircdproto->SetAutoIdentificationToken(u); - - if (enc_decrypt(na->nc->pass, tmp_pass) == 1) - source.Reply(_("Your password is \002%s\002 - remember this for later use."), tmp_pass.c_str()); - - u->lastnickreg = Anope::CurTime; - } - else - { - Log(LOG_COMMAND, u, this) << "to confirm " << nr->nick << " (email: " << (!nr->email.empty() ? nr->email : "none") << ")"; - source.Reply(_("Nickname \002%s\002 confirmed"), nr->nick.c_str()); - User *user = finduser(nr->nick); - /* Delrequest must be called before validate_user */ - delete nr; - if (user) - validate_user(user); - } - - FOREACH_MOD(I_OnNickRegister, OnNickRegister(na)); - - return MOD_CONT; + this->SetFlag(CFLAG_ALLOW_UNREGISTERED); + this->SetDesc("Confirm an auth code"); } - CommandReturn DoConfirm(CommandSource &source, const std::vector<Anope::string> ¶ms) + CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) { User *u = source.u; - Anope::string passcode = !params.empty() ? params[0] : ""; + const Anope::string &passcode = params[0]; - NickRequest *nr = findrequestnick(u->nick); - - if (Config->NSEmailReg) + if (u->Account() && u->Account()->HasPriv("nickserv/confirm")) { - if (passcode.empty()) - { - this->OnSyntaxError(source, ""); - return MOD_CONT; - } - - if (!nr) + NickAlias *na = findnick(passcode); + if (na == NULL) + source.Reply(_(NICK_X_NOT_REGISTERED), passcode.c_str()); + else if (na->nc->HasFlag(NI_UNCONFIRMED) == false) + source.Reply(_("Nick \002%s\002 is already confirmed."), na->nick.c_str()); { - if (u->Account() && u->Account()->HasPriv("nickserv/confirm")) - { - /* If an admin, their nick is obviously already regged, so look at the passcode to get the nick - of the user they are trying to validate, and push that user through regardless of passcode */ - nr = findrequestnick(passcode); - if (nr) - { - ActuallyConfirmNick(source, nr, true); - return MOD_CONT; - } - } - source.Reply(_("Registration step 1 may have expired, please use \"%R%s register <password> <email>\" first."), Config->s_NickServ.c_str()); - - return MOD_CONT; - } - - if (!nr->passcode.equals_cs(passcode)) - { - source.Reply(_(NICK_CONFIRM_INVALID)); - return MOD_CONT; + na->nc->UnsetFlag(NI_UNCONFIRMED); + Log(LOG_ADMIN, u, this) << "to confirm nick " << na->nick << " (" << na->nc->display << ")"; + source.Reply(_("Nick \002%s\002 has been confirmed."), na->nick.c_str()); } } - - if (!nr) + else if (u->Account()) { - source.Reply(_("Sorry, registration failed.")); - return MOD_CONT; + Anope::string code; + if (u->Account()->GetExtRegular<Anope::string>("ns_register_passcode", code) && code == passcode) + { + u->Account()->Shrink("ns_register_passcode"); + Log(LOG_COMMAND, u, this) << "to confirm their email"; + source.Reply(_("Your email address of \002%s\002 has been confirmed."), u->Account()->email.c_str()); + u->Account()->UnsetFlag(NI_UNCONFIRMED); + } + else + source.Reply(_("Invalid passcode.")); } + else + source.Reply(_("Invalid passcode.")); - ActuallyConfirmNick(source, nr, false); return MOD_CONT; } - public: - CommandNSConfirm(const Anope::string &cmdn, int min, int max) : Command(cmdn, min, max) - { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); - this->SetDesc("Confirm a nickserv auth code"); - } - - CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) - { - return this->DoConfirm(source, params); - } - bool OnHelp(CommandSource &source, const Anope::string &subcommand) { User *u = source.u; source.Reply(_("Syntax: \002CONFIRM \037passcode\037\002\n" " \n" - "This is the second step of nickname registration process.\n" - "You must perform this command in order to get your nickname\n" - "registered with %s. The passcode (or called auth code also)\n" - "is sent to your e-mail address in the first step of the\n" - "registration process. For more information about the first\n" - "stage of the registration process, type: \002%R%s HELP REGISTER\002\n" + "This command is used by several commands as a way to confirm\n" + "changes made to your account.\n" + " \n" + "This is most commonly used to confirm your email address once\n" + "you register or change it.\n" " \n" "This is also used after the RESETPASS command has been used to\n" - "force identify you to your nick so you may change your password."), - NickServ->nick.c_str()); + "force identify you to your nick so you may change your password.")); if (u->Account() && u->Account()->HasPriv("nickserv/confirm")) source.Reply(_("Additionally, Services Operators with the \037nickserv/confirm\037 permission can\n" "replace \037passcode\037 with a users nick to force validate them.")); @@ -166,10 +86,10 @@ class CommandNSConfirm : public Command } }; -class CommandNSRegister : public CommandNSConfirm +class CommandNSRegister : public Command { public: - CommandNSRegister() : CommandNSConfirm("REGISTER", 1, 2) + CommandNSRegister() : Command("REGISTER", 1, 2) { this->SetFlag(CFLAG_ALLOW_UNREGISTERED); this->SetDesc("Register a nickname"); @@ -178,22 +98,11 @@ class CommandNSRegister : public CommandNSConfirm CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) { User *u = source.u; - NickRequest *nr = NULL, *anr = NULL; NickAlias *na; size_t prefixlen = Config->NSGuestNickPrefix.length(); size_t nicklen = u->nick.length(); Anope::string pass = params[0]; Anope::string email = params.size() > 1 ? params[1] : ""; - Anope::string passcode; - int idx, min = 1, max = 62; - int chars[] = { - ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', - 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', - 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' - }; - std::list<std::pair<Anope::string, Anope::string> >::iterator it, it_end; if (readonly) { @@ -207,12 +116,6 @@ class CommandNSRegister : public CommandNSConfirm return MOD_CONT; } - if ((anr = findrequestnick(u->nick))) - { - source.Reply(_(NICK_REQUESTED)); - return MOD_CONT; - } - /* Prevent "Guest" nicks from being registered. -TheShadow */ /* Guest nick can now have a series of between 1 and 7 digits. @@ -231,7 +134,7 @@ class CommandNSRegister : public CommandNSConfirm } if (Config->RestrictOperNicks) - for (it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it) + for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = Config->Opers.begin(), it_end = Config->Opers.end(); it != it_end; ++it) { Anope::string nick = it->first; @@ -265,38 +168,46 @@ class CommandNSRegister : public CommandNSConfirm source.Reply(_(MAIL_X_INVALID), email.c_str()); else { - for (idx = 0; idx < 9; ++idx) - passcode += chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min]; - nr = new NickRequest(u->nick); - nr->passcode = passcode; - enc_encrypt(pass, nr->password); + na = new NickAlias(u->nick, new NickCore(u->nick)); + enc_encrypt(pass, na->nc->pass); if (!email.empty()) - nr->email = email; - nr->requested = Anope::CurTime; - FOREACH_MOD(I_OnMakeNickRequest, OnMakeNickRequest(nr)); + na->nc->email = email; + + Anope::string last_usermask = u->GetIdent() + "@" + u->GetDisplayedHost(); + na->last_usermask = last_usermask; + na->last_realname = u->realname; + if (Config->NSAddAccessOnReg) + na->nc->AddAccess(create_mask(u)); + + u->Login(na->nc); + + Log(LOG_COMMAND, u, this) << "to register " << na->nick << " (email: " << (!na->nc->email.empty() ? na->nc->email : "none") << ")"; + + FOREACH_MOD(I_OnNickRegister, OnNickRegister(na)); + + if (Config->NSAddAccessOnReg) + source.Reply(_("Nickname \002%s\002 registered under your account: %s"), u->nick.c_str(), na->nc->GetAccess(0).c_str()); + else + source.Reply(_("Nickname \002%s\002 registered."), u->nick.c_str()); + + Anope::string tmp_pass; + if (enc_decrypt(na->nc->pass, tmp_pass) == 1) + source.Reply(_("Your password is \002%s\002 - remember this for later use."), tmp_pass.c_str()); + if (Config->NSEmailReg) { - if (SendRegmail(u, nr)) + na->nc->SetFlag(NI_UNCONFIRMED); + if (SendRegmail(u, na)) { - source.Reply(_("A passcode has been sent to %s, please type %R%s confirm <passcode> to complete registration.\n" - "If you need to cancel your registration, use \"%R%s drop <password>\"."), - email.c_str(), Config->s_NickServ.c_str(), Config->s_NickServ.c_str()); - - Log(LOG_COMMAND, u, this) << "send registration verification code to " << nr->email; - } - else - { - Log(LOG_COMMAND, u, this) << "unable to send registration verification mail"; - source.Reply(_("Nick NOT registered, please try again later.")); - delete nr; - return MOD_CONT; + source.Reply(_("A passcode has been sent to %s, please type %R%s confirm <passcode> to confirm your email address."), email.c_str(), NickServ->nick.c_str()); + source.Reply(_("If you do not confirm your email address within %s your account will expire."), duration(na->nc, Config->NSUnconfirmedExpire).c_str()); } } - else - { - std::vector<Anope::string> empty_params; - return this->DoConfirm(source, empty_params); - } + + ircdproto->SendAccountLogin(u, u->Account()); + ircdproto->SetAutoIdentificationToken(u); + + u->lastnickreg = Anope::CurTime; } return MOD_CONT; @@ -353,47 +264,54 @@ class CommandNSResend : public Command public: CommandNSResend() : Command("RESEND", 0, 0) { - this->SetFlag(CFLAG_ALLOW_UNREGISTERED); - this->SetDesc("Resend a nickserv auth code"); } CommandReturn Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) { + if (!Config->NSEmailReg) + return MOD_CONT; + User *u = source.u; - NickRequest *nr = NULL; - if (Config->NSEmailReg) + NickAlias *na = findnick(u->nick); + + if (na == NULL) + source.Reply(_(NICK_NOT_REGISTERED)); + else if (na->nc != u->Account() || u->Account()->HasFlag(NI_UNCONFIRMED) == false) + source.Reply(_("Your account is already confirmed.")); + else { - if ((nr = findrequestnick(u->nick))) + if (Anope::CurTime < u->Account()->lastmail + Config->NSResendDelay) + source.Reply(_("Cannot send mail now; please retry a little later.")); + else if (!SendRegmail(u, na)) { - if (Anope::CurTime < nr->lastmail + Config->NSResendDelay) - { - source.Reply(_("Cannot send mail now; please retry a little later.")); - return MOD_CONT; - } - if (!SendRegmail(u, nr)) - { - nr->lastmail = Anope::CurTime; - source.Reply(_("Your passcode has been re-sent to %s."), nr->email.c_str()); - Log(LOG_COMMAND, u, this) << "resend registration verification code for " << nr->nick; - } - else - { - Log(LOG_COMMAND, u, this) << "unable to resend registration verification code for " << nr->nick; - return MOD_CONT; - } + na->nc->lastmail = Anope::CurTime; + source.Reply(_("Your passcode has been re-sent to %s."), na->nc->email.c_str()); + Log(LOG_COMMAND, u, this) << "to resend registration verification code"; } + else + Log() << "Unable to resend registration verification code for " << u->nick; } + return MOD_CONT; } bool OnHelp(CommandSource &source, const Anope::string &subcommand) { + if (!Config->NSEmailReg) + return false; + source.Reply(_("Syntax: \002RESEND\002\n" " \n" "This command will re-send the auth code (also called passcode)\n" "to the e-mail address of the user whom is performing it.")); return true; } + + void OnServHelp(CommandSource &source) + { + if (Config->NSEmailReg) + source.Reply(_("Resend the registration passcode")); + } }; class NSRegister : public Module @@ -403,7 +321,7 @@ class NSRegister : public Module CommandNSResend commandnsrsend; public: - NSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator), commandnsconfirm("CONFIRM", 1, 1) + NSRegister(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator) { this->SetAuthor("Anope"); this->SetType(CORE); @@ -414,21 +332,40 @@ class NSRegister : public Module } }; -static bool SendRegmail(User *u, NickRequest *nr) +static bool SendRegmail(User *u, NickAlias *na) { - char subject[BUFSIZE], message[BUFSIZE]; + Anope::string code; + if (na->nc->GetExtRegular<Anope::string>("ns_register_passcode", code) == false) + { + int chars[] = { + ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', + 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', + 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' + }; + int idx, min = 1, max = 62; + for (idx = 0; idx < 9; ++idx) + code += chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min]; + na->nc->Extend("ns_register_passcode", new ExtensibleItemRegular<Anope::string>(code)); + } - snprintf(subject, sizeof(subject), GetString(NULL, "Nickname Registration (%s)").c_str(), nr->nick.c_str()); - snprintf(message, sizeof(message), GetString(NULL, "Hi,\n" + Anope::string subject = Anope::printf(_("Nickname Registration (%s)"), na->nick.c_str()); + Anope::string message = Anope::printf(_("Hi,\n" " \n" "You have requested to register the nickname %s on %s.\n" "Please type \" %R%s confirm %s \" to complete registration.\n" " \n" "If you don't know why this mail was sent to you, please ignore it silently.\n" " \n" - "%s administrators.").c_str(), nr->nick.c_str(), Config->NetworkName.c_str(), Config->s_NickServ.c_str(), nr->passcode.c_str(), Config->NetworkName.c_str()); + "%s administrators."), na->nick.c_str(), Config->NetworkName.c_str(), Config->s_NickServ.c_str(), code.c_str(), Config->NetworkName.c_str()); + + if (Config->UseStrictPrivMsg) + message = message.replace_all_cs("%R", "/"); + else + message = message.replace_all_cs("%R", "/msg "); - return Mail(u, nr, NickServ, subject, message); + return Mail(u, na->nc, NickServ, subject, message); } MODULE_INIT(NSRegister) diff --git a/modules/core/ns_resetpass.cpp b/modules/core/ns_resetpass.cpp index 068cb2b4f..7f9a3fd11 100644 --- a/modules/core/ns_resetpass.cpp +++ b/modules/core/ns_resetpass.cpp @@ -31,7 +31,7 @@ class CommandNSResetPass : public Command if (Config->RestrictMail && (!u->Account() || !u->Account()->HasCommand("nickserv/resetpass"))) source.Reply(_(ACCESS_DENIED)); - if (!(na = findnick(params[0]))) + else if (!(na = findnick(params[0]))) source.Reply(_(NICK_X_NOT_REGISTERED), params[0].c_str()); else if (na->HasFlag(NS_FORBIDDEN)) source.Reply(_(NICK_X_FORBIDDEN), na->nick.c_str()); @@ -82,36 +82,40 @@ class NSResetPass : public Module EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> ¶ms) { User *u = source.u; - BotInfo *service = source.owner; - if (service == NickServ && command->name.equals_ci("CONFIRM") && !params.empty()) + if (command->service == NickServ && command->name.equals_ci("CONFIRM") && params.size() > 1) { - NickAlias *na = findnick(source.u->nick); + NickAlias *na = findnick(params[0]); time_t t; Anope::string c; if (na && na->nc->GetExtRegular("ns_resetpass_code", c) && na->nc->GetExtRegular("ns_resetpass_time", t)) { + const Anope::string &passcode = params[1]; if (t < Anope::CurTime - 3600) { na->nc->Shrink("ns_resetpass_code"); na->nc->Shrink("ns_resetpass_time"); source.Reply(_("Your password reset request has expired.")); - return EVENT_STOP; } - - Anope::string passcode = params[0]; - if (passcode.equals_cs(c)) + else if (passcode.equals_cs(c)) { na->nc->Shrink("ns_resetpass_code"); na->nc->Shrink("ns_resetpass_time"); - u->UpdateHost(); - na->last_realname = u->realname; - na->last_seen = Anope::CurTime; + NickAlias *this_na = findnick(u->nick); + + if (this_na && this_na == na) + { + u->UpdateHost(); + na->last_realname = u->realname; + na->last_seen = Anope::CurTime; + u->SetMode(NickServ, UMODE_REGISTERED); + } + u->Login(na->nc); ircdproto->SendAccountLogin(u, u->Account()); ircdproto->SetAutoIdentificationToken(u); - u->SetMode(NickServ, UMODE_REGISTERED); + na->nc->UnsetFlag(NI_UNCONFIRMED); FOREACH_MOD(I_OnNickIdentify, OnNickIdentify(u)); Log(LOG_COMMAND, u, &commandnsresetpass) << "confirmed RESETPASS to forcefully identify to " << na->nick; @@ -124,11 +128,7 @@ class NSResetPass : public Module check_memos(u); } else - { - Log(LOG_COMMAND, u, &commandnsresetpass) << "invalid confirm passcode for " << na->nick; - source.Reply(_(NICK_CONFIRM_INVALID)); - bad_password(u); - } + return EVENT_CONTINUE; return EVENT_STOP; } @@ -140,10 +140,6 @@ class NSResetPass : public Module static bool SendResetEmail(User *u, NickAlias *na) { - char subject[BUFSIZE], message[BUFSIZE]; - - snprintf(subject, sizeof(subject), GetString(na->nc, _("Reset password request for %s")).c_str(), na->nick.c_str()); - int min = 1, max = 62; int chars[] = { ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', @@ -158,18 +154,21 @@ static bool SendResetEmail(User *u, NickAlias *na) for (idx = 0; idx < 20; ++idx) passcode += chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min]; - snprintf(message, sizeof(message), GetString(na->nc, + Anope::string subject = Anope::printf(GetString(na->nc, "Reset password request for %s"), na->nick.c_str()); + Anope::string message = Anope::printf(GetString(na->nc, "Hi,\n" " \n" "You have requested to have the password for %s reset.\n" - "To reset your password, type \002%R%s CONFIRM %s\002\n" + "To reset your password, type %R%s CONFIRM %s %s\n" " \n" "If you don't know why this mail was sent to you, please ignore it silently.\n" " \n" - "%s administrators.").c_str(), na->nick.c_str(), Config->s_NickServ.c_str(), passcode.c_str(), Config->NetworkName.c_str()); + "%s administrators."), na->nick.c_str(), Config->s_NickServ.c_str(), na->nick.c_str(), passcode.c_str(), Config->NetworkName.c_str()); - na->nc->Shrink("ns_resetpass_code"); - na->nc->Shrink("ns_resetpass_time"); + if (Config->UseStrictPrivMsg) + message = message.replace_all_cs("%R", "/"); + else + message = message.replace_all_cs("%R", "/msg "); na->nc->Extend("ns_resetpass_code", new ExtensibleItemRegular<Anope::string>(passcode)); na->nc->Extend("ns_resetpass_time", new ExtensibleItemRegular<time_t>(Anope::CurTime)); diff --git a/modules/core/ns_set_email.cpp b/modules/core/ns_set_email.cpp index 6d6d97795..f6374f240 100644 --- a/modules/core/ns_set_email.cpp +++ b/modules/core/ns_set_email.cpp @@ -13,6 +13,39 @@ #include "module.h" +static bool SendConfirmMail(User *u) +{ + int chars[] = { + ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', + 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', + 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' + }; + int idx, min = 1, max = 62; + Anope::string code; + for (idx = 0; idx < 9; ++idx) + code += chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min]; + u->Account()->Extend("ns_set_email_passcode", new ExtensibleItemRegular<Anope::string>(code)); + + Anope::string subject = _("Email confirmation"); + Anope::string message = Anope::printf(_("Hi,\n" + " \n" + "You have requested to change your email address to %s.\n" + "Please type \" %R%s confirm %s \" to confirm this change.\n" + " \n" + "If you don't know why this mail was sent to you, please ignore it silently.\n" + " \n" + "%s administrators."), u->Account()->email.c_str(), Config->s_NickServ.c_str(), code.c_str(), Config->NetworkName.c_str()); + + if (Config->UseStrictPrivMsg) + message = message.replace_all_cs("%R", "/"); + else + message = message.replace_all_cs("%R", "/msg "); + + return Mail(u, u->Account(), NickServ, subject, message); +} + class CommandNSSetEmail : public Command { public: @@ -47,15 +80,27 @@ class CommandNSSetEmail : public Command return MOD_CONT; } - if (!param.empty()) + if (!param.empty() && Config->NSConfirmEmailChanges && !u->Account()->IsServicesOper()) { - nc->email = param; - source.Reply(_("E-mail address for \002%s\002 changed to \002%s\002."), nc->display.c_str(), param.c_str()); + u->Account()->Extend("ns_set_email", new ExtensibleItemRegular<Anope::string>(param)); + Anope::string old = u->Account()->email; + u->Account()->email = param; + if (SendConfirmMail(u)) + source.Reply(_("A confirmation email has been sent to \002%s\002. Follow the instructions in it to change your email address."), param.c_str()); + u->Account()->email = old; } else { - nc->email.clear(); - source.Reply(_("E-mail address for \002%s\002 unset."), nc->display.c_str()); + if (!param.empty()) + { + nc->email = param; + source.Reply(_("E-mail address for \002%s\002 changed to \002%s\002."), nc->display.c_str(), param.c_str()); + } + else + { + nc->email.clear(); + source.Reply(_("E-mail address for \002%s\002 unset."), nc->display.c_str()); + } } return MOD_CONT; @@ -99,6 +144,8 @@ class NSSetEmail : public Module this->SetAuthor("Anope"); this->SetType(CORE); + ModuleManager::Attach(I_OnPreCommand, this); + Command *c = FindCommand(NickServ, "SET"); if (c) c->AddSubcommand(this, &commandnssetemail); @@ -118,6 +165,29 @@ class NSSetEmail : public Module if (c) c->DelSubcommand(&commandnssasetemail); } + + EventReturn OnPreCommand(CommandSource &source, Command *command, const std::vector<Anope::string> ¶ms) + { + User *u = source.u; + if (command->service == NickServ && command->name.equals_ci("CONFIRM") && !params.empty() && u->IsIdentified()) + { + Anope::string new_email, passcode; + if (u->Account()->GetExtRegular("ns_set_email", new_email) && u->Account()->GetExtRegular("ns_set_email_passcode", passcode)) + { + if (params[0] == passcode) + { + u->Account()->email = new_email; + Log(LOG_COMMAND, u, command) << "to confirm their email address change to " << u->Account()->email; + source.Reply(_("Your email address has been changed to \002%s\002."), u->Account()->email.c_str()); + u->Account()->Shrink("ns_set_email"); + u->Account()->Shrink("ns_set_email_passcode"); + return EVENT_STOP; + } + } + } + + return EVENT_CONTINUE; + } }; MODULE_INIT(NSSetEmail) diff --git a/modules/extra/db_mysql.cpp b/modules/extra/db_mysql.cpp index 4b06c8ef1..f6dce95d2 100644 --- a/modules/extra/db_mysql.cpp +++ b/modules/extra/db_mysql.cpp @@ -217,8 +217,8 @@ class DBMySQL : public Module I_OnSaveDatabase, I_OnPostCommand, /* NickServ */ I_OnNickAddAccess, I_OnNickEraseAccess, I_OnNickClearAccess, - I_OnDelCore, I_OnNickForbidden, I_OnNickGroup, I_OnMakeNickRequest, - I_OnDelNickRequest, I_OnNickRegister, I_OnChangeCoreDisplay, + I_OnDelCore, I_OnNickForbidden, I_OnNickGroup, + I_OnNickRegister, I_OnChangeCoreDisplay, I_OnNickSuspended, I_OnDelNick, /* ChanServ */ I_OnAccessAdd, I_OnAccessDel, I_OnAccessChange, I_OnAccessClear, I_OnLevelChange, @@ -236,7 +236,7 @@ class DBMySQL : public Module /* HostServ */ I_OnSetVhost, I_OnDeleteVhost }; - ModuleManager::Attach(i, this, 42); + ModuleManager::Attach(i, this, 40); } EventReturn OnLoadDatabase() @@ -588,16 +588,6 @@ class DBMySQL : public Module FOREACH_RESULT(I_OnDatabaseReadMetadata, OnDatabaseReadMetadata(ci, ci->name, Params)); } - r = SQL->RunQuery("SELECT * FROM `anope_ns_request`"); - for (int i = 0; i < r.Rows(); ++i) - { - NickRequest *nr = new NickRequest(r.Get(i, "nick")); - nr->password = r.Get(i, "passcode"); - nr->password = r.Get(i, "password"); - nr->email = r.Get(i, "email"); - nr->requested = r.Get(i, "requested").is_pos_number_only() ? convertTo<time_t>(r.Get(i, "requested")) : Anope::CurTime; - } - r = SQL->RunQuery("SELECT * FROM `anope_ms_info`"); for (int i = 0; i < r.Rows(); ++i) { @@ -947,16 +937,6 @@ class DBMySQL : public Module OnNickRegister(findnick(u->nick)); } - void OnMakeNickRequest(NickRequest *nr) - { - this->RunQuery("INSERT INTO `anope_ns_request` (nick, passcode, password, email, requested) VALUES('" + this->Escape(nr->nick) + "', '" + this->Escape(nr->passcode) + "', '" + this->Escape(nr->password) + "', '" + this->Escape(nr->email) + "', " + stringify(nr->requested) + ")"); - } - - void OnDelNickRequest(NickRequest *nr) - { - this->RunQuery("DELETE FROM `anope_ns_request` WHERE `nick` = '" + this->Escape(nr->nick) + "'"); - } - void InsertAlias(NickAlias *na) { this->RunQuery("INSERT INTO `anope_ns_alias` (nick, last_quit, last_realname, last_usermask, time_registered, last_seen, flags, display) VALUES('" + @@ -1369,11 +1349,6 @@ static void SaveDatabases() } } - me->RunQuery("TRUNCATE TABLE `anope_ns_request`"); - - for (nickrequest_map::const_iterator it = NickRequestList.begin(), it_end = NickRequestList.end(); it != it_end; ++it) - me->OnMakeNickRequest(it->second); - if (SGLine) for (unsigned i = 0, end = SGLine->GetCount(); i < end; ++i) me->OnAddAkill(NULL, SGLine->GetEntry(i)); diff --git a/modules/extra/m_ldap.cpp b/modules/extra/m_ldap.cpp index 0d198e27d..1d5aeca09 100644 --- a/modules/extra/m_ldap.cpp +++ b/modules/extra/m_ldap.cpp @@ -222,7 +222,10 @@ class ModuleLDAP : public Module, public Pipe ~ModuleLDAP() { for (std::map<Anope::string, LDAPService *>::iterator it = this->LDAPServices.begin(); it != this->LDAPServices.end(); ++it) + { it->second->SetExitState(); + it->second->Wakeup(); + } LDAPServices.clear(); } @@ -239,7 +242,7 @@ class ModuleLDAP : public Module, public Pipe for (i = 0, num = config.Enumerate("ldap"); i < num; ++i) { - if (config.ReadValue("ldap", "name", "", i) == cname) + if (config.ReadValue("ldap", "name", "main", i) == cname) { break; } @@ -250,6 +253,7 @@ class ModuleLDAP : public Module, public Pipe Log(LOG_NORMAL, "ldap") << "LDAP: Removing server connection " << cname; s->SetExitState(); + s->Wakeup(); this->LDAPServices.erase(cname); } } diff --git a/modules/extra/m_mysql.cpp b/modules/extra/m_mysql.cpp index e26d13b6a..9895d025d 100644 --- a/modules/extra/m_mysql.cpp +++ b/modules/extra/m_mysql.cpp @@ -186,7 +186,7 @@ class ModuleSQL : public Module, public Pipe for (i = 0, num = config.Enumerate("mysql"); i < num; ++i) { - if (config.ReadValue("mysql", "name", "", i) == cname) + if (config.ReadValue("mysql", "name", "main", i) == cname) { break; } diff --git a/modules/extra/ns_identify_ldap.cpp b/modules/extra/ns_identify_ldap.cpp index 7bc237289..6e01e0103 100644 --- a/modules/extra/ns_identify_ldap.cpp +++ b/modules/extra/ns_identify_ldap.cpp @@ -68,7 +68,7 @@ class IdentifyInterface : public LDAPInterface, public Command ircdproto->SendAccountLogin(u, u->Account()); ircdproto->SetAutoIdentificationToken(u); - if (this_na && this_na->nc == na->nc) + if (this_na && this_na->nc == na->nc && this_na->nc->HasFlag(NI_UNCONFIRMED) == false) u->SetMode(NickServ, UMODE_REGISTERED); u->UpdateHost(); diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index be782fe18..285fd316c 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -296,7 +296,8 @@ class BahamutIRCdMessage : public IRCdMessage if (user->timestamp == convertTo<time_t>(params[7]) && (na = findnick(user->nick))) { user->Login(na->nc); - user->SetMode(NickServ, UMODE_REGISTERED); + if (na->nc->HasFlag(NI_UNCONFIRMED) == false) + user->SetMode(NickServ, UMODE_REGISTERED); } else validate_user(user); diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp index 0689b8605..e4ccd90b6 100644 --- a/modules/protocol/inspircd11.cpp +++ b/modules/protocol/inspircd11.cpp @@ -296,7 +296,8 @@ class InspircdIRCdMessage : public IRCdMessage if (na && na->nc->GetExtRegular("authenticationtoken", svidbuf) && svidbuf == params[0]) { user->Login(na->nc); - user->SetMode(NickServ, UMODE_REGISTERED); + if (na->nc->HasFlag(NI_UNCONFIRMED)) + user->SetMode(NickServ, UMODE_REGISTERED); } else validate_user(user); diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp index d2ae35c9f..f89ef2dc9 100644 --- a/modules/protocol/inspircd12.cpp +++ b/modules/protocol/inspircd12.cpp @@ -264,7 +264,7 @@ bool event_metadata(const Anope::string &source, const std::vector<Anope::string if (u && nc) { u->Login(nc); - if (user_na && user_na->nc == nc) + if (user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false) u->SetMode(NickServ, UMODE_REGISTERED); } } diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index a0fd55481..908868463 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -274,7 +274,7 @@ bool event_metadata(const Anope::string &source, const std::vector<Anope::string if (u && nc) { u->Login(nc); - if (user_na && user_na->nc == nc) + if (user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false) u->SetMode(NickServ, UMODE_REGISTERED); } } diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp index 9d360312e..a7ebabd86 100644 --- a/modules/protocol/plexus.cpp +++ b/modules/protocol/plexus.cpp @@ -526,7 +526,7 @@ bool event_encap(const Anope::string &source, const std::vector<Anope::string> & if (u && nc) { u->Login(nc); - if (user_na && user_na->nc == nc) + if (user_na && user_na->nc == nc && user_na->nc->HasFlag(NI_UNCONFIRMED) == false) u->SetMode(NickServ, UMODE_REGISTERED); } } diff --git a/modules/protocol/unreal32.cpp b/modules/protocol/unreal32.cpp index 89940ab42..c510a4976 100644 --- a/modules/protocol/unreal32.cpp +++ b/modules/protocol/unreal32.cpp @@ -427,7 +427,8 @@ class Unreal32IRCdMessage : public IRCdMessage if (na && user->timestamp == convertTo<time_t>(params[6])) { user->Login(na->nc); - user->SetMode(NickServ, UMODE_REGISTERED); + if (na->nc->HasFlag(NI_UNCONFIRMED) == false) + user->SetMode(NickServ, UMODE_REGISTERED); } else validate_user(user); @@ -448,7 +449,8 @@ class Unreal32IRCdMessage : public IRCdMessage if (na && user->timestamp == convertTo<time_t>(params[6])) { user->Login(na->nc); - user->SetMode(NickServ, UMODE_REGISTERED); + if (na->nc->HasFlag(NI_UNCONFIRMED) == false) + user->SetMode(NickServ, UMODE_REGISTERED); } else validate_user(user); diff --git a/src/commands.cpp b/src/commands.cpp index 425c72671..00fe6574c 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -65,7 +65,7 @@ void mod_run_cmd(BotInfo *bi, User *u, ChannelInfo *ci, Command *c, const Anope: // Command requires registered users only if (!c->HasFlag(CFLAG_ALLOW_UNREGISTERED) && !u->IsIdentified()) { - u->SendMessage(bi, _(_(NICK_IDENTIFY_REQUIRED)), Config->s_NickServ.c_str()); + u->SendMessage(bi, _(NICK_IDENTIFY_REQUIRED), Config->s_NickServ.c_str()); Log(LOG_COMMAND, "denied", bi) << "Access denied for unregistered user " << u->GetMask() << " with command " << command; PopLanguage(); return; diff --git a/src/config.cpp b/src/config.cpp index cc0879936..ae8ccfc8c 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -480,7 +480,7 @@ bool ValidateEmailReg(ServerConfig *config, const Anope::string &tag, const Anop { if (config->NSEmailReg) { - if (value.equals_ci("preregexpire")) + if (value.equals_ci("unconfirmedexpire")) { if (!data.GetInteger() && !dotime(data.GetValue())) throw ConfigException("The value for <" + tag + ":" + value + "> must be non-zero when e-mail registration are enabled!"); @@ -1070,6 +1070,7 @@ void ServerConfig::Read() {"nickserv", "emailregistration", "no", new ValueContainerBool(&this->NSEmailReg), DT_BOOLEAN, NoValidation}, {"nickserv", "modules", "", new ValueContainerString(&NickCoreModules), DT_STRING, NoValidation}, {"nickserv", "forceemail", "no", new ValueContainerBool(&this->NSForceEmail), DT_BOOLEAN, ValidateEmailReg}, + {"nickserv", "confirmemailchanges", "no", new ValueContainerBool(&this->NSConfirmEmailChanges), DT_BOOLEAN, NoValidation}, {"nickserv", "defaults", "secure memosignon memoreceive", new ValueContainerString(&NSDefaults), DT_STRING, NoValidation}, {"nickserv", "languages", "", new ValueContainerString(&this->Languages), DT_STRING, NoValidation}, {"nickserv", "defaultlanguage", "0", new ValueContainerString(&this->NSDefLanguage), DT_STRING, NoValidation}, @@ -1078,7 +1079,7 @@ void ServerConfig::Read() {"nickserv", "expire", "21d", new ValueContainerTime(&this->NSExpire), DT_TIME, NoValidation}, {"nickserv", "suspendexpire", "0", new ValueContainerTime(&this->NSSuspendExpire), DT_TIME, NoValidation}, {"nickserv", "forbidexpire", "0", new ValueContainerTime(&this->NSForbidExpire), DT_TIME, NoValidation}, - {"nickserv", "preregexpire", "0", new ValueContainerTime(&this->NSRExpire), DT_TIME, ValidateEmailReg}, + {"nickserv", "unconfirmedexpire", "0", new ValueContainerTime(&this->NSUnconfirmedExpire), DT_TIME, ValidateEmailReg}, {"nickserv", "maxaliases", "0", new ValueContainerUInt(&this->NSMaxAliases), DT_UINTEGER, NoValidation}, {"nickserv", "accessmax", "0", new ValueContainerUInt(&this->NSAccessMax), DT_UINTEGER, ValidateNotZero}, {"nickserv", "enforceruser", "", new ValueContainerString(&temp_nsuserhost), DT_STRING, ValidateNotEmpty}, diff --git a/src/mail.cpp b/src/mail.cpp index 3a07f7e49..58a0ddac8 100644 --- a/src/mail.cpp +++ b/src/mail.cpp @@ -37,27 +37,6 @@ void MailThread::Run() SetExitState(); } -bool Mail(User *u, NickRequest *nr, BotInfo *service, const Anope::string &subject, const Anope::string &message) -{ - if (!u || !nr || !service || subject.empty() || message.empty()) - return false; - - if (!Config->UseMail) - u->SendMessage(service, _("Services have been configured to not send mail.")); - else if (Anope::CurTime - u->lastmail < Config->MailDelay) - u->SendMessage(service, _("Please wait \002%d\002 seconds and retry."), Config->MailDelay - Anope::CurTime - u->lastmail); - else if (nr->email.empty()) - u->SendMessage(service, _("E-mail for \002%s\002 is invalid."), nr->nick.c_str()); - else - { - u->lastmail = nr->lastmail = Anope::CurTime; - threadEngine.Start(new MailThread(nr->nick, nr->email, subject, message)); - return true; - } - - return false; -} - bool Mail(User *u, NickCore *nc, BotInfo *service, const Anope::string &subject, const Anope::string &message) { if (!u || !nc || !service || subject.empty() || message.empty()) diff --git a/src/main.cpp b/src/main.cpp index c59fe7829..563262195 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -137,7 +137,6 @@ extern void expire_all() Log(LOG_DEBUG) << "Running expire routines"; expire_nicks(); expire_chans(); - expire_requests(); expire_exceptions(); FOREACH_MOD(I_OnDatabaseExpire, OnDatabaseExpire()); diff --git a/src/misc.cpp b/src/misc.cpp index 9efacf314..0ad233402 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -69,43 +69,6 @@ int tolower(char c) /*************************************************************************/ -/** - * merge_args: Take an argument count and argument vector and merge them - * into a single string in which each argument is separated by - * a space. - * @param int Number of Args - * @param argv Array - * @return string of the merged array - */ -const char *merge_args(int argc, const char **argv) -{ - int i; - static char s[4096]; - char *t; - - t = s; - for (i = 0; i < argc; ++i) - t += snprintf(t, sizeof(s) - (t - s), "%s%s", *argv++, i < argc - 1 ? " " : ""); - return s; -} - -/* - * XXX: temporary "safe" version to avoid casting, it's still ugly. - */ -const char *merge_args(int argc, char **argv) -{ - int i; - static char s[4096]; - char *t; - - t = s; - for (i = 0; i < argc; ++i) - t += snprintf(t, sizeof(s) - (t - s), "%s%s", *argv++, i < argc - 1 ? " " : ""); - return s; -} - -/*************************************************************************/ - NumberList::NumberList(const Anope::string &list, bool descending) : is_valid(true), desc(descending) { Anope::string error; @@ -839,12 +802,12 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case * @param ... any number of parameters * @return a Anope::string */ -Anope::string Anope::printf(const char *fmt, ...) +Anope::string Anope::printf(const Anope::string &fmt, ...) { va_list args; char buf[1024]; - va_start(args, fmt); - vsnprintf(buf, sizeof(buf), fmt, args); + va_start(args, fmt.c_str()); + vsnprintf(buf, sizeof(buf), fmt.c_str(), args); va_end(args); return buf; } diff --git a/src/nickalias.cpp b/src/nickalias.cpp index 258e46a07..b82e27ce6 100644 --- a/src/nickalias.cpp +++ b/src/nickalias.cpp @@ -1,25 +1,6 @@ #include "services.h" #include "modules.h" -NickRequest::NickRequest(const Anope::string &nickname) -{ - if (nickname.empty()) - throw CoreException("Empty nick passed to NickRequest constructor"); - - this->requested = this->lastmail = 0; - - this->nick = nickname; - - NickRequestList[this->nick] = this; -} - -NickRequest::~NickRequest() -{ - FOREACH_MOD(I_OnDelNickRequest, OnDelNickRequest(this)); - - NickRequestList.erase(this->nick); -} - /** Default constructor * @param nick The nick * @param nickcore The nickcofe for this nick diff --git a/src/nickserv.cpp b/src/nickserv.cpp index 4a45e6ce2..e12673d08 100644 --- a/src/nickserv.cpp +++ b/src/nickserv.cpp @@ -14,7 +14,6 @@ nickalias_map NickAliasList; nickcore_map NickCoreList; -nickrequest_map NickRequestList; typedef std::map<Anope::string, NickServCollide *> nickservcollides_map; typedef std::map<Anope::string, NickServRelease *> nickservreleases_map; @@ -169,13 +168,6 @@ void ns_init() int validate_user(User *u) { - NickRequest *nr = findrequestnick(u->nick); - if (nr) - { - u->SendMessage(NickServ, _(NICK_IS_PREREG)); - return 0; - } - NickAlias *na = findnick(u->nick); if (!na) return 0; @@ -291,32 +283,8 @@ void expire_nicks() } } -void expire_requests() -{ - for (nickrequest_map::const_iterator it = NickRequestList.begin(), it_end = NickRequestList.end(); it != it_end; ) - { - NickRequest *nr = it->second; - ++it; - - if (Config->NSRExpire && Anope::CurTime - nr->requested >= Config->NSRExpire) - { - Log(LOG_NORMAL, "expire") << "Request for nick " << nr->nick << " expiring"; - delete nr; - } - } -} - /*************************************************************************/ -NickRequest *findrequestnick(const Anope::string &nick) -{ - nickrequest_map::const_iterator it = NickRequestList.find(nick); - - if (it != NickRequestList.end()) - return it->second; - return NULL; -} - NickAlias *findnick(const Anope::string &nick) { FOREACH_MOD(I_OnFindNick, OnFindNick(nick)); diff --git a/src/users.cpp b/src/users.cpp index fa486935f..a11e1b5ce 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -806,7 +806,8 @@ User *do_nick(const Anope::string &source, const Anope::string &nick, const Anop user->UpdateHost(); do_on_id(user); ircdproto->SetAutoIdentificationToken(user); - user->SetMode(NickServ, UMODE_REGISTERED); + if (na->nc->HasFlag(NI_UNCONFIRMED) == false) + user->SetMode(NickServ, UMODE_REGISTERED); Log(NickServ) << user->GetMask() << " automatically identified for group " << user->Account()->display; } |