]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/authcmds/auth.c
CHANSERV: tell user when they can't attempts to auth any more, and drop max attempts...
[irc/quakenet/newserv.git] / chanserv / authcmds / auth.c
1 /* Automatically generated by refactor.pl.
2 *
3 *
4 * CMDNAME: auth
5 * CMDALIASES: login ircdauth
6 * CMDLEVEL: QCMD_SECURE | QCMD_NOTAUTHED
7 * CMDARGS: 2
8 * CMDDESC: Authenticates you on the bot.
9 * CMDFUNC: csa_doauth
10 * CMDPROTO: int csa_doauth(void *source, int cargc, char **cargv);
11 * CMDHELP: Usage: @UCOMMAND@ <username> <password>
12 * CMDHELP: Authenticates you on the bot, where:
13 * CMDHELP: username - your username
14 * CMDHELP: password - your password
15 * CMDHELP: If you do not have a username and password, see HELLO.
16 * CMDHELP: Note: due to the sensitive nature of this command, you must send the message
17 * CMDHELP: to Q@CServe.quakenet.org when using it.
18 * CMDHELP: Note: the preferred way to authenticate is to use the /AUTH command.
19 */
20
21 #include "../chanserv.h"
22 #include "../authlib.h"
23 #include "../../lib/irc_string.h"
24 #include <stdio.h>
25 #include <string.h>
26
27 int csa_completeauth(nick *sender, reguser *rup, char *authtype);
28
29 int csa_auth(void *source, int cargc, char **cargv, CRAlgorithm alg) {
30 reguser *rup;
31 activeuser *aup;
32 nick *sender=source;
33 int challenge=0;
34 char *authtype = "AUTH";
35
36 if (alg) {
37 challenge=1;
38 authtype = "CHALLENGEAUTH";
39 } else if (cargc<2) {
40 chanservstdmessage(sender, QM_NOTENOUGHPARAMS, "auth");
41 return CMD_ERROR;
42 }
43
44 if (!(aup = getactiveuserfromnick(sender)))
45 return CMD_ERROR;
46
47 aup->authattempts++;
48 if (aup->authattempts > MAXAUTHATTEMPT) {
49 /*
50 if ((aup->authattempts % 100) == 0)
51 chanservwallmessage("Warning: User %s!%s@%s attempted to auth %d times. Last attempt: %s %s %s",
52 sender->nick, sender->ident, sender->host->name->content, aup->authattempts, authtype, cargv[0], cargv[1]);
53 */
54
55 chanservstdmessage(sender, QM_TOOMANYAUTHATTEMPTS);
56 cs_log(sender,"%s FAIL too many auth attempts (last attempt: %s %s %s)", authtype, authtype, cargv[0], cargv[1]);
57 return CMD_ERROR;
58 }
59
60 if (!(rup=findreguserbynick(cargv[0]))) {
61 chanservstdmessage(sender, QM_AUTHFAIL);
62 cs_log(sender,"%s FAIL bad username %s",authtype,cargv[0]);
63 return CMD_ERROR;
64 }
65
66 if (!challenge) {
67 if (!checkpassword(rup, cargv[1])) {
68 chanservstdmessage(sender, QM_AUTHFAIL);
69 cs_log(sender,"%s FAIL username %s bad password %s",authtype,rup->username,cargv[1]);
70 return CMD_ERROR;
71 }
72 } else {
73 if (!checkresponse(rup, aup->entropy, cargv[1], alg)) {
74 chanservstdmessage(sender, QM_AUTHFAIL);
75 cs_log(sender,"%s FAIL username %s bad response",authtype,rup->username);
76 return CMD_ERROR;
77 }
78 }
79
80 return csa_completeauth(sender, rup, authtype);
81 }
82
83 int csa_completeauth(nick *sender, reguser *rup, char *authtype) {
84 int toomanyauths=0;
85 time_t now, oldlastauth;
86 char userhost[USERLEN+HOSTLEN+2];
87 nick *onp;
88 void *args[2];
89 authname *anp;
90
91 /* This should never fail but do something other than crashing if it does. */
92 if (!(anp=findauthname(rup->ID))) {
93 chanservstdmessage(sender, QM_AUTHFAIL);
94 return CMD_ERROR;
95 }
96
97 /* Check for too many auths. Don't return immediately, since we will still warn
98 * other users on the acct in this case. */
99 if (!UHasStaffPriv(rup) && !UIsNoAuthLimit(rup)) {
100 if (anp->usercount >= MAXAUTHCOUNT) {
101 chanservstdmessage(sender, QM_TOOMANYAUTHS);
102 toomanyauths=1;
103 }
104 }
105
106 for (onp=anp->nicks;onp;onp=onp->nextbyauthname) {
107 if (toomanyauths) {
108 chanservstdmessage(onp, QM_OTHERUSERAUTHEDLIMIT, sender->nick, sender->ident, sender->host->name->content, MAXAUTHCOUNT);
109 } else {
110 chanservstdmessage(onp, QM_OTHERUSERAUTHED, sender->nick, sender->ident, sender->host->name->content);
111 }
112 }
113
114 if (toomanyauths)
115 return CMD_ERROR;
116
117 now=time(NULL);
118
119 if (UHasSuspension(rup) && rup->suspendexp && (now >= rup->suspendexp)) {
120 /* suspension has expired, remove it */
121 rup->flags&=(~(QUFLAG_SUSPENDED|QUFLAG_GLINE|QUFLAG_DELAYEDGLINE));
122 rup->suspendby=0;
123 rup->suspendexp=0;
124 freesstring(rup->suspendreason);
125 rup->suspendreason=0;
126 csdb_updateuser(rup);
127 }
128
129 if (UIsSuspended(rup)) {
130 /* plain suspend */
131 chanservstdmessage(sender, QM_AUTHSUSPENDED);
132 if(rup->suspendreason)
133 chanservstdmessage(sender, QM_REASON, rup->suspendreason->content);
134 if (rup->suspendexp)
135 chanservstdmessage(sender, QM_EXPIRES, rup->suspendexp);
136 return CMD_ERROR;
137 }
138 if (UIsInactive(rup)) {
139 chanservstdmessage(sender, QM_INACTIVEACCOUNT);
140 return CMD_ERROR;
141 }
142
143 /* Guarantee a unique auth timestamp for each account */
144 oldlastauth=rup->lastauth;
145
146 if (rup->lastauth < now)
147 rup->lastauth=now;
148 else
149 rup->lastauth++;
150
151 sprintf(userhost,"%s@%s",sender->ident,sender->host->name->content);
152 if (rup->lastuserhost)
153 freesstring(rup->lastuserhost);
154 rup->lastuserhost=getsstring(userhost,USERLEN+HOSTLEN+1);
155
156 csdb_updateuser(rup);
157
158 cs_log(sender,"%s OK username %s", authtype,rup->username);
159
160 localusersetaccount(sender, rup->username, rup->ID, cs_accountflagmap(rup), rup->lastauth);
161
162 chanservstdmessage(sender, QM_AUTHOK, rup->username);
163
164 args[0]=sender;
165 args[1]=(void *)oldlastauth;
166 triggerhook(HOOK_CHANSERV_AUTH, args);
167
168 return CMD_OK;
169 }
170
171 int csa_doauth(void *source, int cargc, char **cargv) {
172 return csa_auth(source, cargc, cargv, NULL);
173 }