]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/authcmds.c
0d3d5fc9f5f8ff8655293858aaa515c7f2163f4e
[irc/quakenet/newserv.git] / chanserv / authcmds.c
1 #include "chanserv.h"
2 #include "authlib.h"
3 #include "../lib/irc_string.h"
4
5 #include <stdio.h>
6 #include <string.h>
7
8 int csa_dohello(void *source, int cargc, char **cargv);
9 int csa_doauth(void *source, int cargc, char **cargv);
10 int csa_doreqpw(void *source, int cargc, char **cargv);
11 int csa_doreqmasterpw(void *source, int cargc, char **cargv);
12 int csa_donewpw(void *source, int cargc, char **cargv);
13 int csa_doemail(void *source, int cargc, char **cargv);
14 int csa_dosetpw(void *source, int cargc, char **cargv);
15 int csa_dosetmail(void *source, int cargc, char **cargv);
16 int csa_dosetmasterpw(void *source, int cargc, char **cargv);
17
18 void _init() {
19 csa_initregex();
20 chanservaddcommand("hello", QCMD_NOTAUTHED, 2, csa_dohello, "Creates a new user account.");
21 chanservaddcommand("auth", QCMD_ALIAS | QCMD_SECURE | QCMD_NOTAUTHED, 2, csa_doauth, "Authenticates you on the bot.");
22 chanservaddcommand("login", QCMD_SECURE | QCMD_NOTAUTHED, 2, csa_doauth, "Authenticates you on the bot.");
23 chanservaddcommand("newpass", QCMD_AUTHED, 3, csa_donewpw, "Change your password.");
24 chanservaddcommand("email", QCMD_AUTHED, 3, csa_doemail, "Change your email address.");
25 chanservaddcommand("requestpassword", QCMD_NOTAUTHED, 2, csa_doreqpw, "Requests the current password by email.");
26 chanservaddcommand("requestmasterpassword", QCMD_AUTHED, 1, csa_doreqmasterpw, "Requests a new master password by email.");
27 chanservaddcommand("setpassword", QCMD_OPER, 2, csa_dosetpw, "Set a new password.");
28 chanservaddcommand("setemail", QCMD_OPER, 2, csa_dosetmail, "Set the email address.");
29 chanservaddcommand("setmasterpassword", QCMD_OPER, 2, csa_dosetmasterpw, "Set the master password.");
30 // chanservaddcommand("getpassword", QCMD_DEV, 2, csa_dogetpw, "Get the password.");
31 // chanservaddcommand("getmasterpassword", QCMD_DEV, 2, csa_dogetmasterpw, "Get the master password.");
32 }
33
34 void _fini() {
35 csa_freeregex();
36 chanservremovecommand("hello", csa_dohello);
37 chanservremovecommand("auth", csa_doauth);
38 chanservremovecommand("login", csa_doauth);
39 chanservremovecommand("requestpassword", csa_doreqpw);
40 chanservremovecommand("requestmasterpassword", csa_doreqmasterpw);
41 chanservremovecommand("newpass", csa_donewpw);
42 chanservremovecommand("email", csa_doemail);
43 chanservremovecommand("setpassword", csa_dosetpw);
44 chanservremovecommand("setemail", csa_dosetmail);
45 chanservremovecommand("setmasterpassword", csa_dosetmasterpw);
46 }
47
48 /*
49 * check if account is "throttled"
50 */
51 int csa_checkthrottled(nick *sender, reguser *rup, char *s)
52 {
53 time_t now;
54 long d;
55 float t;
56
57 now=time(NULL);
58 d=MAX_RESEND_TIME+rup->lastemailchange-now;
59
60 if (d>MAX_RESEND_TIME)
61 d=MAX_RESEND_TIME;
62
63 if (d>0L) {
64 t = ((float) d) / ((float) 3600);
65 chanservstdmessage(sender, QM_MAILTHROTTLED, t);
66 cs_log(sender,"%s FAIL username %s, new request throttled for %.1f hours",s,rup->username,t);
67 return 1;
68 }
69 return 0;
70 }
71
72 /*
73 * /msg Q HELLO <email address> <email address>
74 */
75 int csa_dohello(void *source, int cargc, char **cargv) {
76 nick *sender=source;
77 reguser *rup;
78 char userhost[USERLEN+HOSTLEN+2];
79
80 if (getreguserfromnick(sender))
81 return CMD_ERROR;
82
83 if (cargc<2) {
84 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "hello");
85 return CMD_ERROR;
86 }
87
88 if (findreguserbynick(sender->nick)) {
89 chanservstdmessage(sender, QM_AUTHNAMEINUSE, sender->nick);
90 return CMD_ERROR;
91 }
92
93 if (strcmp(cargv[0],cargv[1])) {
94 chanservstdmessage(sender, QM_EMAILDONTMATCH);
95 cs_log(sender,"HELLO FAIL username %s email don't match (%s vs %s)",sender->nick,cargv[0],cargv[1]);
96 return CMD_ERROR;
97 }
98
99 if (csa_checkeboy(sender, cargv[0]))
100 return CMD_ERROR;
101
102 rup=getreguser();
103 rup->status=0;
104 rup->ID=++lastuserID;
105 strncpy(rup->username,sender->nick,NICKLEN); rup->username[NICKLEN]='\0';
106 rup->created=time(NULL);
107 rup->lastauth=time(NULL);
108 rup->lastemailchange=time(NULL);
109 rup->flags=QUFLAG_NOTICE;
110 rup->languageid=0;
111 rup->suspendby=0;
112 rup->suspendexp=0;
113 rup->password[0]='\0';
114 rup->masterpass[0]='\0';
115 rup->email=getsstring(cargv[0],EMAILLEN);
116 rup->info=NULL;
117 sprintf(userhost,"%s@%s",sender->ident,sender->host->name->content);
118 rup->lastuserhost=getsstring(userhost,USERLEN+HOSTLEN+1);
119 rup->suspendreason=NULL;
120 rup->comment=NULL;
121 rup->knownon=NULL;
122 rup->checkshd=NULL;
123 rup->stealcount=0;
124 rup->fakeuser=NULL;
125 rup->nicks=NULL;
126 addregusertohash(rup);
127 csa_createrandompw(rup->password, PASSLEN);
128 csa_createrandompw(rup->masterpass, PASSLEN);
129 chanservstdmessage(sender, QM_NEWACCOUNT, rup->username,rup->email->content);
130 cs_log(sender,"HELLO OK created auth %s (%s)",rup->username,rup->email->content);
131 csdb_createuser(rup);
132 csdb_createmail(rup, QMAIL_NEWACCOUNT);
133
134 return CMD_OK;
135 }
136
137 /*
138 * /msg Q AUTH <account> <password>
139 */
140 int csa_doauth(void *source, int cargc, char **cargv) {
141 reguser *rup;
142 activeuser* aup;
143 nick *sender=source;
144 nicklist *nl;
145 char userhost[USERLEN+HOSTLEN+2];
146 int ucount=0;
147
148 if (cargc<2) {
149 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "auth");
150 return CMD_ERROR;
151 }
152
153 if (!(aup = getactiveuserfromnick(sender)))
154 return CMD_ERROR;
155
156 aup->authattempts++;
157 if (aup->authattempts > MAXAUTHATTEMPT) {
158 if ((aup->authattempts % 100) == 0)
159 chanservwallmessage("Warning: User %s!%s@%s attempted to auth %d times. Last attempt: AUTH %s %s",
160 nl->np->nick, nl->np->ident, nl->np->host->name->content, cargv[0], cargv[1]);
161 chanservstdmessage(sender, QM_AUTHFAIL);
162 cs_log(sender,"AUTH FAIL too many auth attempts (last attempt: AUTH %s %s)",cargv[0], cargv[1]);
163 return CMD_ERROR;
164 }
165
166 if (!(rup=findreguserbynick(cargv[0]))) {
167 chanservstdmessage(sender, QM_AUTHFAIL);
168 cs_log(sender,"AUTH FAIL bad username %s",cargv[0]);
169 return CMD_ERROR;
170 }
171
172 if (!checkpassword(rup, cargv[1])) {
173 chanservstdmessage(sender, QM_AUTHFAIL);
174 cs_log(sender,"AUTH FAIL username %s bad password %s",rup->username,cargv[1]);
175 return CMD_ERROR;
176 }
177
178 rup->lastauth=time(NULL);
179 sprintf(userhost,"%s@%s",sender->ident,sender->host->name->content);
180 if (rup->lastuserhost)
181 freesstring(rup->lastuserhost);
182 rup->lastuserhost=getsstring(userhost,USERLEN+HOSTLEN+1);
183
184 if (UHasSuspension(rup) && rup->suspendexp && (time(0) >= rup->suspendexp)) {
185 /* suspension has expired, remove it */
186 rup->flags&=(~(QUFLAG_SUSPENDED|QUFLAG_GLINE|QUFLAG_DELAYEDGLINE));
187 rup->suspendby=0;
188 rup->suspendexp=0;
189 freesstring(rup->suspendreason);
190 rup->suspendreason=0;
191 }
192
193 if (UIsNeedAuth(rup))
194 rup->flags&=~(QUFLAG_NEEDAUTH);
195 csdb_updateuser(rup);
196
197 if (UIsDelayedGline(rup)) {
198 /* delayed-gline - schedule the user's squelching */
199 deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
200 scheduleoneshot(time(NULL)+rand()%900, &chanservdgline, (void*)rup);
201 }
202 else if (UIsGline(rup)) {
203 /* instant-gline - lets be lazy and set a schedule expiring now :) */
204 deleteschedule(NULL, &chanservdgline, (void*)rup); /* icky, but necessary unless we stick more stuff in reguser structure */
205 scheduleoneshot(time(NULL), &chanservdgline, (void*)rup);
206 }
207 else if (UIsSuspended(rup)) {
208 /* plain suspend */
209 chanservstdmessage(sender, QM_AUTHSUSPENDED);
210 chanservstdmessage(sender, QM_REASON, rup->suspendreason->content);
211 if (rup->suspendexp) {
212 struct tm* tmp;
213 char buf[200];
214
215 tmp=gmtime(&(rup->suspendexp));
216 strftime(buf, 15, "%d/%m/%y %H:%M", tmp);
217 chanservstdmessage(sender, QM_EXPIRES, buf);
218 }
219 return CMD_ERROR;
220 }
221
222 if (!UHasHelperPriv(rup) && !UIsNoAuthLimit(rup)) {
223 for (nl=rup->nicks; nl; nl=nl->next)
224 ucount++;
225
226 if (ucount >= MAXAUTHCOUNT) {
227 chanservstdmessage(sender, QM_TOOMANYAUTHS);
228 return CMD_ERROR;
229 }
230 }
231
232 chanservstdmessage(sender, QM_AUTHOK, rup->username);
233 cs_log(sender,"AUTH OK username %s", rup->username);
234 localusersetaccount(sender, rup->username);
235
236 return CMD_OK;
237 }
238
239 /*
240 * /msg Q REQUESTPASSWORD <account> <email>
241 */
242 int csa_doreqpw(void *source, int cargc, char **cargv) {
243 reguser *rup;
244 nick *sender=source;
245
246 if (cargc<2) {
247 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "requestpassword");
248 return CMD_ERROR;
249 }
250
251 if (!(rup=findreguser(sender, cargv[0])))
252 return CMD_ERROR;
253
254 if (ircd_strcmp(cargv[1],rup->email->content)) {
255 chanservstdmessage(sender, QM_BADEMAIL, rup->username);
256 cs_log(sender,"REQUESTPASSWORD FAIL wrong email, username %s email %s",rup->username,cargv[1]);
257 return CMD_ERROR;
258 }
259
260 if (csa_checkthrottled(sender, rup, "REQUESTPASSWORD"))
261 return CMD_ERROR;
262
263 rup->lastemailchange=time(NULL);
264 csdb_updateuser(rup);
265 csdb_createmail(rup, QMAIL_REQPW);
266 chanservstdmessage(sender, QM_MAILQUEUED, rup->username);
267 cs_log(sender,"REQUESTPASSWORD OK username %s email %s", rup->username,rup->email->content);
268
269 return CMD_OK;
270 }
271
272 /*
273 * /msg Q NEWPASS <master password> <new password> <new password>
274 */
275 int csa_donewpw(void *source, int cargc, char **cargv) {
276 reguser *rup;
277 nick *sender=source;
278
279 if (cargc<3) {
280 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "newpass");
281 return CMD_ERROR;
282 }
283
284 if (!(rup=getreguserfromnick(sender)))
285 return CMD_ERROR;
286
287 if (!checkmasterpassword(rup, cargv[0])) {
288 chanservstdmessage(sender, QM_AUTHFAIL);
289 cs_log(sender,"NEWPASS FAIL username %s bad masterpassword %s",rup->username,cargv[0]);
290 return CMD_ERROR;
291 }
292
293 if (strcmp(cargv[1],cargv[2])) {
294 chanservstdmessage(sender, QM_PWDONTMATCH); /* Sorry, passwords do not match */
295 cs_log(sender,"NEWPASS FAIL username %s new passwords don't match (%s vs %s)",rup->username,cargv[1],cargv[2]);
296 return CMD_ERROR;
297 }
298
299 if (strlen(cargv[1]) < 6) {
300 chanservstdmessage(sender, QM_PWTOSHORT); /* new password to short */
301 cs_log(sender,"NEWPASS FAIL username %s password to short %s (%d characters)",rup->username,cargv[1],strlen(cargv[1]));
302 return CMD_ERROR;
303 }
304
305 setpassword(rup, cargv[1]);
306 rup->lastauth=time(NULL);
307 chanservstdmessage(sender, QM_PWCHANGED);
308 cs_log(sender,"NEWPASS OK username %s", rup->username);
309 csdb_updateuser(rup);
310 csdb_createmail(rup, QMAIL_NEWPW);
311
312 return CMD_OK;
313 }
314
315 /*
316 * /msg Q REQUESTMASTERPASSWORD
317 */
318 int csa_doreqmasterpw(void *source, int cargc, char **cargv) {
319 reguser *rup;
320 nick *sender=source;
321
322 if (!(rup=getreguserfromnick(sender)))
323 return CMD_ERROR;
324
325 if (csa_checkthrottled(sender, rup, "REQUESTMASTERPASSWORD"))
326 return CMD_ERROR;
327
328 csa_createrandompw(rup->masterpass, PASSLEN);
329 chanservstdmessage(sender, QM_MASTERPWCHANGED);
330 cs_log(sender,"REQUESTMASTERPASSWORD OK username %s",rup->username);
331 csdb_updateuser(rup);
332 csdb_createmail(rup, QMAIL_NEWMASTERPW);
333
334 return CMD_OK;
335 }
336
337 /*
338 * /msg Q EMAIL <master password> <email address> <email address>
339 */
340 int csa_doemail(void *source, int cargc, char **cargv) {
341 reguser *rup;
342 nick *sender=source;
343
344 if (cargc<3) {
345 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "email");
346 return CMD_ERROR;
347 }
348
349 if (!(rup=getreguserfromnick(sender)))
350 return CMD_ERROR;
351
352 if (!checkmasterpassword(rup, cargv[0])) {
353 chanservstdmessage(sender, QM_AUTHFAIL);
354 cs_log(sender,"EMAIL FAIL username %s bad masterpass %s",rup->username,cargv[0]);
355 return CMD_ERROR;
356 }
357
358 if (strcmp(cargv[1],cargv[2])) {
359 chanservstdmessage(sender, QM_EMAILDONTMATCH);
360 cs_log(sender,"EMAIL FAIL username %s email don't match (%s vs %s)",rup->username,cargv[1],cargv[2]);
361 return CMD_ERROR;
362 }
363
364 if (csa_checkeboy(sender, cargv[1]))
365 return CMD_ERROR;
366
367 // rup2->ID = rup->ID;
368 // rup2->email=getsstring(rup->email->content,EMAILLEN); /* save previous email addy */
369
370 csdb_createmail(rup, QMAIL_NEWEMAIL);
371 freesstring(rup->email);
372 rup->email=getsstring(cargv[1],EMAILLEN);
373 rup->lastemailchange=time(NULL);
374 chanservstdmessage(sender, QM_EMAILCHANGED, cargv[1]);
375 cs_log(sender,"EMAIL OK username %s",rup->username);
376 csdb_updateuser(rup);
377
378 return CMD_OK;
379 }
380
381 /*
382 * /msg Q SETPASSWORD <account> <new password>
383 */
384 int csa_dosetpw(void *source, int cargc, char **cargv) {
385 reguser *rup;
386 nick *sender=source;
387
388 if (cargc<2) {
389 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "setpassword");
390 return CMD_ERROR;
391 }
392
393 if (!(rup=findreguser(sender, cargv[0])))
394 return CMD_ERROR;
395
396 strncpy(rup->password,cargv[1],PASSLEN);
397 rup->password[PASSLEN]='\0';
398 chanservstdmessage(sender, QM_PWCHANGED);
399 cs_log(sender,"SETPASSWORD OK username %s",rup->username);
400 csdb_updateuser(rup);
401
402 return CMD_OK;
403 }
404
405 /*
406 * /msg Q SETEMAIL <account> <email address>
407 */
408 int csa_dosetmail(void *source, int cargc, char **cargv) {
409 reguser *rup;
410 nick *sender=source;
411
412 if (cargc<2) {
413 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "setemail");
414 return CMD_ERROR;
415 }
416
417 if (!(rup=findreguser(sender, cargv[0])))
418 return CMD_ERROR;
419
420 if (csa_checkeboy(sender, cargv[1]))
421 return CMD_ERROR;
422
423 freesstring(rup->email);
424 rup->email=getsstring(cargv[1],EMAILLEN);
425 rup->lastemailchange=time(NULL);
426 chanservstdmessage(sender, QM_EMAILCHANGED, cargv[1]);
427 cs_log(sender,"SETEMAIL OK username %s <%s>",rup->username,rup->email->content);
428 csdb_updateuser(rup);
429
430 return CMD_OK;
431 }
432
433 /*
434 * /msg Q SETMASTERPASSWORD <account>
435 */
436 int csa_dosetmasterpw(void *source, int cargc, char **cargv) {
437 reguser *rup;
438 nick *sender=source;
439
440 if (cargc<1) {
441 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "setmasterpassword");
442 return CMD_ERROR;
443 }
444
445 if (!(rup=findreguser(sender, cargv[0])))
446 return CMD_ERROR;
447
448 csa_createrandompw(rup->masterpass, PASSLEN);
449 chanservstdmessage(sender, QM_MASTERPWCHANGED);
450 cs_log(sender,"SETMASTERPASSWORD OK username %s",rup->username);
451 csdb_updateuser(rup);
452
453 return CMD_OK;
454 }