ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 5164
Committed: Fri Dec 26 18:52:10 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 28215 byte(s)
Log Message:
- Replaced all occurrences of inet_pton() with getaddrinfo()

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

Properties

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