ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 5374
Committed: Tue Jan 13 19:01:23 2015 UTC (10 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 26867 byte(s)
Log Message:
- scan.c:scan_manual(): replaced inet_ntoa() with inet_ntop()

File Contents

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

Properties

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