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