]> jfr.im git - irc/quakenet/newserv.git/blame - chanserv/authlib.c
Make the pool allocator Valgrind-aware.
[irc/quakenet/newserv.git] / chanserv / authlib.c
CommitLineData
c86edd1d
Q
1/* authlib.c */
2
c86edd1d
Q
3#include "chanserv.h"
4#include "../lib/irc_string.h"
6ff65e48 5#include "authlib.h"
c86edd1d 6
6ff65e48 7#include <stdio.h>
c86edd1d
Q
8#include <string.h>
9#include <ctype.h>
10#include <sys/types.h>
11#include <regex.h>
12
dc9548f4 13regex_t remail, raccount;
e2340b39 14static int regexinit;
c86edd1d 15
dc9548f4 16int csa_initregex(void) {
e2340b39
CP
17 if (regexinit)
18 return 1;
19
dc9548f4 20 if (regcomp(&remail, VALID_EMAIL, REG_EXTENDED | REG_NOSUB | REG_ICASE))
e2340b39
CP
21 return 0;
22
dc9548f4
CP
23 if (regcomp(&raccount, VALID_ACCOUNT_NAME, REG_EXTENDED | REG_NOSUB | REG_ICASE)) {
24 regfree(&remail);
25 return 0;
26 }
27
e2340b39
CP
28 regexinit = 1;
29 return 1;
c86edd1d
Q
30}
31
dc9548f4
CP
32void csa_freeregex(void) {
33 if(!regexinit)
34 return;
35
36 regfree(&remail);
37 regfree(&raccount);
38 regexinit = 0;
c86edd1d
Q
39}
40
41/*
42 * use regex matching to determine if it's a valid eboy or not
43 */
6ff65e48
CP
44int csa_checkeboy_r(char *eboy)
45{
c86edd1d
Q
46 int i, len;
47
48 len = (((strlen(eboy)) < (EMAILLEN)) ? (strlen(eboy)) : (EMAILLEN));
49 if (len <= 4) {
6ff65e48 50 return QM_EMAILTOOSHORT;
c86edd1d
Q
51 }
52
53 if (strstr(&eboy[1], "@") == NULL) {
6ff65e48 54 return QM_EMAILNOAT;
c86edd1d
Q
55 }
56
57 if (eboy[len - 1] == '@') {
6ff65e48 58 return QM_EMAILATEND;
c86edd1d
Q
59 }
60
61 for (i = 0; i < len; i++) {
62 if (!isalpha(eboy[i]) && !isdigit(eboy[i])
63 && !(eboy[i] == '@') && !(eboy[i] == '.')
64 && !(eboy[i] == '_') && !(eboy[i] == '-')) {
6ff65e48 65 return QM_EMAILINVCHR;
c86edd1d
Q
66 }
67 }
68
69 /* catch some real lame attempts */
70 if (!ircd_strncmp("user@mymailhost.xx", eboy, len) || !ircd_strncmp("info@quakenet.org", eboy, len)
71 || !ircd_strncmp("user@mymail.xx", eboy, len) || !ircd_strncmp("user@mail.cc", eboy, len)
72 || !ircd_strncmp("user@host.com", eboy, len) || !ircd_strncmp("Jackie@your.isp.com", eboy, len)
6ff65e48
CP
73 || !ircd_strncmp("QBot@QuakeNet.org", eboy, len) || !ircd_strncmp("Q@CServe.quakenet.org", eboy, len)
74 || !ircd_strncmp("badger@example.com", eboy, len)) {
75 return QM_NOTYOUREMAIL;
c86edd1d
Q
76 }
77
dc9548f4 78 if (regexec(&remail, eboy, (size_t) 0, NULL, 0)) {
6ff65e48 79 return QM_INVALIDEMAIL;
c86edd1d
Q
80 }
81
6ff65e48
CP
82 return -1;
83}
84
85int csa_checkeboy(nick *sender, char *eboy)
86{
87 int r = csa_checkeboy_r(eboy);
88 if (r == -1)
89 return 0;
90
91 if(sender)
92 chanservstdmessage(sender, r, eboy);
93
94 return 1;
c86edd1d
Q
95}
96
dc9548f4
CP
97/*
98 * use regex matching to determine if it's a valid account name or not
99 */
6ff65e48 100int csa_checkaccountname_r(char *accountname) {
dc9548f4 101 if (regexec(&raccount, accountname, (size_t) 0, NULL, 0)) {
dc9548f4
CP
102 return (1);
103 }
104 return (0);
105}
106
6ff65e48
CP
107int csa_checkaccountname(nick *sender, char *accountname) {
108 int r = csa_checkaccountname_r(accountname);
109 if(r && sender)
110 chanservstdmessage(sender, QM_INVALIDACCOUNTNAME);
111
112 return r;
113}
dc9548f4 114
c86edd1d
Q
115/*
116 * create a random pw. code stolen from fox's O
117 */
118void csa_createrandompw(char *pw, int n)
119{
120 int i;
121 char upwdchars[] = "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789-!";
122
123 for (i = 0; i < n; i++) {
124 pw[i] = upwdchars[rand() % (sizeof(upwdchars) - 1)];
125 }
126 pw[n] = '\0';
127}
1dd6d55d 128
129/*
130 * check if account is "throttled"
131 */
132int csa_checkthrottled(nick *sender, reguser *rup, char *s)
133{
134 time_t now;
135 long d;
136 float t;
137
138 now=time(NULL);
139 d=MAX_RESEND_TIME+rup->lastemailchange-now;
140
141 if (d>MAX_RESEND_TIME)
142 d=MAX_RESEND_TIME;
143
144 if (d>0L) {
145 t = ((float) d) / ((float) 3600);
146 chanservstdmessage(sender, QM_MAILTHROTTLED, t);
147 cs_log(sender,"%s FAIL username %s, new request throttled for %.1f hours",s,rup->username,t);
148 return 1;
149 }
150 return 0;
151}
6ff65e48
CP
152
153int csa_checkpasswordquality(char *password) {
154 int i, cntweak = 0, cntdigits = 0, cntletters = 0;
155 if (strlen(password) < 6)
156 return QM_PWTOSHORT;
157
158 for ( i = 0; password[i] && i < PASSLEN; i++ ) {
159 if ( password[i] == password[i+1] || password[i] + 1 == password[i+1] || password[i] - 1 == password[i+1] )
160 cntweak++;
161 if(isdigit(password[i]))
162 cntdigits++;
163 if(islower(password[i]) || isupper(password[i]))
164 cntletters++;
165 }
166
167 if( cntweak > 3 || !cntdigits || !cntletters)
168 return QM_PWTOWEAK;
169
170 return -1;
171}
172
173reguser *csa_createaccount(char *username, char *password, char *email) {
174 time_t t = time(NULL);
175 char *local, *dupemail;
176
177 dupemail = strdup(email);
178 local=strchr(dupemail, '@');
179 if(!local) {
180 free(dupemail);
181 return NULL;
182 }
183 *(local++)='\0';
184
185 reguser *rup=getreguser();
186 rup->status=0;
187 rup->ID=++lastuserID;
188 strncpy(rup->username,username,NICKLEN); rup->username[NICKLEN]='\0';
189 rup->created=t;
190 rup->lastauth=0;
191 rup->lastemailchange=t;
192 rup->lastpasschange=t;
193 rup->flags=QUFLAG_NOTICE;
194 rup->languageid=0;
195 rup->suspendby=0;
196 rup->suspendexp=0;
197 rup->suspendtime=0;
198 rup->lockuntil=0;
199 strncpy(rup->password,password,PASSLEN); rup->password[PASSLEN]='\0';
200 rup->email=getsstring(email,EMAILLEN);
201 rup->lastemail=NULL;
202
203 rup->localpart=getsstring(dupemail,EMAILLEN);
204 free(dupemail);
205
206 rup->domain=findorcreatemaildomain(email);
207 addregusertomaildomain(rup, rup->domain);
208 rup->info=NULL;
209 rup->lastuserhost=NULL;
210 rup->suspendreason=NULL;
211 rup->comment=NULL;
212 rup->knownon=NULL;
213 rup->checkshd=NULL;
214 rup->stealcount=0;
215 rup->fakeuser=NULL;
216 addregusertohash(rup);
217
218 return rup;
219}