aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Elkins <melkins@tislabs.com>2010-07-01 18:09:17 +0000
committerMichael Elkins <melkins@tislabs.com>2010-07-01 18:09:17 +0000
commit930d00877a47e8b1b1d171a872129b7ac0439315 (patch)
tree45fe610ab918a117d2eb03dfb3c06fa17e702bc8
parent73fa74c23b2d6a6af7ea31c72a17611a793e8fae (diff)
add auxillary scripts for querying rpkid/rcynic, add model objects to represent resource certs
svn path=/portal-gui/rpkigui/myrpki/admin.py; revision=3307
-rw-r--r--portal-gui/rpkigui/myrpki/admin.py20
-rw-r--r--portal-gui/rpkigui/myrpki/models.py35
-rw-r--r--portal-gui/rpkigui/myrpki/urls.py3
-rw-r--r--portal-gui/rpkigui/myrpki/views.py95
-rw-r--r--portal-gui/rpkigui/settings.py2
-rw-r--r--portal-gui/rpkigui/templates/myrpki/child_view.html27
-rw-r--r--portal-gui/rpkigui/templates/myrpki/dashboard.html17
-rw-r--r--portal-gui/rpkigui/templates/myrpki/parent_view.html16
-rw-r--r--portal-gui/rpkigui/templates/myrpki/resource_view.html8
-rwxr-xr-xportal-gui/scripts/list_resources5
-rwxr-xr-xportal-gui/scripts/list_resources.py132
-rwxr-xr-xportal-gui/scripts/roa_check.py70
12 files changed, 356 insertions, 74 deletions
diff --git a/portal-gui/rpkigui/myrpki/admin.py b/portal-gui/rpkigui/myrpki/admin.py
index 72d330a2..3d843bb0 100644
--- a/portal-gui/rpkigui/myrpki/admin.py
+++ b/portal-gui/rpkigui/myrpki/admin.py
@@ -2,9 +2,6 @@ from django import forms
from django.contrib import admin
from rpkigui.myrpki import models
-#class CertAdmin( admin.ModelAdmin ):
-# pass
-
class ConfAdmin( admin.ModelAdmin ):
pass
@@ -23,10 +20,13 @@ class ParentAdmin( admin.ModelAdmin ):
class RoaAdmin( admin.ModelAdmin ):
pass
-#admin.site.register( models.Cert, CertAdmin )
-admin.site.register( models.Conf, ConfAdmin )
-admin.site.register( models.Child, ChildAdmin )
-admin.site.register( models.AddressRange, AddressRangeAdmin )
-admin.site.register( models.Asn, AsnAdmin )
-admin.site.register( models.Parent, ParentAdmin )
-admin.site.register( models.Roa, RoaAdmin )
+class ResourceCertAdmin(admin.ModelAdmin):
+ pass
+
+admin.site.register(models.Conf, ConfAdmin)
+admin.site.register(models.Child, ChildAdmin)
+admin.site.register(models.AddressRange, AddressRangeAdmin)
+admin.site.register(models.Asn, AsnAdmin)
+admin.site.register(models.Parent, ParentAdmin)
+admin.site.register(models.Roa, RoaAdmin)
+admin.site.register(models.ResourceCert, ResourceCertAdmin)
diff --git a/portal-gui/rpkigui/myrpki/models.py b/portal-gui/rpkigui/myrpki/models.py
index d062698e..9abc80ed 100644
--- a/portal-gui/rpkigui/myrpki/models.py
+++ b/portal-gui/rpkigui/myrpki/models.py
@@ -79,10 +79,9 @@ class Parent(models.Model):
# service_uri = models.URLField( verify_exists=False )
# sia_base = models.URLField( verify_exists=False )
- # resources granted from my parent
- address_range = models.ManyToManyField(AddressRange, blank=True,
- related_name='from_parent')
- asn = models.ManyToManyField(Asn, related_name='from_parent', blank=True)
+ #address_range = models.ManyToManyField(AddressRange, blank=True,
+ # related_name='from_parent')
+ #asn = models.ManyToManyField(Asn, related_name='from_parent', blank=True)
def __unicode__(self):
return u"%s's parent %s" % (self.conf, self.handle)
@@ -94,15 +93,43 @@ class Parent(models.Model):
# parents of a specific configuration should be unique
unique_together = ('conf', 'handle')
+class ResourceCert(models.Model):
+ parent = models.ForeignKey(Parent, related_name='resources')
+
+ # resources granted from my parent
+ asn = models.ManyToManyField(Asn, related_name='from_cert', blank=True,
+ null=True)
+ address_range = models.ManyToManyField(AddressRange, related_name='from_cert',
+ blank=True, null=True)
+
+ # unique id for this resource certificate
+ # FIXME: URLField(verify_exists=False) doesn't seem to work - the admin
+ # editor won't accept a rsync:// scheme as valid
+ uri = models.CharField(max_length=200)
+
+ # certificate validity period
+ not_before = models.DateTimeField()
+ not_after = models.DateTimeField()
+
+ def get_absolute_url(self):
+ return u"/myrpki/resource/%d" % (self.pk,)
+
+ def __unicode__(self):
+ return u"%s's resource cert from parent %s" % (self.parent.conf.handle,
+ self.parent.handle)
+
class Roa(models.Model):
conf = models.ForeignKey(Conf, related_name='roas')
prefix = models.ManyToManyField(AddressRange)
max_len = models.IntegerField()
asn = models.IntegerField()
comments = models.TextField()
+ active = models.BooleanField()
def __unicode__(self):
return u"%s's ROA for %d" % (self.conf, self.asn)
def get_absolute_url(self):
return u'/myrpki/roa/%d' % (self.pk, )
+
+# vim:sw=4 ts=8 expandtab
diff --git a/portal-gui/rpkigui/myrpki/urls.py b/portal-gui/rpkigui/myrpki/urls.py
index 2a8e2a96..b8230bff 100644
--- a/portal-gui/rpkigui/myrpki/urls.py
+++ b/portal-gui/rpkigui/myrpki/urls.py
@@ -16,6 +16,7 @@ urlpatterns = patterns('',
(r'^import/parent$', views.parent_import),
(r'^import/child$', views.child_import),
(r'^parent/(?P<parent_handle>[^/]+)$', views.parent_view),
+ (r'^child/(?P<child_handle>[^/]+)$', views.child_view),
# (r'^parent/(?P<parent_handle>[^/]+)/address$', views.parent_address),
# (r'^parent/(?P<parent_handle>[^/]+)/asn$', views.parent_asn),
(r'^address/(?P<pk>\d+)$', views.address_view),
@@ -23,3 +24,5 @@ urlpatterns = patterns('',
(r'^roa/$', views.roa_edit ),
(r'^roa/(?P<pk>\d+)$', views.roa_edit ),
)
+
+# vim:sw=4 ts=8 expandtab
diff --git a/portal-gui/rpkigui/myrpki/views.py b/portal-gui/rpkigui/myrpki/views.py
index 1789fd91..c7d93779 100644
--- a/portal-gui/rpkigui/myrpki/views.py
+++ b/portal-gui/rpkigui/myrpki/views.py
@@ -91,14 +91,16 @@ def dashboard(request):
roa_asns = [r.asn for r in handle.roas.all()]
# get list of unallocated asns
asns = [o for p in handle.parents.all()
- for o in p.asn.filter(parent__isnull=True, allocated__isnull=True).exclude(lo__in=roa_asns)
+ for c in p.resources.all()
+ for o in c.asn.filter(parent__isnull=True, allocated__isnull=True).exclude(lo__in=roa_asns)
if (o.hi == o.lo)]
# get list of address ranges included in ROAs
roa_addrs = [p for r in handle.roas.all() for p in r.prefix.all()]
# get list of unallocated address ranges
ars = [o for p in handle.parents.all()
- for o in p.address_range.filter(parent__isnull=True, allocated__isnull=True)
+ for c in p.resources.all()
+ for o in c.address_range.filter(parent__isnull=True, allocated__isnull=True)
if (not o in roa_addrs)]
return render('myrpki/dashboard.html', { 'conf': handle, 'asns': asns,
@@ -138,36 +140,36 @@ def dashboard(request):
# return delete_object( request, model=models.Cert, object_id=id,
# post_delete_redirect='/dashboard/' )
-@login_required
-def conf_add(request):
- '''Allow the user to create a new configuration.'''
- errors = []
- if request.method == 'POST':
- form = forms.AddConfForm(request.POST)
- if form.is_valid():
- try:
- handle = form.cleaned_data['handle']
- # ensure this user is in the group for this handle
- grps = request.user.groups.filter(name=handle)
- if len(grps) == 0:
- errors.append(
- 'You are not in the proper group for that handle.')
- else:
- conf = models.Conf.objects.create(
- handle=form.cleaned_data['handle'], owner=grps[0])
- conf.save()
- glue.form_to_conf(form.cleaned_data)
- return http.HttpResponseRedirect('/myrpki/')
- # data model will ensure the handle is unique
- except IntegrityError, e:
- print e
- errors.append('That handle already exists.')
- else:
- errors.append("The form wasn't valid.")
- else:
- form = forms.AddConfForm()
- return render_to_response('myrpki/add_conf.html',
- { 'form': form, 'errors': errors })
+#@login_required
+#def conf_add(request):
+# '''Allow the user to create a new configuration.'''
+# errors = []
+# if request.method == 'POST':
+# form = forms.AddConfForm(request.POST)
+# if form.is_valid():
+# try:
+# handle = form.cleaned_data['handle']
+# # ensure this user is in the group for this handle
+# grps = request.user.groups.filter(name=handle)
+# if len(grps) == 0:
+# errors.append(
+# 'You are not in the proper group for that handle.')
+# else:
+# conf = models.Conf.objects.create(
+# handle=form.cleaned_data['handle'], owner=grps[0])
+# conf.save()
+# glue.form_to_conf(form.cleaned_data)
+# return http.HttpResponseRedirect('/myrpki/')
+# # data model will ensure the handle is unique
+# except IntegrityError, e:
+# print e
+# errors.append('That handle already exists.')
+# else:
+# errors.append("The form wasn't valid.")
+# else:
+# form = forms.AddConfForm()
+# return render_to_response('myrpki/add_conf.html',
+# { 'form': form, 'errors': errors })
@login_required
def conf_list(request):
@@ -314,26 +316,23 @@ def child_import(request):
{ 'form': form, 'kind': 'child',
'post_url': '/myrpki/import/child'}, request)
-def get_parent_or_404(handle, obj):
- '''Return the Parent object that the given address range derives
+def get_parents_or_404(handle, obj):
+ '''Return the Parent object(s) that the given address range derives
from, or raise a 404 error.'''
while obj.parent: obj = obj.parent
- if isinstance(obj, models.AddressRange):
- fn = lambda x: x.address_range.all()
- else:
- fn = lambda x: x.asn.all()
+ cert_set = obj.from_cert.filter(parent__in=handle.parents.all())
+ if cert_set.count() == 0:
+ raise http.Http404
- for p in handle.parents.all():
- if obj in fn(p): return p
- raise http.Http404
+ return handle.parents.filter(pk__in=[c.parent.pk for c in cert_set])
def resource_view(request, object_type, form_type, pk):
'''view/subdivide an address range.'''
handle = request.session['handle']
obj = get_object_or_404(object_type, pk=pk)
# ensure this resource range belongs to a parent of the current conf
- parent = get_parent_or_404(handle, obj)
+ parent_set = get_parents_or_404(handle, obj)
if request.method == 'POST':
form = form_type(handle, obj, request.POST)
@@ -357,7 +356,7 @@ def resource_view(request, object_type, form_type, pk):
else:
form = form_type(handle, obj)
return render('myrpki/resource_view.html', { 'addr': obj, 'form': form,
- 'parent': parent }, request)
+ 'parent': parent_set }, request)
@handle_required
def address_view(request, pk):
@@ -405,3 +404,13 @@ def roa_edit(request, pk=None):
prefix = [o.pk for o in obj.prefix.all()] if obj else []
form = forms.RoaForm(handle, asn, comments, prefix)
return render('myrpki/roaform.html', { 'form': form }, request)
+
+@handle_required
+def child_view(request, child_handle):
+ '''Detail view of child for the currently selected handle.'''
+ handle = request.session['handle']
+ child = get_object_or_404(handle.children.all(), handle__exact=child_handle)
+
+ return render('myrpki/child_view.html', { 'child': child }, request)
+
+# vim:sw=4 ts=8 expandtab
diff --git a/portal-gui/rpkigui/settings.py b/portal-gui/rpkigui/settings.py
index 529b0235..bc7a6a99 100644
--- a/portal-gui/rpkigui/settings.py
+++ b/portal-gui/rpkigui/settings.py
@@ -62,7 +62,7 @@ MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
# for django 1.2
-# 'django.middleware.csrf.CsrfMiddleware'
+ 'django.middleware.csrf.CsrfMiddleware'
)
ROOT_URLCONF = 'rpkigui.urls'
diff --git a/portal-gui/rpkigui/templates/myrpki/child_view.html b/portal-gui/rpkigui/templates/myrpki/child_view.html
new file mode 100644
index 00000000..77e2cf51
--- /dev/null
+++ b/portal-gui/rpkigui/templates/myrpki/child_view.html
@@ -0,0 +1,27 @@
+{% extends "base.html" %}
+
+{% block content %}
+<p>Handle: <a href="/myrpki/">{{ request.session.handle.handle }}</a>
+<h1>Child View</h1>
+<p>Child: {{ child.handle }}
+
+<h2>Delegated Addresses</h2>
+<table>
+ <tr><td>Low</td><td>High</td><td></td></tr>
+{% for a in child.address_range.all %}
+<tr>
+ <td>{{ a.lo }}</td>
+ <td>{{ a.hi }}</td>
+ <td><a href="{{ a.get_absolute_url }}">view</a></td>
+</tr>
+{% endfor %}
+</table>
+
+<h2>Delegated ASNs</h2>
+<ul>
+{% for a in child.asn.all %}
+<li><a href="{{ a.get_absolute_url }}">{{ a }}</a>
+{% endfor %}
+</ul>
+
+{% endblock %}
diff --git a/portal-gui/rpkigui/templates/myrpki/dashboard.html b/portal-gui/rpkigui/templates/myrpki/dashboard.html
index 12fee303..692e204d 100644
--- a/portal-gui/rpkigui/templates/myrpki/dashboard.html
+++ b/portal-gui/rpkigui/templates/myrpki/dashboard.html
@@ -7,22 +7,31 @@
<div style="border: inset">
<h1 style="text-align: center">Parents</h1>
+
<ul>
{% for parent in request.session.handle.parents.all %}
<li><a href="{{ parent.get_absolute_url }}">{{ parent.handle }}</a>
-{% if parent.asn.count or parent.address_range.count %}
+
+{% if parent.resources.count %}
<p>Accepted resources:
<ul>
-{% for asn in parent.asn.all %}
+{% for cert in parent.resources.all %}
+
+{% for asn in cert.asn.all %}
<li><a href="{{ asn.get_absolute_url }}">{{ asn }}</a>
{% endfor %}
-{% for address in parent.address_range.all %}
+
+{% for address in cert.address_range.all %}
<li><a href="{{ address.get_absolute_url }}">{{ address }}</a>
{% endfor %}
+
+{% endfor %} <!--certs-->
</ul>
{% endif %}
+
{% endfor %}
</ul>
+
<a href="/myrpki/import/parent">[add]</a>
</div>
@@ -32,7 +41,7 @@
<p>
<ul>
{% for child in request.session.handle.children.all %}
-<li><a href="/myrpki/child/{{ child.handle }}/">{{ child.handle }}</a>
+<li><a href="/myrpki/child/{{ child.handle }}">{{ child.handle }}</a>
{% if child.address_range.count or child.asn.count %}
<p>Delegated resources:
<ul>
diff --git a/portal-gui/rpkigui/templates/myrpki/parent_view.html b/portal-gui/rpkigui/templates/myrpki/parent_view.html
index 1f1c2465..9756c83a 100644
--- a/portal-gui/rpkigui/templates/myrpki/parent_view.html
+++ b/portal-gui/rpkigui/templates/myrpki/parent_view.html
@@ -5,30 +5,26 @@
<h1>Parent View</h1>
<p>Parent: {{ parent.handle }}
<h2>Delegated Addresses</h2>
-{% if parent.address_range.count %}
<table>
<tr><td>Low</td><td>High</td><td></td></tr>
-{% for a in parent.address_range.all %}
+{% for c in parent.resources.all %}
+{% for a in c.address_range.all %}
<tr>
<td>{{ a.lo }}</td>
<td>{{ a.hi }}</td>
<td><a href="{{ a.get_absolute_url }}">view</a></td>
</tr>
{% endfor %}
+{% endfor %}
</table>
-{% else %}
-<p>--none--
-{% endif %}
<h2>Delegated ASNs</h2>
-{% if parent.asn.count %}
<ul>
-{% for a in parent.asn.all %}
+{% for c in parent.resources.all %}
+{% for a in c.asn.all %}
<li><a href="{{ a.get_absolute_url }}">{{ a }}</a>
{% endfor %}
+{% endfor %}
</ul>
-{% else %}
-<p>--none--
-{% endif %}
{% endblock %}
diff --git a/portal-gui/rpkigui/templates/myrpki/resource_view.html b/portal-gui/rpkigui/templates/myrpki/resource_view.html
index e2992f4e..d230e66f 100644
--- a/portal-gui/rpkigui/templates/myrpki/resource_view.html
+++ b/portal-gui/rpkigui/templates/myrpki/resource_view.html
@@ -8,8 +8,12 @@
<td>Range:</td><td>{{ addr }}</td>
</tr>
<tr>
- <td>Parent:</td>
- <td><a href="{{ parent.get_absolute_url }}">{{ parent.handle }}</a></td>
+ <td>Received from:</td>
+ <td>
+ {% for p in parent %}
+ <a href="{{ p.get_absolute_url }}">{{ p.handle }}</a>
+ {% endfor %}
+ </td>
</tr>
{% if addr.parent %}
<tr>
diff --git a/portal-gui/scripts/list_resources b/portal-gui/scripts/list_resources
new file mode 100755
index 00000000..07df3541
--- /dev/null
+++ b/portal-gui/scripts/list_resources
@@ -0,0 +1,5 @@
+#!/bin/sh
+BASE_PATH=`dirname $0`/../..
+export PYTHONPATH=$BASE_PATH/rpkid:$BASE_PATH/portal-gui
+export DJANGO_SETTINGS_MODULE=rpkigui.settings
+python `dirname $0`/list_resources.py
diff --git a/portal-gui/scripts/list_resources.py b/portal-gui/scripts/list_resources.py
new file mode 100755
index 00000000..ae95228b
--- /dev/null
+++ b/portal-gui/scripts/list_resources.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python
+
+import os
+from rpki.myrpki import EntityDB, CA
+import rpki.config
+import rpki.x509
+import rpki.https
+import rpki.async
+import rpki.left_right
+import rpki.resource_set
+import rpki.ipaddrs
+
+from rpkigui.myrpki import models
+
+class ReceivedResources(object):
+ def __init__(self, self_handle, parent_handle, asn, ipv4, ipv6, uri, not_before, not_after):
+ self.self_handle = self_handle
+ self.parent_handle = parent_handle
+ self.asn = asn
+ self.ipv4 = ipv4
+ self.ipv6 = ipv6
+ self.uri = uri
+ self.not_before = not_before
+ self.not_after = not_after
+
+ def __str__(self):
+ return "%s's received resources from parent %s" % (self.self_handle, self.parent_handle, )
+
+def query_rpkid(handle=None):
+ """Fetch our received resources from the local rpkid using the myrpki.conf in the current directory."""
+ cfg_file = os.getenv("MYRPKI_CONF", "myrpki.conf")
+ cfg = rpki.config.parser(cfg_file, "myrpki")
+ if handle is None:
+ handle = cfg.get('handle')
+ entitydb = EntityDB(cfg)
+ bpki_resources = CA(cfg_file, cfg.get("bpki_resources_directory"))
+ bpki_servers = CA(cfg_file, cfg.get("bpki_servers_directory"))
+ rpkid_base = "https://%s:%s/" % (cfg.get("rpkid_server_host"), cfg.get("rpkid_server_port"))
+
+ call_rpkid = rpki.async.sync_wrapper(rpki.https.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 = True))
+
+ print 'calling rpkid...'
+ rpkid_reply = call_rpkid(
+ #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),
+ rpki.left_right.list_received_resources_elt.make_pdu(tag = "resources",
+ self_handle = handle))
+ print 'done'
+
+ resources = []
+ for x in rpkid_reply:
+ if isinstance(x, rpki.left_right.parent_elt):
+ print x.parent_handle, x.sia_base, x.sender_name, x.recipient_name, \
+ x.peer_contact_uri
+ #elif isinstance(x, rpki.left_right.list_roa_requests_elt):
+ # print x.asn, x.ipv4, x.ipv6
+ if isinstance(x, rpki.left_right.list_received_resources_elt):
+ resources.append(ReceivedResources(self_handle=handle,
+ parent_handle=x.parent_handle,
+ asn=rpki.resource_set.resource_set_as(x.asn),
+ ipv4=rpki.resource_set.resource_set_ipv4(x.ipv4),
+ ipv6=rpki.resource_set.resource_set_ipv6(x.ipv6),
+ uri=x.uri,
+ not_after=x.notAfter,
+ not_before=x.notBefore))
+ return resources
+
+x = query_rpkid()
+for y in x:
+ conf = models.Conf.objects.filter(handle=y.self_handle)[0]
+
+ parent_set = conf.parents.filter(handle=y.parent_handle)
+ if not parent_set:
+ print 'have not yet seen parent %s, creating...' % (y.parent_handle, )
+ # have not seen this parent before
+ parent = models.Parent(conf=conf, handle=y.parent_handle)
+ parent.save()
+ else:
+ parent = parent_set[0]
+
+ # have we seen this resource cert before?
+ cert_set = conf.resources.filter(uri=y.uri)
+ if cert_set.count() == 0:
+ # no
+ cert = models.ResourceCert(uri=uri, parent=parent, not_before=x.not_before,
+ not_after=x.not_after)
+ else:
+ # yes
+ cert = cert_set[0]
+
+ for asn in y.asn:
+ # see if this resource is already part of the cert
+ if cert.asn.get(lo=asn.min, hi=asn.max) is None:
+ # ensure that this range wasn't previously seen from another of our parents
+ for v in models.Asn.objects.filter(lo=asn.min, hi=asn.max):
+ # determine if this resource is delegated from another parent as well
+ if v.from_cert.filter(parent__in=conf.parents.all()).count():
+ cert.asn.add(v)
+ break
+ else:
+ print 'could not find ASN %s in known set' % ( 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.get(lo=lo, hi=hi) is None:
+ # 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:
+ print 'could not find address range %s in known set' % ( ip, )
+ cert.address_range.create(lo=lo, hi=hi)
+ cert.save()
+
+ add_missing_address(y.ipv4)
+ add_missing_address(y.ipv6)
+
+# vim:sw=4 expandtab ts=4
diff --git a/portal-gui/scripts/roa_check.py b/portal-gui/scripts/roa_check.py
new file mode 100755
index 00000000..fd3adc36
--- /dev/null
+++ b/portal-gui/scripts/roa_check.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+#
+# Runs through all the published ROAs and updates the Django DB with the
+# current active status of each defined ROA.
+#
+
+import socket
+
+from rcynic_output_iterator import rcynic_xml_iterator, rcynic_roa
+from rpki.resource_set import resource_set_ipv4, resource_set_ipv6
+from rpki.resource_set import roa_prefix_set_ipv4, roa_prefix_set_ipv6
+from rpki.resource_set import resource_range_ipv4, resource_range_ipv6
+from rpki.ipaddrs import v4addr, v6addr
+
+from rpkigui.myrpki.models import Roa
+
+# build up a list of all the authenticated roa's using the asn as the key
+roaiter = rcynic_xml_iterator(
+ rcynic_root='/home/melkins/rcynic/rcynic-data/',
+ xml_file='/home/melkins/rcynic/rcynic.xml')
+
+# key is an ASN
+# each element is a tuple of (resource_set_ipv4, resource_set_ipv6)
+roaauth = {}
+
+for roa in roaiter:
+ if isinstance(roa, rcynic_roa):
+ k = roa.asID
+ if not roaauth.has_key(k):
+ v = [resource_set_ipv4(), resource_set_ipv6()]
+ roaauth[k] = v
+ else:
+ v = roaauth[k]
+ for pfx in roa.prefix_sets:
+ if isinstance(pfx, roa_prefix_set_ipv4):
+ v[0] = v[0].union(pfx.to_resource_set())
+ elif isinstance(pfx, roa_prefix_set_ipv6):
+ v[1] = v[1].union(pfx.to_resource_set())
+
+#for k, v in roaauth.iteritems():
+# print 'asn %d : prefixes %s' % (k, ' '.join(map(str,v)))
+
+# run through all the ROA's in the GUI's database
+for roa in Roa.objects.all():
+ k = int(roa.asn)
+ valid = False
+ if roaauth.has_key(k):
+ # ensure that all prefixes listed in the roa are present
+ # we convert the list of prefixes into prefix sets and use the
+ # resource_set class to perform set comparisons
+ ipv4_set = resource_set_ipv4()
+ ipv6_set = resource_set_ipv6()
+ for pfx in roa.prefix.all():
+ # IP addresses are just stored as strings in the sqlite db
+ try:
+ ipv4_set.append(resource_range_ipv4(v4addr(str(pfx.lo)), v4addr(str(pfx.hi))))
+ except socket.error:
+ ipv6_set.append(resource_range_ipv6(v6addr(str(pfx.lo)), v6addr(str(pfx.hi))))
+ r = roaauth[k]
+ if ipv4_set.issubset(r[0]) and ipv6_set.issubset(r[1]):
+ valid = True
+ if valid:
+ if not roa.active:
+ roa.active = True
+ roa.save()
+ else:
+ print 'roa for asn %s is not valid' % (roa.asn, )
+ if roa.active:
+ roa.active = False
+ roa.save()