1 | /* |
1 | /* |
2 | * function.C: Miscellaneous functions. |
2 | * function.C: Miscellaneous functions. |
3 | * Rights to this code are documented in doc/pod/license.pod. |
3 | * Rights to this code are documented in doc/pod/license.pod. |
4 | * |
4 | * |
5 | * Copyright © 2005-2007 Atheme Project (http://www.atheme.org) |
5 | * Copyright © 2005-2007 Atheme Project (http://www.atheme.org) |
6 | */ |
6 | */ |
7 | |
7 | |
8 | static char const rcsid[] = "$Id: function.C,v 1.3 2007/07/21 13:23:21 pippijn Exp $"; |
8 | static char const rcsid[] = "$Id: function.C,v 1.4 2007/08/28 17:08:12 pippijn Exp $"; |
9 | |
9 | |
10 | #include "atheme.h" |
10 | #include "atheme.h" |
|
|
11 | #include <ermyth/crypto.h> |
11 | #include <account/mychan.h> |
12 | #include <account/mychan.h> |
12 | #include <account/chanacs.h> |
13 | #include <account/chanacs.h> |
13 | #include <account/myuser.h> |
14 | #include <account/myuser.h> |
|
|
15 | #include <common/random.h> |
14 | |
16 | |
15 | char ch[27] = "abcdefghijklmnopqrstuvwxyz"; |
17 | char ch[27] = "abcdefghijklmnopqrstuvwxyz"; |
16 | |
18 | |
17 | /* This function uses smalloc() to allocate memory. |
19 | /* This function uses allocates memory. |
18 | * You MUST free the result when you are done with it! |
20 | * You MUST free the result when you are done with it! |
19 | */ |
21 | */ |
20 | char * |
22 | char * |
21 | gen_pw (int sz) |
23 | gen_pw (int sz) |
22 | { |
24 | { |
23 | int i; |
25 | int i; |
24 | char *buf = static_cast<char *> (smalloc (sz + 1)); /* padding */ |
26 | char *buf = alloc<char> (sz + 1); /* padding */ |
25 | |
27 | |
26 | for (i = 0; i < sz; i++) |
28 | for (i = 0; i < sz; i++) |
27 | { |
29 | { |
28 | buf[i] = ch[arc4random () % 26]; |
30 | buf[i] = ch[gen_rand32 () % 26]; |
29 | } |
31 | } |
30 | |
32 | |
31 | buf[sz] = 0; |
33 | buf[sz] = 0; |
32 | |
34 | |
33 | return buf; |
35 | return buf; |
… | |
… | |
71 | |
73 | |
72 | while ((c = strchr (line, '\t'))) |
74 | while ((c = strchr (line, '\t'))) |
73 | *c = ' '; |
75 | *c = ' '; |
74 | } |
76 | } |
75 | |
77 | |
76 | /* |
|
|
77 | * This generates a hash value, based on chongo's hash algo, |
|
|
78 | * located at http://www.isthe.com/chongo/tech/comp/fnv/ |
|
|
79 | * |
|
|
80 | * The difference between FNV and Atheme's hash algorithm is |
|
|
81 | * that FNV uses a random key for toasting, we just use |
|
|
82 | * 16 instead. |
|
|
83 | */ |
|
|
84 | unsigned int |
|
|
85 | shash (const unsigned char *p) |
|
|
86 | { |
|
|
87 | unsigned int hval = HASHINIT; |
|
|
88 | |
|
|
89 | if (!p) |
|
|
90 | return (0); |
|
|
91 | for (; *p != '\0'; ++p) |
|
|
92 | { |
|
|
93 | hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24); |
|
|
94 | hval ^= (ToLower (*p) ^ 16); |
|
|
95 | } |
|
|
96 | |
|
|
97 | return ((hval >> HASHBITS) ^ (hval & ((1 << HASHBITS) - 1)) % HASHSIZE); |
|
|
98 | } |
|
|
99 | |
|
|
100 | /* replace all occurances of 'oldstr' with 'newstr' */ |
78 | /* replace all occurances of 'oldstr' with 'newstr' */ |
101 | char * |
79 | char * |
102 | replace (char *s, int size, const char *oldstr, const char *newstr) |
80 | replace (char *s, int size, char const * const oldstr, char const * const newstr) |
103 | { |
81 | { |
104 | char *ptr = s; |
82 | char *ptr = s; |
105 | int left = strlen (s); |
83 | int left = strlen (s); |
106 | int avail = size - (left + 1); |
84 | int avail = size - (left + 1); |
107 | int oldstrlen = strlen (oldstr); |
85 | int oldstrlen = strlen (oldstr); |
… | |
… | |
217 | unsigned long |
195 | unsigned long |
218 | makekey (void) |
196 | makekey (void) |
219 | { |
197 | { |
220 | unsigned long k; |
198 | unsigned long k; |
221 | |
199 | |
222 | k = arc4random () & 0x7FFFFFFF; |
200 | k = gen_rand32 () & 0x7FFFFFFF; |
223 | |
201 | |
224 | /* shorten or pad it to 9 digits */ |
202 | /* shorten or pad it to 9 digits */ |
225 | if (k > 1000000000) |
203 | if (k > 1000000000) |
226 | k = k - 1000000000; |
204 | k = k - 1000000000; |
227 | if (k < 100000000) |
205 | if (k < 100000000) |
… | |
… | |
267 | } |
245 | } |
268 | |
246 | |
269 | bool |
247 | bool |
270 | validhostmask (char *host) |
248 | validhostmask (char *host) |
271 | { |
249 | { |
|
|
250 | char *p, *q; |
|
|
251 | |
272 | if (strchr (host, ' ')) |
252 | if (strchr (host, ' ')) |
273 | return false; |
253 | return false; |
274 | |
254 | |
275 | /* make sure it has ! and @ */ |
255 | /* make sure it has ! and @ in that order and only once */ |
276 | if (!strchr (host, '!') || !strchr (host, '@')) |
256 | p = strchr (host, '!'); |
|
|
257 | q = strchr (host, '@'); |
|
|
258 | if (p == NULL || q == NULL || p > q || strchr (p + 1, '!') || strchr (q + 1, '@')) |
277 | return false; |
259 | return false; |
278 | |
260 | |
279 | /* XXX this NICKLEN is too long */ |
261 | /* XXX this NICKLEN is too long */ |
280 | if (strlen (host) > NICKLEN + USERLEN + HOSTLEN + 1) |
262 | if (strlen (host) > NICKLEN + USERLEN + HOSTLEN + 1) |
281 | return false; |
263 | return false; |
… | |
… | |
293 | * type is EMAIL_*, see include/tools.h |
275 | * type is EMAIL_*, see include/tools.h |
294 | * mu is the recipient user |
276 | * mu is the recipient user |
295 | * param depends on type, also see include/tools.h |
277 | * param depends on type, also see include/tools.h |
296 | */ |
278 | */ |
297 | int |
279 | int |
298 | sendemail (user_t *u, int type, myuser_t *mu, const char *param) |
280 | sendemail (user_t *u, int type, myuser_t *mu, char const * const param) |
299 | { |
281 | { |
300 | char *email, *date = NULL; |
282 | char *email, *date = NULL; |
301 | char cmdbuf[512], timebuf[256], to[128], from[128], subject[128]; |
283 | char cmdbuf[512], timebuf[256], to[128], from[128], subject[128]; |
302 | FILE *out; |
284 | FILE *out; |
303 | time_t t; |
285 | time_t t; |
… | |
… | |
458 | return rc; |
440 | return rc; |
459 | } |
441 | } |
460 | |
442 | |
461 | /* various access level checkers */ |
443 | /* various access level checkers */ |
462 | bool |
444 | bool |
463 | is_founder (mychan_t *mychan, myuser_t *myuser) |
445 | myuser_t::is_founder (mychan_t *mc) const |
464 | { |
446 | { |
465 | if (!myuser) |
447 | if (chanacs_find (mc, this, CA_FOUNDER)) |
466 | return false; |
|
|
467 | |
|
|
468 | if (mychan->founder == myuser) |
|
|
469 | return true; |
448 | return true; |
470 | |
449 | |
471 | return false; |
450 | return false; |
472 | } |
451 | } |
473 | |
452 | |
474 | bool |
453 | bool |
475 | should_owner (mychan_t *mychan, myuser_t *myuser) |
454 | myuser_t::should_owner (mychan_t *mc) const |
476 | { |
455 | { |
477 | if (!myuser) |
|
|
478 | return false; |
|
|
479 | |
|
|
480 | if (MC_NOOP & mychan->flags) |
456 | if (MC_NOOP & mc->flags) |
481 | return false; |
457 | return false; |
482 | |
458 | |
483 | if (MU_NOOP & myuser->flags) |
459 | if (MU_NOOP & flags) |
484 | return false; |
460 | return false; |
485 | |
461 | |
486 | if (is_founder (mychan, myuser)) |
462 | if (is_founder (mc)) |
487 | return true; |
463 | return true; |
488 | |
464 | |
489 | return false; |
465 | return false; |
490 | } |
466 | } |
491 | |
467 | |
492 | bool |
468 | bool |
493 | should_protect (mychan_t *mychan, myuser_t *myuser) |
469 | myuser_t::should_protect (mychan_t *mc) const |
494 | { |
470 | { |
495 | if (!myuser) |
|
|
496 | return false; |
|
|
497 | |
|
|
498 | if (MC_NOOP & mychan->flags) |
471 | if (MC_NOOP & mc->flags) |
499 | return false; |
472 | return false; |
500 | |
473 | |
501 | if (MU_NOOP & myuser->flags) |
474 | if (MU_NOOP & flags) |
502 | return false; |
475 | return false; |
503 | |
476 | |
504 | if (chanacs_find (mychan, myuser, CA_SET)) |
477 | if (chanacs_find (mc, this, CA_SET)) |
505 | return true; |
478 | return true; |
506 | |
479 | |
507 | return false; |
480 | return false; |
508 | } |
481 | } |
509 | |
482 | |
… | |
… | |
524 | |
497 | |
525 | return false; |
498 | return false; |
526 | } |
499 | } |
527 | |
500 | |
528 | void |
501 | void |
529 | set_password (myuser_t *mu, char *newpassword) |
502 | myuser_t::set_password (char const * const newpassword) |
530 | { |
503 | { |
531 | if (mu == NULL || newpassword == NULL) |
504 | if (newpassword == NULL) |
532 | return; |
505 | return; |
533 | |
506 | |
534 | /* if we can, try to crypt it */ |
507 | /* if we can, try to crypt it */ |
535 | if (crypto_module_loaded == true) |
508 | if (crypto::handler::loaded) |
536 | { |
509 | { |
537 | mu->flags |= MU_CRYPTPASS; |
510 | flags |= MU_CRYPTPASS; |
538 | strlcpy (mu->pass, crypt_string (newpassword, gen_salt ()), NICKLEN); |
511 | strlcpy (pass, crypter->crypt (newpassword, crypto::gen_salt ()), NICKLEN); |
539 | } |
512 | } |
540 | else |
513 | else |
541 | { |
514 | { |
542 | mu->flags &= ~MU_CRYPTPASS; /* just in case */ |
515 | flags &= ~MU_CRYPTPASS; /* just in case */ |
543 | strlcpy (mu->pass, newpassword, NICKLEN); |
516 | strlcpy (pass, newpassword, NICKLEN); |
544 | } |
517 | } |
545 | } |
518 | } |
546 | |
519 | |
547 | bool |
520 | bool |
548 | verify_password (myuser_t *mu, char *password) |
521 | myuser_t::verify_password (char const * const password) const |
549 | { |
522 | { |
550 | if (mu == NULL || password == NULL) |
523 | if (password == NULL) |
551 | return false; |
524 | return false; |
552 | |
525 | |
553 | if (mu->flags & MU_CRYPTPASS) |
526 | if (flags & MU_CRYPTPASS) |
554 | if (crypto_module_loaded == true) |
527 | if (crypto::handler::loaded) |
555 | return crypt_verify_password (password, mu->pass); |
528 | return crypto::verify_password (password, pass); |
556 | else |
529 | else |
557 | { /* not good! */ |
530 | { /* not good! */ |
558 | slog (LG_ERROR, "check_password(): can't check crypted password -- no crypto module!"); |
531 | slog (LG_ERROR, "check_password(): can't check crypted password -- no crypto module!"); |
559 | return false; |
532 | return false; |
560 | } |
533 | } |
561 | else |
534 | else |
562 | return (strcmp (mu->pass, password) == 0); |
535 | return (strcmp (pass, password) == 0); |
563 | } |
536 | } |
564 | |
537 | |
565 | char * |
538 | char const * |
566 | sbytes (float x) |
539 | sbytes (float x) |
567 | { |
540 | { |
568 | if (x > 1073741824.0) |
541 | if (x > 1073741824.0) |
569 | return "GB"; |
542 | return "GB"; |
570 | |
543 | |
… | |
… | |
589 | if (x > 1024.0) |
562 | if (x > 1024.0) |
590 | return (x / 1024.0); |
563 | return (x / 1024.0); |
591 | |
564 | |
592 | return x; |
565 | return x; |
593 | } |
566 | } |
594 | |
|
|
595 | /* vim:cinoptions=>s,e0,n0,f0,{0,}0,^0,=s,ps,t0,c3,+s,(2s,us,)20,*30,gs,hs |
|
|
596 | * vim:ts=8 |
|
|
597 | * vim:sw=8 |
|
|
598 | * vim:noexpandtab |
|
|
599 | */ |
|
|