]> jfr.im git - solanum.git/blame - extensions/sasl_usercloak.c
Revert "recheck users after applying SASL account cloaks"
[solanum.git] / extensions / sasl_usercloak.c
CommitLineData
721410d5
SB
1#include "stdinc.h"
2#include "modules.h"
3#include "hook.h"
4#include "client.h"
5#include "ircd.h"
6#include "send.h"
7#include "hash.h"
8#include "s_conf.h"
9#include "s_user.h"
10#include "s_serv.h"
11#include "numeric.h"
12
13#include <stdint.h>
14
15static void check_new_user(void *data);
16mapi_hfn_list_av1 sasl_usercloak_hfnlist[] = {
17 { "new_local_user", (hookfn) check_new_user },
18 { NULL, NULL }
19};
20
21DECLARE_MODULE_AV1(sasl_usercloak, NULL, NULL, NULL, NULL,
22 sasl_usercloak_hfnlist, "$Revision: 3526 $");
23
24unsigned int fnv_hash_string(char *str)
25{
26 unsigned int hash = 0x811c9dc5; // Magic value for 32-bit fnv1 hash initialisation.
27 unsigned char *p = (unsigned char *)str;
28 while (*p)
29 {
30 hash += (hash<<1) + (hash<<4) + (hash<<7) + (hash<<8) + (hash<<24);
31 hash ^= *p++;
32 }
33 return hash;
34}
35
36static void
37check_new_user(void *vdata)
38{
39 struct Client *source_p = (void *)vdata;
40
41 if (!IsIPSpoof(source_p))
42 return;
43
44 if (EmptyString(source_p->user->suser))
45 return;
46
dae6f5db 47 char *accountpart = strstr(source_p->orighost, "account");
721410d5
SB
48 if (!accountpart)
49 return;
50
51 char buf[HOSTLEN];
271ddd99 52 memset(buf, 0, sizeof(buf));
721410d5
SB
53 char *dst = buf;
54
dae6f5db
SB
55 strncpy(buf, source_p->orighost, accountpart - source_p->orighost);
56 dst += accountpart - source_p->orighost;
721410d5
SB
57
58 int needhash = 0;
59
60 for (char *src = source_p->user->suser; *src ; src++ )
61 {
62 if (dst > buf + sizeof(buf))
63 {
64 /* Doesn't fit. Warn opers and bail. */
65 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
66 "Couldn't fit account name part %s in hostname for %s!%s@%s",
dae6f5db 67 source_p->user->suser, source_p->name, source_p->username, source_p->orighost);
721410d5
SB
68 return;
69 }
70
71 char c = ToLower(*src);
72
73 if (IsHostChar(c))
74 *dst++ = c;
75 else
76 needhash = 1;
77 }
78
79 if (needhash)
80 {
81 if (dst > buf + sizeof(buf) - 12) /* '/x-' plus eight digit hash plus null terminator */
82 {
83 /* Doesn't fit. Warn opers and bail. */
84 sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
85 "Couldn't fit account name part %s in hostname for %s!%s@%s",
dae6f5db 86 source_p->user->suser, source_p->name, source_p->username, source_p->orighost);
721410d5
SB
87 return;
88 }
89
90 *dst++ = '/';
91 *dst++ = 'x';
92 *dst++ = '-';
93
94 unsigned int hashval = fnv_hash_string(source_p->user->suser);
95 hashval %= 100000000; // eight digits only please.
96 snprintf(dst, 9, "%08ud", hashval);
97 }
98
99 /* just in case */
100 buf[HOSTLEN-1] = '\0';
101
dae6f5db
SB
102 /* If hostname has been changed already (probably by services cloak on SASL login), then
103 * leave it intact. If not, change it. In either case, update the original hostname.
104 */
105 if (0 == irccmp(source_p->host, source_p->orighost))
106 change_nick_user_host(source_p, source_p->name, source_p->username, buf, 0, "Changing host");
107 strncpy(source_p->orighost, buf, HOSTLEN);
721410d5 108}