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