ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/branches/1.1.x/src/scan.c
Revision: 6029
Committed: Tue Jun 2 16:41:29 2015 UTC (8 years, 9 months ago) by michael
Content type: text/x-csrc
Original Path: hopm/trunk/src/scan.c
File size: 26746 byte(s)
Log Message:
- scan.c:scan_irckline(): avoid table indexing where possible

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

Properties

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