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 struct
     17  import base64
     18  import binascii
     19
     20  import dns.exception
     21  import dns.rdata
     22  import dns.rdatatype
     23
     24
     25 -class HIP(dns.rdata.Rdata):
     26
     27      """HIP record
     28
     29      @ivar hit: the host identity tag
     30      @type hit: string
     31      @ivar algorithm: the public key cryptographic algorithm
     32      @type algorithm: int
     33      @ivar key: the public key
     34      @type key: string
     35      @ivar servers: the rendezvous servers
     36      @type servers: list of dns.name.Name objects
     37      @see: RFC 5205"""
     38
     39      __slots__ = ['hit', 'algorithm', 'key', 'servers']
     40
     41 -    def __init__(self, rdclass, rdtype, hit, algorithm, key, servers):
     42          super(HIP, self).__init__(rdclass, rdtype)
     43          self.hit = hit
     44          self.algorithm = algorithm
     45          self.key = key
     46          self.servers = servers
     47
     48 -    def to_text(self, origin=None, relativize=True, **kw):
     49          hit = binascii.hexlify(self.hit).decode()
     50          key = base64.b64encode(self.key).replace(b'\n', b'').decode()
     51          text = u''
     52          servers = []
     53          for server in self.servers:
     54              servers.append(server.choose_relativity(origin, relativize))
     55          if len(servers) > 0:
     56              text += (u' ' + u' '.join((x.to_unicode() for x in servers)))
     57          return u'%u %s %s%s' % (self.algorithm, hit, key, text)
     58
     59      @classmethod
     60 -    def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
     61          algorithm = tok.get_uint8()
     62          hit = binascii.unhexlify(tok.get_string().encode())
     63          if len(hit) > 255:
     64              raise dns.exception.SyntaxError("HIT too long")
     65          key = base64.b64decode(tok.get_string().encode())
     66          servers = []
     67          while 1:
     68              token = tok.get()
     69              if token.is_eol_or_eof():
     70                  break
     71              server = dns.name.from_text(token.value, origin)
     72              server.choose_relativity(origin, relativize)
     73              servers.append(server)
     74          return cls(rdclass, rdtype, hit, algorithm, key, servers)
     75
     76 -    def to_wire(self, file, compress=None, origin=None):
     77          lh = len(self.hit)
     78          lk = len(self.key)
     79          file.write(struct.pack("!BBH", lh, self.algorithm, lk))
     80          file.write(self.hit)
     81          file.write(self.key)
     82          for server in self.servers:
     83              server.to_wire(file, None, origin)
     84
     85      @classmethod
     86 -    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None):
     87          (lh, algorithm, lk) = struct.unpack('!BBH',
     88                                              wire[current: current + 4])
     89          current += 4
     90          rdlen -= 4
     91          hit = wire[current: current + lh].unwrap()
     92          current += lh
     93          rdlen -= lh
     94          key = wire[current: current + lk].unwrap()
     95          current += lk
     96          rdlen -= lk
     97          servers = []
     98          while rdlen > 0:
     99              (server, cused) = dns.name.from_wire(wire[: current + rdlen],
    100                                                   current)
    101              current += cused
    102              rdlen -= cused
    103              if origin is not None:
    104                  server = server.relativize(origin)
    105              servers.append(server)
    106          return cls(rdclass, rdtype, hit, algorithm, key, servers)
    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