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

# Source Code for Module dns.rdtypes.sigbase

      1  # Copyright (C) 2004-2007, 2009, 2010 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 calendar
     17  import struct
     18  import time
     19
     20  import dns.dnssec
     21  import dns.exception
     22  import dns.rdata
     23  import dns.rdatatype
     24
     25 -class BadSigTime(dns.exception.DNSException):
     26      """Raised when a SIG or RRSIG RR's time cannot be parsed."""
     27      pass
     28
     29 -def sigtime_to_posixtime(what):
     30      if len(what) != 14:
     31          raise BadSigTime
     32      year = int(what[0:4])
     33      month = int(what[4:6])
     34      day = int(what[6:8])
     35      hour = int(what[8:10])
     36      minute = int(what[10:12])
     37      second = int(what[12:14])
     38      return calendar.timegm((year, month, day, hour, minute, second,
     39                              0, 0, 0))
     40
     41 -def posixtime_to_sigtime(what):
     42      return time.strftime('%Y%m%d%H%M%S', time.gmtime(what))
     43
     44 -class SIGBase(dns.rdata.Rdata):
     45      """SIG-like record base
     46
     47      @ivar type_covered: the rdata type this signature covers
     48      @type type_covered: int
     49      @ivar algorithm: the algorithm used for the sig
     50      @type algorithm: int
     51      @ivar labels: number of labels
     52      @type labels: int
     53      @ivar original_ttl: the original TTL
     54      @type original_ttl: long
     55      @ivar expiration: signature expiration time
     56      @type expiration: long
     57      @ivar inception: signature inception time
     58      @type inception: long
     59      @ivar key_tag: the key tag
     60      @type key_tag: int
     61      @ivar signer: the signer
     62      @type signer: dns.name.Name object
     63      @ivar signature: the signature
     64      @type signature: string"""
     65
     66      __slots__ = ['type_covered', 'algorithm', 'labels', 'original_ttl',
     67                   'expiration', 'inception', 'key_tag', 'signer',
     68                   'signature']
     69
     70 -    def __init__(self, rdclass, rdtype, type_covered, algorithm, labels,
     71                   original_ttl, expiration, inception, key_tag, signer,
     72                   signature):
     73          super(SIGBase, self).__init__(rdclass, rdtype)
     74          self.type_covered = type_covered
     75          self.algorithm = algorithm
     76          self.labels = labels
     77          self.original_ttl = original_ttl
     78          self.expiration = expiration
     79          self.inception = inception
     80          self.key_tag = key_tag
     81          self.signer = signer
     82          self.signature = signature
     83
     84 -    def covers(self):
     85          return self.type_covered
     86
     87 -    def to_text(self, origin=None, relativize=True, **kw):
     88          return '%s %d %d %d %s %s %d %s %s' % (
     89              dns.rdatatype.to_text(self.type_covered),
     90              self.algorithm,
     91              self.labels,
     92              self.original_ttl,
     93              posixtime_to_sigtime(self.expiration),
     94              posixtime_to_sigtime(self.inception),
     95              self.key_tag,
     96              self.signer,
     97              dns.rdata._base64ify(self.signature)
     98              )
     99
    100 -    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
    101          type_covered = dns.rdatatype.from_text(tok.get_string())
    102          algorithm = dns.dnssec.algorithm_from_text(tok.get_string())
    103          labels = tok.get_int()
    104          original_ttl = tok.get_ttl()
    105          expiration = sigtime_to_posixtime(tok.get_string())
    106          inception = sigtime_to_posixtime(tok.get_string())
    107          key_tag = tok.get_int()
    108          signer = tok.get_name()
    109          signer = signer.choose_relativity(origin, relativize)
    110          chunks = []
    111          while 1:
    112              t = tok.get().unescape()
    113              if t.is_eol_or_eof():
    114                  break
    115              if not t.is_identifier():
    116                  raise dns.exception.SyntaxError
    117              chunks.append(t.value)
    118          b64 = ''.join(chunks)
    119          signature = b64.decode('base64_codec')
    120          return cls(rdclass, rdtype, type_covered, algorithm, labels,
    121                     original_ttl, expiration, inception, key_tag, signer,
    122                     signature)
    123
    124      from_text = classmethod(from_text)
    125
    126 -    def to_wire(self, file, compress = None, origin = None):
    127          header = struct.pack('!HBBIIIH', self.type_covered,
    128                               self.algorithm, self.labels,
    129                               self.original_ttl, self.expiration,
    130                               self.inception, self.key_tag)
    131          file.write(header)
    132          self.signer.to_wire(file, None, origin)
    133          file.write(self.signature)
    134
    135 -    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
    136          header = struct.unpack('!HBBIIIH', wire[current : current + 18])
    137          current += 18
    138          rdlen -= 18
    139          (signer, cused) = dns.name.from_wire(wire[: current + rdlen], current)
    140          current += cused
    141          rdlen -= cused
    142          if not origin is None:
    143              signer = signer.relativize(origin)
    144          signature = wire[current : current + rdlen]
    145          return cls(rdclass, rdtype, header[0], header[1], header[2],
    146                     header[3], header[4], header[5], header[6], signer,
    147                     signature)
    148
    149      from_wire = classmethod(from_wire)
    150
    151 -    def choose_relativity(self, origin = None, relativize = True):
    152          self.signer = self.signer.choose_relativity(origin, relativize)
    153
    154 -    def _cmp(self, other):
    155          return self._wire_cmp(other)
    156