xref: /minix3/external/bsd/bind/dist/bin/python/dnssec-checkds.py.in (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek#!@PYTHON@
2*00b67f09SDavid van Moolenbroek############################################################################
3*00b67f09SDavid van Moolenbroek# Copyright (C) 2012-2014  Internet Systems Consortium, Inc. ("ISC")
4*00b67f09SDavid van Moolenbroek#
5*00b67f09SDavid van Moolenbroek# Permission to use, copy, modify, and/or distribute this software for any
6*00b67f09SDavid van Moolenbroek# purpose with or without fee is hereby granted, provided that the above
7*00b67f09SDavid van Moolenbroek# copyright notice and this permission notice appear in all copies.
8*00b67f09SDavid van Moolenbroek#
9*00b67f09SDavid van Moolenbroek# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10*00b67f09SDavid van Moolenbroek# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11*00b67f09SDavid van Moolenbroek# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12*00b67f09SDavid van Moolenbroek# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13*00b67f09SDavid van Moolenbroek# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14*00b67f09SDavid van Moolenbroek# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15*00b67f09SDavid van Moolenbroek# PERFORMANCE OF THIS SOFTWARE.
16*00b67f09SDavid van Moolenbroek############################################################################
17*00b67f09SDavid van Moolenbroek
18*00b67f09SDavid van Moolenbroekimport argparse
19*00b67f09SDavid van Moolenbroekimport pprint
20*00b67f09SDavid van Moolenbroekimport os
21*00b67f09SDavid van Moolenbroek
22*00b67f09SDavid van Moolenbroekprog='dnssec-checkds'
23*00b67f09SDavid van Moolenbroek
24*00b67f09SDavid van Moolenbroek# These routines permit platform-independent location of BIND 9 tools
25*00b67f09SDavid van Moolenbroekif os.name == 'nt':
26*00b67f09SDavid van Moolenbroek    import win32con
27*00b67f09SDavid van Moolenbroek    import win32api
28*00b67f09SDavid van Moolenbroek
29*00b67f09SDavid van Moolenbroekdef prefix(bindir = ''):
30*00b67f09SDavid van Moolenbroek    if os.name != 'nt':
31*00b67f09SDavid van Moolenbroek        return os.path.join('@prefix@', bindir)
32*00b67f09SDavid van Moolenbroek
33*00b67f09SDavid van Moolenbroek    bind_subkey = "Software\\ISC\\BIND"
34*00b67f09SDavid van Moolenbroek    hKey = None
35*00b67f09SDavid van Moolenbroek    keyFound = True
36*00b67f09SDavid van Moolenbroek    try:
37*00b67f09SDavid van Moolenbroek        hKey = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE, bind_subkey)
38*00b67f09SDavid van Moolenbroek    except:
39*00b67f09SDavid van Moolenbroek        keyFound = False
40*00b67f09SDavid van Moolenbroek    if keyFound:
41*00b67f09SDavid van Moolenbroek        try:
42*00b67f09SDavid van Moolenbroek            (namedBase, _) = win32api.RegQueryValueEx(hKey, "InstallDir")
43*00b67f09SDavid van Moolenbroek        except:
44*00b67f09SDavid van Moolenbroek            keyFound = False
45*00b67f09SDavid van Moolenbroek        win32api.RegCloseKey(hKey)
46*00b67f09SDavid van Moolenbroek    if keyFound:
47*00b67f09SDavid van Moolenbroek        return os.path.join(namedBase, bindir)
48*00b67f09SDavid van Moolenbroek    return os.path.join(win32api.GetSystemDirectory(), bindir)
49*00b67f09SDavid van Moolenbroek
50*00b67f09SDavid van Moolenbroekdef shellquote(s):
51*00b67f09SDavid van Moolenbroek    if os.name == 'nt':
52*00b67f09SDavid van Moolenbroek        return '"' + s.replace('"', '"\\"') + '"'
53*00b67f09SDavid van Moolenbroek    return "'" + s.replace("'", "'\\''") + "'"
54*00b67f09SDavid van Moolenbroek
55*00b67f09SDavid van Moolenbroek############################################################################
56*00b67f09SDavid van Moolenbroek# DSRR class:
57*00b67f09SDavid van Moolenbroek# Delegation Signer (DS) resource record
58*00b67f09SDavid van Moolenbroek############################################################################
59*00b67f09SDavid van Moolenbroekclass DSRR:
60*00b67f09SDavid van Moolenbroek    hashalgs = {1: 'SHA-1', 2: 'SHA-256', 3: 'GOST', 4: 'SHA-384' }
61*00b67f09SDavid van Moolenbroek    rrname=''
62*00b67f09SDavid van Moolenbroek    rrclass='IN'
63*00b67f09SDavid van Moolenbroek    rrtype='DS'
64*00b67f09SDavid van Moolenbroek    keyid=None
65*00b67f09SDavid van Moolenbroek    keyalg=None
66*00b67f09SDavid van Moolenbroek    hashalg=None
67*00b67f09SDavid van Moolenbroek    digest=''
68*00b67f09SDavid van Moolenbroek    ttl=0
69*00b67f09SDavid van Moolenbroek
70*00b67f09SDavid van Moolenbroek    def __init__(self, rrtext):
71*00b67f09SDavid van Moolenbroek        if not rrtext:
72*00b67f09SDavid van Moolenbroek            return
73*00b67f09SDavid van Moolenbroek
74*00b67f09SDavid van Moolenbroek        fields = rrtext.split()
75*00b67f09SDavid van Moolenbroek        if len(fields) < 7:
76*00b67f09SDavid van Moolenbroek            return
77*00b67f09SDavid van Moolenbroek
78*00b67f09SDavid van Moolenbroek        self.rrname = fields[0].lower()
79*00b67f09SDavid van Moolenbroek        fields = fields[1:]
80*00b67f09SDavid van Moolenbroek        if fields[0].upper() in ['IN','CH','HS']:
81*00b67f09SDavid van Moolenbroek            self.rrclass = fields[0].upper()
82*00b67f09SDavid van Moolenbroek            fields = fields[1:]
83*00b67f09SDavid van Moolenbroek        else:
84*00b67f09SDavid van Moolenbroek            self.ttl = int(fields[0])
85*00b67f09SDavid van Moolenbroek            self.rrclass = fields[1].upper()
86*00b67f09SDavid van Moolenbroek            fields = fields[2:]
87*00b67f09SDavid van Moolenbroek
88*00b67f09SDavid van Moolenbroek        if fields[0].upper() != 'DS':
89*00b67f09SDavid van Moolenbroek            raise Exception
90*00b67f09SDavid van Moolenbroek
91*00b67f09SDavid van Moolenbroek        self.rrtype = 'DS'
92*00b67f09SDavid van Moolenbroek        self.keyid = int(fields[1])
93*00b67f09SDavid van Moolenbroek        self.keyalg = int(fields[2])
94*00b67f09SDavid van Moolenbroek        self.hashalg = int(fields[3])
95*00b67f09SDavid van Moolenbroek        self.digest = ''.join(fields[4:]).upper()
96*00b67f09SDavid van Moolenbroek
97*00b67f09SDavid van Moolenbroek    def __repr__(self):
98*00b67f09SDavid van Moolenbroek        return('%s %s %s %d %d %d %s' %
99*00b67f09SDavid van Moolenbroek                (self.rrname, self.rrclass, self.rrtype, self.keyid,
100*00b67f09SDavid van Moolenbroek                self.keyalg, self.hashalg, self.digest))
101*00b67f09SDavid van Moolenbroek
102*00b67f09SDavid van Moolenbroek    def __eq__(self, other):
103*00b67f09SDavid van Moolenbroek        return self.__repr__() == other.__repr__()
104*00b67f09SDavid van Moolenbroek
105*00b67f09SDavid van Moolenbroek############################################################################
106*00b67f09SDavid van Moolenbroek# DLVRR class:
107*00b67f09SDavid van Moolenbroek# DNSSEC Lookaside Validation (DLV) resource record
108*00b67f09SDavid van Moolenbroek############################################################################
109*00b67f09SDavid van Moolenbroekclass DLVRR:
110*00b67f09SDavid van Moolenbroek    hashalgs = {1: 'SHA-1', 2: 'SHA-256', 3: 'GOST', 4: 'SHA-384' }
111*00b67f09SDavid van Moolenbroek    parent=''
112*00b67f09SDavid van Moolenbroek    dlvname=''
113*00b67f09SDavid van Moolenbroek    rrname='IN'
114*00b67f09SDavid van Moolenbroek    rrclass='IN'
115*00b67f09SDavid van Moolenbroek    rrtype='DLV'
116*00b67f09SDavid van Moolenbroek    keyid=None
117*00b67f09SDavid van Moolenbroek    keyalg=None
118*00b67f09SDavid van Moolenbroek    hashalg=None
119*00b67f09SDavid van Moolenbroek    digest=''
120*00b67f09SDavid van Moolenbroek    ttl=0
121*00b67f09SDavid van Moolenbroek
122*00b67f09SDavid van Moolenbroek    def __init__(self, rrtext, dlvname):
123*00b67f09SDavid van Moolenbroek        if not rrtext:
124*00b67f09SDavid van Moolenbroek            return
125*00b67f09SDavid van Moolenbroek
126*00b67f09SDavid van Moolenbroek        fields = rrtext.split()
127*00b67f09SDavid van Moolenbroek        if len(fields) < 7:
128*00b67f09SDavid van Moolenbroek            return
129*00b67f09SDavid van Moolenbroek
130*00b67f09SDavid van Moolenbroek        self.dlvname = dlvname.lower()
131*00b67f09SDavid van Moolenbroek        parent = fields[0].lower().strip('.').split('.')
132*00b67f09SDavid van Moolenbroek        parent.reverse()
133*00b67f09SDavid van Moolenbroek        dlv = dlvname.split('.')
134*00b67f09SDavid van Moolenbroek        dlv.reverse()
135*00b67f09SDavid van Moolenbroek        while len(dlv) != 0 and len(parent) != 0 and parent[0] == dlv[0]:
136*00b67f09SDavid van Moolenbroek            parent = parent[1:]
137*00b67f09SDavid van Moolenbroek            dlv = dlv[1:]
138*00b67f09SDavid van Moolenbroek        if len(dlv) != 0:
139*00b67f09SDavid van Moolenbroek            raise Exception
140*00b67f09SDavid van Moolenbroek        parent.reverse()
141*00b67f09SDavid van Moolenbroek        self.parent = '.'.join(parent)
142*00b67f09SDavid van Moolenbroek        self.rrname = self.parent + '.' + self.dlvname + '.'
143*00b67f09SDavid van Moolenbroek
144*00b67f09SDavid van Moolenbroek        fields = fields[1:]
145*00b67f09SDavid van Moolenbroek        if fields[0].upper() in ['IN','CH','HS']:
146*00b67f09SDavid van Moolenbroek            self.rrclass = fields[0].upper()
147*00b67f09SDavid van Moolenbroek            fields = fields[1:]
148*00b67f09SDavid van Moolenbroek        else:
149*00b67f09SDavid van Moolenbroek            self.ttl = int(fields[0])
150*00b67f09SDavid van Moolenbroek            self.rrclass = fields[1].upper()
151*00b67f09SDavid van Moolenbroek            fields = fields[2:]
152*00b67f09SDavid van Moolenbroek
153*00b67f09SDavid van Moolenbroek        if fields[0].upper() != 'DLV':
154*00b67f09SDavid van Moolenbroek            raise Exception
155*00b67f09SDavid van Moolenbroek
156*00b67f09SDavid van Moolenbroek        self.rrtype = 'DLV'
157*00b67f09SDavid van Moolenbroek        self.keyid = int(fields[1])
158*00b67f09SDavid van Moolenbroek        self.keyalg = int(fields[2])
159*00b67f09SDavid van Moolenbroek        self.hashalg = int(fields[3])
160*00b67f09SDavid van Moolenbroek        self.digest = ''.join(fields[4:]).upper()
161*00b67f09SDavid van Moolenbroek
162*00b67f09SDavid van Moolenbroek    def __repr__(self):
163*00b67f09SDavid van Moolenbroek        return('%s %s %s %d %d %d %s' %
164*00b67f09SDavid van Moolenbroek                (self.rrname, self.rrclass, self.rrtype,
165*00b67f09SDavid van Moolenbroek                self.keyid, self.keyalg, self.hashalg, self.digest))
166*00b67f09SDavid van Moolenbroek
167*00b67f09SDavid van Moolenbroek    def __eq__(self, other):
168*00b67f09SDavid van Moolenbroek        return self.__repr__() == other.__repr__()
169*00b67f09SDavid van Moolenbroek
170*00b67f09SDavid van Moolenbroek############################################################################
171*00b67f09SDavid van Moolenbroek# checkds:
172*00b67f09SDavid van Moolenbroek# Fetch DS RRset for the given zone from the DNS; fetch DNSKEY
173*00b67f09SDavid van Moolenbroek# RRset from the masterfile if specified, or from DNS if not.
174*00b67f09SDavid van Moolenbroek# Generate a set of expected DS records from the DNSKEY RRset,
175*00b67f09SDavid van Moolenbroek# and report on congruency.
176*00b67f09SDavid van Moolenbroek############################################################################
177*00b67f09SDavid van Moolenbroekdef checkds(zone, masterfile = None):
178*00b67f09SDavid van Moolenbroek    dslist=[]
179*00b67f09SDavid van Moolenbroek    fp=os.popen("%s +noall +answer -t ds -q %s" %
180*00b67f09SDavid van Moolenbroek                (shellquote(args.dig), shellquote(zone)))
181*00b67f09SDavid van Moolenbroek    for line in fp:
182*00b67f09SDavid van Moolenbroek        dslist.append(DSRR(line))
183*00b67f09SDavid van Moolenbroek    dslist = sorted(dslist, key=lambda ds: (ds.keyid, ds.keyalg, ds.hashalg))
184*00b67f09SDavid van Moolenbroek    fp.close()
185*00b67f09SDavid van Moolenbroek
186*00b67f09SDavid van Moolenbroek    dsklist=[]
187*00b67f09SDavid van Moolenbroek
188*00b67f09SDavid van Moolenbroek    if masterfile:
189*00b67f09SDavid van Moolenbroek        fp = os.popen("%s -f %s %s " %
190*00b67f09SDavid van Moolenbroek                      (shellquote(args.dsfromkey), shellquote(masterfile),
191*00b67f09SDavid van Moolenbroek                       shellquote(zone)))
192*00b67f09SDavid van Moolenbroek    else:
193*00b67f09SDavid van Moolenbroek        fp = os.popen("%s +noall +answer -t dnskey -q %s | %s -f - %s" %
194*00b67f09SDavid van Moolenbroek                      (shellquote(args.dig), shellquote(zone),
195*00b67f09SDavid van Moolenbroek                       shellquote(args.dsfromkey), shellquote(zone)))
196*00b67f09SDavid van Moolenbroek
197*00b67f09SDavid van Moolenbroek    for line in fp:
198*00b67f09SDavid van Moolenbroek        dsklist.append(DSRR(line))
199*00b67f09SDavid van Moolenbroek
200*00b67f09SDavid van Moolenbroek    fp.close()
201*00b67f09SDavid van Moolenbroek
202*00b67f09SDavid van Moolenbroek    if (len(dsklist) < 1):
203*00b67f09SDavid van Moolenbroek        print ("No DNSKEY records found in zone apex")
204*00b67f09SDavid van Moolenbroek        return False
205*00b67f09SDavid van Moolenbroek
206*00b67f09SDavid van Moolenbroek    found = False
207*00b67f09SDavid van Moolenbroek    for ds in dsklist:
208*00b67f09SDavid van Moolenbroek        if ds in dslist:
209*00b67f09SDavid van Moolenbroek            print ("DS for KSK %s/%03d/%05d (%s) found in parent" %
210*00b67f09SDavid van Moolenbroek                   (ds.rrname.strip('.'), ds.keyalg,
211*00b67f09SDavid van Moolenbroek                    ds.keyid, DSRR.hashalgs[ds.hashalg]))
212*00b67f09SDavid van Moolenbroek            found = True
213*00b67f09SDavid van Moolenbroek        else:
214*00b67f09SDavid van Moolenbroek            print ("DS for KSK %s/%03d/%05d (%s) missing from parent" %
215*00b67f09SDavid van Moolenbroek                   (ds.rrname.strip('.'), ds.keyalg,
216*00b67f09SDavid van Moolenbroek                    ds.keyid, DSRR.hashalgs[ds.hashalg]))
217*00b67f09SDavid van Moolenbroek
218*00b67f09SDavid van Moolenbroek    if not found:
219*00b67f09SDavid van Moolenbroek        print ("No DS records were found for any DNSKEY")
220*00b67f09SDavid van Moolenbroek
221*00b67f09SDavid van Moolenbroek    return found
222*00b67f09SDavid van Moolenbroek
223*00b67f09SDavid van Moolenbroek############################################################################
224*00b67f09SDavid van Moolenbroek# checkdlv:
225*00b67f09SDavid van Moolenbroek# Fetch DLV RRset for the given zone from the DNS; fetch DNSKEY
226*00b67f09SDavid van Moolenbroek# RRset from the masterfile if specified, or from DNS if not.
227*00b67f09SDavid van Moolenbroek# Generate a set of expected DLV records from the DNSKEY RRset,
228*00b67f09SDavid van Moolenbroek# and report on congruency.
229*00b67f09SDavid van Moolenbroek############################################################################
230*00b67f09SDavid van Moolenbroekdef checkdlv(zone, lookaside, masterfile = None):
231*00b67f09SDavid van Moolenbroek    dlvlist=[]
232*00b67f09SDavid van Moolenbroek    fp=os.popen("%s +noall +answer -t dlv -q %s" %
233*00b67f09SDavid van Moolenbroek                (shellquote(args.dig), shellquote(zone + '.' + lookaside)))
234*00b67f09SDavid van Moolenbroek    for line in fp:
235*00b67f09SDavid van Moolenbroek        dlvlist.append(DLVRR(line, lookaside))
236*00b67f09SDavid van Moolenbroek    dlvlist = sorted(dlvlist,
237*00b67f09SDavid van Moolenbroek                     key=lambda dlv: (dlv.keyid, dlv.keyalg, dlv.hashalg))
238*00b67f09SDavid van Moolenbroek    fp.close()
239*00b67f09SDavid van Moolenbroek
240*00b67f09SDavid van Moolenbroek    #
241*00b67f09SDavid van Moolenbroek    # Fetch DNSKEY records from DNS and generate DLV records from them
242*00b67f09SDavid van Moolenbroek    #
243*00b67f09SDavid van Moolenbroek    dlvklist=[]
244*00b67f09SDavid van Moolenbroek    if masterfile:
245*00b67f09SDavid van Moolenbroek        fp = os.popen("%s -f %s -l %s %s " %
246*00b67f09SDavid van Moolenbroek                      (args.dsfromkey, masterfile, lookaside, zone))
247*00b67f09SDavid van Moolenbroek    else:
248*00b67f09SDavid van Moolenbroek        fp = os.popen("%s +noall +answer -t dnskey %s | %s -f - -l %s %s"
249*00b67f09SDavid van Moolenbroek                      % (shellquote(args.dig), shellquote(zone),
250*00b67f09SDavid van Moolenbroek                         shellquote(args.dsfromkey), shellquote(lookaside),
251*00b67f09SDavid van Moolenbroek                         shellquote(zone)))
252*00b67f09SDavid van Moolenbroek
253*00b67f09SDavid van Moolenbroek    for line in fp:
254*00b67f09SDavid van Moolenbroek        dlvklist.append(DLVRR(line, lookaside))
255*00b67f09SDavid van Moolenbroek
256*00b67f09SDavid van Moolenbroek    fp.close()
257*00b67f09SDavid van Moolenbroek
258*00b67f09SDavid van Moolenbroek    if (len(dlvklist) < 1):
259*00b67f09SDavid van Moolenbroek        print ("No DNSKEY records found in zone apex")
260*00b67f09SDavid van Moolenbroek        return False
261*00b67f09SDavid van Moolenbroek
262*00b67f09SDavid van Moolenbroek    found = False
263*00b67f09SDavid van Moolenbroek    for dlv in dlvklist:
264*00b67f09SDavid van Moolenbroek        if dlv in dlvlist:
265*00b67f09SDavid van Moolenbroek            print ("DLV for KSK %s/%03d/%05d (%s) found in %s" %
266*00b67f09SDavid van Moolenbroek                   (dlv.parent, dlv.keyalg, dlv.keyid,
267*00b67f09SDavid van Moolenbroek                    DLVRR.hashalgs[dlv.hashalg], dlv.dlvname))
268*00b67f09SDavid van Moolenbroek            found = True
269*00b67f09SDavid van Moolenbroek        else:
270*00b67f09SDavid van Moolenbroek            print ("DLV for KSK %s/%03d/%05d (%s) missing from %s" %
271*00b67f09SDavid van Moolenbroek                   (dlv.parent, dlv.keyalg, dlv.keyid,
272*00b67f09SDavid van Moolenbroek                    DLVRR.hashalgs[dlv.hashalg], dlv.dlvname))
273*00b67f09SDavid van Moolenbroek
274*00b67f09SDavid van Moolenbroek    if not found:
275*00b67f09SDavid van Moolenbroek        print ("No DLV records were found for any DNSKEY")
276*00b67f09SDavid van Moolenbroek
277*00b67f09SDavid van Moolenbroek    return found
278*00b67f09SDavid van Moolenbroek
279*00b67f09SDavid van Moolenbroek
280*00b67f09SDavid van Moolenbroek############################################################################
281*00b67f09SDavid van Moolenbroek# parse_args:
282*00b67f09SDavid van Moolenbroek# Read command line arguments, set global 'args' structure
283*00b67f09SDavid van Moolenbroek############################################################################
284*00b67f09SDavid van Moolenbroekdef parse_args():
285*00b67f09SDavid van Moolenbroek    global args
286*00b67f09SDavid van Moolenbroek    parser = argparse.ArgumentParser(description=prog + ': checks DS coverage')
287*00b67f09SDavid van Moolenbroek
288*00b67f09SDavid van Moolenbroek    bindir = 'bin'
289*00b67f09SDavid van Moolenbroek    if os.name == 'nt':
290*00b67f09SDavid van Moolenbroek        sbindir = 'bin'
291*00b67f09SDavid van Moolenbroek    else:
292*00b67f09SDavid van Moolenbroek        sbindir = 'sbin'
293*00b67f09SDavid van Moolenbroek
294*00b67f09SDavid van Moolenbroek    parser.add_argument('zone', type=str, help='zone to check')
295*00b67f09SDavid van Moolenbroek    parser.add_argument('-f', '--file', dest='masterfile', type=str,
296*00b67f09SDavid van Moolenbroek                        help='zone master file')
297*00b67f09SDavid van Moolenbroek    parser.add_argument('-l', '--lookaside', dest='lookaside', type=str,
298*00b67f09SDavid van Moolenbroek                        help='DLV lookaside zone')
299*00b67f09SDavid van Moolenbroek    parser.add_argument('-d', '--dig', dest='dig',
300*00b67f09SDavid van Moolenbroek                        default=os.path.join(prefix(bindir), 'dig'),
301*00b67f09SDavid van Moolenbroek                        type=str, help='path to \'dig\'')
302*00b67f09SDavid van Moolenbroek    parser.add_argument('-D', '--dsfromkey', dest='dsfromkey',
303*00b67f09SDavid van Moolenbroek                        default=os.path.join(prefix(sbindir),
304*00b67f09SDavid van Moolenbroek                                             'dnssec-dsfromkey'),
305*00b67f09SDavid van Moolenbroek                        type=str, help='path to \'dig\'')
306*00b67f09SDavid van Moolenbroek    parser.add_argument('-v', '--version', action='version', version='9.9.1')
307*00b67f09SDavid van Moolenbroek    args = parser.parse_args()
308*00b67f09SDavid van Moolenbroek
309*00b67f09SDavid van Moolenbroek    args.zone = args.zone.strip('.')
310*00b67f09SDavid van Moolenbroek    if args.lookaside:
311*00b67f09SDavid van Moolenbroek        lookaside = args.lookaside.strip('.')
312*00b67f09SDavid van Moolenbroek
313*00b67f09SDavid van Moolenbroek############################################################################
314*00b67f09SDavid van Moolenbroek# Main
315*00b67f09SDavid van Moolenbroek############################################################################
316*00b67f09SDavid van Moolenbroekdef main():
317*00b67f09SDavid van Moolenbroek    parse_args()
318*00b67f09SDavid van Moolenbroek
319*00b67f09SDavid van Moolenbroek    if args.lookaside:
320*00b67f09SDavid van Moolenbroek        found = checkdlv(args.zone, args.lookaside, args.masterfile)
321*00b67f09SDavid van Moolenbroek    else:
322*00b67f09SDavid van Moolenbroek        found = checkds(args.zone, args.masterfile)
323*00b67f09SDavid van Moolenbroek
324*00b67f09SDavid van Moolenbroek    exit(0 if found else 1)
325*00b67f09SDavid van Moolenbroek
326*00b67f09SDavid van Moolenbroekif __name__ == "__main__":
327*00b67f09SDavid van Moolenbroek    main()
328