diff options
-rw-r--r-- | rpki/left_right.py | 19 | ||||
-rw-r--r-- | rpki/relaxng.py | 14 | ||||
-rw-r--r-- | rpki/rpkid.py | 76 | ||||
-rw-r--r-- | rpki/rpkid_tasks.py | 64 | ||||
-rw-r--r-- | schemas/relaxng/left-right.rnc | 2 | ||||
-rw-r--r-- | schemas/relaxng/left-right.rng | 14 |
6 files changed, 98 insertions, 91 deletions
diff --git a/rpki/left_right.py b/rpki/left_right.py index 3b2c9b9f..7d3b0f60 100644 --- a/rpki/left_right.py +++ b/rpki/left_right.py @@ -46,11 +46,20 @@ xmlns = rpki.relaxng.left_right.xmlns nsmap = rpki.relaxng.left_right.nsmap version = rpki.relaxng.left_right.version -tag_list_resources = xmlns + "list_resources" -tag_list_roa_requests = xmlns + "list_roa_requests" -tag_msg = xmlns + "msg" -tag_pkcs10 = xmlns + "pkcs10" -tag_report_error = xmlns + "report_error" +tag_bsc = xmlns + "bsc" +tag_child = xmlns + "child" +tag_list_ee_certificate_requests = xmlns + "list_ee_certificate_requests" +tag_list_ghostbuster_requests = xmlns + "list_ghostbuster_requests" +tag_list_published_objects = xmlns + "list_published_objects" +tag_list_received_resources = xmlns + "list_received_resources" +tag_list_resources = xmlns + "list_resources" +tag_list_roa_requests = xmlns + "list_roa_requests" +tag_msg = xmlns + "msg" +tag_parent = xmlns + "parent" +tag_pkcs10 = xmlns + "pkcs10" +tag_report_error = xmlns + "report_error" +tag_repository = xmlns + "repository" +tag_self = xmlns + "self" ## @var enforce_strict_up_down_xml_sender diff --git a/rpki/relaxng.py b/rpki/relaxng.py index 71e8ade4..9c0ae6d6 100644 --- a/rpki/relaxng.py +++ b/rpki/relaxng.py @@ -967,14 +967,12 @@ left_right = RelaxNGParser(r'''<?xml version="1.0" encoding="UTF-8"?> <ref name="ipv6_list"/> </attribute> </optional> - <optional> - <attribute name="cn"> - <data type="string"> - <param name="maxLength">64</param> - <param name="pattern">[\-0-9A-Za-z_ ]+</param> - </data> - </attribute> - </optional> + <attribute name="cn"> + <data type="string"> + <param name="maxLength">64</param> + <param name="pattern">[\-0-9A-Za-z_ ]+</param> + </data> + </attribute> <optional> <attribute name="sn"> <data type="string"> diff --git a/rpki/rpkid.py b/rpki/rpkid.py index 07a81f79..25a6206d 100644 --- a/rpki/rpkid.py +++ b/rpki/rpkid.py @@ -154,35 +154,34 @@ class main(object): else: logger.debug("Not using internal clock, start_cron() call ignored") - def irdb_query(self, callback, errback, *q_pdus, **kwargs): + @staticmethod + def _compose_left_right_query(): + """ + Compose top level element of a left-right query to irdbd. + """ + + return Element(rpki.left_right.tag_msg, nsmap = rpki.left_right.nsmap, + type = "query", version = rpki.left_right.version) + + def irdb_query(self, q_msg, callback, errback): """ Perform an IRDB callback query. """ try: - q_types = tuple(type(q_pdu) for q_pdu in q_pdus) - - expected_pdu_count = kwargs.pop("expected_pdu_count", None) - assert len(kwargs) == 0 + q_tags = set(q_pdu.tag for q_pdu in q_msg) - q_msg = rpki.left_right.msg.query() - q_msg.extend(q_pdus) - q_der = rpki.left_right.cms_msg().wrap(q_msg, self.rpkid_key, self.rpkid_cert) + q_der = rpki.left_right.cms_msg_no_sax().wrap(q_msg, self.rpkid_key, self.rpkid_cert) def unwrap(r_der): try: - r_cms = rpki.left_right.cms_msg(DER = r_der) + r_cms = rpki.left_right.cms_msg_no_sax(DER = r_der) r_msg = r_cms.unwrap((self.bpki_ta, self.irdb_cert)) self.irdbd_cms_timestamp = r_cms.check_replay(self.irdbd_cms_timestamp, self.irdb_url) - if not r_msg.is_reply() or not all(type(r_pdu) in q_types for r_pdu in r_msg): + #rpki.left_right.check_response(r_msg) + if r_msg.get("type") != "reply" or not all(r_pdu.tag in q_tags for r_pdu in r_msg): raise rpki.exceptions.BadIRDBReply( "Unexpected response to IRDB query: %s" % r_cms.pretty_print_content()) - if expected_pdu_count is not None and len(r_msg) != expected_pdu_count: - assert isinstance(expected_pdu_count, (int, long)) - raise rpki.exceptions.BadIRDBReply( - "Expected exactly %d PDU%s from IRDB: %s" % ( - expected_pdu_count, "" if expected_pdu_count == 1 else "s", - r_cms.pretty_print_content())) callback(r_msg) except Exception, e: errback(e) @@ -202,53 +201,50 @@ class main(object): Ask IRDB about a child's resources. """ - q_pdu = rpki.left_right.list_resources_elt() - q_pdu.self_handle = self_handle - q_pdu.child_handle = child_handle + q_msg = self._compose_left_right_query() + SubElement(q_msg, rpki.left_right.tag_list_resources, + self_handle = self_handle, child_handle = child_handle) def done(r_msg): + if len(r_msg) != 1: + raise rpki.exceptions.BadIRDBReply( + "Expected exactly one PDU from IRDB: %s" % r_cms.pretty_print_content()) callback(rpki.resource_set.resource_bag( - asn = r_msg[0].asn, - v4 = r_msg[0].ipv4, - v6 = r_msg[0].ipv6, - valid_until = r_msg[0].valid_until)) + asn = rpki.resource_set.resource_set_as(r_msg[0].get("asn")), + v4 = rpki.resource_set.resource_set_ipv4(r_msg[0].get("ipv4")), + v6 = rpki.resource_set.resource_set_ipv6(r_msg[0].get("ipv6")), + valid_until = rpki.sundial.datetime.fromXMLtime(r_msg[0].get("valid_until")))) - self.irdb_query(done, errback, q_pdu, expected_pdu_count = 1) + self.irdb_query(q_msg, done, errback) def irdb_query_roa_requests(self, self_handle, callback, errback): """ Ask IRDB about self's ROA requests. """ - q_pdu = rpki.left_right.list_roa_requests_elt() - q_pdu.self_handle = self_handle - - self.irdb_query(callback, errback, q_pdu) + q_msg = self._compose_left_right_query() + SubElement(q_msg, rpki.left_right.tag_list_roa_requests, self_handle = self_handle) + self.irdb_query(q_msg, callback, errback) def irdb_query_ghostbuster_requests(self, self_handle, parent_handles, callback, errback): """ Ask IRDB about self's ghostbuster record requests. """ - q_pdus = [] - + q_msg = self._compose_left_right_query() for parent_handle in parent_handles: - q_pdu = rpki.left_right.list_ghostbuster_requests_elt() - q_pdu.self_handle = self_handle - q_pdu.parent_handle = parent_handle - q_pdus.append(q_pdu) - - self.irdb_query(callback, errback, *q_pdus) + SubElement(q_msg, rpki.left_right.tag_list_ghostbuster_requests, + self_handle = self_handle, parent_handle = parent_handle) + self.irdb_query(q_msg, callback, errback) def irdb_query_ee_certificate_requests(self, self_handle, callback, errback): """ Ask IRDB about self's EE certificate requests. """ - q_pdu = rpki.left_right.list_ee_certificate_requests_elt() - q_pdu.self_handle = self_handle - - self.irdb_query(callback, errback, q_pdu) + q_msg = self._compose_left_right_query() + SubElement(q_msg, rpki.left_right.tag_list_ee_certificate_requests, self_handle = self_handle) + self.irdb_query(q_msg, callback, errback) def left_right_handler(self, query, path, cb): """ diff --git a/rpki/rpkid_tasks.py b/rpki/rpkid_tasks.py index 5405834f..c43d3283 100644 --- a/rpki/rpkid_tasks.py +++ b/rpki/rpkid_tasks.py @@ -358,7 +358,7 @@ class UpdateROAsTask(AbstractTask): logger.debug("Issuing query for ROA requests") self.gctx.irdb_query_roa_requests(self.self_handle, self.got_roa_requests, self.roa_requests_failed) - def got_roa_requests(self, roa_requests): + def got_roa_requests(self, r_msg): self.gctx.checkpoint() logger.debug("Received response to query for ROA requests") @@ -384,15 +384,17 @@ class UpdateROAsTask(AbstractTask): else: self.orphans.append(roa) - for roa_request in roa_requests: - k = (roa_request.asn, str(roa_request.ipv4), str(roa_request.ipv6)) + for r_pdu in r_msg: + k = (r_pdu.get("asn"), r_pdu.get("ipv4"), r_pdu.get("ipv6")) if k in seen: - logger.warning("Skipping duplicate ROA request %r", roa_request) + logger.warning("Skipping duplicate ROA request %r", r_pdu) else: seen.add(k) roa = roas.pop(k, None) if roa is None: - roa = rpki.rpkid.roa_obj(self.gctx, self.self_id, roa_request.asn, roa_request.ipv4, roa_request.ipv6) + roa = rpki.rpkid.roa_obj(self.gctx, self.self_id, long(r_pdu.get("asn")), + rpki.resource_set.roa_prefix_set_ipv4(r_pdu.get("ipv4")), + rpki.resource_set.roa_prefix_set_ipv6(r_pdu.get("ipv6"))) logger.debug("Created new %r", roa) else: logger.debug("Found existing %r", roa) @@ -484,7 +486,7 @@ class UpdateGhostbustersTask(AbstractTask): self.got_ghostbuster_requests, self.ghostbuster_requests_failed) - def got_ghostbuster_requests(self, ghostbuster_requests): + def got_ghostbuster_requests(self, r_msg): try: self.gctx.checkpoint() @@ -507,24 +509,24 @@ class UpdateGhostbustersTask(AbstractTask): else: ghostbusters[k] = ghostbuster - for ghostbuster_request in ghostbuster_requests: - if ghostbuster_request.parent_handle not in parents: - logger.warning("Unknown parent_handle %r in Ghostbuster request, skipping", ghostbuster_request.parent_handle) + for r_pdu in r_msg: + if r_pdu.get("parent_handle") not in parents: + logger.warning("Unknown parent_handle %r in Ghostbuster request, skipping", r_pdu.get("parent_handle")) continue - k = (ghostbuster_request.parent_handle, ghostbuster_request.vcard) + k = (r_pdu.get("parent_handle"), r_pdu.text) if k in seen: - logger.warning("Skipping duplicate Ghostbuster request %r", ghostbuster_request) + logger.warning("Skipping duplicate Ghostbuster request %r", r_pdu) continue seen.add(k) - for ca in parents[ghostbuster_request.parent_handle].cas: + for ca in parents[r_pdu.get("parent_handle")].cas: ca_detail = ca.active_ca_detail if ca_detail is not None: - ghostbuster = ghostbusters.pop((ca_detail.ca_detail_id, ghostbuster_request.vcard), None) + ghostbuster = ghostbusters.pop((ca_detail.ca_detail_id, r_pdu.text), None) if ghostbuster is None: - ghostbuster = rpki.rpkid.ghostbuster_obj(self.gctx, self.self_id, ca_detail.ca_detail_id, ghostbuster_request.vcard) - logger.debug("Created new %r for %r", ghostbuster, ghostbuster_request.parent_handle) + ghostbuster = rpki.rpkid.ghostbuster_obj(self.gctx, self.self_id, ca_detail.ca_detail_id, r_pdu.text) + logger.debug("Created new %r for %r", ghostbuster, r_pdu.get("parent_handle")) else: - logger.debug("Found existing %r for %s", ghostbuster, ghostbuster_request.parent_handle) + logger.debug("Found existing %r for %s", ghostbuster, r_pdu.get("parent_handle")) ghostbuster.update(publisher = publisher, fast = True) ca_details.add(ca_detail) @@ -575,7 +577,7 @@ class UpdateEECertificatesTask(AbstractTask): self.got_requests, self.get_requests_failed) - def got_requests(self, requests): + def got_requests(self, r_msg): try: self.gctx.checkpoint() @@ -594,39 +596,43 @@ class UpdateEECertificatesTask(AbstractTask): ca_details = set() - for req in requests: - ees = existing.pop(req.gski, ()) + for r_pdu in r_msg: + gski = r_pdu.get("gski") + ees = existing.pop(gski, ()) resources = rpki.resource_set.resource_bag( - asn = req.asn, - v4 = req.ipv4, - v6 = req.ipv6, - valid_until = req.valid_until) + asn = rpki.resource_set.resource_set_as(r_pdu.get("asn")), + v4 = rpki.resource_set.resource_set_ipv4(r_pdu.get("ipv4")), + v6 = rpki.resource_set.resource_set_ipv6(r_pdu.get("ipv6")), + valid_until = rpki.sundial.datetime.fromXMLtime(r_pdu.get("valid_until"))) covering = self.find_covering_ca_details(resources) ca_details.update(covering) for ee in ees: if ee.ca_detail in covering: logger.debug("Updating existing EE certificate for %s %s", - req.gski, resources) + gski, resources) ee.reissue( resources = resources, publisher = publisher) covering.remove(ee.ca_detail) else: logger.debug("Existing EE certificate for %s %s is no longer covered", - req.gski, resources) + gski, resources) ee.revoke(publisher = publisher) + subject_name = rpki.x509.X501DN.from_cn(r_pdu.get("cn"), r_pdu.get("sn")) + subject_key = rpki.x509.PKCS10(Base64 = r_pdu.text).getPublicKey() + for ca_detail in covering: logger.debug("No existing EE certificate for %s %s", - req.gski, resources) + gski, resources) rpki.rpkid.ee_cert_obj.create( ca_detail = ca_detail, - subject_name = rpki.x509.X501DN.from_cn(req.cn, req.sn), - subject_key = req.pkcs10.getPublicKey(), + subject_name = subject_name, + subject_key = subject_key, resources = resources, publisher = publisher, - eku = req.eku or None) + eku = r_pdu.eku or None) # Anything left is an orphan for ees in existing.values(): diff --git a/schemas/relaxng/left-right.rnc b/schemas/relaxng/left-right.rnc index 201f8ff0..22d971f0 100644 --- a/schemas/relaxng/left-right.rnc +++ b/schemas/relaxng/left-right.rnc @@ -271,7 +271,7 @@ list_ee_certificate_requests_reply = element list_ee_certificate_requests { attribute asn { asn_list }?, attribute ipv4 { ipv4_list }?, attribute ipv6 { ipv6_list }?, - attribute cn { xsd:string { maxLength="64" pattern="[\-0-9A-Za-z_ ]+" } }?, + attribute cn { xsd:string { maxLength="64" pattern="[\-0-9A-Za-z_ ]+" } }, attribute sn { xsd:string { maxLength="64" pattern="[0-9A-Fa-f]+" } }?, attribute eku { xsd:string { maxLength="512000" pattern="[.,0-9]+" } }?, element pkcs10 { base64 } diff --git a/schemas/relaxng/left-right.rng b/schemas/relaxng/left-right.rng index 15dd2fa1..b521e0d7 100644 --- a/schemas/relaxng/left-right.rng +++ b/schemas/relaxng/left-right.rng @@ -961,14 +961,12 @@ <ref name="ipv6_list"/> </attribute> </optional> - <optional> - <attribute name="cn"> - <data type="string"> - <param name="maxLength">64</param> - <param name="pattern">[\-0-9A-Za-z_ ]+</param> - </data> - </attribute> - </optional> + <attribute name="cn"> + <data type="string"> + <param name="maxLength">64</param> + <param name="pattern">[\-0-9A-Za-z_ ]+</param> + </data> + </attribute> <optional> <attribute name="sn"> <data type="string"> |