diff options
-rwxr-xr-x | potpourri/ca-unpickle.py | 132 |
1 files changed, 122 insertions, 10 deletions
diff --git a/potpourri/ca-unpickle.py b/potpourri/ca-unpickle.py index 5f255d8f..6b872b77 100755 --- a/potpourri/ca-unpickle.py +++ b/potpourri/ca-unpickle.py @@ -3,24 +3,136 @@ # $Id$ """ -Unpickle CA state packaged by ca-pickle. - -This version is a stub, and exists only to test ca-pickle. +Unpickle trunk/ CA state packaged by ca-pickle and attempt to whack a +tk705/ rpki-ca instance into an equivalent state. """ +import os import sys +import time import cPickle +import datetime import argparse import subprocess -parser = argparse.ArgumentParser(description = __doc__) -parser.add_argument("input", help = "input file") -args = parser.parse_args() +import rpki.config +import rpki.x509 + + +class LazyDict(dict): + """ + Convenience wrapper to allow attribute notation for brevity + when diving into deeply nested mappings created by ca-pickle. + """ + + def __getattr__(self, name): + if name in self: + return self[name] + raise AttributeError + + @classmethod + def insinuate(cls, thing): + if isinstance(thing, dict): + return cls((k, cls.insinuate(v)) for k, v in thing.iteritems()) + if isinstance(thing, list): + return list(cls.insinuate(v) for v in thing) + if isinstance(thing, tuple): + return tuple(cls.insinuate(v) for v in thing) + return thing -xzcat = subprocess.Popen(("xzcat", args.input), stdout = subprocess.PIPE) -world = cPickle.load(xzcat.stdout) + +os.environ.update(TZ = "UTC") +time.tzset() + +cfg = rpki.config.argparser(doc = __doc__) +cfg.argparser.add_argument("input_file", help = "input file") +cfg.add_logging_arguments() +args = cfg.argparser.parse_args() +cfg.configure_logging(args = args) + +xzcat = subprocess.Popen(("xzcat", args.input_file), stdout = subprocess.PIPE) +world = LazyDict.insinuate(cPickle.load(xzcat.stdout)) if xzcat.wait() != 0: sys.exit("XZ unpickling failed with code {}".format(xzcat.returncode)) -print "import datetime" -print "world =", repr(world) +# Trivial test, but if this works, the LazyDict stuff is probably working +#print "Engine handle is", world.cooked_config.myrpki.handle + +def maybe_X509(obj): return None if obj is None else rpki.x509.X509( DER = obj) +def maybe_CRL(obj): return None if obj is None else rpki.x509.CRL( DER = obj) +def maybe_RSA(obj): return None if obj is None else rpki.x509.RSA( DER = obj) +def maybe_PKCS10(obj): return None if obj is None else rpki.x509.PKCS10(DER = obj) + +# Because of the way Django ORM uses DJANGO_SETTINGS_MODULE, we'll +# probably need to fork() to handle the several databases. Shouldn't +# be particularly difficult, write three driver functions and a +# service function that fork()s then calls a driver, or something like +# that. +# +# Prototype with rpkid for now, fork later. + +os.environ.update(DJANGO_SETTINGS_MODULE = "rpki.django_settings.rpkid") +import django +django.setup() +import rpki.rpkidb + +print "rpkid self" + +for row in world.databases.rpkid.self: + rpki.rpkidb.models.Tenant.objects.create( + pk = row.self_id, + tenant_handle = row.self_handle, + use_hsm = row.use_hsm, + crl_interval = row.crl_interval, + regen_margin = row.regen_margin, + bpki_cert = maybe_X509(row.bpki_cert), + bpki_glue = maybe_X509(row.bpki_glue)) + +print "rpkid bsc" + +for row in world.databases.rpkid.bsc: + tenant = rpki.rpkidb.models.Tenant.objects.get(pk = row.self_id) + rpki.rpkidb.models.BSC.objects.create( + pk = row.bsc_id, + bsc_handle = row.bsc_handle, + private_key_id = maybe_RSA(row.private_key_id), + pkcs10_request = maybe_PKCS10(row.pkcs10_request), + hash_alg = row.hash_alg or "sha256", + signing_cert = maybe_X509(row.signing_cert), + signing_cert_crl = maybe_CRL(row.signing_cert_crl), + tenant = tenant) + +print "rpkid repository" + +for row in world.databases.rpkid.repository: + tenant = rpki.rpkidb.models.Tenant.objects.get(pk = row.self_id ) + bsc = rpki.rpkidb.models.BSC.objects.get (pk = row.bsc_id, tenant = tenant) + rpki.rpkidb.models.Repository.objects.create( + pk = row.repository_id, + repository_handle = row.repository_handle, + peer_contact_uri = row.peer_contact_uri, + bpki_cert = maybe_X509(row.bpki_cert), + bpki_glue = maybe_X509(row.bpki_glue), + last_cms_timestamp = row.last_cms_timestamp, + bsc = bsc, + tenant = tenant) + +print "rpkid parent" + +for row in world.databases.rpkid.parent: + tenant = rpki.rpkidb.models.Tenant.objects.get (pk = row.self_id ) + bsc = rpki.rpkidb.models.BSC.objects.get (pk = row.bsc_id, tenant = tenant) + repository = rpki.rpkidb.models.Repository.objects.get(pk = row.repository_id, tenant = tenant) + rpki.rpkidb.models.Parent.objects.create( + pk = row.parent_id, + parent_handle = row.parent_handle, + bpki_cert = maybe_X509(row.bpki_cms_cert), + bpki_glue = maybe_X509(row.bpki_cms_glue), + peer_contact_uri = row.peer_contact_uri, + sia_base = row.sia_base, + sender_name = row.sender_name, + recipient_name = row.recipient_name, + last_cms_timestamp = row.last_cms_timestamp, + bsc = bsc, + repository = repository, + tenant = tenant) |