aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rpkid/rpki/left_right.py37
-rw-r--r--rpkid/rpki/pubproto.py117
-rwxr-xr-xrpkid/xml-parse-test.py13
3 files changed, 149 insertions, 18 deletions
diff --git a/rpkid/rpki/left_right.py b/rpkid/rpki/left_right.py
index 46c1c908..d7dd75ef 100644
--- a/rpkid/rpki/left_right.py
+++ b/rpkid/rpki/left_right.py
@@ -20,9 +20,8 @@ import base64, lxml.etree, time, traceback, os
import rpki.resource_set, rpki.x509, rpki.sql, rpki.exceptions, rpki.sax_utils
import rpki.https, rpki.up_down, rpki.relaxng, rpki.sundial, rpki.log, rpki.roa
-xmlns = "http://www.hactrn.net/uris/rpki/left-right-spec/"
-
-nsmap = { None : xmlns }
+left_right_xmlns = "http://www.hactrn.net/uris/rpki/left-right-spec/"
+left_right_nsmap = { None : left_right_xmlns }
# Enforce strict checking of XML "sender" field in up-down protocol
enforce_strict_up_down_xml_sender = False
@@ -34,6 +33,9 @@ class base_elt(object):
elements = ()
booleans = ()
+ xmlns = left_right_xmlns
+ nsmap = left_right_nsmap
+
def startElement(self, stack, name, attrs):
"""Default startElement() handler: just process attributes."""
self.read_attrs(attrs)
@@ -54,7 +56,7 @@ class base_elt(object):
def make_elt(self):
"""XML element constructor."""
- elt = lxml.etree.Element("{%s}%s" % (xmlns, self.element_name), nsmap = nsmap)
+ elt = lxml.etree.Element("{%s}%s" % (self.xmlns, self.element_name), nsmap = self.nsmap)
for key in self.attributes:
val = getattr(self, key, None)
if val is not None:
@@ -69,12 +71,22 @@ class base_elt(object):
if value is None:
value = getattr(self, name, None)
if value is not None:
- lxml.etree.SubElement(elt, "{%s}%s" % (xmlns, name), nsmap = nsmap).text = base64.b64encode(value)
+ lxml.etree.SubElement(elt, "{%s}%s" % (self.xmlns, name), nsmap = self.nsmap).text = base64.b64encode(value)
def __str__(self):
"""Convert a base_elt object to string format."""
lxml.etree.tostring(self.toXML(), pretty_print = True, encoding = "us-ascii")
+ @classmethod
+ def make_pdu(cls, **kargs):
+ """Generic left-right PDU constructor."""
+ self = cls()
+ for k,v in kargs.items():
+ if isinstance(v, bool):
+ v = 1 if v else 0
+ setattr(self, k, v)
+ return self
+
class data_elt(base_elt, rpki.sql.sql_persistant):
"""Virtual class for top-level left-right protocol data elements."""
@@ -86,16 +98,6 @@ class data_elt(base_elt, rpki.sql.sql_persistant):
"""Return BSC object to which this object links."""
return bsc_elt.sql_fetch(self.gctx, self.bsc_id)
- @classmethod
- def make_pdu(cls, **kargs):
- """Generic left-right PDU constructor."""
- self = cls()
- for k,v in kargs.items():
- if isinstance(v, bool):
- v = 1 if v else 0
- setattr(self, k, v)
- return self
-
def make_reply(self, r_pdu = None):
"""Construct a reply PDU."""
if r_pdu is None:
@@ -1025,6 +1027,9 @@ class report_error_elt(base_elt):
class msg(list):
"""Left-right PDU."""
+ xmlns = left_right_xmlns
+ nsmap = left_right_nsmap
+
## @var version
# Protocol version
version = 1
@@ -1058,7 +1063,7 @@ class msg(list):
def toXML(self):
"""Generate left-right PDU."""
- elt = lxml.etree.Element("{%s}msg" % (xmlns), nsmap = nsmap, version = str(self.version), type = self.type)
+ elt = lxml.etree.Element("{%s}msg" % (self.xmlns), nsmap = self.nsmap, version = str(self.version), type = self.type)
elt.extend([i.toXML() for i in self])
return elt
diff --git a/rpkid/rpki/pubproto.py b/rpkid/rpki/pubproto.py
new file mode 100644
index 00000000..39373f5a
--- /dev/null
+++ b/rpkid/rpki/pubproto.py
@@ -0,0 +1,117 @@
+# $Id$
+
+# Copyright (C) 2007--2008 American Registry for Internet Numbers ("ARIN")
+#
+# Permission to use, copy, modify, and distribute this software 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 ARIN DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ARIN 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.
+
+"""RPKI "publication" protocol.
+
+At the moment this module imports and tweaks classes from
+rpki.left_right. The code in question should be refactored at some
+point to make the imports cleaner, but it's faster to write it this
+way and see which things I end up using before spending time on
+refactoring stuff I don't really need....
+"""
+
+import base64, lxml.etree, time, traceback, os
+import rpki.resource_set, rpki.x509, rpki.sql, rpki.exceptions, rpki.sax_utils
+import rpki.https, rpki.up_down, rpki.relaxng, rpki.sundial, rpki.log, rpki.roa
+import rpki.left_right
+
+pubproto_xmlns = "http://www.hactrn.net/uris/rpki/publication-spec/"
+pubproto_nsmap = { None : pubproto_xmlns }
+
+class data_elt(rpki.left_right.base_elt):
+ """Virtual class for top-level publication protocol data elements.
+
+ This is a placeholder. It will probably end up being a mixin that
+ uses rpki.sql.sql_persistant, just like its counterpart in
+ rpki.left_right, but wait and see.
+ """
+
+ xmlns = pubproto_xmlns
+ nsmap = pubproto_nsmap
+
+class client_elt(data_elt):
+ """<client/> element."""
+
+ element_name = "client"
+ attributes = ("action", "tag", "client_id", "base_uri")
+ elements = ("bpki_cert", "bpki_glue")
+
+ bpki_cert = None
+ bpki_glue = None
+
+ def startElement(self, stack, name, attrs):
+ """Handle <client/> element."""
+ if name not in ("bpki_cert", "bpki_glue"):
+ assert name == self.element_name, "Unexpected name %s, stack %s" % (name, stack)
+ self.read_attrs(attrs)
+
+ def endElement(self, stack, name, text):
+ """Handle <client/> element."""
+ if name == "bpki_cert":
+ self.bpki_cert = rpki.x509.X509(Base64 = text)
+ self.clear_https_ta_cache = True
+ elif name == "bpki_glue":
+ self.bpki_glue = rpki.x509.X509(Base64 = text)
+ self.clear_https_ta_cache = True
+ else:
+ assert name == self.element_name, "Unexpected name %s, stack %s" % (name, stack)
+ stack.pop()
+
+ def toXML(self):
+ """Generate <client/> element."""
+ elt = self.make_elt()
+ if self.bpki_cert and not self.bpki_cert.empty():
+ self.make_b64elt(elt, "bpki_cert", self.bpki_cert.get_DER())
+ if self.bpki_glue and not self.bpki_glue.empty():
+ self.make_b64elt(elt, "bpki_glue", self.bpki_glue.get_DER())
+ return elt
+
+class report_error_elt(rpki.left_right.report_error_elt):
+ """<report_error/> element.
+
+ For now this is identical to its left_right equivilent.
+ """
+
+ pass
+
+class msg(rpki.left_right.msg):
+ """Publication PDU."""
+
+ xmlns = pubproto_xmlns
+ nsmap = pubproto_nsmap
+
+ ## @var version
+ # Protocol version
+ version = 1
+
+ ## @var pdus
+ # Dispatch table of PDUs for this protocol.
+ pdus = dict((x.element_name, x)
+ for x in (client_elt, report_error_elt))
+
+class sax_handler(rpki.sax_utils.handler):
+ """SAX handler for publication protocol."""
+
+ pdu = msg
+ name = "msg"
+ version = "1"
+
+class cms_msg(rpki.x509.XML_CMS_object):
+ """Class to hold a CMS-signed publication PDU."""
+
+ encoding = "us-ascii"
+ schema = rpki.relaxng.publication
+ saxify = sax_handler.saxify
diff --git a/rpkid/xml-parse-test.py b/rpkid/xml-parse-test.py
index 15e787da..e8747f65 100755
--- a/rpkid/xml-parse-test.py
+++ b/rpkid/xml-parse-test.py
@@ -15,9 +15,9 @@
# PERFORMANCE OF THIS SOFTWARE.
import glob, xml.sax, lxml.etree, lxml.sax, POW, POW.pkix
-import rpki.up_down, rpki.left_right, rpki.relaxng
+import rpki.up_down, rpki.left_right, rpki.pubproto, rpki.relaxng
-verbose = False
+verbose = True
def test(fileglob, rng, sax_handler, encoding, tester = None):
files = glob.glob(fileglob)
@@ -73,6 +73,9 @@ def lr_tester(elt_in, elt_out, msg):
pprint(((obj.bpki_cert, "Certificate"),
(obj.bpki_glue, "Glue")))
+def pp_tester(elt_in, elt_out, msg):
+ assert isinstance(msg, rpki.pubproto.msg)
+
test(fileglob = "up-down-protocol-samples/*.xml",
rng = rpki.relaxng.up_down,
sax_handler = rpki.up_down.sax_handler,
@@ -84,3 +87,9 @@ test(fileglob = "left-right-protocol-samples/*.xml",
sax_handler = rpki.left_right.sax_handler,
encoding = "us-ascii",
tester = lr_tester)
+
+test(fileglob = "publication-protocol-samples/*.xml",
+ rng = rpki.relaxng.publication,
+ sax_handler = rpki.pubproto.sax_handler,
+ encoding = "us-ascii",
+ tester = pp_tester)