]> jfr.im git - irc/quakenet/newserv.git/blob - trusts/trusts_policy.c
Implement policy enforcement.
[irc/quakenet/newserv.git] / trusts / trusts_policy.c
1 #include "../core/hooks.h"
2 #include "../core/config.h"
3 #include "../control/control.h"
4 #include "../lib/irc_string.h"
5 #include "../irc/irc.h"
6 #include "trusts.h"
7
8 static int countext, enforcepolicy;
9
10 static void policycheck(int hooknum, void *arg) {
11 void **args = arg;
12 nick *np = args[0];
13 long moving = (long)args[1];
14 trusthost *th = gettrusthost(np);
15 trustgroup *tg;
16 patricia_node_t *head, *node;
17 int nodecount = 0;
18
19 if(moving)
20 return;
21
22 if(!th)
23 return;
24
25 tg = th->group;
26
27 head = refnode(iptree, &np->p_ipaddr, th->nodebits);
28 PATRICIA_WALK(head, node)
29 {
30 nodecount += node->usercount;
31 }
32 PATRICIA_WALK_END;
33 derefnode(iptree, head);
34
35 if(th->maxpernode && nodecount > th->maxpernode) {
36 controlwall(NO_OPER, NL_TRUSTS, "Hard connection limit exceeded on IP: %s (group: %s) %d connected, %d max.", IPtostr(np->p_ipaddr), tg->name->content, nodecount, th->maxpernode);
37
38 if(enforcepolicy)
39 irc_send("%s GL * +*@%s %d %jd :Too many connections from your host.", mynumeric->content, trusts_cidr2str(&np->p_ipaddr, th->nodebits), POLICY_GLINE_DURATION, (intmax_t)getnettime());
40
41 return;
42 }
43
44 /*
45 * the purpose of this logic is to avoid spam like this:
46 * WARNING: tgX exceeded limit: 11 connected vs 10 max
47 * (goes back down to 10)
48 * WARNING: tgX exceeded limit: 11 connected vs 10 max
49 */
50
51 if(hooknum == HOOK_TRUSTS_NEWNICK) {
52 if(tg->trustedfor && tg->count > tg->trustedfor) {
53 /*
54 if(tg->count > (long)tg->exts[countext]) {
55
56 tg->exts[countext] = (void *)(long)tg->count;
57 */
58 controlwall(NO_OPER, NL_TRUSTS, "Hard connection limit exceeded: '%s', %d connected, %d max.", tg->name->content, tg->count, tg->trustedfor);
59 }
60 /*
61 }
62 */
63 if((tg->mode == 1) && (np->ident[0] == '~')) {
64 controlwall(NO_OPER, NL_TRUSTS, "Ident required: '%s' %s!%s@%s.", tg->name->content, np->nick, np->ident, np->host->name->content);
65
66 if (enforcepolicy)
67 irc_send("%s GL * +%s@%s %d %jd :IDENT required from your host.", mynumeric->content, np->ident, trusts_cidr2str(&np->p_ipaddr, th->nodebits), POLICY_GLINE_DURATION, (intmax_t)getnettime());
68 }
69
70 if(tg->maxperident > 0) {
71 int identcount = 0;
72 trusthost *th2;
73 nick *tnp;
74
75 for(th2=tg->hosts;th2;th2=th2->next) {
76 for(tnp=th2->users;tnp;tnp=nextbytrust(tnp)) {
77 if(!ircd_strcmp(tnp->ident, np->ident))
78 identcount++;
79 }
80 }
81
82 if(identcount > tg->maxperident) {
83 controlwall(NO_OPER, NL_TRUSTS, "Hard ident limit exceeded: '%s' %s!%s@%s, %d connected, %d max.", tg->name->content, np->nick, np->ident, np->host->name->content, identcount, tg->maxperident);
84
85 if (enforcepolicy)
86 irc_send("%s GL * +%s@%s %d %jd :Too many connections from your user.", mynumeric->content, np->ident, trusts_cidr2str(&np->p_ipaddr, th->nodebits), POLICY_GLINE_DURATION, (intmax_t)getnettime());
87 }
88 }
89 } else {
90 if(tg->count < tg->maxusage)
91 tg->exts[countext] = (void *)(long)tg->count;
92 }
93 }
94
95 void _init(void) {
96 countext = registertgext("count");
97 if(countext == -1)
98 return;
99
100 sstring *m;
101
102 m = getconfigitem("trusts_policy", "enforcepolicy");
103 if(m)
104 enforcepolicy = atoi(m->content);
105
106 registerhook(HOOK_TRUSTS_NEWNICK, policycheck);
107 registerhook(HOOK_TRUSTS_LOSTNICK, policycheck);
108 }
109
110 void _fini(void) {
111 if(countext == -1)
112 return;
113
114 releasetgext(countext);
115
116 deregisterhook(HOOK_TRUSTS_NEWNICK, policycheck);
117 deregisterhook(HOOK_TRUSTS_LOSTNICK, policycheck);
118 }