From c2fe725a17c75409639b7dd2194a8ca2a1ae6047 Mon Sep 17 00:00:00 2001 From: Papoteur Date: Sat, 27 Mar 2021 18:51:42 +0100 Subject: Check the signature as a first step after selecting an image to write. Nothing happens if the check is OK. Else a message is displayed about missing signature file or checked not passed, and ask to continue or not. The check is now done in main program instead of backend. --- lib/isodumper.py | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/isodumper.py b/lib/isodumper.py index d91bc3d..f095410 100755 --- a/lib/isodumper.py +++ b/lib/isodumper.py @@ -45,6 +45,8 @@ import re import gettext from subprocess import Popen, PIPE from pydbus import SystemBus +import gnupg +import datetime import logging import threading @@ -274,6 +276,53 @@ class IsoDumper(basedialog.BaseDialog): else: self.backup_is_selected = False + def get_sum(self, source): + self.return_state = False + self.signature_checked = False + logging.debug("Starting getting sum") + # Check if the sum file has a valid signature + gpg = gnupg.GPG() + gpg.encoding = 'utf-8' + # Use Mageia public key + mageia_keyid = "835E41F4EDCA7A90" + self.sum_type = 'sha3' + sig_file = "{}.{}.gpg".format(source, self.sum_type) + self.source_file = "{}.{}".format(source, self.sum_type) + keys_list = gpg.list_keys() + key_present = False + for entry in keys_list: + if (mageia_keyid == entry['keyid']): + if entry['expires'] and (datetime.datetime.now().timestamp() > float(entry['expires'])): + logging.info("Mageia key expired, reloading") + else: + logging.info("Mageia key already present") + key_present = True + break + try: + if not key_present: + gpg.recv_keys('pool.sks-keyservers.net', mageia_keyid) + self.sum_check_searched = True + with open(sig_file, 'rb') as g: + self.signature_found = True + verified = gpg.verify_file(g, close_file=False) + if verified: + self.signature_checked = True + logging.debug("signature checked") + g.close() + else: + g.seek(0) + verified = gpg.verify_file(g, self.source_file) + if verified: + self.signature_checked = True + logging.debug("Detached signature is OK") + else: + self.signature_checked = False + logging.warning("Signature is false") + except Exception as e: + self.signature_found = False + logging.error(str(e)) + logging.info(_("Signature file {} not found\n" + _("or key expired")).format(sig_file)) + def do_format(self): #code, format_type, name = self.ask_format() if self.partition_cb.value() != "": @@ -305,7 +354,7 @@ class IsoDumper(basedialog.BaseDialog): self.logger(message) self.emergency(message) else: - message = _('An error occurred.') + message = _('An error {} occurred.'.format(rc)) self.emergency(message) self.initial_state() @@ -448,7 +497,6 @@ class IsoDumper(basedialog.BaseDialog): if success: # Writing step self.iface.do_write(source, target, b) - self.iface.get_sum(source) progress = self.iface.progress while not self.iface.done: progress = self.iface.progress @@ -851,6 +899,25 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog def ask_image(self): self.img_name = yui.YUI.app().askForExistingFile("", "*.iso *.img", self.ChooseImage) if self.img_name != "": + # Check if the image has a signed checksum + self.get_sum(self.img_name) + if self.signature_found: + if not self.signature_checked: + info = Info(_("Warning"), True, + _("The validation of the GPG signature failed !") + "\n" + _("Do you want to continue?")) + if self.ask_YesOrNo(info): + pass + else: + self.img_name = "" + return + else: + info = Info(_("Warning"), True, + _('No GPG signature has been found or the key is expired. Are you sure you want to use this image?')) + if self.ask_YesOrNo(info): + pass + else: + self.img_name = "" + return self.ima.setLabel(os.path.basename(self.img_name)) self.dialog.recalcLayout() self.start_bt.setEnabled() -- cgit v1.2.1