Package dns :: Package rdtypes :: Package ANY :: Module NSEC3
[hide private]
[frames] | no frames]

Source Code for Module dns.rdtypes.ANY.NSEC3

  1  # Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. 
  2  # 
  3  # Permission to use, copy, modify, and distribute this software and its 
  4  # documentation for any purpose with or without fee is hereby granted, 
  5  # provided that the above copyright notice and this permission notice 
  6  # appear in all copies. 
  7  # 
  8  # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES 
  9  # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 
 10  # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR 
 11  # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
 12  # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
 13  # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 
 14  # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 
 15   
 16  import base64 
 17  import binascii 
 18  import string 
 19  import struct 
 20   
 21  import dns.exception 
 22  import dns.rdata 
 23  import dns.rdatatype 
 24  from dns._compat import xrange, text_type 
 25   
 26  try: 
 27      b32_hex_to_normal = string.maketrans('0123456789ABCDEFGHIJKLMNOPQRSTUV', 
 28                                           'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567') 
 29      b32_normal_to_hex = string.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', 
 30                                           '0123456789ABCDEFGHIJKLMNOPQRSTUV') 
 31  except AttributeError: 
 32      b32_hex_to_normal = bytes.maketrans(b'0123456789ABCDEFGHIJKLMNOPQRSTUV', 
 33                                          b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567') 
 34      b32_normal_to_hex = bytes.maketrans(b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', 
 35                                          b'0123456789ABCDEFGHIJKLMNOPQRSTUV') 
 36   
 37  # hash algorithm constants 
 38  SHA1 = 1 
 39   
 40  # flag constants 
 41  OPTOUT = 1 
42 43 44 -class NSEC3(dns.rdata.Rdata):
45 46 """NSEC3 record 47 48 @ivar algorithm: the hash algorithm number 49 @type algorithm: int 50 @ivar flags: the flags 51 @type flags: int 52 @ivar iterations: the number of iterations 53 @type iterations: int 54 @ivar salt: the salt 55 @type salt: string 56 @ivar next: the next name hash 57 @type next: string 58 @ivar windows: the windowed bitmap list 59 @type windows: list of (window number, string) tuples""" 60 61 __slots__ = ['algorithm', 'flags', 'iterations', 'salt', 'next', 'windows'] 62
63 - def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt, 64 next, windows):
65 super(NSEC3, self).__init__(rdclass, rdtype) 66 self.algorithm = algorithm 67 self.flags = flags 68 self.iterations = iterations 69 if isinstance(salt, text_type): 70 self.salt = salt.encode() 71 else: 72 self.salt = salt 73 self.next = next 74 self.windows = windows
75
76 - def to_text(self, origin=None, relativize=True, **kw):
77 next = base64.b32encode(self.next).translate( 78 b32_normal_to_hex).lower().decode() 79 if self.salt == b'': 80 salt = '-' 81 else: 82 salt = binascii.hexlify(self.salt).decode() 83 text = u'' 84 for (window, bitmap) in self.windows: 85 bits = [] 86 for i in xrange(0, len(bitmap)): 87 byte = bitmap[i] 88 for j in xrange(0, 8): 89 if byte & (0x80 >> j): 90 bits.append(dns.rdatatype.to_text(window * 256 + 91 i * 8 + j)) 92 text += (u' ' + u' '.join(bits)) 93 return u'%u %u %u %s %s%s' % (self.algorithm, self.flags, 94 self.iterations, salt, next, text)
95 96 @classmethod
97 - def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
98 algorithm = tok.get_uint8() 99 flags = tok.get_uint8() 100 iterations = tok.get_uint16() 101 salt = tok.get_string() 102 if salt == u'-': 103 salt = b'' 104 else: 105 salt = binascii.unhexlify(salt.encode('ascii')) 106 next = tok.get_string().encode( 107 'ascii').upper().translate(b32_hex_to_normal) 108 next = base64.b32decode(next) 109 rdtypes = [] 110 while 1: 111 token = tok.get().unescape() 112 if token.is_eol_or_eof(): 113 break 114 nrdtype = dns.rdatatype.from_text(token.value) 115 if nrdtype == 0: 116 raise dns.exception.SyntaxError("NSEC3 with bit 0") 117 if nrdtype > 65535: 118 raise dns.exception.SyntaxError("NSEC3 with bit > 65535") 119 rdtypes.append(nrdtype) 120 rdtypes.sort() 121 window = 0 122 octets = 0 123 prior_rdtype = 0 124 bitmap = bytearray(b'\0' * 32) 125 windows = [] 126 for nrdtype in rdtypes: 127 if nrdtype == prior_rdtype: 128 continue 129 prior_rdtype = nrdtype 130 new_window = nrdtype // 256 131 if new_window != window: 132 if octets != 0: 133 windows.append((window, ''.join(bitmap[0:octets]))) 134 bitmap = bytearray(b'\0' * 32) 135 window = new_window 136 offset = nrdtype % 256 137 byte = offset // 8 138 bit = offset % 8 139 octets = byte + 1 140 bitmap[byte] = bitmap[byte] | (0x80 >> bit) 141 if octets != 0: 142 windows.append((window, bitmap[0:octets])) 143 return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, 144 windows)
145
146 - def to_wire(self, file, compress=None, origin=None):
147 l = len(self.salt) 148 file.write(struct.pack("!BBHB", self.algorithm, self.flags, 149 self.iterations, l)) 150 file.write(self.salt) 151 l = len(self.next) 152 file.write(struct.pack("!B", l)) 153 file.write(self.next) 154 for (window, bitmap) in self.windows: 155 file.write(struct.pack("!BB", window, len(bitmap))) 156 file.write(bitmap)
157 158 @classmethod
159 - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
160 (algorithm, flags, iterations, slen) = \ 161 struct.unpack('!BBHB', wire[current: current + 5]) 162 163 current += 5 164 rdlen -= 5 165 salt = wire[current: current + slen].unwrap() 166 current += slen 167 rdlen -= slen 168 nlen = wire[current] 169 current += 1 170 rdlen -= 1 171 next = wire[current: current + nlen].unwrap() 172 current += nlen 173 rdlen -= nlen 174 windows = [] 175 while rdlen > 0: 176 if rdlen < 3: 177 raise dns.exception.FormError("NSEC3 too short") 178 window = wire[current] 179 octets = wire[current + 1] 180 if octets == 0 or octets > 32: 181 raise dns.exception.FormError("bad NSEC3 octets") 182 current += 2 183 rdlen -= 2 184 if rdlen < octets: 185 raise dns.exception.FormError("bad NSEC3 bitmap length") 186 bitmap = bytearray(wire[current: current + octets].unwrap()) 187 current += octets 188 rdlen -= octets 189 windows.append((window, bitmap)) 190 return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, 191 windows)
192