]> jfr.im git - irc/quakenet/newserv.git/blob - chanserv/chanserv_protect.c
Ignore users encroaching on nicks is their user@host matches that used for the last...
[irc/quakenet/newserv.git] / chanserv / chanserv_protect.c
1 /*
2 * Nick protection system for the chanserv
3 */
4
5 #include "chanserv.h"
6 #include "../core/schedule.h"
7 #include "../localuser/localuser.h"
8
9
10 #define PROTECTTIME 60 /* How long you have to renick if you encroach.. */
11
12 void csp_handlenick(int hooknum, void *arg);
13 void csp_freenick(int hooknum, void *arg);
14 void csp_timerfunc (void *arg);
15 int csp_doclaimnick(void *source, int cargc, char **cargv);
16
17 void _init() {
18 registerhook(HOOK_NICK_NEWNICK, csp_handlenick);
19 registerhook(HOOK_NICK_RENAME, csp_handlenick);
20
21 registerhook(HOOK_NICK_NEWNICK, csp_freenick);
22 registerhook(HOOK_NICK_ACCOUNT, csp_freenick);
23
24 chanservaddcommand("claimnick", QCMD_HELPER, 0, csp_doclaimnick, "Reclaims your nickname if it has been stolen.","");
25 }
26
27 void _fini() {
28 reguser *rup;
29 int i;
30
31 deregisterhook(HOOK_NICK_NEWNICK, csp_handlenick);
32 deregisterhook(HOOK_NICK_RENAME, csp_handlenick);
33
34 deregisterhook(HOOK_NICK_NEWNICK, csp_freenick);
35 deregisterhook(HOOK_NICK_ACCOUNT, csp_freenick);
36
37 chanservremovecommand("claimnick", csp_doclaimnick);
38 deleteallschedules(csp_timerfunc);
39
40 /* Kill off all fakeusers too */
41 for (i=0;i<REGUSERHASHSIZE;i++)
42 for (rup=regusernicktable[i];rup;rup=rup->nextbyname)
43 if (rup->fakeuser) {
44 if (getnickbynick(rup->username) == rup->fakeuser) {
45 deregisterlocaluser(rup->fakeuser,NULL);
46 }
47 rup->fakeuser=NULL;
48 }
49 }
50
51 void csp_handlenick(int hooknum, void *arg) {
52 nick *np=arg;
53 reguser *rup;
54 char userhostbuf[USERLEN+HOSTLEN+2];
55
56 /* Check that it's a protected nick */
57 if (!(rup=findreguserbynick(np->nick)) || !UIsProtect(rup))
58 return;
59
60 /* If we already had a timer running, this means someone renamed off and back.
61 * Clear the old timer.
62 */
63 if (rup->checkshd) {
64 deleteschedule(rup->checkshd, csp_timerfunc, rup);
65 rup->checkshd=NULL;
66 }
67
68 /* If they're an oper, or the legal user of the nick, it's OK */
69 /* Also, don't warn them if they are a fakeuser */
70 if (getreguserfromnick(np)==rup) {
71 rup->stealcount=0;
72 return;
73 }
74
75 if (rup->lastuserhost) {
76 sprintf(userhostbuf,"%s@%s",np->ident,np->host->name->content);
77 if (!ircd_strcmp(userhostbuf, rup->lastuserhost->content))
78 return;
79 }
80
81 if (IsOper(np) || homeserver(np->numeric)==mylongnum)
82 return;
83
84 /* OK, at this stage we've established that:
85 * - This is a protected nick
86 * - The person using it isn't authed as the correct user
87 */
88
89 /* Send warning */
90 chanservstdmessage(np, QM_PROTECTEDNICK, rup->username);
91
92 /* Schedule checkup */
93 rup->checkshd=scheduleoneshot(time(NULL)+PROTECTTIME, csp_timerfunc, rup);
94 }
95
96 void csp_freenick(int hooknum, void *arg) {
97 nick *np=arg;
98 reguser *rup=getreguserfromnick(np);
99
100 if (!rup || !UIsProtect(rup))
101 return;
102
103 if (rup->checkshd) {
104 deleteschedule(rup->checkshd, csp_timerfunc, rup);
105 rup->checkshd=NULL;
106 }
107
108 rup->stealcount=0;
109 if (rup->fakeuser) {
110 /* Before killing, check the user is valid */
111 if (getnickbynick(rup->username) == rup->fakeuser) {
112 /* Free up the fakeuser */
113 deregisterlocaluser(rup->fakeuser, NULL);
114 rup->fakeuser=NULL;
115 chanservstdmessage(np, QM_NICKWASFAKED, rup->username);
116 }
117 }
118 }
119
120 void csp_timerfunc (void *arg) {
121 reguser *rup=arg;
122 nick *np;
123
124 rup->checkshd=NULL;
125
126 /* Check that we still have a user with this name and
127 * that they're not now opered or authed.. */
128 if (!(np=getnickbynick(rup->username)) || IsOper(np) || (getreguserfromnick(np)==rup))
129 return;
130
131 /* KILL! KILL! KILL! */
132 killuser(chanservnick, np, "Protected nick.");
133
134 rup->stealcount++;
135
136 /* If it's been stolen too much, create a fake user.. */
137 if (rup->stealcount >= 3) {
138 rup->fakeuser=registerlocaluser(rup->username, "reserved", "nick", "Protected nick.", NULL, UMODE_INV, NULL);
139 }
140 }
141
142 int csp_doclaimnick(void *source, int cargc, char **cargv) {
143 nick *sender=source;
144 reguser *rup=getreguserfromnick(sender);
145 nick *target;
146
147 if (!rup)
148 return CMD_ERROR;
149
150 if (!UIsProtect(rup)) {
151 chanservstdmessage(sender, QM_NOTPROTECTED,rup->username);
152 return CMD_ERROR;
153 }
154
155 if (!(target=getnickbynick(rup->username))) {
156 chanservstdmessage(sender, QM_UNKNOWNUSER, rup->username);
157 return CMD_ERROR;
158 }
159
160 if (getreguserfromnick(target)==rup) {
161 chanservstdmessage(sender, QM_SAMEAUTH, target->nick, rup->username);
162 return CMD_ERROR;
163 }
164
165 if (rup->fakeuser==target) {
166 deregisterlocaluser(rup->fakeuser, NULL);
167 rup->fakeuser=NULL;
168 } else {
169 if (!IsOper(target))
170 killuser(chanservnick, target, "Protected nick.");
171 }
172
173 chanservstdmessage(sender, QM_DONE);
174 return CMD_OK;
175 }