From 65ac14c1a930aa5ca1bd4193acc8c7d2a8aada80 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Wed, 19 May 2010 11:13:09 +0200 Subject: [PATCH] Mi ero dimenticato di committare l'unico file rilevante. --- pywhoisd.py | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100755 pywhoisd.py diff --git a/pywhoisd.py b/pywhoisd.py new file mode 100755 index 0000000..4c92128 --- /dev/null +++ b/pywhoisd.py @@ -0,0 +1,164 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# +# This is a simple whois daemon intended to +# provide a basic whois for GNet. +# + +import SocketServer, re, math + +ip_database = {} +domain_database = {} +config = {} + +def ip_in_subnet(ip, network, subnet): + ip = map(int, ip.split(".")) + network = map(int, network.split(".")) + if "." in subnet: + subnet = map(int, subnet.split(".")) + subnet = map(lambda x: 255 - x, subnet) + subnet = math.log(subnet[3] + subnet[2] * 256 + subnet[1] * pow(256,2) + subnet[0] * pow(256,3), 2) + subnet = pow(2, 32 - int(subnet)) + ip = ip[3] + ip[2] * 256 + ip[1] * pow(256,2) + ip[0] * pow(256,3) + network = network[3] + network[2] * 256 + network[1] * pow(256,2) + network[0]*pow(256,3) + if ((ip - network) < subnet) and (ip-network >= 0): + return True + else: + return False + +def get_net_of_ip(ip): + for (address, net) in ip_database.items(): + nip, netmask = address.split("/") + + if ip_in_subnet(ip, nip, netmask): + return address + +def format_output(field, value): + """ + Append a value to the output + """ + output = (field + ":").ljust(24) + output += value + "\n" + return " "*4 + output + +def format_message(message): + output = "\n" + for line in message.split("\n"): + line = line.strip() + output += """\n %% """ + line.ljust(85) + """ %%""" + return output + "\n\n" + +def resolve_ip(ip): + output = "" + net = get_net_of_ip(ip) + if net is not None: + output += format_message("GNet whoisd answering for ip %s" % ip) + net = ip_database[net] + if net.name is not None: + output += format_output ("Name", net.name) + if net.owner is not None: + output += format_output ("Owner", net.owner) + if net.ns is not None: + output += format_output ("Nameserver", net.ns) + if len(net.data.items()) > 0: + output += format_message("Additional data") + for k, v in data.items(): + output += format_output (k.capitalize(),v) + else: + output = format_message("IP %s not found\n" % ip) + output += format_message("Bye") + return output + +def resolve_domain(domain): + return format_message("Feature not yet implemented") + +def hello(): + if config.has_key('welcome_banner'): + return config['welcome_banner'] + else: + return "" + + +class WhoisRequestHandler(SocketServer.StreamRequestHandler): + """ + This handler answers to the whois request + """ + + def handle(self): + # Come prima cosa salutiamo + response = format_message(hello()) + + # Obtain the whois request + request = self.rfile.readline().strip() + + if re.search(r"\d+\.\d+\.\d+\.\d+", request.strip()): + response += resolve_ip(request.split("/")[0]) + else: + response += resolve_domain(request) + + self.request.send (response) + +class Net(): + + def __init__(self, name, owner, ns, data): + self.name = name + self.owner = owner + self.ns = ns + self.data = data + +def populate_databases(config_file): + """ + Populate databases with the data of our zones + """ + print "Populating database" + try: + f = open(config_file, 'r') + data = f.read() + except IOError: + print >>stderr, "Error while loading config file. exiting" + + nets = re.findall (r"net\s+(\d+\.\d+\.\d+\.\d+[/\d]*)[\s|\n]+\{([^\}]+)\};", data) + for net in nets: + print "> net %s loaded" % net[0] + fields = re.findall(r"(\w+)\s*=\s*([^;]+);", net[1]) + name, owner, ns = None, None, None + data = {} + for field, value in fields: + if field.lower() == 'name': + name = value.strip() + elif field.lower() == 'owner': + owner = value.strip() + elif field.lower() == 'ns': + ns = value.strip() + else: + data[field] = value + ip_database[net[0]] = Net(name = name, owner = owner, ns = ns, + data = data) + +def parse_config_file(config_file): + + config = {} + f = open(config_file, 'r') + content = f.read() + f.close() + for (key, value) in re.findall(r"([^\s]+)\s*=\s*([^;]+)\s*;", content): + config[key] = value + return config + + + + +if __name__ == "__main__": + + config = parse_config_file ('pywhoisd.conf') + populate_databases(config['config_file']) + host, port = "localhost", 43 + server = SocketServer.TCPServer((host, port), WhoisRequestHandler) + try: + server.serve_forever(0.1) + except KeyboardInterrupt: + print "Exiting...", + print "done" + + + -- 2.1.4