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 cStringIO 
 18  import string 
 19  import struct 
 20   
 21  import dns.exception 
 22  import dns.rdata 
 23  import dns.rdatatype 
 24   
 25  b32_hex_to_normal = string.maketrans('0123456789ABCDEFGHIJKLMNOPQRSTUV', 
 26                                       'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567') 
 27  b32_normal_to_hex = string.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', 
 28                                       '0123456789ABCDEFGHIJKLMNOPQRSTUV') 
 29   
 30  # hash algorithm constants 
 31  SHA1 = 1 
 32   
 33  # flag constants 
 34  OPTOUT = 1 
 35   
36 -class NSEC3(dns.rdata.Rdata):
37 """NSEC3 record 38 39 @ivar algorithm: the hash algorithm number 40 @type algorithm: int 41 @ivar flags: the flags 42 @type flags: int 43 @ivar iterations: the number of iterations 44 @type iterations: int 45 @ivar salt: the salt 46 @type salt: string 47 @ivar next: the next name hash 48 @type next: string 49 @ivar windows: the windowed bitmap list 50 @type windows: list of (window number, string) tuples""" 51 52 __slots__ = ['algorithm', 'flags', 'iterations', 'salt', 'next', 'windows'] 53
54 - def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt, 55 next, windows):
56 super(NSEC3, self).__init__(rdclass, rdtype) 57 self.algorithm = algorithm 58 self.flags = flags 59 self.iterations = iterations 60 self.salt = salt 61 self.next = next 62 self.windows = windows
63
64 - def to_text(self, origin=None, relativize=True, **kw):
65 next = base64.b32encode(self.next).translate(b32_normal_to_hex).lower() 66 if self.salt == '': 67 salt = '-' 68 else: 69 salt = self.salt.encode('hex-codec') 70 text = '' 71 for (window, bitmap) in self.windows: 72 bits = [] 73 for i in xrange(0, len(bitmap)): 74 byte = ord(bitmap[i]) 75 for j in xrange(0, 8): 76 if byte & (0x80 >> j): 77 bits.append(dns.rdatatype.to_text(window * 256 + \ 78 i * 8 + j)) 79 text += (' ' + ' '.join(bits)) 80 return '%u %u %u %s %s%s' % (self.algorithm, self.flags, self.iterations, 81 salt, next, text)
82
83 - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
84 algorithm = tok.get_uint8() 85 flags = tok.get_uint8() 86 iterations = tok.get_uint16() 87 salt = tok.get_string() 88 if salt == '-': 89 salt = '' 90 else: 91 salt = salt.decode('hex-codec') 92 next = tok.get_string().upper().translate(b32_hex_to_normal) 93 next = base64.b32decode(next) 94 rdtypes = [] 95 while 1: 96 token = tok.get().unescape() 97 if token.is_eol_or_eof(): 98 break 99 nrdtype = dns.rdatatype.from_text(token.value) 100 if nrdtype == 0: 101 raise dns.exception.SyntaxError("NSEC3 with bit 0") 102 if nrdtype > 65535: 103 raise dns.exception.SyntaxError("NSEC3 with bit > 65535") 104 rdtypes.append(nrdtype) 105 rdtypes.sort() 106 window = 0 107 octets = 0 108 prior_rdtype = 0 109 bitmap = ['\0'] * 32 110 windows = [] 111 for nrdtype in rdtypes: 112 if nrdtype == prior_rdtype: 113 continue 114 prior_rdtype = nrdtype 115 new_window = nrdtype // 256 116 if new_window != window: 117 windows.append((window, ''.join(bitmap[0:octets]))) 118 bitmap = ['\0'] * 32 119 window = new_window 120 offset = nrdtype % 256 121 byte = offset // 8 122 bit = offset % 8 123 octets = byte + 1 124 bitmap[byte] = chr(ord(bitmap[byte]) | (0x80 >> bit)) 125 windows.append((window, ''.join(bitmap[0:octets]))) 126 return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, windows)
127 128 from_text = classmethod(from_text) 129
130 - def to_wire(self, file, compress = None, origin = None):
131 l = len(self.salt) 132 file.write(struct.pack("!BBHB", self.algorithm, self.flags, 133 self.iterations, l)) 134 file.write(self.salt) 135 l = len(self.next) 136 file.write(struct.pack("!B", l)) 137 file.write(self.next) 138 for (window, bitmap) in self.windows: 139 file.write(chr(window)) 140 file.write(chr(len(bitmap))) 141 file.write(bitmap)
142
143 - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
144 (algorithm, flags, iterations, slen) = struct.unpack('!BBHB', 145 wire[current : current + 5]) 146 current += 5 147 rdlen -= 5 148 salt = wire[current : current + slen].unwrap() 149 current += slen 150 rdlen -= slen 151 (nlen, ) = struct.unpack('!B', wire[current]) 152 current += 1 153 rdlen -= 1 154 next = wire[current : current + nlen].unwrap() 155 current += nlen 156 rdlen -= nlen 157 windows = [] 158 while rdlen > 0: 159 if rdlen < 3: 160 raise dns.exception.FormError("NSEC3 too short") 161 window = ord(wire[current]) 162 octets = ord(wire[current + 1]) 163 if octets == 0 or octets > 32: 164 raise dns.exception.FormError("bad NSEC3 octets") 165 current += 2 166 rdlen -= 2 167 if rdlen < octets: 168 raise dns.exception.FormError("bad NSEC3 bitmap length") 169 bitmap = wire[current : current + octets].unwrap() 170 current += octets 171 rdlen -= octets 172 windows.append((window, bitmap)) 173 return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, windows)
174 175 from_wire = classmethod(from_wire) 176
177 - def _cmp(self, other):
178 b1 = cStringIO.StringIO() 179 self.to_wire(b1) 180 b2 = cStringIO.StringIO() 181 other.to_wire(b2) 182 return cmp(b1.getvalue(), b2.getvalue())
183