aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2014-09-19 23:32:16 +0000
committerRob Austein <sra@hactrn.net>2014-09-19 23:32:16 +0000
commit3343f587e25c153333981cc4c9ad43c95516c279 (patch)
treef88cb15624169565167fcfcb4228938dc9e493f4
parentbcd211ab6dfb899733d04edaa909115ae7e83c3e (diff)
Convert irdbd from SAX to lxml.etree.
svn path=/branches/tk705/; revision=5962
-rw-r--r--rpki/irdbd.py150
-rw-r--r--rpki/left_right.py20
-rw-r--r--rpki/pubd.py6
3 files changed, 88 insertions, 88 deletions
diff --git a/rpki/irdbd.py b/rpki/irdbd.py
index 6e7e1632..805280d7 100644
--- a/rpki/irdbd.py
+++ b/rpki/irdbd.py
@@ -36,111 +36,108 @@ import rpki.log
import rpki.x509
import rpki.daemonize
+from lxml.etree import Element, SubElement
+
logger = logging.getLogger(__name__)
class main(object):
def handle_list_resources(self, q_pdu, r_msg):
+ self_handle = q_pdu.get("self_handle")
+ child_handle = q_pdu.get("child_handle")
child = rpki.irdb.Child.objects.get(
- issuer__handle__exact = q_pdu.self_handle,
- handle = q_pdu.child_handle)
+ issuer__handle__exact = self_handle,
+ handle = child_handle)
resources = child.resource_bag
- r_pdu = rpki.left_right.list_resources_elt()
- r_pdu.tag = q_pdu.tag
- r_pdu.self_handle = q_pdu.self_handle
- r_pdu.child_handle = q_pdu.child_handle
- r_pdu.valid_until = child.valid_until.strftime("%Y-%m-%dT%H:%M:%SZ")
- r_pdu.asn = resources.asn
- r_pdu.ipv4 = resources.v4
- r_pdu.ipv6 = resources.v6
- r_msg.append(r_pdu)
+ r_pdu = SubElement(r_msg, rpki.left_right.tag_list_resources, self_handle = self_handle, child_handle = child_handle,
+ valid_until = child.valid_until.strftime("%Y-%m-%dT%H:%M:%SZ"))
+ for k, v in (("asn", resources.asn),
+ ("ipv4", resources.v4),
+ ("ipv6", resources.v6),
+ ("tag", q_pdu.get("tag"))):
+ if v:
+ r_pdu.set(k, str(v))
def handle_list_roa_requests(self, q_pdu, r_msg):
+ self_handle = q_pdu.get("self_handle")
for request in rpki.irdb.ROARequest.objects.raw("""
SELECT irdb_roarequest.*
FROM irdb_roarequest, irdb_resourceholderca
WHERE irdb_roarequest.issuer_id = irdb_resourceholderca.id
AND irdb_resourceholderca.handle = %s
- """, [q_pdu.self_handle]):
+ """, [self_handle]):
prefix_bag = request.roa_prefix_bag
- r_pdu = rpki.left_right.list_roa_requests_elt()
- r_pdu.tag = q_pdu.tag
- r_pdu.self_handle = q_pdu.self_handle
- r_pdu.asn = request.asn
- r_pdu.ipv4 = prefix_bag.v4
- r_pdu.ipv6 = prefix_bag.v6
- r_msg.append(r_pdu)
+ r_pdu = SubElement(r_msg, rpki.left_right.tag_list_roa_requests, self_handle = self_handle, asn = str(request.asn))
+ for k, v in (("ipv4", prefix_bag.v4),
+ ("ipv6", prefix_bag.v6),
+ ("tag", q_pdu.get("tag"))):
+ if v:
+ r_pdu.set(k, str(v))
def handle_list_ghostbuster_requests(self, q_pdu, r_msg):
+ self_handle = q_pdu.get("self_handle")
+ parent_handle = q_pdu.get("parent_handle")
ghostbusters = rpki.irdb.GhostbusterRequest.objects.filter(
- issuer__handle__exact = q_pdu.self_handle,
- parent__handle__exact = q_pdu.parent_handle)
+ issuer__handle__exact = self_handle,
+ parent__handle__exact = parent_handle)
if ghostbusters.count() == 0:
ghostbusters = rpki.irdb.GhostbusterRequest.objects.filter(
- issuer__handle__exact = q_pdu.self_handle,
+ issuer__handle__exact = self_handle,
parent = None)
for ghostbuster in ghostbusters:
- r_pdu = rpki.left_right.list_ghostbuster_requests_elt()
- r_pdu.tag = q_pdu.tag
- r_pdu.self_handle = q_pdu.self_handle
- r_pdu.parent_handle = q_pdu.parent_handle
- r_pdu.vcard = ghostbuster.vcard
- r_msg.append(r_pdu)
+ r_pdu = SubElement(r_msg, q_pdu.tag, self_handle = self_handle, parent_handle = parent_handle)
+ if q_pdu.get("tag"):
+ r_pdu.set("tag", q_pdu.get("tag"))
+ r_pdu.text = ghostbuster.vcard
def handle_list_ee_certificate_requests(self, q_pdu, r_msg):
- for ee_req in rpki.irdb.EECertificateRequest.objects.filter(issuer__handle__exact = q_pdu.self_handle):
+ self_handle = q_pdu.get("self_handle")
+ for ee_req in rpki.irdb.EECertificateRequest.objects.filter(issuer__handle__exact = self_handle):
resources = ee_req.resource_bag
- r_pdu = rpki.left_right.list_ee_certificate_requests_elt()
- r_pdu.tag = q_pdu.tag
- r_pdu.self_handle = q_pdu.self_handle
- r_pdu.gski = ee_req.gski
- r_pdu.valid_until = ee_req.valid_until.strftime("%Y-%m-%dT%H:%M:%SZ")
- r_pdu.asn = resources.asn
- r_pdu.ipv4 = resources.v4
- r_pdu.ipv6 = resources.v6
- r_pdu.cn = ee_req.cn
- r_pdu.sn = ee_req.sn
- r_pdu.eku = ee_req.eku
- r_pdu.pkcs10 = ee_req.pkcs10
- r_msg.append(r_pdu)
+ r_pdu = SubElement(r_msg, q_pdu.tag, self_handle = self_handle, gski = ee_req.gski,
+ valid_until = ee_req.valid_until.strftime("%Y-%m-%dT%H:%M:%SZ"),
+ cn = ee_req.cn, sn = ee_req.sn)
+ for k, v in (("asn", resources.asn),
+ ("ipv4", resources.v4),
+ ("ipv6", resources.v6),
+ ("eku", ee_req.eku),
+ ("tag", q_pdu.get("tag"))):
+ if v:
+ r_pdu.set(k, str(v))
+ SubElement(r_pdu, rpki.left_right.tag_pkcs10).text = ee_req.pkcs10.get_Base64()
def handler(self, request, q_der):
try:
- q_pdu = None
- r_msg = rpki.left_right.msg.reply()
from django.db import connection
connection.cursor() # Reconnect to mysqld if necessary
self.start_new_transaction()
serverCA = rpki.irdb.ServerCA.objects.get()
rpkid = serverCA.ee_certificates.get(purpose = "rpkid")
+ irdbd = serverCA.ee_certificates.get(purpose = "irdbd")
+ q_cms = rpki.left_right.cms_msg_no_sax(DER = q_der)
+ q_msg = q_cms.unwrap((serverCA.certificate, rpkid.certificate))
+ self.cms_timestamp = q_cms.check_replay(self.cms_timestamp, request.path)
+ if q_msg.get("type") != "query":
+ raise rpki.exceptions.BadQuery("Message type is %s, expected query" % q_msg.get("type"))
+ r_msg = Element(rpki.left_right.tag_msg, nsmap = rpki.left_right.nsmap,
+ type = "reply", version = rpki.left_right.version)
try:
- q_cms = rpki.left_right.cms_msg(DER = q_der)
- q_msg = q_cms.unwrap((serverCA.certificate, rpkid.certificate))
- self.cms_timestamp = q_cms.check_replay(self.cms_timestamp, request.path)
- if not isinstance(q_msg, rpki.left_right.msg) or not q_msg.is_query():
- raise rpki.exceptions.BadQuery("Unexpected %r PDU" % q_msg)
for q_pdu in q_msg:
- self.dispatch(q_pdu, r_msg)
+ getattr(self, "handle_" + q_pdu.tag[len(rpki.left_right.xmlns):])(q_pdu, r_msg)
+
except Exception, e:
- logger.exception("Exception while handling HTTP request")
- if q_pdu is None:
- r_msg.append(rpki.left_right.report_error_elt.from_exception(e))
- else:
- r_msg.append(rpki.left_right.report_error_elt.from_exception(e, q_pdu.self_handle, q_pdu.tag))
- irdbd = serverCA.ee_certificates.get(purpose = "irdbd")
- request.send_cms_response(rpki.left_right.cms_msg().wrap(r_msg, irdbd.private_key, irdbd.certificate))
+ logger.exception("Exception processing PDU %r", q_pdu)
+ r_pdu = SubElement(r_msg, rpki.left_right.tag_report_error, error_code = e.__class__.__name__)
+ r_pdu.text = str(e)
+ if q_pdu.get("tag") is not None:
+ r_pdu.set("tag", q_pdu.get("tag"))
+
+ request.send_cms_response(rpki.left_right.cms_msg_no_sax().wrap(r_msg, irdbd.private_key, irdbd.certificate))
+
except Exception, e:
logger.exception("Unhandled exception while processing HTTP request")
request.send_error(500, "Unhandled exception %s: %s" % (e.__class__.__name__, e))
- def dispatch(self, q_pdu, r_msg):
- try:
- handler = self.dispatch_vector[type(q_pdu)]
- except KeyError:
- raise rpki.exceptions.BadQuery("Unexpected %r PDU" % q_pdu)
- else:
- handler(q_pdu, r_msg)
-
def __init__(self, **kwargs):
global rpki # pylint: disable=W0602
@@ -214,27 +211,8 @@ class main(object):
import django.db.transaction
self.start_new_transaction = django.db.transaction.commit_manually(django.db.transaction.commit)
- self.dispatch_vector = {
- rpki.left_right.list_resources_elt : self.handle_list_resources,
- rpki.left_right.list_roa_requests_elt : self.handle_list_roa_requests,
- rpki.left_right.list_ghostbuster_requests_elt : self.handle_list_ghostbuster_requests,
- rpki.left_right.list_ee_certificate_requests_elt : self.handle_list_ee_certificate_requests}
-
- try:
- self.http_server_host = self.cfg.get("server-host", "")
- self.http_server_port = self.cfg.getint("server-port")
- except: # pylint: disable=W0702
- #
- # Backwards compatibility, remove this eventually.
- #
- u = urlparse.urlparse(self.cfg.get("http-url"))
- if (u.scheme not in ("", "http") or
- u.username is not None or
- u.password is not None or
- u.params or u.query or u.fragment):
- raise
- self.http_server_host = u.hostname
- self.http_server_port = int(u.port)
+ self.http_server_host = self.cfg.get("server-host", "")
+ self.http_server_port = self.cfg.getint("server-port")
self.cms_timestamp = None
diff --git a/rpki/left_right.py b/rpki/left_right.py
index 2dfa6efd..58612c10 100644
--- a/rpki/left_right.py
+++ b/rpki/left_right.py
@@ -41,6 +41,17 @@ from lxml.etree import Element, SubElement
logger = logging.getLogger(__name__)
+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"
+
+
## @var enforce_strict_up_down_xml_sender
# Enforce strict checking of XML "sender" field in up-down protocol
@@ -1339,3 +1350,12 @@ class cms_msg(rpki.x509.XML_CMS_object):
encoding = "us-ascii"
schema = rpki.relaxng.left_right
saxify = sax_handler.saxify
+
+class cms_msg_no_sax(cms_msg):
+ """
+ Class to hold a CMS-signed left-right PDU.
+
+ Name is a transition kludge: once we ditch SAX, this will become cms_msg.
+ """
+
+ saxify = None
diff --git a/rpki/pubd.py b/rpki/pubd.py
index 3e7d4506..3bb139cb 100644
--- a/rpki/pubd.py
+++ b/rpki/pubd.py
@@ -132,9 +132,10 @@ class main(object):
Process one PDU from the IRBE.
"""
- from django.db import transaction
+ from django.db import transaction, connection
try:
+ connection.cursor() # Reconnect to mysqld if necessary
q_cms = rpki.publication_control.cms_msg_no_sax(DER = q_der)
q_msg = q_cms.unwrap((self.bpki_ta, self.irbe_cert))
self.irbe_cms_timestamp = q_cms.check_replay(self.irbe_cms_timestamp, "control")
@@ -220,9 +221,10 @@ class main(object):
Process one PDU from a client.
"""
- from django.db import transaction
+ from django.db import transaction, connection
try:
+ connection.cursor() # Reconnect to mysqld if necessary
match = self.client_url_regexp.search(request.path)
if match is None:
raise rpki.exceptions.BadContactURL("Bad path: %s" % request.path)