1 /*
2  *
3  * (C) 2003-2020 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  * Based on the original code of Epona by Lara.
9  * Based on the original code of Services by Andy Church.
10  */
11 
12 #ifndef ACCOUNT_H
13 #define ACCOUNT_H
14 
15 #include "extensible.h"
16 #include "serialize.h"
17 #include "anope.h"
18 #include "memo.h"
19 #include "base.h"
20 
21 typedef Anope::hash_map<NickAlias *> nickalias_map;
22 typedef Anope::hash_map<NickCore *> nickcore_map;
23 typedef TR1NS::unordered_map<uint64_t, NickCore *> nickcoreid_map;
24 
25 extern CoreExport Serialize::Checker<nickalias_map> NickAliasList;
26 extern CoreExport Serialize::Checker<nickcore_map> NickCoreList;
27 extern CoreExport nickcoreid_map NickCoreIdList;
28 
29 /* A registered nickname.
30  * It matters that Base is here before Extensible (it is inherited by Serializable)
31  */
32 class CoreExport NickAlias : public Serializable, public Extensible
33 {
34 	Anope::string vhost_ident, vhost_host, vhost_creator;
35 	time_t vhost_created;
36 
37  public:
38 	Anope::string nick;
39 	Anope::string last_quit;
40 	Anope::string last_realname;
41 	/* Last usermask this nick was seen on, eg user@host */
42 	Anope::string last_usermask;
43 	/* Last uncloaked usermask, requires nickserv/auspex to see */
44 	Anope::string last_realhost;
45 	time_t time_registered;
46 	time_t last_seen;
47 	/* Account this nick is tied to. Multiple nicks can be tied to a single account. */
48 	Serialize::Reference<NickCore> nc;
49 
50 	/** Constructor
51 	 * @param nickname The nick
52 	 * @param nickcore The nickcore for this nick
53 	 */
54 	NickAlias(const Anope::string &nickname, NickCore *nickcore);
55 	~NickAlias();
56 
57 	void Serialize(Serialize::Data &data) const anope_override;
58 	static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
59 
60 	/** Set a vhost for the user
61 	 * @param ident The ident
62 	 * @param host The host
63 	 * @param creator Who created the vhost
64 	 * @param time When the vhost was craated
65 	 */
66 	void SetVhost(const Anope::string &ident, const Anope::string &host, const Anope::string &creator, time_t created = Anope::CurTime);
67 
68 	/** Remove a users vhost
69 	 **/
70 	void RemoveVhost();
71 
72 	/** Check if the user has a vhost
73 	 * @return true or false
74 	 */
75 	bool HasVhost() const;
76 
77 	/** Retrieve the vhost ident
78 	 * @return the ident
79 	 */
80 	const Anope::string &GetVhostIdent() const;
81 
82 	/** Retrieve the vhost host
83 	 * @return the host
84 	 */
85 	const Anope::string &GetVhostHost() const;
86 
87 	/** Retrieve the vhost creator
88 	 * @return the creator
89 	 */
90 	const Anope::string &GetVhostCreator() const;
91 
92 	/** Retrieve when the vhost was created
93 	 * @return the time it was created
94 	 */
95 	time_t GetVhostCreated() const;
96 
97 	/** Finds a registered nick
98 	 * @param nick The nick to lookup
99 	 * @return the nick, if found
100 	 */
101 	static NickAlias *Find(const Anope::string &nick);
102 };
103 
104 /* A registered account. Each account must have a NickAlias with the same nick as the
105  * account's display.
106  * It matters that Base is here before Extensible (it is inherited by Serializable)
107  */
108 class CoreExport NickCore : public Serializable, public Extensible
109 {
110 	/* Channels which reference this core in some way (this is on their access list, akick list, is founder, successor, etc) */
111 	Serialize::Checker<std::map<ChannelInfo *, int> > chanaccess;
112 	/* Unique identifier for the account. */
113 	uint64_t id;
114  public:
115 	/* Name of the account. Find(display)->nc == this. */
116 	Anope::string display;
117 	/* User password in form of hashm:data */
118 	Anope::string pass;
119 	Anope::string email;
120 	/* Locale name of the language of the user. Empty means default language */
121 	Anope::string language;
122 	/* Access list, contains user@host masks of users who get certain privileges based
123 	 * on if NI_SECURE is set and what (if any) kill protection is enabled. */
124 	std::vector<Anope::string> access;
125 	MemoInfo memos;
126 	std::map<Anope::string, Anope::string> last_modes;
127 
128 	/* Nicknames registered that are grouped to this account.
129 	 * for n in aliases, n->nc == this.
130 	 */
131 	Serialize::Checker<std::vector<NickAlias *> > aliases;
132 
133 	/* Set if this user is a services operattor. o->ot must exist. */
134 	Oper *o;
135 
136 	/* Unsaved data */
137 
138 	/* Number of channels registered by this account */
139 	uint16_t channelcount;
140 	/* Last time an email was sent to this user */
141 	time_t lastmail;
142 	/* Users online now logged into this account */
143 	std::list<User *> users;
144 
145 	/** Constructor
146 	 * @param display The display nick
147 	 * @param id The account id
148 	 */
149 	NickCore(const Anope::string &nickdisplay, uint64_t nickid = 0);
150 	~NickCore();
151 
152 	void Serialize(Serialize::Data &data) const anope_override;
153 	static Serializable* Unserialize(Serializable *obj, Serialize::Data &);
154 
155 	/** Changes the display for this account
156 	 * @param na The new display, must be grouped to this account.
157 	 */
158 	void SetDisplay(const NickAlias *na);
159 
160 	/** Checks whether this account is a services oper or not.
161 	 * @return True if this account is a services oper, false otherwise.
162 	 */
163 	virtual bool IsServicesOper() const;
164 
165 	/** Add an entry to the nick's access list
166 	 *
167 	 * @param entry The nick!ident@host entry to add to the access list
168 	 *
169 	 * Adds a new entry into the access list.
170 	 */
171 	void AddAccess(const Anope::string &entry);
172 
173 	/** Get an entry from the nick's access list by index
174 	 *
175 	 * @param entry Index in the access list vector to retrieve
176 	 * @return The access list entry of the given index if within bounds, an empty string if the vector is empty or the index is out of bounds
177 	 *
178 	 * Retrieves an entry from the access list corresponding to the given index.
179 	 */
180 	Anope::string GetAccess(unsigned entry) const;
181 
182 	/** Get the number of entries on the access list for this account.
183 	 */
184 	unsigned GetAccessCount() const;
185 
186 	/** Retrieves the account id for this user */
187 	uint64_t GetId();
188 
189 	/** Find an entry in the nick's access list
190 	 *
191 	 * @param entry The nick!ident@host entry to search for
192 	 * @return True if the entry is found in the access list, false otherwise
193 	 *
194 	 * Search for an entry within the access list.
195 	 */
196 	bool FindAccess(const Anope::string &entry);
197 
198 	/** Erase an entry from the nick's access list
199 	 *
200 	 * @param entry The nick!ident@host entry to remove
201 	 *
202 	 * Removes the specified access list entry from the access list.
203 	 */
204 	void EraseAccess(const Anope::string &entry);
205 
206 	/** Clears the entire nick's access list
207 	 *
208 	 * Deletes all the memory allocated in the access list vector and then clears the vector.
209 	 */
210 	void ClearAccess();
211 
212 	/** Is the given user on this accounts access list?
213 	 *
214 	 * @param u The user
215 	 *
216 	 * @return true if the user is on the access list
217 	 */
218 	bool IsOnAccess(const User *u) const;
219 
220 	/** Finds an account
221 	 * @param nick The account name to find
222 	 * @return The account, if it exists
223 	 */
224 	static NickCore* Find(const Anope::string &nick);
225 
226 	void AddChannelReference(ChannelInfo *ci);
227 	void RemoveChannelReference(ChannelInfo *ci);
228 	void GetChannelReferences(std::deque<ChannelInfo *> &queue);
229 };
230 
231 /* A request to check if an account/password is valid. These can exist for
232  * extended periods due to the time some authentication modules take.
233  */
234 class CoreExport IdentifyRequest
235 {
236 	/* Owner of this request, used to cleanup requests if a module is unloaded
237 	 * while a reqyest us pending */
238 	Module *owner;
239 	Anope::string account;
240 	Anope::string password;
241 
242 	std::set<Module *> holds;
243 	bool dispatched;
244 	bool success;
245 
246 	static std::set<IdentifyRequest *> Requests;
247 
248  protected:
249 	IdentifyRequest(Module *o, const Anope::string &acc, const Anope::string &pass);
250 	virtual ~IdentifyRequest();
251 
252  public:
253 	/* One of these is called when the request goes through */
254 	virtual void OnSuccess() = 0;
255 	virtual void OnFail() = 0;
256 
GetOwner()257 	Module *GetOwner() const { return owner; }
GetAccount()258 	const Anope::string &GetAccount() const { return account; }
GetPassword()259 	const Anope::string &GetPassword() const { return password; }
260 
261 	/* Holds this request. When a request is held it must be Released later
262 	 * for the request to complete. Multiple modules may hold a request at any time,
263 	 * but the request is not complete until every module has released it. If you do not
264 	 * require holding this (eg, your password check is done in this thread and immediately)
265 	 * then you don't need to hold the request before Successing it.
266 	 * @param m The module holding this request
267 	 */
268 	void Hold(Module *m);
269 
270 	/** Releases a held request
271 	 * @param m The module releaseing the hold
272 	 */
273 	void Release(Module *m);
274 
275 	/** Called by modules when this IdentifyRequest has successeded successfully.
276 	 * If this request is behind held it must still be Released after calling this.
277 	 * @param m The module confirming authentication
278 	 */
279 	void Success(Module *m);
280 
281 	/** Used to either finalize this request or marks
282 	 * it as dispatched and begins waiting for the module(s)
283 	 * that have holds to finish.
284 	 */
285 	void Dispatch();
286 
287 	static void ModuleUnload(Module *m);
288 };
289 
290 #endif // ACCOUNT_H
291