ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 8110
Committed: Sun Apr 2 16:05:44 2017 UTC (8 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 26135 byte(s)
Log Message:
- firedns.c, scan.c: whitespace changes

File Contents

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

Properties

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