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 if octets != 0: 118 windows.append((window, ''.join(bitmap[0:octets]))) 119 bitmap = ['\0'] * 32 120 window = new_window 121 offset = nrdtype % 256 122 byte = offset // 8 123 bit = offset % 8 124 octets = byte + 1 125 bitmap[byte] = chr(ord(bitmap[byte]) | (0x80 >> bit)) 126 if octets != 0: 127 windows.append((window, ''.join(bitmap[0:octets]))) 128 return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, windows)
129 130 from_text = classmethod(from_text) 131
132 - def to_wire(self, file, compress = None, origin = None):
133 l = len(self.salt) 134 file.write(struct.pack("!BBHB", self.algorithm, self.flags, 135 self.iterations, l)) 136 file.write(self.salt) 137 l = len(self.next) 138 file.write(struct.pack("!B", l)) 139 file.write(self.next) 140 for (window, bitmap) in self.windows: 141 file.write(chr(window)) 142 file.write(chr(len(bitmap))) 143 file.write(bitmap)
144
145 - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
146 (algorithm, flags, iterations, slen) = struct.unpack('!BBHB', 147 wire[current : current + 5]) 148 current += 5 149 rdlen -= 5 150 salt = wire[current : current + slen].unwrap() 151 current += slen 152 rdlen -= slen 153 (nlen, ) = struct.unpack('!B', wire[current]) 154 current += 1 155 rdlen -= 1 156 next = wire[current : current + nlen].unwrap() 157 current += nlen 158 rdlen -= nlen 159 windows = [] 160 while rdlen > 0: 161 if rdlen < 3: 162 raise dns.exception.FormError("NSEC3 too short") 163 window = ord(wire[current]) 164 octets = ord(wire[current + 1]) 165 if octets == 0 or octets > 32: 166 raise dns.exception.FormError("bad NSEC3 octets") 167 current += 2 168 rdlen -= 2 169 if rdlen < octets: 170 raise dns.exception.FormError("bad NSEC3 bitmap length") 171 bitmap = wire[current : current + octets].unwrap() 172 current += octets 173 rdlen -= octets 174 windows.append((window, bitmap)) 175 return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, windows)
176 177 from_wire = classmethod(from_wire) 178
179 - def _cmp(self, other):
180 b1 = cStringIO.StringIO() 181 self.to_wire(b1) 182 b2 = cStringIO.StringIO() 183 other.to_wire(b2) 184 return cmp(b1.getvalue(), b2.getvalue())
185