aboutsummaryrefslogtreecommitdiff
path: root/rpkid/rpki/gui/scripts/list_resources.py
diff options
context:
space:
mode:
Diffstat (limited to 'rpkid/rpki/gui/scripts/list_resources.py')
-rw-r--r--rpkid/rpki/gui/scripts/list_resources.py217
1 files changed, 217 insertions, 0 deletions
diff --git a/rpkid/rpki/gui/scripts/list_resources.py b/rpkid/rpki/gui/scripts/list_resources.py
new file mode 100644
index 00000000..77380505
--- /dev/null
+++ b/rpkid/rpki/gui/scripts/list_resources.py
@@ -0,0 +1,217 @@
+# $Id$
+#
+# Copyright (C) 2010 SPARTA, Inc. dba Cobham Analytic Solutions
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL SPARTA 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.
+#
+#
+# This script is reponsible for talking to rpkid and populating the
+# portal-gui's sqlite database. It asks rpkid for the list of received
+# resources, and the handles of any children.
+#
+# This script should be run in the directory containing the rpki.conf
+# for the handle that is self-hosting rpkid.
+#
+# Exit values:
+# 0 success, no errors
+# 1 fatal error
+# 2 usage error
+# 3 did not receive all <list_received_resources/> responses, try again
+# later
+
+import sys
+
+import os
+os.environ['DJANGO_SETTINGS_MODULE'] = 'rpki.gui.settings'
+
+from datetime import datetime
+import getopt
+from os.path import basename
+
+from rpki.myrpki import CA
+import rpki.config
+import rpki.x509
+import rpki.http
+import rpki.async
+import rpki.left_right
+import rpki.resource_set
+
+from rpki.gui.app import models
+
+verbose = False
+version = '$Id$'
+
+def query_rpkid():
+ """Fetch our received resources from the local rpkid using the rpki.conf
+ in the current directory."""
+ cfg_file = os.getenv("RPKI_CONF", "rpki.conf")
+ cfg = rpki.config.parser(cfg_file, "myrpki")
+ bpki_servers = CA(cfg_file, cfg.get("bpki_servers_directory"))
+ rpkid_base = "http://%s:%s/" % (cfg.get("rpkid_server_host"), cfg.get("rpkid_server_port"))
+
+ if verbose:
+ print 'current directory is', os.getcwd()
+ print 'cfg_file=', cfg_file
+ print 'bpki_servers=', bpki_servers.dir
+ print 'rpkid_base=', rpkid_base
+
+ call_rpkid = rpki.async.sync_wrapper(rpki.http.caller(
+ proto = rpki.left_right,
+ client_key = rpki.x509.RSA(PEM_file = bpki_servers.dir + "/irbe.key"),
+ client_cert = rpki.x509.X509(PEM_file = bpki_servers.dir + "/irbe.cer"),
+ server_ta = rpki.x509.X509(PEM_file = bpki_servers.cer),
+ server_cert = rpki.x509.X509(PEM_file = bpki_servers.dir + "/rpkid.cer"),
+ url = rpkid_base + "left-right",
+ debug = verbose))
+
+ if verbose:
+ print 'retrieving the list of <self/> handles served by this rpkid'
+ rpkid_reply = call_rpkid(rpki.left_right.self_elt.make_pdu(action="list"))
+
+ # retrieve info about each handle
+ pdus = []
+ handles = []
+ for h in rpkid_reply:
+ assert isinstance(h, rpki.left_right.self_elt)
+ if verbose:
+ print 'adding handle %s to query' % (h.self_handle,)
+ # keep a list of the handles served by rpkid so that we may check that
+ # all expected responses are received.
+ handles.append(h.self_handle)
+ pdus.extend(
+ [rpki.left_right.child_elt.make_pdu(action="list", self_handle=h.self_handle),
+ rpki.left_right.list_received_resources_elt.make_pdu(self_handle=h.self_handle)
+ #rpki.left_right.parent_elt.make_pdu(action="list", tag="parents", self_handle=handle),
+ #rpki.left_right.list_roa_requests_elt.make_pdu(tag='roas', self_handle=handle),
+ ])
+
+ if verbose:
+ print 'querying for children and resources'
+ return handles, call_rpkid(*pdus)
+
+def usage(rc):
+ print 'usage: %s [ -hvV ] [ --help ] [ --verbose ] [ --version ]' % basename(sys.argv[0],)
+ sys.exit(rc)
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], 'hvV', [ 'help', 'verbose', 'version'])
+except getopt.GetoptError, err:
+ print str(err)
+ usage(2)
+
+for o,a in opts:
+ if o in ('-h', '--help'):
+ usage(0)
+ elif o in ('-v', '--verbose'):
+ verbose = True
+ elif o in ('-V', '--version'):
+ print basename(sys.argv[0]), version
+ sys.exit(0)
+
+handles, pdus = query_rpkid()
+seen = set() # which handles we got <list_received_resources/> responses
+for pdu in pdus:
+ conf_set = models.Conf.objects.filter(handle=pdu.self_handle)
+ if conf_set.count():
+ conf = conf_set[0]
+ else:
+ if verbose:
+ print 'creating new conf for %s' % (pdu.self_handle,)
+ conf = models.Conf.objects.create(handle=pdu.self_handle)
+
+ #if isinstance(pdu, rpki.left_right.parent_elt):
+# print x.parent_handle, x.sia_base, x.sender_name, x.recipient_name, \
+# x.peer_contact_uri
+ if isinstance(pdu, rpki.left_right.child_elt):
+ # have we seen this child before?
+ child_set = conf.children.filter(handle=pdu.child_handle)
+ if not child_set:
+ if verbose:
+ print 'creating new child %s' % (pdu.child_handle,)
+ child = models.Child(conf=conf, handle=pdu.child_handle)
+ child.save()
+ #elif isinstance(x, rpki.left_right.list_roa_requests_elt):
+ # print x.asn, x.ipv4, x.ipv6
+ elif isinstance(pdu, rpki.left_right.list_received_resources_elt):
+ # keep track of handles we got replies for
+ seen.add(pdu.self_handle)
+ # have we seen this parent before?
+ parent_set = conf.parents.filter(handle=pdu.parent_handle)
+ if not parent_set:
+ if verbose:
+ print 'creating new parent %s' % (pdu.parent_handle,)
+ parent = models.Parent(conf=conf, handle=pdu.parent_handle)
+ parent.save()
+ else:
+ parent = parent_set[0]
+
+ not_before = datetime.strptime(pdu.notBefore, "%Y-%m-%dT%H:%M:%SZ")
+ not_after = datetime.strptime(pdu.notAfter, "%Y-%m-%dT%H:%M:%SZ")
+
+ # have we seen this resource cert before?
+ cert_set = parent.resources.filter(uri=pdu.uri)
+ if cert_set.count() == 0:
+ cert = models.ResourceCert(uri=pdu.uri, parent=parent,
+ not_before=not_before, not_after=not_after)
+ else:
+ cert = cert_set[0]
+ # update timestamps since it could have been modified
+ cert.not_before = not_before
+ cert.not_after = not_after
+ cert.save()
+
+ for asn in rpki.resource_set.resource_set_as(pdu.asn):
+ # see if this resource is already part of the cert
+ if cert.asn.filter(lo=asn.min, hi=asn.max).count() == 0:
+ # ensure this range wasn't seen from another of our parents
+ for v in models.Asn.objects.filter(lo=asn.min, hi=asn.max):
+ # determine if resource is delegated from another parent
+ if v.from_cert.filter(parent__in=conf.parents.all()).count():
+ cert.asn.add(v)
+ break
+ else:
+ if verbose:
+ print 'adding AS %s' % (asn,)
+ cert.asn.create(lo=asn.min, hi=asn.max)
+ cert.save()
+
+ # IPv4/6 - not separated in the django db
+ def add_missing_address(addr_set):
+ for ip in addr_set:
+ lo=str(ip.min)
+ hi=str(ip.max)
+ if cert.address_range.filter(lo=lo, hi=hi).count() == 0:
+ # ensure that this range wasn't previously seen from another of our parents
+ for v in models.AddressRange.objects.filter(lo=lo, hi=hi):
+ # determine if this resource is delegated from another parent as well
+ if v.from_cert.filter(parent__in=conf.parents.all()).count():
+ cert.address_range.add(v)
+ break
+ else:
+ if verbose:
+ print 'adding address range %s' % (ip,)
+ cert.address_range.create(lo=lo, hi=hi)
+ cert.save()
+
+ add_missing_address(rpki.resource_set.resource_set_ipv4(pdu.ipv4))
+ add_missing_address(rpki.resource_set.resource_set_ipv6(pdu.ipv6))
+
+# verify that we got responses for all expected handles
+for h in handles:
+ if h not in seen:
+ print >>sys.stderr, 'error: did not receive response for handle %s' % (h,)
+ sys.exit(3)
+
+sys.exit(0) # success
+
+# vim:sw=4 expandtab ts=4