ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.0.x/src/scan.c
Revision: 5321
Committed: Tue Jan 6 14:59:31 2015 UTC (9 years, 2 months ago) by michael
Content type: text/x-csrc
File size: 26541 byte(s)
Log Message:
- Fixed coding convention issues

File Contents

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

Properties

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