diff options
| author | Sadie Powell <sadie@witchery.services> | 2025-03-08 12:22:07 +0000 |
|---|---|---|
| committer | Sadie Powell <sadie@witchery.services> | 2025-03-08 12:22:07 +0000 |
| commit | df0cd3ef3e9a5cd1230aebdb45569f54512373ad (patch) | |
| tree | 3abf54908e7aac069da940f1d6db85829a46b302 /include/modules/nickserv | |
| parent | 9e37a643f13a8e6b5b8468f245f21fd23238f058 (diff) | |
Move some headers around.
Diffstat (limited to 'include/modules/nickserv')
| -rw-r--r-- | include/modules/nickserv/cert.h | 83 | ||||
| -rw-r--r-- | include/modules/nickserv/sasl.h | 188 | ||||
| -rw-r--r-- | include/modules/nickserv/service.h | 23 |
3 files changed, 294 insertions, 0 deletions
diff --git a/include/modules/nickserv/cert.h b/include/modules/nickserv/cert.h new file mode 100644 index 000000000..9462d66a0 --- /dev/null +++ b/include/modules/nickserv/cert.h @@ -0,0 +1,83 @@ +/* NickServ core functions + * + * (C) 2003-2025 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +#pragma once + +struct NSCertList +{ +protected: + NSCertList() = default; +public: + virtual ~NSCertList() = default; + + /** 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. + */ + virtual void AddCert(const Anope::string &entry) = 0; + + /** Get an entry from the nick's cert list by index + * + * @param entry Index in the certificate 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. + */ + virtual Anope::string GetCert(unsigned entry) const = 0; + + virtual unsigned GetCertCount() const = 0; + + /** 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. + */ + virtual bool FindCert(const Anope::string &entry) const = 0; + + /** Erase a fingerprint from the nick's certificate list + * + * @param entry The fingerprint to remove + * + * Removes the specified fingerprint from the cert list. + */ + virtual void EraseCert(const Anope::string &entry) = 0; + + /** Replaces a fingerprint in the nick's certificate list + * + * @param oldentry The old fingerprint to remove + * @param newentry The new fingerprint to add + * + * Replaces the specified fingerprint in the cert list. + */ + virtual void ReplaceCert(const Anope::string &oldentry, const Anope::string &newentry) = 0; + + /** Clears the entire nick's cert list + * + * Deletes all the memory allocated in the certificate list vector and then clears the vector. + */ + virtual void ClearCert() = 0; + + virtual void Check() = 0; +}; + +class CertService + : public Service +{ +public: + CertService(Module *c) : Service(c, "CertService", "certs") { } + + virtual NickCore *FindAccountFromCert(const Anope::string &cert) = 0; + virtual void ReplaceCert(const Anope::string &oldcert, const Anope::string &newcert) = 0; +}; diff --git a/include/modules/nickserv/sasl.h b/include/modules/nickserv/sasl.h new file mode 100644 index 000000000..f23a5d32a --- /dev/null +++ b/include/modules/nickserv/sasl.h @@ -0,0 +1,188 @@ +/* + * + * (C) 2014-2025 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + */ + +#pragma once + +namespace SASL +{ + struct Message final + { + Anope::string source; + Anope::string target; + Anope::string type; + std::vector<Anope::string> data; + }; + + class Mechanism; + struct Session; + + class Service + : public ::Service + { + public: + Service(Module *o) : ::Service(o, "SASL::Service", "sasl") { } + + virtual void ProcessMessage(const Message &) = 0; + + virtual Session *GetSession(const Anope::string &uid) = 0; + + virtual void SendMessage(SASL::Session *session, const Anope::string &type, const Anope::string &data) = 0; + + virtual void Succeed(Session *, NickCore *) = 0; + virtual void Fail(Session *) = 0; + virtual void DeleteSessions(Mechanism *, bool = false) = 0; + virtual void RemoveSession(Session *) = 0; + }; + + static ServiceReference<SASL::Service> service("SASL::Service", "sasl"); + + struct Session + { + time_t created; + Anope::string uid; + Anope::string hostname, ip; + Reference<Mechanism> mech; + + Session(Mechanism *m, const Anope::string &u) : created(Anope::CurTime), uid(u), mech(m) { } + + inline Anope::string GetUserInfo() + { + auto *u = User::Find(uid); + if (u) + return u->GetMask(); + if (!hostname.empty() && !ip.empty()) + return Anope::printf("%s (%s)", hostname.c_str(), ip.c_str()); + return "A user"; + }; + + virtual ~Session() + { + if (service) + service->RemoveSession(this); + } + }; + + /* PLAIN, EXTERNAL, etc */ + class Mechanism + : public ::Service + { + public: + Mechanism(Module *o, const Anope::string &sname) : Service(o, "SASL::Mechanism", sname) { } + + virtual Session *CreateSession(const Anope::string &uid) { return new Session(this, uid); } + + virtual bool ProcessMessage(Session *session, const Message &) = 0; + + virtual ~Mechanism() + { + if (service) + service->DeleteSessions(this, true); + } + }; + + class IdentifyRequest + : public ::IdentifyRequest + { + Anope::string uid; + Anope::string hostname; + + inline Anope::string GetUserInfo() + { + auto *u = User::Find(uid); + if (u) + return u->GetMask(); + if (!hostname.empty() && !GetAddress().empty()) + return Anope::printf("%s (%s)", hostname.c_str(), GetAddress().c_str()); + return "A user"; + }; + + public: + IdentifyRequest(Module *m, const Anope::string &id, const Anope::string &acc, const Anope::string &pass, const Anope::string &h, const Anope::string &i) + : ::IdentifyRequest(m, acc, pass, i) + , uid(id) + , hostname(h) + { + } + + void OnSuccess() override + { + if (!service) + return; + + NickAlias *na = NickAlias::Find(GetAccount()); + if (!na || na->nc->HasExt("NS_SUSPENDED") || na->nc->HasExt("UNCONFIRMED")) + return OnFail(); + + unsigned int maxlogins = Config->GetModule("ns_identify").Get<unsigned int>("maxlogins"); + if (maxlogins && na->nc->users.size() >= maxlogins) + return OnFail(); + + Session *s = service->GetSession(uid); + if (s) + { + Log(this->GetOwner(), "sasl", Config->GetClient("NickServ")) << GetUserInfo() << " identified to account " << this->GetAccount() << " using SASL"; + service->Succeed(s, na->nc); + delete s; + } + } + + void OnFail() override + { + if (!service) + return; + + Session *s = service->GetSession(uid); + if (s) + { + service->Fail(s); + delete s; + } + + Anope::string accountstatus; + NickAlias *na = NickAlias::Find(GetAccount()); + if (!na) + accountstatus = "nonexistent "; + else if (na->nc->HasExt("NS_SUSPENDED")) + accountstatus = "suspended "; + else if (na->nc->HasExt("UNCONFIRMED")) + accountstatus = "unconfirmed "; + + Log(this->GetOwner(), "sasl", Config->GetClient("NickServ")) << GetUserInfo() << " failed to identify for " << accountstatus << "account " << this->GetAccount() << " using SASL"; + } + }; + + /** Sends IRCd messages used by the SASL module. */ + class ProtocolInterface + : public ::Service + { + protected: + ProtocolInterface(Module *o) + : ::Service(o, "SASL::ProtocolInterface", "sasl") + { + } + + public: + /** Sends the list of SASL mechanisms to the IRCd + * @param mechs The list of SASL mechanisms. + */ + virtual void SendSASLMechanisms(std::vector<Anope::string> &mechs) { }; + + /** Sends a SASL message to the IRCd. + * @param message The SASL message to send. + */ + virtual void SendSASLMessage(const SASL::Message &message) = 0; + + /** Sends a login or logout for \p uid to \p na. + * @param uid The uid of the user to log in. + * @param na The nick alias to log the user in as or logout if nullptr. + */ + virtual void SendSVSLogin(const Anope::string &uid, NickAlias *na) = 0; + }; + + static ServiceReference<SASL::ProtocolInterface> protocol_interface("SASL::ProtocolInterface", "sasl"); +} diff --git a/include/modules/nickserv/service.h b/include/modules/nickserv/service.h new file mode 100644 index 000000000..2c659501e --- /dev/null +++ b/include/modules/nickserv/service.h @@ -0,0 +1,23 @@ +/* + * + * (C) 2011-2025 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + */ + +#pragma once + +class NickServService + : public Service +{ +public: + NickServService(Module *m) : Service(m, "NickServService", "NickServ") + { + } + + virtual void Validate(User *u) = 0; + virtual void Collide(User *u, NickAlias *na) = 0; + virtual void Release(NickAlias *na) = 0; + virtual bool IsGuestNick(const Anope::string &nick) const = 0; +}; |
