ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 5202
Committed: Mon Dec 29 17:50:43 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 27814 byte(s)
Log Message:
- Moved OPT_DEBUG prototype to main.h (where it belongs to) and removed extern.h

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

Properties

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