]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/authlib.c
CHANSERV: refactor authlib slightly
[irc/quakenet/newserv.git] / chanserv / authlib.c
1 /* authlib.c */
2
3 #include "chanserv.h"
4 #include "../lib/irc_string.h"
5 #include "authlib.h"
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <ctype.h>
10 #include <sys/types.h>
11 #include <regex.h>
12
13 regex_t remail, raccount;
14 static int regexinit;
15
16 int csa_initregex(void) {
17 if (regexinit)
18 return 1;
19
20 if (regcomp(&remail, VALID_EMAIL, REG_EXTENDED | REG_NOSUB | REG_ICASE))
21 return 0;
22
23 if (regcomp(&raccount, VALID_ACCOUNT_NAME, REG_EXTENDED | REG_NOSUB | REG_ICASE)) {
24 regfree(&remail);
25 return 0;
26 }
27
28 regexinit = 1;
29 return 1;
30 }
31
32 void csa_freeregex(void) {
33 if(!regexinit)
34 return;
35
36 regfree(&remail);
37 regfree(&raccount);
38 regexinit = 0;
39 }
40
41 /*
42 * use regex matching to determine if it's a valid eboy or not
43 */
44 int csa_checkeboy_r(char *eboy)
45 {
46 int i, len;
47
48 len = (((strlen(eboy)) < (EMAILLEN)) ? (strlen(eboy)) : (EMAILLEN));
49 if (len <= 4) {
50 return QM_EMAILTOOSHORT;
51 }
52
53 if (strstr(&eboy[1], "@") == NULL) {
54 return QM_EMAILNOAT;
55 }
56
57 if (eboy[len - 1] == '@') {
58 return QM_EMAILATEND;
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] == '-')) {
65 return QM_EMAILINVCHR;
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)
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;
76 }
77
78 if (regexec(&remail, eboy, (size_t) 0, NULL, 0)) {
79 return QM_INVALIDEMAIL;
80 }
81
82 return -1;
83 }
84
85 int 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;
95 }
96
97 /*
98 * use regex matching to determine if it's a valid account name or not
99 */
100 int csa_checkaccountname_r(char *accountname) {
101 if (regexec(&raccount, accountname, (size_t) 0, NULL, 0)) {
102 return (1);
103 }
104 return (0);
105 }
106
107 int 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 }
114
115 /*
116 * create a random pw. code stolen from fox's O
117 */
118 void 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 }
128
129 /*
130 * check if account is "throttled"
131 */
132 int 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 }
152
153 int 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
173 reguser *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 }