ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.0.x/src/scan.c
Revision: 5134
Committed: Thu Dec 25 18:50:02 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
Original Path: hopm/trunk/src/scan.c
File size: 27885 byte(s)
Log Message:
- propset svn:keywords "Id"

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

Properties

Name Value
svn:keywords Id