diff --git a/plinth/modules/ssh/__init__.py b/plinth/modules/ssh/__init__.py index 7d3911cbd..2169ab7a2 100644 --- a/plinth/modules/ssh/__init__.py +++ b/plinth/modules/ssh/__init__.py @@ -18,6 +18,10 @@ FreedomBox app for OpenSSH server. """ +import pathlib +import re +import subprocess + from django.utils.translation import ugettext_lazy as _ from plinth import actions @@ -25,9 +29,8 @@ from plinth import app as app_module from plinth import menu from plinth.daemon import Daemon from plinth.modules.firewall.components import Firewall -from plinth.views import AppView -from .manifest import backup # noqa, pylint: disable=unused-import +from .manifest import backup # noqa, pylint: disable=unused-import version = 1 @@ -84,8 +87,21 @@ def setup(helper, old_version=None): actions.superuser_run('ssh', ['setup']) -class SshAppView(AppView): - app_id = 'ssh' - name = name - description = description - port_forwarding_info = port_forwarding_info +def get_host_keys(): + """Return Host keys of the system.""" + etc_ssh = pathlib.Path('/etc/ssh/') + host_keys = [] + pattern = re.compile(r'^(?P\d+) (?P[\S]+) ' + r'.+ \((?P\w+)\)$') + + for public_key in etc_ssh.glob('*.pub'): + process = subprocess.run(['ssh-keygen', '-l', '-f', + str(public_key)], stdout=subprocess.PIPE, + check=True) + output = process.stdout.decode().strip() + if output: + match = re.match(pattern, output) + if match: + host_keys.append(match.groupdict()) + + return host_keys diff --git a/plinth/modules/ssh/templates/ssh.html b/plinth/modules/ssh/templates/ssh.html new file mode 100644 index 000000000..e9589476c --- /dev/null +++ b/plinth/modules/ssh/templates/ssh.html @@ -0,0 +1,51 @@ +{% extends "app.html" %} +{% comment %} +# +# This file is part of FreedomBox. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +{% endcomment %} +{% load bootstrap %} +{% load i18n %} + +{% block status %} + {{ block.super }} + +

{% trans "Server Fingerprints" %}

+ +

+ {% blocktrans trimmed %} + When connecting to the server, ensure that the fingerprint shown by the + SSH client matches one of these fingerprints. + {% endblocktrans %} +

+ + + + + + + + + + {% for host_key in host_keys %} + + + + + {% endfor %} + +
{% trans "Algorithm" %}{% trans "Fingerprint" %}
{{ host_key.algorithm }}{{ host_key.fingerprint }}
+{% endblock %} diff --git a/plinth/modules/ssh/urls.py b/plinth/modules/ssh/urls.py index e8b1264d3..66d4701c9 100644 --- a/plinth/modules/ssh/urls.py +++ b/plinth/modules/ssh/urls.py @@ -20,7 +20,7 @@ URLs for the Secure Shell Server module. from django.conf.urls import url -from plinth.modules.ssh import SshAppView +from plinth.modules.ssh.views import SshAppView urlpatterns = [ url(r'^sys/ssh/$', SshAppView.as_view(), name='index'), diff --git a/plinth/modules/ssh/views.py b/plinth/modules/ssh/views.py new file mode 100644 index 000000000..83ce5b5f0 --- /dev/null +++ b/plinth/modules/ssh/views.py @@ -0,0 +1,36 @@ +# +# This file is part of FreedomBox. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +""" +Views for the SSH module +""" + +from plinth.modules import ssh +from plinth.views import AppView + + +class SshAppView(AppView): + app_id = 'ssh' + name = ssh.name + description = ssh.description + port_forwarding_info = ssh.port_forwarding_info + template_name = 'ssh.html' + + def get_context_data(self, *args, **kwargs): + context = super().get_context_data(**kwargs) + context['host_keys'] = ssh.get_host_keys() + + return context