diff options
-rw-r--r-- | rpkid/rpki/async.py | 2 | ||||
-rw-r--r-- | rpkid/rpki/http.py | 63 | ||||
-rw-r--r-- | rpkid/rpki/irdbd.py | 4 | ||||
-rw-r--r-- | rpkid/rpki/left_right.py | 12 | ||||
-rw-r--r-- | rpkid/rpki/log.py | 17 | ||||
-rw-r--r-- | rpkid/rpki/myrpki.py | 61 | ||||
-rw-r--r-- | rpkid/rpki/pubd.py | 12 | ||||
-rw-r--r-- | rpkid/rpki/publication.py | 6 | ||||
-rw-r--r-- | rpkid/rpki/rootd.py | 6 | ||||
-rw-r--r-- | rpkid/rpki/rpkid.py | 71 | ||||
-rw-r--r-- | rpkid/rpki/x509.py | 6 | ||||
-rw-r--r-- | rpkid/tests/smoketest.py | 4 |
12 files changed, 169 insertions, 95 deletions
diff --git a/rpkid/rpki/async.py b/rpkid/rpki/async.py index dedab83a..9734ea41 100644 --- a/rpkid/rpki/async.py +++ b/rpkid/rpki/async.py @@ -212,7 +212,7 @@ class timer(object): t.errback(e) def __repr__(self): - return "<%s %r %r at 0x%x>" % (self.__class__.__name__, self.when, self.handler, id(self)) + return rpki.log.log_repr(self, self.when, repr(self.handler)) @classmethod def seconds_until_wakeup(cls): diff --git a/rpkid/rpki/http.py b/rpkid/rpki/http.py index 90b8c758..2748c2f3 100644 --- a/rpkid/rpki/http.py +++ b/rpkid/rpki/http.py @@ -241,6 +241,9 @@ class http_request(http_message): self.headers.setdefault("User-Agent", self.software_name) return "%s %s HTTP/%d.%d\r\n" % (self.cmd, self.path, self.version[0], self.version[1]) + def __repr__(self): + return rpki.log.log_repr(self, self.cmd, self.path) + class http_response(http_message): """ HTTP response message. @@ -268,6 +271,9 @@ class http_response(http_message): self.headers.setdefault("Server", self.software_name) return "HTTP/%d.%d %s %s\r\n" % (self.version[0], self.version[1], self.code, self.reason) + def __repr__(self): + return rpki.log.log_repr(self, self.code, self.reason) + def log_method(self, msg, logger = rpki.log.debug): """ Logging method used in several different classes. @@ -276,6 +282,19 @@ def log_method(self, msg, logger = rpki.log.debug): if debug_http or logger is not rpki.log.debug: logger("%r: %s" % (self, msg)) +def addr_to_string(addr): + """ + Convert socket addr tuple to printable string. Assumes 2-element + tuple is IPv4, 4-element tuple is IPv6, throws TypeError for + anything else. + """ + + if len(addr) == 2: + return "%s:%d" % (addr[0], addr[1]) + if len(addr) == 4: + return "%s.%d" % (addr[0], addr[1]) + raise TypeError + class http_stream(asynchat.async_chat): """ Virtual class representing an HTTP message stream. @@ -284,6 +303,14 @@ class http_stream(asynchat.async_chat): log = log_method show_tracebacks = False + def __repr__(self): + status = ["connected"] if self.connected else [] + try: + status.append(addr_to_string(self.addr)) + except TypeError: + pass + return rpki.log.log_repr(self, *status) + def __init__(self, sock = None): asynchat.async_chat.__init__(self, sock) self.buffer = [] @@ -306,7 +333,7 @@ class http_stream(asynchat.async_chat): it. """ if self.timeout is not None: - self.log("Setting timeout %r" % self.timeout) + self.log("Setting timeout %s" % self.timeout) self.timer.set(self.timeout) else: self.log("Clearing timeout") @@ -463,10 +490,10 @@ class http_server(http_stream): timeout = default_server_timeout def __init__(self, sock, handlers): - self.log("Starting") self.handlers = handlers http_stream.__init__(self, sock = sock) self.expect_close = not want_persistent_server + self.log("Starting") def handle_no_content_length(self): """ @@ -492,7 +519,7 @@ class http_server(http_stream): Content-Type, look for a handler, and if everything looks right, pass the message body, path, and a reply callback to the handler. """ - self.log("Received request %s %s" % (self.msg.cmd, self.msg.path)) + self.log("Received request %r" % self.msg) if not self.msg.persistent: self.expect_close = True handler = self.find_handler(self.msg.path) @@ -521,11 +548,11 @@ class http_server(http_stream): """ self.send_message(code = code, reason = reason) - def send_reply(self, code, body): + def send_reply(self, code, body = None, reason = "OK"): """ Send a reply to this request. """ - self.send_message(code = code, body = body) + self.send_message(code = code, body = body, reason = reason) def send_message(self, code, reason = "OK", body = None): """ @@ -557,8 +584,14 @@ class http_listener(asyncore.dispatcher): log = log_method show_tracebacks = False + def __repr__(self): + try: + status = (addr_to_string(self.addr),) + except TypeError: + status = () + return rpki.log.log_repr(self, *status) + def __init__(self, handlers, addrinfo): - self.log("Listener") asyncore.dispatcher.__init__(self) self.handlers = handlers try: @@ -578,21 +611,22 @@ class http_listener(asyncore.dispatcher): if self.show_tracebacks: rpki.log.traceback() self.close() - self.log("Listening on %r, handlers %r" % (sockaddr, handlers)) + for h in handlers: + self.log("Handling %s" % h[0]) def handle_accept(self): """ Asyncore says we have an incoming connection, spawn an http_server stream for it and pass along all of our handler data. """ - self.log("Accepting connection") try: s, client = self.accept() - self.log("Accepting connection from %r" % (client,)) + self.log("Accepting connection from %s" % addr_to_string(client)) http_server(sock = s, handlers = self.handlers) except (rpki.async.ExitNow, SystemExit): raise except: + self.log("Unable to accept connection") self.handle_error() def handle_error(self): @@ -623,7 +657,7 @@ class http_client(http_stream): state = None def __init__(self, queue, hostport): - self.log("Creating new connection to %r" % (hostport,)) + self.log("Creating new connection to %s" % addr_to_string(hostport)) http_stream.__init__(self) self.queue = queue self.host = hostport[0] @@ -777,7 +811,7 @@ class http_client(http_stream): down the connection and pass back the exception. """ eclass, edata = sys.exc_info()[0:2] - self.log("Error on HTTP client connection %s:%s: %s %s" % (self.host, self.port, eclass, edata), rpki.log.warn) + self.log("Error on HTTP client connection %s:%s %s %s" % (self.host, self.port, eclass, edata), rpki.log.warn) http_stream.handle_error(self) self.queue.return_result(self, edata, detach = True) @@ -790,10 +824,13 @@ class http_queue(object): log = log_method + def __repr__(self): + return rpki.log.log_repr(self, "%s" % addr_to_string(self.hostport)) + def __init__(self, hostport): - self.log("Creating queue for %r" % (hostport,)) self.hostport = hostport self.client = None + self.log("Created") self.queue = [] def request(self, *requests): @@ -921,7 +958,7 @@ def client(msg, url, callback, errback): hostport = (u.hostname or "localhost", u.port or default_tcp_port) if debug_http: - rpki.log.debug("Created request %r for %r" % (request, hostport)) + rpki.log.debug("Created request %r for %s" % (request, addr_to_string(hostport))) if hostport not in client_queues: client_queues[hostport] = http_queue(hostport) client_queues[hostport].request(request) diff --git a/rpkid/rpki/irdbd.py b/rpkid/rpki/irdbd.py index a5bf2663..46d4ebe1 100644 --- a/rpkid/rpki/irdbd.py +++ b/rpkid/rpki/irdbd.py @@ -185,7 +185,7 @@ class main(object): rpki.log.traceback() r_msg.append(rpki.left_right.report_error_elt.from_exception(data)) - cb(200, rpki.left_right.cms_msg().wrap(r_msg, self.irdbd_key, self.irdbd_cert)) + cb(200, body = rpki.left_right.cms_msg().wrap(r_msg, self.irdbd_key, self.irdbd_cert)) except (rpki.async.ExitNow, SystemExit): raise @@ -196,7 +196,7 @@ class main(object): # We only get here in cases where we couldn't or wouldn't generate # <report_error/>, so just return HTTP failure. - cb(500, "Unhandled exception %s: %s" % (data.__class__.__name__, data)) + cb(500, reason = "Unhandled exception %s: %s" % (data.__class__.__name__, data)) def __init__(self): diff --git a/rpkid/rpki/left_right.py b/rpkid/rpki/left_right.py index 93274e40..271e9270 100644 --- a/rpkid/rpki/left_right.py +++ b/rpkid/rpki/left_right.py @@ -649,15 +649,15 @@ class self_elt(data_elt): try: k = (roa_request.asn, str(roa_request.ipv4), str(roa_request.ipv6)) if k in seen: - rpki.log.warn("Skipping duplicate ROA request %r for %r" % (k, roa_request)) + rpki.log.warn("Skipping duplicate ROA request %r" % roa_request) continue 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) - rpki.log.debug("Couldn't find existing ROA matching %r, created %r" % (k, roa)) + rpki.log.debug("Couldn't find existing ROA, created %r" % roa) else: - rpki.log.debug("Found existing ROA %r matching %r" % (roa, k)) + rpki.log.debug("Found existing %r" % roa) roa.update(publisher = publisher, fast = True) ca_details.add(roa.ca_detail) except (SystemExit, rpki.async.ExitNow): @@ -665,7 +665,7 @@ class self_elt(data_elt): except Exception, e: if not isinstance(e, rpki.exceptions.NoCoveringCertForROA): rpki.log.traceback() - rpki.log.warn("Could not update ROA %r, %r, skipping: %s" % (roa_request, roa, e)) + rpki.log.warn("Could not update %r, skipping: %s" % (roa, e)) orphans.extend(roas.itervalues()) for roa in orphans: @@ -676,7 +676,7 @@ class self_elt(data_elt): raise except Exception, e: rpki.log.traceback() - rpki.log.warn("Could not revoke ROA %r: %s" % (roa, e)) + rpki.log.warn("Could not revoke %r: %s" % (roa, e)) for ca_detail in ca_details: ca_detail.generate_crl(publisher = publisher) @@ -818,7 +818,7 @@ class repository_elt(data_elt): handlers = {} for q_pdu in q_msg: - rpki.log.info("Sending <%s %r %r> to pubd" % (q_pdu.action, q_pdu.uri, q_pdu.payload)) + rpki.log.info("Sending %s %s to pubd" % (q_pdu.action, q_pdu.uri)) bsc = self.bsc q_der = rpki.publication.cms_msg().wrap(q_msg, bsc.private_key_id, bsc.signing_cert, bsc.signing_cert_crl) diff --git a/rpkid/rpki/log.py b/rpkid/rpki/log.py index 9d346385..658ee984 100644 --- a/rpkid/rpki/log.py +++ b/rpkid/rpki/log.py @@ -45,6 +45,11 @@ enable_trace = False use_syslog = True +## @var show_python_ids +# Whether __repr__() methods should show Python id numbers + +show_python_ids = False + tag = "" pid = 0 @@ -109,3 +114,15 @@ def traceback(): assert bt is not None, "Apparently I'm still not using the right test for null backtrace" for line in bt.splitlines(): warn(line) + +def log_repr(obj, *tokens): + """ + Constructor for __repr__() strings, handles suppression of Python + IDs as needed. + """ + + words = ["%s.%s" % (obj.__class__.__module__, obj.__class__.__name__)] + words.extend(str(token) for token in tokens if token is not None and token != "") + if show_python_ids: + words.append(" at %#x" % id(obj)) + return "<" + " ".join(words) + ">" diff --git a/rpkid/rpki/myrpki.py b/rpkid/rpki/myrpki.py index 372c541b..98271ffe 100644 --- a/rpkid/rpki/myrpki.py +++ b/rpkid/rpki/myrpki.py @@ -93,18 +93,21 @@ class comma_set(set): class EntityDB(object): """ - Wrapper for entitydb path lookups. Hmm, maybe some or all of the - entitydb glob stuff should end up here too? Later. + Wrapper for entitydb path lookups and iterations. """ def __init__(self, cfg): self.dir = cfg.get("entitydb_dir", "entitydb") + self.identity = os.path.join(self.dir, "identity.xml") - def __call__(self, *args): - return os.path.join(self.dir, *args) + def __call__(self, dirname, filebase = None): + if filebase is None: + return os.path.join(self.dir, dirname) + else: + return os.path.join(self.dir, dirname, filebase + ".xml") - def iterate(self, *args): - return glob.iglob(os.path.join(self.dir, *args)) + def iterate(self, dir, base = "*"): + return glob.iglob(os.path.join(self.dir, dir, base + ".xml")) class roa_request(object): """ @@ -274,7 +277,7 @@ class children(dict): Parse child data from entitydb. """ self = cls() - for f in entitydb.iterate("children", "*.xml"): + for f in entitydb.iterate("children"): c = etree_read(f) self.add(handle = os.path.splitext(os.path.split(f)[-1])[0], validity = c.get("valid_until"), @@ -374,7 +377,7 @@ class parents(dict): Parse parent data from entitydb. """ self = cls() - for f in entitydb.iterate("parents", "*.xml"): + for f in entitydb.iterate("parents"): h = os.path.splitext(os.path.split(f)[-1])[0] p = etree_read(f) r = etree_read(f.replace(os.path.sep + "parents" + os.path.sep, @@ -457,7 +460,7 @@ class repositories(dict): Parse repository data from entitydb. """ self = cls() - for f in entitydb.iterate("repositories", "*.xml"): + for f in entitydb.iterate("repositories"): h = os.path.splitext(os.path.split(f)[-1])[0] r = etree_read(f) if r.get("type") == "confirmed": @@ -1047,7 +1050,7 @@ class main(rpki.cli.Cmd): Completion helper for entitydb filenames. """ names = [] - for name in self.entitydb.iterate(prefix, "*.xml"): + for name in self.entitydb.iterate(prefix): name = os.path.splitext(os.path.basename(name))[0] if name.startswith(text): names.append(name) @@ -1124,7 +1127,7 @@ class main(rpki.cli.Cmd): e = Element("identity", handle = self.handle) PEMElement(e, "bpki_ta", self.bpki_resources.cer) - etree_write(e, self.entitydb("identity.xml"), + etree_write(e, self.entitydb.identity, msg = None if self.run_rootd else 'This is the "identity" file you will need to send to your parent') # If we're running rootd, construct a fake parent to go with it, @@ -1138,7 +1141,7 @@ class main(rpki.cli.Cmd): PEMElement(e, "bpki_resource_ta", self.bpki_servers.cer) PEMElement(e, "bpki_child_ta", self.bpki_resources.cer) SubElement(e, "repository", type = "offer") - etree_write(e, self.entitydb("parents", "%s.xml" % self.handle)) + etree_write(e, self.entitydb("parents", self.handle)) self.bpki_resources.xcert(self.bpki_servers.cer) @@ -1146,7 +1149,7 @@ class main(rpki.cli.Cmd): if not os.path.exists(rootd_child_fn): os.link(self.bpki_servers.xcert(self.bpki_resources.cer), rootd_child_fn) - repo_file_name = self.entitydb("repositories", "%s.xml" % self.handle) + repo_file_name = self.entitydb("repositories", self.handle) try: want_offer = etree_read(repo_file_name).get("type") != "confirmed" @@ -1255,7 +1258,7 @@ class main(rpki.cli.Cmd): SubElement(e, "bpki_child_ta").text = c.findtext("bpki_ta") repo = None - for f in self.entitydb.iterate("repositories", "*.xml"): + for f in self.entitydb.iterate("repositories"): r = etree_read(f) if r.get("type") == "confirmed": h = os.path.splitext(os.path.split(f)[-1])[0] @@ -1280,7 +1283,7 @@ class main(rpki.cli.Cmd): SubElement(r, "authorization", referrer = repo.get("client_handle")).text = auth SubElement(r, "contact_info").text = repo.findtext("contact_info") - etree_write(e, self.entitydb("children", "%s.xml" % child_handle), + etree_write(e, self.entitydb("children", child_handle), msg = "Send this file back to the child you just configured") @@ -1293,7 +1296,7 @@ class main(rpki.cli.Cmd): """ try: - os.unlink(self.entitydb("children", "%s.xml" % arg)) + os.unlink(self.entitydb("children", arg)) except OSError: print "No such child \"%s\"" % arg @@ -1333,7 +1336,7 @@ class main(rpki.cli.Cmd): self.bpki_resources.fxcert(p.findtext("bpki_resource_ta")) - etree_write(p, self.entitydb("parents", "%s.xml" % parent_handle)) + etree_write(p, self.entitydb("parents", parent_handle)) r = p.find("repository") @@ -1343,7 +1346,7 @@ class main(rpki.cli.Cmd): r.set("handle", self.handle) r.set("parent_handle", parent_handle) PEMElement(r, "bpki_client_ta", self.bpki_resources.cer) - etree_write(r, self.entitydb("repositories", "%s.xml" % parent_handle), + etree_write(r, self.entitydb("repositories", parent_handle), msg = "This is the file to send to the repository operator") @@ -1356,7 +1359,7 @@ class main(rpki.cli.Cmd): """ try: - os.unlink(self.entitydb("parents", "%s.xml" % arg)) + os.unlink(self.entitydb("parents", arg)) except OSError: print "No such parent \"%s\"" % arg @@ -1395,7 +1398,7 @@ class main(rpki.cli.Cmd): auth = client.find("authorization") if auth is None: raise RuntimeError, "Malformed referral, couldn't find <auth/> element" - referrer = etree_read(self.entitydb("pubclients", "%s.xml" % auth.get("referrer").replace("/","."))) + referrer = etree_read(self.entitydb("pubclients", auth.get("referrer").replace("/","."))) referrer = self.bpki_servers.fxcert(referrer.findtext("bpki_client_ta")) referral = self.bpki_servers.cms_xml_verify(auth.text, referrer) if not b64_equal(referral.text, client.findtext("bpki_client_ta")): @@ -1409,7 +1412,7 @@ class main(rpki.cli.Cmd): client_ta = client.findtext("bpki_client_ta") if not client_ta: raise RuntimeError, "Malformed offer, couldn't find <bpki_client_ta/> element" - for child in self.entitydb.iterate("children", "*.xml"): + for child in self.entitydb.iterate("children"): c = etree_read(child) if b64_equal(c.findtext("bpki_child_ta"), client_ta): sia_base = "rsync://%s/%s/%s/%s/" % (self.rsync_server, self.rsync_module, @@ -1446,7 +1449,7 @@ class main(rpki.cli.Cmd): PEMElement(e, "bpki_server_ta", self.bpki_servers.cer) SubElement(e, "bpki_client_ta").text = client.findtext("bpki_client_ta") SubElement(e, "contact_info").text = self.pubd_contact_info - etree_write(e, self.entitydb("pubclients", "%s.xml" % client_handle.replace("/", ".")), + etree_write(e, self.entitydb("pubclients", client_handle.replace("/", ".")), msg = "Send this file back to the publication client you just configured") @@ -1459,7 +1462,7 @@ class main(rpki.cli.Cmd): """ try: - os.unlink(self.entitydb("pubclients", "%s.xml" % arg)) + os.unlink(self.entitydb("pubclients", arg)) except OSError: print "No such client \"%s\"" % arg @@ -1495,7 +1498,7 @@ class main(rpki.cli.Cmd): print "Repository calls us %r" % (r.get("client_handle")) print "Repository response associated with parent_handle %r" % parent_handle - etree_write(r, self.entitydb("repositories", "%s.xml" % parent_handle)) + etree_write(r, self.entitydb("repositories", parent_handle)) def do_delete_repository(self, arg): @@ -1507,7 +1510,7 @@ class main(rpki.cli.Cmd): """ try: - os.unlink(self.entitydb("repositories", "%s.xml" % arg)) + os.unlink(self.entitydb("repositories", arg)) except OSError: print "No such repository \"%s\"" % arg @@ -1530,11 +1533,11 @@ class main(rpki.cli.Cmd): if plural: if len(argv) != 0: raise RuntimeError, "Unexpected arguments" - children_glob = "*.xml" + children = "*" else: if len(argv) != 1: raise RuntimeError, "Need to specify child handle" - children_glob = argv[0] + ".xml" + children = argv[0] if valid_until is None: valid_until = rpki.sundial.now() + rpki.sundial.timedelta(days = 365) @@ -1545,7 +1548,7 @@ class main(rpki.cli.Cmd): print "New validity date", valid_until - for f in self.entitydb.iterate("children", children_glob): + for f in self.entitydb.iterate("children", children): c = etree_read(f) c.set("valid_until", str(valid_until)) etree_write(c, f) @@ -1943,7 +1946,7 @@ class main(rpki.cli.Cmd): if self.run_pubd: - for f in self.entitydb.iterate("pubclients", "*.xml"): + for f in self.entitydb.iterate("pubclients"): c = etree_read(f) client_handle = c.get("client_handle") diff --git a/rpkid/rpki/pubd.py b/rpkid/rpki/pubd.py index 0fd4b713..513c1c3e 100644 --- a/rpkid/rpki/pubd.py +++ b/rpkid/rpki/pubd.py @@ -123,8 +123,8 @@ class main(object): Process one PDU from the IRBE. """ - def done(x): - cb(200, x) + def done(body): + cb(200, body = body) rpki.log.trace() try: @@ -134,7 +134,7 @@ class main(object): raise except Exception, data: rpki.log.traceback() - cb(500, "Unhandled exception %s" % data) + cb(500, reason = "Unhandled exception %s" % data) client_url_regexp = re.compile("/client/([-A-Z0-9_/]+)$", re.I) @@ -143,8 +143,8 @@ class main(object): Process one PDU from a client. """ - def done(x): - cb(200, x) + def done(body): + cb(200, body = body) rpki.log.trace() try: @@ -164,4 +164,4 @@ class main(object): raise except Exception, data: rpki.log.traceback() - cb(500, "Could not process PDU: %s" % data) + cb(500, reason = "Could not process PDU: %s" % data) diff --git a/rpkid/rpki/publication.py b/rpkid/rpki/publication.py index 51baf505..14e3d36a 100644 --- a/rpkid/rpki/publication.py +++ b/rpkid/rpki/publication.py @@ -206,7 +206,7 @@ class publication_object_elt(rpki.xml_utils.base_elt, publication_namespace): """ Publish an object. """ - rpki.log.info("Publishing %r as %r" % (self.payload, self.uri)) + rpki.log.info("Publishing %s" % self.uri) filename = self.uri_to_filename() filename_tmp = filename + ".tmp" dirname = os.path.dirname(filename) @@ -221,13 +221,13 @@ class publication_object_elt(rpki.xml_utils.base_elt, publication_namespace): """ Withdraw an object. """ - rpki.log.info("Withdrawing %r" % (self.uri,)) + rpki.log.info("Withdrawing %s" % self.uri) filename = self.uri_to_filename() try: os.remove(filename) except OSError, e: if e.errno == errno.ENOENT: - raise rpki.exceptions.NoObjectAtURI, "No object published at %r" % self.uri + raise rpki.exceptions.NoObjectAtURI, "No object published at %s" % self.uri else: raise diff --git a/rpkid/rpki/rootd.py b/rpkid/rpki/rootd.py index 9a8620a1..53f9be1a 100644 --- a/rpkid/rpki/rootd.py +++ b/rpkid/rpki/rootd.py @@ -240,10 +240,10 @@ class main(object): raise except Exception, e: rpki.log.traceback() - return cb(400, "Could not process PDU: %s" % e) + return cb(400, reason = "Could not process PDU: %s" % e) def done(r_msg): - cb(200, cms_msg().wrap(r_msg, self.rootd_bpki_key, self.rootd_bpki_cert, self.rootd_bpki_crl)) + cb(200, body = cms_msg().wrap(r_msg, self.rootd_bpki_key, self.rootd_bpki_cert, self.rootd_bpki_crl)) try: q_msg.serve_top_level(None, done) @@ -257,7 +257,7 @@ class main(object): raise except Exception, e: rpki.log.traceback() - cb(500, "Could not process PDU: %s" % e) + cb(500, reason = "Could not process PDU: %s" % e) def __init__(self): diff --git a/rpkid/rpki/rpkid.py b/rpkid/rpki/rpkid.py index 6e89fedc..54946a43 100644 --- a/rpkid/rpki/rpkid.py +++ b/rpkid/rpki/rpkid.py @@ -230,7 +230,7 @@ class main(object): def done(r_msg): reply = rpki.left_right.cms_msg().wrap(r_msg, self.rpkid_key, self.rpkid_cert) self.sql.sweep() - cb(200, reply) + cb(200, body = reply) try: self.sql.ping() @@ -242,7 +242,7 @@ class main(object): raise except Exception, data: rpki.log.traceback() - cb(500, "Unhandled exception %s" % data) + cb(500, reason = "Unhandled exception %s" % data) up_down_url_regexp = re.compile("/up-down/([-A-Z0-9_]+)/([-A-Z0-9_]+)$", re.I) @@ -255,7 +255,7 @@ class main(object): def done(reply): self.sql.sweep() - cb(200, reply) + cb(200, body = reply) try: self.sql.ping() @@ -272,10 +272,10 @@ class main(object): raise except (rpki.exceptions.ChildNotFound, rpki.exceptions.BadContactURL), e: rpki.log.warn(str(e)) - cb(400, str(e)) + cb(400, reason = str(e)) except Exception, e: rpki.log.traceback() - cb(400, "Could not process PDU: %s" % e) + cb(400, reason = "Could not process PDU: %s" % e) def checkpoint(self): """ @@ -349,10 +349,13 @@ class main(object): uses it. """ + def done(): + cb(200, body = "OK") + if self.use_internal_cron: - cb(500, "Running cron internally") + cb(500, reason = "Running cron internally") else: - self.cron(lambda: cb(200, "OK")) + self.cron(done) class ca_obj(rpki.sql.sql_persistent): """ @@ -461,8 +464,8 @@ class ca_obj(rpki.sql.sql_persistent): if rc_cert is None: - rpki.log.warn("Certificate in database missing from list_response, class %r, SKI %s, maybe parent certificate went away?" - % (rc.class_name, ca_detail.public_key.gSKI())) + rpki.log.warn("SKI %s in resource class %s is in my database but missing from list_response received from %s, maybe parent certificate went away?" + % (ca_detail.public_key.gSKI(), rc.class_name, parent.parent_handle)) publisher = publication_queue() ca_detail.delete(ca = ca_detail.ca, publisher = publisher) return publisher.call_pubd(iterator, eb) @@ -494,24 +497,33 @@ class ca_obj(rpki.sql.sql_persistent): def done(): if cert_map: - rpki.log.warn("Certificates in list_response missing from our database, class %r, SKIs %s" - % (rc.class_name, ", ".join(c.cert.gSKI() for c in cert_map.values()))) + rpki.log.warn("Certificate SKIs in resource class %s in list_response from parent %s that are missing from our database: %s" + % (rc.class_name, parent.parent_handle, ", ".join(c.cert.gSKI() for c in cert_map.values()))) self.gctx.checkpoint() cb() ca_details = self.issue_response_candidate_ca_details if True: - for x in cert_map.itervalues(): - rpki.log.debug("Parent thinks I have %r %s" % (x, x.cert.gSKI())) - for x in ca_details: - if x.latest_ca_cert is not None: - rpki.log.debug("I think I have %r %s" % (x, x.latest_ca_cert.gSKI())) + skis_parent = set(x.cert.gSKI() + for x in cert_map.itervalues()) + skis_me = set(x.latest_ca_cert.gSKI() + for x in ca_details + if x.latest_ca_cert is not None) + for ski in skis_parent & skis_me: + rpki.log.debug("Parent %s and I agree that I have SKI %s in resource class %s" + % (parent.parent_handle, ski, rc.class_name)) + for ski in skis_parent - skis_me: + rpki.log.debug("Parent %s thinks I have SKI %s in resource class %s but I don't think so" + % (parent.parent_handle, ski, rc.class_name)) + for ski in skis_me - skis_parent: + rpki.log.debug("I think I have SKI %s in resource class %s but parent %s doesn't think so" + % (ski, rc.class_name, parent.parent_handle)) if ca_details: rpki.async.iterator(ca_details, loop, done) else: - rpki.log.warn("Existing certificate class %r with no certificates, rekeying" % rc.class_name) + rpki.log.warn("Existing resource class %s from parent %s with no certificates, rekeying" % (rc.class_name, parent.parent_handle)) self.gctx.checkpoint() self.rekey(cb, eb) @@ -1392,6 +1404,11 @@ class roa_obj(rpki.sql.sql_persistent): """ self.gctx.sql.execute("DELETE FROM roa_prefix WHERE roa_id = %s", (self.roa_id,)) + def __repr__(self): + v4 = "" if self.ipv4 is None else self.ipv4 + v6 = "" if self.ipv6 is None else self.ipv6 + return rpki.log.log_repr(self, self.asn, ("%s,%s" % (v4, v6)).strip(",")) + def __init__(self, gctx = None, self_id = None, asn = None, ipv4 = None, ipv6 = None): rpki.sql.sql_persistent.__init__(self) self.gctx = gctx @@ -1413,37 +1430,35 @@ class roa_obj(rpki.sql.sql_persistent): v4 = self.ipv4.to_resource_set() if self.ipv4 is not None else rpki.resource_set.resource_set_ipv4() v6 = self.ipv6.to_resource_set() if self.ipv6 is not None else rpki.resource_set.resource_set_ipv6() - me = "<%s %s>" % (self.asn, ("%s,%s" % (v4, v6)).strip(",")) - if self.roa is None: - rpki.log.debug("ROA doesn't exist, generating %s" % me) + rpki.log.debug("%r doesn't exist, generating" % self) return self.generate(publisher = publisher, fast = fast) ca_detail = self.ca_detail if ca_detail is None: - rpki.log.debug("ROA has no associated ca_detail, generating %s" % me) + rpki.log.debug("%r has no associated ca_detail, generating" % self) return self.generate(publisher = publisher, fast = fast) if ca_detail.state != "active": - rpki.log.debug("ROA's associated ca_detail not active (state %r), regenerating %s" % (ca_detail.state, me)) + rpki.log.debug("ca_detail associated with %r not active (state %s), regenerating" % (self, ca_detail.state)) return self.regenerate(publisher = publisher, fast = fast) regen_time = self.cert.getNotAfter() - rpki.sundial.timedelta(seconds = self.self.regen_margin) if rpki.sundial.now() > regen_time: - rpki.log.debug("ROA past threshold %s, regenerating %s" % (regen_time, me)) + rpki.log.debug("%r past threshold %s, regenerating" % (self, regen_time)) return self.regenerate(publisher = publisher, fast = fast) ca_resources = ca_detail.latest_ca_cert.get_3779resources() ee_resources = self.cert.get_3779resources() if ee_resources.oversized(ca_resources): - rpki.log.debug("ROA oversized with respect to CA, regenerating %s" % me) + rpki.log.debug("%r oversized with respect to CA, regenerating" % self) return self.regenerate(publisher = publisher, fast = fast) if ee_resources.v4 != v4 or ee_resources.v6 != v6: - rpki.log.debug("ROA resources do not match EE, regenerating %s" % me) + rpki.log.debug("%r resources do not match EE, regenerating" % self) return self.regenerate(publisher = publisher, fast = fast) def generate(self, publisher, fast = False): @@ -1492,7 +1507,7 @@ class roa_obj(rpki.sql.sql_persistent): break if ca_detail is None: - raise rpki.exceptions.NoCoveringCertForROA, "generate() could not find a certificate covering %s %s" % (v4, v6) + raise rpki.exceptions.NoCoveringCertForROA, "Could not find a certificate covering %r" % self ca = ca_detail.ca resources = rpki.resource_set.resource_bag(v4 = v4, v6 = v6) @@ -1508,7 +1523,7 @@ class roa_obj(rpki.sql.sql_persistent): self.published = rpki.sundial.now() self.sql_store() - rpki.log.debug("Generating ROA %r" % self.uri) + rpki.log.debug("Generating %r URI %s" % (self, self.uri)) publisher.publish(cls = rpki.publication.roa_elt, uri = self.uri, obj = self.roa, repository = ca.parent.repository, handler = self.published_callback) if not fast: ca_detail.generate_manifest(publisher = publisher) @@ -1548,7 +1563,7 @@ class roa_obj(rpki.sql.sql_persistent): if regenerate: self.generate(publisher = publisher, fast = fast) - rpki.log.debug("Withdrawing ROA %r and revoking its EE cert" % uri) + rpki.log.debug("Withdrawing %r %s and revoking its EE cert" % (self, uri)) rpki.rpkid.revoked_cert_obj.revoke(cert = cert, ca_detail = ca_detail) publisher.withdraw(cls = rpki.publication.roa_elt, uri = uri, obj = roa, repository = ca_detail.ca.parent.repository, handler = False if allow_failure else None) diff --git a/rpkid/rpki/x509.py b/rpkid/rpki/x509.py index 8cc0db88..0fbcf073 100644 --- a/rpkid/rpki/x509.py +++ b/rpkid/rpki/x509.py @@ -454,13 +454,13 @@ class X509(DER_object): """ Get the issuer of this certificate. """ - return self.get_POW().getIssuer() + return "".join("/%s=%s" % rdn for rdn in self.get_POW().getIssuer()) def getSubject(self): """ Get the subject of this certificate. """ - return self.get_POW().getSubject() + return "".join("/%s=%s" % rdn for rdn in self.get_POW().getSubject()) def getNotBefore(self): """ @@ -1314,7 +1314,7 @@ class CRL(DER_object): """ Get issuer value of this CRL. """ - return self.get_POW().getIssuer() + return "".join("/%s=%s" % rdn for rdn in self.get_POW().getIssuer()) @classmethod def generate(cls, keypair, issuer, serial, thisUpdate, nextUpdate, revokedCertificates, version = 1, digestType = "sha256WithRSAEncryption"): diff --git a/rpkid/tests/smoketest.py b/rpkid/tests/smoketest.py index 63528a77..38e0d110 100644 --- a/rpkid/tests/smoketest.py +++ b/rpkid/tests/smoketest.py @@ -860,7 +860,9 @@ class allocation(object): f.write(x.get_PEM()) f.close() - rpki.log.debug("Cross certified (%s) issuer %s [%s] subject %s [%s]" % (certfile, x.getIssuer(), x.hAKI(), x.getSubject(), x.hSKI())) + rpki.log.debug("Cross certified %s:" % certfile) + rpki.log.debug(" Issuer %s [%s]" % (x.getIssuer(), x.hAKI())) + rpki.log.debug(" Subject %s [%s]" % (x.getSubject(), x.hSKI())) return x def create_rpki_objects(self, cb): |