diff options
Diffstat (limited to 'rpkid')
-rw-r--r-- | rpkid/rpki/exceptions.py | 10 | ||||
-rw-r--r-- | rpkid/rpki/https.py | 41 | ||||
-rw-r--r-- | rpkid/rpki/left_right.py | 62 | ||||
-rw-r--r-- | rpkid/rpki/log.py | 8 | ||||
-rw-r--r-- | rpkid/rpki/rpki_engine.py | 28 |
5 files changed, 77 insertions, 72 deletions
diff --git a/rpkid/rpki/exceptions.py b/rpkid/rpki/exceptions.py index 4434ac45..8f0ee3fc 100644 --- a/rpkid/rpki/exceptions.py +++ b/rpkid/rpki/exceptions.py @@ -278,3 +278,13 @@ class BSCNotReady(RPKI_Exception): """ BSC not yet in a usable state, signing_cert not set. """ + +class HTTPSUnexpectedState(RPKI_Exception): + """ + HTTPS event occurred in an unexpected state. + """ + +class HTTPSBadVersion(RPKI_Exception): + """ + HTTPS couldn't parse HTTP version. + """ diff --git a/rpkid/rpki/https.py b/rpkid/rpki/https.py index 4ee8e3b2..1b2d948e 100644 --- a/rpkid/rpki/https.py +++ b/rpkid/rpki/https.py @@ -121,7 +121,7 @@ class http_message(object): def parse_version(self, version): if version[:5] != "HTTP/": - raise RuntimeError, "Couldn't parse version %s" % version + raise rpki.exceptions.HTTPSBadVersion, "Couldn't parse version %s" % version self.version = tuple(int(i) for i in version[5:].split(".")) def persistent(self): @@ -136,8 +136,8 @@ class http_message(object): class http_request(http_message): def __init__(self, cmd = None, path = None, version = default_http_version, body = None, callback = None, errback = None, **headers): - if cmd is not None and cmd != "POST" and body is not None: - raise RuntimeError + #assert cmd is None or cmd == "POST" or body is None + assert cmd == "POST" or body is None http_message.__init__(self, version = version, body = body, headers = headers) self.cmd = cmd self.path = path @@ -267,12 +267,13 @@ class http_stream(asynchat.async_chat): self.handle_message() def handle_error(self): - if sys.exc_info()[0] is SystemExit: - self.log("Caught SystemExit, propagating") + etype = sys.exc_info()[0] + if etype in (SystemExit, rpki.async.ExitNow): + self.log("Caught %s, propagating" % etype.__name__) raise - else: - self.log("Error in HTTP stream handler") - rpki.log.traceback() + self.log("Error in HTTP stream handler") + rpki.log.traceback() + if etype not in (rpki.exceptions.HTTPSClientAborted,): self.log("Closing due to error") self.close() @@ -394,8 +395,7 @@ class http_server(http_stream): self.tls.useCertificate(cert.get_POW()) self.tls.useKey(key.get_POW()) ta = rpki.x509.X509.normalize_chain(dynamic_ta() if dynamic_ta else ta) - if not ta: - raise RuntimeError, "No trust anchor(s) specified, this is unlikely to work" + assert ta for x in ta: self.log_cert("trusted", x) self.tls.addTrust(x.get_POW()) @@ -544,8 +544,7 @@ class http_client(http_stream): self.log_cert("client", self.cert) self.tls.useCertificate(self.cert.get_POW()) self.tls.useKey(self.key.get_POW()) - if not self.ta: - raise RuntimeError, "No trust anchor(s) specified, this is unlikely to work" + assert self.ta for x in self.ta: self.log_cert("trusted", x) self.tls.addTrust(x.get_POW()) @@ -591,7 +590,7 @@ class http_client(http_stream): assert not self.msg.body self.log("Ignoring empty response received while closing") return - raise RuntimeError, "%r received message while in unexpected state %s" % (self, self.state) + raise rpki.exceptions.HTTPSUnexpectedState, "%r received message while in unexpected state %s" % (self, self.state) if self.expect_close: self.log("Closing") @@ -603,11 +602,9 @@ class http_client(http_stream): self.set_state("idle") self.update_timeout() - if self.msg.code == 200: - self.queue.return_result(self.msg) - else: - self.queue.return_result(rpki.exceptions.HTTPRequestFailed( - "HTTPS request failed with status %s, reason %s, response %s" % (self.msg.code, self.msg.reason, self.msg.body))) + if self.msg.code != 200: + raise rpki.exceptions.HTTPRequestFailed, "HTTPS request failed with status %s, reason %s, response %s" % (self.msg.code, self.msg.reason, self.msg.body) + self.queue.return_result(self.msg) def handle_close(self): http_stream.handle_close(self) @@ -616,7 +613,7 @@ class http_client(http_stream): if self.get_terminator() is None: self.handle_body() elif self.state == "request-sent": - self.queue.return_result(rpki.exceptions.HTTPSClientAborted("HTTPS request aborted by close event")) + raise rpki.exceptions.HTTPSClientAborted, "HTTPS request aborted by close event" def handle_timeout(self): if self.state != "idle": @@ -627,11 +624,7 @@ class http_client(http_stream): def handle_error(self): http_stream.handle_error(self) self.queue.detach(self) - etype, edata = sys.exc_info()[:2] - if etype in (SystemExit, rpki.async.ExitNow): - raise edata - else: - self.queue.return_result(edata) + self.queue.return_result(sys.exc_info()[1]) class http_queue(object): diff --git a/rpkid/rpki/left_right.py b/rpkid/rpki/left_right.py index 08dd4fe7..77336b60 100644 --- a/rpkid/rpki/left_right.py +++ b/rpkid/rpki/left_right.py @@ -416,44 +416,52 @@ class self_elt(data_elt): rpki.log.warn("Could not update ROA %r, skipping: %s" % (roa, e)) iterator() - key = (roa_request.asn, str(roa_request.ipv4), str(roa_request.ipv6)) + try: - if key not in roas: - # This really should be using a constructor - roa = rpki.rpki_engine.roa_obj() - roa.gctx = self.gctx - roa.self_id = self.self_id - roa.asn = roa_request.asn - roa.ipv4 = roa_request.ipv4 - roa.ipv6 = roa_request.ipv6 - return roa.generate_roa(iterator, lose) + key = (roa_request.asn, str(roa_request.ipv4), str(roa_request.ipv6)) - roa = roas[key] - del roas[key] + if key not in roas: + # This really should be using a constructor + roa = rpki.rpki_engine.roa_obj() + roa.gctx = self.gctx + roa.self_id = self.self_id + roa.asn = roa_request.asn + roa.ipv4 = roa_request.ipv4 + roa.ipv6 = roa_request.ipv6 + return roa.generate_roa(iterator, lose) - ca_detail = roa.ca_detail() + roa = roas[key] + del roas[key] - if ca_detail is None or ca_detail.state != "active": - return roa.regenerate_roa(iterator, lose) + ca_detail = roa.ca_detail() - regen_margin = rpki.sundial.timedelta(seconds = self.regen_margin) + if ca_detail is None or ca_detail.state != "active": + return roa.regenerate_roa(iterator, lose) - if rpki.sundial.now() + regen_margin > roa.cert.getNotAfter(): - return roa.regenerate_roa(iterator, lose) + regen_margin = rpki.sundial.timedelta(seconds = self.regen_margin) - ca_resources = ca_detail.latest_ca_cert.get_3779resources() - ee_resources = roa.cert.get_3779resources() + if rpki.sundial.now() + regen_margin > roa.cert.getNotAfter(): + return roa.regenerate_roa(iterator, lose) - if ee_resources.oversized(ca_resources): - return roa.regenerate_roa(iterator, lose) + ca_resources = ca_detail.latest_ca_cert.get_3779resources() + ee_resources = roa.cert.get_3779resources() - v4 = roa.ipv4.to_resource_set() if roa.ipv4 is not None else rpki.resource_set.resource_set_ipv4() - v6 = roa.ipv6.to_resource_set() if roa.ipv6 is not None else rpki.resource_set.resource_set_ipv6() + if ee_resources.oversized(ca_resources): + return roa.regenerate_roa(iterator, lose) - if ee_resources.v4 != v4 or ee_resources.v6 != v6: - return roa.regenerate_roa(iterator, lose) + v4 = roa.ipv4.to_resource_set() if roa.ipv4 is not None else rpki.resource_set.resource_set_ipv4() + v6 = roa.ipv6.to_resource_set() if roa.ipv6 is not None else rpki.resource_set.resource_set_ipv6() - iterator() + if ee_resources.v4 != v4 or ee_resources.v6 != v6: + return roa.regenerate_roa(iterator, lose) + + iterator() + + except (SystemExit, rpki.async.ExitNow): + raise + + except Exception, e: + lose(e) def roa_requests_done(): diff --git a/rpkid/rpki/log.py b/rpkid/rpki/log.py index 50f0839d..d3eb41cd 100644 --- a/rpkid/rpki/log.py +++ b/rpkid/rpki/log.py @@ -102,9 +102,9 @@ def traceback(): Consolidated backtrace facility with a bit of extra info. """ + assert sys.exc_info() != (None, None, None), "rpki.log.traceback() called without valid trace on stack, this is a programming error" bt = tb.extract_stack(limit = 3) error("Exception caught in %s() at %s:%d called from %s:%d" % (bt[1][2], bt[1][0], bt[1][1], bt[0][0], bt[0][1])) - if sys.exc_info() == (None, None, None): - error("Stacktrace (most recent call last):\n" + "".join(tb.format_stack())) - else: - error(tb.format_exc()) + bt = tb.format_exc() + assert bt is not None, "Apparently I'm still not using the right test for null backtrace" + error(bt) diff --git a/rpkid/rpki/rpki_engine.py b/rpkid/rpki/rpki_engine.py index e969c7a3..c383f9a2 100644 --- a/rpkid/rpki/rpki_engine.py +++ b/rpkid/rpki/rpki_engine.py @@ -91,10 +91,8 @@ class rpkid_context(object): def unwrap(der): r_msg = rpki.left_right.cms_msg.unwrap(der, (self.bpki_ta, self.irdb_cert)) if not r_msg.is_reply() or [r_pdu for r_pdu in r_msg if type(r_pdu) is not type(q_pdu)]: - errback(rpki.exceptions.BadIRDBReply( - "Unexpected response to IRDB query: %s" % lxml.etree.tostring(r_msg.toXML(), pretty_print = True, encoding = "us-ascii"))) - else: - callback(r_msg) + raise rpki.exceptions.BadIRDBReply, "Unexpected response to IRDB query: %s" % lxml.etree.tostring(r_msg.toXML(), pretty_print = True, encoding = "us-ascii") + callback(r_msg) rpki.https.client( server_ta = (self.bpki_ta, self.irdb_cert), @@ -117,15 +115,13 @@ class rpkid_context(object): q_pdu.child_handle = child_handle def done(r_msg): - if len(r_msg) == 1: - 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)) - else: - errback(rpki.exceptions.BadIRDBReply( - "Expected exactly one PDU from IRDB: %s" % lxml.etree.tostring(r_msg.toXML(), pretty_print = True, encoding = "us-ascii"))) + if len(r_msg) != 1: + raise rpki.exceptions.BadIRDBReply, "Expected exactly one PDU from IRDB: %s" % lxml.etree.tostring(r_msg.toXML(), pretty_print = True, encoding = "us-ascii") + 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)) self.irdb_query(q_pdu, done, errback) @@ -1223,8 +1219,7 @@ class roa_obj(rpki.sql.sql_persistent): """ if self.ipv4 is None and self.ipv6 is None: - errback(rpki.exceptions.EmptyROAPrefixList()) - return + raise rpki.exceptions.EmptyROAPrefixList # Ugly and expensive search for covering ca_detail, there has to # be a better way, but it would require the ability to test for @@ -1248,8 +1243,7 @@ class roa_obj(rpki.sql.sql_persistent): break if ca_detail is None: - errback(rpki.exceptions.NoCoveringCertForROA("generate_roa() could not find a certificate covering %s %s" % (v4, v6))) - return + raise rpki.exceptions.NoCoveringCertForROA, "generate_roa() could not find a certificate covering %s %s" % (v4, v6) ca = ca_detail.ca() |