ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 8140
Committed: Tue Apr 4 17:06:01 2017 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 26087 byte(s)
Log Message:
- scan.c:scan_handle_error(): report bind() errors to irc, too

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

Properties

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