diff options
author | Michael Elkins <melkins@tislabs.com> | 2011-06-15 00:08:42 +0000 |
---|---|---|
committer | Michael Elkins <melkins@tislabs.com> | 2011-06-15 00:08:42 +0000 |
commit | 906e27de0ffffef9bc5e67c2f79457efcf811061 (patch) | |
tree | 4e83a915c17748638e608cc9eb5fcd59d00fc23a | |
parent | bf80201ccb48de25edb2f064f02cb58ac94b4593 (diff) |
display a table containing the full x.509 cert chain for all signed objects
in cert detail view, display validation status for all issued objects in tables
move name and key id fields to signedobject base class in order to store the SN and SKI of the signing EE certs
svn path=/rpkid/portal-gui/scripts/rpkigui-rcynic.py; revision=3875
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': |