summaryrefslogtreecommitdiff
path: root/include/modules/nickserv/sasl.h
blob: 057c92c2a3f65263ced1000a6809ca99efc5a4f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
 *
 * (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);
		}
	};

	/** 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");
}