1#!/usr/bin/env python
2# Contributed 2006 by Stephane Bortzmeyer.
3# Changed 20070102 by Wouter to handle primary zones and file names.
4
5# Converts a nsd 2 "nsd.zones" file to a nsd 3 "nsd.conf" file.
6
7# Change at will
8nsd_zones_name = "./nsd.zones"
9key_dir = "/local/nsd/etc/keys" # Directory holding the TSIG keys
10
11import re
12import os.path
13
14primary_line_re = re.compile("^zone\s+([a-z0-9\.-]+)\s+([a-z0-9/\.-]+)\s*$", re.IGNORECASE)
15secondary_line_re = re.compile("^zone\s+([a-z0-9\.-]+)\s+([a-z0-9/\.-]+)\s+masters\s+([0-9a-f:\. ]*)\s*$", re.IGNORECASE)
16notify_line_re = re.compile("^zone\s+([a-z0-9\.-]+)\s+([a-z0-9/\.-]+)\s+notify\s+([0-9a-f:\. ]*)\s*$", re.IGNORECASE)
17comment_re = re.compile("^\s*;")
18empty_re = re.compile("^\s*$")
19                        
20nsd_zones = open(nsd_zones_name)
21keys = {}
22for line in nsd_zones.xreadlines():
23    if comment_re.search(line) or empty_re.search(line):
24	pass
25    elif secondary_line_re.search(line):
26    	match = secondary_line_re.search(line)
27        zone = match.group(1)
28        zonefile = match.group(2)
29        master_group = match.group(3)
30        masters = re.split("\s+", master_group)
31        print """zone:
32        name: "%s"
33        zonefile: "%s"
34        # This is to allow "nsdc update" to work.
35        allow-notify: 127.0.0.1 NOKEY
36        # This is a slave zone. Masters are listed below.""" % (zone, zonefile)
37        for master in masters:
38            if re.search("^\s*$", master):
39                continue
40            key_filename = "%s/%s.tsiginfo" % (key_dir, master)
41            if os.path.exists(key_filename):
42                key_content = open(key_filename)
43                peer_ip = key_content.readline()
44                peer_ip = peer_ip[:-1]
45                key_name = key_content.readline()
46                key_name = key_name[:-1]
47                algorithm = key_content.readline()
48                algorithm = int(algorithm[:-1])
49                if algorithm == 157:
50                    algorithm_name = "hmac-md5"
51                else:
52                    raise Exception("Unsupported TSIG algorithm %i" % algorithm)
53                secret = key_content.readline()
54                secret = secret[:-1]
55                key_content.close()
56                key = key_name
57                keys[key_name] = {
58                    'algorithm': algorithm_name,
59                    'secret': secret}
60            else:
61                key = "NOKEY"
62            print """        allow-notify: %s %s
63        request-xfr: %s %s""" % (master, key, master, key)
64        print ""
65    elif primary_line_re.search(line):
66	match = primary_line_re.search(line)
67	zone = match.group(1)
68	zonefile = match.group(2)
69	print """zone:
70	name: "%s"
71	zonefile: "%s"
72	""" % (zone, zonefile)
73    elif notify_line_re.search(line):
74    	match = notify_line_re.search(line)
75        zone = match.group(1)
76        zonefile = match.group(2)
77        notify_group = match.group(3)
78        notifies = re.split("\s+", notify_group)
79        print """zone:
80        name: "%s"
81        zonefile: "%s"
82        # This is a master zone. Slaves are listed below.""" % (zone, zonefile)
83        for notify in notifies:
84            if re.search("^\s*$", notify):
85                continue
86            key = "NOKEY"
87            print """        notify: %s %s""" % (notify, key)
88        print ""
89    else:
90	raise Exception("Invalid line \"%s\"" % line)
91nsd_zones.close()
92for key in keys.keys():
93    print """key:
94        name: "%s"
95        algorithm: %s
96        secret: "%s" """ % (key, keys[key]['algorithm'], keys[key]['secret'])
97    print ""
98    
99## Local Variables: ##
100## mode:python ##
101## End: ##
102