ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.0.x/src/scan.c
Revision: 5089
Committed: Tue Dec 23 18:51:47 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
Original Path: hopm/trunk/src/scan.c
File size: 29596 byte(s)
Log Message:
- scan.c:scan_manual(): fixed memory leak

File Contents

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