diff options
author | Rob Austein <sra@hactrn.net> | 2015-10-09 23:24:32 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2015-10-09 23:24:32 +0000 |
commit | ba0ee92b80646633c50b24700b04515cc563487a (patch) | |
tree | fa1b728c51d3246554e1a43e01f41f2c84ccdb05 /rpki/rpkid.py | |
parent | 122d0b33982d94f8a6c96356462a2d6fa062d948 (diff) |
Unwind more of the left_right XML processing from the old
rpki.left_right classes.
svn path=/branches/tk705/; revision=6106
Diffstat (limited to 'rpki/rpkid.py')
-rw-r--r-- | rpki/rpkid.py | 162 |
1 files changed, 148 insertions, 14 deletions
diff --git a/rpki/rpkid.py b/rpki/rpkid.py index f6f8b98f..ce7368df 100644 --- a/rpki/rpkid.py +++ b/rpki/rpkid.py @@ -42,7 +42,7 @@ import rpki.async import rpki.daemonize import rpki.rpkid_tasks -from lxml.etree import Element, SubElement +from lxml.etree import Element, SubElement, tostring as ElementToString logger = logging.getLogger(__name__) @@ -104,6 +104,12 @@ class main(object): if self.profile: logger.info("Running in profile mode with output to %s", self.profile) + import django + django.setup() + + global rpki + import rpki.rpkidb + self.sql = rpki.sql.session(self.cfg) self.bpki_ta = rpki.x509.X509(Auto_update = self.cfg.get("bpki-ta")) @@ -273,10 +279,92 @@ class main(object): return self._left_right_trivial_handlers except AttributeError: self._left_right_trivial_handlers = { - tag_list_published_objects : self.handle_list_published_objects, - tag_list_received_resources : self.handle_list_received_resources } + rpki.left_right.tag_list_published_objects : self.handle_list_published_objects, + rpki.left_right.tag_list_received_resources : self.handle_list_received_resources } return self._left_right_trivial_handlers + def handle_list_published_objects(self, q_pdu, r_msg): + """ + <list_published_objects/> server. + + This is written for the old SQL API, will need rewriting once we + switch rpkid to Django ORM. + """ + + logger.debug(".handle_list_published_objects() %s", ElementToString(q_pdu)) + + self_handle = q_pdu.get("self_handle") + msg_tag = q_pdu.get("tag") + + kw = dict(self_handle = self_handle) + if msg_tag is not None: + kw.update(tag = msg_tag) + + for parent in rpki.left_right.self_elt.serve_fetch_handle(self, None, self_handle).parents: + for ca in parent.cas: + ca_detail = ca.active_ca_detail + if ca_detail is not None: + + SubElement(r_msg, rpki.left_right.tag_list_published_objects, + uri = ca_detail.crl_uri, **kw).text = ca_detail.latest_crl.get_Base64() + + SubElement(r_msg, rpki.left_right.tag_list_published_objects, + uri = ca_detail.manifest_uri, **kw).text = ca_detail.latest_manifest.get_Base64() + + for c in ca_detail.child_certs: + SubElement(r_msg, rpki.left_right.tag_list_published_objects, + uri = c.uri, child_handle = c.child.child_handle, **kw).text = c.cert.get_Base64() + + for r in ca_detail.roas: + if r.roa is not None: + SubElement(r_msg, rpki.left_right.tag_list_published_objects, + uri = r.uri, **kw).text = r.roa.get_Base64() + + for g in ca_detail.ghostbusters: + SubElement(r_msg, rpki.left_right.tag_list_published_objects, + uri = g.uri, **kw).text = g.ghostbuster.get_Base64() + + for c in ca_detail.ee_certificates: + SubElement(r_msg, rpki.left_right.tag_list_published_objects, + uri = c.uri, **kw).text = c.cert.get_Base64() + + def handle_list_received_resources(self, q_pdu, r_msg): + """ + <list_received_resources/> server. + + This is written for the old SQL API, will need rewriting once we + switch rpkid to Django ORM. + """ + + logger.debug(".handle_list_received_resources() %s", ElementToString(q_pdu)) + + self_handle = q_pdu.get("self_handle") + msg_tag = q_pdu.get("tag") + + for parent in rpki.left_right.self_elt.serve_fetch_handle(self, None, self_handle).parents: + for ca in parent.cas: + ca_detail = ca.active_ca_detail + if ca_detail is not None and ca_detail.latest_ca_cert is not None: + + cert = ca_detail.latest_ca_cert + resources = cert.get_3779resources() + + r_pdu = SubElement(r_msg, rpki.left_right.tag_list_received_resources, + self_handle = self_handle, + parent_handle = parent.parent_handle, + uri = ca_detail.ca_cert_uri, + notBefore = str(cert.getNotBefore()), + notAfter = str(cert.getNotAfter()), + sia_uri = cert.get_sia_directory_uri(), + aia_uri = cert.get_aia_uri(), + asn = str(resources.asn), + ipv4 = str(resources.v4), + ipv6 = str(resources.v6)) + + if msg_tag is not None: + r_pdu.set("tag", msg_tag) + + def left_right_handler(self, query, path, cb): """ Process one left-right PDU. @@ -289,25 +377,71 @@ class main(object): # probably just become calls to ordinary methods of this # (rpki.rpkid.main) class. # - # Merge rpki.left_right.msg.serve_top_level() into this method, - # along with a generalization of rpki.pubd.main.control_handler(). - - def done(r_msg): - r_msg = r_msg.toXML() - reply = rpki.left_right.cms_msg().wrap(r_msg, self.rpkid_key, self.rpkid_cert) - self.sql.sweep() - cb(200, body = reply) + # Need to clone logic from rpki.pubd.main.control_handler(). try: q_cms = rpki.left_right.cms_msg(DER = query) q_msg = q_cms.unwrap((self.bpki_ta, self.irbe_cert)) - q_msg = rpki.left_right.msg.fromXML(q_msg) + r_msg = Element(rpki.left_right.tag_msg, nsmap = rpki.left_right.nsmap, + type = "reply", version = rpki.left_right.version) self.irbe_cms_timestamp = q_cms.check_replay(self.irbe_cms_timestamp, path) - if not q_msg.is_query(): + + assert q_msg.tag.startswith(rpki.left_right.xmlns) and all(q_pdu.tag.startswith(rpki.left_right.xmlns) for q_pdu in q_msg) + + if q_msg.get("version") != rpki.left_right.version: + raise rpki.exceptions.BadQuery("Unrecognized protocol version") + + if q_msg.get("type") != "query": raise rpki.exceptions.BadQuery("Message type is not query") - q_msg.serve_top_level(self, done) + + def done(): + self.sql.sweep() + cb(200, body = rpki.left_right.cms_msg().wrap(r_msg, self.rpkid_key, self.rpkid_cert)) + + def loop(iterator, q_pdu): + + def fail(e): + if not isinstance(e, rpki.exceptions.NotFound): + logger.exception("Unhandled exception serving left-right PDU %r", q_pdu) + + # Compatability kludge + if isinstance(q_pdu, rpki.left_right.data_elt): + r_msg.append(rpki.left_right.report_error_elt.from_exception( + e, self_handle = q_pdu.self_handle, tag = q_pdu.tag).toXML()) + else: + r_pdu = rpki.left_right.report_error_elt.from_exception(e, self_handle = q_pdu.get("self_handle")) + tag = q_pdu.get("tag") + if tag: + r_pdu.set("tag", tag) + r_msg.append(r_pdu.toXML()) + + self.sql.sweep() + + cb(200, body = rpki.left_right.cms_msg().wrap(r_msg, self.rpkid_key, self.rpkid_cert)) + + try: + if q_pdu.tag in self.left_right_trivial_handlers: + self.left_right_trivial_handlers[q_pdu.tag](q_pdu, r_msg) + iterator() + else: + q_map = { rpki.left_right.tag_self : rpki.left_right.self_elt, + rpki.left_right.tag_bsc : rpki.left_right.bsc_elt, + rpki.left_right.tag_parent : rpki.left_right.parent_elt, + rpki.left_right.tag_child : rpki.left_right.child_elt, + rpki.left_right.tag_repository : rpki.left_right.repository_elt } + q_pdu = q_map[q_pdu.tag].fromXML(q_pdu) + q_pdu.gctx = self + q_pdu.serve_dispatch(r_msg, iterator, fail) + except (rpki.async.ExitNow, SystemExit): + raise + except Exception, e: + fail(e) + + rpki.async.iterator(q_msg, loop, done) + except (rpki.async.ExitNow, SystemExit): raise + except Exception, e: logger.exception("Unhandled exception serving left-right request") cb(500, reason = "Unhandled exception %s: %s" % (e.__class__.__name__, e)) |