summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Halley <halley@dnspython.org>2006-06-21 23:01:46 +0000
committerBob Halley <halley@dnspython.org>2006-06-21 23:01:46 +0000
commit02a55dc7583df5438c46336b8eac3bee1b1066f3 (patch)
tree10810dd11e54212e5238c060e0e071f5bd138009
parent88722b030e9919504c563222d083ba20f5127ffb (diff)
downloaddnspython-02a55dc7583df5438c46336b8eac3bee1b1066f3.tar.gz
add SPF support
-rw-r--r--ChangeLog4
-rw-r--r--dns/rdatatype.py2
-rw-r--r--dns/rdtypes/ANY/TXT.py76
-rw-r--r--dns/rdtypes/txtbase.py88
-rw-r--r--tests/example1
-rw-r--r--tests/example1.good1
-rw-r--r--tests/example2.good1
7 files changed, 102 insertions, 71 deletions
diff --git a/ChangeLog b/ChangeLog
index 65045e4..162c108 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-06-21 Bob Halley <halley@dnspython.org>
+
+ * dns/rdtypes/ANY/SPF.py: Added support for the SPF RR type.
+
2006-06-02 Bob Halley <halley@dnspython.org>
* (Version 1.4.0 released)
diff --git a/dns/rdatatype.py b/dns/rdatatype.py
index 839ad01..0f29bd7 100644
--- a/dns/rdatatype.py
+++ b/dns/rdatatype.py
@@ -74,6 +74,7 @@ SSHFP = 44
RRSIG = 46
NSEC = 47
DNSKEY = 48
+SPF = 99
UNSPEC = 103
TKEY = 249
TSIG = 250
@@ -128,6 +129,7 @@ _by_text = {
'RRSIG' : RRSIG,
'NSEC' : NSEC,
'DNSKEY' : DNSKEY,
+ 'SPF' : SPF,
'UNSPEC' : UNSPEC,
'TKEY' : TKEY,
'TSIG' : TSIG,
diff --git a/dns/rdtypes/ANY/TXT.py b/dns/rdtypes/ANY/TXT.py
index 0aa5f2f..60a79a6 100644
--- a/dns/rdtypes/ANY/TXT.py
+++ b/dns/rdtypes/ANY/TXT.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2003-2005 Nominum, Inc.
+# Copyright (C) 2003-2006 Nominum, Inc.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose with or without fee is hereby granted,
@@ -13,74 +13,8 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-import dns.exception
-import dns.rdata
-import dns.tokenizer
+import dns.rdtypes.txtbase
-class TXT(dns.rdata.Rdata):
- """TXT record
-
- @ivar strings: the text strings
- @type strings: list of string
- @see: RFC 1035"""
-
- __slots__ = ['strings']
-
- def __init__(self, rdclass, rdtype, strings):
- super(TXT, self).__init__(rdclass, rdtype)
- if isinstance(strings, str):
- strings = [ strings ]
- self.strings = strings[:]
-
- def to_text(self, origin=None, relativize=True, **kw):
- txt = ''
- prefix = ''
- for s in self.strings:
- txt += '%s"%s"' % (prefix, dns.rdata._escapify(s))
- prefix = ' '
- return txt
-
- def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
- strings = []
- while 1:
- (ttype, s) = tok.get()
- if ttype == dns.tokenizer.EOL or ttype == dns.tokenizer.EOF:
- break
- if ttype != dns.tokenizer.QUOTED_STRING and \
- ttype != dns.tokenizer.IDENTIFIER:
- raise dns.exception.SyntaxError, "expected a string"
- if len(s) > 255:
- raise dns.exception.SyntaxError, "string too long"
- strings.append(s)
- if len(strings) == 0:
- raise dns.exception.UnexpectedEnd
- return cls(rdclass, rdtype, strings)
-
- from_text = classmethod(from_text)
-
- def to_wire(self, file, compress = None, origin = None):
- for s in self.strings:
- l = len(s)
- assert l < 256
- byte = chr(l)
- file.write(byte)
- file.write(s)
-
- def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
- strings = []
- while rdlen > 0:
- l = ord(wire[current])
- current += 1
- rdlen -= 1
- if l > rdlen:
- raise dns.exception.FormError
- s = wire[current : current + l]
- current += l
- rdlen -= l
- strings.append(s)
- return cls(rdclass, rdtype, strings)
-
- from_wire = classmethod(from_wire)
-
- def _cmp(self, other):
- return cmp(self.strings, other.strings)
+class TXT(dns.rdtypes.txtbase.TXTBase):
+ """TXT record"""
+ pass
diff --git a/dns/rdtypes/txtbase.py b/dns/rdtypes/txtbase.py
new file mode 100644
index 0000000..ec3c046
--- /dev/null
+++ b/dns/rdtypes/txtbase.py
@@ -0,0 +1,88 @@
+# Copyright (C) 2003-2005 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""TXT-like base class."""
+
+import dns.exception
+import dns.rdata
+import dns.tokenizer
+
+class TXTBase(dns.rdata.Rdata):
+ """Base class for rdata that is like a TXT record
+
+ @ivar strings: the text strings
+ @type strings: list of string
+ @see: RFC 1035"""
+
+ __slots__ = ['strings']
+
+ def __init__(self, rdclass, rdtype, strings):
+ super(TXTBase, self).__init__(rdclass, rdtype)
+ if isinstance(strings, str):
+ strings = [ strings ]
+ self.strings = strings[:]
+
+ def to_text(self, origin=None, relativize=True, **kw):
+ txt = ''
+ prefix = ''
+ for s in self.strings:
+ txt += '%s"%s"' % (prefix, dns.rdata._escapify(s))
+ prefix = ' '
+ return txt
+
+ def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
+ strings = []
+ while 1:
+ (ttype, s) = tok.get()
+ if ttype == dns.tokenizer.EOL or ttype == dns.tokenizer.EOF:
+ break
+ if ttype != dns.tokenizer.QUOTED_STRING and \
+ ttype != dns.tokenizer.IDENTIFIER:
+ raise dns.exception.SyntaxError, "expected a string"
+ if len(s) > 255:
+ raise dns.exception.SyntaxError, "string too long"
+ strings.append(s)
+ if len(strings) == 0:
+ raise dns.exception.UnexpectedEnd
+ return cls(rdclass, rdtype, strings)
+
+ from_text = classmethod(from_text)
+
+ def to_wire(self, file, compress = None, origin = None):
+ for s in self.strings:
+ l = len(s)
+ assert l < 256
+ byte = chr(l)
+ file.write(byte)
+ file.write(s)
+
+ def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
+ strings = []
+ while rdlen > 0:
+ l = ord(wire[current])
+ current += 1
+ rdlen -= 1
+ if l > rdlen:
+ raise dns.exception.FormError
+ s = wire[current : current + l]
+ current += l
+ rdlen -= l
+ strings.append(s)
+ return cls(rdclass, rdtype, strings)
+
+ from_wire = classmethod(from_wire)
+
+ def _cmp(self, other):
+ return cmp(self.strings, other.strings)
diff --git a/tests/example b/tests/example
index 4833201..f705e10 100644
--- a/tests/example
+++ b/tests/example
@@ -205,3 +205,4 @@ dnskey02 DNSKEY HOST|FLAG4 DNSSEC RSAMD5 (
;
unknown3 A \# 4 7f000002
sshfp1 SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab
+spf SPF "v=spf1 mx -all"
diff --git a/tests/example1.good b/tests/example1.good
index d80b8ed..fbbbdb8 100644
--- a/tests/example1.good
+++ b/tests/example1.good
@@ -78,6 +78,7 @@ rt02 3600 IN RT 65535 .
s 300 IN NS ns.s
ns.s 300 IN A 73.80.65.49
sig01 3600 IN SIG NXT 1 3 3600 20200101000000 20030101000000 2143 foo MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY=
+spf 3600 IN SPF "v=spf1 mx -all"
srv01 3600 IN SRV 0 0 0 .
srv02 3600 IN SRV 65535 65535 65535 old-slow-box.example.com.
sshfp1 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab
diff --git a/tests/example2.good b/tests/example2.good
index 62d6ace..32256a0 100644
--- a/tests/example2.good
+++ b/tests/example2.good
@@ -78,6 +78,7 @@ rt02.example. 3600 IN RT 65535 .
s.example. 300 IN NS ns.s.example.
ns.s.example. 300 IN A 73.80.65.49
sig01.example. 3600 IN SIG NXT 1 3 3600 20200101000000 20030101000000 2143 foo.example. MxFcby9k/yvedMfQgKzhH5er0Mu/vILz 45IkskceFGgiWCn/GxHhai6VAuHAoNUz 4YoU1tVfSCSqQYn6//11U6Nld80jEeC8 aTrO+KKmCaY=
+spf.example. 3600 IN SPF "v=spf1 mx -all"
srv01.example. 3600 IN SRV 0 0 0 .
srv02.example. 3600 IN SRV 65535 65535 65535 old-slow-box.example.com.
sshfp1.example. 3600 IN SSHFP 1 1 aa549bfe898489c02d1715d97d79c57ba2fa76ab