ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.0.x/src/scan.c
Revision: 5137
Committed: Thu Dec 25 19:36:37 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
Original Path: hopm/trunk/src/scan.c
File size: 27830 byte(s)
Log Message:
- Removed vim settings from the source files

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

Properties

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