ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 5137
Committed: Thu Dec 25 19:36:37 2014 UTC (11 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 27830 byte(s)
Log Message:
- Removed vim settings from the source files

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

Properties

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