ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.0.x/src/scan.c
Revision: 5174
Committed: Fri Dec 26 21:08:42 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 27816 byte(s)
Log Message:
- Removed now unused inet.c and inet.h

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

Properties

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