ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 5876
Committed: Wed Apr 29 11:25:48 2015 UTC (8 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 26655 byte(s)
Log Message:
- Removed trailing whitespaces

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

Properties

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