/home/lnzliplg/public_html/isc.tar
eventlist.py000064400000013330151733004340007133 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

from collections import defaultdict
from .dnskey import *
from .keydict import *
from .keyevent import *


class eventlist:
    _K = defaultdict(lambda: defaultdict(list))
    _Z = defaultdict(lambda: defaultdict(list))
    _zones = set()
    _kdict = None

    def __init__(self, kdict):
        properties = ["SyncPublish", "Publish", "SyncDelete",
                      "Activate", "Inactive", "Delete"]
        self._kdict = kdict
        for zone in kdict.zones():
            self._zones.add(zone)
            for alg, keys in kdict[zone].items():
                for k in keys.values():
                    for prop in properties:
                        t = k.gettime(prop)
                        if not t:
                            continue
                        e = keyevent(prop, k, t)
                        if k.sep:
                            self._K[zone][alg].append(e)
                        else:
                            self._Z[zone][alg].append(e)

                self._K[zone][alg] = sorted(self._K[zone][alg],
                                            key=lambda event: event.when)
                self._Z[zone][alg] = sorted(self._Z[zone][alg],
                                            key=lambda event: event.when)

    # scan events per zone, algorithm, and key type, in order of
    # occurrence, noting inconsistent states when found
    def coverage(self, zone, keytype, until, output = None):
        def noop(*args, **kwargs): pass
        if not output:
            output = noop

        no_zsk = True if (keytype and keytype == "KSK") else False
        no_ksk = True if (keytype and keytype == "ZSK") else False
        kok = zok = True
        found = False

        if zone and not zone in self._zones:
            output("ERROR: No key events found for %s" % zone)
            return False

        if zone:
            found = True
            if not no_ksk:
                kok = self.checkzone(zone, "KSK", until, output)
            if not no_zsk:
                zok = self.checkzone(zone, "ZSK", until, output)
        else:
            for z in self._zones:
                if not no_ksk and z in self._K.keys():
                    found = True
                    kok = self.checkzone(z, "KSK", until, output)
                if not no_zsk and z in self._Z.keys():
                    found = True
                    zok = self.checkzone(z, "ZSK", until, output)

        if not found:
            output("ERROR: No key events found")
            return False

        return (kok and zok)

    def checkzone(self, zone, keytype, until, output):
        allok = True
        if keytype == "KSK":
            kz = self._K[zone]
        else:
            kz = self._Z[zone]

        for alg in kz.keys():
            output("Checking scheduled %s events for zone %s, "
                   "algorithm %s..." %
                   (keytype, zone, dnskey.algstr(alg)))
            ok = eventlist.checkset(kz[alg], keytype, until, output)
            if ok:
                output("No errors found")
            allok = allok and ok

        return allok

    @staticmethod
    def showset(eventset, output):
        if not eventset:
            return
        output("  " + eventset[0].showtime() + ":", skip=False)
        for event in eventset:
            output("    %s: %s" % (event.what, repr(event.key)), skip=False)

    @staticmethod
    def checkset(eventset, keytype, until, output):
        groups = list()
        group = list()

        # collect up all events that have the same time
        eventsfound = False
        for event in eventset:
            # we found an event
            eventsfound = True

            # add event to current group
            if (not group or group[0].when == event.when):
                group.append(event)

            # if we're at the end of the list, we're done.  if
            # we've found an event with a later time, start a new group
            if (group[0].when != event.when):
                groups.append(group)
                group = list()
                group.append(event)

        if group:
            groups.append(group)

        if not eventsfound:
            output("ERROR: No %s events found" % keytype)
            return False

        active = published = None
        for group in groups:
            if (until and calendar.timegm(group[0].when) > until):
                output("Ignoring events after %s" %
                      time.strftime("%a %b %d %H:%M:%S UTC %Y", 
                          time.gmtime(until)))
                return True

            for event in group:
                (active, published) = event.status(active, published)

            eventlist.showset(group, output)

            # and then check for inconsistencies:
            if not active:
                output("ERROR: No %s's are active after this event" % keytype)
                return False
            elif not published:
                output("ERROR: No %s's are published after this event"
                        % keytype)
                return False
            elif not published.intersection(active):
                output("ERROR: No %s's are both active and published "
                       "after this event" % keytype)
                return False

        return True

__pycache__/keyevent.cpython-36.opt-1.pyc000064400000003500151733004340014171 0ustar003

�!�i�@sddlZGdd�d�ZdS)�Nc@s4eZdZdZddd�Zdd�Zdd�Zdd	d
�ZdS)
�keyeventz� A discrete key event, e.g., Publish, Activate, Inactive, Delete,
    etc. Stores the date of the event, and identifying information
    about the key to which the event will occur.NcCs@||_|p|j|�|_||_|j|_|j|_|j|_|j|_dS)N)	�whatZgettime�when�key�sep�name�zone�alg�keyid)�selfrrr�r�/usr/lib/python3.6/keyevent.py�__init__szkeyevent.__init__cCs t|j|j|j|j|j|jf�S)N)�reprrrr
rrr	)rrrr
�__repr__ szkeyevent.__repr__cCstjd|j�S)Nz%a %b %d %H:%M:%S UTC %Y)�timeZstrftimer)rrrr
�showtime$szkeyevent.showtimecCs�dd�}|s|}|st�}|s$t�}|jdkr<|j|j�n�|jdkrT|j|j�n�|jdkr�|j|kr||dt|j��q�|j|j�nl|jdkr�|j|kr�|j|j�q�|dt|j��n6|jd	kr�|j|kr�|j|j�|j|kr�|j|j�||fS)
Nc_sdS)Nr)�args�kwargsrrr
�noop*szkeyevent.status.<locals>.noopZActivateZPublishZInactivez=	WARNING: %s scheduled to become inactive before it is activeZDeletez@WARNING: key %s is scheduled for deletion before it is publishedZRevoke)�setr�addr
rr�remove)rZactiveZ	published�outputrrrr
�status)s6








zkeyevent.status)N)N)�__name__�
__module__�__qualname__�__doc__rrrrrrrr
rs

	r)rrrrrr
�<module>s__pycache__/policy.cpython-36.opt-1.pyc000064400000046217151733004350013653 0ustar003

�!�i2g�@s:ddlZddljZddljZddlTddlmZGdd�d�ZGdd�d�ZGdd	�d	e	�Z
Gd
d�d�Zedk�r6ddl
Z
e
jd
dkr�ee
jd�Zej�Zej�ed
d�Zeje�nxe
jd
dk�r6y4ee
jdddd�Zeejd�eejd��Wn2e	k
�r4Zzeejd�WYddZ[XnXdS)�N)�*)�copyc
@s�eZdZd3Zed4ZiZdZdZdZdZ	dZ
dd�Zdd�Zd d!�Z
d"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2S)5�	PolicyLex�POLICY�ALGORITHM_POLICY�ZONE�	ALGORITHM�	DIRECTORY�KEYTTL�KEY_SIZE�ROLL_PERIOD�PRE_PUBLISH�POST_PUBLISH�COVERAGE�STANDBY�NONE�
DATESUFFIX�KEYTYPE�ALGNAME�STR�QSTRING�NUMBER�LBRACE�RBRACE�SEMIz 	z	(//|\#).*z\{z\}�;cCs|jj|jjd�7_dS)z\n+�
N)�lexer�lineno�value�count)�self�t�r#�/usr/lib/python3.6/policy.py�	t_newline7szPolicyLex.t_newlinecCs|jj|jjd�7_dS)z/\*(.|\n)*?\*/rN)rrrr )r!r"r#r#r$�	t_comment;szPolicyLex.t_commentcCstjd|j�jd�j�|_|S)z�(?i)(?<=[0-9 \t])(y(?:ears|ear|ea|e)?|mo(?:nths|nth|nt|n)?|w(?:eeks|eek|ee|e)?|d(?:ays|ay|a)?|h(?:ours|our|ou|o)?|mi(?:nutes|nute|nut|nu|n)?|s(?:econds|econd|econ|eco|ec|e)?)\bz(?i)(y|mo|w|d|h|mi|s)([a-z]*)�)�re�matchr�group�lower)r!r"r#r#r$�t_DATESUFFIX?szPolicyLex.t_DATESUFFIXcCs|jj�|_|S)z(?i)\b(KSK|ZSK)\b)r�upper)r!r"r#r#r$�	t_KEYTYPEDszPolicyLex.t_KEYTYPEcCs|jj�|_|S)z�(?i)\b(RSAMD5|DH|DSA|NSEC3DSA|ECC|RSASHA1|NSEC3RSASHA1|RSASHA256|RSASHA512|ECCGOST|ECDSAP256SHA256|ECDSAP384SHA384|ED25519|ED448)\b)rr-)r!r"r#r#r$�	t_ALGNAMEIszPolicyLex.t_ALGNAMEcCs|jj|jd�|_|S)z[A-Za-z._-][\w._-]*r)�reserved_map�getr�type)r!r"r#r#r$�t_STRNszPolicyLex.t_STRcCs&|jj|jd�|_|jdd�|_|S)z"([^"\n]|(\\"))*"rr'���)r0r1rr2)r!r"r#r#r$�	t_QSTRINGSszPolicyLex.t_QSTRINGcCst|j�|_|S)z\d+)�intr)r!r"r#r#r$�t_NUMBERYszPolicyLex.t_NUMBERcCs"td|jd�|jjd�dS)NzIllegal character '%s'rr')�printrr�skip)r!r"r#r#r$�t_error^szPolicyLex.t_errorcKsbdtt�krtjdd�}n
tdd�}x"|jD]}||j|j�j|�<q,Wtjfd|i|��|_dS)N�	maketrans�_�-�object)	�dir�strr;�reservedr0r+�	translate�lexr)r!�kwargsZtrans�rr#r#r$�__init__bs
zPolicyLex.__init__cCs.|jj|�x|jj�}|sPt|�qWdS)N)r�input�tokenr8)r!�textr"r#r#r$�testks
zPolicyLex.testN)
rrrrr	r
rrr
rrrr)	rrrrrrrrr)�__name__�
__module__�__qualname__rA�tokensr0Zt_ignoreZt_ignore_olcommentZt_LBRACEZt_RBRACEZt_SEMIr%r&r,r.r/r3r5r7r:rFrJr#r#r#r$rsN	rc
@s�eZdZdZdZdZdZdZdZdZ	dZ
dZdZdZ
dZdZdZdZdZddgddgddgddgddgddgddgdddddd�Zddd�Zd	d
�Zdd�Zd
d�Zdd�Zdd�ZdS)�PolicyFNiii)�DSA�NSEC3DSA�RSAMD5�RSASHA1�NSEC3RSASHA1�	RSASHA256�	RSASHA512�ECCGOST�ECDSAP256SHA256�ECDSAP384SHA384�ED25519�ED448cCs||_||_||_dS)N)�name�	algorithm�parent)r!r\r]r^r#r#r$rF�szPolicy.__init__cCsFd|jrdp"|jrdp"|jr dp"d|jp*d|jr8|jjp:d|jrRdt|j�dpTd|jp\d|jrlt|j�pnd|j	r~t|j	�p�d|j
r�t|j
�p�d|jr�t|j�p�d|jr�t|j�p�d|j
r�t|j
�p�d|jr�t|j�p�d|jr�t|j�p�d|jr�t|j�p�d|j�rt|j��pd|j�r(t|j��p*d|j�r>t|j��p@dfS)	Na%spolicy %s:
	inherits %s
	directory %s
	algorithm %s
	coverage %s
	ksk_keysize %s
	zsk_keysize %s
	ksk_rollperiod %s
	zsk_rollperiod %s
	ksk_prepublish %s
	ksk_postpublish %s
	zsk_prepublish %s
	zsk_postpublish %s
	ksk_standby %s
	zsk_standby %s
	keyttl %s
zconstructed zzone z
algorithm �ZUNKNOWN�None�")�is_constructed�is_zone�is_algr\r^�	directoryr@r]�coverage�ksk_keysize�zsk_keysize�ksk_rollperiod�zsk_rollperiod�ksk_prepublish�ksk_postpublish�zsk_prepublish�zsk_postpublish�ksk_standby�zsk_standby�keyttl)r!r#r#r$�__repr__�s(

zPolicy.__repr__cCs |d|ko|dkSS)Nrr'r#)r!Zkey_sizeZ
size_ranger#r#r$Z
__verify_size�szPolicy.__verify_sizecCs|jS)N)r\)r!r#r#r$�get_name�szPolicy.get_namecCs|jS)N)rb)r!r#r#r$�constructed�szPolicy.constructedcCs$|jr:|jdk	r:|j|jkr:t|j�dd|j|jffS|jrj|jdk	rj|j|jkrjdd|j|jffS|jr�|jdk	r�|j|jkr�dd|j|jffS|jr�|jdk	r�|j|jkr�dd|j|jffS|jo�|jo�|jo�|j|j|jk�rdd|j|j|jffS|j�rL|j�rL|j�rL|j|j|jk�rLdd|j|j|jffS|jdk	�r |jj	|j�}|dk	�r�|j
|j|��s�dd
|j|ffS|j
|j|��s�dd|j|ffS|jdk�r�|jddk�r�dd|jfS|jdk�r|jddk�rdd|jfS|jd k�r d|_d|_d!S)"zr Check if the values in the policy make sense
        :return: True/False if the policy passes validation
        NFz6KSK pre-publish period (%d) exceeds rollover period %dz7KSK post-publish period (%d) exceeds rollover period %dz6ZSK pre-publish period (%d) exceeds rollover period %dz7ZSK post-publish period (%d) exceeds rollover period %dz%KSK pre/post-publish periods (%d/%d) z"combined exceed rollover period %dz%ZSK pre/post-publish periods (%d/%d) z&KSK key size %d outside valid range %sz&ZSK key size %d outside valid range %srPrQ�@rz$KSK key size %d not divisible by 64 zas required for DSAz$ZSK key size %d not divisible by 64 rWrXrYrZr[Tr_zGKSK pre/post-publish periods (%d/%d) combined exceed rollover period %dzGZSK pre/post-publish periods (%d/%d) combined exceed rollover period %d)rPrQz7KSK key size %d not divisible by 64 as required for DSA)rPrQz7ZSK key size %d not divisible by 64 as required for DSA)rWrXrYrZr[)Tr_)
rirkr8rlrjrmrnr]�valid_key_sz_per_algor1�_Policy__verify_sizergrh)r!Zkey_sz_ranger#r#r$�validate�s�





zPolicy.validate)NNN)rKrLrMrcrdrbrirjrkrmrlrnrgrhrorprqrfrervrFrrrwrsrtrxr#r#r#r$rOvsD
&rOc@seZdZdS)�PolicyExceptionN)rKrLrMr#r#r#r$ry)sryc@s.eZdZiZiZiZdZdZdZdEdd�Z	dd�Z
dd�Zd	d
�Zdd�Z
d
d�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Z d3d4�Z!d5d6�Z"d7d8�Z#d9d:�Z$d;d<�Z%d=d>�Z&d?d@�Z'dAdB�Z(dCdD�Z)dS)F�
dnssec_policyNTcKs�t�|_|jj|_d|kr"d|d<d|kr2d|d<tjfd|i|��|_|jd�t�}d|_d|_d|_	d|_
t|�|jd<d|jd_d|jd_
d	|jd_	t|�|jd
<d
|jd
_d
|jd
_
d	|jd
_	t|�|jd<d|jd_d|jd_
t|�|jd<d|jd_d|jd_
t|�|jd
<d
|jd
_d
|jd
_
t|�|jd<d|jd_d|jd_
t|�|jd<d|jd_d|jd_
t|�|jd<d|jd_d|jd_
t|�|jd<d|jd_d|jd_
d|jd_	d|jd_
t|�|jd<d|jd_d|jd_
d|jd_	d|jd_
t|�|jd<d|jd_d|jd_
d|jd_	d|jd_
t|�|jd<d|jd_d|jd_
d|jd_	d|jd_
|�r�|j|�dS)N�debugF�write_tables�moduleapolicy global { algorithm rsasha256;
                                      key-size ksk 2048;
                                      key-size zsk 2048;
                                      roll-period ksk 0;
                                      roll-period zsk 1y;
                                      pre-publish ksk 1mo;
                                      pre-publish zsk 1mo;
                                      post-publish ksk 1mo;
                                      post-publish zsk 1mo;
                                      standby ksk 0;
                                      standby zsk 0;
                                      keyttl 1h;
                                      coverage 6mo; };
                      policy default { policy global; };TirPirQrRrSrTrUrVrWrXrYrZr[)r�plexrN�yacc�parser�setuprOr]rdrgrhr�
alg_policyr\�load)r!�filenamerD�pr#r#r$rF4s|

zdnssec_policy.__init__c	CsH||_d|_t|��$}|j�}d|jj_|jj|�WdQRXd|_dS)NTr)	r��initial�open�readr~rrr��parse)r!r��frIr#r#r$r��s

zdnssec_policy.loadcCs d|_d|jj_|jj|�dS)NTr)r�r~rrr�r�)r!rIr#r#r$r��s
zdnssec_policy.setupc	Ks`|j�}d}||jkr |j|}|dkrBt|jd�}||_d|_|jdkr�|jpZ|jd}x|rr|jrr|j}q^W|r~|jp�d|_|j|jkr�|j|j}nt	d��|j
dkr�|jp�|jd}x|dk	r�|j
r�|j}q�W|o�|j
|_
|jdk�r:|j�p|jd}x|�r"|j�r"|j}�qW|�r2|j�p6|j|_|jdk�r�|j�pV|jd}x|j�rv|j�rv|j}�qZW|�r�|j�p�|j|_|j
dk�r�|j�p�|jd}x|j�r�|j
�r�|j}�q�W|�r�|j
�p�|j
|_
|jdk�r6|j�p�|jd}x|j�r|j�r|j}�qW|�r.|j�p2|j|_|jdk�r�|j�pR|jd}x|j�rr|j�rr|j}�qVW|�r�|j�p�|j|_|jdk�r�|j�p�|jd}x|j�r�|j�r�|j}�q�W|�r�|j�p�|j|_|jdk�r2|j�p�|jd}x|j�r|j�r|j}�q�W|�r*|j�p.|j|_|jdk�r�|j�pN|jd}x|j�rn|j�rn|j}�qRW|�r~|j�p�|j|_|jdk�r�|j�p�|jd}x|j�r�|j�r�|j}�q�W|�r�|j�p�|j|_|jdk�r(|j�p�|jd}x |dk	�r|j�r|j}�q�W|�o$|j|_d|k�s>|d�r\|j�\}}|�s\t	|��dS|S)N�defaultTzalgorithm not foundZ
novalidate)r+�zone_policyr�named_policyr\rbr]r^r�ryrerfrgrhrirjrkrmrlrnrqrx)	r!ZzonerD�zr�r^ZapZvalid�msgr#r#r$�policy�s�





zdnssec_policy.policycCsdS)zBpolicylist : init policy
                      | policylist policyNr#)r!r�r#r#r$�p_policylist
szdnssec_policy.p_policylistcCs
d|_dS)zinit :FN)r�)r!r�r#r#r$�p_initszdnssec_policy.p_initcCsdS)zTpolicy : alg_policy
                  | zone_policy
                  | named_policyNr#)r!r�r#r#r$�p_policyszdnssec_policy.p_policycCs|d|d<dS)zAname : STR
                | KEYTYPE
                | DATESUFFIXr'rNr#)r!r�r#r#r$�p_nameszdnssec_policy.p_namecCs,|dj�|d<tjd|d�s(td��dS)zcdomain : STR
                  | QSTRING
                  | KEYTYPE
                  | DATESUFFIXr'rz^[\w.-][\w.-]*$zinvalid domainN)�stripr(r)ry)r!r�r#r#r$�p_domain szdnssec_policy.p_domaincCst�|_dS)znew_policy :N)rO�current)r!r�r#r#r$�p_new_policy*szdnssec_policy.p_new_policycCs(|d|j_d|j_|j|j|d<dS)zFalg_policy : ALGORITHM_POLICY ALGNAME new_policy alg_option_group SEMI�TN)r�r\rdr�)r!r�r#r#r$�p_alg_policy.szdnssec_policy.p_alg_policycCs8|djd�|j_d|j_|j|j|djd�j�<dS)z=zone_policy : ZONE domain new_policy policy_option_group SEMIr��.TN)�rstripr�r\rcr�r+)r!r�r#r#r$�
p_zone_policy5szdnssec_policy.p_zone_policycCs$|d|j_|j|j|dj�<dS)z>named_policy : POLICY name new_policy policy_option_group SEMIr�N)r�r\r�r+)r!r�r#r#r$�p_named_policy<szdnssec_policy.p_named_policycCs|d|d<dS)zduration : NUMBERr'rNr#)r!r�r#r#r$�p_duration_1Bszdnssec_policy.p_duration_1cCsd|d<dS)zduration : NONENrr#)r!r�r#r#r$�p_duration_2Gszdnssec_policy.p_duration_2cCs�|ddkr|dd|d<n�|ddkr<|dd|d<n�|ddkrZ|dd	|d<n||dd
krx|dd|d<n^|ddkr�|dd
|d<n@|ddkr�|dd|d<n"|ddkr�|d|d<ntd��dS)zduration : NUMBER DATESUFFIXr��yr'i�3�r�moi�'�wi�:	�di�Q�hiZmi�<�szinvalid durationN)ry)r!r�r#r#r$�p_duration_3Lszdnssec_policy.p_duration_3cCsdS)z6policy_option_group : LBRACE policy_option_list RBRACENr#)r!r�r#r#r$�p_policy_option_group_sz#dnssec_policy.p_policy_option_groupcCsdS)zmpolicy_option_list : policy_option SEMI
                              | policy_option_list policy_option SEMINr#)r!r�r#r#r$�p_policy_option_listcsz"dnssec_policy.p_policy_option_listcCsdS)a�policy_option : parent_option
                         | directory_option
                         | coverage_option
                         | rollperiod_option
                         | prepublish_option
                         | postpublish_option
                         | keysize_option
                         | algorithm_option
                         | keyttl_option
                         | standby_optionNr#)r!r�r#r#r$�p_policy_optionhszdnssec_policy.p_policy_optioncCsdS)z0alg_option_group : LBRACE alg_option_list RBRACENr#)r!r�r#r#r$�p_alg_option_groupusz dnssec_policy.p_alg_option_groupcCsdS)z^alg_option_list : alg_option SEMI
                           | alg_option_list alg_option SEMINr#)r!r�r#r#r$�p_alg_option_listyszdnssec_policy.p_alg_option_listcCsdS)aalg_option : coverage_option
                      | rollperiod_option
                      | prepublish_option
                      | postpublish_option
                      | keyttl_option
                      | keysize_option
                      | standby_optionNr#)r!r�r#r#r$�p_alg_option~szdnssec_policy.p_alg_optioncCs|j|dj�|j_dS)zparent_option : POLICY namer�N)r�r+r�r^)r!r�r#r#r$�p_parent_option�szdnssec_policy.p_parent_optioncCs|d|j_dS)z$directory_option : DIRECTORY QSTRINGr�N)r�re)r!r�r#r#r$�p_directory_option�sz dnssec_policy.p_directory_optioncCs|d|j_dS)z#coverage_option : COVERAGE durationr�N)r�rf)r!r�r#r#r$�p_coverage_option�szdnssec_policy.p_coverage_optioncCs*|ddkr|d|j_n|d|j_dS)z0rollperiod_option : ROLL_PERIOD KEYTYPE durationr��KSK�N)r�rirj)r!r�r#r#r$�p_rollperiod_option�sz!dnssec_policy.p_rollperiod_optioncCs*|ddkr|d|j_n|d|j_dS)z0prepublish_option : PRE_PUBLISH KEYTYPE durationr�r�r�N)r�rkrm)r!r�r#r#r$�p_prepublish_option�sz!dnssec_policy.p_prepublish_optioncCs*|ddkr|d|j_n|d|j_dS)z2postpublish_option : POST_PUBLISH KEYTYPE durationr�r�r�N)r�rlrn)r!r�r#r#r$�p_postpublish_option�sz"dnssec_policy.p_postpublish_optioncCs*|ddkr|d|j_n|d|j_dS)z(keysize_option : KEY_SIZE KEYTYPE NUMBERr�r�r�N)r�rgrh)r!r�r#r#r$�p_keysize_option�szdnssec_policy.p_keysize_optioncCs*|ddkr|d|j_n|d|j_dS)z'standby_option : STANDBY KEYTYPE NUMBERr�r�r�N)r�rorp)r!r�r#r#r$�p_standby_option�szdnssec_policy.p_standby_optioncCs|d|j_dS)zkeyttl_option : KEYTTL durationr�N)r�rq)r!r�r#r#r$�p_keyttl_option�szdnssec_policy.p_keyttl_optioncCs|d|j_dS)z$algorithm_option : ALGORITHM ALGNAMEr�N)r�r])r!r�r#r#r$�p_algorithm_option�sz dnssec_policy.p_algorithm_optioncCsd|r.td|jpd|jrdnd|j|jf�n2|js`td|jp@d|jrJdnd|rV|jpXdf��dS)Nz%s%s%d:syntax error near '%s'r_�:z%s%s%d:unexpected end of inputr)r8r�rrr�ry)r!r�r#r#r$�p_error�szdnssec_policy.p_error)N)*rKrLrMr�r�r�r�r�r�rFr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r#r#r#r$rz,sN
_
h


rz�__main__r'rCr�)r{r�T)r|r{r�znonexistent.zone)r(Zply.lexrCZply.yaccr�stringrrrO�	ExceptionryrzrK�sys�argvr��filer�rI�closer~rJZppr8r�r��e�argsr#r#r#r$�<module>s6

`4!

__pycache__/keydict.cpython-36.opt-1.pyc000064400000005013151733004350013775 0ustar003

�!�i!�@s:ddlmZddlmZddlZddlZGdd�d�ZdS)�)�defaultdict�)�dnskeyNc@sneZdZdZedd��ZdZgZddd�Zdd�Z	d	d
�Z
dd�Zd
d�Zdd�Z
dd�Zdd�Zdd�ZdS)�keydictz> A dictionary of keys, indexed by name, algorithm, and key id cCstt�S)N)r�dict�rr�/usr/lib/python3.6/keydict.py�<lambda>szkeydict.<lambda>NcKs�|jdd�|_|jdd�}|s:|jdd�p,d}|j|�nXxV|D]N}d|krb|ddk	rb|d}n|rr|j|�jptd}|j||�s@|jj|�q@WdS)NZkeyttl�zones�path�.)�get�_defttl�readallZpolicyZ	directory�readone�_missing�append)�selfZdp�kwargsr
r�zonerrr�__init__s

zkeydict.__init__cCsLtjtjj|d��}x2|D]*}t|||j�}||j|j|j|j	<qWdS)Nz	*.private)
�glob�osr�joinrr�_keydict�name�alg�keyid)rr�files�infile�keyrrrr,s
zkeydict.readallc	Cs�|jd�s|d7}d|d}tjtjj||��}d}xR|D]J}t|||j�}|j|krZq<|dkrh|jnd}||j	||j
|j<d}q<W|S)Nr�Kz
+*.privateFT)�endswithrrrrrr�fullnamerrrr)	rrr�matchr�foundrr Zkeynamerrrr3s


zkeydict.readoneccsJxD|jj�D]6\}}x,|j�D] \}}x|j�D]
}|Vq0WqWqWdS)N)r�items�values)rr�
algorithmsr�keysr rrr�__iter__Dszkeydict.__iter__cCs
|j|S)N)r)rrrrr�__getitem__Jszkeydict.__getitem__cCs
|jj�S)N)rr))rrrrr
Msz
keydict.zonescCs|j|j�S)N)rr))rrrrrr(Pszkeydict.algorithmscCs|j||j�S)N)rr))rrrrrrr)Sszkeydict.keyscCs|jS)N)r)rrrr�missingVszkeydict.missing)N)�__name__�
__module__�__qualname__�__doc__rrrrrrrr*r+r
r(r)r,rrrrrs
r)�collectionsr�rrrrrrrr�<module>s__pycache__/rndc.cpython-36.pyc000064400000012000151733004350012322 0ustar003

�!�i+�@sXddlmZddlZddlZddlZddlZddlZddlZddlZGdd�de	�Z
dS)�)�OrderedDictNc@sleZdZdZddddddd�Zd	d
�Zdd�Zddd�Zdd�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dS)�rndczRNDC protocol client library������)�md5Zsha1Zsha224Zsha256Zsha384Zsha512cCsb||_|j�}|jd�r$|dd�}||_tt|�|_tj|�|_	t
jdd�|_d|_
|j�dS)z�Creates a persistent connection to RNDC and logs in
        host - (ip, port) tuple
        algo - HMAC algorithm: one of md5, sha1, sha224, sha256, sha384, sha512
               (with optional prefix 'hmac-')
        secret - HMAC secret, base64 encodedzhmac-�Nr��i)�host�lower�
startswith�algo�getattr�hashlib�hlalgo�base64�	b64decode�secret�randomZrandint�ser�nonce�_rndc__connect_login)�selfrrr�r�/usr/lib/python3.6/rndc.py�__init__$s
z
rndc.__init__cCst|j|d�d�S)z�Call a RNDC command, all parsing is done on the server side
        cmd - a complete string with a command (eg 'reload zone example.com')
        )�type�_data)�dict�_rndc__command)r�cmdrrr�call5sz	rndc.callFcCst�}�x|j�D]�\}}|r(|dkr(q|tjdt|��|jd�7}t|�tkrt|tjddt|��|jd�7}qt|�tkr�|tjddt|��|7}qt|�tkr�|tjddt|��|7}qt|�t	kr�|j
|�}|tjddt|��|7}qtdt|���qW|S)N�_auth�B�asciiz>BIr�z#Cannot serialize element of type %s)�	bytearray�items�struct�pack�len�encoder �str�bytesr�_rndc__serialize_dict�NotImplementedError)r�data�ignore_auth�rv�k�vZsdrrrZ__serialize_dict;s""
zrndc.__serialize_dictc	Os,|jd7_ttj��}t||�}t�}t�|d<t�|d<t|j�|dd<t|�|dd<t|d�|dd<|jdk	r�|j|dd<||d	<|j|d
d�}tj|j	||j
�j�}tj
|�}|jdkr�tjd
|�|dd<n"ttjd|j|j|��|dd<|j|�}tjdt|�dd�|}|S)Nrr&�_ctrlZ_serZ_tim�<Z_exp�_noncer!T)r5r
Z22s�hmd5ZB88s�hshaz>II�)r�int�timerr0rr2�hmac�newrr�digestrZ	b64encoderr,r-r*�_rndc__algosr.)	r�args�kwargsZnowr4�d�msg�hash�bhashrrrZ__prep_messageOs,






zrndc.__prep_messagecCs�|jdk	r |dd|jkr dS|jdkr8|dd}n|dddd�}t|�tkrb|jd	�}|d
dt|�d7}tj|�}|j|dd
�}t	j
|j||j�j
�}||kS)Nr9r;Fr
r&r<r=rr(�=r>T)r5)rrr r1�decoder.rrr2rArBrrrC)rrHrJZremote_hashZmy_msgZmy_hashrrrZ__verify_msgjs


zrndc.__verify_msgc	Os�|j||�}|jj|�}|t|�kr,td��|jjd�}t|�dkrLtd��tjd|�\}}|dkrptd|��|d8}|jj|tj	�}t|�|kr�td��t
|�tkr�t|�}|j
|�}|j|�s�td	��|S)
NzCannot send the message�zCan't read response headerz>IIrzWrong message version %dr>zCan't read response datazAuthentication failure)�_rndc__prep_message�socket�sendr.�IOErrorZrecvr,�unpackr3ZMSG_WAITALLr r0r*�_rndc__parse_message�_rndc__verify_msg)	rrErFrHZsent�headerZlength�versionr4rrrZ	__commandys(

zrndc.__commandcCs2tj|j�|_d|_|jdd�}|dd|_dS)NZnull)r r9r;)rOZcreate_connectionrrr#)rrHrrrZ__connect_login�szrndc.__connect_logincCs�d}||}|d7}||||�jd�}||7}||}|d7}tjd|||d��d}|d7}||||�}||7}||d�}|dkr�|||fS|dkr�t�}	x(t|�dkr�|j|�\}
}}||	|
<q�W||	|fStd|��dS)Nrrr(z>Ir>r)zUnknown element type %d)rLr,rRrr.�_rndc__parse_elementr3)r�input�posZlabellen�labelr Zdatalenr4�restrGZilabel�valuerrrZ__parse_element�s*

zrndc.__parse_elementcCs8t�}d}x(t|�dkr2|j|�\}}}|||<qW|S)Nr)rr.rW)rrXr6ZhdatarZr\rrrZ__parse_message�szrndc.__parse_messageN)F)�__name__�
__module__�__qualname__�__doc__rDrr%r2rNrTr#rrWrSrrrrrs 
r)�collectionsrr@r,rrArrrO�objectrrrrr�<module>s__pycache__/dnskey.cpython-36.opt-1.pyc000064400000032530151733004350013642 0ustar003

�!�i @�@sJddlZddlZddlZddlmZmZGdd�de�ZGdd�d�ZdS)�N)�Popen�PIPEcseZdZ�fdd�Z�ZS)�TimePastcstt|�jd|||f�dS)Nz'%s time for key %s (%d) is already past)�superr�__init__)�self�key�prop�value)�	__class__��/usr/lib/python3.6/dnskey.pyrszTimePast.__init__)�__name__�
__module__�__qualname__r�
__classcell__rr)rr
rsrc@s�eZdZdZdqZdrZdsZdtd!d"�Zd#d$�Zd%d&�Z	e
dud'd(��Zd)d*�Ze
d+d,��Ze
d-d.��Zdvd/d0�Ze
d1d2��Ze
d3d4��Ze
d5d6��Ze
d7d8��Zd9d:�Zd;d<�Zd=d>�Zd?d@�ZdAdB�ZdCdD�Zej�fdEdF�ZdGdH�Zej�fdIdJ�ZdKdL�Zej�fdMdN�Z dOdP�Z!ej�fdQdR�Z"dSdT�Z#ej�fdUdV�Z$dWdX�Z%ej�fdYdZ�Z&d[d\�Z'ej�fd]d^�Z(d_d`�Z)dadb�Z*dcdd�Z+dedf�Z,dgdh�Z-didj�Z.dwdkdl�Z/dxdmdn�Z0e
dodp��Z1dS)y�dnskeyztAn individual DNSSEC key.  Identified by path, name, algorithm, keyid.
    Contains a dictionary of metadata events.�Created�Publish�Activate�Inactive�Delete�Revoke�	DSPublish�SyncPublish�
SyncDeleteN�-P�-A�-I�-D�-R�-Psync�-Dsync�RSAMD5�DH�DSA�ECC�RSASHA1�NSEC3DSA�NSEC3RSASHA1�	RSASHA256�	RSASHA512�ECCGOST�ECDSAP256SHA256�ECDSAP384SHA384�ED25519�ED448cCs�t|t�r:t|�dkr:|pd|_|\}}}|j||||�|pLtjj|�pLd|_tjj|�}|j	d�\}}}|dd�}t
|�}t
|j	d�d�}|j||||�dS)N��.�+�r���)�
isinstance�tuple�len�_dir�	fromtuple�os�path�dirname�basename�split�int)rrZ	directory�keyttl�name�alg�keyidrrr
r&s

zdnskey.__init__cs�|jd�r|}|jd�}n|d}d|||f}|j|jr@tjpBd|d}|j|jr^tjp`d|d}||_||_t|�|_t|�|_	||_
t|d�}	x�|	D]z��ddkr�q��j�}
|
s�q�|
d	j
�dkr�d
}||_nd}|s�t|
d	�n||_t|
|�d	@d	k�rd|_q�d|_q�W|	j�t|d�}t�|_t�|_t�|_t�|_t�|_t�|_t�|_d|_x�|D]���j����sv�ddk�r��qv�fdd�dD�t��g}
tdd�|
D��}�d|�j�}�|d�jd�j�}||j|<�qvWx�tjD]�}d|j|<||jk�rn|j|j|�}||j|<|j |�|j|<|j!|�|j|<|j||j|<n(d|j|<d|j|<d|j|<d|j|<�qW|j�dS)Nr2z
K%s+%03d+%05d�z.keyz.private�rr�;r4�in�ch�hsr1�TFZrUz!#csg|]}�j|��qSr)�find)�.0�c)�linerr
�
<listcomp>lsz$dnskey.fromtuple.<locals>.<listcomp>z:= cSsg|]}|dkr|�qS)r4r5r)rM�posrrr
rPms)rHrIrJ)"�endswith�rstripr9r;�sep�keystrrBr@rCrD�fullname�openr?�lower�ttl�close�dictZmetadata�_changed�_delete�_times�_fmttime�_timestamps�	_original�_origttl�stripr8�min�lstripr�_PROPS�	parsetime�
formattime�
epochfromtime)rrBrCrDrArVrUZkey_fileZprivate_fileZkfp�tokensZseptokenZpfpZpunctuation�foundr
r	�tr)rOr
r:5sv












zdnskey.fromtuplecKsr|jdd�}g}d}|jdk	r0|dt|j�g7}xlttjtj�D]Z\}}|s@|j|r\q@d}||j	krx|j	|rxd}|r�dn|j
|}	|||	g7}d}q@W|�rn|d|jg||jg}
|s�t
ddj|
��y0t|
ttd	�}|j�\}}
|
�rtt|
���Wn8tk
�r:}ztd
|t|�f��WYdd}~XnXd|_x*tjD] }|j||j|<d|j|<�qJWdS)N�quietFTz-LZnonez-Kz# � )�stdout�stderrzunable to run %s: %s)�getrb�strrY�ziprrf�_OPTSr\r]r_r9rU�print�joinrr�communicate�	Exceptionr`ra)rZsettime_bin�kwargsrm�cmd�firstr	�opt�deleteZwhenZfullcmd�prorp�errr
�commit�s<
"z
dnskey.commitcKsL|jdd�}|dd|dt|�g}
|r0|
d|g7}
|r>|
jd�|rN|
d|g7}
|rb|
d	t|�g7}
|	r�tj|	�}|
d
tj|�g7}
|
r�tj|
�}|
dtj|
�g7}
|
j|�|s�tdd
j|
��t|
t	t	d�}|j
�\}}|r�tdt|���y"|j�dj
d�}t|||�}|Stk
�rF}ztdt|���WYdd}~XnXdS)NrmFz-qz-Kz-Lz-rz-fkz-az-bz-Pz-Az# rn)rorpzunable to generate key: r�asciiz!unable to parse generated key: %s)rqrr�appendr�
timefromepochrhrurvrrrwrx�
splitlines�decode)�cls�
keygen_bin�	randomdevZkeys_dirrBrCZkeysizerTrY�publish�activateryrm�
keygen_cmdrlr~rorprU�newkeyrrrr
�generate�s:



zdnskey.generatec
Ks�|jdd�}|j�s td|��|dd|jd|jg}|jrL|dt|j�g7}|r\|d|g7}|rp|d	t|�g7}|s�td
dj|��t	|t
t
d�}|j�\}}	|	r�td
|	��y&|j�dj
d�}
t|
|j|j�}|Std|��YnXdS)NrmFz'predecessor key %s has no inactive datez-qz-Kz-Sz-Lz-rz-iz# rn)rorpzunable to generate key: rr�z'unable to generate successor for key %s)rq�inactiverxr9rUrYrrrurvrrrwr�r�r)rr�r�Z
prepublishryrmr�r~rorprUr�rrr
�generate_successor�s,zdnskey.generate_successorcCs0d}|tttj��kr tj|}|r(|Sd|S)Nz%03d)�ranger8r�	_ALGNAMES)rCrBrrr
�algstr�s
z
dnskey.algstrcCs6|sdS|j�}ytjj|�Stk
r0dSXdS)N)�upperrr��index�
ValueError)rCrrr
�algnum�sz
dnskey.algnumcCs|j|p|j�S)N)r�rC)rrCrrr
�algnameszdnskey.algnamecCs
tj|�S)N)�timeZgmtime)�secsrrr
r�szdnskey.timefromepochcCstj|d�S)Nz%Y%m%d%H%M%S)r�Zstrptime)�stringrrr
rgszdnskey.parsetimecCs
tj|�S)N)�calendarZtimegm)rlrrr
riszdnskey.epochfromtimecCstjd|�S)Nz%Y%m%d%H%M%S)r�Zstrftime)rlrrr
rhszdnskey.formattimecKs�|jdd�}|j||krdS|j|dk	rR|j||krR|rRt|||j|��|dkr�|j|dkrldnd|j|<d|j|<d|j|<d|j|<d|j|<dS|j|�}||j|<||j|<|j	|�|j|<|j||j|kr�dnd|j|<dS)N�forceFT)
rqr`rarr\r]r^r_r�rh)rr	r��nowryr�rlrrr
�setmetas$






zdnskey.setmetacCs
|j|S)N)r^)rr	rrr
�gettime2szdnskey.gettimecCs
|j|S)N)r_)rr	rrr
�
getfmttime5szdnskey.getfmttimecCs
|j|S)N)r`)rr	rrr
�gettimestamp8szdnskey.gettimestampcCs
|jdS)Nr)r`)rrrr
�created;szdnskey.createdcCs
|jdS)Nr)r`)rrrr
�syncpublish>szdnskey.syncpublishcKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�setsyncpublishAszdnskey.setsyncpublishcCs
|jdS)Nr)r`)rrrr
r�Dszdnskey.publishcKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�
setpublishGszdnskey.setpublishcCs
|jdS)Nr)r`)rrrr
r�Jszdnskey.activatecKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�setactivateMszdnskey.setactivatecCs
|jdS)Nr)r`)rrrr
�revokePsz
dnskey.revokecKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�	setrevokeSszdnskey.setrevokecCs
|jdS)Nr)r`)rrrr
r�Vszdnskey.inactivecKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�setinactiveYszdnskey.setinactivecCs
|jdS)Nr)r`)rrrr
r}\sz
dnskey.deletecKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�	setdelete_szdnskey.setdeletecCs
|jdS)Nr)r`)rrrr
�
syncdeletebszdnskey.syncdeletecKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�
setsyncdeleteeszdnskey.setsyncdeletecCsR|dks|j|krdS|jdkr0|j|_||_n|j|krHd|_||_n||_dS)N)rYrb)rrYrrr
�setttlhs

z
dnskey.setttlcCs|jr
dSdS)N�KSK�ZSK)rT)rrrr
�keytypetszdnskey.keytypecCsd|j|j�|jfS)Nz
%s/%s/%05d)rBr�rD)rrrr
�__str__wszdnskey.__str__cCs"d|j|j�|j|jrdndfS)Nz%s/%s/%05d (%s)r�r�)rBr�rDrT)rrrr
�__repr__{szdnskey.__repr__cCs|j�p|j�p|j�S)N)r�r�r�)rrrr
�date�szdnskey.datecCs@|j|jkr|j|jkS|j|jkr0|j|jkS|j�|j�kS)N)rBrCr�)r�otherrrr
�__lt__�s
z
dnskey.__lt__cCs�dd�}|s|}ttj��}|j�}|j�}|s4dS|sT||krP|dt|��dS||krh||krhdS||kr�|dt|�tj|j�p�df�dS||kr�|dt|��dS|jdk	r�|||jkr�|d	t|�tj|j�p�df�dSdS)
Nc_sdS)Nr)�argsryrrr
�noop�sz!dnskey.check_prepub.<locals>.noopFzFWARNING: Key %s is scheduled for
	 activation but not for publication.Tz�WARNING: %s is scheduled to be
	 published and activated at the same time. This
	 could result in a coverage gap if the zone was
	 previously signed. Activation should be at least
	 %s after publication.zone DNSKEY TTLz0WARNING: Key %s is active before it is publishedz�WARNING: Key %s is activated too soon
	 after publication; this could result in coverage 
	 gaps due to resolver caches containing old data.
	 Activation should be at least %s after
	 publication.)r@r�r�r��reprr�durationrY)r�outputr�r��ar~rrr
�check_prepub�s<zdnskey.check_prepubcCs�dd�}|dkr|}|dkr"|j}|dkr>|dt|��d}tj�}|j�}|j�}|s^dS|s~||krz|dt|��dS||kr�||kr�dS||kr�|d	t|��dS|||kr�|d
t|�tj|�f�dSdS)
Nc_sdS)Nr)r�ryrrr
r��sz"dnskey.check_postpub.<locals>.noopz"WARNING: Key %s using default TTL.�<�FzEWARNING: Key %s is scheduled for
	 deletion but not for inactivation.Tz@WARNING: Key %s is scheduled for
	 deletion before inactivation.z�WARNING: Key %s scheduled for
	 deletion too soon after deactivation; this may 
	 result in coverage gaps due to resolver caches
	 containing old data.  Deletion should be at least
	 %s after inactivation.ii�Q)rYr�r�r}r�rr�)rr�Ztimespanr�r��d�irrr
�
check_postpub�s:zdnskey.check_postpubcCsz|sdSddddddg}g}xR|D]J}||d||d}}|dkr"|jd
||d|dkrbdndf�q"Wdj|�S) N�yearr�r�im�month��day�hour�minute�secondr4rz%d %s%s�srEz, ii�Q�3�)r�r�ii�Q��')r�r�i�Q)r�r��)r�r�)r�r�)r�r4)r�rv)r�Zunitsr�Zunit�vrrr
r��s
(zdnskey.duration)	rrrrrrrrr)	Nrrrrr Nr!r")Nr#r$r%r&r'r(r)r*Nr+Nr,r-r.r/r0)NN)NN)N)N)NN)2rrr�__doc__rfrtr�rr:r��classmethodr�r��staticmethodr�r�r�r�rgrirhr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r}r�r�r�r�r�r�r�r�r�r�r�r�rrrr
rsb
M%* 


1
-r)	r;r�r��
subprocessrrrxrrrrrr
�<module>s
__pycache__/coverage.cpython-36.pyc000064400000014323151733004360013202 0ustar003

�!�i�&�@s�ddlmZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZdZddl
mZmZmZmZmZmZdd�Zdad	d
�Zdd�Zd
d�Zddd�Zdd�Zdd�ZdS)�)�print_functionN)�defaultdictzdnssec-coverage)�dnskey�	eventlist�keydict�keyevent�keyzone�utilscOst||�tjd�dS)N�)�print�sys�exit)�args�kwargs�r�/usr/lib/python3.6/coverage.py�fatals
rTcOsJd|kr|d}|jdd�nd}tr,dan|r8td�|rFt||�dS)zuoutput text, adding a vertical space this is *not* the first
    first section being printed since a call to vreset()�skipNTF�)�pop�
_firstliner)rrrrrr�output'srcCsdadS)zreset vertical spacingTN)rrrrr�vreset8srcCs�|j�}yt|�Stk
r$YnXtjd�}|j|�}|sJtd|��|j�\}}t|�}|j�}|jd�rx|dS|jd�r�|dS|jd�r�|dS|jd	�r�|d
S|jd�r�|dS|jd
�r�|dS|jd�r�|Std|��dS)z� convert a formatted time (e.g., 1y, 6mo, 15mi, etc) into seconds
    :param s: String with some text representing a time interval
    :return: Integer with the number of seconds in the time interval
    z([0-9][0-9]*)\s*([A-Za-z]*)zCannot parse %s�yi�3��moi�'�wi�:	�di�Q�hiZmi�<�szInvalid suffix %sN)	�strip�int�
ValueError�re�compile�match�groups�lower�
startswith)r�r�m�nZunitrrr�
parse_timeAs6








r,cCs�|}|s(tjj|�s(tj|tj�r�tjd}|s>tjj}xB|jtj�D]2}tjj	||�}tjj|�rztj|tj�rzPd}qLW|S)a1 find the location of a specified command.  if a default is supplied
    and it works, we use it; otherwise we search PATH for a match.
    :param command: string with a command to look for in the path
    :param default: default location to use
    :return: detected location for the desired command
    �PATHN)
�os�path�isfile�access�X_OK�environ�defpath�split�pathsep�join)Zcommand�defaultZfpathr/Z	directoryrrr�set_pathks$
r9c	0CsDtdtjjtjd�d��}tjtddd�}|j	dt
dddFd�|j	dd
dt
ddd�|j	ddt
ddd�|j	ddt
ddd�|j	ddt
ddd�|j	ddd t
d!dd�|j	d"d#|t
d$d
d�|j	d%d&t
d'd(dd)�|j	d*d+d,d-d.d/�|j	d0d1d,d-d2d/�|j	d3d4d5d,d-d6d/�|j	d7d8d9tjd:�|j�}|j
�rJ|j�rJtd;�n*|j
�sZ|j�rn|j
�rfd<nd=|_nd|_|j�r�t|j�d>k�r�td?�d@dA�|jD�|_y|j�r�t|j�}||_Wntk
�r�YnXy|j�r�t|j�}||_Wntk
�rYnXy|j�r(t|j�}||_Wntk
�r@YnXy<|j�r||j}t|j�}|dBk�rnd|_ntj�||_Wntk
�r�YnX|j�r�|j�r�|S|j�r*|j�r*y:t|jdB|j|j�}|j�p�|j|_|j�p�|j|_Wn4tk
�r(}ztdC|j|�WYdd}~XnX|j�s@tdD�dE|_|S)Gz8Read command line arguments, set global 'args' structureznamed-compilezoneZsbinz: checks future zDNSKEY coverage for a zone)�description�zone�*Nzzone(s) to checkz%(default: all zones in the directory))�type�nargsr8�helpz-Kr/�.z&a directory containing keys to process�dir)�destr8r=r?�metavarz-f�filenamezzone master file�file)rBr=r?rCz-m�maxttlzthe longest TTL in the zone(s)�timez-d�keyttlzthe DNSKEY TTLz-r�resignZ1944000z:the RRSIG refresh interval in seconds [default: 22.5 days]z-c�compilezonezpath to 'named-compilezone'z-l�
checklimit�0zDLength of time to check for DNSSEC coverage [default: 0 (unlimited)])rBr=r8r?rCz-z�no_ksk�
store_trueFz#Only check zone-signing keys (ZSKs))rB�actionr8r?z-k�no_zskz"Only check key-signing keys (KSKs)z-Dz--debugZ
debug_modezTurn on debugging outputz-vz	--version�version)rOrQz)ERROR: -z and -k cannot be used together.ZKSKZZSKr
z)ERROR: -f can only be used with one zone.cSs4g|],}t|�dkr,|ddkr,|dd�n|�qS)r
r@N���rR)�len)�.0�xrrr�
<listcomp>�szparse_args.<locals>.<listcomp>rz"Unable to load zone data from %s: z�WARNING: Maximum TTL value was not specified.  Using 1 week
	 (604800 seconds); re-run with the -m option to get more
	 accurate results.i�:	z5zone(s) to check(default: all zones in the directory)) r9r.r/r7r	�prefix�argparse�ArgumentParser�prog�add_argument�strrQ�
parse_argsrPrMr�keytyperDrSr;rFr,r"rHrIrKrGrrJ�	Exceptionrr)	rJ�parserrr*�kr)Zlimr;�errrr]�s�



















"r]c(Cspt�}td�yt|j|j|jd�}Wn2tk
rX}ztdt|��WYdd}~XnXx<|D]4}|j	t
�|jr�|jt
�q`|jt
|j
|j�q`Wt
d�t�yt|�}Wn2tk
r�}ztdt|��WYdd}~XnXd}|j�s|jd|j|jt
��sXd}nJxH|jD]>}y|j||j|jt
��s6d}Wnt
d|�YnX�qWtj|�rfd	nd
�dS)Nz;PHASE 1--Loading keys to check for internal timing problems)r/ZzonesrHz'ERROR: Unable to build key dictionary: z9PHASE 2--Scanning future key events for coverage failuresz#ERROR: Unable to build event list: FTz&ERROR: Coverage check failed for zone r
r)r]rrr/r;rHr_rr\Zcheck_prepubr�sepZ
check_postpubrFrIrrZcoverager^rKrr
)rZkdrb�keyZelist�errorsr;rrr�main�s:"

"
rf)N)Z
__future__rr.rrXZglobr#rGZcalendar�pprint�collectionsrrZZiscrrrrrr	rrrrr,r9r]rfrrrr�<module>s& 	*
x__pycache__/dnskey.cpython-36.pyc000064400000032530151733004360012704 0ustar003

�!�i @�@sJddlZddlZddlZddlmZmZGdd�de�ZGdd�d�ZdS)�N)�Popen�PIPEcseZdZ�fdd�Z�ZS)�TimePastcstt|�jd|||f�dS)Nz'%s time for key %s (%d) is already past)�superr�__init__)�self�key�prop�value)�	__class__��/usr/lib/python3.6/dnskey.pyrszTimePast.__init__)�__name__�
__module__�__qualname__r�
__classcell__rr)rr
rsrc@s�eZdZdZdqZdrZdsZdtd!d"�Zd#d$�Zd%d&�Z	e
dud'd(��Zd)d*�Ze
d+d,��Ze
d-d.��Zdvd/d0�Ze
d1d2��Ze
d3d4��Ze
d5d6��Ze
d7d8��Zd9d:�Zd;d<�Zd=d>�Zd?d@�ZdAdB�ZdCdD�Zej�fdEdF�ZdGdH�Zej�fdIdJ�ZdKdL�Zej�fdMdN�Z dOdP�Z!ej�fdQdR�Z"dSdT�Z#ej�fdUdV�Z$dWdX�Z%ej�fdYdZ�Z&d[d\�Z'ej�fd]d^�Z(d_d`�Z)dadb�Z*dcdd�Z+dedf�Z,dgdh�Z-didj�Z.dwdkdl�Z/dxdmdn�Z0e
dodp��Z1dS)y�dnskeyztAn individual DNSSEC key.  Identified by path, name, algorithm, keyid.
    Contains a dictionary of metadata events.�Created�Publish�Activate�Inactive�Delete�Revoke�	DSPublish�SyncPublish�
SyncDeleteN�-P�-A�-I�-D�-R�-Psync�-Dsync�RSAMD5�DH�DSA�ECC�RSASHA1�NSEC3DSA�NSEC3RSASHA1�	RSASHA256�	RSASHA512�ECCGOST�ECDSAP256SHA256�ECDSAP384SHA384�ED25519�ED448cCs�t|t�r:t|�dkr:|pd|_|\}}}|j||||�|pLtjj|�pLd|_tjj|�}|j	d�\}}}|dd�}t
|�}t
|j	d�d�}|j||||�dS)N��.�+�r���)�
isinstance�tuple�len�_dir�	fromtuple�os�path�dirname�basename�split�int)rrZ	directory�keyttl�name�alg�keyidrrr
r&s

zdnskey.__init__cs�|jd�r|}|jd�}n|d}d|||f}|j|jr@tjpBd|d}|j|jr^tjp`d|d}||_||_t|�|_t|�|_	||_
t|d�}	x�|	D]z��ddkr�q��j�}
|
s�q�|
d	j
�dkr�d
}||_nd}|s�t|
d	�n||_t|
|�d	@d	k�rd|_q�d|_q�W|	j�t|d�}t�|_t�|_t�|_t�|_t�|_t�|_t�|_d|_x�|D]���j����sv�ddk�r��qv�fdd�dD�t��g}
tdd�|
D��}�d|�j�}�|d�jd�j�}||j|<�qvWx�tjD]�}d|j|<||jk�rn|j|j|�}||j|<|j |�|j|<|j!|�|j|<|j||j|<n(d|j|<d|j|<d|j|<d|j|<�qW|j�dS)Nr2z
K%s+%03d+%05d�z.keyz.private�rr�;r4�in�ch�hsr1�TFZrUz!#csg|]}�j|��qSr)�find)�.0�c)�linerr
�
<listcomp>lsz$dnskey.fromtuple.<locals>.<listcomp>z:= cSsg|]}|dkr|�qS)r4r5r)rM�posrrr
rPms)rHrIrJ)"�endswith�rstripr9r;�sep�keystrrBr@rCrD�fullname�openr?�lower�ttl�close�dictZmetadata�_changed�_delete�_times�_fmttime�_timestamps�	_original�_origttl�stripr8�min�lstripr�_PROPS�	parsetime�
formattime�
epochfromtime)rrBrCrDrArVrUZkey_fileZprivate_fileZkfp�tokensZseptokenZpfpZpunctuation�foundr
r	�tr)rOr
r:5sv












zdnskey.fromtuplecKsr|jdd�}g}d}|jdk	r0|dt|j�g7}xlttjtj�D]Z\}}|s@|j|r\q@d}||j	krx|j	|rxd}|r�dn|j
|}	|||	g7}d}q@W|�rn|d|jg||jg}
|s�t
ddj|
��y0t|
ttd	�}|j�\}}
|
�rtt|
���Wn8tk
�r:}ztd
|t|�f��WYdd}~XnXd|_x*tjD] }|j||j|<d|j|<�qJWdS)N�quietFTz-LZnonez-Kz# � )�stdout�stderrzunable to run %s: %s)�getrb�strrY�ziprrf�_OPTSr\r]r_r9rU�print�joinrr�communicate�	Exceptionr`ra)rZsettime_bin�kwargsrm�cmd�firstr	�opt�deleteZwhenZfullcmd�prorp�errr
�commit�s<
"z
dnskey.commitcKsL|jdd�}|dd|dt|�g}
|r0|
d|g7}
|r>|
jd�|rN|
d|g7}
|rb|
d	t|�g7}
|	r�tj|	�}|
d
tj|�g7}
|
r�tj|
�}|
dtj|
�g7}
|
j|�|s�tdd
j|
��t|
t	t	d�}|j
�\}}|r�tdt|���y"|j�dj
d�}t|||�}|Stk
�rF}ztdt|���WYdd}~XnXdS)NrmFz-qz-Kz-Lz-rz-fkz-az-bz-Pz-Az# rn)rorpzunable to generate key: r�asciiz!unable to parse generated key: %s)rqrr�appendr�
timefromepochrhrurvrrrwrx�
splitlines�decode)�cls�
keygen_bin�	randomdevZkeys_dirrBrCZkeysizerTrY�publish�activateryrm�
keygen_cmdrlr~rorprU�newkeyrrrr
�generate�s:



zdnskey.generatec
Ks�|jdd�}|j�s td|��|dd|jd|jg}|jrL|dt|j�g7}|r\|d|g7}|rp|d	t|�g7}|s�td
dj|��t	|t
t
d�}|j�\}}	|	r�td
|	��y&|j�dj
d�}
t|
|j|j�}|Std|��YnXdS)NrmFz'predecessor key %s has no inactive datez-qz-Kz-Sz-Lz-rz-iz# rn)rorpzunable to generate key: rr�z'unable to generate successor for key %s)rq�inactiverxr9rUrYrrrurvrrrwr�r�r)rr�r�Z
prepublishryrmr�r~rorprUr�rrr
�generate_successor�s,zdnskey.generate_successorcCs0d}|tttj��kr tj|}|r(|Sd|S)Nz%03d)�ranger8r�	_ALGNAMES)rCrBrrr
�algstr�s
z
dnskey.algstrcCs6|sdS|j�}ytjj|�Stk
r0dSXdS)N)�upperrr��index�
ValueError)rCrrr
�algnum�sz
dnskey.algnumcCs|j|p|j�S)N)r�rC)rrCrrr
�algnameszdnskey.algnamecCs
tj|�S)N)�timeZgmtime)�secsrrr
r�szdnskey.timefromepochcCstj|d�S)Nz%Y%m%d%H%M%S)r�Zstrptime)�stringrrr
rgszdnskey.parsetimecCs
tj|�S)N)�calendarZtimegm)rlrrr
riszdnskey.epochfromtimecCstjd|�S)Nz%Y%m%d%H%M%S)r�Zstrftime)rlrrr
rhszdnskey.formattimecKs�|jdd�}|j||krdS|j|dk	rR|j||krR|rRt|||j|��|dkr�|j|dkrldnd|j|<d|j|<d|j|<d|j|<d|j|<dS|j|�}||j|<||j|<|j	|�|j|<|j||j|kr�dnd|j|<dS)N�forceFT)
rqr`rarr\r]r^r_r�rh)rr	r��nowryr�rlrrr
�setmetas$






zdnskey.setmetacCs
|j|S)N)r^)rr	rrr
�gettime2szdnskey.gettimecCs
|j|S)N)r_)rr	rrr
�
getfmttime5szdnskey.getfmttimecCs
|j|S)N)r`)rr	rrr
�gettimestamp8szdnskey.gettimestampcCs
|jdS)Nr)r`)rrrr
�created;szdnskey.createdcCs
|jdS)Nr)r`)rrrr
�syncpublish>szdnskey.syncpublishcKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�setsyncpublishAszdnskey.setsyncpublishcCs
|jdS)Nr)r`)rrrr
r�Dszdnskey.publishcKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�
setpublishGszdnskey.setpublishcCs
|jdS)Nr)r`)rrrr
r�Jszdnskey.activatecKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�setactivateMszdnskey.setactivatecCs
|jdS)Nr)r`)rrrr
�revokePsz
dnskey.revokecKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�	setrevokeSszdnskey.setrevokecCs
|jdS)Nr)r`)rrrr
r�Vszdnskey.inactivecKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�setinactiveYszdnskey.setinactivecCs
|jdS)Nr)r`)rrrr
r}\sz
dnskey.deletecKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�	setdelete_szdnskey.setdeletecCs
|jdS)Nr)r`)rrrr
�
syncdeletebszdnskey.syncdeletecKs|jd||f|�dS)Nr)r�)rr�r�ryrrr
�
setsyncdeleteeszdnskey.setsyncdeletecCsR|dks|j|krdS|jdkr0|j|_||_n|j|krHd|_||_n||_dS)N)rYrb)rrYrrr
�setttlhs

z
dnskey.setttlcCs|jr
dSdS)N�KSK�ZSK)rT)rrrr
�keytypetszdnskey.keytypecCsd|j|j�|jfS)Nz
%s/%s/%05d)rBr�rD)rrrr
�__str__wszdnskey.__str__cCs"d|j|j�|j|jrdndfS)Nz%s/%s/%05d (%s)r�r�)rBr�rDrT)rrrr
�__repr__{szdnskey.__repr__cCs|j�p|j�p|j�S)N)r�r�r�)rrrr
�date�szdnskey.datecCs@|j|jkr|j|jkS|j|jkr0|j|jkS|j�|j�kS)N)rBrCr�)r�otherrrr
�__lt__�s
z
dnskey.__lt__cCs�dd�}|s|}ttj��}|j�}|j�}|s4dS|sT||krP|dt|��dS||krh||krhdS||kr�|dt|�tj|j�p�df�dS||kr�|dt|��dS|jdk	r�|||jkr�|d	t|�tj|j�p�df�dSdS)
Nc_sdS)Nr)�argsryrrr
�noop�sz!dnskey.check_prepub.<locals>.noopFzFWARNING: Key %s is scheduled for
	 activation but not for publication.Tz�WARNING: %s is scheduled to be
	 published and activated at the same time. This
	 could result in a coverage gap if the zone was
	 previously signed. Activation should be at least
	 %s after publication.zone DNSKEY TTLz0WARNING: Key %s is active before it is publishedz�WARNING: Key %s is activated too soon
	 after publication; this could result in coverage 
	 gaps due to resolver caches containing old data.
	 Activation should be at least %s after
	 publication.)r@r�r�r��reprr�durationrY)r�outputr�r��ar~rrr
�check_prepub�s<zdnskey.check_prepubcCs�dd�}|dkr|}|dkr"|j}|dkr>|dt|��d}tj�}|j�}|j�}|s^dS|s~||krz|dt|��dS||kr�||kr�dS||kr�|d	t|��dS|||kr�|d
t|�tj|�f�dSdS)
Nc_sdS)Nr)r�ryrrr
r��sz"dnskey.check_postpub.<locals>.noopz"WARNING: Key %s using default TTL.�<�FzEWARNING: Key %s is scheduled for
	 deletion but not for inactivation.Tz@WARNING: Key %s is scheduled for
	 deletion before inactivation.z�WARNING: Key %s scheduled for
	 deletion too soon after deactivation; this may 
	 result in coverage gaps due to resolver caches
	 containing old data.  Deletion should be at least
	 %s after inactivation.ii�Q)rYr�r�r}r�rr�)rr�Ztimespanr�r��d�irrr
�
check_postpub�s:zdnskey.check_postpubcCsz|sdSddddddg}g}xR|D]J}||d||d}}|dkr"|jd
||d|dkrbdndf�q"Wdj|�S) N�yearr�r�im�month��day�hour�minute�secondr4rz%d %s%s�srEz, ii�Q�3�)r�r�ii�Q��')r�r�i�Q)r�r��)r�r�)r�r�)r�r4)r�rv)r�Zunitsr�Zunit�vrrr
r��s
(zdnskey.duration)	rrrrrrrrr)	Nrrrrr Nr!r")Nr#r$r%r&r'r(r)r*Nr+Nr,r-r.r/r0)NN)NN)N)N)NN)2rrr�__doc__rfrtr�rr:r��classmethodr�r��staticmethodr�r�r�r�rgrirhr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r}r�r�r�r�r�r�r�r�r�r�r�r�rrrr
rsb
M%* 


1
-r)	r;r�r��
subprocessrrrxrrrrrr
�<module>s
__pycache__/keyseries.cpython-36.pyc000064400000010705151733004370013413 0ustar003

�!�i"�@sFddlmZddlTddlTddlTddlTddlZGdd�d�ZdS)�)�defaultdict�)�*Nc@sleZdZedd��Zedd��Ze�ZdZdZ	e
j
�dfdd�Zdd�Zd	d
�Z
dd�Ze
j
�fd
d�ZdS)�	keyseriescCstt�S)N)r�list�rr�/usr/lib/python3.6/keyseries.py�<lambda>szkeyseries.<lambda>cCstt�S)N)rrrrrrr	sNcCs�||_||_t|j��|_x�|j�D]�}|jj|�x�||j�D]�\}}xh|j�D]\}|j	r�|j
�op|j
�|ks�|j||j|�qT|j
�o�|j
�|ksT|j
||j|�qTW|j||j�|j
||j�qBWq$WdS)N)�_kdict�_context�setZmissing�_zones�zones�add�items�values�sep�delete�_K�append�_Z�sort)�selfZkdict�now�context�zone�alg�keys�krrr�__init__szkeyseries.__init__ccsbx\|jD]R}xL|j|jgD]<}||kr(qx,||j�D]\}}x|D]
}|VqDWq6WqWqWdS)N)r
rrr)rr�
collectionrr�keyrrr�__iter__.s
zkeyseries.__iter__cCs"x|D]}tdt|��qWdS)Nz%s)�print�repr)rrrrr�dump7s
zkeyseries.dumpcKs�|jdd�}|sdS|d}|jr>|j}|jp0d}|jp:d}	n|j}|jpLd
}|jpVd}	|j�}
|j	�}|
sv|
|kr�|j
|�|}
|s�||kr�|j|�|}|j�}d}
|s�|j
d|�|jd|��n�|s�|||k�r|�r(|||||
k�r(|j
||f|�|j|||	f|�n�|�s`|j
|||
f|�|j|||	|
f|�n�||k�rln�|||k�r�|j
||f|�|j|||	f|�np|||||
k�r�|j
||f|�|j|||	f|�n0|j
|||
f|�|j|||	|
f|�n�|j�}|�s8||	||
k�rL|j||	f|�nN|�sj|j||	|
f|�n0|||
k�rzn |||	k�r�|j||	f|�|j|jk�r�|j|j�|}x�|dd�D]�}|�s|j
d|�|jd|�|j
d|�|jd|�|j|jk�r�|j|j��q�|j�}||}
|j|f|�|j
|
f|�|j
||f|�|j|||	f|�|j||	f|�|j|jk�r�|j|j�|}�q�Wx�|�r>|j��r>|j�||jk�r>|j|jdf|�|j|jd	|jd
|f|�}|j
|j	�|f|�|j|j�|	f|�|j|�|}�q�W|j
d|�|jd|�x"|D]}|j|jdf|��q^WdS)N�forceFr�i�Qi,rZsettime_path�keygen_path�	randomdevi�'i�'i�'i�')N)N)N)N)N)N)N)N)�getrZksk_rollperiodZksk_prepublishZksk_postpublishZzsk_rollperiodZzsk_prepublishZzsk_postpublishZpublishZactivateZ
setpublishZsetactivateZinactiveZsetinactiveZ	setdeleter�keyttlZttlZsetttlZcoverageZcommitrZgenerate_successorr)rr�policyr�kwargsr&r!ZrpZprepubZpostpub�p�a�iZfudge�d�prevrrr�	fixseries;s�










zkeyseries.fixseriescKs�|jd|j�}|jd|jjdd��}|jdd�}�x�|D�]�}g}|j|�}	|pX|	jpXd}|	j}
tj|
�}d|ks||dr�t|j	||�dkr�tj
|jd	|jd
|||
|	jd|	jp�df|�}|j	||j
|�|j
|j	|�d|ks�|d�rht|j||�dk�rXtj
|jd	|jd
|||
|	jd
|	j�p<df|�}|j||j
|�|j
|j|�x�|D]�}
x||
j�D]p\}}||k�r��q|y|j||	|f|�Wn@tk
�r�}z"td|tj|�t|�f��WYdd}~XnX�q|W�qnWq8WdS)Nr�dirZ	keys_pathr&F�.Zkskrr(r)iZzskTz	%s/%s: %s)r*r
rr,Z	directory�	algorithm�dnskey�algnum�lenrZgenerateZzsk_keysizer+rrZksk_keysizerr3�	ExceptionZalgstr�str)rZpoliciesrr-rZkeys_dirr&r�collectionsr,rr8rr r6r�errr�enforce_policy�sL




zkeyseries.enforce_policy)�__name__�
__module__�__qualname__rrrrr
r
r�timerr"r%r3r>rrrrrs	vr)r<rr7ZkeydictZkeyeventr,rBrrrrr�<module>s__pycache__/eventlist.cpython-36.pyc000064400000007327151733004370013433 0ustar003

�!�i��@s6ddlmZddlTddlTddlTGdd�d�ZdS)�)�defaultdict�)�*c@s`eZdZedd��Zedd��Ze�ZdZdd�Z	ddd�Z
d	d
�Zedd��Z
ed
d��ZdS)�	eventlistcCstt�S)N)r�list�rr�/usr/lib/python3.6/eventlist.py�<lambda>szeventlist.<lambda>cCstt�S)N)rrrrrrr	sNc
Csddddddg}||_x�|j�D]�}|jj|�x�||j�D]�\}}xj|j�D]^}xX|D]P}|j|�}|snqZt|||�}	|jr�|j	||j
|	�qZ|j||j
|	�qZWqPWt|j	||dd�d	�|j	||<t|j||d
d�d	�|j||<q>Wq WdS)NZSyncPublishZPublishZ
SyncDeleteZActivateZInactiveZDeletecSs|jS)N)�when)�eventrrrr	+sz$eventlist.__init__.<locals>.<lambda>)�keycSs|jS)N)r
)rrrrr	-s)
�_kdictZzones�_zones�add�items�valuesZgettime�keyevent�sep�_K�append�_Z�sorted)
�selfZkdictZ
properties�zone�alg�keys�kZprop�t�errr�__init__s&


zeventlist.__init__cCsdd�}|s|}|r |dkr dnd}|r4|dkr4dnd}d}}	d}
|rb||jkrb|d|�dS|r�d}
|s~|j|d||�}|s�|j|d||�}	n`x^|jD]T}|r�||jj�kr�d}
|j|d||�}|r�||jj�kr�d}
|j|d||�}	q�W|
�s|d�dS|�o|	S)	Nc_sdS)Nr)�args�kwargsrrr�noop2sz eventlist.coverage.<locals>.noop�KSKTFZZSKz!ERROR: No key events found for %szERROR: No key events found)r�	checkzonerrr)rr�keytype�until�outputr"Zno_zskZno_kskZkokZzok�found�zrrr�coverage1s6zeventlist.coveragec	Csxd}|dkr|j|}n
|j|}xP|j�D]D}|d||tj|�f�tj|||||�}|rh|d�|on|}q,W|S)NTr#z9Checking scheduled %s events for zone %s, algorithm %s...zNo errors found)rrr�dnskeyZalgstrr�checkset)	rrr%r&r'ZallokZkzr�okrrrr$Ts
zeventlist.checkzonecCsR|sdS|d|dj�ddd�x(|D] }|d|jt|j�fdd�q*WdS)Nz  r�:F)�skipz
    %s: %s)ZshowtimeZwhat�reprr)�eventsetr'rrrr�showsetfs

zeventlist.showsetc
CsNt�}t�}d}xZ|D]R}d}|s4|dj|jkr>|j|�|dj|jkr|j|�t�}|j|�qW|rz|j|�|s�|d|�dSd}}	x�|D]�}|r�tj|dj�|kr�|dtjdtj|���dSx|D]}|j||	�\}}	q�Wt	j
||�|�s|d|�dS|	�s,|d|�dS|	j|�s�|d	|�dSq�WdS)
NFTrzERROR: No %s events foundzIgnoring events after %sz%a %b %d %H:%M:%S UTC %Yz*ERROR: No %s's are active after this eventz-ERROR: No %s's are published after this eventz=ERROR: No %s's are both active and published after this event)rr
rZcalendarZtimegmZtimeZstrftimeZgmtimeZstatusrr2�intersection)
r1r%r&r'�groups�groupZeventsfoundrZactiveZ	publishedrrrr,nsL






zeventlist.checkset)N)�__name__�
__module__�__qualname__rrr�setrr
rr*r$�staticmethodr2r,rrrrrs
#rN)�collectionsrr+Zkeydictrrrrrr�<module>s__pycache__/parsetab.cpython-36.opt-1.pyc000064400000015224151733004400014143 0ustar003

�"�i}�;@s
dZdZdZddddddd	d
ddd
gddddddd	ddddgfddddddd	d
ddd
gddddddd	ddddgfddddddd	d
ddddd
ddgddddddd	ddddddddgfddddd	d
ddd
g	ddddd	ddddg	fddgddgfdddgdddgfdd gd!d"gfddd#d$d%d&d'dgdd(d)d*d+d,d-d(gfdddd.gdd/d/d0gfdd1dd!ddddd(d/d2ddg
d!d!d
dd1dd!dddd3ddg
fdd(d/d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLd.dMdNdOdPdQd"dd0dRdSdTdUdVg*dddddd
dWd=d>dXd#d$d%dYdd4d3d5dd6ddZd7d8d9d:d[ddd(dCd2dd&d'dDd/dd?d@dAdBg*fd3ddZddWdd[dgdXdXdXdXd;dd<dgfd3ddZddWdd[dgd#d#d#d#d;dd<dgfd3ddZddWdd[dgd$d$d$d$d;dd<dgfd3ddZddWdd[dgd%d%d%d%d;dd<dgfd3ddZddWdd[dgdYdYdYdYd;dd<dgfd3ddZddWdd[dgd&d&d&d&d;dd<dgfd3ddZddWdd[dgd'd'd'd'd;dd<dgfddddgd d ddgfddddgddddgfdZddWdd[dgdJdOd;dd<dgfdXdYd)d*d+d,d-gd.d.d.d.d.dUdVgfdXdYd)d*d+gdMdMdMdMdMgfd\�ZiZxXej�D]L\ZZx@eeded�D]*\Z	Z
e	ek�r�iee	<e
ee	e<�q�W�q�W[dgdgfdgdgfddgdd
gfddgddgfddgddgfddgd	d	gfdgd1gfddgddQgfdd1dgd2ddgfd2gd4gfddgd5d6gfd3gdZgfd3dZgd7dKgfd3ddZdgd8dBd8dBgfd3ddZdgd9dCd9dCgfd3ddZdgd:dDd:dDgfd3ddZdgd;dEd;dEgfd3ddZdgd<dHd<dHgfd3ddZdgd=dFd=dFgfd3ddZdgd>dId>dIgfdgdgfddgd?dPgfddgd@d@gfddgdAdAgfddgdGdGgfdXdYd)d*d+gdLdNdRdSdTgfd]�ZiZxXej�D]L\ZZx@eeded�D]*\Z	Z
e	ek�r�iee	<e
ee	e<�q�W�q�W[d^d_dd`d`d`fdadbddcdddefdfdbddcdddgfdhdiddjdddkfdldmddndddofdpdmddndddqfdrdmddndddsfdtduddvdddwfdxduddvdddyfdzduddvddd{fd|d}dd~dddfd�d}dd~ddd�fd�d}dd~ddd�fd�d}dd~ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�d�ddd�dfg6Z
d`S(z3.8ZLALRZ C2FE91AF256AF1CCEB499107DA2CFE7E��������
��.�>�������/�M�X�	�;���=��P�
��<��O�(�)�*�,�-��E�F�G�I�J�C��R�������� �!�"�#�$�%�&�0�1�2�3�4�5�6�7�8�9�:�?�@�B�D�H�K�L�N�S�T�U�V�W�A�'�+��Q)ZALGORITHM_POLICYZZONEZPOLICYz$endZALGNAMEZSTRZQSTRINGZKEYTYPEZ
DATESUFFIX�LBRACE�SEMIZCOVERAGEZROLL_PERIODZPRE_PUBLISHZPOST_PUBLISHZKEYTTLZKEY_SIZEZSTANDBYZ	DIRECTORYZ	ALGORITHM�RBRACE�NUMBERZNONE)�
policylist�init�policy�
alg_policy�zone_policy�named_policy�domain�name�
new_policy�alg_option_group�policy_option_group�alg_option_list�
alg_option�coverage_option�rollperiod_option�prepublish_option�postpublish_option�
keyttl_option�keysize_option�standby_option�policy_option_list�
policy_option�
parent_option�directory_option�algorithm_option�durationzS' -> policylistzS'Nzpolicylist -> init policyr^Zp_policylistz	policy.pyizpolicylist -> policylist policyizinit -> <empty>r_Zp_initizpolicy -> alg_policyr`Zp_policyizpolicy -> zone_policyizpolicy -> named_policyizname -> STRreZp_nameizname -> KEYTYPEizname -> DATESUFFIXiz
domain -> STRrdZp_domaini!zdomain -> QSTRINGi"zdomain -> KEYTYPEi#zdomain -> DATESUFFIXi$znew_policy -> <empty>rfZp_new_policyi+zGalg_policy -> ALGORITHM_POLICY ALGNAME new_policy alg_option_group SEMIraZp_alg_policyi/z>zone_policy -> ZONE domain new_policy policy_option_group SEMIrbZ
p_zone_policyi6z?named_policy -> POLICY name new_policy policy_option_group SEMIrcZp_named_policyi=zduration -> NUMBERrwZp_duration_1iCzduration -> NONEZp_duration_2iHzduration -> NUMBER DATESUFFIXZp_duration_3iMz7policy_option_group -> LBRACE policy_option_list RBRACErhZp_policy_option_groupi`z(policy_option_list -> policy_option SEMIrrZp_policy_option_listidz;policy_option_list -> policy_option_list policy_option SEMIiezpolicy_option -> parent_optionrsZp_policy_optioniiz!policy_option -> directory_optionijz policy_option -> coverage_optionikz"policy_option -> rollperiod_optionilz"policy_option -> prepublish_optionimz#policy_option -> postpublish_optioninzpolicy_option -> keysize_optionioz!policy_option -> algorithm_optionipzpolicy_option -> keyttl_optioniqzpolicy_option -> standby_optionirz1alg_option_group -> LBRACE alg_option_list RBRACErgZp_alg_option_groupivz"alg_option_list -> alg_option SEMIriZp_alg_option_listizz2alg_option_list -> alg_option_list alg_option SEMIi{zalg_option -> coverage_optionrjZp_alg_optionizalg_option -> rollperiod_optioni�zalg_option -> prepublish_optioni�z alg_option -> postpublish_optioni�zalg_option -> keyttl_optioni�zalg_option -> keysize_optioni�zalg_option -> standby_optioni�zparent_option -> POLICY namertZp_parent_optioni�z%directory_option -> DIRECTORY QSTRINGruZp_directory_optioni�z$coverage_option -> COVERAGE durationrkZp_coverage_optioni�z1rollperiod_option -> ROLL_PERIOD KEYTYPE durationrlZp_rollperiod_optioni�z1prepublish_option -> PRE_PUBLISH KEYTYPE durationrmZp_prepublish_optioni�z3postpublish_option -> POST_PUBLISH KEYTYPE durationrnZp_postpublish_optioni�z)keysize_option -> KEY_SIZE KEYTYPE NUMBERrpZp_keysize_optioni�z(standby_option -> STANDBY KEYTYPE NUMBERrqZp_standby_optioni�z keyttl_option -> KEYTTL durationroZp_keyttl_optioni�z%algorithm_option -> ALGORITHM ALGNAMErvZp_algorithm_optioni�)Z_tabversionZ
_lr_methodZ
_lr_signatureZ_lr_action_itemsZ
_lr_action�itemsZ_kZ_v�zipZ_xZ_yZ_lr_goto_itemsZ_lr_gotoZ_lr_productions�rzrz�/usr/lib/python3.6/parsetab.py�<module>s��������__pycache__/utils.cpython-36.opt-1.pyc000064400000002303151733004400013474 0ustar003

�!�i��@sTddlZejdkr"ddlZddlZddd�Zdd�ZdZejdkrHd	Zned
�ZdS)�N�nt�c
Cs tjdkrtjjd|�Stj}d}tj}d}d}ytj||d|�}Wnd}YnX|s�d}|tj	B}ytj||d|�}Wnd}YnX|s�d}|tj
B}ytj||d|�}Wnd}YnX|r�ytj|d�\}}	Wnd}YnXtj|�|�rtjj||�Stjjtj
�|�S)Nrz/usrzSoftware\ISC\BINDTrFZ
InstallDir)�os�name�path�join�win32con�HKEY_LOCAL_MACHINEZKEY_READ�win32apiZRegOpenKeyExZKEY_WOW64_64KEYZKEY_WOW64_32KEYZRegQueryValueExZRegCloseKeyZGetSystemDirectory)
ZbindirZhklmZbind_subkeyZsamZh_keyZ	key_foundZsam64Zsam32Z
named_base�_�r�/usr/lib/python3.6/utils.py�prefixsD







rcCs2tjdkrd|jdd�dSd|jdd�dS)Nr�"z"\"�'z'\'')rr�replace)�srrr
�
shellquote=s
rz"9.11.36-RedHat-9.11.36-16.el8_10.7z/etcZetc)r)rrrr
rr�versionZ
sysconfdirrrrr
�<module>s

)
__pycache__/__init__.cpython-36.pyc000064400000000744151733004410013144 0ustar003

�!�i��
@sjdddddddddd	d
ddg
Zd
dlTd
dlTd
dlTd
dlTd
dlTd
dlTd
dlTd
dlTd
dl	TdS)ZcheckdsZcoverageZkeymgrZdnskeyZ	eventlistZkeydictZkeyeventZ	keyseriesZkeyzoneZpolicyZparsetabZrndcZutils�)�*N)
�__all__Z
isc.dnskeyZ
isc.eventlistZisc.keydictZisc.keyeventZ
isc.keyseriesZisc.keyzoneZ
isc.policyZisc.rndcZ	isc.utils�rr�/usr/lib/python3.6/__init__.py�<module>s


__pycache__/eventlist.cpython-36.opt-1.pyc000064400000007327151733004420014366 0ustar003

�!�i��@s6ddlmZddlTddlTddlTGdd�d�ZdS)�)�defaultdict�)�*c@s`eZdZedd��Zedd��Ze�ZdZdd�Z	ddd�Z
d	d
�Zedd��Z
ed
d��ZdS)�	eventlistcCstt�S)N)r�list�rr�/usr/lib/python3.6/eventlist.py�<lambda>szeventlist.<lambda>cCstt�S)N)rrrrrrr	sNc
Csddddddg}||_x�|j�D]�}|jj|�x�||j�D]�\}}xj|j�D]^}xX|D]P}|j|�}|snqZt|||�}	|jr�|j	||j
|	�qZ|j||j
|	�qZWqPWt|j	||dd�d	�|j	||<t|j||d
d�d	�|j||<q>Wq WdS)NZSyncPublishZPublishZ
SyncDeleteZActivateZInactiveZDeletecSs|jS)N)�when)�eventrrrr	+sz$eventlist.__init__.<locals>.<lambda>)�keycSs|jS)N)r
)rrrrr	-s)
�_kdictZzones�_zones�add�items�valuesZgettime�keyevent�sep�_K�append�_Z�sorted)
�selfZkdictZ
properties�zone�alg�keys�kZprop�t�errr�__init__s&


zeventlist.__init__cCsdd�}|s|}|r |dkr dnd}|r4|dkr4dnd}d}}	d}
|rb||jkrb|d|�dS|r�d}
|s~|j|d||�}|s�|j|d||�}	n`x^|jD]T}|r�||jj�kr�d}
|j|d||�}|r�||jj�kr�d}
|j|d||�}	q�W|
�s|d�dS|�o|	S)	Nc_sdS)Nr)�args�kwargsrrr�noop2sz eventlist.coverage.<locals>.noop�KSKTFZZSKz!ERROR: No key events found for %szERROR: No key events found)r�	checkzonerrr)rr�keytype�until�outputr"Zno_zskZno_kskZkokZzok�found�zrrr�coverage1s6zeventlist.coveragec	Csxd}|dkr|j|}n
|j|}xP|j�D]D}|d||tj|�f�tj|||||�}|rh|d�|on|}q,W|S)NTr#z9Checking scheduled %s events for zone %s, algorithm %s...zNo errors found)rrr�dnskeyZalgstrr�checkset)	rrr%r&r'ZallokZkzr�okrrrr$Ts
zeventlist.checkzonecCsR|sdS|d|dj�ddd�x(|D] }|d|jt|j�fdd�q*WdS)Nz  r�:F)�skipz
    %s: %s)ZshowtimeZwhat�reprr)�eventsetr'rrrr�showsetfs

zeventlist.showsetc
CsNt�}t�}d}xZ|D]R}d}|s4|dj|jkr>|j|�|dj|jkr|j|�t�}|j|�qW|rz|j|�|s�|d|�dSd}}	x�|D]�}|r�tj|dj�|kr�|dtjdtj|���dSx|D]}|j||	�\}}	q�Wt	j
||�|�s|d|�dS|	�s,|d|�dS|	j|�s�|d	|�dSq�WdS)
NFTrzERROR: No %s events foundzIgnoring events after %sz%a %b %d %H:%M:%S UTC %Yz*ERROR: No %s's are active after this eventz-ERROR: No %s's are published after this eventz=ERROR: No %s's are both active and published after this event)rr
rZcalendarZtimegmZtimeZstrftimeZgmtimeZstatusrr2�intersection)
r1r%r&r'�groups�groupZeventsfoundrZactiveZ	publishedrrrr,nsL






zeventlist.checkset)N)�__name__�
__module__�__qualname__rrr�setrr
rr*r$�staticmethodr2r,rrrrrs
#rN)�collectionsrr+Zkeydictrrrrrr�<module>s__pycache__/checkds.cpython-36.opt-1.pyc000064400000010272151733004420013746 0ustar003

�!�i&�@shddlZddlZddlZddlmZmZddlmZmZdZ	Gdd�d�Z
d
dd�Zd	d
�Zdd�Z
dS)�N)�Popen�PIPE)�prefix�versionzdnssec-checkdsc@sPeZdZddddd�ZdZdZdZdZdZdZ	d	Z
dd
d�Zdd
�Zdd�Z
dS)�SECRRzSHA-1zSHA-256ZGOSTzSHA-384)������INNrcCs�|st�t|�tk	r$|jd�j�}n|j�}t|�dkr<t�|r�d|_|j�|_|dj�j	d�jd�}|j
�|jd�}|j
�xDt|�dkr�t|�dkr�|d|dkr�|dd�}|dd�}q�W|r�t�|j
�dj|�|_|jd|jd|_
nd|_|dj�|_
|dd�}|dj�dk�rJ|dj�|_|dd�}n(t|d�|_|dj�|_|dd�}|dj�|jk�r�td|dj�|jf��tt|dd
��\|_|_|_dj|d
d��j�|_dS)N�ascii��DLVr�.r�DSr�CH�HSrz%s does not match %sr
r)rrr)�	Exception�type�str�decode�split�len�rrtype�lower�dlvname�strip�reverse�join�parent�rrname�upper�rrclass�int�ttl�map�keyid�keyalg�hashalg�digest)�selfZrrtextrZfieldsr �dlv�r-�/usr/lib/python3.6/checkds.py�__init__$sH

*zSECRR.__init__cCs$d|j|j|j|j|j|j|jfS)Nz%s %s %s %d %d %d %s)r!r#rr'r(r)r*)r+r-r-r.�__repr__SszSECRR.__repr__cCs|j�|j�kS)N)r0)r+�otherr-r-r.�__eq__XszSECRR.__eq__)N)�__name__�
__module__�__qualname__�hashalgsr!r#r'r(r)r*r%r/r0r2r-r-r-r.rs
/rc
	Cs&g}|jddd|rdndd|r*|d|n|g}t|td�j�\}}x6|j�D]*}t|�tk	rh|jd	�}|jt	||��qNWt
|d
d�d�}g}	|r�|jd
|g}|r�|d|g7}|j|�t|td�j�\}}ndt|jddddd|gtd�j�\}
}|jd
dg}|�r|d|g7}|j|�t|ttd�j|
�\}}x:|j�D].}t|�tk	�rZ|jd	�}|	jt	||���q>Wt|	�dk�r�t
d�dSd}xv|	D]n}||k�r�t
d|j|jjd�|j|jt	j|jf�d}n,t
d|j|jjd�|j|jt	j|jf��q�W|�s"t
d|�rdnd�|S)Nz+noallz+answerz-tr,Zdsz-qr)�stdoutr
cSs|j|j|jfS)N)r'r(r))�rrr-r-r.�<lambda>mszcheck.<locals>.<lambda>)�keyz-fz-lZdnskey�-)�stdinr7rz$No DNSKEY records found in zone apexFz,%s for KSK %s/%03d/%05d (%s) found in parentTz0%s for KSK %s/%03d/%05d (%s) missing from parentz'No %s records were found for any DNSKEYrr)�digrrZcommunicate�
splitlinesrrr�appendr�sorted�	dsfromkeyr�printrr!rr(r'r6r))
�zone�args�
masterfile�	lookasideZrrlist�cmd�fp�_�lineZklistZintods�foundr8r-r-r.�checkcsV





rLcCs�tjtdd�}d}tjdkr"dnd}|jdtdd�|jd	d
dtdd
�|jdddtdd
�|jdddtjjt	|�d�tdd�|jdddtjjt	|�d�tdd�|jdddt
d�|j�}|jj
d �|_|jr�|jj
d �|_|S)!Nz: checks DS coverage)�description�bin�ntZsbinrCz
zone to check)r�helpz-fz--filerEzzone master file)�destrrPz-lz--lookasiderFzDLV lookaside zonez-dz--digr=z
path to 'dig')rQ�defaultrrPz-Dz--dsfromkeyrAzdnssec-dsfromkeyzpath to 'dnssec-dsfromkey'z-vz	--versionr)�actionrr)�argparse�ArgumentParser�prog�os�name�add_argumentr�pathrrr�
parse_argsrCrrF)�parserZbindirZsbindirrDr-r-r.r[�s,




r[cCs.t�}t|j||j|j�}t|r$dnd�dS)Nrr)r[rLrCrErF�exit)rDrKr-r-r.�main�sr^)NN)rTrW�sys�
subprocessrrZ	isc.utilsrrrVrrLr[r^r-r-r-r.�<module>sI
; __pycache__/parsetab.cpython-36.pyc000064400000015224151733004430013207 0ustar003

�"�i}�;@s
dZdZdZddddddd	d
ddd
gddddddd	ddddgfddddddd	d
ddd
gddddddd	ddddgfddddddd	d
ddddd
ddgddddddd	ddddddddgfddddd	d
ddd
g	ddddd	ddddg	fddgddgfdddgdddgfdd gd!d"gfddd#d$d%d&d'dgdd(d)d*d+d,d-d(gfdddd.gdd/d/d0gfdd1dd!ddddd(d/d2ddg
d!d!d
dd1dd!dddd3ddg
fdd(d/d4d5d6d7d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFdGdHdIdJdKdLd.dMdNdOdPdQd"dd0dRdSdTdUdVg*dddddd
dWd=d>dXd#d$d%dYdd4d3d5dd6ddZd7d8d9d:d[ddd(dCd2dd&d'dDd/dd?d@dAdBg*fd3ddZddWdd[dgdXdXdXdXd;dd<dgfd3ddZddWdd[dgd#d#d#d#d;dd<dgfd3ddZddWdd[dgd$d$d$d$d;dd<dgfd3ddZddWdd[dgd%d%d%d%d;dd<dgfd3ddZddWdd[dgdYdYdYdYd;dd<dgfd3ddZddWdd[dgd&d&d&d&d;dd<dgfd3ddZddWdd[dgd'd'd'd'd;dd<dgfddddgd d ddgfddddgddddgfdZddWdd[dgdJdOd;dd<dgfdXdYd)d*d+d,d-gd.d.d.d.d.dUdVgfdXdYd)d*d+gdMdMdMdMdMgfd\�ZiZxXej�D]L\ZZx@eeded�D]*\Z	Z
e	ek�r�iee	<e
ee	e<�q�W�q�W[dgdgfdgdgfddgdd
gfddgddgfddgddgfddgd	d	gfdgd1gfddgddQgfdd1dgd2ddgfd2gd4gfddgd5d6gfd3gdZgfd3dZgd7dKgfd3ddZdgd8dBd8dBgfd3ddZdgd9dCd9dCgfd3ddZdgd:dDd:dDgfd3ddZdgd;dEd;dEgfd3ddZdgd<dHd<dHgfd3ddZdgd=dFd=dFgfd3ddZdgd>dId>dIgfdgdgfddgd?dPgfddgd@d@gfddgdAdAgfddgdGdGgfdXdYd)d*d+gdLdNdRdSdTgfd]�ZiZxXej�D]L\ZZx@eeded�D]*\Z	Z
e	ek�r�iee	<e
ee	e<�q�W�q�W[d^d_dd`d`d`fdadbddcdddefdfdbddcdddgfdhdiddjdddkfdldmddndddofdpdmddndddqfdrdmddndddsfdtduddvdddwfdxduddvdddyfdzduddvddd{fd|d}dd~dddfd�d}dd~ddd�fd�d}dd~ddd�fd�d}dd~ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�dd�ddd�fd�d�d�ddd�dfg6Z
d`S(z3.8ZLALRZ C2FE91AF256AF1CCEB499107DA2CFE7E��������
��.�>�������/�M�X�	�;���=��P�
��<��O�(�)�*�,�-��E�F�G�I�J�C��R�������� �!�"�#�$�%�&�0�1�2�3�4�5�6�7�8�9�:�?�@�B�D�H�K�L�N�S�T�U�V�W�A�'�+��Q)ZALGORITHM_POLICYZZONEZPOLICYz$endZALGNAMEZSTRZQSTRINGZKEYTYPEZ
DATESUFFIX�LBRACE�SEMIZCOVERAGEZROLL_PERIODZPRE_PUBLISHZPOST_PUBLISHZKEYTTLZKEY_SIZEZSTANDBYZ	DIRECTORYZ	ALGORITHM�RBRACE�NUMBERZNONE)�
policylist�init�policy�
alg_policy�zone_policy�named_policy�domain�name�
new_policy�alg_option_group�policy_option_group�alg_option_list�
alg_option�coverage_option�rollperiod_option�prepublish_option�postpublish_option�
keyttl_option�keysize_option�standby_option�policy_option_list�
policy_option�
parent_option�directory_option�algorithm_option�durationzS' -> policylistzS'Nzpolicylist -> init policyr^Zp_policylistz	policy.pyizpolicylist -> policylist policyizinit -> <empty>r_Zp_initizpolicy -> alg_policyr`Zp_policyizpolicy -> zone_policyizpolicy -> named_policyizname -> STRreZp_nameizname -> KEYTYPEizname -> DATESUFFIXiz
domain -> STRrdZp_domaini!zdomain -> QSTRINGi"zdomain -> KEYTYPEi#zdomain -> DATESUFFIXi$znew_policy -> <empty>rfZp_new_policyi+zGalg_policy -> ALGORITHM_POLICY ALGNAME new_policy alg_option_group SEMIraZp_alg_policyi/z>zone_policy -> ZONE domain new_policy policy_option_group SEMIrbZ
p_zone_policyi6z?named_policy -> POLICY name new_policy policy_option_group SEMIrcZp_named_policyi=zduration -> NUMBERrwZp_duration_1iCzduration -> NONEZp_duration_2iHzduration -> NUMBER DATESUFFIXZp_duration_3iMz7policy_option_group -> LBRACE policy_option_list RBRACErhZp_policy_option_groupi`z(policy_option_list -> policy_option SEMIrrZp_policy_option_listidz;policy_option_list -> policy_option_list policy_option SEMIiezpolicy_option -> parent_optionrsZp_policy_optioniiz!policy_option -> directory_optionijz policy_option -> coverage_optionikz"policy_option -> rollperiod_optionilz"policy_option -> prepublish_optionimz#policy_option -> postpublish_optioninzpolicy_option -> keysize_optionioz!policy_option -> algorithm_optionipzpolicy_option -> keyttl_optioniqzpolicy_option -> standby_optionirz1alg_option_group -> LBRACE alg_option_list RBRACErgZp_alg_option_groupivz"alg_option_list -> alg_option SEMIriZp_alg_option_listizz2alg_option_list -> alg_option_list alg_option SEMIi{zalg_option -> coverage_optionrjZp_alg_optionizalg_option -> rollperiod_optioni�zalg_option -> prepublish_optioni�z alg_option -> postpublish_optioni�zalg_option -> keyttl_optioni�zalg_option -> keysize_optioni�zalg_option -> standby_optioni�zparent_option -> POLICY namertZp_parent_optioni�z%directory_option -> DIRECTORY QSTRINGruZp_directory_optioni�z$coverage_option -> COVERAGE durationrkZp_coverage_optioni�z1rollperiod_option -> ROLL_PERIOD KEYTYPE durationrlZp_rollperiod_optioni�z1prepublish_option -> PRE_PUBLISH KEYTYPE durationrmZp_prepublish_optioni�z3postpublish_option -> POST_PUBLISH KEYTYPE durationrnZp_postpublish_optioni�z)keysize_option -> KEY_SIZE KEYTYPE NUMBERrpZp_keysize_optioni�z(standby_option -> STANDBY KEYTYPE NUMBERrqZp_standby_optioni�z keyttl_option -> KEYTTL durationroZp_keyttl_optioni�z%algorithm_option -> ALGORITHM ALGNAMErvZp_algorithm_optioni�)Z_tabversionZ
_lr_methodZ
_lr_signatureZ_lr_action_itemsZ
_lr_action�itemsZ_kZ_v�zipZ_xZ_yZ_lr_goto_itemsZ_lr_gotoZ_lr_productions�rzrz�/usr/lib/python3.6/parsetab.py�<module>s��������__pycache__/rndc.cpython-36.opt-1.pyc000064400000012000151733004430013260 0ustar003

�!�i+�@sXddlmZddlZddlZddlZddlZddlZddlZddlZGdd�de	�Z
dS)�)�OrderedDictNc@sleZdZdZddddddd�Zd	d
�Zdd�Zddd�Zdd�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dS)�rndczRNDC protocol client library������)�md5Zsha1Zsha224Zsha256Zsha384Zsha512cCsb||_|j�}|jd�r$|dd�}||_tt|�|_tj|�|_	t
jdd�|_d|_
|j�dS)z�Creates a persistent connection to RNDC and logs in
        host - (ip, port) tuple
        algo - HMAC algorithm: one of md5, sha1, sha224, sha256, sha384, sha512
               (with optional prefix 'hmac-')
        secret - HMAC secret, base64 encodedzhmac-�Nr��i)�host�lower�
startswith�algo�getattr�hashlib�hlalgo�base64�	b64decode�secret�randomZrandint�ser�nonce�_rndc__connect_login)�selfrrr�r�/usr/lib/python3.6/rndc.py�__init__$s
z
rndc.__init__cCst|j|d�d�S)z�Call a RNDC command, all parsing is done on the server side
        cmd - a complete string with a command (eg 'reload zone example.com')
        )�type�_data)�dict�_rndc__command)r�cmdrrr�call5sz	rndc.callFcCst�}�x|j�D]�\}}|r(|dkr(q|tjdt|��|jd�7}t|�tkrt|tjddt|��|jd�7}qt|�tkr�|tjddt|��|7}qt|�tkr�|tjddt|��|7}qt|�t	kr�|j
|�}|tjddt|��|7}qtdt|���qW|S)N�_auth�B�asciiz>BIr�z#Cannot serialize element of type %s)�	bytearray�items�struct�pack�len�encoder �str�bytesr�_rndc__serialize_dict�NotImplementedError)r�data�ignore_auth�rv�k�vZsdrrrZ__serialize_dict;s""
zrndc.__serialize_dictc	Os,|jd7_ttj��}t||�}t�}t�|d<t�|d<t|j�|dd<t|�|dd<t|d�|dd<|jdk	r�|j|dd<||d	<|j|d
d�}tj|j	||j
�j�}tj
|�}|jdkr�tjd
|�|dd<n"ttjd|j|j|��|dd<|j|�}tjdt|�dd�|}|S)Nrr&�_ctrlZ_serZ_tim�<Z_exp�_noncer!T)r5r
Z22s�hmd5ZB88s�hshaz>II�)r�int�timerr0rr2�hmac�newrr�digestrZ	b64encoderr,r-r*�_rndc__algosr.)	r�args�kwargsZnowr4�d�msg�hash�bhashrrrZ__prep_messageOs,






zrndc.__prep_messagecCs�|jdk	r |dd|jkr dS|jdkr8|dd}n|dddd�}t|�tkrb|jd	�}|d
dt|�d7}tj|�}|j|dd
�}t	j
|j||j�j
�}||kS)Nr9r;Fr
r&r<r=rr(�=r>T)r5)rrr r1�decoder.rrr2rArBrrrC)rrHrJZremote_hashZmy_msgZmy_hashrrrZ__verify_msgjs


zrndc.__verify_msgc	Os�|j||�}|jj|�}|t|�kr,td��|jjd�}t|�dkrLtd��tjd|�\}}|dkrptd|��|d8}|jj|tj	�}t|�|kr�td��t
|�tkr�t|�}|j
|�}|j|�s�td	��|S)
NzCannot send the message�zCan't read response headerz>IIrzWrong message version %dr>zCan't read response datazAuthentication failure)�_rndc__prep_message�socket�sendr.�IOErrorZrecvr,�unpackr3ZMSG_WAITALLr r0r*�_rndc__parse_message�_rndc__verify_msg)	rrErFrHZsent�headerZlength�versionr4rrrZ	__commandys(

zrndc.__commandcCs2tj|j�|_d|_|jdd�}|dd|_dS)NZnull)r r9r;)rOZcreate_connectionrrr#)rrHrrrZ__connect_login�szrndc.__connect_logincCs�d}||}|d7}||||�jd�}||7}||}|d7}tjd|||d��d}|d7}||||�}||7}||d�}|dkr�|||fS|dkr�t�}	x(t|�dkr�|j|�\}
}}||	|
<q�W||	|fStd|��dS)Nrrr(z>Ir>r)zUnknown element type %d)rLr,rRrr.�_rndc__parse_elementr3)r�input�posZlabellen�labelr Zdatalenr4�restrGZilabel�valuerrrZ__parse_element�s*

zrndc.__parse_elementcCs8t�}d}x(t|�dkr2|j|�\}}}|||<qW|S)Nr)rr.rW)rrXr6ZhdatarZr\rrrZ__parse_message�szrndc.__parse_messageN)F)�__name__�
__module__�__qualname__�__doc__rDrr%r2rNrTr#rrWrSrrrrrs 
r)�collectionsrr@r,rrArrrO�objectrrrrr�<module>s__pycache__/policy.cpython-36.pyc000064400000046217151733004440012714 0ustar003

�!�i2g�@s:ddlZddljZddljZddlTddlmZGdd�d�ZGdd�d�ZGdd	�d	e	�Z
Gd
d�d�Zedk�r6ddl
Z
e
jd
dkr�ee
jd�Zej�Zej�ed
d�Zeje�nxe
jd
dk�r6y4ee
jdddd�Zeejd�eejd��Wn2e	k
�r4Zzeejd�WYddZ[XnXdS)�N)�*)�copyc
@s�eZdZd3Zed4ZiZdZdZdZdZ	dZ
dd�Zdd�Zd d!�Z
d"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2S)5�	PolicyLex�POLICY�ALGORITHM_POLICY�ZONE�	ALGORITHM�	DIRECTORY�KEYTTL�KEY_SIZE�ROLL_PERIOD�PRE_PUBLISH�POST_PUBLISH�COVERAGE�STANDBY�NONE�
DATESUFFIX�KEYTYPE�ALGNAME�STR�QSTRING�NUMBER�LBRACE�RBRACE�SEMIz 	z	(//|\#).*z\{z\}�;cCs|jj|jjd�7_dS)z\n+�
N)�lexer�lineno�value�count)�self�t�r#�/usr/lib/python3.6/policy.py�	t_newline7szPolicyLex.t_newlinecCs|jj|jjd�7_dS)z/\*(.|\n)*?\*/rN)rrrr )r!r"r#r#r$�	t_comment;szPolicyLex.t_commentcCstjd|j�jd�j�|_|S)z�(?i)(?<=[0-9 \t])(y(?:ears|ear|ea|e)?|mo(?:nths|nth|nt|n)?|w(?:eeks|eek|ee|e)?|d(?:ays|ay|a)?|h(?:ours|our|ou|o)?|mi(?:nutes|nute|nut|nu|n)?|s(?:econds|econd|econ|eco|ec|e)?)\bz(?i)(y|mo|w|d|h|mi|s)([a-z]*)�)�re�matchr�group�lower)r!r"r#r#r$�t_DATESUFFIX?szPolicyLex.t_DATESUFFIXcCs|jj�|_|S)z(?i)\b(KSK|ZSK)\b)r�upper)r!r"r#r#r$�	t_KEYTYPEDszPolicyLex.t_KEYTYPEcCs|jj�|_|S)z�(?i)\b(RSAMD5|DH|DSA|NSEC3DSA|ECC|RSASHA1|NSEC3RSASHA1|RSASHA256|RSASHA512|ECCGOST|ECDSAP256SHA256|ECDSAP384SHA384|ED25519|ED448)\b)rr-)r!r"r#r#r$�	t_ALGNAMEIszPolicyLex.t_ALGNAMEcCs|jj|jd�|_|S)z[A-Za-z._-][\w._-]*r)�reserved_map�getr�type)r!r"r#r#r$�t_STRNszPolicyLex.t_STRcCs&|jj|jd�|_|jdd�|_|S)z"([^"\n]|(\\"))*"rr'���)r0r1rr2)r!r"r#r#r$�	t_QSTRINGSszPolicyLex.t_QSTRINGcCst|j�|_|S)z\d+)�intr)r!r"r#r#r$�t_NUMBERYszPolicyLex.t_NUMBERcCs"td|jd�|jjd�dS)NzIllegal character '%s'rr')�printrr�skip)r!r"r#r#r$�t_error^szPolicyLex.t_errorcKsbdtt�krtjdd�}n
tdd�}x"|jD]}||j|j�j|�<q,Wtjfd|i|��|_dS)N�	maketrans�_�-�object)	�dir�strr;�reservedr0r+�	translate�lexr)r!�kwargsZtrans�rr#r#r$�__init__bs
zPolicyLex.__init__cCs.|jj|�x|jj�}|sPt|�qWdS)N)r�input�tokenr8)r!�textr"r#r#r$�testks
zPolicyLex.testN)
rrrrr	r
rrr
rrrr)	rrrrrrrrr)�__name__�
__module__�__qualname__rA�tokensr0Zt_ignoreZt_ignore_olcommentZt_LBRACEZt_RBRACEZt_SEMIr%r&r,r.r/r3r5r7r:rFrJr#r#r#r$rsN	rc
@s�eZdZdZdZdZdZdZdZdZ	dZ
dZdZdZ
dZdZdZdZdZddgddgddgddgddgddgddgdddddd�Zddd�Zd	d
�Zdd�Zd
d�Zdd�Zdd�ZdS)�PolicyFNiii)�DSA�NSEC3DSA�RSAMD5�RSASHA1�NSEC3RSASHA1�	RSASHA256�	RSASHA512�ECCGOST�ECDSAP256SHA256�ECDSAP384SHA384�ED25519�ED448cCs||_||_||_dS)N)�name�	algorithm�parent)r!r\r]r^r#r#r$rF�szPolicy.__init__cCsFd|jrdp"|jrdp"|jr dp"d|jp*d|jr8|jjp:d|jrRdt|j�dpTd|jp\d|jrlt|j�pnd|j	r~t|j	�p�d|j
r�t|j
�p�d|jr�t|j�p�d|jr�t|j�p�d|j
r�t|j
�p�d|jr�t|j�p�d|jr�t|j�p�d|jr�t|j�p�d|j�rt|j��pd|j�r(t|j��p*d|j�r>t|j��p@dfS)	Na%spolicy %s:
	inherits %s
	directory %s
	algorithm %s
	coverage %s
	ksk_keysize %s
	zsk_keysize %s
	ksk_rollperiod %s
	zsk_rollperiod %s
	ksk_prepublish %s
	ksk_postpublish %s
	zsk_prepublish %s
	zsk_postpublish %s
	ksk_standby %s
	zsk_standby %s
	keyttl %s
zconstructed zzone z
algorithm �ZUNKNOWN�None�")�is_constructed�is_zone�is_algr\r^�	directoryr@r]�coverage�ksk_keysize�zsk_keysize�ksk_rollperiod�zsk_rollperiod�ksk_prepublish�ksk_postpublish�zsk_prepublish�zsk_postpublish�ksk_standby�zsk_standby�keyttl)r!r#r#r$�__repr__�s(

zPolicy.__repr__cCs |d|ko|dkSS)Nrr'r#)r!Zkey_sizeZ
size_ranger#r#r$Z
__verify_size�szPolicy.__verify_sizecCs|jS)N)r\)r!r#r#r$�get_name�szPolicy.get_namecCs|jS)N)rb)r!r#r#r$�constructed�szPolicy.constructedcCs$|jr:|jdk	r:|j|jkr:t|j�dd|j|jffS|jrj|jdk	rj|j|jkrjdd|j|jffS|jr�|jdk	r�|j|jkr�dd|j|jffS|jr�|jdk	r�|j|jkr�dd|j|jffS|jo�|jo�|jo�|j|j|jk�rdd|j|j|jffS|j�rL|j�rL|j�rL|j|j|jk�rLdd|j|j|jffS|jdk	�r |jj	|j�}|dk	�r�|j
|j|��s�dd
|j|ffS|j
|j|��s�dd|j|ffS|jdk�r�|jddk�r�dd|jfS|jdk�r|jddk�rdd|jfS|jd k�r d|_d|_d!S)"zr Check if the values in the policy make sense
        :return: True/False if the policy passes validation
        NFz6KSK pre-publish period (%d) exceeds rollover period %dz7KSK post-publish period (%d) exceeds rollover period %dz6ZSK pre-publish period (%d) exceeds rollover period %dz7ZSK post-publish period (%d) exceeds rollover period %dz%KSK pre/post-publish periods (%d/%d) z"combined exceed rollover period %dz%ZSK pre/post-publish periods (%d/%d) z&KSK key size %d outside valid range %sz&ZSK key size %d outside valid range %srPrQ�@rz$KSK key size %d not divisible by 64 zas required for DSAz$ZSK key size %d not divisible by 64 rWrXrYrZr[Tr_zGKSK pre/post-publish periods (%d/%d) combined exceed rollover period %dzGZSK pre/post-publish periods (%d/%d) combined exceed rollover period %d)rPrQz7KSK key size %d not divisible by 64 as required for DSA)rPrQz7ZSK key size %d not divisible by 64 as required for DSA)rWrXrYrZr[)Tr_)
rirkr8rlrjrmrnr]�valid_key_sz_per_algor1�_Policy__verify_sizergrh)r!Zkey_sz_ranger#r#r$�validate�s�





zPolicy.validate)NNN)rKrLrMrcrdrbrirjrkrmrlrnrgrhrorprqrfrervrFrrrwrsrtrxr#r#r#r$rOvsD
&rOc@seZdZdS)�PolicyExceptionN)rKrLrMr#r#r#r$ry)sryc@s.eZdZiZiZiZdZdZdZdEdd�Z	dd�Z
dd�Zd	d
�Zdd�Z
d
d�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Z d3d4�Z!d5d6�Z"d7d8�Z#d9d:�Z$d;d<�Z%d=d>�Z&d?d@�Z'dAdB�Z(dCdD�Z)dS)F�
dnssec_policyNTcKs�t�|_|jj|_d|kr"d|d<d|kr2d|d<tjfd|i|��|_|jd�t�}d|_d|_d|_	d|_
t|�|jd<d|jd_d|jd_
d	|jd_	t|�|jd
<d
|jd
_d
|jd
_
d	|jd
_	t|�|jd<d|jd_d|jd_
t|�|jd<d|jd_d|jd_
t|�|jd
<d
|jd
_d
|jd
_
t|�|jd<d|jd_d|jd_
t|�|jd<d|jd_d|jd_
t|�|jd<d|jd_d|jd_
t|�|jd<d|jd_d|jd_
d|jd_	d|jd_
t|�|jd<d|jd_d|jd_
d|jd_	d|jd_
t|�|jd<d|jd_d|jd_
d|jd_	d|jd_
t|�|jd<d|jd_d|jd_
d|jd_	d|jd_
|�r�|j|�dS)N�debugF�write_tables�moduleapolicy global { algorithm rsasha256;
                                      key-size ksk 2048;
                                      key-size zsk 2048;
                                      roll-period ksk 0;
                                      roll-period zsk 1y;
                                      pre-publish ksk 1mo;
                                      pre-publish zsk 1mo;
                                      post-publish ksk 1mo;
                                      post-publish zsk 1mo;
                                      standby ksk 0;
                                      standby zsk 0;
                                      keyttl 1h;
                                      coverage 6mo; };
                      policy default { policy global; };TirPirQrRrSrTrUrVrWrXrYrZr[)r�plexrN�yacc�parser�setuprOr]rdrgrhr�
alg_policyr\�load)r!�filenamerD�pr#r#r$rF4s|

zdnssec_policy.__init__c	CsH||_d|_t|��$}|j�}d|jj_|jj|�WdQRXd|_dS)NTr)	r��initial�open�readr~rrr��parse)r!r��frIr#r#r$r��s

zdnssec_policy.loadcCs d|_d|jj_|jj|�dS)NTr)r�r~rrr�r�)r!rIr#r#r$r��s
zdnssec_policy.setupc	Ks`|j�}d}||jkr |j|}|dkrBt|jd�}||_d|_|jdkr�|jpZ|jd}x|rr|jrr|j}q^W|r~|jp�d|_|j|jkr�|j|j}nt	d��|j
dkr�|jp�|jd}x|dk	r�|j
r�|j}q�W|o�|j
|_
|jdk�r:|j�p|jd}x|�r"|j�r"|j}�qW|�r2|j�p6|j|_|jdk�r�|j�pV|jd}x|j�rv|j�rv|j}�qZW|�r�|j�p�|j|_|j
dk�r�|j�p�|jd}x|j�r�|j
�r�|j}�q�W|�r�|j
�p�|j
|_
|jdk�r6|j�p�|jd}x|j�r|j�r|j}�qW|�r.|j�p2|j|_|jdk�r�|j�pR|jd}x|j�rr|j�rr|j}�qVW|�r�|j�p�|j|_|jdk�r�|j�p�|jd}x|j�r�|j�r�|j}�q�W|�r�|j�p�|j|_|jdk�r2|j�p�|jd}x|j�r|j�r|j}�q�W|�r*|j�p.|j|_|jdk�r�|j�pN|jd}x|j�rn|j�rn|j}�qRW|�r~|j�p�|j|_|jdk�r�|j�p�|jd}x|j�r�|j�r�|j}�q�W|�r�|j�p�|j|_|jdk�r(|j�p�|jd}x |dk	�r|j�r|j}�q�W|�o$|j|_d|k�s>|d�r\|j�\}}|�s\t	|��dS|S)N�defaultTzalgorithm not foundZ
novalidate)r+�zone_policyr�named_policyr\rbr]r^r�ryrerfrgrhrirjrkrmrlrnrqrx)	r!ZzonerD�zr�r^ZapZvalid�msgr#r#r$�policy�s�





zdnssec_policy.policycCsdS)zBpolicylist : init policy
                      | policylist policyNr#)r!r�r#r#r$�p_policylist
szdnssec_policy.p_policylistcCs
d|_dS)zinit :FN)r�)r!r�r#r#r$�p_initszdnssec_policy.p_initcCsdS)zTpolicy : alg_policy
                  | zone_policy
                  | named_policyNr#)r!r�r#r#r$�p_policyszdnssec_policy.p_policycCs|d|d<dS)zAname : STR
                | KEYTYPE
                | DATESUFFIXr'rNr#)r!r�r#r#r$�p_nameszdnssec_policy.p_namecCs,|dj�|d<tjd|d�s(td��dS)zcdomain : STR
                  | QSTRING
                  | KEYTYPE
                  | DATESUFFIXr'rz^[\w.-][\w.-]*$zinvalid domainN)�stripr(r)ry)r!r�r#r#r$�p_domain szdnssec_policy.p_domaincCst�|_dS)znew_policy :N)rO�current)r!r�r#r#r$�p_new_policy*szdnssec_policy.p_new_policycCs(|d|j_d|j_|j|j|d<dS)zFalg_policy : ALGORITHM_POLICY ALGNAME new_policy alg_option_group SEMI�TN)r�r\rdr�)r!r�r#r#r$�p_alg_policy.szdnssec_policy.p_alg_policycCs8|djd�|j_d|j_|j|j|djd�j�<dS)z=zone_policy : ZONE domain new_policy policy_option_group SEMIr��.TN)�rstripr�r\rcr�r+)r!r�r#r#r$�
p_zone_policy5szdnssec_policy.p_zone_policycCs$|d|j_|j|j|dj�<dS)z>named_policy : POLICY name new_policy policy_option_group SEMIr�N)r�r\r�r+)r!r�r#r#r$�p_named_policy<szdnssec_policy.p_named_policycCs|d|d<dS)zduration : NUMBERr'rNr#)r!r�r#r#r$�p_duration_1Bszdnssec_policy.p_duration_1cCsd|d<dS)zduration : NONENrr#)r!r�r#r#r$�p_duration_2Gszdnssec_policy.p_duration_2cCs�|ddkr|dd|d<n�|ddkr<|dd|d<n�|ddkrZ|dd	|d<n||dd
krx|dd|d<n^|ddkr�|dd
|d<n@|ddkr�|dd|d<n"|ddkr�|d|d<ntd��dS)zduration : NUMBER DATESUFFIXr��yr'i�3�r�moi�'�wi�:	�di�Q�hiZmi�<�szinvalid durationN)ry)r!r�r#r#r$�p_duration_3Lszdnssec_policy.p_duration_3cCsdS)z6policy_option_group : LBRACE policy_option_list RBRACENr#)r!r�r#r#r$�p_policy_option_group_sz#dnssec_policy.p_policy_option_groupcCsdS)zmpolicy_option_list : policy_option SEMI
                              | policy_option_list policy_option SEMINr#)r!r�r#r#r$�p_policy_option_listcsz"dnssec_policy.p_policy_option_listcCsdS)a�policy_option : parent_option
                         | directory_option
                         | coverage_option
                         | rollperiod_option
                         | prepublish_option
                         | postpublish_option
                         | keysize_option
                         | algorithm_option
                         | keyttl_option
                         | standby_optionNr#)r!r�r#r#r$�p_policy_optionhszdnssec_policy.p_policy_optioncCsdS)z0alg_option_group : LBRACE alg_option_list RBRACENr#)r!r�r#r#r$�p_alg_option_groupusz dnssec_policy.p_alg_option_groupcCsdS)z^alg_option_list : alg_option SEMI
                           | alg_option_list alg_option SEMINr#)r!r�r#r#r$�p_alg_option_listyszdnssec_policy.p_alg_option_listcCsdS)aalg_option : coverage_option
                      | rollperiod_option
                      | prepublish_option
                      | postpublish_option
                      | keyttl_option
                      | keysize_option
                      | standby_optionNr#)r!r�r#r#r$�p_alg_option~szdnssec_policy.p_alg_optioncCs|j|dj�|j_dS)zparent_option : POLICY namer�N)r�r+r�r^)r!r�r#r#r$�p_parent_option�szdnssec_policy.p_parent_optioncCs|d|j_dS)z$directory_option : DIRECTORY QSTRINGr�N)r�re)r!r�r#r#r$�p_directory_option�sz dnssec_policy.p_directory_optioncCs|d|j_dS)z#coverage_option : COVERAGE durationr�N)r�rf)r!r�r#r#r$�p_coverage_option�szdnssec_policy.p_coverage_optioncCs*|ddkr|d|j_n|d|j_dS)z0rollperiod_option : ROLL_PERIOD KEYTYPE durationr��KSK�N)r�rirj)r!r�r#r#r$�p_rollperiod_option�sz!dnssec_policy.p_rollperiod_optioncCs*|ddkr|d|j_n|d|j_dS)z0prepublish_option : PRE_PUBLISH KEYTYPE durationr�r�r�N)r�rkrm)r!r�r#r#r$�p_prepublish_option�sz!dnssec_policy.p_prepublish_optioncCs*|ddkr|d|j_n|d|j_dS)z2postpublish_option : POST_PUBLISH KEYTYPE durationr�r�r�N)r�rlrn)r!r�r#r#r$�p_postpublish_option�sz"dnssec_policy.p_postpublish_optioncCs*|ddkr|d|j_n|d|j_dS)z(keysize_option : KEY_SIZE KEYTYPE NUMBERr�r�r�N)r�rgrh)r!r�r#r#r$�p_keysize_option�szdnssec_policy.p_keysize_optioncCs*|ddkr|d|j_n|d|j_dS)z'standby_option : STANDBY KEYTYPE NUMBERr�r�r�N)r�rorp)r!r�r#r#r$�p_standby_option�szdnssec_policy.p_standby_optioncCs|d|j_dS)zkeyttl_option : KEYTTL durationr�N)r�rq)r!r�r#r#r$�p_keyttl_option�szdnssec_policy.p_keyttl_optioncCs|d|j_dS)z$algorithm_option : ALGORITHM ALGNAMEr�N)r�r])r!r�r#r#r$�p_algorithm_option�sz dnssec_policy.p_algorithm_optioncCsd|r.td|jpd|jrdnd|j|jf�n2|js`td|jp@d|jrJdnd|rV|jpXdf��dS)Nz%s%s%d:syntax error near '%s'r_�:z%s%s%d:unexpected end of inputr)r8r�rrr�ry)r!r�r#r#r$�p_error�szdnssec_policy.p_error)N)*rKrLrMr�r�r�r�r�r�rFr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r#r#r#r$rz,sN
_
h


rz�__main__r'rCr�)r{r�T)r|r{r�znonexistent.zone)r(Zply.lexrCZply.yaccr�stringrrrO�	ExceptionryrzrK�sys�argvr��filer�rI�closer~rJZppr8r�r��e�argsr#r#r#r$�<module>s6

`4!

__pycache__/checkds.cpython-36.pyc000064400000010272151733004440013011 0ustar003

�!�i&�@shddlZddlZddlZddlmZmZddlmZmZdZ	Gdd�d�Z
d
dd�Zd	d
�Zdd�Z
dS)�N)�Popen�PIPE)�prefix�versionzdnssec-checkdsc@sPeZdZddddd�ZdZdZdZdZdZdZ	d	Z
dd
d�Zdd
�Zdd�Z
dS)�SECRRzSHA-1zSHA-256ZGOSTzSHA-384)������INNrcCs�|st�t|�tk	r$|jd�j�}n|j�}t|�dkr<t�|r�d|_|j�|_|dj�j	d�jd�}|j
�|jd�}|j
�xDt|�dkr�t|�dkr�|d|dkr�|dd�}|dd�}q�W|r�t�|j
�dj|�|_|jd|jd|_
nd|_|dj�|_
|dd�}|dj�dk�rJ|dj�|_|dd�}n(t|d�|_|dj�|_|dd�}|dj�|jk�r�td|dj�|jf��tt|dd
��\|_|_|_dj|d
d��j�|_dS)N�ascii��DLVr�.r�DSr�CH�HSrz%s does not match %sr
r)rrr)�	Exception�type�str�decode�split�len�rrtype�lower�dlvname�strip�reverse�join�parent�rrname�upper�rrclass�int�ttl�map�keyid�keyalg�hashalg�digest)�selfZrrtextrZfieldsr �dlv�r-�/usr/lib/python3.6/checkds.py�__init__$sH

*zSECRR.__init__cCs$d|j|j|j|j|j|j|jfS)Nz%s %s %s %d %d %d %s)r!r#rr'r(r)r*)r+r-r-r.�__repr__SszSECRR.__repr__cCs|j�|j�kS)N)r0)r+�otherr-r-r.�__eq__XszSECRR.__eq__)N)�__name__�
__module__�__qualname__�hashalgsr!r#r'r(r)r*r%r/r0r2r-r-r-r.rs
/rc
	Cs&g}|jddd|rdndd|r*|d|n|g}t|td�j�\}}x6|j�D]*}t|�tk	rh|jd	�}|jt	||��qNWt
|d
d�d�}g}	|r�|jd
|g}|r�|d|g7}|j|�t|td�j�\}}ndt|jddddd|gtd�j�\}
}|jd
dg}|�r|d|g7}|j|�t|ttd�j|
�\}}x:|j�D].}t|�tk	�rZ|jd	�}|	jt	||���q>Wt|	�dk�r�t
d�dSd}xv|	D]n}||k�r�t
d|j|jjd�|j|jt	j|jf�d}n,t
d|j|jjd�|j|jt	j|jf��q�W|�s"t
d|�rdnd�|S)Nz+noallz+answerz-tr,Zdsz-qr)�stdoutr
cSs|j|j|jfS)N)r'r(r))�rrr-r-r.�<lambda>mszcheck.<locals>.<lambda>)�keyz-fz-lZdnskey�-)�stdinr7rz$No DNSKEY records found in zone apexFz,%s for KSK %s/%03d/%05d (%s) found in parentTz0%s for KSK %s/%03d/%05d (%s) missing from parentz'No %s records were found for any DNSKEYrr)�digrrZcommunicate�
splitlinesrrr�appendr�sorted�	dsfromkeyr�printrr!rr(r'r6r))
�zone�args�
masterfile�	lookasideZrrlist�cmd�fp�_�lineZklistZintods�foundr8r-r-r.�checkcsV





rLcCs�tjtdd�}d}tjdkr"dnd}|jdtdd�|jd	d
dtdd
�|jdddtdd
�|jdddtjjt	|�d�tdd�|jdddtjjt	|�d�tdd�|jdddt
d�|j�}|jj
d �|_|jr�|jj
d �|_|S)!Nz: checks DS coverage)�description�bin�ntZsbinrCz
zone to check)r�helpz-fz--filerEzzone master file)�destrrPz-lz--lookasiderFzDLV lookaside zonez-dz--digr=z
path to 'dig')rQ�defaultrrPz-Dz--dsfromkeyrAzdnssec-dsfromkeyzpath to 'dnssec-dsfromkey'z-vz	--versionr)�actionrr)�argparse�ArgumentParser�prog�os�name�add_argumentr�pathrrr�
parse_argsrCrrF)�parserZbindirZsbindirrDr-r-r.r[�s,




r[cCs.t�}t|j||j|j�}t|r$dnd�dS)Nrr)r[rLrCrErF�exit)rDrKr-r-r.�main�sr^)NN)rTrW�sys�
subprocessrrZ	isc.utilsrrrVrrLr[r^r-r-r-r.�<module>sI
; __pycache__/keyzone.cpython-36.pyc000064400000002344151733004450013073 0ustar003

�!�i��@sJddlZddlZddlZddlmZmZGdd�de�ZGdd�d�ZdS)�N)�Popen�PIPEc@seZdZdS)�KeyZoneExceptionN)�__name__�
__module__�__qualname__�rr�/usr/lib/python3.6/keyzone.pyrsrc@seZdZdZdd�ZdS)�keyzonez/reads a zone file to find data relevant to keysc
Cs�d|_d|_|sdS|s8tjj|�s8tj|tj�rDtd��dSd}}t|dd||gt	t	d�j
�\}}xv|j�D]j}t|�t
k	r�|jd�}tjd|�r�qv|j�}	|s�t|	d�|kr�t|	d�}|	dd	krvt|	d�}qvW||_||_dS)
Nz"named-compilezone" not foundz-o�-)�stdout�stderr�asciiz^[:space:]*;��ZDNSKEY)�maxttl�keyttl�os�path�isfile�access�X_OKrrrZcommunicate�
splitlines�type�str�decode�re�search�split�int)
�self�name�filenameZczpathrr�fp�_�lineZfieldsrrr	�__init__s.
zkeyzone.__init__N)rrr�__doc__r&rrrr	r
sr
)	r�sysr�
subprocessrr�	Exceptionrr
rrrr	�<module>s
__pycache__/__init__.cpython-36.opt-1.pyc000064400000000744151733004450014107 0ustar003

�!�i��
@sjdddddddddd	d
ddg
Zd
dlTd
dlTd
dlTd
dlTd
dlTd
dlTd
dlTd
dlTd
dl	TdS)ZcheckdsZcoverageZkeymgrZdnskeyZ	eventlistZkeydictZkeyeventZ	keyseriesZkeyzoneZpolicyZparsetabZrndcZutils�)�*N)
�__all__Z
isc.dnskeyZ
isc.eventlistZisc.keydictZisc.keyeventZ
isc.keyseriesZisc.keyzoneZ
isc.policyZisc.rndcZ	isc.utils�rr�/usr/lib/python3.6/__init__.py�<module>s


__pycache__/keyevent.cpython-36.pyc000064400000003500151733004460013235 0ustar003

�!�i�@sddlZGdd�d�ZdS)�Nc@s4eZdZdZddd�Zdd�Zdd�Zdd	d
�ZdS)
�keyeventz� A discrete key event, e.g., Publish, Activate, Inactive, Delete,
    etc. Stores the date of the event, and identifying information
    about the key to which the event will occur.NcCs@||_|p|j|�|_||_|j|_|j|_|j|_|j|_dS)N)	�whatZgettime�when�key�sep�name�zone�alg�keyid)�selfrrr�r�/usr/lib/python3.6/keyevent.py�__init__szkeyevent.__init__cCs t|j|j|j|j|j|jf�S)N)�reprrrr
rrr	)rrrr
�__repr__ szkeyevent.__repr__cCstjd|j�S)Nz%a %b %d %H:%M:%S UTC %Y)�timeZstrftimer)rrrr
�showtime$szkeyevent.showtimecCs�dd�}|s|}|st�}|s$t�}|jdkr<|j|j�n�|jdkrT|j|j�n�|jdkr�|j|kr||dt|j��q�|j|j�nl|jdkr�|j|kr�|j|j�q�|dt|j��n6|jd	kr�|j|kr�|j|j�|j|kr�|j|j�||fS)
Nc_sdS)Nr)�args�kwargsrrr
�noop*szkeyevent.status.<locals>.noopZActivateZPublishZInactivez=	WARNING: %s scheduled to become inactive before it is activeZDeletez@WARNING: key %s is scheduled for deletion before it is publishedZRevoke)�setr�addr
rr�remove)rZactiveZ	published�outputrrrr
�status)s6








zkeyevent.status)N)N)�__name__�
__module__�__qualname__�__doc__rrrrrrrr
rs

	r)rrrrrr
�<module>s__pycache__/keymgr.cpython-36.pyc000064400000010165151733004460012706 0ustar003

�!�ik�@s�ddlmZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZdZddl
mZmZmZmZmZmZdd�Zddd	�Zd
d�Zdd
�ZdS)�)�print_functionN)�defaultdictz
dnssec-keymgr)�dnskey�keydict�	keyseries�policy�parsetab�utilscOst||�tjd�dS)N�)�print�sys�exit)�args�kwargs�r�/usr/lib/python3.6/keymgr.py�fatals
rcCs�|}|s(tjj|�s(tj|tj�r�tjd}|s>tjj}xB|jtj�D]2}|tj	|}tjj|�rztj|tj�rzPd}qLW|S)a2 find the location of a specified command. If a default is supplied,
    exists and it's an executable, we use it; otherwise we search PATH
    for an alternative.
    :param command: command to look for
    :param default: default value to use
    :return: PATH with the location of a suitable binary
    �PATHN)
�os�path�isfile�access�X_OK�environ�defpath�split�pathsep�sep)Zcommand�defaultZfpathrZ	directoryrrr�set_paths$
rcCs�tdtjjtjd�d��}tdtjjtjd�d��}tjtdd�}|j	dt
ddd;d�|j	dd
t
ddd�|j	ddt
ddd�|j	dd|t
dd
d�|j	ddt
ddd
d�|j	dd|t
dd
d�|j	d d!d"d#d$d%�|j	d&d'd"d#d(d%�|j	d)d*d+d"d#d<d%�|j	d.d/d0d"d#d1d%�|j	d2d3d4tjd5�|j�}|j
�rJ|j�rJtd6�|jdk�r^td7�|jdk�rrtd8�|jdk	�r�tjj|j��s�td9|j�n(tjjtjd:�|_tjj|j��s�d|_|S)=zc Read command line arguments, returns 'args' object
    :return: args object properly prepared
    z
dnssec-keygenZsbinzdnssec-settimezA: schedule DNSSEC key rollovers according to a pre-defined policy)�description�zone�*Nz.Zone(s) to which the policy should be applied z%(default: all zones in the directory))�type�nargsr�helpz-KrzDirectory containing keys�dir)�destr#r%�metavarz-c�
policyfilezPolicy definition file�filez-g�keygenzPath to 'dnssec-keygen')r'rr#r%r(z-r�	randomdevz@Path to a file containing random data to pass to 'dnssec-keygen')r'r#rr%r(z-s�settimezPath to 'dnssec-settime'z-k�no_zsk�
store_trueFz,Only apply policy to key-signing keys (KSKs))r'�actionrr%z-z�no_kskz-Only apply policy to zone-signing keys (ZSKs)z-fz--force�forcezForce updates to key events zeven if they are in the pastz-qz--quiet�quietzUpdate keys silentlyz-vz	--version�version)r0r4z)ERROR: -z and -k cannot be used together.zERROR: dnssec-keygen not foundzERROR: dnssec-settime not foundz!ERROR: Policy file "%s" not foundzdnssec-policy.confzSZone(s) to which the policy should be applied (default: all zones in the directory)z8Force updates to key events even if they are in the past)rrr�joinr	�prefix�argparse�ArgumentParser�prog�add_argument�strr4�
parse_argsr.r1rr+r-r)�existsZ
sysconfdir)r+r-�parserrrrrr<6sb







r<c:CsHt�}|j|j|j|jd�}ytj|j�}Wn2tk
r^}zt	dt
|��WYdd}~XnXyt||j|jd�}Wn2tk
r�}zt	dt
|��WYdd}~XnXyt
||d�}Wn2tk
r�}zt	dt
|��WYdd}~XnXy |j||j|j|j|jd�Wn4tk
�rB}zt	dt
|��WYdd}~XnXdS)	N)Zkeygen_pathZsettime_pathZ	keys_pathr,zUnable to load DNSSEC policy: )rZzonesz Unable to build key dictionary: )�contextzUnable to build key series: )ZkskZzskr2r3zUnable to apply policy: )r<r+r-rr,rZ
dnssec_policyr)�	Exceptionrr;rr!rZenforce_policyr.r1r2r3)rr?Zdp�eZkdZksrrr�main}s,
"""rB)N)Z
__future__rrrr7Zglob�reZtimeZcalendar�pprint�collectionsrr9Ziscrrrrrr	rrr<rBrrrr�<module>s@ 
G__pycache__/keyzone.cpython-36.opt-1.pyc000064400000002344151733004470014034 0ustar003

�!�i��@sJddlZddlZddlZddlmZmZGdd�de�ZGdd�d�ZdS)�N)�Popen�PIPEc@seZdZdS)�KeyZoneExceptionN)�__name__�
__module__�__qualname__�rr�/usr/lib/python3.6/keyzone.pyrsrc@seZdZdZdd�ZdS)�keyzonez/reads a zone file to find data relevant to keysc
Cs�d|_d|_|sdS|s8tjj|�s8tj|tj�rDtd��dSd}}t|dd||gt	t	d�j
�\}}xv|j�D]j}t|�t
k	r�|jd�}tjd|�r�qv|j�}	|s�t|	d�|kr�t|	d�}|	dd	krvt|	d�}qvW||_||_dS)
Nz"named-compilezone" not foundz-o�-)�stdout�stderr�asciiz^[:space:]*;��ZDNSKEY)�maxttl�keyttl�os�path�isfile�access�X_OKrrrZcommunicate�
splitlines�type�str�decode�re�search�split�int)
�self�name�filenameZczpathrr�fp�_�lineZfieldsrrr	�__init__s.
zkeyzone.__init__N)rrr�__doc__r&rrrr	r
sr
)	r�sysr�
subprocessrr�	Exceptionrr
rrrr	�<module>s
__pycache__/keymgr.cpython-36.opt-1.pyc000064400000010165151733004470013646 0ustar003

�!�ik�@s�ddlmZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZdZddl
mZmZmZmZmZmZdd�Zddd	�Zd
d�Zdd
�ZdS)�)�print_functionN)�defaultdictz
dnssec-keymgr)�dnskey�keydict�	keyseries�policy�parsetab�utilscOst||�tjd�dS)N�)�print�sys�exit)�args�kwargs�r�/usr/lib/python3.6/keymgr.py�fatals
rcCs�|}|s(tjj|�s(tj|tj�r�tjd}|s>tjj}xB|jtj�D]2}|tj	|}tjj|�rztj|tj�rzPd}qLW|S)a2 find the location of a specified command. If a default is supplied,
    exists and it's an executable, we use it; otherwise we search PATH
    for an alternative.
    :param command: command to look for
    :param default: default value to use
    :return: PATH with the location of a suitable binary
    �PATHN)
�os�path�isfile�access�X_OK�environ�defpath�split�pathsep�sep)Zcommand�defaultZfpathrZ	directoryrrr�set_paths$
rcCs�tdtjjtjd�d��}tdtjjtjd�d��}tjtdd�}|j	dt
ddd;d�|j	dd
t
ddd�|j	ddt
ddd�|j	dd|t
dd
d�|j	ddt
ddd
d�|j	dd|t
dd
d�|j	d d!d"d#d$d%�|j	d&d'd"d#d(d%�|j	d)d*d+d"d#d<d%�|j	d.d/d0d"d#d1d%�|j	d2d3d4tjd5�|j�}|j
�rJ|j�rJtd6�|jdk�r^td7�|jdk�rrtd8�|jdk	�r�tjj|j��s�td9|j�n(tjjtjd:�|_tjj|j��s�d|_|S)=zc Read command line arguments, returns 'args' object
    :return: args object properly prepared
    z
dnssec-keygenZsbinzdnssec-settimezA: schedule DNSSEC key rollovers according to a pre-defined policy)�description�zone�*Nz.Zone(s) to which the policy should be applied z%(default: all zones in the directory))�type�nargsr�helpz-KrzDirectory containing keys�dir)�destr#r%�metavarz-c�
policyfilezPolicy definition file�filez-g�keygenzPath to 'dnssec-keygen')r'rr#r%r(z-r�	randomdevz@Path to a file containing random data to pass to 'dnssec-keygen')r'r#rr%r(z-s�settimezPath to 'dnssec-settime'z-k�no_zsk�
store_trueFz,Only apply policy to key-signing keys (KSKs))r'�actionrr%z-z�no_kskz-Only apply policy to zone-signing keys (ZSKs)z-fz--force�forcezForce updates to key events zeven if they are in the pastz-qz--quiet�quietzUpdate keys silentlyz-vz	--version�version)r0r4z)ERROR: -z and -k cannot be used together.zERROR: dnssec-keygen not foundzERROR: dnssec-settime not foundz!ERROR: Policy file "%s" not foundzdnssec-policy.confzSZone(s) to which the policy should be applied (default: all zones in the directory)z8Force updates to key events even if they are in the past)rrr�joinr	�prefix�argparse�ArgumentParser�prog�add_argument�strr4�
parse_argsr.r1rr+r-r)�existsZ
sysconfdir)r+r-�parserrrrrr<6sb







r<c:CsHt�}|j|j|j|jd�}ytj|j�}Wn2tk
r^}zt	dt
|��WYdd}~XnXyt||j|jd�}Wn2tk
r�}zt	dt
|��WYdd}~XnXyt
||d�}Wn2tk
r�}zt	dt
|��WYdd}~XnXy |j||j|j|j|jd�Wn4tk
�rB}zt	dt
|��WYdd}~XnXdS)	N)Zkeygen_pathZsettime_pathZ	keys_pathr,zUnable to load DNSSEC policy: )rZzonesz Unable to build key dictionary: )�contextzUnable to build key series: )ZkskZzskr2r3zUnable to apply policy: )r<r+r-rr,rZ
dnssec_policyr)�	Exceptionrr;rr!rZenforce_policyr.r1r2r3)rr?Zdp�eZkdZksrrr�main}s,
"""rB)N)Z
__future__rrrr7Zglob�reZtimeZcalendar�pprint�collectionsrr9Ziscrrrrrr	rrr<rBrrrr�<module>s@ 
G__pycache__/coverage.cpython-36.opt-1.pyc000064400000014323151733004470014143 0ustar003

�!�i�&�@s�ddlmZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZdZddl
mZmZmZmZmZmZdd�Zdad	d
�Zdd�Zd
d�Zddd�Zdd�Zdd�ZdS)�)�print_functionN)�defaultdictzdnssec-coverage)�dnskey�	eventlist�keydict�keyevent�keyzone�utilscOst||�tjd�dS)N�)�print�sys�exit)�args�kwargs�r�/usr/lib/python3.6/coverage.py�fatals
rTcOsJd|kr|d}|jdd�nd}tr,dan|r8td�|rFt||�dS)zuoutput text, adding a vertical space this is *not* the first
    first section being printed since a call to vreset()�skipNTF�)�pop�
_firstliner)rrrrrr�output'srcCsdadS)zreset vertical spacingTN)rrrrr�vreset8srcCs�|j�}yt|�Stk
r$YnXtjd�}|j|�}|sJtd|��|j�\}}t|�}|j�}|jd�rx|dS|jd�r�|dS|jd�r�|dS|jd	�r�|d
S|jd�r�|dS|jd
�r�|dS|jd�r�|Std|��dS)z� convert a formatted time (e.g., 1y, 6mo, 15mi, etc) into seconds
    :param s: String with some text representing a time interval
    :return: Integer with the number of seconds in the time interval
    z([0-9][0-9]*)\s*([A-Za-z]*)zCannot parse %s�yi�3��moi�'�wi�:	�di�Q�hiZmi�<�szInvalid suffix %sN)	�strip�int�
ValueError�re�compile�match�groups�lower�
startswith)r�r�m�nZunitrrr�
parse_timeAs6








r,cCs�|}|s(tjj|�s(tj|tj�r�tjd}|s>tjj}xB|jtj�D]2}tjj	||�}tjj|�rztj|tj�rzPd}qLW|S)a1 find the location of a specified command.  if a default is supplied
    and it works, we use it; otherwise we search PATH for a match.
    :param command: string with a command to look for in the path
    :param default: default location to use
    :return: detected location for the desired command
    �PATHN)
�os�path�isfile�access�X_OK�environ�defpath�split�pathsep�join)Zcommand�defaultZfpathr/Z	directoryrrr�set_pathks$
r9c	0CsDtdtjjtjd�d��}tjtddd�}|j	dt
dddFd�|j	dd
dt
ddd�|j	ddt
ddd�|j	ddt
ddd�|j	ddt
ddd�|j	ddd t
d!dd�|j	d"d#|t
d$d
d�|j	d%d&t
d'd(dd)�|j	d*d+d,d-d.d/�|j	d0d1d,d-d2d/�|j	d3d4d5d,d-d6d/�|j	d7d8d9tjd:�|j�}|j
�rJ|j�rJtd;�n*|j
�sZ|j�rn|j
�rfd<nd=|_nd|_|j�r�t|j�d>k�r�td?�d@dA�|jD�|_y|j�r�t|j�}||_Wntk
�r�YnXy|j�r�t|j�}||_Wntk
�rYnXy|j�r(t|j�}||_Wntk
�r@YnXy<|j�r||j}t|j�}|dBk�rnd|_ntj�||_Wntk
�r�YnX|j�r�|j�r�|S|j�r*|j�r*y:t|jdB|j|j�}|j�p�|j|_|j�p�|j|_Wn4tk
�r(}ztdC|j|�WYdd}~XnX|j�s@tdD�dE|_|S)Gz8Read command line arguments, set global 'args' structureznamed-compilezoneZsbinz: checks future zDNSKEY coverage for a zone)�description�zone�*Nzzone(s) to checkz%(default: all zones in the directory))�type�nargsr8�helpz-Kr/�.z&a directory containing keys to process�dir)�destr8r=r?�metavarz-f�filenamezzone master file�file)rBr=r?rCz-m�maxttlzthe longest TTL in the zone(s)�timez-d�keyttlzthe DNSKEY TTLz-r�resignZ1944000z:the RRSIG refresh interval in seconds [default: 22.5 days]z-c�compilezonezpath to 'named-compilezone'z-l�
checklimit�0zDLength of time to check for DNSSEC coverage [default: 0 (unlimited)])rBr=r8r?rCz-z�no_ksk�
store_trueFz#Only check zone-signing keys (ZSKs))rB�actionr8r?z-k�no_zskz"Only check key-signing keys (KSKs)z-Dz--debugZ
debug_modezTurn on debugging outputz-vz	--version�version)rOrQz)ERROR: -z and -k cannot be used together.ZKSKZZSKr
z)ERROR: -f can only be used with one zone.cSs4g|],}t|�dkr,|ddkr,|dd�n|�qS)r
r@N���rR)�len)�.0�xrrr�
<listcomp>�szparse_args.<locals>.<listcomp>rz"Unable to load zone data from %s: z�WARNING: Maximum TTL value was not specified.  Using 1 week
	 (604800 seconds); re-run with the -m option to get more
	 accurate results.i�:	z5zone(s) to check(default: all zones in the directory)) r9r.r/r7r	�prefix�argparse�ArgumentParser�prog�add_argument�strrQ�
parse_argsrPrMr�keytyperDrSr;rFr,r"rHrIrKrGrrJ�	Exceptionrr)	rJ�parserrr*�kr)Zlimr;�errrr]�s�



















"r]c(Cspt�}td�yt|j|j|jd�}Wn2tk
rX}ztdt|��WYdd}~XnXx<|D]4}|j	t
�|jr�|jt
�q`|jt
|j
|j�q`Wt
d�t�yt|�}Wn2tk
r�}ztdt|��WYdd}~XnXd}|j�s|jd|j|jt
��sXd}nJxH|jD]>}y|j||j|jt
��s6d}Wnt
d|�YnX�qWtj|�rfd	nd
�dS)Nz;PHASE 1--Loading keys to check for internal timing problems)r/ZzonesrHz'ERROR: Unable to build key dictionary: z9PHASE 2--Scanning future key events for coverage failuresz#ERROR: Unable to build event list: FTz&ERROR: Coverage check failed for zone r
r)r]rrr/r;rHr_rr\Zcheck_prepubr�sepZ
check_postpubrFrIrrZcoverager^rKrr
)rZkdrb�keyZelist�errorsr;rrr�main�s:"

"
rf)N)Z
__future__rr.rrXZglobr#rGZcalendar�pprint�collectionsrrZZiscrrrrrr	rrrrr,r9r]rfrrrr�<module>s& 	*
x__pycache__/utils.cpython-36.pyc000064400000002303151733004500012536 0ustar003

�!�i��@sTddlZejdkr"ddlZddlZddd�Zdd�ZdZejdkrHd	Zned
�ZdS)�N�nt�c
Cs tjdkrtjjd|�Stj}d}tj}d}d}ytj||d|�}Wnd}YnX|s�d}|tj	B}ytj||d|�}Wnd}YnX|s�d}|tj
B}ytj||d|�}Wnd}YnX|r�ytj|d�\}}	Wnd}YnXtj|�|�rtjj||�Stjjtj
�|�S)Nrz/usrzSoftware\ISC\BINDTrFZ
InstallDir)�os�name�path�join�win32con�HKEY_LOCAL_MACHINEZKEY_READ�win32apiZRegOpenKeyExZKEY_WOW64_64KEYZKEY_WOW64_32KEYZRegQueryValueExZRegCloseKeyZGetSystemDirectory)
ZbindirZhklmZbind_subkeyZsamZh_keyZ	key_foundZsam64Zsam32Z
named_base�_�r�/usr/lib/python3.6/utils.py�prefixsD







rcCs2tjdkrd|jdd�dSd|jdd�dS)Nr�"z"\"�'z'\'')rr�replace)�srrr
�
shellquote=s
rz"9.11.36-RedHat-9.11.36-16.el8_10.7z/etcZetc)r)rrrr
rr�versionZ
sysconfdirrrrr
�<module>s

)
__pycache__/keydict.cpython-36.pyc000064400000005013151733004500013033 0ustar003

�!�i!�@s:ddlmZddlmZddlZddlZGdd�d�ZdS)�)�defaultdict�)�dnskeyNc@sneZdZdZedd��ZdZgZddd�Zdd�Z	d	d
�Z
dd�Zd
d�Zdd�Z
dd�Zdd�Zdd�ZdS)�keydictz> A dictionary of keys, indexed by name, algorithm, and key id cCstt�S)N)r�dict�rr�/usr/lib/python3.6/keydict.py�<lambda>szkeydict.<lambda>NcKs�|jdd�|_|jdd�}|s:|jdd�p,d}|j|�nXxV|D]N}d|krb|ddk	rb|d}n|rr|j|�jptd}|j||�s@|jj|�q@WdS)NZkeyttl�zones�path�.)�get�_defttl�readallZpolicyZ	directory�readone�_missing�append)�selfZdp�kwargsr
r�zonerrr�__init__s

zkeydict.__init__cCsLtjtjj|d��}x2|D]*}t|||j�}||j|j|j|j	<qWdS)Nz	*.private)
�glob�osr�joinrr�_keydict�name�alg�keyid)rr�files�infile�keyrrrr,s
zkeydict.readallc	Cs�|jd�s|d7}d|d}tjtjj||��}d}xR|D]J}t|||j�}|j|krZq<|dkrh|jnd}||j	||j
|j<d}q<W|S)Nr�Kz
+*.privateFT)�endswithrrrrrr�fullnamerrrr)	rrr�matchr�foundrr Zkeynamerrrr3s


zkeydict.readoneccsJxD|jj�D]6\}}x,|j�D] \}}x|j�D]
}|Vq0WqWqWdS)N)r�items�values)rr�
algorithmsr�keysr rrr�__iter__Dszkeydict.__iter__cCs
|j|S)N)r)rrrrr�__getitem__Jszkeydict.__getitem__cCs
|jj�S)N)rr))rrrrr
Msz
keydict.zonescCs|j|j�S)N)rr))rrrrrr(Pszkeydict.algorithmscCs|j||j�S)N)rr))rrrrrrr)Sszkeydict.keyscCs|jS)N)r)rrrr�missingVszkeydict.missing)N)�__name__�
__module__�__qualname__�__doc__rrrrrrrr*r+r
r(r)r,rrrrrs
r)�collectionsr�rrrrrrrr�<module>s__pycache__/keyseries.cpython-36.opt-1.pyc000064400000010705151733004500014345 0ustar003

�!�i"�@sFddlmZddlTddlTddlTddlTddlZGdd�d�ZdS)�)�defaultdict�)�*Nc@sleZdZedd��Zedd��Ze�ZdZdZ	e
j
�dfdd�Zdd�Zd	d
�Z
dd�Ze
j
�fd
d�ZdS)�	keyseriescCstt�S)N)r�list�rr�/usr/lib/python3.6/keyseries.py�<lambda>szkeyseries.<lambda>cCstt�S)N)rrrrrrr	sNcCs�||_||_t|j��|_x�|j�D]�}|jj|�x�||j�D]�\}}xh|j�D]\}|j	r�|j
�op|j
�|ks�|j||j|�qT|j
�o�|j
�|ksT|j
||j|�qTW|j||j�|j
||j�qBWq$WdS)N)�_kdict�_context�setZmissing�_zones�zones�add�items�values�sep�delete�_K�append�_Z�sort)�selfZkdict�now�context�zone�alg�keys�krrr�__init__szkeyseries.__init__ccsbx\|jD]R}xL|j|jgD]<}||kr(qx,||j�D]\}}x|D]
}|VqDWq6WqWqWdS)N)r
rrr)rr�
collectionrr�keyrrr�__iter__.s
zkeyseries.__iter__cCs"x|D]}tdt|��qWdS)Nz%s)�print�repr)rrrrr�dump7s
zkeyseries.dumpcKs�|jdd�}|sdS|d}|jr>|j}|jp0d}|jp:d}	n|j}|jpLd
}|jpVd}	|j�}
|j	�}|
sv|
|kr�|j
|�|}
|s�||kr�|j|�|}|j�}d}
|s�|j
d|�|jd|��n�|s�|||k�r|�r(|||||
k�r(|j
||f|�|j|||	f|�n�|�s`|j
|||
f|�|j|||	|
f|�n�||k�rln�|||k�r�|j
||f|�|j|||	f|�np|||||
k�r�|j
||f|�|j|||	f|�n0|j
|||
f|�|j|||	|
f|�n�|j�}|�s8||	||
k�rL|j||	f|�nN|�sj|j||	|
f|�n0|||
k�rzn |||	k�r�|j||	f|�|j|jk�r�|j|j�|}x�|dd�D]�}|�s|j
d|�|jd|�|j
d|�|jd|�|j|jk�r�|j|j��q�|j�}||}
|j|f|�|j
|
f|�|j
||f|�|j|||	f|�|j||	f|�|j|jk�r�|j|j�|}�q�Wx�|�r>|j��r>|j�||jk�r>|j|jdf|�|j|jd	|jd
|f|�}|j
|j	�|f|�|j|j�|	f|�|j|�|}�q�W|j
d|�|jd|�x"|D]}|j|jdf|��q^WdS)N�forceFr�i�Qi,rZsettime_path�keygen_path�	randomdevi�'i�'i�'i�')N)N)N)N)N)N)N)N)�getrZksk_rollperiodZksk_prepublishZksk_postpublishZzsk_rollperiodZzsk_prepublishZzsk_postpublishZpublishZactivateZ
setpublishZsetactivateZinactiveZsetinactiveZ	setdeleter�keyttlZttlZsetttlZcoverageZcommitrZgenerate_successorr)rr�policyr�kwargsr&r!ZrpZprepubZpostpub�p�a�iZfudge�d�prevrrr�	fixseries;s�










zkeyseries.fixseriescKs�|jd|j�}|jd|jjdd��}|jdd�}�x�|D�]�}g}|j|�}	|pX|	jpXd}|	j}
tj|
�}d|ks||dr�t|j	||�dkr�tj
|jd	|jd
|||
|	jd|	jp�df|�}|j	||j
|�|j
|j	|�d|ks�|d�rht|j||�dk�rXtj
|jd	|jd
|||
|	jd
|	j�p<df|�}|j||j
|�|j
|j|�x�|D]�}
x||
j�D]p\}}||k�r��q|y|j||	|f|�Wn@tk
�r�}z"td|tj|�t|�f��WYdd}~XnX�q|W�qnWq8WdS)Nr�dirZ	keys_pathr&F�.Zkskrr(r)iZzskTz	%s/%s: %s)r*r
rr,Z	directory�	algorithm�dnskey�algnum�lenrZgenerateZzsk_keysizer+rrZksk_keysizerr3�	ExceptionZalgstr�str)rZpoliciesrr-rZkeys_dirr&r�collectionsr,rr8rr r6r�errr�enforce_policy�sL




zkeyseries.enforce_policy)�__name__�
__module__�__qualname__rrrrr
r
r�timerr"r%r3r>rrrrrs	vr)r<rr7ZkeydictZkeyeventr,rBrrrrr�<module>sutils.py000064400000004240151733004500006254 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

import os

# These routines permit platform-independent location of BIND 9 tools
if os.name == 'nt':
    import win32con
    import win32api


def prefix(bindir=''):
    if os.name != 'nt':
        return os.path.join('/usr', bindir)

    hklm = win32con.HKEY_LOCAL_MACHINE
    bind_subkey = "Software\\ISC\\BIND"
    sam = win32con.KEY_READ
    h_key = None
    key_found = True
    # can fail if the registry redirected for 32/64 bits
    try:
        h_key = win32api.RegOpenKeyEx(hklm, bind_subkey, 0, sam)
    except:
        key_found = False
    # retry for 32 bit python with 64 bit bind9
    if not key_found:
        key_found = True
        sam64 = sam | win32con.KEY_WOW64_64KEY
        try:
            h_key = win32api.RegOpenKeyEx(hklm, bind_subkey, 0, sam64)
        except:
            key_found = False
    # retry 64 bit python with 32 bit bind9
    if not key_found:
        key_found = True
        sam32 = sam | win32con.KEY_WOW64_32KEY
        try:
            h_key = win32api.RegOpenKeyEx(hklm, bind_subkey, 0, sam32)
        except:
            key_found = False
    if key_found:
        try:
            (named_base, _) = win32api.RegQueryValueEx(h_key, "InstallDir")
        except:
            key_found = False
        win32api.RegCloseKey(h_key)
    if key_found:
        return os.path.join(named_base, bindir)
    return os.path.join(win32api.GetSystemDirectory(), bindir)


def shellquote(s):
    if os.name == 'nt':
        return '"' + s.replace('"', '"\\"') + '"'
    return "'" + s.replace("'", "'\\''") + "'"


version = '9.11.36-RedHat-9.11.36-16.el8_10.7'
if os.name != 'nt':
    sysconfdir = '/etc'
else:
    sysconfdir = prefix('etc')
policy.py000064400000063462151733004510006427 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

import re
import ply.lex as lex
import ply.yacc as yacc
from string import *
from copy import copy


############################################################################
# PolicyLex: a lexer for the policy file syntax.
############################################################################
class PolicyLex:
    reserved = ('POLICY',
                'ALGORITHM_POLICY',
                'ZONE',
                'ALGORITHM',
                'DIRECTORY',
                'KEYTTL',
                'KEY_SIZE',
                'ROLL_PERIOD',
                'PRE_PUBLISH',
                'POST_PUBLISH',
                'COVERAGE',
                'STANDBY',
                'NONE')

    tokens = reserved + ('DATESUFFIX',
                         'KEYTYPE',
                         'ALGNAME',
                         'STR',
                         'QSTRING',
                         'NUMBER',
                         'LBRACE',
                         'RBRACE',
                         'SEMI')
    reserved_map = {}

    t_ignore           = ' \t'
    t_ignore_olcomment = r'(//|\#).*'

    t_LBRACE           = r'\{'
    t_RBRACE           = r'\}'
    t_SEMI             = r';';

    def t_newline(self, t):
        r'\n+'
        t.lexer.lineno += t.value.count("\n")

    def t_comment(self, t):
        r'/\*(.|\n)*?\*/'
        t.lexer.lineno += t.value.count('\n')

    def t_DATESUFFIX(self, t):
        r'(?i)(?<=[0-9 \t])(y(?:ears|ear|ea|e)?|mo(?:nths|nth|nt|n)?|w(?:eeks|eek|ee|e)?|d(?:ays|ay|a)?|h(?:ours|our|ou|o)?|mi(?:nutes|nute|nut|nu|n)?|s(?:econds|econd|econ|eco|ec|e)?)\b'
        t.value = re.match(r'(?i)(y|mo|w|d|h|mi|s)([a-z]*)', t.value).group(1).lower()
        return t

    def t_KEYTYPE(self, t):
        r'(?i)\b(KSK|ZSK)\b'
        t.value = t.value.upper()
        return t

    def t_ALGNAME(self, t):
        r'(?i)\b(RSAMD5|DH|DSA|NSEC3DSA|ECC|RSASHA1|NSEC3RSASHA1|RSASHA256|RSASHA512|ECCGOST|ECDSAP256SHA256|ECDSAP384SHA384|ED25519|ED448)\b'
        t.value = t.value.upper()
        return t

    def t_STR(self, t):
        r'[A-Za-z._-][\w._-]*'
        t.type = self.reserved_map.get(t.value, "STR")
        return t

    def t_QSTRING(self, t):
        r'"([^"\n]|(\\"))*"'
        t.type = self.reserved_map.get(t.value, "QSTRING")
        t.value = t.value[1:-1]
        return t

    def t_NUMBER(self, t):
        r'\d+'
        t.value = int(t.value)
        return t

    def t_error(self, t):
        print("Illegal character '%s'" % t.value[0])
        t.lexer.skip(1)

    def __init__(self, **kwargs):
        if 'maketrans' in dir(str):
            trans = str.maketrans('_', '-')
        else:
            trans = maketrans('_', '-')
        for r in self.reserved:
            self.reserved_map[r.lower().translate(trans)] = r
        self.lexer = lex.lex(object=self, **kwargs)

    def test(self, text):
        self.lexer.input(text)
        while True:
            t = self.lexer.token()
            if not t:
                break
            print(t)

############################################################################
# Policy: this object holds a set of DNSSEC policy settings.
############################################################################
class Policy:
    is_zone = False
    is_alg = False
    is_constructed = False
    ksk_rollperiod = None
    zsk_rollperiod = None
    ksk_prepublish = None
    zsk_prepublish = None
    ksk_postpublish = None
    zsk_postpublish = None
    ksk_keysize = None
    zsk_keysize = None
    ksk_standby = None
    zsk_standby = None
    keyttl = None
    coverage = None
    directory = None
    valid_key_sz_per_algo = {'DSA': [512, 1024],
                             'NSEC3DSA': [512, 1024],
                             'RSAMD5': [512, 4096],
                             'RSASHA1': [512, 4096],
                             'NSEC3RSASHA1': [512, 4096],
                             'RSASHA256': [512, 4096],
                             'RSASHA512': [512, 4096],
                             'ECCGOST': None,
                             'ECDSAP256SHA256': None,
                             'ECDSAP384SHA384': None,
                             'ED25519': None,
                             'ED448': None}

    def __init__(self, name=None, algorithm=None, parent=None):
        self.name = name
        self.algorithm = algorithm
        self.parent = parent
        pass

    def __repr__(self):
        return ("%spolicy %s:\n"
                "\tinherits %s\n"
                "\tdirectory %s\n"
                "\talgorithm %s\n"
                "\tcoverage %s\n"
                "\tksk_keysize %s\n"
                "\tzsk_keysize %s\n"
                "\tksk_rollperiod %s\n"
                "\tzsk_rollperiod %s\n"
                "\tksk_prepublish %s\n"
                "\tksk_postpublish %s\n"
                "\tzsk_prepublish %s\n"
                "\tzsk_postpublish %s\n"
                "\tksk_standby %s\n"
                "\tzsk_standby %s\n"
                "\tkeyttl %s\n"
                %
                ((self.is_constructed and 'constructed ' or \
                  self.is_zone and 'zone ' or \
                  self.is_alg and 'algorithm ' or ''),
                 self.name or 'UNKNOWN',
                 self.parent and self.parent.name or 'None',
                 self.directory and ('"' + str(self.directory) + '"') or 'None',
                 self.algorithm or 'None',
                 self.coverage and str(self.coverage) or 'None',
                 self.ksk_keysize and str(self.ksk_keysize) or 'None',
                 self.zsk_keysize and str(self.zsk_keysize) or 'None',
                 self.ksk_rollperiod and str(self.ksk_rollperiod) or 'None',
                 self.zsk_rollperiod and str(self.zsk_rollperiod) or 'None',
                 self.ksk_prepublish and str(self.ksk_prepublish) or 'None',
                 self.ksk_postpublish and str(self.ksk_postpublish) or 'None',
                 self.zsk_prepublish and str(self.zsk_prepublish) or 'None',
                 self.zsk_postpublish and str(self.zsk_postpublish) or 'None',
                 self.ksk_standby and str(self.ksk_standby) or 'None',
                 self.zsk_standby and str(self.zsk_standby) or 'None',
                 self.keyttl and str(self.keyttl) or 'None'))

    def __verify_size(self, key_size, size_range):
        return (size_range[0] <= key_size <= size_range[1])

    def get_name(self):
        return self.name

    def constructed(self):
        return self.is_constructed

    def validate(self):
        """ Check if the values in the policy make sense
        :return: True/False if the policy passes validation
        """
        if self.ksk_rollperiod and \
           self.ksk_prepublish is not None and \
           self.ksk_prepublish > self.ksk_rollperiod:
            print(self.ksk_rollperiod)
            return (False,
                    ('KSK pre-publish period (%d) exceeds rollover period %d'
                     % (self.ksk_prepublish, self.ksk_rollperiod)))

        if self.ksk_rollperiod and \
           self.ksk_postpublish is not None and \
           self.ksk_postpublish > self.ksk_rollperiod:
            return (False,
                    ('KSK post-publish period (%d) exceeds rollover period %d'
                     % (self.ksk_postpublish, self.ksk_rollperiod)))

        if self.zsk_rollperiod and \
           self.zsk_prepublish is not None and \
           self.zsk_prepublish >= self.zsk_rollperiod:
            return (False,
                    ('ZSK pre-publish period (%d) exceeds rollover period %d'
                     % (self.zsk_prepublish, self.zsk_rollperiod)))

        if self.zsk_rollperiod and \
           self.zsk_postpublish is not None and \
           self.zsk_postpublish >= self.zsk_rollperiod:
            return (False,
                    ('ZSK post-publish period (%d) exceeds rollover period %d'
                     % (self.zsk_postpublish, self.zsk_rollperiod)))

        if self.ksk_rollperiod and \
           self.ksk_prepublish and self.ksk_postpublish and \
           self.ksk_prepublish + self.ksk_postpublish >= self.ksk_rollperiod:
            return (False,
                    (('KSK pre/post-publish periods (%d/%d) ' +
                      'combined exceed rollover period %d') %
                     (self.ksk_prepublish,
                      self.ksk_postpublish,
                      self.ksk_rollperiod)))

        if self.zsk_rollperiod and \
           self.zsk_prepublish and self.zsk_postpublish and \
           self.zsk_prepublish + self.zsk_postpublish >= self.zsk_rollperiod:
            return (False,
                    (('ZSK pre/post-publish periods (%d/%d) ' +
                      'combined exceed rollover period %d') %
                     (self.zsk_prepublish,
                      self.zsk_postpublish,
                      self.zsk_rollperiod)))

        if self.algorithm is not None:
            # Validate the key size
            key_sz_range = self.valid_key_sz_per_algo.get(self.algorithm)
            if key_sz_range is not None:
                # Verify KSK
                if not self.__verify_size(self.ksk_keysize, key_sz_range):
                    return False, 'KSK key size %d outside valid range %s' \
                            % (self.ksk_keysize, key_sz_range)

                # Verify ZSK
                if not self.__verify_size(self.zsk_keysize, key_sz_range):
                    return False, 'ZSK key size %d outside valid range %s' \
                            % (self.zsk_keysize, key_sz_range)

            # Specific check for DSA keys
            if self.algorithm in ['DSA', 'NSEC3DSA'] and \
               self.ksk_keysize % 64 != 0:
                return False, \
                        ('KSK key size %d not divisible by 64 ' +
                         'as required for DSA') % self.ksk_keysize

            if self.algorithm in ['DSA', 'NSEC3DSA'] and \
               self.zsk_keysize % 64 != 0:
                return False, \
                        ('ZSK key size %d not divisible by 64 ' +
                         'as required for DSA') % self.zsk_keysize

            if self.algorithm in ['ECCGOST', \
                                  'ECDSAP256SHA256', \
                                  'ECDSAP384SHA384', \
                                  'ED25519', \
                                  'ED448']:
                self.ksk_keysize = None
                self.zsk_keysize = None

        return True, ''

############################################################################
# dnssec_policy:
# This class reads a dnssec.policy file and creates a dictionary of
# DNSSEC policy rules from which a policy for a specific zone can
# be generated.
############################################################################
class PolicyException(Exception):
    pass

class dnssec_policy:
    alg_policy = {}
    named_policy = {}
    zone_policy = {}
    current = None
    filename = None
    initial = True

    def __init__(self, filename=None, **kwargs):
        self.plex = PolicyLex()
        self.tokens = self.plex.tokens
        if 'debug' not in kwargs:
            kwargs['debug'] = False
        if 'write_tables' not in kwargs:
            kwargs['write_tables'] = False
        self.parser = yacc.yacc(module=self, **kwargs)

        # set defaults
        self.setup('''policy global { algorithm rsasha256;
                                      key-size ksk 2048;
                                      key-size zsk 2048;
                                      roll-period ksk 0;
                                      roll-period zsk 1y;
                                      pre-publish ksk 1mo;
                                      pre-publish zsk 1mo;
                                      post-publish ksk 1mo;
                                      post-publish zsk 1mo;
                                      standby ksk 0;
                                      standby zsk 0;
                                      keyttl 1h;
                                      coverage 6mo; };
                      policy default { policy global; };''')

        p = Policy()
        p.algorithm = None
        p.is_alg = True
        p.ksk_keysize = 2048;
        p.zsk_keysize = 2048;

        # set default algorithm policies
        # these need a lower default key size:
        self.alg_policy['DSA'] = copy(p)
        self.alg_policy['DSA'].algorithm = "DSA"
        self.alg_policy['DSA'].name = "DSA"
        self.alg_policy['DSA'].ksk_keysize = 1024;

        self.alg_policy['NSEC3DSA'] = copy(p)
        self.alg_policy['NSEC3DSA'].algorithm = "NSEC3DSA"
        self.alg_policy['NSEC3DSA'].name = "NSEC3DSA"
        self.alg_policy['NSEC3DSA'].ksk_keysize = 1024;

        # these can use default settings
        self.alg_policy['RSAMD5'] = copy(p)
        self.alg_policy['RSAMD5'].algorithm = "RSAMD5"
        self.alg_policy['RSAMD5'].name = "RSAMD5"

        self.alg_policy['RSASHA1'] = copy(p)
        self.alg_policy['RSASHA1'].algorithm = "RSASHA1"
        self.alg_policy['RSASHA1'].name = "RSASHA1"

        self.alg_policy['NSEC3RSASHA1'] = copy(p)
        self.alg_policy['NSEC3RSASHA1'].algorithm = "NSEC3RSASHA1"
        self.alg_policy['NSEC3RSASHA1'].name = "NSEC3RSASHA1"

        self.alg_policy['RSASHA256'] = copy(p)
        self.alg_policy['RSASHA256'].algorithm = "RSASHA256"
        self.alg_policy['RSASHA256'].name = "RSASHA256"

        self.alg_policy['RSASHA512'] = copy(p)
        self.alg_policy['RSASHA512'].algorithm = "RSASHA512"
        self.alg_policy['RSASHA512'].name = "RSASHA512"

        self.alg_policy['ECCGOST'] = copy(p)
        self.alg_policy['ECCGOST'].algorithm = "ECCGOST"
        self.alg_policy['ECCGOST'].name = "ECCGOST"

        self.alg_policy['ECDSAP256SHA256'] = copy(p)
        self.alg_policy['ECDSAP256SHA256'].algorithm = "ECDSAP256SHA256"
        self.alg_policy['ECDSAP256SHA256'].name = "ECDSAP256SHA256"
        self.alg_policy['ECDSAP256SHA256'].ksk_keysize = None;
        self.alg_policy['ECDSAP256SHA256'].zsk_keysize = None;

        self.alg_policy['ECDSAP384SHA384'] = copy(p)
        self.alg_policy['ECDSAP384SHA384'].algorithm = "ECDSAP384SHA384"
        self.alg_policy['ECDSAP384SHA384'].name = "ECDSAP384SHA384"
        self.alg_policy['ECDSAP384SHA384'].ksk_keysize = None;
        self.alg_policy['ECDSAP384SHA384'].zsk_keysize = None;

        self.alg_policy['ED25519'] = copy(p)
        self.alg_policy['ED25519'].algorithm = "ED25519"
        self.alg_policy['ED25519'].name = "ED25519"
        self.alg_policy['ED25519'].ksk_keysize = None;
        self.alg_policy['ED25519'].zsk_keysize = None;

        self.alg_policy['ED448'] = copy(p)
        self.alg_policy['ED448'].algorithm = "ED448"
        self.alg_policy['ED448'].name = "ED448"
        self.alg_policy['ED448'].ksk_keysize = None;
        self.alg_policy['ED448'].zsk_keysize = None;

        if filename:
            self.load(filename)

    def load(self, filename):
        self.filename = filename
        self.initial = True
        with open(filename) as f:
            text = f.read()
            self.plex.lexer.lineno = 0
            self.parser.parse(text)

        self.filename = None

    def setup(self, text):
        self.initial = True
        self.plex.lexer.lineno = 0
        self.parser.parse(text)

    def policy(self, zone, **kwargs):
        z = zone.lower()
        p = None

        if z in self.zone_policy:
            p = self.zone_policy[z]

        if p is None:
            p = copy(self.named_policy['default'])
            p.name = zone
            p.is_constructed = True

        if p.algorithm is None:
            parent = p.parent or self.named_policy['default']
            while parent and not parent.algorithm:
                parent = parent.parent
            p.algorithm = parent and parent.algorithm or None

        if p.algorithm in self.alg_policy:
            ap = self.alg_policy[p.algorithm]
        else:
            raise PolicyException('algorithm not found')

        if p.directory is None:
            parent = p.parent or self.named_policy['default']
            while parent is not None and not parent.directory:
                parent = parent.parent
            p.directory = parent and parent.directory

        if p.coverage is None:
            parent = p.parent or self.named_policy['default']
            while parent and not parent.coverage:
                parent = parent.parent
            p.coverage = parent and parent.coverage or ap.coverage

        if p.ksk_keysize is None:
            parent = p.parent or self.named_policy['default']
            while parent.parent and not parent.ksk_keysize:
                parent = parent.parent
            p.ksk_keysize = parent and parent.ksk_keysize or ap.ksk_keysize

        if p.zsk_keysize is None:
            parent = p.parent or self.named_policy['default']
            while parent.parent and not parent.zsk_keysize:
                parent = parent.parent
            p.zsk_keysize = parent and parent.zsk_keysize or ap.zsk_keysize

        if p.ksk_rollperiod is None:
            parent = p.parent or self.named_policy['default']
            while parent.parent and not parent.ksk_rollperiod:
                parent = parent.parent
            p.ksk_rollperiod = parent and \
                parent.ksk_rollperiod or ap.ksk_rollperiod

        if p.zsk_rollperiod is None:
            parent = p.parent or self.named_policy['default']
            while parent.parent and not parent.zsk_rollperiod:
                parent = parent.parent
            p.zsk_rollperiod = parent and \
                parent.zsk_rollperiod or ap.zsk_rollperiod

        if p.ksk_prepublish is None:
            parent = p.parent or self.named_policy['default']
            while parent.parent and not parent.ksk_prepublish:
                parent = parent.parent
            p.ksk_prepublish = parent and \
                parent.ksk_prepublish or ap.ksk_prepublish

        if p.zsk_prepublish is None:
            parent = p.parent or self.named_policy['default']
            while parent.parent and not parent.zsk_prepublish:
                parent = parent.parent
            p.zsk_prepublish = parent and \
                parent.zsk_prepublish or ap.zsk_prepublish

        if p.ksk_postpublish is None:
            parent = p.parent or self.named_policy['default']
            while parent.parent and not parent.ksk_postpublish:
                parent = parent.parent
            p.ksk_postpublish = parent and \
                parent.ksk_postpublish or ap.ksk_postpublish

        if p.zsk_postpublish is None:
            parent = p.parent or self.named_policy['default']
            while parent.parent and not parent.zsk_postpublish:
                parent = parent.parent
            p.zsk_postpublish = parent and \
                parent.zsk_postpublish or ap.zsk_postpublish

        if p.keyttl is None:
            parent = p.parent or self.named_policy['default']
            while parent is not None and not parent.keyttl:
                parent = parent.parent
            p.keyttl = parent and parent.keyttl

        if 'novalidate' not in kwargs or not kwargs['novalidate']:
            (valid, msg) = p.validate()
            if not valid:
                raise PolicyException(msg)
                return None

        return p


    def p_policylist(self, p):
        '''policylist : init policy
                      | policylist policy'''
        pass

    def p_init(self, p):
        "init :"
        self.initial = False

    def p_policy(self, p):
        '''policy : alg_policy
                  | zone_policy
                  | named_policy'''
        pass

    def p_name(self, p):
        '''name : STR
                | KEYTYPE
                | DATESUFFIX'''
        p[0] = p[1]
        pass

    def p_domain(self, p):
        '''domain : STR
                  | QSTRING
                  | KEYTYPE
                  | DATESUFFIX'''
        p[0] = p[1].strip()
        if not re.match(r'^[\w.-][\w.-]*$', p[0]):
            raise PolicyException('invalid domain')
        pass

    def p_new_policy(self, p):
        "new_policy :"
        self.current = Policy()

    def p_alg_policy(self, p):
        "alg_policy : ALGORITHM_POLICY ALGNAME new_policy alg_option_group SEMI"
        self.current.name = p[2]
        self.current.is_alg = True
        self.alg_policy[p[2]] = self.current
        pass

    def p_zone_policy(self, p):
        "zone_policy : ZONE domain new_policy policy_option_group SEMI"
        self.current.name = p[2].rstrip('.')
        self.current.is_zone = True
        self.zone_policy[p[2].rstrip('.').lower()] = self.current
        pass

    def p_named_policy(self, p):
        "named_policy : POLICY name new_policy policy_option_group SEMI"
        self.current.name = p[2]
        self.named_policy[p[2].lower()] = self.current
        pass

    def p_duration_1(self, p):
        "duration : NUMBER"
        p[0] = p[1]
        pass

    def p_duration_2(self, p):
        "duration : NONE"
        p[0] = None
        pass

    def p_duration_3(self, p):
        "duration : NUMBER DATESUFFIX"
        if p[2] == "y":
            p[0] = p[1] * 31536000 # year
        elif p[2] == "mo":
            p[0] = p[1] * 2592000  # month
        elif p[2] == "w":
            p[0] = p[1] * 604800   # week
        elif p[2] == "d":
            p[0] = p[1] * 86400    # day
        elif p[2] == "h":
            p[0] = p[1] * 3600     # hour
        elif p[2] == "mi":
            p[0] = p[1] * 60       # minute
        elif p[2] == "s":
            p[0] = p[1]            # second
        else:
            raise PolicyException('invalid duration')

    def p_policy_option_group(self, p):
        "policy_option_group : LBRACE policy_option_list RBRACE"
        pass

    def p_policy_option_list(self, p):
        '''policy_option_list : policy_option SEMI
                              | policy_option_list policy_option SEMI'''
        pass

    def p_policy_option(self, p):
        '''policy_option : parent_option
                         | directory_option
                         | coverage_option
                         | rollperiod_option
                         | prepublish_option
                         | postpublish_option
                         | keysize_option
                         | algorithm_option
                         | keyttl_option
                         | standby_option'''
        pass

    def p_alg_option_group(self, p):
        "alg_option_group : LBRACE alg_option_list RBRACE"
        pass

    def p_alg_option_list(self, p):
        '''alg_option_list : alg_option SEMI
                           | alg_option_list alg_option SEMI'''
        pass

    def p_alg_option(self, p):
        '''alg_option : coverage_option
                      | rollperiod_option
                      | prepublish_option
                      | postpublish_option
                      | keyttl_option
                      | keysize_option
                      | standby_option'''
        pass

    def p_parent_option(self, p):
        "parent_option : POLICY name"
        self.current.parent = self.named_policy[p[2].lower()]

    def p_directory_option(self, p):
        "directory_option : DIRECTORY QSTRING"
        self.current.directory = p[2]

    def p_coverage_option(self, p):
        "coverage_option : COVERAGE duration"
        self.current.coverage = p[2]

    def p_rollperiod_option(self, p):
        "rollperiod_option : ROLL_PERIOD KEYTYPE duration"
        if p[2] == "KSK":
            self.current.ksk_rollperiod = p[3]
        else:
            self.current.zsk_rollperiod = p[3]

    def p_prepublish_option(self, p):
        "prepublish_option : PRE_PUBLISH KEYTYPE duration"
        if p[2] == "KSK":
            self.current.ksk_prepublish = p[3]
        else:
            self.current.zsk_prepublish = p[3]

    def p_postpublish_option(self, p):
        "postpublish_option : POST_PUBLISH KEYTYPE duration"
        if p[2] == "KSK":
            self.current.ksk_postpublish = p[3]
        else:
            self.current.zsk_postpublish = p[3]

    def p_keysize_option(self, p):
        "keysize_option : KEY_SIZE KEYTYPE NUMBER"
        if p[2] == "KSK":
            self.current.ksk_keysize = p[3]
        else:
            self.current.zsk_keysize = p[3]

    def p_standby_option(self, p):
        "standby_option : STANDBY KEYTYPE NUMBER"
        if p[2] == "KSK":
            self.current.ksk_standby = p[3]
        else:
            self.current.zsk_standby = p[3]

    def p_keyttl_option(self, p):
        "keyttl_option : KEYTTL duration"
        self.current.keyttl = p[2]

    def p_algorithm_option(self, p):
        "algorithm_option : ALGORITHM ALGNAME"
        self.current.algorithm = p[2]

    def p_error(self, p):
        if p:
            print("%s%s%d:syntax error near '%s'" %
                    (self.filename or "", ":" if self.filename else "",
                     p.lineno, p.value))
        else:
            if not self.initial:
                raise PolicyException("%s%s%d:unexpected end of input" %
                    (self.filename or "", ":" if self.filename else "",
                     p and p.lineno or 0))

if __name__ == "__main__":
    import sys
    if sys.argv[1] == "lex":
        file = open(sys.argv[2])
        text = file.read()
        file.close()
        plex = PolicyLex(debug=1)
        plex.test(text)
    elif sys.argv[1] == "parse":
        try:
            pp = dnssec_policy(sys.argv[2], write_tables=True, debug=True)
            print(pp.named_policy['default'])
            print(pp.policy("nonexistent.zone"))
        except Exception as e:
            print(e.args[0])
__init__.py000064400000001651151733004510006657 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

__all__ = ['checkds', 'coverage', 'keymgr', 'dnskey', 'eventlist',
           'keydict', 'keyevent', 'keyseries', 'keyzone', 'policy',
           'parsetab', 'rndc', 'utils']

from isc.dnskey import *
from isc.eventlist import *
from isc.keydict import *
from isc.keyevent import *
from isc.keyseries import *
from isc.keyzone import *
from isc.policy import *
from isc.rndc import *
from isc.utils import *
keyevent.py000064400000005413151733004510006752 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

import time


########################################################################
# Class keyevent
########################################################################
class keyevent:
    """ A discrete key event, e.g., Publish, Activate, Inactive, Delete,
    etc. Stores the date of the event, and identifying information
    about the key to which the event will occur."""

    def __init__(self, what, key, when=None):
        self.what = what
        self.when = when or key.gettime(what)
        self.key = key
        self.sep = key.sep
        self.zone = key.name
        self.alg = key.alg
        self.keyid = key.keyid

    def __repr__(self):
        return repr((self.when, self.what, self.keyid, self.sep,
                     self.zone, self.alg))

    def showtime(self):
        return time.strftime("%a %b %d %H:%M:%S UTC %Y", self.when)

    # update sets of active and published keys, based on
    # the contents of this keyevent
    def status(self, active, published, output = None):
        def noop(*args, **kwargs): pass
        if not output:
            output = noop

        if not active:
            active = set()
        if not published:
            published = set()

        if self.what == "Activate":
            active.add(self.keyid)
        elif self.what == "Publish":
            published.add(self.keyid)
        elif self.what == "Inactive":
            if self.keyid not in active:
                output("\tWARNING: %s scheduled to become inactive "
                       "before it is active"
                       % repr(self.key))
            else:
                active.remove(self.keyid)
        elif self.what == "Delete":
            if self.keyid in published:
                published.remove(self.keyid)
            else:
                output("WARNING: key %s is scheduled for deletion "
                       "before it is published" % repr(self.key))
        elif self.what == "Revoke":
            # We don't need to worry about the logic of this one;
            # just stop counting this key as either active or published
            if self.keyid in published:
                published.remove(self.keyid)
            if self.keyid in active:
                active.remove(self.keyid)

        return active, published
keyseries.py000064400000021022151733004510007115 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

from collections import defaultdict
from .dnskey import *
from .keydict import *
from .keyevent import *
from .policy import *
import time


class keyseries:
    _K = defaultdict(lambda: defaultdict(list))
    _Z = defaultdict(lambda: defaultdict(list))
    _zones = set()
    _kdict = None
    _context = None

    def __init__(self, kdict, now=time.time(), context=None):
        self._kdict = kdict
        self._context = context
        self._zones = set(kdict.missing())

        for zone in kdict.zones():
            self._zones.add(zone)
            for alg, keys in kdict[zone].items():
                for k in keys.values():
                    if k.sep:
                        if not (k.delete() and k.delete() < now):
                          self._K[zone][alg].append(k)
                    else:
                        if not (k.delete() and k.delete() < now):
                          self._Z[zone][alg].append(k)

                self._K[zone][alg].sort()
                self._Z[zone][alg].sort()

    def __iter__(self):
        for zone in self._zones:
            for collection in [self._K, self._Z]:
                if zone not in collection:
                    continue
                for alg, keys in collection[zone].items():
                    for key in keys:
                        yield key

    def dump(self):
        for k in self:
            print("%s" % repr(k))

    def fixseries(self, keys, policy, now, **kwargs):
        force = kwargs.get('force', False)
        if not keys:
            return

        # handle the first key
        key = keys[0]
        if key.sep:
            rp = policy.ksk_rollperiod
            prepub = policy.ksk_prepublish or (30 * 86400)
            postpub = policy.ksk_postpublish or (30 * 86400)
        else:
            rp = policy.zsk_rollperiod
            prepub = policy.zsk_prepublish or (30 * 86400)
            postpub = policy.zsk_postpublish or (30 * 86400)

        # the first key should be published and active
        p = key.publish()
        a = key.activate()
        if not p or p > now:
            key.setpublish(now)
            p = now
        if not a or a > now:
            key.setactivate(now)
            a = now

        i = key.inactive()
        fudge = 300
        if not rp:
            key.setinactive(None, **kwargs)
            key.setdelete(None, **kwargs)
        elif not i or a + rp != i:
            if not i and a + rp > now + prepub + fudge:
                key.setinactive(a + rp, **kwargs)
                key.setdelete(a + rp + postpub, **kwargs)
            elif not i:
                key.setinactive(now + prepub + fudge, **kwargs)
                key.setdelete(now + prepub + postpub + fudge, **kwargs)
            elif i < now:
                pass
            elif a + rp > i:
                key.setinactive(a + rp, **kwargs)
                key.setdelete(a + rp + postpub, **kwargs)
            elif a + rp > now + prepub + fudge:
                key.setinactive(a + rp, **kwargs)
                key.setdelete(a + rp + postpub, **kwargs)
            else:
                key.setinactive(now + prepub + fudge, **kwargs)
                key.setdelete(now + prepub + postpub + fudge, **kwargs)
        else:
            d = key.delete()
            if not d or i + postpub > now + fudge:
                key.setdelete(i + postpub, **kwargs)
            elif not d:
                key.setdelete(now + postpub + fudge, **kwargs)
            elif d < now + fudge:
                pass
            elif d < i + postpub:
                key.setdelete(i + postpub, **kwargs)

        if policy.keyttl != key.ttl:
            key.setttl(policy.keyttl)

        # handle all the subsequent keys
        prev = key
        for key in keys[1:]:
            # if no rollperiod, then all keys after the first in
            # the series kept inactive.
            # (XXX: we need to change this to allow standby keys)
            if not rp:
                key.setpublish(None, **kwargs)
                key.setactivate(None, **kwargs)
                key.setinactive(None, **kwargs)
                key.setdelete(None, **kwargs)
                if policy.keyttl != key.ttl:
                    key.setttl(policy.keyttl)
                continue

            # otherwise, ensure all dates are set correctly based on
            # the initial key
            a = prev.inactive()
            p = a - prepub
            key.setactivate(a, **kwargs)
            key.setpublish(p, **kwargs)
            key.setinactive(a + rp, **kwargs)
            key.setdelete(a + rp + postpub, **kwargs)
            prev.setdelete(a + postpub, **kwargs)
            if policy.keyttl != key.ttl:
                key.setttl(policy.keyttl)
            prev = key

        # if we haven't got sufficient coverage, create successor key(s)
        while rp and prev.inactive() and \
              prev.inactive() < now + policy.coverage:
            # commit changes to predecessor: a successor can only be
            # generated if Inactive has been set in the predecessor key
            prev.commit(self._context['settime_path'], **kwargs)
            key = prev.generate_successor(self._context['keygen_path'],
                                          self._context['randomdev'],
                                          prepub, **kwargs)

            key.setinactive(key.activate() + rp, **kwargs)
            key.setdelete(key.inactive() + postpub, **kwargs)
            keys.append(key)
            prev = key

        # last key? we already know we have sufficient coverage now, so
        # disable the inactivation of the final key (if it was set),
        # ensuring that if dnssec-keymgr isn't run again, the last key
        # in the series will at least remain usable.
        prev.setinactive(None, **kwargs)
        prev.setdelete(None, **kwargs)

        # commit changes
        for key in keys:
            key.commit(self._context['settime_path'], **kwargs)


    def enforce_policy(self, policies, now=time.time(), **kwargs):
        # If zones is provided as a parameter, use that list.
        # If not, use what we have in this object
        zones = kwargs.get('zones', self._zones)
        keys_dir = kwargs.get('dir', self._context.get('keys_path', None))
        force = kwargs.get('force', False)

        for zone in zones:
            collections = []
            policy = policies.policy(zone)
            keys_dir = keys_dir or policy.directory or '.'
            alg = policy.algorithm
            algnum = dnskey.algnum(alg)
            if 'ksk' not in kwargs or not kwargs['ksk']:
                if len(self._Z[zone][algnum]) == 0:
                    k = dnskey.generate(self._context['keygen_path'],
                                        self._context['randomdev'],
                                        keys_dir, zone, alg,
                                        policy.zsk_keysize, False,
                                        policy.keyttl or 3600,
                                        **kwargs)
                    self._Z[zone][algnum].append(k)
                collections.append(self._Z[zone])

            if 'zsk' not in kwargs or not kwargs['zsk']:
                if len(self._K[zone][algnum]) == 0:
                    k = dnskey.generate(self._context['keygen_path'],
                                        self._context['randomdev'],
                                        keys_dir, zone, alg,
                                        policy.ksk_keysize, True,
                                        policy.keyttl or 3600,
                                        **kwargs)
                    self._K[zone][algnum].append(k)
                collections.append(self._K[zone])

            for collection in collections:
                for algorithm, keys in collection.items():
                    if algorithm != algnum:
                        continue
                    try:
                        self.fixseries(keys, policy, now, **kwargs)
                    except Exception as e:
                        raise Exception('%s/%s: %s' %
                                        (zone, dnskey.algstr(algnum), str(e)))
coverage.py000064400000023375151733004510006722 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

from __future__ import print_function
import os
import sys
import argparse
import glob
import re
import time
import calendar
import pprint
from collections import defaultdict

prog = 'dnssec-coverage'

from isc import dnskey, eventlist, keydict, keyevent, keyzone, utils

############################################################################
# print a fatal error and exit
############################################################################
def fatal(*args, **kwargs):
    print(*args, **kwargs)
    sys.exit(1)


############################################################################
# output:
############################################################################
_firstline = True
def output(*args, **kwargs):
    """output text, adding a vertical space this is *not* the first
    first section being printed since a call to vreset()"""
    global _firstline
    if 'skip' in kwargs:
        skip = kwargs['skip']
        kwargs.pop('skip', None)
    else:
        skip = True
    if _firstline:
        _firstline = False
    elif skip:
        print('')
    if args:
        print(*args, **kwargs)


def vreset():
    """reset vertical spacing"""
    global _firstline
    _firstline = True


############################################################################
# parse_time
############################################################################
def parse_time(s):
    """ convert a formatted time (e.g., 1y, 6mo, 15mi, etc) into seconds
    :param s: String with some text representing a time interval
    :return: Integer with the number of seconds in the time interval
    """
    s = s.strip()

    # if s is an integer, we're done already
    try:
        return int(s)
    except ValueError:
        pass

    # try to parse as a number with a suffix indicating unit of time
    r = re.compile(r'([0-9][0-9]*)\s*([A-Za-z]*)')
    m = r.match(s)
    if not m:
        raise ValueError("Cannot parse %s" % s)
    n, unit = m.groups()
    n = int(n)
    unit = unit.lower()
    if unit.startswith('y'):
        return n * 31536000
    elif unit.startswith('mo'):
        return n * 2592000
    elif unit.startswith('w'):
        return n * 604800
    elif unit.startswith('d'):
        return n * 86400
    elif unit.startswith('h'):
        return n * 3600
    elif unit.startswith('mi'):
        return n * 60
    elif unit.startswith('s'):
        return n
    else:
        raise ValueError("Invalid suffix %s" % unit)


############################################################################
# set_path:
############################################################################
def set_path(command, default=None):
    """ find the location of a specified command.  if a default is supplied
    and it works, we use it; otherwise we search PATH for a match.
    :param command: string with a command to look for in the path
    :param default: default location to use
    :return: detected location for the desired command
    """

    fpath = default
    if not fpath or not os.path.isfile(fpath) or not os.access(fpath, os.X_OK):
        path = os.environ["PATH"]
        if not path:
            path = os.path.defpath
        for directory in path.split(os.pathsep):
            fpath = os.path.join(directory, command)
            if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
                break
            fpath = None

    return fpath


############################################################################
# parse_args:
############################################################################
def parse_args():
    """Read command line arguments, set global 'args' structure"""
    compilezone = set_path('named-compilezone',
                           os.path.join(utils.prefix('sbin'),
                           'named-compilezone'))

    parser = argparse.ArgumentParser(description=prog + ': checks future ' +
                                     'DNSKEY coverage for a zone')

    parser.add_argument('zone', type=str, nargs='*', default=None,
                        help='zone(s) to check' +
                        '(default: all zones in the directory)')
    parser.add_argument('-K', dest='path', default='.', type=str,
                        help='a directory containing keys to process',
                        metavar='dir')
    parser.add_argument('-f', dest='filename', type=str,
                        help='zone master file', metavar='file')
    parser.add_argument('-m', dest='maxttl', type=str,
                        help='the longest TTL in the zone(s)',
                        metavar='time')
    parser.add_argument('-d', dest='keyttl', type=str,
                        help='the DNSKEY TTL', metavar='time')
    parser.add_argument('-r', dest='resign', default='1944000',
                        type=str, help='the RRSIG refresh interval '
                                       'in seconds [default: 22.5 days]',
                        metavar='time')
    parser.add_argument('-c', dest='compilezone',
                        default=compilezone, type=str,
                        help='path to \'named-compilezone\'',
                        metavar='path')
    parser.add_argument('-l', dest='checklimit',
                        type=str, default='0',
                        help='Length of time to check for '
                             'DNSSEC coverage [default: 0 (unlimited)]',
                        metavar='time')
    parser.add_argument('-z', dest='no_ksk',
                        action='store_true', default=False,
                        help='Only check zone-signing keys (ZSKs)')
    parser.add_argument('-k', dest='no_zsk',
                        action='store_true', default=False,
                        help='Only check key-signing keys (KSKs)')
    parser.add_argument('-D', '--debug', dest='debug_mode',
                        action='store_true', default=False,
                        help='Turn on debugging output')
    parser.add_argument('-v', '--version', action='version',
                        version=utils.version)

    args = parser.parse_args()

    if args.no_zsk and args.no_ksk:
        fatal("ERROR: -z and -k cannot be used together.")
    elif args.no_zsk or args.no_ksk:
        args.keytype = "KSK" if args.no_zsk else "ZSK"
    else:
        args.keytype = None

    if args.filename and len(args.zone) > 1:
        fatal("ERROR: -f can only be used with one zone.")

    # strip trailing dots if any
    args.zone = [x[:-1] if (len(x) > 1 and x[-1] == '.') else x
                        for x in args.zone]

    # convert from time arguments to seconds
    try:
        if args.maxttl:
            m = parse_time(args.maxttl)
            args.maxttl = m
    except ValueError:
        pass

    try:
        if args.keyttl:
            k = parse_time(args.keyttl)
            args.keyttl = k
    except ValueError:
        pass

    try:
        if args.resign:
            r = parse_time(args.resign)
            args.resign = r
    except ValueError:
        pass

    try:
        if args.checklimit:
            lim = args.checklimit
            r = parse_time(args.checklimit)
            if r == 0:
                args.checklimit = None
            else:
                args.checklimit = time.time() + r
    except ValueError:
        pass

    # if we've got the values we need from the command line, stop now
    if args.maxttl and args.keyttl:
        return args

    # load keyttl and maxttl data from zonefile
    if args.zone and args.filename:
        try:
            zone = keyzone(args.zone[0], args.filename, args.compilezone)
            args.maxttl = args.maxttl or zone.maxttl
            args.keyttl = args.maxttl or zone.keyttl
        except Exception as e:
            print("Unable to load zone data from %s: " % args.filename, e)

    if not args.maxttl:
        output("WARNING: Maximum TTL value was not specified.  Using 1 week\n"
               "\t (604800 seconds); re-run with the -m option to get more\n"
               "\t accurate results.")
        args.maxttl = 604800

    return args

############################################################################
# Main
############################################################################
def main():
    args = parse_args()

    print("PHASE 1--Loading keys to check for internal timing problems")

    try:
        kd = keydict(path=args.path, zones=args.zone, keyttl=args.keyttl)
    except Exception as e:
        fatal('ERROR: Unable to build key dictionary: ' + str(e))

    for key in kd:
        key.check_prepub(output)
        if key.sep:
            key.check_postpub(output)
        else:
            key.check_postpub(output, args.maxttl + args.resign)

    output("PHASE 2--Scanning future key events for coverage failures")
    vreset()

    try:
        elist = eventlist(kd)
    except Exception as e:
        fatal('ERROR: Unable to build event list: ' + str(e))

    errors = False
    if not args.zone:
        if not elist.coverage(None, args.keytype, args.checklimit, output):
            errors = True
    else:
        for zone in args.zone:
            try:
                if not elist.coverage(zone, args.keytype,
                                      args.checklimit, output):
                    errors = True
            except:
                output('ERROR: Coverage check failed for zone ' + zone)

    sys.exit(1 if errors else 0)
keymgr.py000064400000014553151733004510006423 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

from __future__ import print_function
import os, sys, argparse, glob, re, time, calendar, pprint
from collections import defaultdict

prog='dnssec-keymgr'

from isc import dnskey, keydict, keyseries, policy, parsetab, utils

############################################################################
# print a fatal error and exit
############################################################################
def fatal(*args, **kwargs):
    print(*args, **kwargs)
    sys.exit(1)

############################################################################
# find the location of an external command
############################################################################
def set_path(command, default=None):
    """ find the location of a specified command. If a default is supplied,
    exists and it's an executable, we use it; otherwise we search PATH
    for an alternative.
    :param command: command to look for
    :param default: default value to use
    :return: PATH with the location of a suitable binary
    """
    fpath = default
    if not fpath or not os.path.isfile(fpath) or not os.access(fpath, os.X_OK):
        path = os.environ["PATH"]
        if not path:
            path = os.path.defpath
        for directory in path.split(os.pathsep):
            fpath = directory + os.sep + command
            if os.path.isfile(fpath) and os.access(fpath, os.X_OK):
                break
            fpath = None

    return fpath

############################################################################
# parse arguments
############################################################################
def parse_args():
    """ Read command line arguments, returns 'args' object
    :return: args object properly prepared
    """

    keygen = set_path('dnssec-keygen',
                      os.path.join(utils.prefix('sbin'), 'dnssec-keygen'))
    settime = set_path('dnssec-settime',
                       os.path.join(utils.prefix('sbin'), 'dnssec-settime'))

    parser = argparse.ArgumentParser(description=prog + ': schedule '
                                     'DNSSEC key rollovers according to a '
                                     'pre-defined policy')

    parser.add_argument('zone', type=str, nargs='*', default=None,
                        help='Zone(s) to which the policy should be applied ' +
                        '(default: all zones in the directory)')
    parser.add_argument('-K', dest='path', type=str,
                        help='Directory containing keys', metavar='dir')
    parser.add_argument('-c', dest='policyfile', type=str,
                        help='Policy definition file', metavar='file')
    parser.add_argument('-g', dest='keygen', default=keygen, type=str,
                        help='Path to \'dnssec-keygen\'',
                        metavar='path')
    parser.add_argument('-r', dest='randomdev', type=str, default=None,
                        help='Path to a file containing random data to pass to \'dnssec-keygen\'',
                        metavar='path')
    parser.add_argument('-s', dest='settime', default=settime, type=str,
                        help='Path to \'dnssec-settime\'',
                        metavar='path')
    parser.add_argument('-k', dest='no_zsk',
                        action='store_true', default=False,
                        help='Only apply policy to key-signing keys (KSKs)')
    parser.add_argument('-z', dest='no_ksk',
                        action='store_true', default=False,
                        help='Only apply policy to zone-signing keys (ZSKs)')
    parser.add_argument('-f', '--force', dest='force', action='store_true',
                        default=False, help='Force updates to key events '+
                        'even if they are in the past')
    parser.add_argument('-q', '--quiet', dest='quiet', action='store_true',
                        default=False, help='Update keys silently')
    parser.add_argument('-v', '--version', action='version',
                        version=utils.version)

    args = parser.parse_args()

    if args.no_zsk and args.no_ksk:
        fatal("ERROR: -z and -k cannot be used together.")

    if args.keygen is None:
        fatal("ERROR: dnssec-keygen not found")

    if args.settime is None:
        fatal("ERROR: dnssec-settime not found")

    # if a policy file was specified, check that it exists.
    # if not, use the default file, unless it doesn't exist
    if args.policyfile is not None:
        if not os.path.exists(args.policyfile):
            fatal('ERROR: Policy file "%s" not found' % args.policyfile)
    else:
        args.policyfile = os.path.join(utils.sysconfdir,
                                       'dnssec-policy.conf')
        if not os.path.exists(args.policyfile):
            args.policyfile = None

    return args

############################################################################
# main
############################################################################
def main():
    args = parse_args()

    # As we may have specific locations for the binaries, we put that info
    # into a context object that can be passed around
    context = {'keygen_path': args.keygen,
               'settime_path': args.settime,
               'keys_path': args.path,
               'randomdev': args.randomdev}

    try:
        dp = policy.dnssec_policy(args.policyfile)
    except Exception as e:
        fatal('Unable to load DNSSEC policy: ' + str(e))

    try:
        kd = keydict(dp, path=args.path, zones=args.zone)
    except Exception as e:
        fatal('Unable to build key dictionary: ' + str(e))

    try:
        ks = keyseries(kd, context=context)
    except Exception as e:
        fatal('Unable to build key series: ' + str(e))

    try:
        ks.enforce_policy(dp, ksk=args.no_zsk, zsk=args.no_ksk,
                          force=args.force, quiet=args.quiet)
    except Exception as e:
        fatal('Unable to apply policy: ' + str(e))
checkds.py000064400000015446151733004510006533 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

import argparse
import os
import sys
from subprocess import Popen, PIPE

from isc.utils import prefix,version

prog = 'dnssec-checkds'


############################################################################
# SECRR class:
# Class for DS/DLV resource record
############################################################################
class SECRR:
    hashalgs = {1: 'SHA-1', 2: 'SHA-256', 3: 'GOST', 4: 'SHA-384'}
    rrname = ''
    rrclass = 'IN'
    keyid = None
    keyalg = None
    hashalg = None
    digest = ''
    ttl = 0

    def __init__(self, rrtext, dlvname = None):
        if not rrtext:
            raise Exception

        # 'str' does not have decode method in python3
        if type(rrtext) is not str:
            fields = rrtext.decode('ascii').split()
        else:
            fields = rrtext.split()
        if len(fields) < 7:
            raise Exception

        if dlvname:
            self.rrtype = "DLV"
            self.dlvname = dlvname.lower()
            parent = fields[0].lower().strip('.').split('.')
            parent.reverse()
            dlv = dlvname.split('.')
            dlv.reverse()
            while len(dlv) != 0 and len(parent) != 0 and parent[0] == dlv[0]:
                parent = parent[1:]
                dlv = dlv[1:]
            if dlv:
                raise Exception
            parent.reverse()
            self.parent = '.'.join(parent)
            self.rrname = self.parent + '.' + self.dlvname + '.'
        else:
            self.rrtype = "DS"
            self.rrname = fields[0].lower()

        fields = fields[1:]
        if fields[0].upper() in ['IN', 'CH', 'HS']:
            self.rrclass = fields[0].upper()
            fields = fields[1:]
        else:
            self.ttl = int(fields[0])
            self.rrclass = fields[1].upper()
            fields = fields[2:]

        if fields[0].upper() != self.rrtype:
            raise Exception('%s does not match %s' %
                            (fields[0].upper(), self.rrtype))

        self.keyid, self.keyalg, self.hashalg = map(int, fields[1:4])
        self.digest = ''.join(fields[4:]).upper()

    def __repr__(self):
        return '%s %s %s %d %d %d %s' % \
               (self.rrname, self.rrclass, self.rrtype,
                self.keyid, self.keyalg, self.hashalg, self.digest)

    def __eq__(self, other):
        return self.__repr__() == other.__repr__()


############################################################################
# check:
# Fetch DS/DLV RRset for the given zone from the DNS; fetch DNSKEY
# RRset from the masterfile if specified, or from DNS if not.
# Generate a set of expected DS/DLV records from the DNSKEY RRset,
# and report on congruency.
############################################################################
def check(zone, args, masterfile=None, lookaside=None):
    rrlist = []
    cmd = [args.dig, "+noall", "+answer", "-t", "dlv" if lookaside else "ds",
           "-q", zone + "." + lookaside if lookaside else zone]
    fp, _ = Popen(cmd, stdout=PIPE).communicate()

    for line in fp.splitlines():
        if type(line) is not str:
            line = line.decode('ascii')
        rrlist.append(SECRR(line, lookaside))
    rrlist = sorted(rrlist, key=lambda rr: (rr.keyid, rr.keyalg, rr.hashalg))

    klist = []

    if masterfile:
        cmd = [args.dsfromkey, "-f", masterfile]
        if lookaside:
            cmd += ["-l", lookaside]
        cmd.append(zone)
        fp, _ = Popen(cmd, stdout=PIPE).communicate()
    else:
        intods, _ = Popen([args.dig, "+noall", "+answer", "-t", "dnskey",
                           "-q", zone], stdout=PIPE).communicate()
        cmd = [args.dsfromkey, "-f", "-"]
        if lookaside:
            cmd += ["-l", lookaside]
        cmd.append(zone)
        fp, _ = Popen(cmd, stdin=PIPE, stdout=PIPE).communicate(intods)

    for line in fp.splitlines():
        if type(line) is not str:
            line = line.decode('ascii')
        klist.append(SECRR(line, lookaside))

    if len(klist) < 1:
        print("No DNSKEY records found in zone apex")
        return False

    found = False
    for rr in klist:
        if rr in rrlist:
            print("%s for KSK %s/%03d/%05d (%s) found in parent" %
                  (rr.rrtype, rr.rrname.strip('.'), rr.keyalg,
                   rr.keyid, SECRR.hashalgs[rr.hashalg]))
            found = True
        else:
            print("%s for KSK %s/%03d/%05d (%s) missing from parent" %
                  (rr.rrtype, rr.rrname.strip('.'), rr.keyalg,
                   rr.keyid, SECRR.hashalgs[rr.hashalg]))

    if not found:
        print("No %s records were found for any DNSKEY" % ("DLV" if lookaside else "DS"))

    return found

############################################################################
# parse_args:
# Read command line arguments, set global 'args' structure
############################################################################
def parse_args():
    parser = argparse.ArgumentParser(description=prog + ': checks DS coverage')

    bindir = 'bin'
    sbindir = 'bin' if os.name == 'nt' else 'sbin'

    parser.add_argument('zone', type=str, help='zone to check')
    parser.add_argument('-f', '--file', dest='masterfile', type=str,
                        help='zone master file')
    parser.add_argument('-l', '--lookaside', dest='lookaside', type=str,
                        help='DLV lookaside zone')
    parser.add_argument('-d', '--dig', dest='dig',
                        default=os.path.join(prefix(bindir), 'dig'),
                        type=str, help='path to \'dig\'')
    parser.add_argument('-D', '--dsfromkey', dest='dsfromkey',
                        default=os.path.join(prefix(sbindir),
                                             'dnssec-dsfromkey'),
                        type=str, help='path to \'dnssec-dsfromkey\'')
    parser.add_argument('-v', '--version', action='version',
                        version=version)
    args = parser.parse_args()

    args.zone = args.zone.strip('.')
    if args.lookaside:
        args.lookaside = args.lookaside.strip('.')

    return args


############################################################################
# Main
############################################################################
def main():
    args = parse_args()
    found = check(args.zone, args, args.masterfile, args.lookaside)
    exit(0 if found else 1)
parsetab.py000064400000017575151733004510006735 0ustar00
# parsetab.py
# This file is automatically generated. Do not edit.
_tabversion = '3.8'

_lr_method = 'LALR'

_lr_signature = 'C2FE91AF256AF1CCEB499107DA2CFE7E'
    
_lr_action_items = {'ALGORITHM_POLICY':([0,1,2,3,4,5,6,10,29,46,62,],[-3,7,7,-2,-4,-5,-6,-1,-15,-16,-17,]),'ZONE':([0,1,2,3,4,5,6,10,29,46,62,],[-3,8,8,-2,-4,-5,-6,-1,-15,-16,-17,]),'POLICY':([0,1,2,3,4,5,6,10,27,29,46,47,62,77,88,],[-3,9,9,-2,-4,-5,-6,-1,59,-15,-16,59,-17,-22,-23,]),'$end':([1,3,4,5,6,10,29,46,62,],[0,-2,-4,-5,-6,-1,-15,-16,-17,]),'ALGNAME':([7,61,],[11,80,]),'STR':([8,9,59,],[13,18,18,]),'QSTRING':([8,60,],[14,79,]),'KEYTYPE':([8,9,40,41,42,44,45,59,],[15,19,69,70,71,73,74,19,]),'DATESUFFIX':([8,9,59,67,],[16,20,20,82,]),'LBRACE':([11,12,13,14,15,16,17,18,19,20,21,22,23,],[-14,-14,-10,-11,-12,-13,-14,-7,-8,-9,25,27,27,]),'SEMI':([18,19,20,24,26,28,31,32,33,34,35,36,37,38,48,49,50,51,52,53,54,55,56,57,58,63,64,66,67,68,72,75,76,78,79,80,82,83,84,85,86,87,],[-7,-8,-9,29,46,62,65,-37,-38,-39,-40,-41,-42,-43,77,-24,-25,-26,-27,-28,-29,-30,-31,-32,-33,-34,81,-46,-18,-19,-52,-21,88,-44,-45,-53,-20,-47,-48,-49,-50,-51,]),'COVERAGE':([25,27,30,47,65,77,81,88,],[39,39,39,39,-35,-22,-36,-23,]),'ROLL_PERIOD':([25,27,30,47,65,77,81,88,],[40,40,40,40,-35,-22,-36,-23,]),'PRE_PUBLISH':([25,27,30,47,65,77,81,88,],[41,41,41,41,-35,-22,-36,-23,]),'POST_PUBLISH':([25,27,30,47,65,77,81,88,],[42,42,42,42,-35,-22,-36,-23,]),'KEYTTL':([25,27,30,47,65,77,81,88,],[43,43,43,43,-35,-22,-36,-23,]),'KEY_SIZE':([25,27,30,47,65,77,81,88,],[44,44,44,44,-35,-22,-36,-23,]),'STANDBY':([25,27,30,47,65,77,81,88,],[45,45,45,45,-35,-22,-36,-23,]),'DIRECTORY':([27,47,77,88,],[60,60,-22,-23,]),'ALGORITHM':([27,47,77,88,],[61,61,-22,-23,]),'RBRACE':([30,47,65,77,81,88,],[63,75,-35,-22,-36,-23,]),'NUMBER':([39,43,69,70,71,73,74,],[67,67,67,67,67,86,87,]),'NONE':([39,43,69,70,71,],[68,68,68,68,68,]),}

_lr_action = {}
for _k, _v in _lr_action_items.items():
   for _x,_y in zip(_v[0],_v[1]):
      if not _x in _lr_action:  _lr_action[_x] = {}
      _lr_action[_x][_k] = _y
del _lr_action_items

_lr_goto_items = {'policylist':([0,],[1,]),'init':([0,],[2,]),'policy':([1,2,],[3,10,]),'alg_policy':([1,2,],[4,4,]),'zone_policy':([1,2,],[5,5,]),'named_policy':([1,2,],[6,6,]),'domain':([8,],[12,]),'name':([9,59,],[17,78,]),'new_policy':([11,12,17,],[21,22,23,]),'alg_option_group':([21,],[24,]),'policy_option_group':([22,23,],[26,28,]),'alg_option_list':([25,],[30,]),'alg_option':([25,30,],[31,64,]),'coverage_option':([25,27,30,47,],[32,51,32,51,]),'rollperiod_option':([25,27,30,47,],[33,52,33,52,]),'prepublish_option':([25,27,30,47,],[34,53,34,53,]),'postpublish_option':([25,27,30,47,],[35,54,35,54,]),'keyttl_option':([25,27,30,47,],[36,57,36,57,]),'keysize_option':([25,27,30,47,],[37,55,37,55,]),'standby_option':([25,27,30,47,],[38,58,38,58,]),'policy_option_list':([27,],[47,]),'policy_option':([27,47,],[48,76,]),'parent_option':([27,47,],[49,49,]),'directory_option':([27,47,],[50,50,]),'algorithm_option':([27,47,],[56,56,]),'duration':([39,43,69,70,71,],[66,72,83,84,85,]),}

_lr_goto = {}
for _k, _v in _lr_goto_items.items():
   for _x, _y in zip(_v[0], _v[1]):
       if not _x in _lr_goto: _lr_goto[_x] = {}
       _lr_goto[_x][_k] = _y
del _lr_goto_items
_lr_productions = [
  ("S' -> policylist","S'",1,None,None,None),
  ('policylist -> init policy','policylist',2,'p_policylist','policy.py',523),
  ('policylist -> policylist policy','policylist',2,'p_policylist','policy.py',524),
  ('init -> <empty>','init',0,'p_init','policy.py',528),
  ('policy -> alg_policy','policy',1,'p_policy','policy.py',532),
  ('policy -> zone_policy','policy',1,'p_policy','policy.py',533),
  ('policy -> named_policy','policy',1,'p_policy','policy.py',534),
  ('name -> STR','name',1,'p_name','policy.py',538),
  ('name -> KEYTYPE','name',1,'p_name','policy.py',539),
  ('name -> DATESUFFIX','name',1,'p_name','policy.py',540),
  ('domain -> STR','domain',1,'p_domain','policy.py',545),
  ('domain -> QSTRING','domain',1,'p_domain','policy.py',546),
  ('domain -> KEYTYPE','domain',1,'p_domain','policy.py',547),
  ('domain -> DATESUFFIX','domain',1,'p_domain','policy.py',548),
  ('new_policy -> <empty>','new_policy',0,'p_new_policy','policy.py',555),
  ('alg_policy -> ALGORITHM_POLICY ALGNAME new_policy alg_option_group SEMI','alg_policy',5,'p_alg_policy','policy.py',559),
  ('zone_policy -> ZONE domain new_policy policy_option_group SEMI','zone_policy',5,'p_zone_policy','policy.py',566),
  ('named_policy -> POLICY name new_policy policy_option_group SEMI','named_policy',5,'p_named_policy','policy.py',573),
  ('duration -> NUMBER','duration',1,'p_duration_1','policy.py',579),
  ('duration -> NONE','duration',1,'p_duration_2','policy.py',584),
  ('duration -> NUMBER DATESUFFIX','duration',2,'p_duration_3','policy.py',589),
  ('policy_option_group -> LBRACE policy_option_list RBRACE','policy_option_group',3,'p_policy_option_group','policy.py',608),
  ('policy_option_list -> policy_option SEMI','policy_option_list',2,'p_policy_option_list','policy.py',612),
  ('policy_option_list -> policy_option_list policy_option SEMI','policy_option_list',3,'p_policy_option_list','policy.py',613),
  ('policy_option -> parent_option','policy_option',1,'p_policy_option','policy.py',617),
  ('policy_option -> directory_option','policy_option',1,'p_policy_option','policy.py',618),
  ('policy_option -> coverage_option','policy_option',1,'p_policy_option','policy.py',619),
  ('policy_option -> rollperiod_option','policy_option',1,'p_policy_option','policy.py',620),
  ('policy_option -> prepublish_option','policy_option',1,'p_policy_option','policy.py',621),
  ('policy_option -> postpublish_option','policy_option',1,'p_policy_option','policy.py',622),
  ('policy_option -> keysize_option','policy_option',1,'p_policy_option','policy.py',623),
  ('policy_option -> algorithm_option','policy_option',1,'p_policy_option','policy.py',624),
  ('policy_option -> keyttl_option','policy_option',1,'p_policy_option','policy.py',625),
  ('policy_option -> standby_option','policy_option',1,'p_policy_option','policy.py',626),
  ('alg_option_group -> LBRACE alg_option_list RBRACE','alg_option_group',3,'p_alg_option_group','policy.py',630),
  ('alg_option_list -> alg_option SEMI','alg_option_list',2,'p_alg_option_list','policy.py',634),
  ('alg_option_list -> alg_option_list alg_option SEMI','alg_option_list',3,'p_alg_option_list','policy.py',635),
  ('alg_option -> coverage_option','alg_option',1,'p_alg_option','policy.py',639),
  ('alg_option -> rollperiod_option','alg_option',1,'p_alg_option','policy.py',640),
  ('alg_option -> prepublish_option','alg_option',1,'p_alg_option','policy.py',641),
  ('alg_option -> postpublish_option','alg_option',1,'p_alg_option','policy.py',642),
  ('alg_option -> keyttl_option','alg_option',1,'p_alg_option','policy.py',643),
  ('alg_option -> keysize_option','alg_option',1,'p_alg_option','policy.py',644),
  ('alg_option -> standby_option','alg_option',1,'p_alg_option','policy.py',645),
  ('parent_option -> POLICY name','parent_option',2,'p_parent_option','policy.py',649),
  ('directory_option -> DIRECTORY QSTRING','directory_option',2,'p_directory_option','policy.py',653),
  ('coverage_option -> COVERAGE duration','coverage_option',2,'p_coverage_option','policy.py',657),
  ('rollperiod_option -> ROLL_PERIOD KEYTYPE duration','rollperiod_option',3,'p_rollperiod_option','policy.py',661),
  ('prepublish_option -> PRE_PUBLISH KEYTYPE duration','prepublish_option',3,'p_prepublish_option','policy.py',668),
  ('postpublish_option -> POST_PUBLISH KEYTYPE duration','postpublish_option',3,'p_postpublish_option','policy.py',675),
  ('keysize_option -> KEY_SIZE KEYTYPE NUMBER','keysize_option',3,'p_keysize_option','policy.py',682),
  ('standby_option -> STANDBY KEYTYPE NUMBER','standby_option',3,'p_standby_option','policy.py',689),
  ('keyttl_option -> KEYTTL duration','keyttl_option',2,'p_keyttl_option','policy.py',696),
  ('algorithm_option -> ALGORITHM ALGNAME','algorithm_option',2,'p_algorithm_option','policy.py',700),
]
dnskey.py000064400000040040151733004520006411 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

import os
import time
import calendar
from subprocess import Popen, PIPE

########################################################################
# Class dnskey
########################################################################
class TimePast(Exception):
    def __init__(self, key, prop, value):
        super(TimePast, self).__init__('%s time for key %s (%d) is already past'
                                       % (prop, key, value))

class dnskey:
    """An individual DNSSEC key.  Identified by path, name, algorithm, keyid.
    Contains a dictionary of metadata events."""

    _PROPS = ('Created', 'Publish', 'Activate', 'Inactive', 'Delete',
              'Revoke', 'DSPublish', 'SyncPublish', 'SyncDelete')
    _OPTS = (None, '-P', '-A', '-I', '-D', '-R', None, '-Psync', '-Dsync')

    _ALGNAMES = (None, 'RSAMD5', 'DH', 'DSA', 'ECC', 'RSASHA1',
                 'NSEC3DSA', 'NSEC3RSASHA1', 'RSASHA256', None,
                 'RSASHA512', None, 'ECCGOST', 'ECDSAP256SHA256',
                 'ECDSAP384SHA384', 'ED25519', 'ED448')

    def __init__(self, key, directory=None, keyttl=None):
        # this makes it possible to use algname as a class or instance method
        if isinstance(key, tuple) and len(key) == 3:
            self._dir = directory or '.'
            (name, alg, keyid) = key
            self.fromtuple(name, alg, keyid, keyttl)

        self._dir = directory or os.path.dirname(key) or '.'
        key = os.path.basename(key)
        (name, alg, keyid) = key.split('+')
        name = name[1:-1]
        alg = int(alg)
        keyid = int(keyid.split('.')[0])
        self.fromtuple(name, alg, keyid, keyttl)

    def fromtuple(self, name, alg, keyid, keyttl):
        if name.endswith('.'):
            fullname = name
            name = name.rstrip('.')
        else:
            fullname = name + '.'

        keystr = "K%s+%03d+%05d" % (fullname, alg, keyid)
        key_file = self._dir + (self._dir and os.sep or '') + keystr + ".key"
        private_file = (self._dir + (self._dir and os.sep or '') +
                        keystr + ".private")

        self.keystr = keystr

        self.name = name
        self.alg = int(alg)
        self.keyid = int(keyid)
        self.fullname = fullname

        kfp = open(key_file, "r")
        for line in kfp:
            if line[0] == ';':
                continue
            tokens = line.split()
            if not tokens:
                continue

            if tokens[1].lower() in ('in', 'ch', 'hs'):
                septoken = 3
                self.ttl = keyttl
            else:
                septoken = 4
                self.ttl = int(tokens[1]) if not keyttl else keyttl

            if (int(tokens[septoken]) & 0x1) == 1:
                self.sep = True
            else:
                self.sep = False
        kfp.close()

        pfp = open(private_file, "rU")

        self.metadata = dict()
        self._changed = dict()
        self._delete = dict()
        self._times = dict()
        self._fmttime = dict()
        self._timestamps = dict()
        self._original = dict()
        self._origttl = None

        for line in pfp:
            line = line.strip()
            if not line or line[0] in ('!#'):
                continue
            punctuation = [line.find(c) for c in ':= '] + [len(line)]
            found = min([pos for pos in punctuation if pos != -1])
            name = line[:found].rstrip()
            value = line[found:].lstrip(":= ").rstrip()
            self.metadata[name] = value

        for prop in dnskey._PROPS:
            self._changed[prop] = False
            if prop in self.metadata:
                t = self.parsetime(self.metadata[prop])
                self._times[prop] = t
                self._fmttime[prop] = self.formattime(t)
                self._timestamps[prop] = self.epochfromtime(t)
                self._original[prop] = self._timestamps[prop]
            else:
                self._times[prop] = None
                self._fmttime[prop] = None
                self._timestamps[prop] = None
                self._original[prop] = None

        pfp.close()

    def commit(self, settime_bin, **kwargs):
        quiet = kwargs.get('quiet', False)
        cmd = []
        first = True

        if self._origttl is not None:
            cmd += ["-L", str(self.ttl)]

        for prop, opt in zip(dnskey._PROPS, dnskey._OPTS):
            if not opt or not self._changed[prop]:
                continue

            delete = False
            if prop in self._delete and self._delete[prop]:
                delete = True

            when = 'none' if delete else self._fmttime[prop]
            cmd += [opt, when]
            first = False

        if cmd:
            fullcmd = [settime_bin, "-K", self._dir] + cmd + [self.keystr,]
            if not quiet:
                print('# ' + ' '.join(fullcmd))
            try:
                p = Popen(fullcmd, stdout=PIPE, stderr=PIPE)
                stdout, stderr = p.communicate()
                if stderr:
                    raise Exception(str(stderr))
            except Exception as e:
                raise Exception('unable to run %s: %s' %
                                (settime_bin, str(e)))
            self._origttl = None
            for prop in dnskey._PROPS:
                self._original[prop] = self._timestamps[prop]
                self._changed[prop] = False

    @classmethod
    def generate(cls, keygen_bin, randomdev, keys_dir, name, alg, keysize, sep,
                 ttl, publish=None, activate=None, **kwargs):
        quiet = kwargs.get('quiet', False)

        keygen_cmd = [keygen_bin, "-q", "-K", keys_dir, "-L", str(ttl)]

        if randomdev:
            keygen_cmd += ["-r", randomdev]

        if sep:
            keygen_cmd.append("-fk")

        if alg:
            keygen_cmd += ["-a", alg]

        if keysize:
            keygen_cmd += ["-b", str(keysize)]

        if publish:
            t = dnskey.timefromepoch(publish)
            keygen_cmd += ["-P", dnskey.formattime(t)]

        if activate:
            t = dnskey.timefromepoch(activate)
            keygen_cmd += ["-A", dnskey.formattime(activate)]

        keygen_cmd.append(name)

        if not quiet:
            print('# ' + ' '.join(keygen_cmd))

        p = Popen(keygen_cmd, stdout=PIPE, stderr=PIPE)
        stdout, stderr = p.communicate()
        if stderr:
            raise Exception('unable to generate key: ' + str(stderr))

        try:
            keystr = stdout.splitlines()[0].decode('ascii')
            newkey = dnskey(keystr, keys_dir, ttl)
            return newkey
        except Exception as e:
            raise Exception('unable to parse generated key: %s' % str(e))

    def generate_successor(self, keygen_bin, randomdev, prepublish, **kwargs):
        quiet = kwargs.get('quiet', False)

        if not self.inactive():
            raise Exception("predecessor key %s has no inactive date" % self)

        keygen_cmd = [keygen_bin, "-q", "-K", self._dir, "-S", self.keystr]

        if self.ttl:
            keygen_cmd += ["-L", str(self.ttl)]

        if randomdev:
            keygen_cmd += ["-r", randomdev]

        if prepublish:
            keygen_cmd += ["-i", str(prepublish)]

        if not quiet:
            print('# ' + ' '.join(keygen_cmd))

        p = Popen(keygen_cmd, stdout=PIPE, stderr=PIPE)
        stdout, stderr = p.communicate()
        if stderr:
            raise Exception('unable to generate key: ' + stderr)

        try:
            keystr = stdout.splitlines()[0].decode('ascii')
            newkey = dnskey(keystr, self._dir, self.ttl)
            return newkey
        except:
            raise Exception('unable to generate successor for key %s' % self)

    @staticmethod
    def algstr(alg):
        name = None
        if alg in range(len(dnskey._ALGNAMES)):
            name = dnskey._ALGNAMES[alg]
        return name if name else ("%03d" % alg)

    @staticmethod
    def algnum(alg):
        if not alg:
            return None
        alg = alg.upper()
        try:
            return dnskey._ALGNAMES.index(alg)
        except ValueError:
            return None

    def algname(self, alg=None):
        return self.algstr(alg or self.alg)

    @staticmethod
    def timefromepoch(secs):
        return time.gmtime(secs)

    @staticmethod
    def parsetime(string):
        return time.strptime(string, "%Y%m%d%H%M%S")

    @staticmethod
    def epochfromtime(t):
        return calendar.timegm(t)

    @staticmethod
    def formattime(t):
        return time.strftime("%Y%m%d%H%M%S", t)

    def setmeta(self, prop, secs, now, **kwargs):
        force = kwargs.get('force', False)

        if self._timestamps[prop] == secs:
            return

        if self._original[prop] is not None and \
           self._original[prop] < now and not force:
            raise TimePast(self, prop, self._original[prop])

        if secs is None:
            self._changed[prop] = False \
                if self._original[prop] is None else True

            self._delete[prop] = True
            self._timestamps[prop] = None
            self._times[prop] = None
            self._fmttime[prop] = None
            return

        t = self.timefromepoch(secs)
        self._timestamps[prop] = secs
        self._times[prop] = t
        self._fmttime[prop] = self.formattime(t)
        self._changed[prop] = False if \
            self._original[prop] == self._timestamps[prop] else True

    def gettime(self, prop):
        return self._times[prop]

    def getfmttime(self, prop):
        return self._fmttime[prop]

    def gettimestamp(self, prop):
        return self._timestamps[prop]

    def created(self):
        return self._timestamps["Created"]

    def syncpublish(self):
        return self._timestamps["SyncPublish"]

    def setsyncpublish(self, secs, now=time.time(), **kwargs):
        self.setmeta("SyncPublish", secs, now, **kwargs)

    def publish(self):
        return self._timestamps["Publish"]

    def setpublish(self, secs, now=time.time(), **kwargs):
        self.setmeta("Publish", secs, now, **kwargs)

    def activate(self):
        return self._timestamps["Activate"]

    def setactivate(self, secs, now=time.time(), **kwargs):
        self.setmeta("Activate", secs, now, **kwargs)

    def revoke(self):
        return self._timestamps["Revoke"]

    def setrevoke(self, secs, now=time.time(), **kwargs):
        self.setmeta("Revoke", secs, now, **kwargs)

    def inactive(self):
        return self._timestamps["Inactive"]

    def setinactive(self, secs, now=time.time(), **kwargs):
        self.setmeta("Inactive", secs, now, **kwargs)

    def delete(self):
        return self._timestamps["Delete"]

    def setdelete(self, secs, now=time.time(), **kwargs):
        self.setmeta("Delete", secs, now, **kwargs)

    def syncdelete(self):
        return self._timestamps["SyncDelete"]

    def setsyncdelete(self, secs, now=time.time(), **kwargs):
        self.setmeta("SyncDelete", secs, now, **kwargs)

    def setttl(self, ttl):
        if ttl is None or self.ttl == ttl:
            return
        elif self._origttl is None:
            self._origttl = self.ttl
            self.ttl = ttl
        elif self._origttl == ttl:
            self._origttl = None
            self.ttl = ttl
        else:
            self.ttl = ttl

    def keytype(self):
        return ("KSK" if self.sep else "ZSK")

    def __str__(self):
        return ("%s/%s/%05d"
                % (self.name, self.algname(), self.keyid))

    def __repr__(self):
        return ("%s/%s/%05d (%s)"
                % (self.name, self.algname(), self.keyid,
                   ("KSK" if self.sep else "ZSK")))

    def date(self):
        return (self.activate() or self.publish() or self.created())

    # keys are sorted first by zone name, then by algorithm. within
    # the same name/algorithm, they are sorted according to their
    # 'date' value: the activation date if set, OR the publication
    # if set, OR the creation date.
    def __lt__(self, other):
        if self.name != other.name:
            return self.name < other.name
        if self.alg != other.alg:
            return self.alg < other.alg
        return self.date() < other.date()

    def check_prepub(self, output=None):
        def noop(*args, **kwargs): pass
        if not output:
            output = noop

        now = int(time.time())
        a = self.activate()
        p = self.publish()

        if not a:
            return False

        if not p:
            if a > now:
                output("WARNING: Key %s is scheduled for\n"
                       "\t activation but not for publication."
                       % repr(self))
            return False

        if p <= now and a <= now:
            return True

        if p == a:
            output("WARNING: %s is scheduled to be\n"
                   "\t published and activated at the same time. This\n"
                   "\t could result in a coverage gap if the zone was\n"
                   "\t previously signed. Activation should be at least\n"
                   "\t %s after publication."
                   % (repr(self),
                       dnskey.duration(self.ttl) or 'one DNSKEY TTL'))
            return True

        if a < p:
            output("WARNING: Key %s is active before it is published"
                   % repr(self))
            return False

        if self.ttl is not None and a - p < self.ttl:
            output("WARNING: Key %s is activated too soon\n"
                   "\t after publication; this could result in coverage \n"
                   "\t gaps due to resolver caches containing old data.\n"
                   "\t Activation should be at least %s after\n"
                   "\t publication."
                   % (repr(self),
                      dnskey.duration(self.ttl) or 'one DNSKEY TTL'))
            return False

        return True

    def check_postpub(self, output = None, timespan = None):
        def noop(*args, **kwargs): pass
        if output is None:
            output = noop

        if timespan is None:
            timespan = self.ttl

        if timespan is None:
            output("WARNING: Key %s using default TTL." % repr(self))
            timespan = (60*60*24)

        now = time.time()
        d = self.delete()
        i = self.inactive()

        if not d:
            return False

        if not i:
            if d > now:
                output("WARNING: Key %s is scheduled for\n"
                       "\t deletion but not for inactivation." % repr(self))
            return False

        if d < now and i < now:
            return True

        if d < i:
            output("WARNING: Key %s is scheduled for\n"
                   "\t deletion before inactivation."
                   % repr(self))
            return False

        if d - i < timespan:
            output("WARNING: Key %s scheduled for\n"
                   "\t deletion too soon after deactivation; this may \n"
                   "\t result in coverage gaps due to resolver caches\n"
                   "\t containing old data.  Deletion should be at least\n"
                   "\t %s after inactivation."
                   % (repr(self), dnskey.duration(timespan)))
            return False

        return True

    @staticmethod
    def duration(secs):
        if not secs:
            return None

        units = [("year", 60*60*24*365),
                 ("month", 60*60*24*30),
                 ("day", 60*60*24),
                 ("hour", 60*60),
                 ("minute", 60),
                 ("second", 1)]

        output = []
        for unit in units:
            v, secs = secs // unit[1], secs % unit[1]
            if v > 0:
                output.append("%d %s%s" % (v, unit[0], "s" if v > 1 else ""))

        return ", ".join(output)

rndc.py000064400000015053151733004520006050 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

############################################################################
# rndc.py
# This module implements the RNDC control protocol.
############################################################################

from collections import OrderedDict
import time
import struct
import hashlib
import hmac
import base64
import random
import socket


class rndc(object):
    """RNDC protocol client library"""
    __algos = {'md5':    157,
               'sha1':   161,
               'sha224': 162,
               'sha256': 163,
               'sha384': 164,
               'sha512': 165}

    def __init__(self, host, algo, secret):
        """Creates a persistent connection to RNDC and logs in
        host - (ip, port) tuple
        algo - HMAC algorithm: one of md5, sha1, sha224, sha256, sha384, sha512
               (with optional prefix 'hmac-')
        secret - HMAC secret, base64 encoded"""
        self.host = host
        algo = algo.lower()
        if algo.startswith('hmac-'):
            algo = algo[5:]
        self.algo = algo
        self.hlalgo = getattr(hashlib, algo)
        self.secret = base64.b64decode(secret)
        self.ser = random.randint(0, 1 << 24)
        self.nonce = None
        self.__connect_login()

    def call(self, cmd):
        """Call a RNDC command, all parsing is done on the server side
        cmd - a complete string with a command (eg 'reload zone example.com')
        """
        return dict(self.__command(type=cmd)['_data'])

    def __serialize_dict(self, data, ignore_auth=False):
        rv = bytearray()
        for k, v in data.items():
            if ignore_auth and k == '_auth':
                continue
            rv += struct.pack('B', len(k)) + k.encode('ascii')
            if type(v) == str:
                rv += struct.pack('>BI', 1, len(v)) + v.encode('ascii')
            elif type(v) == bytes:
                rv += struct.pack('>BI', 1, len(v)) + v
            elif type(v) == bytearray:
                rv += struct.pack('>BI', 1, len(v)) + v
            elif type(v) == OrderedDict:
                sd = self.__serialize_dict(v)
                rv += struct.pack('>BI', 2, len(sd)) + sd
            else:
                raise NotImplementedError('Cannot serialize element of type %s'
                                          % type(v))
        return rv

    def __prep_message(self, *args, **kwargs):
        self.ser += 1
        now = int(time.time())
        data = OrderedDict(*args, **kwargs)

        d = OrderedDict()
        d['_auth'] = OrderedDict()
        d['_ctrl'] = OrderedDict()
        d['_ctrl']['_ser'] = str(self.ser)
        d['_ctrl']['_tim'] = str(now)
        d['_ctrl']['_exp'] = str(now+60)
        if self.nonce is not None:
            d['_ctrl']['_nonce'] = self.nonce
        d['_data'] = data

        msg = self.__serialize_dict(d, ignore_auth=True)
        hash = hmac.new(self.secret, msg, self.hlalgo).digest()
        bhash = base64.b64encode(hash)
        if self.algo == 'md5':
            d['_auth']['hmd5'] = struct.pack('22s', bhash)
        else:
            d['_auth']['hsha'] = bytearray(struct.pack('B88s',
                                             self.__algos[self.algo], bhash))
        msg = self.__serialize_dict(d)
        msg = struct.pack('>II', len(msg) + 4, 1) + msg
        return msg

    def __verify_msg(self, msg):
        if self.nonce is not None and msg['_ctrl']['_nonce'] != self.nonce:
            return False
        if self.algo == 'md5':
            bhash = msg['_auth']['hmd5']
        else:
            bhash = msg['_auth']['hsha'][1:]
        if type(bhash) == bytes:
            bhash = bhash.decode('ascii')
        bhash += '=' * (4 - (len(bhash) % 4))
        remote_hash = base64.b64decode(bhash)
        my_msg = self.__serialize_dict(msg, ignore_auth=True)
        my_hash = hmac.new(self.secret, my_msg, self.hlalgo).digest()
        return (my_hash == remote_hash)

    def __command(self, *args, **kwargs):
        msg = self.__prep_message(*args, **kwargs)
        sent = self.socket.send(msg)
        if sent != len(msg):
            raise IOError("Cannot send the message")

        header = self.socket.recv(8)
        if len(header) != 8:
            # What should we throw here? Bad auth can cause this...
            raise IOError("Can't read response header")

        length, version = struct.unpack('>II', header)
        if version != 1:
            raise NotImplementedError('Wrong message version %d' % version)

        # it includes the header
        length -= 4
        data = self.socket.recv(length, socket.MSG_WAITALL)
        if len(data) != length:
            raise IOError("Can't read response data")

        if type(data) == str:
            data = bytearray(data)
        msg = self.__parse_message(data)
        if not self.__verify_msg(msg):
            raise IOError("Authentication failure")

        return msg

    def __connect_login(self):
        self.socket = socket.create_connection(self.host)
        self.nonce = None
        msg = self.__command(type='null')
        self.nonce = msg['_ctrl']['_nonce']

    def __parse_element(self, input):
        pos = 0
        labellen = input[pos]
        pos += 1
        label = input[pos:pos+labellen].decode('ascii')
        pos += labellen
        type = input[pos]
        pos += 1
        datalen = struct.unpack('>I', input[pos:pos+4])[0]
        pos += 4
        data = input[pos:pos+datalen]
        pos += datalen
        rest = input[pos:]

        if type == 1:         # raw binary value
            return label, data, rest
        elif type == 2:       # dictionary
            d = OrderedDict()
            while len(data) > 0:
                ilabel, value, data = self.__parse_element(data)
                d[ilabel] = value
            return label, d, rest
        # TODO type 3 - list
        else:
            raise NotImplementedError('Unknown element type %d' % type)

    def __parse_message(self, input):
        rv = OrderedDict()
        hdata = None
        while len(input) > 0:
            label, value, input = self.__parse_element(input)
            rv[label] = value
        return rv
keyzone.py000064400000003677151733004520006617 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

import os
import sys
import re
from subprocess import Popen, PIPE

########################################################################
# Exceptions
########################################################################
class KeyZoneException(Exception):
    pass

########################################################################
# class keyzone
########################################################################
class keyzone:
    """reads a zone file to find data relevant to keys"""

    def __init__(self, name, filename, czpath):
        self.maxttl = None
        self.keyttl = None

        if not name:
            return

        if not czpath or not os.path.isfile(czpath) \
                or not os.access(czpath, os.X_OK):
            raise KeyZoneException('"named-compilezone" not found')
            return

        maxttl = keyttl = None

        fp, _ = Popen([czpath, "-o", "-", name, filename],
                      stdout=PIPE, stderr=PIPE).communicate()
        for line in fp.splitlines():
            if type(line) is not str:
                line = line.decode('ascii')
            if re.search('^[:space:]*;', line):
                continue
            fields = line.split()
            if not maxttl or int(fields[1]) > maxttl:
                maxttl = int(fields[1])
            if fields[3] == "DNSKEY":
                keyttl = int(fields[1])

        self.keyttl = keyttl
        self.maxttl = maxttl
keydict.py000064400000005441151733004530006557 0ustar00############################################################################
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
############################################################################

from collections import defaultdict
from . import dnskey
import os
import glob


########################################################################
# Class keydict
########################################################################
class keydict:
    """ A dictionary of keys, indexed by name, algorithm, and key id """

    _keydict = defaultdict(lambda: defaultdict(dict))
    _defttl = None
    _missing = []

    def __init__(self, dp=None, **kwargs):
        self._defttl = kwargs.get('keyttl', None)
        zones = kwargs.get('zones', None)

        if not zones:
            path = kwargs.get('path',None) or '.'
            self.readall(path)
        else:
            for zone in zones:
                if 'path' in kwargs and kwargs['path'] is not None:
                    path = kwargs['path']
                else:
                    path = dp and dp.policy(zone).directory or '.'
                if not self.readone(path, zone):
                    self._missing.append(zone)

    def readall(self, path):
        files = glob.glob(os.path.join(path, '*.private'))

        for infile in files:
            key = dnskey(infile, path, self._defttl)
            self._keydict[key.name][key.alg][key.keyid] = key

    def readone(self, path, zone):
        if not zone.endswith('.'):
            zone += '.'
        match='K' + zone + '+*.private'
        files = glob.glob(os.path.join(path, match))

        found = False
        for infile in files:
            key = dnskey(infile, path, self._defttl)
            if key.fullname != zone: # shouldn't ever happen
                continue
            keyname=key.name if zone != '.' else '.'
            self._keydict[keyname][key.alg][key.keyid] = key
            found = True

        return found

    def __iter__(self):
        for zone, algorithms in self._keydict.items():
            for alg, keys in algorithms.items():
                for key in keys.values():
                    yield key

    def __getitem__(self, name):
        return self._keydict[name]

    def zones(self):
        return (self._keydict.keys())

    def algorithms(self, zone):
        return (self._keydict[zone].keys())

    def keys(self, zone, alg):
        return (self._keydict[zone][alg].keys())

    def missing(self):
        return (self._missing)