diff options
author | Adam <Adam@anope.org> | 2013-07-01 22:17:52 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2013-07-01 22:17:52 -0400 |
commit | 1a3d9a016d3adc49788bbff73aac9b3b5ea85b17 (patch) | |
tree | c0ecf92ed768473bc82ff64a7fce827245f37ba9 /modules/commands/ns_cert.cpp | |
parent | 518182ac9204f815258b0de91b3f884d8efa1502 (diff) |
Change extensible keys to require explicitly having a type defined for it. Completely modularize more features like bs_kick, entrymsg, log, mode, etc. Move fantasy to its own module. Move greet to its own module.
Diffstat (limited to 'modules/commands/ns_cert.cpp')
-rw-r--r-- | modules/commands/ns_cert.cpp | 224 |
1 files changed, 176 insertions, 48 deletions
diff --git a/modules/commands/ns_cert.cpp b/modules/commands/ns_cert.cpp index dc877e467..c87ff7179 100644 --- a/modules/commands/ns_cert.cpp +++ b/modules/commands/ns_cert.cpp @@ -10,15 +10,135 @@ */ #include "module.h" +#include "modules/ns_cert.h" -static unsigned accessmax; +struct NSCertListImpl : NSCertList +{ + Serialize::Reference<NickCore> nc; + std::vector<Anope::string> certs; + + public: + NSCertListImpl(Extensible *obj) : nc(anope_dynamic_static_cast<NickCore *>(obj)) { } + + /** Add an entry to the nick's certificate list + * + * @param entry The fingerprint to add to the cert list + * + * Adds a new entry into the cert list. + */ + void AddCert(const Anope::string &entry) anope_override + { + this->certs.push_back(entry); + FOREACH_MOD(OnNickAddCert, (this->nc, entry)); + } + + /** Get an entry from the nick's cert list by index + * + * @param entry Index in the certificaate list vector to retrieve + * @return The fingerprint entry of the given index if within bounds, an empty string if the vector is empty or the index is out of bounds + * + * Retrieves an entry from the certificate list corresponding to the given index. + */ + Anope::string GetCert(unsigned entry) const anope_override + { + if (entry >= this->certs.size()) + return ""; + return this->certs[entry]; + } + + unsigned GetCertCount() const anope_override + { + return this->certs.size(); + } + + /** Find an entry in the nick's cert list + * + * @param entry The fingerprint to search for + * @return True if the fingerprint is found in the cert list, false otherwise + * + * Search for an fingerprint within the cert list. + */ + bool FindCert(const Anope::string &entry) const anope_override + { + return std::find(this->certs.begin(), this->certs.end(), entry) != this->certs.end(); + } + + /** Erase a fingerprint from the nick's certificate list + * + * @param entry The fingerprint to remove + * + * Removes the specified fingerprint from the cert list. + */ + void EraseCert(const Anope::string &entry) anope_override + { + std::vector<Anope::string>::iterator it = std::find(this->certs.begin(), this->certs.end(), entry); + if (it != this->certs.end()) + { + FOREACH_MOD(OnNickEraseCert, (this->nc, entry)); + this->certs.erase(it); + } + } + + /** Clears the entire nick's cert list + * + * Deletes all the memory allocated in the certificate list vector and then clears the vector. + */ + void ClearCert() anope_override + { + FOREACH_MOD(OnNickClearCert, (this->nc)); + this->certs.clear(); + } + + void Check() anope_override + { + if (this->certs.empty()) + nc->Shrink<NSCertList>("certificates"); + } + + struct ExtensibleItem : ::ExtensibleItem<NSCertListImpl> + { + ExtensibleItem(Module *m, const Anope::string &name) : ::ExtensibleItem<NSCertListImpl>(m, name) { } + + void ExtensibleSerialize(const Extensible *e, const Serializable *s, Serialize::Data &data) const anope_override + { + if (s->GetSerializableType()->GetName() != "NickCore") + return; + + const NickCore *nc = anope_dynamic_static_cast<const NickCore *>(e); + NSCertList *certs = this->Get(nc); + if (certs == NULL || !certs->GetCertCount()) + return; + + for (unsigned i = 0; i < certs->GetCertCount(); ++i) + data["cert"] << certs->GetCert(i) << " "; + } + + void ExtensibleUnserialize(Extensible *e, Serializable *s, Serialize::Data &data) anope_override + { + if (s->GetSerializableType()->GetName() != "NickCore") + return; + + NickCore *nc = anope_dynamic_static_cast<NickCore *>(e); + NSCertListImpl *certs = this->Require(nc); + + Anope::string buf; + data["cert"] >> buf; + spacesepstream sep(buf); + certs->certs.clear(); + while (sep.GetToken(buf)) + certs->certs.push_back(buf); + } + }; +}; class CommandNSCert : public Command { private: void DoServAdminList(CommandSource &source, const NickCore *nc) { - if (nc->cert.empty()) + NSCertList *cl = nc->GetExt<NSCertList>("certificates"); + + if (!cl || !cl->GetCertCount()) { source.Reply(_("Certificate list for \002%s\002 is empty."), nc->display.c_str()); return; @@ -33,9 +153,9 @@ class CommandNSCert : public Command ListFormatter list; list.AddColumn("Certificate"); - for (unsigned i = 0, end = nc->cert.size(); i < end; ++i) + for (unsigned i = 0; i < cl->GetCertCount(); ++i) { - Anope::string fingerprint = nc->GetCert(i); + const Anope::string &fingerprint = cl->GetCert(i); ListFormatter::ListEntry entry; entry["Certificate"] = fingerprint; list.AddEntry(entry); @@ -47,74 +167,74 @@ class CommandNSCert : public Command list.Process(replies); for (unsigned i = 0; i < replies.size(); ++i) source.Reply(replies[i]); - - return; } void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &mask) { + NSCertList *cl = nc->Require<NSCertList>("certificates"); - if (nc->cert.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax")) + if (cl->GetCertCount() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax")) { source.Reply(_("Sorry, you can only have %d certificate entries for a nickname."), Config->GetModule(this->owner)->Get<unsigned>("accessmax")); return; } - if (source.GetUser() && !source.GetUser()->fingerprint.empty() && !nc->FindCert(source.GetUser()->fingerprint)) - { - nc->AddCert(source.GetUser()->fingerprint); - source.Reply(_("\002%s\002 added to your certificate list."), source.GetUser()->fingerprint.c_str()); - return; - } - if (mask.empty()) { - this->OnSyntaxError(source, "ADD"); + if (source.GetUser() && !source.GetUser()->fingerprint.empty() && !cl->FindCert(source.GetUser()->fingerprint)) + { + cl->AddCert(source.GetUser()->fingerprint); + source.Reply(_("\002%s\002 added to your certificate list."), source.GetUser()->fingerprint.c_str()); + } + else + this->OnSyntaxError(source, "ADD"); + return; } - if (nc->FindCert(mask)) + if (cl->FindCert(mask)) { source.Reply(_("Fingerprint \002%s\002 already present on your certificate list."), mask.c_str()); return; } - nc->AddCert(mask); + cl->AddCert(mask); source.Reply(_("\002%s\002 added to your certificate list."), mask.c_str()); - return; } void DoDel(CommandSource &source, NickCore *nc, const Anope::string &mask) { - if (source.GetUser() && !source.GetUser()->fingerprint.empty() && nc->FindCert(source.GetUser()->fingerprint)) - { - nc->EraseCert(source.GetUser()->fingerprint); - source.Reply(_("\002%s\002 deleted from your certificate list."), source.GetUser()->fingerprint.c_str()); - return; - } + NSCertList *cl = nc->Require<NSCertList>("certificates"); if (mask.empty()) { - this->OnSyntaxError(source, "DEL"); + if (source.GetUser() && !source.GetUser()->fingerprint.empty() && cl->FindCert(source.GetUser()->fingerprint)) + { + cl->EraseCert(source.GetUser()->fingerprint); + source.Reply(_("\002%s\002 deleted from your certificate list."), source.GetUser()->fingerprint.c_str()); + } + else + this->OnSyntaxError(source, "DEL"); + return; } - if (!nc->FindCert(mask)) + if (!cl->FindCert(mask)) { source.Reply(_("\002%s\002 not found on your certificate list."), mask.c_str()); return; } source.Reply(_("\002%s\002 deleted from your certificate list."), mask.c_str()); - nc->EraseCert(mask); - - return; + cl->EraseCert(mask); + cl->Check(); } void DoList(CommandSource &source, const NickCore *nc) { + NSCertList *cl = nc->GetExt<NSCertList>("certificates"); - if (nc->cert.empty()) + if (!cl || !cl->GetCertCount()) { source.Reply(_("Your certificate list is empty.")); return; @@ -123,10 +243,10 @@ class CommandNSCert : public Command ListFormatter list; list.AddColumn("Certificate"); - for (unsigned i = 0, end = nc->cert.size(); i < end; ++i) + for (unsigned i = 0; i < cl->GetCertCount(); ++i) { ListFormatter::ListEntry entry; - entry["Certificate"] = nc->GetCert(i); + entry["Certificate"] = cl->GetCert(i); list.AddEntry(entry); } @@ -197,8 +317,17 @@ class CommandNSCert : public Command class NSCert : public Module { CommandNSCert commandnscert; + NSCertListImpl::ExtensibleItem certs; + + public: + NSCert(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), + commandnscert(this), certs(this, "certificates") + { + if (!IRCD || !IRCD->CanCertFP) + throw ModuleException("Your IRCd does not support ssl client certificates"); + } - void DoAutoIdentify(User *u) + void OnFingerprint(User *u) anope_override { NickAlias *na = NickAlias::Find(u->nick); BotInfo *NickServ = Config->GetClient("NickServ"); @@ -208,29 +337,28 @@ class NSCert : public Module return; if (na->nc->HasExt("SUSPENDED")) return; - if (!na->nc->FindCert(u->fingerprint)) + + NSCertList *cl = certs.Get(na->nc); + if (!cl || !cl->FindCert(u->fingerprint)) return; u->Identify(na); u->SendMessage(NickServ, _("SSL Fingerprint accepted. You are now identified.")); - Log(u) << "automatically identified for account " << na->nc->display << " using a valid SSL fingerprint"; - return; + Log(u) << "automatically identified for account " << na->nc->display << " via SSL certificate fingerprint"; } - public: - NSCert(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), - commandnscert(this) + EventReturn OnNickValidate(User *u, NickAlias *na) anope_override { + NSCertList *cl = certs.Get(na->nc); + if (!u->fingerprint.empty() && cl && cl->FindCert(u->fingerprint)) + { + u->Identify(na); + u->SendMessage(Config->GetClient("NickServ"), _("SSL fingerprint accepted, you are now identified.")); + Log(u) << "automatically identified for account " << na->nc->display << " via SSL fingerprint."; + return EVENT_ALLOW; + } - if (!IRCD || !IRCD->CanCertFP) - throw ModuleException("Your IRCd does not support ssl client certificates"); - - - } - - void OnFingerprint(User *u) anope_override - { - DoAutoIdentify(u); + return EVENT_CONTINUE; } }; |