ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 5274
Committed: Thu Jan 1 20:00:33 2015 UTC (10 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 27610 byte(s)
Log Message:
- Renamed MyMalloc() to xcalloc()

File Contents

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

Properties

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