ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/scan.c
Revision: 8563
Committed: Sun Sep 23 11:39:44 2018 UTC (6 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 26118 byte(s)
Log Message:
- Update copyright years

File Contents

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

Properties

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