ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.1.x/src/scan.c
Revision: 10025
Committed: Sat Jan 1 10:22:47 2022 UTC (2 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 26083 byte(s)
Log Message:
- Bump copyright years

File Contents

# User Rev Content
1 michael 5052 /*
2 michael 5351 * Copyright (c) 2002 Erik Fears
3 michael 10025 * Copyright (c) 2014-2022 ircd-hybrid development team
4 michael 5052 *
5 michael 5351 * This program is free software; you can redistribute it and/or modify
6     * it under the terms of the GNU General Public License as published by
7     * the Free Software Foundation; either version 2 of the License, or
8     * (at your option) any later version.
9 michael 5052 *
10 michael 5351 * This program is distributed in the hope that it will be useful,
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     * GNU General Public License for more details.
14 michael 5052 *
15 michael 5351 * You should have received a copy of the GNU General Public License
16     * along with this program; if not, write to the Free Software
17     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18     * USA
19 michael 5052 */
20    
21     #include "setup.h"
22    
23     #include <stdio.h>
24 michael 5207 #include <stdlib.h>
25     #include <string.h>
26 michael 5266 #include <time.h>
27 michael 5311 #include <sys/socket.h>
28 michael 8108 #include <netdb.h>
29 michael 5311 #include <netinet/in.h>
30 michael 5052
31     #include "compat.h"
32     #include "config.h"
33     #include "irc.h"
34     #include "log.h"
35     #include "stats.h"
36     #include "dnsbl.h"
37     #include "options.h"
38     #include "negcache.h"
39 michael 5202 #include "main.h"
40 michael 5333 #include "memory.h"
41 michael 5052 #include "match.h"
42 michael 6971 #include "misc.h"
43 michael 5052 #include "scan.h"
44    
45 michael 8138 /* libopm includes */
46 michael 5052 #include "libopm/src/opm.h"
47     #include "libopm/src/opm_common.h"
48     #include "libopm/src/opm_error.h"
49     #include "libopm/src/opm_types.h"
50    
51    
52 michael 8186 /* GLOBAL LIST */
53     static list_t SCANNERS; /* List of OPM_T */
54 michael 5052
55     /* Function declarations */
56 michael 5338 static struct scan_struct *scan_create(const char *[], const char *);
57 michael 5322 static void scan_free(struct scan_struct *);
58 michael 5338 static void scan_irckline(const struct scan_struct *, const char *, const char *);
59     static void scan_negative(const struct scan_struct *);
60 michael 5052 static void scan_log(OPM_REMOTE_T *);
61    
62     /** Callbacks for LIBOPM */
63 michael 5338 static void scan_open_proxy(OPM_T *, OPM_REMOTE_T *, int, void *);
64     static void scan_negotiation_failed(OPM_T *, OPM_REMOTE_T *, int, void *);
65 michael 5052 static void scan_timeout(OPM_T *, OPM_REMOTE_T *, int, void *);
66     static void scan_end(OPM_T *, OPM_REMOTE_T *, int, void *);
67     static void scan_handle_error(OPM_T *, OPM_REMOTE_T *, int, void *);
68    
69     extern FILE *scanlogfile;
70    
71 michael 5114
72 michael 5052 /* scan_cycle
73     *
74     * Perform scanner tasks.
75     */
76 michael 5114 void
77     scan_cycle(void)
78 michael 5052 {
79 michael 5695 node_t *node;
80 michael 5052
81 michael 5114 /* Cycle through the blacklist first.. */
82     dnsbl_cycle();
83 michael 5052
84 michael 5114 /* Cycle each scanner object */
85 michael 8186 LIST_FOREACH(node, SCANNERS.head)
86 michael 5114 {
87 michael 5695 struct scanner_struct *scs = node->data;
88 michael 5114 opm_cycle(scs->scanner);
89     }
90 michael 5052 }
91    
92     /* scan_timer
93 michael 5876 *
94 michael 5052 * Perform actions that are to be performed every ~1 second.
95     *
96     * Parameters: NONE
97     * Return: NONE
98     *
99     */
100 michael 5114 void
101     scan_timer(void)
102 michael 5052 {
103 michael 5332 static time_t nc_counter;
104 michael 5052
105 michael 8580 if (OptionsItem.negcache)
106 michael 5114 {
107 michael 8580 if (nc_counter++ >= OptionsItem.negcache_rebuild)
108 michael 5114 {
109     /*
110 michael 5332 * Time to rebuild the negative cache.
111 michael 5114 */
112     if (OPT_DEBUG)
113     log_printf("SCAN -> Rebuilding negative cache");
114 michael 5052
115 michael 5114 negcache_rebuild();
116     nc_counter = 0;
117     }
118     }
119 michael 5052 }
120    
121     /* scan_gettype(int protocol)
122     *
123     * Return human readable name of OPM PROTOCOL given OPM_TYPE_PROTOCOL
124     *
125     * Parameters:
126     * protocol: Protocol to return (from libopm/src/opm_types.h)
127     *
128     * Return:
129     * Pointer to static string containing human readable form of protocol
130     * name
131     *
132     */
133 michael 5114 const char *
134     scan_gettype(int protocol)
135 michael 5052 {
136 michael 8156 static const char *const undef = "undefined";
137 michael 5338 static const struct protocol_assoc protocols[] =
138 michael 5114 {
139 michael 8156 { .type = OPM_TYPE_HTTP, .name = "HTTP" },
140     { .type = OPM_TYPE_HTTPPOST, .name = "HTTPPOST" },
141     { .type = OPM_TYPE_SOCKS4, .name = "SOCKS4" },
142     { .type = OPM_TYPE_SOCKS5, .name = "SOCKS5" },
143     { .type = OPM_TYPE_WINGATE, .name = "WINGATE" },
144     { .type = OPM_TYPE_ROUTER, .name = "ROUTER" },
145     { .type = OPM_TYPE_HTTPS, .name = "HTTPS" },
146     { .type = OPM_TYPE_HTTPSPOST, .name = "HTTPSPOST" },
147     { .type = OPM_TYPE_DREAMBOX, .name = "DREAMBOX" },
148 michael 8565 { .type = OPM_TYPE_SSH, .name = "SSH" },
149 michael 8156 { .type = 0 }
150 michael 5114 };
151 michael 5052
152 michael 8156 for (const struct protocol_assoc *tab = protocols; tab->type; ++tab)
153     if (protocol == tab->type)
154     return tab->name;
155 michael 5052
156 michael 5114 return undef;
157 michael 5052 }
158    
159 michael 6299 /* scan_checkexempt
160     *
161     * Check mask against exempt list.
162     *
163     * Parameters:
164     * mask: Mask to check
165     *
166     * Return:
167     * 1 if mask is in list
168     * 0 if mask is not in list
169     */
170     static int
171     scan_checkexempt(const char *mask, const char *ipmask)
172     {
173     node_t *node;
174    
175 michael 8580 LIST_FOREACH(node, ExemptItem.masks.head)
176 michael 6299 {
177     const char *exempt_mask = node->data;
178    
179 michael 8554 if (match(exempt_mask, mask) == 0 || match(exempt_mask, ipmask) == 0)
180 michael 6299 return 1;
181     }
182    
183     return 0;
184     }
185    
186 michael 5052 /* scan_init
187    
188     Initialize scanner and masks list based on configuration.
189    
190     Parameters:
191     None
192 michael 5876
193 michael 5052 Return:
194     None
195     */
196 michael 5114 void
197     scan_init(void)
198 michael 5052 {
199 michael 8581 node_t *p, *p2, *p3, *p4;
200 michael 5052
201 michael 5116 /* Setup each individual scanner */
202 michael 8580 LIST_FOREACH(p, ScannerItemList.head)
203 michael 5116 {
204 michael 8138 struct ScannerConf *sc = p->data;
205 michael 5052
206 michael 5116 if (OPT_DEBUG)
207     log_printf("SCAN -> Setting up scanner [%s]", sc->name);
208 michael 5052
209 michael 5116 /* Build the scanner */
210 michael 8138 struct scanner_struct *scs = xcalloc(sizeof(*scs));
211 michael 5116 scs->scanner = opm_create();
212     scs->name = xstrdup(sc->name);
213 michael 5052
214 michael 5116 /* Setup configuration */
215 michael 5121 opm_config(scs->scanner, OPM_CONFIG_FD_LIMIT, &sc->fd);
216 michael 5116 opm_config(scs->scanner, OPM_CONFIG_SCAN_IP, sc->target_ip);
217 michael 5121 opm_config(scs->scanner, OPM_CONFIG_SCAN_PORT, &sc->target_port);
218     opm_config(scs->scanner, OPM_CONFIG_TIMEOUT, &sc->timeout);
219     opm_config(scs->scanner, OPM_CONFIG_MAX_READ, &sc->max_read);
220 michael 9726 opm_config(scs->scanner, OPM_CONFIG_BIND_IP, sc->bind);
221 michael 5052
222 michael 5116 /* add target strings */
223 michael 8580 LIST_FOREACH(p2, sc->target_string.head)
224 michael 5227 opm_config(scs->scanner, OPM_CONFIG_TARGET_STRING, p2->data);
225 michael 5052
226 michael 5116 /* Setup callbacks */
227     opm_callback(scs->scanner, OPM_CALLBACK_OPENPROXY, &scan_open_proxy, scs);
228     opm_callback(scs->scanner, OPM_CALLBACK_NEGFAIL, &scan_negotiation_failed, scs);
229     opm_callback(scs->scanner, OPM_CALLBACK_TIMEOUT, &scan_timeout, scs);
230     opm_callback(scs->scanner, OPM_CALLBACK_END, &scan_end, scs);
231     opm_callback(scs->scanner, OPM_CALLBACK_ERROR, &scan_handle_error, scs);
232 michael 5052
233 michael 5116 /* Setup the protocols */
234 michael 8580 LIST_FOREACH(p2, sc->protocols.head)
235 michael 5116 {
236 michael 8138 struct ProtocolConf *pc = p2->data;
237 michael 5052
238 michael 5116 if (OPT_DEBUG >= 2)
239     log_printf("SCAN -> Adding protocol %s:%d to scanner [%s]",
240     scan_gettype(pc->type), pc->port, scs->name);
241 michael 5052
242 michael 5116 if (opm_addtype(scs->scanner, pc->type, pc->port) == OPM_ERR_BADPROTOCOL)
243     log_printf("SCAN -> Error bad protocol %s:%d in scanner [%s]",
244     scan_gettype(pc->type), pc->port, scs->name);
245     }
246 michael 5052
247 michael 8581 list_add(scs, node_create(), &SCANNERS);
248 michael 5116 }
249 michael 5052
250 michael 5116 /* Give scanners a list of masks they scan */
251 michael 8186 LIST_FOREACH(p, SCANNERS.head)
252 michael 5116 {
253 michael 8138 struct scanner_struct *scs = p->data;
254 michael 5052
255 michael 8580 LIST_FOREACH(p2, UserItemList.head)
256 michael 5116 {
257 michael 8138 struct UserConf *uc = p2->data;
258 michael 5052
259 michael 8580 LIST_FOREACH(p3, uc->scanners.head)
260 michael 5116 {
261 michael 5699 const char *scannername = p3->data;
262 michael 5052
263 michael 5116 /* Add all these masks to scanner */
264     if (strcasecmp(scannername, scs->name) == 0)
265     {
266 michael 8580 LIST_FOREACH(p4, uc->masks.head)
267 michael 5116 {
268 michael 5699 const char *mask = p4->data;
269 michael 5052
270 michael 5116 if (OPT_DEBUG)
271     log_printf("SCAN -> Linking the mask [%s] to scanner [%s]", mask, scannername);
272 michael 5052
273 michael 8581 list_add(xstrdup(mask), node_create(), &scs->masks);
274 michael 5116 }
275 michael 5052
276 michael 5116 break;
277     }
278 michael 5052 }
279 michael 5116 }
280     }
281 michael 5052
282 michael 5116 /* Initialise negative cache */
283 michael 8580 if (OptionsItem.negcache)
284 michael 5116 {
285     if (OPT_DEBUG >= 2)
286     log_printf("SCAN -> Initializing negative cache");
287    
288 michael 7880 negcache_init();
289 michael 5116 }
290 michael 5052 }
291    
292     /* scan_connect
293     *
294     * scan_connect is called when m_notice (irc.c) matches a connection
295     * notice and parses the connecting user out of it.
296     *
297     * Parameters:
298     * user: Parsed items from the connection notice:
299     * user[0] = connecting users nickname
300     * user[1] = connecting users username
301     * user[2] = connecting users hostname
302     * user[3] = connecting users IP
303     * msg = Original connect notice
304     * Return: NONE
305     *
306     */
307 michael 5116 void
308 michael 5338 scan_connect(const char *user[], const char *msg)
309 michael 5052 {
310 michael 5116 node_t *p, *p2;
311     int ret;
312 michael 5052
313 michael 5116 /*
314     * Have to use MSGLENMAX here because it is unknown what the max size of
315     * username/hostname can be. Some ircds use really mad values for
316     * these.
317     */
318 michael 6292 char hostmask[MSGLENMAX];
319     char addrmask[MSGLENMAX];
320 michael 5052
321 michael 5116 /* Check negcache before anything */
322 michael 7880 if (negcache_check(user[3]))
323 michael 5116 {
324 michael 7880 if (OPT_DEBUG)
325 michael 8142 log_printf("SCAN -> %s!%s@%s [%s] is negatively cached. Skipping all tests.",
326 michael 7880 user[0], user[1], user[2], user[3]);
327     return;
328 michael 5284 }
329 michael 5052
330 michael 5284 /* Generate user mask */
331 michael 6292 snprintf(hostmask, sizeof(hostmask), "%s!%s@%s", user[0], user[1], user[2]);
332     snprintf(addrmask, sizeof(addrmask), "%s!%s@%s", user[0], user[1], user[3]);
333 michael 5052
334 michael 5284 /* Check exempt list now that we have a mask */
335 michael 6292 if (scan_checkexempt(hostmask, addrmask))
336 michael 5284 {
337     if (OPT_DEBUG)
338 michael 8142 log_printf("SCAN -> %s [%s] is exempt from scanning", hostmask, user[3]);
339 michael 5052
340 michael 5284 return;
341     }
342 michael 5052
343 michael 6293 /* Create scan_struct */
344 michael 8121 struct scan_struct *ss = scan_create(user, msg);
345 michael 5052
346 michael 5284 /* Store ss in the remote struct, so that in callbacks we have ss */
347     ss->remote->data = ss;
348 michael 5052
349 michael 5284 /* Start checking our DNSBLs */
350 michael 8580 if (LIST_SIZE(&OpmItem.blacklists))
351 michael 5284 dnsbl_add(ss);
352    
353     /* Add ss->remote to all matching scanners */
354 michael 8186 LIST_FOREACH(p, SCANNERS.head)
355 michael 5284 {
356 michael 8121 struct scanner_struct *scs = p->data;
357 michael 5284
358 michael 8580 LIST_FOREACH(p2, scs->masks.head)
359 michael 5284 {
360 michael 5699 const char *scsmask = p2->data;
361 michael 5284
362 michael 8554 if (match(scsmask, hostmask) == 0)
363 michael 5052 {
364 michael 5284 if (OPT_DEBUG)
365 michael 6292 log_printf("SCAN -> Passing %s to scanner [%s]", hostmask, scs->name);
366 michael 5052
367 michael 5284 if ((ret = opm_scan(scs->scanner, ss->remote)) != OPM_SUCCESS)
368     {
369     switch (ret)
370     {
371     case OPM_ERR_NOPROTOCOLS:
372     continue;
373     break;
374     case OPM_ERR_BADADDR:
375 michael 8146 if (!strchr(ss->ip, ':')) /* XXX: hack alert. remove when libopm can deal with IPv6 addresses */
376     log_printf("OPM -> Bad address %s [%s]", ss->ip, scs->name);
377 michael 5284 break;
378     default:
379 michael 8133 log_printf("OPM -> Unknown error %s [%s]", ss->ip, scs->name);
380 michael 5284 break;
381     }
382     }
383     else
384     ++ss->scans; /* Increase scan count only if OPM_SUCCESS */
385 michael 5052
386 michael 5284 break; /* Continue to next scanner */
387 michael 5052 }
388 michael 5284 }
389     }
390 michael 5052
391 michael 5116 /* All scanners returned !OPM_SUCCESS and there were no dnsbl checks */
392     if (ss->scans == 0)
393     scan_free(ss);
394 michael 5052 }
395    
396     /* scan_create
397     *
398 michael 5116 * Allocate scan struct, including user information and REMOTE
399 michael 5052 * for LIBOPM.
400     *
401     * Parameters:
402     * user: Parsed items from the connection notice:
403     * user[0] = connecting users nickname
404     * user[1] = connecting users username
405     * user[2] = connecting users hostname
406     * user[3] = connecting users IP
407     * msg = Original connect notice (used as PROOF)
408     *
409     * Return: Pointer to new scan_struct
410     *
411     */
412 michael 5322 static struct scan_struct *
413 michael 5338 scan_create(const char *user[], const char *msg)
414 michael 5052 {
415 michael 6149 struct scan_struct *ss = xcalloc(sizeof(*ss));
416 michael 5052
417 michael 5116 ss->irc_nick = xstrdup(user[0]);
418     ss->irc_username = xstrdup(user[1]);
419     ss->irc_hostname = xstrdup(user[2]);
420     ss->ip = xstrdup(user[3]);
421     ss->proof = xstrdup(msg);
422     ss->remote = opm_remote_create(ss->ip);
423 michael 5052
424 michael 5116 return ss;
425 michael 5052 }
426    
427     /* scan_free
428     *
429     * Free a scan_struct. This should only be done if the scan struct has
430     * no scans left!
431     *
432     * Parameters:
433     * ss: scan_struct to free
434 michael 5116 *
435 michael 5052 * Return: NONE
436     */
437 michael 5322 static void
438 michael 5114 scan_free(struct scan_struct *ss)
439 michael 5052 {
440 michael 5426 xfree(ss->irc_nick);
441     xfree(ss->irc_username);
442     xfree(ss->irc_hostname);
443     xfree(ss->ip);
444     xfree(ss->proof);
445 michael 5052
446 michael 5114 opm_remote_free(ss->remote);
447 michael 5426 xfree(ss);
448 michael 5052 }
449    
450     /* scan_checkfinished
451     *
452     * Check if a scan is complete (ss->scans <= 0)
453     * and free it if need be.
454     */
455 michael 5114 void
456     scan_checkfinished(struct scan_struct *ss)
457 michael 5052 {
458 michael 5116 if (ss->scans <= 0)
459     {
460     if (ss->manual_target)
461     irc_send("PRIVMSG %s :CHECK -> All tests on %s completed.",
462 michael 8194 ss->manual_target, ss->ip);
463 michael 5116 else
464     {
465     if (OPT_DEBUG)
466     /* If there was a manual_target, then irc_nick, etc is NULL. */
467 michael 8142 log_printf("SCAN -> All tests on %s!%s@%s [%s] complete.",
468     ss->irc_nick, ss->irc_username, ss->irc_hostname, ss->ip);
469 michael 5052
470 michael 5116 /* Scan was a negative */
471 michael 5322 if (ss->positive == 0)
472 michael 5116 scan_negative(ss);
473     }
474 michael 5052
475 michael 5116 scan_free(ss);
476     }
477 michael 5052 }
478    
479     /* scan_positive
480     *
481     * Remote host (defined by ss) has been found positive by one or more
482     * tests.
483     *
484     * Parameters:
485 michael 5116 * ss: scan_struct containing information regarding positive host
486 michael 5052 * kline: command to send to IRC server to ban the user (see scan_irckline)
487     * type: string of the type of proxy found to be running on the host
488     *
489     * Return: NONE
490     *
491     */
492 michael 5114 void
493     scan_positive(struct scan_struct *ss, const char *kline, const char *type)
494 michael 5052 {
495 michael 5114 node_t *node;
496 michael 5052
497 michael 5114 /* If already a positive, don't kline/close again */
498     if (ss->positive)
499     return;
500 michael 5052
501 michael 5114 /* Format KLINE and send to IRC server */
502     scan_irckline(ss, kline, type);
503 michael 5052
504 michael 5114 /* Speed up the cleanup procedure */
505     /* Close all scans prematurely */
506 michael 8186 LIST_FOREACH(node, SCANNERS.head)
507 michael 5114 {
508     OPM_T *scanner = ((struct scanner_struct *)node->data)->scanner;
509     opm_end(scanner, ss->remote);
510     }
511 michael 5052
512 michael 8138 /* Set it as a positive to avoid a scan_negative call later on */
513 michael 5114 ss->positive = 1;
514 michael 5052 }
515    
516     /* scan_open_proxy CALLBACK
517     *
518     * Called by libopm when a proxy is verified open.
519     *
520     * Parameters:
521     * scanner: Scanner that found the open proxy.
522     * remote: Remote struct containing information regarding remote end
523     *
524     * Return: NONE
525     */
526 michael 5338 static void
527 michael 5114 scan_open_proxy(OPM_T *scanner, OPM_REMOTE_T *remote, int notused, void *data)
528 michael 5052 {
529 michael 8138 struct scan_struct *ss = remote->data;
530     struct scanner_struct *scs = data;
531 michael 5052
532 michael 5116 /* Record that a scan happened */
533     scan_log(remote);
534 michael 5052
535 michael 7882 if (ss->manual_target)
536 michael 5116 {
537 michael 7882 irc_send("PRIVMSG %s :CHECK -> OPEN PROXY %s:%d (%s) [%s]",
538 michael 8194 ss->manual_target, remote->ip, remote->port,
539 michael 7882 scan_gettype(remote->protocol), scs->name);
540     log_printf("SCAN -> OPEN PROXY %s:%d (%s) [%s]", remote->ip,
541     remote->port, scan_gettype(remote->protocol), scs->name);
542     }
543     else
544     {
545 michael 5116 /* kline and close scan */
546 michael 8580 scan_positive(ss, IRCItem.kline, scan_gettype(remote->protocol));
547 michael 5052
548 michael 5116 /* Report to blacklist */
549     dnsbl_report(ss);
550 michael 5052
551 michael 5116 irc_send_channels("OPEN PROXY -> %s!%s@%s %s:%d (%s) [%s]",
552     ss->irc_nick, ss->irc_username, ss->irc_hostname, remote->ip,
553     remote->port, scan_gettype(remote->protocol), scs->name);
554     log_printf("SCAN -> OPEN PROXY %s!%s@%s %s:%d (%s) [%s]",
555     ss->irc_nick, ss->irc_username, ss->irc_hostname, remote->ip,
556     remote->port, scan_gettype(remote->protocol), scs->name);
557     }
558 michael 5052
559 michael 5116 /* Record the proxy for stats purposes */
560     stats_openproxy(remote->protocol);
561 michael 5052 }
562    
563     /* scan_negotiation_failed CALLBACK
564     *
565     * Called by libopm when negotiation of a specific protocol failed.
566     *
567     * Parameters:
568     * scanner: Scanner where the negotiation failed.
569     * remote: Remote struct containing information regarding remote end
570     *
571     * Return: NONE
572     *
573     */
574 michael 5338 static void
575 michael 5116 scan_negotiation_failed(OPM_T *scanner, OPM_REMOTE_T *remote, int notused, void *data)
576 michael 5052 {
577 michael 6285 const struct scanner_struct *scs = data;
578 michael 5052
579 michael 5116 /* Record that a scan happened */
580     scan_log(remote);
581 michael 5052
582 michael 5116 if (OPT_DEBUG)
583     log_printf("SCAN -> Negotiation failed %s:%d (%s) [%s] (%d bytes read)",
584 michael 6285 remote->ip, remote->port, scan_gettype(remote->protocol), scs->name,
585     remote->bytes_read);
586 michael 5052 }
587    
588     /* scan_timeout CALLBACK
589     *
590     * Called by libopm when the negotiation of a specific protocol timed out.
591     *
592     * Parameters:
593     * scanner: Scanner where the connection timed out.
594     * remote: Remote struct containing information regarding remote end
595     *
596     * Return: NONE
597     *
598     */
599 michael 5116 static void
600     scan_timeout(OPM_T *scanner, OPM_REMOTE_T *remote, int notused, void *data)
601 michael 5052 {
602 michael 6285 const struct scanner_struct *scs = data;
603 michael 5052
604 michael 5116 /* Record that a scan happened */
605     scan_log(remote);
606 michael 5052
607 michael 5116 if (OPT_DEBUG)
608     log_printf("SCAN -> Negotiation timed out %s:%d (%s) [%s] (%d bytes read)",
609 michael 6285 remote->ip, remote->port, scan_gettype(remote->protocol), scs->name,
610 michael 5116 remote->bytes_read);
611 michael 5052 }
612    
613     /* scan_end CALLBACK
614     *
615     * Called by libopm when a specific SCAN has completed (all protocols in
616     * that scan).
617     *
618     * Parameters:
619     * scanner: Scanner the scan ended on.
620     * remote: Remote struct containing information regarding remote end
621     *
622     * Return: NONE
623     */
624 michael 5116 static void
625     scan_end(OPM_T *scanner, OPM_REMOTE_T *remote, int notused, void *data)
626 michael 5052 {
627 michael 8138 struct scan_struct *ss = remote->data;
628     struct scanner_struct *scs = data;
629 michael 5052
630 michael 5116 if (OPT_DEBUG)
631     log_printf("SCAN -> Scan %s [%s] completed", remote->ip, scs->name);
632 michael 5052
633 michael 5116 --ss->scans;
634     scan_checkfinished(ss);
635 michael 5052 }
636    
637     /* scan_handle_error CALLBACK
638     *
639     * Called by libopm when an error occurs with a specific connection. This
640     * does not mean the entire scan has ended.
641     *
642     * Parameters:
643     * scanner: Scanner where the error occured.
644     * remote: Remote struct containing information regarding remote end
645     * err: OPM_ERROR code describing the error.
646     *
647     * Return: NONE
648     */
649 michael 5116 static void
650     scan_handle_error(OPM_T *scanner, OPM_REMOTE_T *remote, int err, void *data)
651 michael 5052 {
652 michael 8138 struct scan_struct *ss = remote->data;
653     struct scanner_struct *scs = data;
654 michael 5052
655 michael 5116 switch (err)
656     {
657 michael 5284 case OPM_ERR_MAX_READ:
658     if (OPT_DEBUG >= 2)
659     log_printf("SCAN -> Max read on %s:%d (%s) [%s] (%d bytes read)",
660     remote->ip, remote->port, scan_gettype(remote->protocol),
661     scs->name, remote->bytes_read);
662 michael 5114
663 michael 5284 if (ss->manual_target)
664     irc_send("PRIVMSG %s :CHECK -> Negotiation failed %s:%d (%s) "
665 michael 8194 "[%s] (%d bytes read)", ss->manual_target,
666 michael 5284 remote->ip, remote->port, scan_gettype(remote->protocol),
667     scs->name, remote->bytes_read);
668     break;
669     case OPM_ERR_BIND:
670     log_printf("SCAN -> Bind error on %s:%d (%s) [%s]", remote->ip,
671     remote->port, scan_gettype(remote->protocol), scs->name);
672 michael 8139
673     if (ss->manual_target)
674     irc_send("PRIVMSG %s :CHECK -> Bind error on %s:%d (%s) [%s]",
675 michael 8194 ss->manual_target, remote->ip, remote->port,
676 michael 8139 scan_gettype(remote->protocol), scs->name);
677 michael 5284 break;
678     case OPM_ERR_NOFD:
679     log_printf("SCAN -> File descriptor allocation error %s:%d (%s) "
680     "[%s]", remote->ip, remote->port,
681     scan_gettype(remote->protocol), scs->name);
682 michael 5116
683 michael 5284 if (ss->manual_target)
684     irc_send("PRIVMSG %s :CHECK -> Scan failed %s:%d (%s) [%s] "
685     "(file descriptor allocation error)",
686 michael 8194 ss->manual_target, remote->ip, remote->port,
687 michael 5284 scan_gettype(remote->protocol), scs->name);
688     break;
689     default: /* Unknown Error! */
690     if (OPT_DEBUG)
691     log_printf("SCAN -> Unknown error %s:%d (%s) [%s]", remote->ip,
692     remote->port, scan_gettype(remote->protocol), scs->name);
693     break;
694 michael 5116 }
695 michael 5052 }
696    
697     /* scan_negative
698     *
699     * Remote host (defined by ss) has passed all tests.
700     *
701     * Parameters:
702     * ss: scan_struct containing information regarding negative host.
703     *
704     * Return: NONE
705     *
706     */
707 michael 5114 static void
708 michael 5338 scan_negative(const struct scan_struct *ss)
709 michael 5114 {
710     /* Insert IP in negcache */
711 michael 8580 if (OptionsItem.negcache)
712 michael 5114 {
713     if (OPT_DEBUG >= 2)
714     log_printf("SCAN -> Adding %s to negative cache", ss->ip);
715 michael 5052
716 michael 5114 negcache_insert(ss->ip);
717     }
718 michael 5052 }
719    
720     /* scan_irckline
721     *
722 michael 5876 * ss has been found as a positive host and is to be klined.
723 michael 5052 * Format a kline message using the kline message provided
724     * as a format, then pass it to irc_send() to be sent to the remote server.
725     *
726     * Parameters:
727     * ss: scan_struct containing information regarding host to be klined
728     * format: kline message to format
729     * type: type of proxy found (%t format character)
730 michael 5876 *
731 michael 5052 * Return: NONE
732     */
733 michael 5114 static void
734 michael 5338 scan_irckline(const struct scan_struct *ss, const char *format, const char *type)
735 michael 5052 {
736 michael 6238 char message[MSGLENMAX] = ""; /* OUTPUT */
737 michael 5052
738 michael 5114 unsigned int pos = 0; /* position in format */
739     unsigned int len = 0; /* position in message */
740     unsigned int size = 0; /* temporary size buffer */
741 michael 6025 struct kline_format_assoc
742 michael 5114 {
743 michael 6025 const char key;
744 michael 6030 const char *data;
745 michael 6025 } table[] =
746     {
747 michael 6288 { 'i', ss->ip },
748     { 'h', ss->irc_hostname },
749     { 'u', ss->irc_username },
750     { 'n', ss->irc_nick },
751     { 't', type },
752     { '\0', NULL }
753 michael 5114 };
754 michael 5052
755 michael 5114 /*
756     * Copy format to message character by character, inserting any matching
757     * data after %.
758     */
759     while (format[pos] != '\0' && len < (MSGLENMAX - 2))
760     {
761     switch (format[pos])
762     {
763 michael 5284 case '%':
764     /* % is the last char in the string, move on */
765     if (format[pos + 1] == '\0')
766     continue;
767 michael 5052
768 michael 5284 /* %% escapes % and becomes % */
769     if (format[pos + 1] == '%')
770     {
771     message[len++] = '%';
772     ++pos; /* Skip past the escaped % */
773     break;
774     }
775 michael 5052
776 michael 5284 /* Safe to check against table now */
777 michael 6029 for (const struct kline_format_assoc *tab = table; tab->key; ++tab)
778 michael 5284 {
779 michael 6029 if (tab->key == format[pos + 1])
780 michael 5284 {
781 michael 6029 size = strlen(tab->data);
782 michael 5284
783     /* Check if the new string can fit! */
784     if ((size + len) > (MSGLENMAX - 1))
785     break;
786     else
787 michael 5052 {
788 michael 6029 strlcat(message, tab->data, sizeof(message));
789 michael 5284 len += size;
790 michael 5052 }
791 michael 5284 }
792     }
793 michael 5052
794 michael 5284 /* Skip key character */
795     ++pos;
796     break;
797 michael 5052
798 michael 5284 default:
799     message[len++] = format[pos];
800     message[len] = '\0';
801     break;
802     }
803 michael 5052
804 michael 5284 /* Continue to next character in format */
805     ++pos;
806 michael 5114 }
807    
808     irc_send("%s", message);
809 michael 5052 }
810    
811     /* scan_manual
812     *
813     * Create a manual scan. A manual scan is a scan where the
814     * scan_struct contains a manual_target pointer.
815     */
816 michael 5114 void
817 michael 8194 scan_manual(char *param, const char *target)
818 michael 5052 {
819 michael 5374 char buf[INET6_ADDRSTRLEN];
820     const void *addr = NULL;
821     const char *ip = NULL;
822 michael 5114 char *scannername;
823 michael 5695 node_t *node;
824 michael 8108 int ret, n;
825     struct sockaddr_storage storage;
826     socklen_t storage_len = 0;
827 michael 5052
828 michael 5114 /* If there were no parameters sent, simply alert the user and return */
829     if (param == NULL)
830     {
831 michael 8194 irc_send("PRIVMSG %s :OPM -> Invalid parameters.", target);
832 michael 5114 return;
833     }
834 michael 5052
835 michael 5114 /*
836     * Try to extract a scanner name from param, otherwise we'll be
837     * adding to all scanners
838     */
839     ip = param;
840 michael 5052
841 michael 5114 if ((scannername = strchr(param, ' ')))
842     {
843     *scannername = '\0';
844     scannername++;
845     }
846 michael 5052
847 michael 8108 memset(&storage, 0, sizeof(storage));
848    
849     if ((addr = firedns_resolveip6(ip)))
850 michael 5114 {
851 michael 8108 struct sockaddr_in6 *in = (struct sockaddr_in6 *)&storage;
852    
853     storage_len = sizeof(*in);
854     storage.ss_family = AF_INET6;
855     memcpy(&in->sin6_addr, addr, sizeof(in->sin6_addr));
856     }
857     else if ((addr = firedns_resolveip4(ip)))
858     {
859     struct sockaddr_in *in = (struct sockaddr_in *)&storage;
860    
861     storage_len = sizeof(*in);
862     storage.ss_family = AF_INET;
863     memcpy(&in->sin_addr, addr, sizeof(in->sin_addr));
864     }
865     else
866     {
867 michael 5114 irc_send("PRIVMSG %s :CHECK -> Error resolving host '%s': %s",
868 michael 8194 target, ip, firedns_strerror(firedns_errno));
869 michael 5114 return;
870     }
871 michael 5052
872 michael 8108 if ((n = getnameinfo((const struct sockaddr *)&storage, storage_len, buf, sizeof(buf), NULL, 0, NI_NUMERICHOST)))
873 michael 5374 {
874 michael 5377 irc_send("PRIVMSG %s :CHECK -> invalid address: %s",
875 michael 8194 target, gai_strerror(n));
876 michael 5374 return;
877     }
878 michael 5052
879 michael 8108 ip = buf;
880    
881 michael 8121 struct scan_struct *ss = xcalloc(sizeof(*ss));
882 michael 5114 ss->ip = xstrdup(ip);
883     ss->remote = opm_remote_create(ss->ip);
884     ss->remote->data = ss;
885     ss->manual_target = target;
886 michael 5052
887 michael 5114 if (scannername)
888     irc_send("PRIVMSG %s :CHECK -> Checking '%s' for open proxies [%s]",
889 michael 8194 target, ss->ip, scannername);
890 michael 5114 else
891 michael 8121 irc_send("PRIVMSG %s :CHECK -> Checking '%s' for open proxies on all scanners",
892 michael 8194 target, ss->ip);
893 michael 5052
894 michael 8580 if (LIST_SIZE(&OpmItem.blacklists))
895 michael 5114 dnsbl_add(ss);
896 michael 5052
897 michael 5284 /* Add ss->remote to all scanners */
898 michael 8186 LIST_FOREACH(node, SCANNERS.head)
899 michael 5284 {
900 michael 8121 struct scanner_struct *scs = node->data;
901 michael 5052
902 michael 5284 /*
903     * If we have a scannername, only allow that scanner
904     * to be used
905     */
906     if (scannername)
907     if (strcasecmp(scannername, scs->name))
908     continue;
909 michael 5052
910 michael 5284 if (OPT_DEBUG)
911 michael 8138 log_printf("SCAN -> Passing %s to scanner [%s] (MANUAL SCAN)", ss->ip, scs->name);
912 michael 5052
913 michael 5284 if ((ret = opm_scan(scs->scanner, ss->remote)) != OPM_SUCCESS)
914     {
915     switch (ret)
916 michael 5052 {
917 michael 5284 case OPM_ERR_NOPROTOCOLS:
918     break;
919     case OPM_ERR_BADADDR:
920 michael 8146 if (!strchr(ss->ip, ':')) /* XXX: hack alert. remove when libopm can deal with IPv6 addresses */
921     irc_send("PRIVMSG %s :OPM -> Bad address %s [%s]",
922 michael 8194 ss->manual_target, ss->ip, scs->name);
923 michael 5284 break;
924     default:
925     irc_send("PRIVMSG %s :OPM -> Unknown error %s [%s]",
926 michael 8194 ss->manual_target, ss->ip, scs->name);
927 michael 5284 break;
928 michael 5052 }
929 michael 5284 }
930     else
931     ++ss->scans; /* Increase scan count only if OPM_SUCCESS */
932     }
933 michael 5052
934 michael 5114 /*
935     * If all of the scanners gave !OPM_SUCCESS and there were no dnsbl checks,
936     * cleanup here
937     */
938     if (ss->scans == 0)
939     {
940     if (scannername)
941 michael 8121 irc_send("PRIVMSG %s :CHECK -> No such scanner '%s', or '%s' has 0 protocols.",
942 michael 8194 ss->manual_target, scannername, scannername);
943 michael 5052
944 michael 5114 irc_send("PRIVMSG %s :CHECK -> No scans active on '%s', aborting scan.",
945 michael 8194 ss->manual_target, ss->ip);
946 michael 5114 scan_free(ss);
947     }
948 michael 5052 }
949    
950     /* scan_log
951     *
952     * Log the fact that a given ip/port/protocol has just been scanned, if the
953     * user has asked for this to be logged.
954     *
955     * Parameters:
956     * remote: OPM_REMOTE_T for the remote end
957     */
958 michael 5114 static void
959     scan_log(OPM_REMOTE_T *remote)
960 michael 5052 {
961 michael 5114 struct scan_struct *ss = remote->data;
962 michael 5052
963 michael 8580 if (!(OptionsItem.scanlog && scanlogfile))
964 michael 5114 return;
965 michael 5052
966 michael 6971 fprintf(scanlogfile, "[%s] %s:%d (%s) \"%s\"\n", date_iso8601(0), remote->ip,
967 michael 5114 remote->port, scan_gettype(remote->protocol), ss->proof);
968     fflush(scanlogfile);
969 michael 5052 }

Properties

Name Value
svn:eol-style native
svn:keywords Id