1 /**
2  * Client for DNS blacklist services.
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <vladimir@thecybershadow.net>
12  */
13 
14 
15 module ae.net.dns.dnsbl;
16 
17 import std.socket;
18 import std.string;
19 import ae.net.asockets;
20 
21 string getIP(string hostname)
22 {
23 	try
24 		return (new InternetAddress(hostname, 0)).toAddrString;
25 	catch (Exception o)
26 		return null;
27 }
28 
29 int lookupAgainst(string ip, string db)
30 {
31 	string[] sections = split(ip, ".");
32 	assert(sections.length == 4);
33 	string addr = sections[3] ~ "." ~ sections[2] ~ "." ~ sections[1] ~ "." ~ sections[0] ~ "." ~ db;
34 	InternetHost ih = new InternetHost;
35 	if (ih.getHostByName(addr))
36 		return ih.addrList[0] & 0xFF;
37 	else
38 		return 0;
39 }
40 
41 string lookupDroneBL(string ip)
42 {
43 	switch (lookupAgainst(ip, "dnsbl.dronebl.org"))
44 	{
45 		case  0: return null;
46 		case  2: return "Sample";
47 		case  3: return "IRC Drone";
48 		case  5: return "Bottler";
49 		case  6: return "Unknown spambot or drone";
50 		case  7: return "DDOS Drone";
51 		case  8: return "SOCKS Proxy";
52 		case  9: return "HTTP Proxy";
53 		case 10: return "ProxyChain";
54 		case 13: return "Brute force attackers";
55 		case 14: return "Open Wingate Proxy";
56 		case 15: return "Compromised router / gateway";
57 		default: return "Unknown";
58 	}
59 }
60 
61 string lookupEfnetRBL(string ip)
62 {
63 	switch (lookupAgainst(ip, "rbl.efnetrbl.org"))
64 	{
65 		case  0: return null;
66 		case  1: return "Open Proxy";
67 		case  2: return "spamtrap666";
68 		case  3: return "spamtrap50";
69 		case  4: return "TOR";
70 		case  5: return "Drones / Flooding";
71 		default: return "Unknown";
72 	}
73 }
74 
75 string[] blacklistCheck(string hostname)
76 {
77 	string ip = getIP(hostname);
78 
79 	if (!ip)
80 		throw new Exception("Can't resolve hostname to IPv4 address: " ~ hostname);
81 
82 	string result;
83 
84 	result = lookupDroneBL(ip);
85 	if (result) return [result, "DroneBL"  , "http://dronebl.org/lookup?ip="~ip];
86 
87 	result = lookupEfnetRBL(ip);
88 	if (result) return [result, "EFnet RBL", "http://rbl.efnetrbl.org/?i="  ~ip];
89 
90 	return null;
91 }