From c660d5285200afef26393a5b31f765eb2669b9f2 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Thu, 20 May 2010 00:55:29 +0200 Subject: [PATCH] =?UTF-8?q?Riorganizzazione=20del=20codice=20molto=20pi?= =?UTF-8?q?=C3=B9=20sensata.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pywhoisd.conf | 4 +- pywhoisd.py | 249 +++++----------------------------------------------------- 2 files changed, 22 insertions(+), 231 deletions(-) diff --git a/pywhoisd.conf b/pywhoisd.conf index 2ab6977..e729322 100644 --- a/pywhoisd.conf +++ b/pywhoisd.conf @@ -7,7 +7,7 @@ # This sets the file with the definition of the net # to be served -config_file = pywhoisd.db; +database_file = pywhoisd.db; # This sets the welcome banner that will be displayed to user # contacting us on port 43 @@ -15,4 +15,4 @@ welcome_banner = This is the whoisd server for the GNet autonomous network. If you'd like to become part of our network visit us at http://linus.robol.it/gnet/ or (if you have access now) http://linus.leo.gnet/gnet/. - See you soon!; \ No newline at end of file + See you soon!; diff --git a/pywhoisd.py b/pywhoisd.py index 5adaeaa..41672e5 100755 --- a/pywhoisd.py +++ b/pywhoisd.py @@ -5,241 +5,32 @@ # provide a basic whois for GNet. # -import SocketServer, re, math, syslog -from ipcalc import IP, Network - -# Dictionaries that will contain runtime data -# for the server -ip_database = {} -domain_database = {} -config = {} - -def Log(message): - syslog.syslog ("[pywhoisd] " + message) - -def get_net_of_ip(ip): - """ - Get network in which the given ip is - """ - interesting_networks = [] - for (address, net) in ip_database.items(): - try: - if IP(ip) in Network(address): - interesting_networks.append (address) - except: - continue - return interesting_networks - -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): - """ - Normal message of the server - """ - output = "\n" - for line in message.split("\n"): - line = line.strip() - output += """\n %% """ + line.ljust(65) + """ %%""" - return output + "\n\n" - -def resolve_ip(ip): - """ - Resolve an ip: it search all the data that match it - """ - output = "" - nets = get_net_of_ip(ip) - for net in nets: - output += format_message("GNet whoisd answering for ip %s" % ip) - output += format_output ("Range", net) - 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 net.data.items(): - output += format_output (k.capitalize(),v) - if len(nets) == 0: - - output = format_message("IP %s not found\n" % ip) - return output - -def get_domains_of_name(domain): - interesting_domains = [] - for domain_name, domain_data in domain_database.items(): - if domain.endswith(domain_name): - interesting_domains.append (domain_name) - - return interesting_domains - -def resolve_domain(domain): - """ - Resolve a domain. It is not yet implemented - """ - domain = domain.strip(".") - output = "" - domains = get_domains_of_name(domain) - for d in domains: - output += format_message("GNet whoisd answering for domain %s" % d) - output += format_output ("Domain", d) - domain = domain_database[d] - if domain.name is not None: - output += format_output ("Name", domain.name) - if domain.owner is not None: - output += format_output ("Owner", domain.owner) - if domain.ns is not None: - output += format_output ("Nameserver", domain.ns) - if len(domain.data.items()) > 0: - output += format_message("Additional data") - for k, v in domain.data.items(): - output += format_output (k.capitalize(),v) - if len(domains) == 0: - return format_message("No domain found for %s" % domain) - return output - -def hello(): - """ - Say hello, server! - """ - 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) - response += format_message("Bye") - - self.request.send (response) - return - -class Net(): - # - # Net is a class representing the network - # contained in the local database and the - # net obtained from other whois server. - # - # It act as a C struct containing only the - # data and no method. - def __init__(self, name, owner, ns, data): - self.name = name - self.owner = owner - self.ns = ns - self.data = data - -class Domain(): - # - # - # - def __init__(self, name, owner, ns, data): - self.name, self.owner, self.ns = name, owner, ns - self.data = data - -def populate_databases(config_file): - """ - Populate databases with the data of our zones - """ - Log ("Populating database with entry in %s" % config_file) - try: - f = open(config_file, 'r') - config_data = f.read() - except IOError: - Log ("Error while loading config file. exiting") - - nets = re.findall (r"net\s+(\d+\.\d+\.\d+\.\d+[/\d]*)[\s|\n]+\{([^\}]+)\};", config_data) - for net in nets: - Log ("Loading net %s" % 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) - - domains = re.findall(r"domain\s+([^\s]+)[\s|\n]+\{([^\}]+)\};", config_data) - for domain in domains: - Log ("Loading domain %s" % domain[0]) - fields = re.findall(r"(\w+)\s*=\s*([^;]+);", domain[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 - domain_database[domain[0]] = Domain(name = name, owner = owner, ns = ns, - data = data) - - -def parse_config_file(config_file): - """ - Parse config file and load_data into memory - """ - config = {} - f = open(config_file, 'r') - content = f.read() - f.close() - for (key, value) in re.findall(r"([^\s]+)\s*=\s*([^;]+)\s*;", content): - # Gestiamo in maniera particolare - # i campi che mi forniscono un array. - if key == "master_domains": - config[key] = [] - for domain in eval(value): - config[key].append(domain) - else: - config[key] = value - return config - - - +import pywhois +from optparse import OptionParser if __name__ == "__main__": - config = parse_config_file ('pywhoisd.conf') - populate_databases(config['config_file']) + parser = OptionParser() + parser.add_option("-v", "--verbose", action="store_true", + default = False, help = "Print syslog to screen") + parser.add_option("-c", "--config", dest="config_file", + default="pywhoisd.conf", + help = "Set config file", metavar="CONFIG_FILE") + + (options, args) = parser.parse_args() + + # Load configuration and create logger + # istance + config = pywhois.Config(options.config_file) + logger = pywhois.Logger(options.verbose) + + # Prepare the real server, listening to the whole world host, port = "0.0.0.0", 43 - server = SocketServer.ThreadingTCPServer((host, port), WhoisRequestHandler) - server.allow_reuse_address = True + server = pywhois.WhoisServer((host, port), logger, config) try: - server.serve_forever(0.1) + server.serve_forever() except KeyboardInterrupt: - Log ("Exiting...") + logger.Log ("pywhoisd daemon exiting now") -- 2.1.4