aboutsummaryrefslogtreecommitdiff
path: root/rpkid/rpki/irdbd.py
diff options
context:
space:
mode:
Diffstat (limited to 'rpkid/rpki/irdbd.py')
-rw-r--r--rpkid/rpki/irdbd.py266
1 files changed, 0 insertions, 266 deletions
diff --git a/rpkid/rpki/irdbd.py b/rpkid/rpki/irdbd.py
deleted file mode 100644
index 41739dc4..00000000
--- a/rpkid/rpki/irdbd.py
+++ /dev/null
@@ -1,266 +0,0 @@
-# $Id$
-#
-# Copyright (C) 2013--2014 Dragon Research Labs ("DRL")
-# Portions copyright (C) 2009--2012 Internet Systems Consortium ("ISC")
-# Portions copyright (C) 2007--2008 American Registry for Internet Numbers ("ARIN")
-#
-# Permission to use, copy, modify, and distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notices and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND DRL, ISC, AND ARIN DISCLAIM ALL
-# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DRL,
-# ISC, OR ARIN BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
-# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
-# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""
-IR database daemon.
-"""
-
-import sys
-import os
-import time
-import argparse
-import urlparse
-import rpki.http
-import rpki.config
-import rpki.resource_set
-import rpki.relaxng
-import rpki.exceptions
-import rpki.left_right
-import rpki.log
-import rpki.x509
-import rpki.daemonize
-
-class main(object):
-
- def handle_list_resources(self, q_pdu, r_msg):
- child = rpki.irdb.Child.objects.get(
- issuer__handle__exact = q_pdu.self_handle,
- handle = q_pdu.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)
-
- def handle_list_roa_requests(self, q_pdu, r_msg):
- 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]):
- 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)
-
- def handle_list_ghostbuster_requests(self, q_pdu, r_msg):
- ghostbusters = rpki.irdb.GhostbusterRequest.objects.filter(
- issuer__handle__exact = q_pdu.self_handle,
- parent__handle__exact = q_pdu.parent_handle)
- if ghostbusters.count() == 0:
- ghostbusters = rpki.irdb.GhostbusterRequest.objects.filter(
- issuer__handle__exact = q_pdu.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)
-
- 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):
- 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)
-
- def handler(self, query, path, cb):
- 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")
- try:
- q_cms = rpki.left_right.cms_msg(DER = query)
- q_msg = q_cms.unwrap((serverCA.certificate, rpkid.certificate))
- self.cms_timestamp = q_cms.check_replay(self.cms_timestamp, 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)
- except (rpki.async.ExitNow, SystemExit):
- raise
- except Exception, e:
- rpki.log.traceback()
- 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")
- cb(200, body = rpki.left_right.cms_msg().wrap(r_msg, irdbd.private_key, irdbd.certificate))
- except (rpki.async.ExitNow, SystemExit):
- raise
- except Exception, e:
- rpki.log.traceback()
- cb(500, reason = "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
-
- os.environ["TZ"] = "UTC"
- time.tzset()
-
- parser = argparse.ArgumentParser(description = __doc__)
- parser.add_argument("-c", "--config",
- help = "override default location of configuration file")
- parser.add_argument("-d", "--debug", action = "store_true",
- help = "enable debugging mode")
- parser.add_argument("-f", "--foreground", action = "store_true",
- help = "do not daemonize")
- parser.add_argument("--pidfile",
- help = "override default location of pid file")
- parser.add_argument("--profile",
- help = "enable profiling, saving data to PROFILE")
- args = parser.parse_args()
-
- rpki.log.init("irdbd", use_syslog = not args.debug)
-
- self.cfg = rpki.config.parser(args.config, "irdbd")
- self.cfg.set_global_flags()
-
- if not args.foreground and not args.debug:
- rpki.daemonize.daemon(pidfile = args.pidfile)
-
- if args.profile:
- import cProfile
- prof = cProfile.Profile()
- try:
- prof.runcall(self.main)
- finally:
- prof.dump_stats(args.profile)
- rpki.log.info("Dumped profile data to %s" % args.profile)
- else:
- self.main()
-
- def main(self):
-
- global rpki # pylint: disable=W0602
- from django.conf import settings
-
- startup_msg = self.cfg.get("startup-message", "")
- if startup_msg:
- rpki.log.info(startup_msg)
-
- # Do -not- turn on DEBUG here except for short-lived tests,
- # otherwise irdbd will eventually run out of memory and crash.
- #
- # If you must enable debugging, use django.db.reset_queries() to
- # clear the query list manually, but it's probably better just to
- # run with debugging disabled, since that's the expectation for
- # production code.
- #
- # https://docs.djangoproject.com/en/dev/faq/models/#why-is-django-leaking-memory
-
- settings.configure(
- DATABASES = {
- "default" : {
- "ENGINE" : "django.db.backends.mysql",
- "NAME" : self.cfg.get("sql-database"),
- "USER" : self.cfg.get("sql-username"),
- "PASSWORD" : self.cfg.get("sql-password"),
- "HOST" : "",
- "PORT" : "" }},
- INSTALLED_APPS = ("rpki.irdb",),)
-
- import rpki.irdb # pylint: disable=W0621
-
- # Entirely too much fun with read-only access to transactional databases.
- #
- # http://stackoverflow.com/questions/3346124/how-do-i-force-django-to-ignore-any-caches-and-reload-data
- # http://devblog.resolversystems.com/?p=439
- # http://groups.google.com/group/django-users/browse_thread/thread/e25cec400598c06d
- # http://stackoverflow.com/questions/1028671/python-mysqldb-update-query-fails
- # http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html
- #
- # It turns out that MySQL is doing us a favor with this weird
- # transactional behavior on read, because without it there's a
- # race condition if multiple updates are committed to the IRDB
- # while we're in the middle of processing a query. Note that
- # proper transaction management by the committers doesn't protect
- # us, this is a transactional problem on read. So we need to use
- # explicit transaction management. Since irdbd is a read-only
- # consumer of IRDB data, this means we need to commit an empty
- # transaction at the beginning of processing each query, to reset
- # the transaction isolation snapshot.
-
- 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:
- #
- # 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.cms_timestamp = None
-
- rpki.http.server(
- host = self.http_server_host,
- port = self.http_server_port,
- handlers = self.handler)