ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 6237
Committed: Wed Jul 8 13:49:12 2015 UTC (10 years, 1 month ago) by michael
Content type: text/x-csrc
File size: 26844 byte(s)
Log Message:
- scan.c:scan_irckline(): highly unlikely that strlcat() is first to write to 'message', but initialize it anyway

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

Properties

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