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