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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
|
/* +------------------------------------+
* | Inspire Internet Relay Chat Daemon |
* +------------------------------------+
*
* InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
* E-mail:
* <brain@chatspike.net>
* <Craig@chatspike.net>
*
* Written by Craig Edwards, Craig McLure, and others.
* This program is free but copyrighted software; see
* the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __USERS_H__
#define __USERS_H__
#include <string>
#include "inspircd_config.h"
#include "socket.h"
#include "channels.h"
#include "inspstring.h"
#include "connection.h"
#include "hashcomp.h"
#include "dns.h"
#include "cull_list.h"
enum ChanStatus {
STATUS_OP = 4,
STATUS_HOP = 2,
STATUS_VOICE = 1,
STATUS_NORMAL = 0
};
enum ClassTypes {
CC_ALLOW = 0,
CC_DENY = 1
};
/** RFC1459 channel modes
* */
enum UserModes {
UM_SERVERNOTICE = 's'-65,
UM_WALLOPS = 'w'-65,
UM_INVISIBLE = 'i'-65,
UM_OPERATOR = 'o'-65,
};
enum RegistrationState {
REG_NONE = 0, /* Has sent nothing */
REG_USER = 1, /* Has sent USER */
REG_NICK = 2, /* Has sent NICK */
REG_NICKUSER = 3, /* Bitwise combination of REG_NICK and REG_USER */
REG_ALL = 7 /* REG_NICKUSER plus next bit along */
};
/** Holds a channel name to which a user has been invited.
*/
class Invited : public classbase
{
public:
irc::string channel;
};
/** Derived from Resolver, and performs user forward/reverse lookups.
*/
class UserResolver : public Resolver
{
private:
/** User this class is 'attached' to.
*/
userrec* bound_user;
int bound_fd;
bool fwd;
public:
UserResolver(userrec* user, std::string to_resolve, bool forward);
void OnLookupComplete(const std::string &result);
void OnError(ResolverError e, const std::string &errormessage);
};
/** Holds information relevent to <connect allow> and <connect deny> tags in the config file.
*/
class ConnectClass : public classbase
{
public:
/** Type of line, either CC_ALLOW or CC_DENY
*/
char type;
/** Max time to register the connection in seconds
*/
int registration_timeout;
/** Number of lines in buffer before excess flood is triggered
*/
int flood;
/** Host mask for this line
*/
std::string host;
/** Number of seconds between pings for this line
*/
int pingtime;
/** (Optional) Password for this line
*/
std::string pass;
/** Threshold value for flood disconnect
*/
int threshold;
/** Maximum size of sendq for users in this class (bytes)
*/
long sendqmax;
/** Maximum size of recvq for users in this class (bytes)
*/
long recvqmax;
/** Local max when connecting by this connection class
*/
long maxlocal;
/** Global max when connecting by this connection class
*/
long maxglobal;
ConnectClass() : registration_timeout(0), flood(0), host(""), pingtime(0), pass(""), threshold(0), sendqmax(0), recvqmax(0)
{
}
};
/** Holds a complete list of all channels to which a user has been invited and has not yet joined.
*/
typedef std::vector<Invited> InvitedList;
/** Holds a complete list of all allow and deny tags from the configuration file (connection classes)
*/
typedef std::vector<ConnectClass> ClassVector;
/** Typedef for the list of user-channel records for a user
*/
typedef std::vector<ucrec*> UserChanList;
/** Holds all information about a user
* This class stores all information about a user connected to the irc server. Everything about a
* connection is stored here primarily, from the user's socket ID (file descriptor) through to the
* user's nickname and hostname. Use the Find method of the server class to locate a specific user
* by nickname.
*/
class userrec : public connection
{
private:
/** A list of channels the user has a pending invite to.
*/
InvitedList invites;
public:
/** Resolvers for looking up this users hostname
*/
UserResolver* res_forward;
UserResolver* res_reverse;
std::string stored_host;
void StartDNSLookup();
/** The users nickname.
* An invalid nickname indicates an unregistered connection prior to the NICK command.
*/
char nick[NICKMAX];
/** The users ident reply.
* Two characters are added to the user-defined limit to compensate for the tilde etc.
*/
char ident[IDENTMAX+2];
/** The host displayed to non-opers (used for cloaking etc).
* This usually matches the value of userrec::host.
*/
char dhost[65];
/** The users full name.
*/
char fullname[MAXGECOS+1];
/** The user's mode list.
* This is NOT a null terminated string! In the 1.1 version of InspIRCd
* this is an array of values in a similar way to channel modes.
* A value of 1 in field (modeletter-65) indicates that the mode is
* set, for example, to work out if mode +s is set, we check the field
* userrec::modes['s'-65] != 0.
* The following RFC characters o, w, s, i have constants defined via an
* enum, such as UM_SERVERNOTICE and UM_OPETATOR.
*/
char modes[64];
/** What snomasks are set on this user.
* This functions the same as the above modes.
*/
char snomasks[64];
UserChanList chans;
/** The server the user is connected to.
*/
const char* server;
/** The user's away message.
* If this string is empty, the user is not marked as away.
*/
char awaymsg[MAXAWAY+1];
/** Number of lines the user can place into the buffer
* (up to the global NetBufferSize bytes) before they
* are disconnected for excess flood
*/
int flood;
/** Number of seconds this user is given to send USER/NICK
* If they do not send their details in this time limit they
* will be disconnected
*/
unsigned int timeout;
/** The oper type they logged in as, if they are an oper.
* This is used to check permissions in operclasses, so that
* we can say 'yay' or 'nay' to any commands they issue.
* The value of this is the value of a valid 'type name=' tag.
*/
char oper[NICKMAX];
/** True when DNS lookups are completed.
*/
bool dns_done;
/** Number of seconds between PINGs for this user (set from <connect:allow> tag
*/
unsigned int pingmax;
/** Password specified by the user when they registered.
* This is stored even if the <connect> block doesnt need a password, so that
* modules may check it.
*/
char password[64];
/** User's receive queue.
* Lines from the IRCd awaiting processing are stored here.
* Upgraded april 2005, old system a bit hairy.
*/
std::string recvq;
/** User's send queue.
* Lines waiting to be sent are stored here until their buffer is flushed.
*/
std::string sendq;
/** Flood counters
*/
int lines_in;
time_t reset_due;
long threshold;
/** IPV4 ip address
*/
sockaddr ip;
/** Initialize the clients sockaddr
*/
void SetSockAddr(int protocol_family, const char* ip, int port);
/** Get port number from sockaddr
*/
int GetPort();
/** Get protocol family from sockaddr
*/
int GetProtocolFamily();
/** Get IP string from sockaddr
*/
const char* GetIPString();
/* Write error string
*/
std::string WriteError;
/** Maximum size this user's sendq can become
*/
long sendqmax;
/** Maximum size this user's recvq can become
*/
long recvqmax;
/** Default constructor
*/
userrec();
/** Returns the full displayed host of the user
* This member function returns the hostname of the user as seen by other users
* on the server, in nick!ident&at;host form.
*/
virtual char* GetFullHost();
/** Returns the full real host of the user
* This member function returns the hostname of the user as seen by other users
* on the server, in nick!ident&at;host form. If any form of hostname cloaking is in operation,
* e.g. through a module, then this method will ignore it and return the true hostname.
*/
virtual char* GetFullRealHost();
/*
* Create a displayable mode string for this users umodes
*/
const char* FormatNoticeMasks();
bool userrec::ProcessNoticeMasks(const char *sm);
bool IsNoticeMaskSet(unsigned char sm);
void SetNoticeMask(unsigned char sm, bool value);
/*
* Create a displayable mode string for this users umodes
*/
const char* FormatModes();
bool IsModeSet(unsigned char m);
void SetMode(unsigned char m, bool value);
/** Returns true if a user is invited to a channel.
*/
virtual bool IsInvited(irc::string &channel);
/** Adds a channel to a users invite list (invites them to a channel)
*/
virtual void InviteTo(irc::string &channel);
/** Removes a channel from a users invite list.
* This member function is called on successfully joining an invite only channel
* to which the user has previously been invited, to clear the invitation.
*/
virtual void RemoveInvite(irc::string &channel);
/** Returns true or false for if a user can execute a privilaged oper command.
* This is done by looking up their oper type from userrec::oper, then referencing
* this to their oper classes and checking the commands they can execute.
*/
bool HasPermission(const std::string &command);
/** Calls read() to read some data for this user using their fd.
*/
int ReadData(void* buffer, size_t size);
/** This method adds data to the buffer of the user.
* The buffer can grow to any size within limits of the available memory,
* managed by the size of a std::string, however if any individual line in
* the buffer grows over 600 bytes in length (which is 88 chars over the
* RFC-specified limit per line) then the method will return false and the
* text will not be inserted.
*/
bool AddBuffer(const std::string &a);
/** This method returns true if the buffer contains at least one carriage return
* character (e.g. one complete line may be read)
*/
bool BufferIsReady();
/** This function clears the entire buffer by setting it to an empty string.
*/
void ClearBuffer();
/** This method returns the first available string at the tail end of the buffer
* and advances the tail end of the buffer past the string. This means it is
* a one way operation in a similar way to strtok(), and multiple calls return
* multiple lines if they are available. The results of this function if there
* are no lines to be read are unknown, always use BufferIsReady() to check if
* it is ok to read the buffer before calling GetBuffer().
*/
std::string GetBuffer();
/** Sets the write error for a connection. This is done because the actual disconnect
* of a client may occur at an inopportune time such as half way through /LIST output.
* The WriteErrors of clients are checked at a more ideal time (in the mainloop) and
* errored clients purged.
*/
void SetWriteError(const std::string &error);
/** Returns the write error which last occured on this connection or an empty string
* if none occured.
*/
const char* GetWriteError();
/** Adds to the user's write buffer.
* You may add any amount of text up to this users sendq value, if you exceed the
* sendq value, SetWriteError() will be called to set the users error string to
* "SendQ exceeded", and further buffer adds will be dropped.
*/
void AddWriteBuf(const std::string &data);
/** Flushes as much of the user's buffer to the file descriptor as possible.
* This function may not always flush the entire buffer, rather instead as much of it
* as it possibly can. If the send() call fails to send the entire buffer, the buffer
* position is advanced forwards and the rest of the data sent at the next call to
* this method.
*/
void FlushWriteBuf();
/** Returns the list of channels this user has been invited to but has not yet joined.
*/
InvitedList* GetInviteList();
/** Creates a wildcard host.
* Takes a buffer to use and fills the given buffer with the host in the format *!*@hostname
*/
char* MakeWildHost();
/** Creates a host.
* Takes a buffer to use and fills the given buffer with the host in the format nick!user@host
*/
void MakeHost(char* nhost);
/** Shuts down and closes the user's socket
*/
void CloseSocket();
/** Default destructor
*/
virtual ~userrec();
};
/** Used to hold WHOWAS information
*/
class WhoWasGroup : public classbase
{
public:
char* host;
char* dhost;
char* ident;
const char* server;
char* gecos;
time_t signon;
WhoWasGroup(userrec* user);
~WhoWasGroup();
};
typedef std::deque<WhoWasGroup*> whowas_set;
typedef std::map<irc::string,whowas_set*> whowas_users;
void AddOper(userrec* user);
void DeleteOper(userrec* user);
void kill_link(userrec *user,const char* r);
void kill_link_silent(userrec *user,const char* r);
void AddWhoWas(userrec* u);
void MaintainWhoWas(time_t TIME);
void AddClient(int socket, int port, bool iscached, insp_inaddr ip4);
void FullConnectUser(userrec* user, CullList* Goners);
userrec* ReHashNick(const char* Old, const char* New);
void force_nickchange(userrec* user,const char* newnick);
/* Configuration callbacks */
bool InitTypes(const char* tag);
bool InitClasses(const char* tag);
bool DoType(const char* tag, char** entries, void** values, int* types);
bool DoClass(const char* tag, char** entries, void** values, int* types);
bool DoneClassesAndTypes(const char* tag);
long FindMatchingGlobal(userrec* user);
long FindMatchingLocal(userrec* user);
#endif
|