monkeysphere: Add Let's Encrypt certificates

Filter letsencrypt domains from snakeoil list.
Rename views for snakeoil and letsencrypt.
This commit is contained in:
James Valleroy 2016-02-18 18:05:48 -05:00 committed by Sunil Mohan Adapa
parent cc6f44d87e
commit 5c810ed87f
No known key found for this signature in database
GPG Key ID: 36C361440C9BC971
4 changed files with 140 additions and 21 deletions

View File

@ -41,9 +41,14 @@ def parse_arguments():
host_import_ssh_key.add_argument(
'domain', help='Fully-qualified domain name')
host_import_https_key = subparsers.add_parser(
'host-import-https-key', help='Import host HTTPS key')
host_import_https_key.add_argument(
host_import_snakeoil_key = subparsers.add_parser(
'host-import-snakeoil-key', help='Import host snakeoil key')
host_import_snakeoil_key.add_argument(
'domain', help='Fully-qualified domain name')
host_import_letsencrypt_key = subparsers.add_parser(
'host-import-letsencrypt-key', help="Import Let's Encrypt key")
host_import_letsencrypt_key.add_argument(
'domain', help='Fully-qualified domain name')
host_publish_key = subparsers.add_parser(
@ -96,13 +101,41 @@ def subcommand_host_import_ssh_key(arguments):
print(output.decode())
def subcommand_host_import_https_key(arguments):
"""Import host HTTPS key."""
output = subprocess.check_output(
def subcommand_host_import_snakeoil_key(arguments):
"""Import host snakeoil key."""
proc = subprocess.Popen(
['monkeysphere-host', 'import-key',
'/etc/ssl/private/ssl-cert-snakeoil.key',
'https://' + arguments.domain])
print(output.decode())
'https://' + arguments.domain],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=dict(
os.environ,
MONKEYSPHERE_PROMPT='false'))
output, error = proc.communicate()
output, error = output.decode(), error.decode()
if proc.returncode != 0:
raise Exception(output, error)
print(output)
def subcommand_host_import_letsencrypt_key(arguments):
"""Import Let's Encrypt key."""
proc = subprocess.Popen(
['monkeysphere-host', 'import-key',
os.path.join('/etc/letsencrypt/live',
arguments.domain, 'privkey.pem'),
'https://' + arguments.domain],
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
env=dict(
os.environ,
MONKEYSPHERE_PROMPT='false'))
output, error = proc.communicate()
output, error = output.decode(), error.decode()
if proc.returncode != 0:
raise Exception(output, error)
print(output)
def subcommand_host_publish_key(arguments):

View File

@ -127,7 +127,7 @@
</tr>
</thead>
<tbody>
{% for domain in status.https_domains %}
{% for domain in status.snakeoil_domains %}
<tr>
<td>{{ domain.name }}</td>
<td>
@ -143,7 +143,59 @@
<td>
{% if not domain.key %}
<form class="form" method="post"
action="{% url 'monkeysphere:generate_https' domain.name %}">
action="{% url 'monkeysphere:generate_snakeoil' domain.name %}">
{% csrf_token %}
<button type="submit" class="btn btn-primary btn-sm pull-right">
{% trans "Generate OpenPGP Key" %}</button>
</form>
{% elif not running %}
<form class="form" method="post"
action="{% url 'monkeysphere:publish' domain.key.pgp_fingerprint %}">
{% csrf_token %}
<button type="submit" class="btn btn-warning btn-sm pull-right">
{% trans "Publish Key" %}</button>
</form>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<h4>{% trans "Let's Encrypt Certificates" %}</h4>
<div class="row">
<div class="col-sm-8">
<table class="table table-bordered table-condensed table-striped">
<thead>
<tr>
<th>{% trans "Domain" %}</th>
<th>{% trans "OpenPGP Fingerprint" %}</th>
<th>{% trans "Actions" %}</th>
</tr>
</thead>
<tbody>
{% for domain in status.letsencrypt_domains %}
<tr>
<td>{{ domain.name }}</td>
<td>
{% if domain.key %}
<a href="{% url 'monkeysphere:details' domain.key.pgp_fingerprint %}"
title="Show details for key {{ domain.key.pgp_fingerprint }}">
{{ domain.key.pgp_fingerprint }}
</a>
{% else %}
{% trans "Not Available" %}
{% endif %}
</td>
<td>
{% if not domain.key %}
<form class="form" method="post"
action="{% url 'monkeysphere:generate_letsencrypt' domain.name %}">
{% csrf_token %}
<button type="submit" class="btn btn-primary btn-sm pull-right">

View File

@ -28,8 +28,10 @@ urlpatterns = [
url(r'^sys/monkeysphere/$', views.index, name='index'),
url(r'^sys/monkeysphere/(?P<domain>[^/]+)/generate/$',
views.generate, name='generate'),
url(r'^sys/monkeysphere/(?P<domain>[^/]+)/generate_https/$',
views.generate_https, name='generate_https'),
url(r'^sys/monkeysphere/(?P<domain>[^/]+)/generate_snakeoil/$',
views.generate_snakeoil, name='generate_snakeoil'),
url(r'^sys/monkeysphere/(?P<domain>[^/]+)/generate_letsencrypt/$',
views.generate_letsencrypt, name='generate_letsencrypt'),
url(r'^sys/monkeysphere/(?P<fingerprint>[0-9A-Fa-f]+)/details/$',
views.details, name='details'),
url(r'^sys/monkeysphere/(?P<fingerprint>[0-9A-Fa-f]+)/publish/$',

View File

@ -63,14 +63,30 @@ def generate(request, domain):
@require_POST
def generate_https(request, domain):
"""Generate OpenPGP key for HTTPS service."""
def generate_snakeoil(request, domain):
"""Generate OpenPGP key for snakeoil certificate."""
valid_domain = any((domain in domains
for domains in names.domains.values()))
if valid_domain:
try:
actions.superuser_run(
'monkeysphere', ['host-import-https-key', domain])
'monkeysphere', ['host-import-snakeoil-key', domain])
messages.success(request, _('Generated OpenPGP key.'))
except actions.ActionError as exception:
messages.error(request, str(exception))
return redirect(reverse_lazy('monkeysphere:index'))
@require_POST
def generate_letsencrypt(request, domain):
"""Generate OpenPGP key for Let's Encrypt certificate."""
valid_domain = any((domain in domains
for domains in names.domains.values()))
if valid_domain:
try:
actions.superuser_run(
'monkeysphere', ['host-import-letsencrypt-key', domain])
messages.success(request, _('Generated OpenPGP key.'))
except actions.ActionError as exception:
messages.error(request, str(exception))
@ -129,15 +145,31 @@ def get_status():
'key': keys.get(domain),
})
https_domains = []
# XXX: Currently, there's no way to tell if keys in monkeysphere are for
# snakeoil or letsencrypt certs. If snakeoil cert is imported for a domain,
# then later that domain is activated for letsencrypt, the snakeoil cert
# will be shown in the letsencrypt table.
output = actions.superuser_run('letsencrypt', ['get-status'])
letsencrypt_domains_all = json.loads(output)['domains']
letsencrypt_domains = []
snakeoil_domains = []
for domains_of_a_type in names.domains.values():
for domain in domains_of_a_type:
https_domains.append({
'name': domain,
'key': https_keys.get(domain),
})
if domain in letsencrypt_domains_all and \
letsencrypt_domains_all[domain]['certificate_available']:
letsencrypt_domains.append({
'name': domain,
'key': https_keys.get(domain),
})
else:
snakeoil_domains.append({
'name': domain,
'key': https_keys.get(domain),
})
return {'domains': domains, 'https_domains': https_domains}
return {'domains': domains,
'snakeoil_domains': snakeoil_domains,
'letsencrypt_domains': letsencrypt_domains}
def get_key(fingerprint):