ascension

Migrate DNS zones to the GNU Name System
Log | Files | Refs | README | LICENSE

commit bc7fed5c8452baccfe0767c8fcf075d4fc8afd3f
parent dac1a3b94297cdd66ac33efeeea2a73c47554f2a
Author: rexxnor <rexxnor+gnunet@brief.li>
Date:   Thu, 20 Sep 2018 10:19:17 +0200

initial prototype, bootstrapping zones and zone transfer

Diffstat:
M.gitignore | 1+
Agnsmigrator/__init__.py | 0
Agnsmigrator/gnsmigrator.py | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Arequirements.txt | 4++++
4 files changed, 149 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -95,3 +95,4 @@ ENV/ # mkdocs documentation /site +.idea/ diff --git a/gnsmigrator/__init__.py b/gnsmigrator/__init__.py diff --git a/gnsmigrator/gnsmigrator.py b/gnsmigrator/gnsmigrator.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 +"""GNS Migrator + +Usage: + gnsmigrator.py <file> + gnsmigrator.py -h | --help + gnsmigrator.py --version + +Options: + -h --help Show this screen. + --version Show version. +""" + +# imports +import subprocess +import csv +import dns.query +import dns.resolver +import dns.zone +import docopt + +# GLOBALS +GNUNET_ZONE_CREATION_COMMAND = 'gnunet-identity' +GNUNET_NAMESTORE_COMMAND = 'gnunet-namestore' +GNUNET_GNS_COMMAND = 'gnunet-gns' + +class GNSMigrator(): + """ + Class that provides functionality to migrate zones + """ + + @classmethod + def __init__(cls, domainlist): + cls.domainlist = domainlist + cls.zones = {} + + @classmethod + def initial_zone_transfer(cls): + """ + Fetch all the zones via zone transfer + """ + for domain in cls.domainlist: + try: + soa_answer = dns.resolver.query(domain, 'SOA') + except dns.resolver.NoAnswer: + print("the domain '%s' does not exist" % domain) + continue + + master_answer = dns.resolver.query(soa_answer[0].mname, 'A') + + try: + zone = dns.zone.from_xfr(dns.query.xfr(master_answer[0].address, domain)) + except dns.resolver.NoAnswer: + print("the domain '%s' did not answer our xfr request" % domain) + continue + except dns.exception.FormError: + print("the domain '%s' does not allow xfr requests from your ip" % domain) + continue + cls.zones[domain] = (zone, (master_answer[0].address, domain)) + + @classmethod + def bootstrap_zones(cls): + """ + Bootstrap the zone structure into GNS + """ + for domain in cls.domainlist: + counter = 0 + # building list with arguments + reverse_parsing = domain.split('.')[::-1] + for domainpart in reverse_parsing: + pkey_lookup = subprocess.Popen([GNUNET_ZONE_CREATION_COMMAND, '-d'], + stdout=subprocess.PIPE) + pkey_line = subprocess.Popen(['grep', domainpart], + stdin=pkey_lookup.stdout, + stdout=subprocess.PIPE) + pkey_zone = subprocess.check_output(['cut', '-d', ' ', '-f3'], + stdin=pkey_line.stdout).decode().strip() + # Create identity in GNUnet + if not pkey_zone: + subprocess.run([GNUNET_ZONE_CREATION_COMMAND, + '-C', domainpart]) + + # If it is TLD, don't add PKEY to higher zone as they do not exist + if counter > 0: + result = subprocess.check_output([GNUNET_GNS_COMMAND, + '-t', 'PKEY', + '-u', '%s.%s' % + (domainpart, reverse_parsing[counter - 1])]) + + if "No results." in result.decode(): + subprocess.run([GNUNET_NAMESTORE_COMMAND, + '-z', reverse_parsing[counter - 1], + '-a', '-n', domainpart, + '-t', 'PKEY', + '-V', pkey_zone, + '-e', 'never']) + #'-e', current+validity]) + counter += 1 + + @staticmethod + def add_records_to_gns(zone): + """ + Adds the records from the zones to GNS with expiration + :param zone: zone to add to GNS + :returns: 0 on success, 1 on error + """ + pass + + @staticmethod + def check_records_existing(zone): + """ + Checks if records are present + :param param1: zone to lookup + :returns: parts of zone that are not in GNS + """ + for record in zone.iterate_rdatas(): + print(record) + return "" + + +def main(): + """ + Initializes object and handles arguments + """ + args = docopt.docopt(__doc__, version='GNS Migrator 0.1a') + csvfile = args['<file>'] + domainlist = [] + with open(csvfile, 'r') as openedcsv: + linereader = csv.reader(openedcsv, delimiter=' ', quotechar='|') + for domain in linereader: + domainlist += domain + + gnsmigrator = GNSMigrator(domainlist) + gnsmigrator.bootstrap_zones() + gnsmigrator.initial_zone_transfer() + + for domain, zonetuple in gnsmigrator.zones.items(): + zone, xfrinfo = zonetuple + remaining_records = gnsmigrator.check_records_existing(zone) + # gnsmigrator.add_records_to_gns(remaining_records) + + +if __name__ == '__main__': + main() diff --git a/requirements.txt b/requirements.txt @@ -0,0 +1,4 @@ +cffi==1.11.5 +dnspython==1.15.0 +docopt==0.6.2 +pycparser==2.18