1# Copyright (C) Internet Systems Consortium, Inc. ("ISC") 2# 3# SPDX-License-Identifier: MPL-2.0 4# 5# This Source Code Form is subject to the terms of the Mozilla Public 6# License, v. 2.0. If a copy of the MPL was not distributed with this 7# file, you can obtain one at https://mozilla.org/MPL/2.0/. 8# 9# See the COPYRIGHT file distributed with this work for additional 10# information regarding copyright ownership. 11 12from collections import defaultdict 13from . import dnskey 14import os 15import glob 16 17 18######################################################################## 19# Class keydict 20######################################################################## 21class keydict: 22 """ A dictionary of keys, indexed by name, algorithm, and key id """ 23 24 _keydict = defaultdict(lambda: defaultdict(dict)) 25 _defttl = None 26 _missing = [] 27 28 def __init__(self, dp=None, **kwargs): 29 self._defttl = kwargs.get('keyttl', None) 30 zones = kwargs.get('zones', None) 31 32 if not zones: 33 path = kwargs.get('path',None) or '.' 34 self.readall(path) 35 else: 36 for zone in zones: 37 if 'path' in kwargs and kwargs['path'] is not None: 38 path = kwargs['path'] 39 else: 40 path = dp and dp.policy(zone).directory or '.' 41 if not self.readone(path, zone): 42 self._missing.append(zone) 43 44 def readall(self, path): 45 files = glob.glob(os.path.join(path, '*.private')) 46 47 for infile in files: 48 key = dnskey(infile, path, self._defttl) 49 self._keydict[key.name][key.alg][key.keyid] = key 50 51 def readone(self, path, zone): 52 if not zone.endswith('.'): 53 zone += '.' 54 match='K' + zone + '+*.private' 55 files = glob.glob(os.path.join(path, match)) 56 57 found = False 58 for infile in files: 59 key = dnskey(infile, path, self._defttl) 60 if key.fullname != zone: # shouldn't ever happen 61 continue 62 keyname=key.name if zone != '.' else '.' 63 self._keydict[keyname][key.alg][key.keyid] = key 64 found = True 65 66 return found 67 68 def __iter__(self): 69 for zone, algorithms in self._keydict.items(): 70 for alg, keys in algorithms.items(): 71 for key in keys.values(): 72 yield key 73 74 def __getitem__(self, name): 75 return self._keydict[name] 76 77 def zones(self): 78 return (self._keydict.keys()) 79 80 def algorithms(self, zone): 81 return (self._keydict[zone].keys()) 82 83 def keys(self, zone, alg): 84 return (self._keydict[zone][alg].keys()) 85 86 def missing(self): 87 return (self._missing) 88