diff options
6 files changed, 95 insertions, 64 deletions
diff --git a/rpkid/portal-gui/scripts/rpkigui-rcynic.py b/rpkid/portal-gui/scripts/rpkigui-rcynic.py index dc74b2ec..5be68039 100644 --- a/rpkid/portal-gui/scripts/rpkigui-rcynic.py +++ b/rpkid/portal-gui/scripts/rpkigui-rcynic.py @@ -58,6 +58,10 @@ def process_object(obj, model_class): inst.mtime = mtime inst.not_before = obj.notBefore.to_sql() inst.not_after = obj.notAfter.to_sql() + if debug: + sys.stderr.write('name=%s ski=%s\n' % (obj.subject, obj.ski)) + inst.name = obj.subject + inst.keyid = obj.ski # look up signing cert if obj.issuer == obj.subject: @@ -87,8 +91,6 @@ def process_rescert(cert): refresh, obj = process_object(cert, models.Cert) if refresh: - obj.name = cert.subject - obj.keyid = cert.ski obj.save() # resources can change when a cert is updated diff --git a/rpkid/rpki/gui/cacheview/models.py b/rpkid/rpki/gui/cacheview/models.py index afdd2c74..d68601fc 100644 --- a/rpkid/rpki/gui/cacheview/models.py +++ b/rpkid/rpki/gui/cacheview/models.py @@ -107,6 +107,12 @@ class SignedObject(models.Model): mtime = models.PositiveIntegerField(default=0) + # SubjectName + name = models.CharField(max_length=255) + + # value from the SKI extension + keyid = models.CharField(max_length=50, db_index=True) + # validity period from EE cert which signed object not_before = models.DateTimeField() not_after = models.DateTimeField() @@ -120,16 +126,13 @@ class SignedObject(models.Model): """ return datetime.utcfromtimestamp(self.mtime + time.timezone) + def __unicode__(self): + return u'%s' % self.name + class Cert(SignedObject): """ Object representing a resource certificate. """ - # SubjectName - name = models.CharField(max_length=255) - - # value from the SKI extension - keyid = models.CharField(max_length=50, db_index=True) - addresses = models.ManyToManyField(AddressRange, related_name='certs') asns = models.ManyToManyField(ASRange, related_name='certs') issuer = models.ForeignKey('Cert', related_name='children', null=True, blank=True) @@ -138,9 +141,6 @@ class Cert(SignedObject): def get_absolute_url(self): return ('rpki.gui.cacheview.views.cert_detail', [str(self.pk)]) - def __unicode__(self): - return u'%s' % self.name - class ROAPrefix(models.Model): family = models.PositiveIntegerField() prefix = models.IPAddressField() diff --git a/rpkid/rpki/gui/cacheview/templates/cacheview/cacheview_base.html b/rpkid/rpki/gui/cacheview/templates/cacheview/cacheview_base.html index 65f8da07..9831e0cb 100644 --- a/rpkid/rpki/gui/cacheview/templates/cacheview/cacheview_base.html +++ b/rpkid/rpki/gui/cacheview/templates/cacheview/cacheview_base.html @@ -4,6 +4,7 @@ .good { background-color: #77ff77 } .warn { background-color: yellow } .bad { background-color: #ff5500 } +.section { border-width:thin; border-style:solid; border-color:black; margin-top:1em; padding:1em } {% endblock %} {% block sidebar %} diff --git a/rpkid/rpki/gui/cacheview/templates/cacheview/cert_detail.html b/rpkid/rpki/gui/cacheview/templates/cacheview/cert_detail.html index 46d84d61..a0291d7b 100644 --- a/rpkid/rpki/gui/cacheview/templates/cacheview/cert_detail.html +++ b/rpkid/rpki/gui/cacheview/templates/cacheview/cert_detail.html @@ -6,55 +6,47 @@ Resource Certificate Detail {% block detail %} -<p> -<table> - <tr><td>Subject</td><td>{{ object.name }}</td></tr> - <tr><td>SKI</td><td>{{ object.keyid }}</td></tr> -</table> - <h2>RFC3779 Resources</h2> -<ul> - -<li> - -<h3>AS</h3> -{% if object.asns.all %} -<ul> -{% for asn in object.asns.all %} -<li><a href="{{ asn.get_absolute_url }}">{{ asn }}</a> -{% endfor %} -</ul> -{% else %} -<p>none</p> -{% endif %} - -<li> -<h2>IP Ranges</h2> - -{% if object.addresses.all %} -<ul> -{% for rng in object.addresses.all %} -<li><a href="{{ rng.get_absolute_url }}">{{ rng }}</a> -{% endfor %} -</ul> -{% else %} -<p>none</p> -{% endif %} -</ul><!--resources--> +<table> + <tr><th>AS Ranges</th><th>IP Ranges</th></tr> + <tr> + <td style='text-align:left;vertical-align:top'> + <ul class='compact'> + {% for asn in object.asns.all %} + <li><a href="{{ asn.get_absolute_url }}">{{ asn }}</a></li> + {% endfor %} + </ul> + </td> + <td style='text-align:left;vertical-align:top'> + <ul class='compact'> + {% for rng in object.addresses.all %} + <li><a href="{{ rng.get_absolute_url }}">{{ rng }}</a></li> + {% endfor %} + </ul> + </td> + </tr> +</table> +<div class='section'> <h2>Issued Objects</h2> <ul> <li> <h3>Ghostbusters</h3> -{% if object.ghostbusters.all %} -<ul> + +<table> + <tr><th>Name</th><th>Valid</th><th>Until</th></tr> + {% for g in object.ghostbusters.all %} -<li><a href="{{ g.get_absolute_url }}">{{ g }}</a> + <tr class='{{ g.status.kind_as_str }}'> + <td><a href="{{ g.get_absolute_url }}">{{ g }}</a></td> + <td>{{ g.ok }}</td> + <td>{{ g.not_after }}</td> + </tr> {% endfor %} -</ul> -{% endif %} + +</table> <li> <h3>ROAs</h3> @@ -63,10 +55,10 @@ Resource Certificate Detail <tr><th>Prefix</th><th>AS</th><th>Valid</th><th>Until</th></tr> {% for roa in object.roas.all %} {% for pfx in roa.prefixes.all %} - <tr> + <tr class='{{ roa.status.kind_as_str }}'> <td>{{ pfx }}</td> <td>{{ roa.asid }}</td> - <td class='{{ roa.status.kind_as_str }}'><a href="{{ roa.get_absolute_url }}">{{ roa.ok }}</a></td> + <td><a href="{{ roa.get_absolute_url }}">{{ roa.ok }}</a></td> <td>{{ roa.not_after }}</td> </tr> {% endfor %} @@ -75,15 +67,23 @@ Resource Certificate Detail {% endif %} <li> + <h3>Children</h3> -{% if object.children.all %} -<ul> +<table> + <tr><th>Name</th><th>Valid</th><th>Until</th></tr> + {% for child in object.children.all %} - <li><a href="{{ child.get_absolute_url }}">{{ child.name }}</a> + <tr class='{{ child.status.kind_as_str }}'> + <td><a href="{{ child.get_absolute_url }}">{{ child.name }}</a></td> + <td>{{ child.ok }}</td> + <td>{{ child.not_after }}</td> + </tr> {% endfor %} + +</table> + </ul> -{% endif %} -</ul><!--issued objects--> +</div><!--issued objects--> {% endblock %} diff --git a/rpkid/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html b/rpkid/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html index e18b3cf4..45dff81b 100644 --- a/rpkid/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html +++ b/rpkid/rpki/gui/cacheview/templates/cacheview/signedobject_detail.html @@ -9,15 +9,24 @@ <tr><td>URI</td><td>{{ object.uri }}</td></tr> <tr><td>Last Modified</td><td>{{ object.mtime_as_datetime|date:"DATETIME_FORMAT" }}</td></tr> <tr><td>Timestamp</td><td>{{ object.timestamp }}</td></tr> - <tr><td>Status</td><td class='{{ object.status.kind_as_str }}'>{{ object.status.status }}</td></tr> <tr><td>Valid</td><td>{{ object.ok }}</td></tr> + <tr><td>Status</td><td class='{{ object.status.kind_as_str }}'>{{ object.status.status }}</td></tr> </table> -<h2>X.509 Certificate Info</h2> +<h2>X.509 Certificate Chain</h2> <table> - <tr><td>Validity</td><td>{{ object.not_before }} - {{ object.not_after }}</td></tr> - <tr><td>Issuer</td><td><a href='{{object.issuer.get_absolute_url}}'>{{ object.issuer.name }}</a></td></tr> + <tr><th>Depth</th><th>Name</th><th>Valid</th><th>Until</th></tr> + +{% for cert in chain %} +<tr class='{{ cert.1.status.kind_as_str }}'> + <td>{{ cert.0 }}</td> + <td><a href="{{ cert.1.get_absolute_url }}">{{ cert.1.name }}</a></td> + <td>{{ cert.1.ok }}</td> + <td>{{ cert.1.not_after }}</td> +</tr> +{% endfor %} + </table> {% block detail %}{% endblock %} diff --git a/rpkid/rpki/gui/cacheview/views.py b/rpkid/rpki/gui/cacheview/views.py index 4001fda7..53e06859 100644 --- a/rpkid/rpki/gui/cacheview/views.py +++ b/rpkid/rpki/gui/cacheview/views.py @@ -24,6 +24,25 @@ from rpki.ipaddrs import v4addr, v6addr # Create your views here. +def cert_chain(obj): + """ + returns an iterator covering all certs from the root cert down to the EE. + """ + chain = [] + while obj: + chain.append(obj) + obj = obj.issuer + return zip(range(len(chain)), reversed(chain)) + +def signed_object_detail(request, model_class, pk): + """ + wrapper around object_detail which fetches the x.509 cert chain for signed + objects. + """ + obj = get_object_or_404(model_class, pk=pk) + return list_detail.object_detail(request, queryset=model_class.objects.all(), + object_id=pk, extra_context={ 'chain': cert_chain(obj) }) + def addressrange_detail(request, pk): return list_detail.object_detail(request, models.AddressRange.objects.all(), pk) @@ -31,13 +50,13 @@ def asrange_detail(request, pk): return list_detail.object_detail(request, models.ASRange.objects.all(), pk) def roa_detail(request, pk): - return list_detail.object_detail(request, models.ROA.objects.all(), pk) + return signed_object_detail(request, models.ROA, pk) def cert_detail(request, pk): - return list_detail.object_detail(request, models.Cert.objects.all(), pk) + return signed_object_detail(request, models.Cert, pk) def ghostbuster_detail(request, pk): - return list_detail.object_detail(request, models.Ghostbuster.objects.all(), pk) + return signed_object_detail(request, models.Ghostbuster, pk) def search_view(request): if request.method == 'POST': |