ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 5116
Committed: Thu Dec 25 15:04:31 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 27893 byte(s)
Log Message:
- Style corrections

File Contents

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