1 |
michael |
812 |
/* |
2 |
|
|
* ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). |
3 |
|
|
* m_spoof.c: Supports dynamic auth{} creation/deletion. |
4 |
|
|
* |
5 |
|
|
* Copyright (C) 2002 by the past and present ircd coders, and others. |
6 |
|
|
* |
7 |
|
|
* This program is free software; you can redistribute it and/or modify |
8 |
|
|
* it under the terms of the GNU General Public License as published by |
9 |
|
|
* the Free Software Foundation; either version 2 of the License, or |
10 |
|
|
* (at your option) any later version. |
11 |
|
|
* |
12 |
|
|
* This program is distributed in the hope that it will be useful, |
13 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 |
|
|
* GNU General Public License for more details. |
16 |
|
|
* |
17 |
|
|
* You should have received a copy of the GNU General Public License |
18 |
|
|
* along with this program; if not, write to the Free Software |
19 |
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
20 |
|
|
* USA |
21 |
|
|
* |
22 |
|
|
* $Id: m_spoof.c 801 2006-08-30 16:54:25Z adx $ |
23 |
|
|
*/ |
24 |
|
|
|
25 |
|
|
/* MODULE CONFIGURATION FOLLOWS -- please read!! */ |
26 |
|
|
|
27 |
|
|
/* |
28 |
|
|
* change to #define if you want to propagate received SPOOF/DELSPOOF messages |
29 |
|
|
* to other servers. This allows you create subnets inside which spoofs are |
30 |
|
|
* propagated. By manipulating PROPAGATE_SPOOF and RECEIVE_SPOOF, you can |
31 |
|
|
* prepare boundary hubs of such subnets. |
32 |
|
|
* |
33 |
|
|
* I realize a shared{} could be better, but I don't want to touch core code. |
34 |
|
|
* |
35 |
|
|
* If you decide to enable this, remember to load m_spoof on all servers |
36 |
|
|
* I am connected to, or you'll get plenty of "Unknown command" errors... |
37 |
|
|
*/ |
38 |
|
|
#define PROPAGATE_SPOOF |
39 |
|
|
|
40 |
|
|
/* |
41 |
|
|
* this server is allowed to receive spoofs/delspoofs from other servers. |
42 |
|
|
* Use in conjunction with PROPAGATE_SPOOF (on target servers). |
43 |
|
|
*/ |
44 |
|
|
#define RECEIVE_SPOOF |
45 |
|
|
|
46 |
|
|
/* where to put dynamic auth's -- this must be included from ircd.conf! |
47 |
|
|
* Ideally put .include "spoof.conf" before all other auths. |
48 |
|
|
* #undef if you want only a propagating hub server, not storing any data */ |
49 |
|
|
#define SPOOF_FILE "etc/spoof.conf" |
50 |
|
|
|
51 |
|
|
/* disable if you don't want opers notices/logs */ |
52 |
|
|
#define LOG_SPOOF |
53 |
|
|
|
54 |
|
|
|
55 |
|
|
/* END OF MODULE CONFIGURATION */ |
56 |
|
|
|
57 |
|
|
/* Usage: SPOOF <umask@hmask> <free.form.spoof|-> [flags|- [password]] |
58 |
|
|
* -- Appends an auth{} block. Flags consist of characters: |
59 |
|
|
* t (no_tilde), i (need_ident), k (kline_exempt), |
60 |
|
|
* g (gline_exempt), l (exceed_limit), o (class = "opers"), |
61 |
|
|
* f (can_flood), p (need_password), everything other is ignored. |
62 |
|
|
* DELSPOOF <umask@hmask> |
63 |
|
|
* -- Removes an auth{} block of exact umask@hmask, if found |
64 |
|
|
* |
65 |
|
|
* These commands are restricted to admins, so make sure your oper{} block |
66 |
|
|
* has admin = yes or so. |
67 |
|
|
*/ |
68 |
|
|
|
69 |
|
|
#if !defined(PROPAGATE_SPOOF) && !defined(SPOOF_FILE) |
70 |
|
|
#error You disabled both SPOOF_FILE and PROPAGATE_SPOOF, what do you expect me to do? |
71 |
|
|
#endif |
72 |
|
|
|
73 |
|
|
/* List of ircd includes from ../include/ */ |
74 |
|
|
#include "stdinc.h" |
75 |
|
|
#include "conf/conf.h" |
76 |
|
|
#include "handlers.h" |
77 |
|
|
#include "client.h" |
78 |
|
|
#include "common.h" /* FALSE bleah */ |
79 |
|
|
#include "hash.h" |
80 |
|
|
#include "ircd.h" |
81 |
|
|
#include "numeric.h" |
82 |
|
|
#include "server.h" |
83 |
|
|
#include "send.h" |
84 |
|
|
#include "msg.h" |
85 |
|
|
#include "parse.h" |
86 |
|
|
|
87 |
|
|
static void mo_spoof(struct Client *, struct Client *, int, char *[]); |
88 |
|
|
static void mo_delspoof(struct Client *, struct Client *, int, char *[]); |
89 |
|
|
|
90 |
|
|
struct Message spoof_msgtab = { |
91 |
|
|
"SPOOF", 0, 0, 3, 0, MFLG_SLOW, 0, |
92 |
|
|
#ifdef RECEIVE_SPOOF |
93 |
|
|
{m_unregistered, m_not_oper, mo_spoof, m_ignore, mo_spoof, m_ignore} |
94 |
|
|
#else |
95 |
|
|
{m_unregistered, m_not_oper, m_ignore, m_ignore, mo_spoof, m_ignore} |
96 |
|
|
#endif |
97 |
|
|
}; |
98 |
|
|
|
99 |
|
|
struct Message delspoof_msgtab = { |
100 |
|
|
"DELSPOOF", 0, 0, 1, 0, MFLG_SLOW, 0, |
101 |
|
|
#ifdef RECEIVE_SPOOF |
102 |
|
|
{m_unregistered, m_not_oper, mo_delspoof, m_ignore, mo_delspoof, m_ignore} |
103 |
|
|
#else |
104 |
|
|
{m_unregistered, m_not_oper, m_ignore, m_ignore, mo_delspoof, m_ignore} |
105 |
|
|
#endif |
106 |
|
|
}; |
107 |
|
|
|
108 |
|
|
INIT_MODULE(m_spoof, "$Revision: 801 $") |
109 |
|
|
{ |
110 |
|
|
mod_add_cmd(&spoof_msgtab); |
111 |
|
|
mod_add_cmd(&delspoof_msgtab); |
112 |
|
|
} |
113 |
|
|
|
114 |
|
|
CLEANUP_MODULE |
115 |
|
|
{ |
116 |
|
|
mod_del_cmd(&delspoof_msgtab); |
117 |
|
|
mod_del_cmd(&spoof_msgtab); |
118 |
|
|
} |
119 |
|
|
|
120 |
|
|
#ifdef SPOOF_FILE |
121 |
|
|
static void |
122 |
|
|
try_flag(FBFILE *f, int *flags, int flag, const char *string) |
123 |
|
|
{ |
124 |
|
|
if ((*flags & flag)) |
125 |
|
|
{ |
126 |
|
|
fbputs(string, f, strlen(string)); |
127 |
|
|
|
128 |
|
|
*flags &= ~flag; |
129 |
|
|
fbputs(*flags ? ", " : ";\n", f, 2); |
130 |
|
|
} |
131 |
|
|
} |
132 |
|
|
#endif |
133 |
|
|
|
134 |
|
|
static void |
135 |
|
|
mo_spoof(struct Client *client_p, struct Client *source_p, |
136 |
|
|
int parc, char *parv[]) |
137 |
|
|
{ |
138 |
|
|
char *host, *spoof, *password; |
139 |
|
|
const char *tmp = NULL; |
140 |
|
|
const char *user = NULL; |
141 |
|
|
const char *flags = NULL; |
142 |
|
|
int i = 0; |
143 |
|
|
#ifdef SPOOF_FILE |
144 |
|
|
int class_opers; |
145 |
|
|
FBFILE *f; |
146 |
|
|
char buffer[1024]; |
147 |
|
|
#endif |
148 |
|
|
|
149 |
|
|
if (MyConnect(source_p) && !IsOperAdmin(source_p)) |
150 |
|
|
{ |
151 |
|
|
sendto_one(source_p, form_str(ERR_NOPRIVS), |
152 |
|
|
me.name, source_p->name, "SPOOF"); |
153 |
|
|
return; |
154 |
|
|
} |
155 |
|
|
|
156 |
|
|
/* check the user@host mask */ |
157 |
|
|
if (strchr(parv[1], '!') != NULL) |
158 |
|
|
{ |
159 |
|
|
syntax: |
160 |
|
|
if (MyConnect(source_p)) |
161 |
|
|
sendto_one(source_p, ":%s NOTICE %s :Syntax: SPOOF <umask@hmask> " |
162 |
|
|
"<spoof/-> [flags/- [password]]", me.name, source_p->name); |
163 |
|
|
return; |
164 |
|
|
} |
165 |
|
|
|
166 |
|
|
(void) collapse(parv[1]); |
167 |
|
|
|
168 |
|
|
for (tmp = parv[1]; *tmp; tmp++) |
169 |
|
|
if (!IsKWildChar(*tmp)) |
170 |
|
|
if (++i >= General.min_nonwildcard) |
171 |
|
|
break; |
172 |
|
|
if (i < General.min_nonwildcard) |
173 |
|
|
{ |
174 |
|
|
if (MyConnect(source_p)) |
175 |
|
|
sendto_one(source_p, ":%s NOTICE %s :Not enough non-wildcard characters " |
176 |
|
|
"in user@host mask", |
177 |
|
|
me.name, source_p->name); |
178 |
|
|
return; |
179 |
|
|
} |
180 |
|
|
|
181 |
|
|
host = strchr(parv[1], '@'); |
182 |
|
|
if (host) |
183 |
|
|
{ |
184 |
|
|
user = parv[1]; |
185 |
|
|
*host = '\0'; |
186 |
|
|
host++; |
187 |
|
|
} |
188 |
|
|
else |
189 |
|
|
{ |
190 |
|
|
user = "*"; |
191 |
|
|
host = parv[1]; |
192 |
|
|
} |
193 |
|
|
|
194 |
|
|
/* check the spoof field */ |
195 |
|
|
spoof = parv[2]; |
196 |
|
|
if (spoof == NULL || !*spoof) |
197 |
|
|
goto syntax; |
198 |
|
|
|
199 |
|
|
if (spoof[0] != '-' || spoof[1] != '\0') |
200 |
|
|
{ |
201 |
|
|
for (tmp = spoof; *tmp; tmp++) |
202 |
|
|
if (!IsHostChar(*tmp)) { |
203 |
|
|
if (MyConnect(source_p)) |
204 |
|
|
sendto_one(source_p, ":%s NOTICE %s :The spoof [%s] is invalid", |
205 |
|
|
me.name, source_p->name, spoof); |
206 |
|
|
return; |
207 |
|
|
} |
208 |
|
|
if (strlen(spoof) >= HOSTLEN) { |
209 |
|
|
if (MyConnect(source_p)) |
210 |
|
|
sendto_one(source_p, ":%s NOTICE %s :Spoofs must be less than %d.." |
211 |
|
|
"ignoring it", me.name, source_p->name, HOSTLEN); |
212 |
|
|
return; |
213 |
|
|
} |
214 |
|
|
} |
215 |
|
|
|
216 |
|
|
flags = (parc > 3) ? parv[3] : "-"; |
217 |
|
|
password = (parc > 4 && parv[4][0]) ? parv[4] : NULL; |
218 |
|
|
|
219 |
|
|
#ifdef PROPAGATE_SPOOF |
220 |
|
|
sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, |
221 |
|
|
":%s SPOOF %s@%s %s %s :%s", |
222 |
|
|
source_p->name, user, host, spoof, flags, password ? password : ""); |
223 |
|
|
#endif |
224 |
|
|
|
225 |
|
|
#ifdef SPOOF_FILE |
226 |
|
|
/* Walk through auth {} items and check if we have another auth block |
227 |
|
|
* for this hostname */ |
228 |
|
|
if (find_exact_access_conf(acb_type_auth, user, host)) |
229 |
|
|
{ |
230 |
|
|
// auth entry already exists |
231 |
|
|
if (MyConnect(source_p)) |
232 |
|
|
sendto_one(source_p, |
233 |
|
|
":%s NOTICE %s :auth for %s@%s already exists, you need " |
234 |
|
|
"to use /DELSPOOF first", me.name, source_p->name, user, host); |
235 |
|
|
#ifdef LOG_SPOOF |
236 |
|
|
sendto_realops_flags(UMODE_ALL, L_ALL, |
237 |
|
|
"%s attemped to re-add auth for %s@%s " |
238 |
|
|
"[spoof: %s, flags: %s]", source_p->name, user, host, |
239 |
|
|
spoof, flags); |
240 |
|
|
#endif |
241 |
|
|
return; |
242 |
|
|
} |
243 |
|
|
|
244 |
|
|
// Add the spoof to the the spoof file |
245 |
|
|
if ((f = fbopen(SPOOF_FILE, "a")) == NULL) |
246 |
|
|
{ |
247 |
|
|
sendto_realops_flags(UMODE_ALL, L_ALL, |
248 |
|
|
"Could not open %s file, auth for %s@%s " |
249 |
|
|
"[spoof: %s, flags: %s, requested by %s] not added", |
250 |
|
|
SPOOF_FILE, user, host, spoof, flags, source_p->name); |
251 |
|
|
return; |
252 |
|
|
} |
253 |
|
|
|
254 |
|
|
/* write the auth {} block */ |
255 |
|
|
fbputs("auth {\n", f, 7); |
256 |
|
|
i = ircsprintf(buffer, "\tuser = \"%s@%s\";\n", user, host); |
257 |
|
|
fbputs(buffer, f, i); |
258 |
|
|
if (spoof[0] != '-' || spoof[1] != '\0') |
259 |
|
|
{ |
260 |
|
|
i = ircsprintf(buffer, "\tspoof = \"%s\";\n", spoof); |
261 |
|
|
fbputs(buffer, f, i); |
262 |
|
|
} |
263 |
|
|
if (password) |
264 |
|
|
{ |
265 |
|
|
i = ircsprintf(buffer, "\tpassword = \"%s\";\n", password); |
266 |
|
|
fbputs(buffer, f, i); |
267 |
|
|
} |
268 |
|
|
|
269 |
|
|
/* process given flags */ |
270 |
|
|
i = class_opers = 0; |
271 |
|
|
for (tmp = flags; *tmp; ++tmp) |
272 |
|
|
switch (*tmp) |
273 |
|
|
{ |
274 |
|
|
case 't': i |= AUTH_FLAG_NO_TILDE; /* no_tilde = yes; */ |
275 |
|
|
break; |
276 |
|
|
case 'i': i |= AUTH_FLAG_NEED_IDENT; /* need_ident = yes; */ |
277 |
|
|
break; |
278 |
|
|
case 'k': i |= AUTH_FLAG_KLINE_EXEMPT; /* kline_exempt = yes; */ |
279 |
|
|
break; |
280 |
|
|
case 'g': i |= AUTH_FLAG_GLINE_EXEMPT; /* gline_exempt = yes; */ |
281 |
|
|
break; |
282 |
|
|
case 'l': i |= AUTH_FLAG_EXCEED_LIMIT; /* exceed_limit = yes; */ |
283 |
|
|
break; |
284 |
|
|
case 'o': class_opers = 1; /* class = "opers"; */ |
285 |
|
|
break; |
286 |
|
|
case 'f': i |= AUTH_FLAG_CAN_FLOOD; /* can_flood = yes; */ |
287 |
|
|
break; |
288 |
|
|
case 'p': i|= AUTH_FLAG_NEED_PASSWORD; /* need_password = yes; */ |
289 |
|
|
} |
290 |
|
|
|
291 |
|
|
if (i) |
292 |
|
|
{ |
293 |
|
|
fbputs("\tflags = ", f, 9); |
294 |
|
|
try_flag(f, &i, AUTH_FLAG_NO_TILDE, "no_tilde"); |
295 |
|
|
try_flag(f, &i, AUTH_FLAG_NEED_IDENT, "need_ident"); |
296 |
|
|
try_flag(f, &i, AUTH_FLAG_KLINE_EXEMPT, "kline_exempt"); |
297 |
|
|
try_flag(f, &i, AUTH_FLAG_GLINE_EXEMPT, "gline_exempt"); |
298 |
|
|
try_flag(f, &i, AUTH_FLAG_EXCEED_LIMIT, "exceed_limit"); |
299 |
|
|
try_flag(f, &i, AUTH_FLAG_CAN_FLOOD, "can_flood"); |
300 |
|
|
try_flag(f, &i, AUTH_FLAG_NEED_PASSWORD, "need_password"); |
301 |
|
|
} |
302 |
|
|
|
303 |
|
|
if (class_opers) |
304 |
|
|
fbputs("\tclass = \"opers\";\n", f, 18); |
305 |
|
|
else |
306 |
|
|
fbputs("\tclass = \"users\";\n", f, 18); |
307 |
|
|
|
308 |
|
|
fbputs("};\n\n", f, 4); |
309 |
|
|
fbclose(f); |
310 |
|
|
|
311 |
|
|
read_conf_files(NO); |
312 |
|
|
#endif |
313 |
|
|
|
314 |
|
|
#ifdef LOG_SPOOF |
315 |
|
|
sendto_realops_flags(UMODE_ALL, L_ALL, |
316 |
|
|
"%s added auth for %s@%s [spoof: %s, flags: %s]", |
317 |
|
|
source_p->name, user, host, spoof, flags); |
318 |
|
|
ilog(L_TRACE, "%s added auth for %s@%s [spoof: %s, flags: %s]", |
319 |
|
|
source_p->name, user, host, spoof, flags); |
320 |
|
|
#endif |
321 |
|
|
} |
322 |
|
|
|
323 |
|
|
/* Now, our job is a bit harder. I will scan through the SPOOF_FILE |
324 |
|
|
* and read all auths{} (assuming they are written in our line formatting..), |
325 |
|
|
* then rewrite them skipping the one to delete. --adx */ |
326 |
|
|
static void |
327 |
|
|
mo_delspoof(struct Client *client_p, struct Client *source_p, |
328 |
|
|
int parc, char *parv[]) |
329 |
|
|
{ |
330 |
|
|
#ifdef SPOOF_FILE |
331 |
|
|
FBFILE *f, *fout; |
332 |
|
|
int ignore_it = 1, spoof_found = 0; |
333 |
|
|
char buffer[1024], *tmp; |
334 |
|
|
#endif |
335 |
|
|
const char *user = NULL; |
336 |
|
|
char *host = NULL; |
337 |
|
|
|
338 |
|
|
if (MyConnect(source_p) && !IsOperAdmin(source_p)) |
339 |
|
|
{ |
340 |
|
|
sendto_one(source_p, form_str(ERR_NOPRIVS), me.name, parv[0], "DELSPOOF"); |
341 |
|
|
return; |
342 |
|
|
} |
343 |
|
|
|
344 |
|
|
if (parv[1] == NULL || !*parv[1]) |
345 |
|
|
{ |
346 |
|
|
if (MyConnect(source_p)) |
347 |
|
|
sendto_one(source_p, ":%s NOTICE %s :Syntax: /DELSPOOF <user@host>", |
348 |
|
|
me.name, source_p->name); |
349 |
|
|
return; |
350 |
|
|
} |
351 |
|
|
|
352 |
|
|
/* check user@host mask */ |
353 |
|
|
(void) collapse(parv[1]); |
354 |
|
|
|
355 |
|
|
host = strchr(parv[1], '@'); |
356 |
|
|
if (host != NULL) |
357 |
|
|
{ |
358 |
|
|
user = parv[1]; |
359 |
|
|
*host = '\0'; |
360 |
|
|
host++; |
361 |
|
|
} |
362 |
|
|
else |
363 |
|
|
{ |
364 |
|
|
user = "*"; |
365 |
|
|
host = parv[1]; |
366 |
|
|
} |
367 |
|
|
|
368 |
|
|
#ifdef PROPAGATE_SPOOF |
369 |
|
|
sendto_server(client_p, source_p, NULL, NOCAPS, NOCAPS, |
370 |
|
|
":%s DELSPOOF %s@%s", source_p->name, user, host); |
371 |
|
|
#endif |
372 |
|
|
|
373 |
|
|
#ifdef SPOOF_FILE |
374 |
|
|
if ((f = fbopen(SPOOF_FILE, "r")) == NULL) |
375 |
|
|
{ |
376 |
|
|
sendto_realops_flags(UMODE_ALL, L_ALL, |
377 |
|
|
"Could not open %s file, auth for %s@%s not deleted " |
378 |
|
|
"(requested by %s)", |
379 |
|
|
SPOOF_FILE, user, host, source_p->name); |
380 |
|
|
return; |
381 |
|
|
} |
382 |
|
|
|
383 |
|
|
if ((fout = fbopen(SPOOF_FILE ".new", "w")) == NULL) |
384 |
|
|
{ |
385 |
|
|
sendto_realops_flags(UMODE_ALL, L_ALL, |
386 |
|
|
"Could not create %s.new file, auth for %s@%s not " |
387 |
|
|
"deleted (requested by %s)", |
388 |
|
|
SPOOF_FILE, user, host, source_p->name); |
389 |
|
|
return; |
390 |
|
|
} |
391 |
|
|
|
392 |
|
|
while (fbgets(buffer, 1024, f)) |
393 |
|
|
{ |
394 |
|
|
if (!ircncmp(buffer, "auth {", 6)) |
395 |
|
|
{ |
396 |
|
|
/* don't process it yet.. we have to check whether the user="..."; field |
397 |
|
|
* matches the user@host mask which is being deleted |
398 |
|
|
*/ |
399 |
|
|
ignore_it = 1; |
400 |
|
|
continue; |
401 |
|
|
} |
402 |
|
|
|
403 |
|
|
/* a simple parser substitute... */ |
404 |
|
|
for (tmp = buffer; *tmp == '\t' || *tmp == ' '; tmp++) |
405 |
|
|
; |
406 |
|
|
if (!ircncmp(tmp, "user", 4)) |
407 |
|
|
{ |
408 |
|
|
for (tmp += 4; *tmp == '\t' || *tmp == ' '; tmp++) |
409 |
|
|
; |
410 |
|
|
if (*tmp == '=') { |
411 |
|
|
for (++tmp; *tmp == '\t' || *tmp == ' '; tmp++) |
412 |
|
|
; |
413 |
|
|
if (*tmp == '\"') |
414 |
|
|
{ |
415 |
|
|
/* yuppi, we've just reached the user="..."; field */ |
416 |
|
|
int matches; |
417 |
|
|
char *tmp2 = strchr(++tmp, '\"'); |
418 |
|
|
|
419 |
|
|
if (tmp2 != NULL) |
420 |
|
|
*tmp2 = '\0'; |
421 |
|
|
tmp2 = strchr(tmp, '@'); |
422 |
|
|
|
423 |
|
|
/* is it matching our mask? */ |
424 |
|
|
if (tmp2 == NULL) |
425 |
|
|
matches = !irccmp(user, "*") && !irccmp(host, tmp); |
426 |
|
|
else |
427 |
|
|
{ |
428 |
|
|
*tmp2++ = '\0'; |
429 |
|
|
matches = !irccmp(user, tmp) && !irccmp(host, tmp2); |
430 |
|
|
} |
431 |
|
|
|
432 |
|
|
if (!matches) |
433 |
|
|
{ |
434 |
|
|
/* no.. so leave it unchanged */ |
435 |
|
|
if (ignore_it) |
436 |
|
|
{ |
437 |
|
|
ignore_it = 0; |
438 |
|
|
fbputs("auth {\n", fout, 7); |
439 |
|
|
/* user="..." should be the first field in the auth {}; block, |
440 |
|
|
* otherwise we could have problems... |
441 |
|
|
*/ |
442 |
|
|
} |
443 |
|
|
|
444 |
|
|
fbputs("\tuser = \"", fout, 9); |
445 |
|
|
if (tmp2 == NULL) |
446 |
|
|
fbputs("*", fout, 1); |
447 |
|
|
else |
448 |
|
|
fbputs(tmp, fout, strlen(tmp)); |
449 |
|
|
fbputs("@", fout, 1); |
450 |
|
|
fbputs(tmp2, fout, strlen(tmp2)); |
451 |
|
|
fbputs("\";\n", fout, 3); |
452 |
|
|
} |
453 |
|
|
else |
454 |
|
|
{ |
455 |
|
|
/* we've got it! - omit and continue working */ |
456 |
|
|
spoof_found = 1; |
457 |
|
|
} |
458 |
|
|
|
459 |
|
|
continue; |
460 |
|
|
} |
461 |
|
|
} |
462 |
|
|
} |
463 |
|
|
|
464 |
|
|
if (!ignore_it) |
465 |
|
|
fbputs(buffer, fout, strlen(buffer)); |
466 |
|
|
} |
467 |
|
|
|
468 |
|
|
fbclose(f); |
469 |
|
|
fbclose(fout); |
470 |
|
|
|
471 |
|
|
if (!spoof_found) |
472 |
|
|
{ |
473 |
|
|
if (MyConnect(source_p)) |
474 |
|
|
sendto_one(source_p, ":%s NOTICE %s :No auth for %s@%s found", |
475 |
|
|
me.name, source_p->name, user, host); |
476 |
|
|
unlink(SPOOF_FILE ".new"); |
477 |
|
|
return; |
478 |
|
|
} |
479 |
|
|
|
480 |
|
|
unlink(SPOOF_FILE); |
481 |
|
|
rename(SPOOF_FILE ".new", SPOOF_FILE); |
482 |
|
|
read_conf_files(NO); |
483 |
|
|
#endif |
484 |
|
|
|
485 |
|
|
#ifdef LOG_SPOOF |
486 |
|
|
sendto_realops_flags(UMODE_ALL, L_ALL, "%s deleted auth for %s@%s", |
487 |
|
|
source_p->name, user, host); |
488 |
|
|
#endif |
489 |
|
|
} |