ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 6970
Committed: Sat Dec 19 20:29:27 2015 UTC (10 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 25916 byte(s)
Log Message:
- Add date_iso8601() and make use of it

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

Properties

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