ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 8155
Committed: Sat Apr 8 16:30:11 2017 UTC (8 years, 4 months ago) by michael
Content type: text/x-csrc
File size: 26460 byte(s)
Log Message:
- Use designated initializers; scan_gettype(): use pointer arithmetic

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

Properties

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