ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 5322
Committed: Tue Jan 6 15:00:39 2015 UTC (11 years, 6 months ago) by michael
Content type: text/x-csrc
File size: 26541 byte(s)
Log Message:
- Fixed coding convention issues

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

Properties

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