]>
Commit | Line | Data |
---|---|---|
1 | #include <ctype.h> | |
2 | #include <string.h> | |
3 | #include "../lib/strlfunc.h" | |
4 | #include "../core/config.h" | |
5 | #include "../core/schedule.h" | |
6 | #include "../localuser/localuser.h" | |
7 | #include "patrol.h" | |
8 | ||
9 | static sstring *patrol_hostpool[PATROL_POOLSIZE], *patrol_tailpool[PATROL_POOLSIZE]; | |
10 | static unsigned int patrol_hostpoolsize, patrol_tailpoolsize; | |
11 | static int patrol_min_hosts; | |
12 | static char patrol_hostmode; | |
13 | ||
14 | int patrol_minmaxrand(float min, float max) { | |
15 | return (int)((max - min + 1) * rand() / (RAND_MAX + min)) + min; | |
16 | } | |
17 | ||
18 | nick *patrol_selectuser(void) { | |
19 | int target = patrol_minmaxrand(0, 500), loops = 150, j; | |
20 | nick *np; | |
21 | ||
22 | do { | |
23 | for (j = patrol_minmaxrand(0, NICKHASHSIZE - 1); j < NICKHASHSIZE; j++) | |
24 | for (np = nicktable[j]; np; np = np->next) | |
25 | if (!--target) | |
26 | return np; | |
27 | } while (--loops > 0); | |
28 | ||
29 | return NULL; | |
30 | } | |
31 | ||
32 | host *patrol_selecthost(void) { | |
33 | int target = patrol_minmaxrand(0, 500), loops = 150, j; | |
34 | host *hp; | |
35 | ||
36 | do { | |
37 | for (j = patrol_minmaxrand(0, HOSTHASHSIZE - 1); j < HOSTHASHSIZE; j++) | |
38 | for (hp = hosttable[j]; hp; hp = hp->next) | |
39 | if (!--target) | |
40 | return hp; | |
41 | } while (--loops > 0); | |
42 | ||
43 | return NULL; | |
44 | } | |
45 | ||
46 | int patrol_isip(char *host) { | |
47 | struct irc_in_addr ip; | |
48 | unsigned char bits; | |
49 | ||
50 | return (ipmask_parse(host, &ip, &bits)); | |
51 | } | |
52 | ||
53 | static int specialuseronhost(host *hp) { | |
54 | nick *np; | |
55 | ||
56 | for (np = hp->nicks; np; np = np->nextbyhost) | |
57 | if (IsOper(np) || IsService(np) || IsXOper(np) || NickOnServiceServer(np)) | |
58 | return 1; | |
59 | ||
60 | return 0; | |
61 | } | |
62 | ||
63 | char patrol_genchar(int ty) { | |
64 | /* hostname and realname characters*/ | |
65 | if (!ty) { | |
66 | if (!(patrol_minmaxrand(0, 40) % 10)) { | |
67 | return patrol_minmaxrand(48, 57); | |
68 | } else { | |
69 | return patrol_minmaxrand(97, 122); | |
70 | } | |
71 | ||
72 | /* ident characters - without numbers*/ | |
73 | } else if (ty == 1) { | |
74 | return patrol_minmaxrand(97, 122); | |
75 | /* ident characters - with numbers*/ | |
76 | } else if (ty == 2) { | |
77 | ty = patrol_minmaxrand(97, 125); | |
78 | ||
79 | if (ty > 122) return patrol_minmaxrand(48, 57); | |
80 | ||
81 | return ty; | |
82 | /* nick characters - with and without numbers*/ | |
83 | } else if (ty == 3 || ty == 4) { | |
84 | if (!(patrol_minmaxrand(0, 59) % 16)) { | |
85 | char weirdos[6] = { '\\', '|', '[', '{', ']', '}' }; | |
86 | return weirdos[patrol_minmaxrand(0, 5)]; | |
87 | } | |
88 | ||
89 | if (ty == 4) { | |
90 | ty = patrol_minmaxrand(65, 93); | |
91 | ||
92 | if (ty > 90) return patrol_minmaxrand(48, 57); | |
93 | } else { | |
94 | ty = patrol_minmaxrand(65, 90); | |
95 | } | |
96 | ||
97 | if (!(patrol_minmaxrand(0, 40) % 8)) return ty; | |
98 | ||
99 | return ty + 32; | |
100 | /* moron check */ | |
101 | } else { | |
102 | return ' '; | |
103 | } | |
104 | } | |
105 | ||
106 | void patrol_gennick(char *ptc, char size) { | |
107 | int i; | |
108 | ||
109 | for (i = 0; i < size; i++) { | |
110 | if (i == 0) { | |
111 | ptc[i] = patrol_genchar(3); | |
112 | } else { | |
113 | ptc[i] = patrol_genchar(4); | |
114 | } | |
115 | } | |
116 | ||
117 | ptc[i] = '\0'; | |
118 | } | |
119 | ||
120 | void patrol_genident(char *ptc, char size) { | |
121 | int i; | |
122 | ||
123 | for (i = 0; i < size; i++) { | |
124 | if (i == 0) { | |
125 | ptc[i] = patrol_genchar(1); | |
126 | } else { | |
127 | ptc[i] = patrol_genchar(2); | |
128 | } | |
129 | } | |
130 | ||
131 | ptc[i] = '\0'; | |
132 | } | |
133 | ||
134 | void patrol_genhost(char *ptc, char size, struct irc_in_addr *ipaddress) { | |
135 | int dots = patrol_minmaxrand(2, 5), i, dotexist = 0, cur; | |
136 | ||
137 | while (!dotexist) { | |
138 | for (i = 0; i < size; i++) { | |
139 | ptc[i] = patrol_genchar(0); | |
140 | ||
141 | if ((i > 5) && (i < (size - 4))) { | |
142 | if ((ptc[i - 1] != '.') && (ptc[i - 1] != '-')) { | |
143 | cur = patrol_minmaxrand(1, size / dots); | |
144 | ||
145 | if (cur < 3) { | |
146 | if (cur == 1) { | |
147 | ptc[i] = '.'; | |
148 | dotexist = 1; | |
149 | } else { | |
150 | ptc[i] = '-'; | |
151 | } | |
152 | } | |
153 | } | |
154 | } | |
155 | } | |
156 | } | |
157 | ||
158 | ptc[i] = '\0'; | |
159 | ||
160 | memset(ipaddress, 0, sizeof(*ipaddress)); | |
161 | ((unsigned short *)(ipaddress->in6_16))[5] = 65535; | |
162 | ((unsigned short *)(ipaddress->in6_16))[6] = patrol_minmaxrand(0, 65535); | |
163 | ((unsigned short *)(ipaddress->in6_16))[7] = patrol_minmaxrand(0, 65535); | |
164 | } | |
165 | ||
166 | void patrol_genreal(char *ptc, char size) { | |
167 | int spaces = patrol_minmaxrand(2, 4), i; | |
168 | ||
169 | for (i = 0; i < size; i++) { | |
170 | ptc[i] = patrol_genchar(0); | |
171 | ||
172 | if ((i > 5) && (i < (size - 4))) { | |
173 | if (ptc[i - 1] != ' ') { | |
174 | if (patrol_minmaxrand(1, size / spaces) == 1) ptc[i] = ' '; | |
175 | } | |
176 | } | |
177 | } | |
178 | ||
179 | ptc[i] = '\0'; | |
180 | } | |
181 | ||
182 | void patrol_generatehost(char *buf, int maxsize, struct irc_in_addr *ipaddress) { | |
183 | if (PATROL_HOST_MODE == PATROL_STEAL_HOST) { | |
184 | host *hp; | |
185 | int loops = 20; | |
186 | ||
187 | buf[0] = '\0'; | |
188 | ||
189 | do { | |
190 | hp = patrol_selecthost(); | |
191 | ||
192 | if (hp && (hp->clonecount <= PATROL_MAX_CLONE_COUNT) && !patrol_isip(hp->name->content) && !specialuseronhost(hp)) { | |
193 | strlcpy(buf, hp->name->content, maxsize + 1); | |
194 | ||
195 | if (hp->nicks) { | |
196 | memcpy(ipaddress, &hp->nicks->ipaddress, sizeof(struct irc_in_addr)); | |
197 | } else { | |
198 | memset(ipaddress, 0, sizeof(struct irc_in_addr)); | |
199 | ((unsigned short *)(ipaddress->in6_16))[5] = 65535; | |
200 | ((unsigned short *)(ipaddress->in6_16))[6] = patrol_minmaxrand(0, 65535); | |
201 | ((unsigned short *)(ipaddress->in6_16))[7] = patrol_minmaxrand(0, 65535); | |
202 | } | |
203 | ||
204 | break; | |
205 | } | |
206 | } while (--loops > 0); | |
207 | } else { | |
208 | char *cpos; | |
209 | int pieces = patrol_minmaxrand(2, 4), totallen = 0, a = 0, i; | |
210 | int *choices = malloc(sizeof(int) * (pieces + 1)); | |
211 | int *lengths = malloc(sizeof(int) * (pieces + 1)); | |
212 | ||
213 | choices[pieces] = patrol_minmaxrand(0, patrol_tailpoolsize - 1); | |
214 | lengths[pieces] = strlen(patrol_tailpool[choices[pieces]]->content) + 1; | |
215 | totallen += lengths[pieces]; | |
216 | ||
217 | for (i = 0; i < pieces; i++) { | |
218 | choices[i] = patrol_minmaxrand(0, patrol_hostpoolsize - 1); | |
219 | lengths[i] = strlen(patrol_hostpool[choices[i]]->content) + 1; | |
220 | ||
221 | if (totallen + lengths[i] > maxsize) { | |
222 | choices[i] = choices[pieces]; | |
223 | lengths[i] = lengths[pieces]; | |
224 | pieces -= (pieces - i); | |
225 | break; | |
226 | } | |
227 | ||
228 | totallen += lengths[i]; | |
229 | } | |
230 | ||
231 | for (i = 0; i < pieces; i++) { | |
232 | for (cpos = patrol_hostpool[choices[i]]->content; *cpos;) | |
233 | buf[a++] = *cpos++; | |
234 | ||
235 | buf[a++] = '.'; | |
236 | } | |
237 | ||
238 | for (cpos = patrol_tailpool[choices[i]]->content; *cpos;) { | |
239 | buf[a++] = *cpos++; | |
240 | } | |
241 | ||
242 | buf[a] = '\0'; | |
243 | free(choices); | |
244 | free(lengths); | |
245 | ||
246 | memset(ipaddress, 0, sizeof(struct irc_in_addr)); | |
247 | ((unsigned short *)(ipaddress->in6_16))[5] = 65535; | |
248 | ((unsigned short *)(ipaddress->in6_16))[6] = patrol_minmaxrand(0, 65535); | |
249 | ((unsigned short *)(ipaddress->in6_16))[7] = patrol_minmaxrand(0, 65535); | |
250 | } | |
251 | } | |
252 | ||
253 | void patrol_generatenick(char *buf, int maxsize) { | |
254 | int bits = patrol_minmaxrand(2, 3), loops = 0, wanttocopy, len = 0, i, d = 0, newmaxsize = maxsize - patrol_minmaxrand(0, 7); | |
255 | nick *np; | |
256 | ||
257 | if (newmaxsize > 2) | |
258 | maxsize = newmaxsize; | |
259 | ||
260 | do { | |
261 | np = patrol_selectuser(); | |
262 | ||
263 | if (np) { | |
264 | wanttocopy = patrol_minmaxrand(1, (strlen(np->nick) / 2) + 3); | |
265 | ||
266 | for (i = 0; ((i < wanttocopy) && (len < maxsize)); i++) | |
267 | buf[len++] = np->nick[i]; | |
268 | ||
269 | if (++d > bits) { | |
270 | buf[len] = '\0'; | |
271 | return; | |
272 | } | |
273 | } | |
274 | } while (++loops < 10); | |
275 | ||
276 | buf[0] = '\0'; | |
277 | } | |
278 | ||
279 | void patrol_generateident(char *buf, int maxsize) { | |
280 | nick *np = patrol_selectuser(); | |
281 | buf[0] = '\0'; | |
282 | ||
283 | if (np) | |
284 | strlcpy(buf, np->ident, maxsize + 1); | |
285 | } | |
286 | ||
287 | void patrol_generaterealname(char *buf, int maxsize) { | |
288 | nick *np = patrol_selectuser(); | |
289 | buf[0] = '\0'; | |
290 | ||
291 | if (np) | |
292 | strlcpy(buf, np->realname->name->content, maxsize + 1); | |
293 | } | |
294 | ||
295 | nick *patrol_generateclone(int extraumodes, UserMessageHandler handler) { | |
296 | int loops = 0, modes = UMODE_XOPER | UMODE_INV | extraumodes; | |
297 | char c_nick[NICKLEN + 1], c_ident[USERLEN + 1], c_host[HOSTLEN + 1], c_real[REALLEN + 1]; | |
298 | struct irc_in_addr ipaddress; | |
299 | ||
300 | /* PPA: unlikely to be infinite */ | |
301 | do { | |
302 | c_nick[0] = '\0'; | |
303 | ||
304 | if (!loops && patrol_hostmode) /* only have one go at this */ | |
305 | patrol_generatenick(c_nick, NICKLEN); | |
306 | ||
307 | if (!c_nick[0]) | |
308 | patrol_gennick(c_nick, patrol_minmaxrand(7, PATROL_MMIN(13, NICKLEN))); | |
309 | ||
310 | loops++; | |
311 | } while ((getnickbynick(c_nick) != NULL)); | |
312 | ||
313 | patrol_generateident(c_ident, USERLEN); | |
314 | ||
315 | if (!c_ident[0]) | |
316 | patrol_genident(c_ident, patrol_minmaxrand(4, PATROL_MMIN(8, USERLEN))); | |
317 | ||
318 | if (patrol_hostmode) { | |
319 | patrol_generatehost(c_host, HOSTLEN, &ipaddress); | |
320 | ||
321 | if (!c_host[0]) | |
322 | patrol_genhost(c_host, HOSTLEN, &ipaddress); | |
323 | } else { | |
324 | patrol_genhost(c_host, HOSTLEN, &ipaddress); | |
325 | } | |
326 | ||
327 | patrol_generaterealname(c_real, REALLEN); | |
328 | ||
329 | if (!c_real[0]) | |
330 | patrol_genreal(c_real, patrol_minmaxrand(15, PATROL_MMIN(50, REALLEN))); | |
331 | ||
332 | return registerlocaluserflagsip(c_nick, c_ident, c_host, c_real, NULL, 0, 0, modes, &ipaddress, handler); | |
333 | } | |
334 | ||
335 | void patrol_nickchange(nick *np) { | |
336 | char c_nick[NICKLEN + 1]; | |
337 | int loops = 0; | |
338 | ||
339 | /* PPA: unlikely to be infinite */ | |
340 | do { | |
341 | if ((loops++ < 10) && patrol_hostmode) { | |
342 | patrol_generatenick(c_nick, NICKLEN); | |
343 | } else { | |
344 | patrol_gennick(c_nick, patrol_minmaxrand(7, PATROL_MMIN(13, NICKLEN))); | |
345 | } | |
346 | } while (c_nick[0] && (getnickbynick(c_nick) != NULL)); | |
347 | ||
348 | renamelocaluser(np, c_nick); | |
349 | } | |
350 | ||
351 | int patrol_is_not_octet(char *begin, int length) { | |
352 | int i; | |
353 | ||
354 | if (length > 3) | |
355 | return 0; | |
356 | ||
357 | for (i = 0; i < length; i++) { | |
358 | if (!((*begin >= '0') && (*begin <= '9'))) | |
359 | return 0; | |
360 | ||
361 | begin++; | |
362 | } | |
363 | ||
364 | return 1; | |
365 | } | |
366 | ||
367 | int patrol_generatepool(void) { | |
368 | int i, k = 0, j = 0, loops = 0; | |
369 | char *p, *pp; | |
370 | nick *np; | |
371 | ||
372 | for (i = 0; i < NICKHASHSIZE; i++) | |
373 | for (np = nicktable[i]; np; np = np->next) | |
374 | j++; | |
375 | ||
376 | if (j < patrol_min_hosts) | |
377 | return 0; | |
378 | ||
379 | if (PATROL_HOST_MODE == PATROL_STEAL_HOST) | |
380 | return PATROL_MINPOOLSIZE; | |
381 | ||
382 | i = 0; | |
383 | ||
384 | do { | |
385 | for (j = patrol_minmaxrand(0, NICKHASHSIZE - 1); j < NICKHASHSIZE; j++) { | |
386 | if (nicktable[j]) { | |
387 | for (p = nicktable[j]->host->name->content, pp = p; *p;) { | |
388 | if (*++p == '.') { | |
389 | if (!patrol_is_not_octet(pp, p - pp)) { | |
390 | if (i < PATROL_POOLSIZE) { | |
391 | if (i < patrol_hostpoolsize) | |
392 | freesstring(patrol_hostpool[i]); | |
393 | ||
394 | patrol_hostpool[i] = getsstring(pp, p - pp); | |
395 | i++; | |
396 | } else { | |
397 | if (k >= PATROL_POOLSIZE) | |
398 | break; | |
399 | } | |
400 | } | |
401 | ||
402 | pp = ++p; | |
403 | } | |
404 | } | |
405 | ||
406 | if (!patrol_is_not_octet(pp, p - pp)) { | |
407 | if (k < PATROL_POOLSIZE) { | |
408 | if (k < patrol_tailpoolsize) | |
409 | freesstring(patrol_tailpool[k]); | |
410 | ||
411 | patrol_tailpool[k] = getsstring(pp, p - pp); | |
412 | k++; | |
413 | } else { | |
414 | if (i >= PATROL_POOLSIZE) | |
415 | break; | |
416 | } | |
417 | } | |
418 | } | |
419 | } | |
420 | ||
421 | loops++; | |
422 | } while ((loops < 5) && ((i < PATROL_POOLSIZE) || (k < PATROL_POOLSIZE))); | |
423 | ||
424 | patrol_hostpoolsize = i; | |
425 | patrol_tailpoolsize = k; | |
426 | return i; | |
427 | } | |
428 | ||
429 | int patrol_repool(void) { | |
430 | if (patrol_generatepool() < PATROL_MINPOOLSIZE) { | |
431 | patrol_hostmode = 0; | |
432 | return 0; | |
433 | } else { | |
434 | patrol_hostmode = 1; | |
435 | return 1; | |
436 | } | |
437 | } | |
438 | ||
439 | void patrol_sched_repool(void *arg) { | |
440 | int delta; | |
441 | ||
442 | if (patrol_repool()) | |
443 | delta = PATROL_POOL_REGENERATION; | |
444 | else | |
445 | delta = 10; | |
446 | ||
447 | scheduleoneshot(time(NULL) + delta, &patrol_sched_repool, NULL); | |
448 | } | |
449 | ||
450 | void _init(void) { | |
451 | char buf[32]; | |
452 | sstring *m; | |
453 | ||
454 | snprintf(buf, sizeof(buf), "%d", PATROL_MINIMUM_HOSTS_BEFORE_POOL); | |
455 | m = getcopyconfigitem("patrol", "minpoolhosts", buf, 32); | |
456 | patrol_min_hosts = atoi(m->content); | |
457 | freesstring(m); | |
458 | ||
459 | scheduleoneshot(time(NULL) + 5, &patrol_sched_repool, NULL); | |
460 | } | |
461 | ||
462 | void _fini(void) { | |
463 | int i; | |
464 | ||
465 | deleteallschedules(&patrol_sched_repool); | |
466 | ||
467 | for (i = 0; i < patrol_hostpoolsize; i++) | |
468 | freesstring(patrol_hostpool[i]); | |
469 | ||
470 | for (i = 0; i < patrol_tailpoolsize; i++) | |
471 | freesstring(patrol_tailpool[i]); | |
472 | } | |
473 |