summaryrefslogtreecommitdiff
path: root/include/modules/nickserv
diff options
context:
space:
mode:
authorSadie Powell <sadie@witchery.services>2025-03-08 12:22:07 +0000
committerSadie Powell <sadie@witchery.services>2025-03-08 12:22:07 +0000
commitdf0cd3ef3e9a5cd1230aebdb45569f54512373ad (patch)
tree3abf54908e7aac069da940f1d6db85829a46b302 /include/modules/nickserv
parent9e37a643f13a8e6b5b8468f245f21fd23238f058 (diff)
Move some headers around.
Diffstat (limited to 'include/modules/nickserv')
-rw-r--r--include/modules/nickserv/cert.h83
-rw-r--r--include/modules/nickserv/sasl.h188
-rw-r--r--include/modules/nickserv/service.h23
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;
+};