aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2014-09-21 22:08:07 +0000
committerRob Austein <sra@hactrn.net>2014-09-21 22:08:07 +0000
commit8232d6a259a7045e9b5de192f199776cb7ee17b2 (patch)
tree68690f358b5f484e575b5a0cc7adee940326d6ee
parentfeadd1293e004d1acef12e39184cfdb1a280ea18 (diff)
Add CMS goo to simple CMS client, remove need for async HTTP in Zookeeper.
svn path=/branches/tk705/; revision=5966
-rw-r--r--rpki/http_simple.py29
-rw-r--r--rpki/irdb/zookeeper.py55
-rw-r--r--rpki/rootd.py31
3 files changed, 63 insertions, 52 deletions
diff --git a/rpki/http_simple.py b/rpki/http_simple.py
index 4a05d607..2a00ff9c 100644
--- a/rpki/http_simple.py
+++ b/rpki/http_simple.py
@@ -1,5 +1,5 @@
# $Id$
-
+#
# Copyright (C) 2014 Dragon Research Labs ("DRL")
#
# Permission to use, copy, modify, and distribute this software for any
@@ -97,11 +97,10 @@ class BadContentType(Exception):
"Wrong HTTP Content-Type"
-def client(url, query):
+def client(proto_cms_msg, client_key, client_cert, server_ta, server_cert, url, q_msg,
+ debug = False, replay_track = None, client_crl = None):
"""
- Issue single a query and return the response.
-
- Might want to add CMS processing here, not sure yet.
+ Issue single a query and return the response, handling all the CMS and XML goo.
"""
u = urlparse.urlparse(url)
@@ -109,10 +108,14 @@ def client(url, query):
if u.scheme not in ("", "http") or u.username or u.password or u.params or u.query or u.fragment:
raise BadURL("Unusable URL %s", url)
- http = httplib.HTTPConnection(u.hostname, u.port or httplib.HTTP_PORT)
+ q_cms = proto_cms_msg()
+ q_der = q_cms.wrap(q_msg, client_key, client_cert, client_crl)
- http.request("POST", u.path, query, {"Content-Type" : rpki_content_type})
+ if debug:
+ debug.write("<!-- Query -->\n" + q_cms.pretty_print_content() + "\n")
+ http = httplib.HTTPConnection(u.hostname, u.port or httplib.HTTP_PORT)
+ http.request("POST", u.path, q_der, {"Content-Type" : rpki_content_type})
r = http.getresponse()
if r.status != 200:
@@ -121,4 +124,14 @@ def client(url, query):
if r.getheader("Content-Type") != rpki_content_type:
raise BadContentType("HTTP Content-Type %r, expected %r" % (r.getheader("Content-Type"), rpki_content_type))
- return r.read()
+ r_der = r.read()
+ r_cms = proto_cms_msg(DER = r_der)
+ r_msg = r_cms.unwrap((server_ta, server_cert))
+
+ if replay_track is not None:
+ replay_track.cms_timestamp = r_cms.check_replay(replay_track.cms_timestamp, url)
+
+ if debug:
+ debug.write("<!-- Reply -->\n" + r_cms.pretty_print_content() + "\n")
+
+ return r_msg
diff --git a/rpki/irdb/zookeeper.py b/rpki/irdb/zookeeper.py
index c9f7d78e..41060f9e 100644
--- a/rpki/irdb/zookeeper.py
+++ b/rpki/irdb/zookeeper.py
@@ -28,12 +28,11 @@ import types
import rpki.config
import rpki.sundial
import rpki.oids
-import rpki.http
+import rpki.http_simple
import rpki.resource_set
import rpki.relaxng
import rpki.left_right
import rpki.x509
-import rpki.async
import rpki.irdb
import rpki.publication_control
import django.db.transaction
@@ -189,9 +188,9 @@ class etree_wrapper(object):
class Zookeeper(object):
## @var show_xml
- # Whether to show XML for debugging
+ # If not None, a file-like object to which to prettyprint XML, for debugging.
- show_xml = False
+ show_xml = None
def __init__(self, cfg = None, handle = None, logstream = None):
@@ -1035,11 +1034,6 @@ class Zookeeper(object):
def call_rpkid(self, *pdus):
"""
Issue a call to rpkid, return result.
-
- Implementation is a little silly, constructs a wrapper object,
- invokes it once, then throws it away. Hard to do better without
- rewriting a bit of the HTTP code, as we want to be sure we're
- using the current BPKI certificate and key objects.
"""
url = "http://%s:%s/left-right" % (
@@ -1054,16 +1048,15 @@ class Zookeeper(object):
elif len(pdus) == 1 and isinstance(pdus[0], (tuple, list)):
pdus = pdus[0]
- call_rpkid = rpki.async.sync_wrapper(rpki.http.caller(
- proto = rpki.left_right,
- client_key = irbe.private_key,
- client_cert = irbe.certificate,
- server_ta = self.server_ca.certificate,
- server_cert = rpkid.certificate,
- url = url,
- debug = self.show_xml))
-
- return call_rpkid(*pdus)
+ return rpki.http_simple.client(
+ proto_cms_msg = rpki.left_right.cms_msg,
+ client_key = irbe.private_key,
+ client_cert = irbe.certificate,
+ server_ta = self.server_ca.certificate,
+ server_cert = rpkid.certificate,
+ url = url,
+ q_msg = rpki.left_right.msg.query(*pdus),
+ debug = self.show_xml)
def run_rpkid_now(self):
@@ -1145,11 +1138,6 @@ class Zookeeper(object):
def call_pubd(self, *pdus):
"""
Issue a call to pubd, return result.
-
- Implementation is a little silly, constructs a wrapper object,
- invokes it once, then throws it away. Hard to do better without
- rewriting a bit of the HTTP code, as we want to be sure we're
- using the current BPKI certificate and key objects.
"""
url = "http://%s:%s/control" % (
@@ -1164,16 +1152,15 @@ class Zookeeper(object):
elif len(pdus) == 1 and isinstance(pdus[0], (tuple, list)):
pdus = pdus[0]
- call_pubd = rpki.async.sync_wrapper(rpki.http.caller(
- proto = rpki.publication_control,
- client_key = irbe.private_key,
- client_cert = irbe.certificate,
- server_ta = self.server_ca.certificate,
- server_cert = pubd.certificate,
- url = url,
- debug = self.show_xml))
-
- return call_pubd(*pdus)
+ return rpki.http_simple.client(
+ proto_cms_msg = rpki.publication_control.cms_msg,
+ client_key = irbe.private_key,
+ client_cert = irbe.certificate,
+ server_ta = self.server_ca.certificate,
+ server_cert = pubd.certificate,
+ url = url,
+ q_msg = rpki.publication_control.msg.query(*pdus),
+ debug = self.show_xml)
def check_error_report(self, pdus):
diff --git a/rpki/rootd.py b/rpki/rootd.py
index a9562881..2bd7ce44 100644
--- a/rpki/rootd.py
+++ b/rpki/rootd.py
@@ -46,6 +46,16 @@ from lxml.etree import Element, SubElement
logger = logging.getLogger(__name__)
+class ReplayTracker(object):
+ """
+ Stash for replay protection timestamps.
+ """
+
+ def __init__(self):
+ self.cms_timestamp = None
+
+
+
class main(object):
@@ -248,11 +258,16 @@ class main(object):
def call_pubd(self, q_msg):
for q_pdu in q_msg:
logger.info("Sending %s to pubd", q_pdu.get("uri"))
- q_der = rpki.publication.cms_msg_no_sax().wrap(q_msg, self.rootd_bpki_key, self.rootd_bpki_cert, self.rootd_bpki_crl)
- r_der = rpki.http_simple.client(self.pubd_url, q_der)
- r_cms = rpki.publication.cms_msg_no_sax(DER = r_der)
- r_msg = r_cms.unwrap((self.bpki_ta, self.pubd_bpki_cert))
- self.pubd_cms_timestamp = r_cms.check_replay(self.pubd_cms_timestamp, self.pubd_url)
+ r_msg = rpki.http_simple.client(
+ proto_cms_msg = rpki.publication.cms_msg_no_sax,
+ client_key = self.rootd_bpki_key,
+ client_cert = self.rootd_bpki_cert,
+ client_crl = self.rootd_bpki_crl,
+ server_ta = self.bpki_ta,
+ server_cert = self.pubd_bpki_cert,
+ url = self.pubd_url,
+ q_msg = q_msg,
+ replay_track = self.pubd_replay_tracker)
rpki.publication.raise_if_error(r_msg)
return r_msg
@@ -373,15 +388,11 @@ class main(object):
def __init__(self):
-
- global rootd
- rootd = self # Gross, but simpler than what we'd have to do otherwise
-
self.serial_number = None
self.crl_number = None
self.revoked = []
self.rpkid_cms_timestamp = None
- self.pubd_cms_timestamp = None
+ self.pubd_replay_tracker = ReplayTracker()
os.environ["TZ"] = "UTC"
time.tzset()