ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 9865
Committed: Sat Jan 2 18:42:37 2021 UTC (5 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 26083 byte(s)
Log Message:
- Bump copyright years

File Contents

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

Properties

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