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

# Source Code for Module dns.rdtypes.ANY.HIP

      1  # Copyright (C) 2010, 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 cStringIO
     17  import string
     18  import struct
     19
     20  import dns.exception
     21  import dns.rdata
     22  import dns.rdatatype
     23
     24 -class HIP(dns.rdata.Rdata):
     25      """HIP record
     26
     27      @ivar hit: the host identity tag
     28      @type hit: string
     29      @ivar algorithm: the public key cryptographic algorithm
     30      @type algorithm: int
     31      @ivar key: the public key
     32      @type key: string
     33      @ivar servers: the rendezvous servers
     34      @type servers: list of dns.name.Name objects
     35      @see: RFC 5205"""
     36
     37      __slots__ = ['hit', 'algorithm', 'key', 'servers']
     38
     39 -    def __init__(self, rdclass, rdtype, hit, algorithm, key, servers):
     40          super(HIP, self).__init__(rdclass, rdtype)
     41          self.hit = hit
     42          self.algorithm = algorithm
     43          self.key = key
     44          self.servers = servers
     45
     46 -    def to_text(self, origin=None, relativize=True, **kw):
     47          hit = self.hit.encode('hex-codec')
     48          key = self.key.encode('base64-codec').replace('\n', '')
     49          text = ''
     50          servers = []
     51          for server in self.servers:
     52              servers.append(str(server.choose_relativity(origin, relativize)))
     53          if len(servers) > 0:
     54              text += (' ' + ' '.join(servers))
     55          return '%u %s %s%s' % (self.algorithm, hit, key, text)
     56
     57 -    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
     58          algorithm = tok.get_uint8()
     59          hit = tok.get_string().decode('hex-codec')
     60          if len(hit) > 255:
     61              raise dns.exception.SyntaxError("HIT too long")
     62          key = tok.get_string().decode('base64-codec')
     63          servers = []
     64          while 1:
     65              token = tok.get()
     66              if token.is_eol_or_eof():
     67                  break
     68              server = dns.name.from_text(token.value, origin)
     69              server.choose_relativity(origin, relativize)
     70              servers.append(server)
     71          return cls(rdclass, rdtype, hit, algorithm, key, servers)
     72
     73      from_text = classmethod(from_text)
     74
     75 -    def to_wire(self, file, compress = None, origin = None):
     76          lh = len(self.hit)
     77          lk = len(self.key)
     78          file.write(struct.pack("!BBH", lh, self.algorithm, lk))
     79          file.write(self.hit)
     80          file.write(self.key)
     81          for server in self.servers:
     82              server.to_wire(file, None, origin)
     83
     84 -    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
     85          (lh, algorithm, lk) = struct.unpack('!BBH',
     86                                              wire[current : current + 4])
     87          current += 4
     88          rdlen -= 4
     89          hit = wire[current : current + lh].unwrap()
     90          current += lh
     91          rdlen -= lh
     92          key = wire[current : current + lk].unwrap()
     93          current += lk
     94          rdlen -= lk
     95          servers = []
     96          while rdlen > 0:
     97              (server, cused) = dns.name.from_wire(wire[: current + rdlen],
     98                                                   current)
     99              current += cused
    100              rdlen -= cused
    101              if not origin is None:
    102                  server = server.relativize(origin)
    103              servers.append(server)
    104          return cls(rdclass, rdtype, hit, algorithm, key, servers)
    105
    106      from_wire = classmethod(from_wire)
    107
    108 -    def choose_relativity(self, origin = None, relativize = True):
    109          servers = []
    110          for server in self.servers:
    111              server = server.choose_relativity(origin, relativize)
    112              servers.append(server)
    113          self.servers = servers
    114
    115 -    def _cmp(self, other):
    116          b1 = cStringIO.StringIO()
    117          lh = len(self.hit)
    118          lk = len(self.key)
    119          b1.write(struct.pack("!BBH", lh, self.algorithm, lk))
    120          b1.write(self.hit)
    121          b1.write(self.key)
    122          b2 = cStringIO.StringIO()
    123          lh = len(other.hit)
    124          lk = len(other.key)
    125          b2.write(struct.pack("!BBH", lh, other.algorithm, lk))
    126          b2.write(other.hit)
    127          b2.write(other.key)
    128          v = cmp(b1.getvalue(), b2.getvalue())
    129          if v != 0:
    130              return v
    131          ls = len(self.servers)
    132          lo = len(other.servers)
    133          count = min(ls, lo)
    134          i = 0
    135          while i < count:
    136              v = cmp(self.servers[i], other.servers[i])
    137              if v != 0:
    138                  return v
    139              i += 1
    140          return ls - lo
    141