ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.1.x/src/scan.c
Revision: 6251
Committed: Fri Jul 10 12:43:03 2015 UTC (8 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 26826 byte(s)
Log Message:
- scan.c: remove poll.h header include

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

Properties

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