/[svn]/hopm/trunk/src/scan.c
ViewVC logotype

Contents of /hopm/trunk/src/scan.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5099 - (show annotations)
Tue Dec 23 21:14:37 2014 UTC (7 years, 6 months ago) by michael
File MIME type: text/x-chdr
File size: 29084 byte(s)
- Replaced several short ints with just ints

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

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28