ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 5114
Committed: Wed Dec 24 22:12:05 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 28611 byte(s)
Log Message:
- Style corrections

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