diff options
| -rw-r--r-- | core.py | 64 | ||||
| -rw-r--r-- | model.py | 21 | ||||
| -rw-r--r-- | pywhoisd.conf | 6 | ||||
| -rwxr-xr-x | pywhoisd.py | 35 | 
4 files changed, 78 insertions, 48 deletions
| @@ -2,34 +2,33 @@ import socketserver  import ipaddr  class Daemon(): -    def __init__(data): +    def __init__(self, data):          self.data = data     -    def query(q): +    def query(self, q):          if self.is_ip(q): -            self.search_ip(q) -             +            self.search_ip(q)                      elif self.is_domain(q): -            self.search_domain(q) -             +            self.search_domain(q)                      else:              # Try to find a person with the given query              person = search_person(q)              if person:                  return person              else: -                return self.show_help() +                return self.get_help()      def search_ip(self, ip):          result = {}          # Iterate over all IP block elements -        for network in self.data.get_networks(): -           for block in network.ip_blocks: +        networks = self.data.get_networks() +        for key in networks: +           for block in networks[key].ip_blocks:                 if ipaddr.IPAddress(ip) in ipaddr.IPNetwork(block): -                   result['name'] = network.name -                   for key in network.data: -                       result[key] = network.data[key] +                   result['name'] = networks[key].name +                   for k in networks[key].data: +                       result[k] = networks[key].data[k]                     return result @@ -40,46 +39,57 @@ class Daemon():      def search_domain(self, domain):          pass +    # TODO +      def search_person(self, query):          pass      # TODO      def is_ip(self, query): -        pass +        return True      # TODO      def is_domain(self, query):          pass      # TODO -    def show_help(): -        pass     +    def get_help(self): +        return "This will be the help" + +    # TODO +    def get_footer(self): +        return "This will be the footer" + +    # TODO +    def get_header(self): +        return "This will be the header"  class WhoisHandler(socketserver.BaseRequestHandler): +    def setup(self): +        self.daemon = self.server.daemon +      def handle(self): -        daemon = self.server.daemon -        data = self.request.recv(100) -        cur_thread = threading.current_thread() -        response = daemon.get_header() + "\n" + daemon.query(data) + "\n" + daemon.get_footer() +        data = str(self.request.recv(100), 'utf-8')[:-2] + +        response = self.daemon.get_header() + "\n" +        response += self.daemon.query(data) + "\n" +        response += self.daemon.get_footer()          self.request.sendall(response) -class ClassicServer(socketserver.ThreadingTCPServer): +class ClassicServer(socketserver.ThreadingTCPServer):          def __init__(self, config, daemon):          host = config['Servers']['classic_host'] -        port = config['Servers']['classic_port'] +        port = int(config['Servers']['classic_port'])          self.daemon = daemon -        ThreadingTCPServer.__init__(self, (host, port), WhoisHandler) - -    def start(self): -        pass         +        socketserver.ThreadingTCPServer.__init__(self, (host, port), WhoisHandler)  class WebServer(socketserver.ThreadingTCPServer):      def __init__(self, config, daemon):          self.host = config['Servers']['web_host'] -        self.port = config['Servers']['web_port'] +        self.port = int(config['Servers']['web_port'])          self.daemon = daemon -        ThreadingTCPServer.__init__(self, (host, port), WhoisHandler) +        socketserver.ThreadingTCPServer.__init__(self, (self.host, self.port), WhoisHandler) @@ -1,4 +1,4 @@ -from xml.etree import ElementTree +from xml.etree.ElementTree import ElementTree  class Network():      """A simple network definition""" @@ -37,9 +37,9 @@ class Data():      def __init__(self, config):          self.config = config -        self.networks = [] -        self.domains = [] -        self.persons = [] +        self.networks = None +        self.domains = None +        self.persons = None      def parse_config(self):          """Parse neccesary config params depending on the method used @@ -79,7 +79,7 @@ class Data():          return self.persons -class DataXML(model.Data): +class DataXML(Data):      """Reads network information from a XML file"""      def parse_config(self): @@ -90,8 +90,13 @@ class DataXML(model.Data):      def load_data(self):          """Parse XML for getting network information""" +        self.parse_config()          root = ElementTree(file=self.data_file).getroot() +        self.networks = {} +        self.domains = {} +        self.persons = {} +                  for elem in root:              if elem.tag == 'person':                  self.add_person(elem) @@ -105,7 +110,7 @@ class DataXML(model.Data):      def add_person(self, elem):          """Adds a new person""" -        person = model.Person() +        person = Person()          for e in elem:              if e.tag == 'name':                  person.name = e.text @@ -121,7 +126,7 @@ class DataXML(model.Data):      def add_domain(self, elem):          """Adds a new domain""" -        domain = model.Domain() +        domain = Domain()          for e in elem:              if e.tag == 'name':                  domain.name == e.text @@ -133,7 +138,7 @@ class DataXML(model.Data):      def add_network(self, elem):          """Adds a new network""" -        network = model.Network() +        network = Network()          for e in elem:              if e.tag == 'name':                  network.name = e.text diff --git a/pywhoisd.conf b/pywhoisd.conf index b7d0662..b18da39 100644 --- a/pywhoisd.conf +++ b/pywhoisd.conf @@ -6,10 +6,10 @@ classic = yes  # Only makes sense when classic server is enabled  classic_host = localhost -classic_port = 4343 +classic_port = 4344  # Run a web whois server? -web = yes +web = no  # Only makes sense when web server is enabled  web_host = localhost @@ -20,4 +20,4 @@ web_port = 8080  mode = xml  # Only makes sense when xml storage mode is enabled -xml_file = networks.xml
\ No newline at end of file +xml_file = examples/networks.xml
\ No newline at end of file diff --git a/pywhoisd.py b/pywhoisd.py index 6572cac..11ad133 100755 --- a/pywhoisd.py +++ b/pywhoisd.py @@ -1,5 +1,6 @@  #!/usr/bin/python3  import configparser +import concurrent.futures  import core  import model @@ -9,10 +10,14 @@ class PyWhoisD():      def __init__(self):          self.config = configparser.ConfigParser() -        self.config.read('examples/pywhoisd.conf') +        self.config.read('pywhoisd.conf')          self.data = None          self.daemon = None +        self.classic_server = None +        self.web_server = None + +        self.executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)      # What kind of storage are we using?      def config_data(self): @@ -24,7 +29,7 @@ class PyWhoisD():          mode = self.config['Storage']['mode']          if mode == 'xml': -            self.data = xml.DataXML(self.config) +            self.data = model.DataXML(self.config)      def config_daemon(self):          """Config common information source for all configured servers""" @@ -40,34 +45,44 @@ class PyWhoisD():      def classic(self): -        """Returns true if web server is enabled""" +        """Returns true if classic whois server is enabled""" -        self.config['Servers']['classic'] == 'yes' +        return self.config['Servers']['classic'] == 'yes'      def config_servers(self):          """Sets up server configuration from config files"""          if self.classic(): -            self.classic_server = core.ClassicServer(self.config, self.daemon) +            self.classic_server = core.ClassicServer(self.config, self.daemon)             +        else: +            print("[+] Classic server is not enabled")          if self.web():              self.web_server = core.WebServer(self.config, self.daemon) +        else: +            print("[+] Web server is not enabled") +      def start_servers(self): -        """Start configured servers""" +        """Properly configure and start configured servers"""          self.config_servers() -        if self.classic(): -            self.classic_server.start() +        if self.classic_server: +            print("[+] Starting classic whois server") +            self.executor.submit(self.classic_server.serve_forever) -        if self.web(): -            self.web_server.start() +        if self.web_server: +            self.executor.submit(self.web_server.serve_forever) +      def main(self):          self.config_daemon()          self.start_servers() +        # Wait for running server to finish. Probably never. +        self.executor.shutdown() +  if __name__ == "__main__":      pwd = PyWhoisD()      pwd.main() | 
