ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 5679
Committed: Fri Mar 13 19:23:06 2015 UTC (10 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 26776 byte(s)
Log Message:
- scan.c: removed two useless assert()

File Contents

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

Properties

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