#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#

"""Helper module for GPG signing"""

import bb
import os
import shlex
import subprocess
import tempfile

class LocalSigner(object):
    """Class for handling local (on the build host) signing"""
    def __init__(self, d):
        self.gpg_bin = d.getVar('GPG_BIN') or \
                  bb.utils.which(os.getenv('PATH'), 'gpg')
        self.gpg_cmd = [self.gpg_bin]
        self.gpg_agent_bin = bb.utils.which(os.getenv('PATH'), "gpg-agent")
        # Without this we see "Cannot allocate memory" errors when running processes in parallel
        # It needs to be set for any gpg command since any agent launched can stick around in memory
        # and this parameter must be set.
        if self.gpg_agent_bin:
            self.gpg_cmd += ["--agent-program=%s|--auto-expand-secmem" % (self.gpg_agent_bin)]
        self.gpg_path = d.getVar('GPG_PATH')
        self.rpm_bin = bb.utils.which(os.getenv('PATH'), "rpmsign")
        self.gpg_version = self.get_gpg_version()


    def export_pubkey(self, output_file, keyid, armor=True):
        """Export GPG public key to a file"""
        cmd = self.gpg_cmd + ["--no-permission-warning", "--batch", "--yes", "--export", "-o", output_file]
        if self.gpg_path:
            cmd += ["--homedir", self.gpg_path]
        if armor:
            cmd += ["--armor"]
        cmd += [keyid]
        subprocess.check_output(cmd, stderr=subprocess.STDOUT)

    def sign_rpms(self, files, keyid, passphrase, digest, sign_chunk, fsk=None, fsk_password=None):
        """Sign RPM files"""

        cmd = self.rpm_bin + " --addsign --define '_gpg_name %s'  " % keyid
        gpg_args = '--no-permission-warning --batch --passphrase=%s --agent-program=%s|--auto-expand-secmem' % (passphrase, self.gpg_agent_bin)
        if self.gpg_version > (2,1,):
            gpg_args += ' --pinentry-mode=loopback'
        cmd += "--define '_gpg_sign_cmd_extra_args %s' " % gpg_args
        cmd += "--define '_binary_filedigest_algorithm %s' " % digest
        if self.gpg_bin:
            cmd += "--define '__gpg %s' " % self.gpg_bin
        if self.gpg_path:
            cmd += "--define '_gpg_path %s' " % self.gpg_path
        if fsk:
            cmd += "--signfiles --fskpath %s " % fsk
            if fsk_password:
                cmd += "--define '_file_signing_key_password %s' " % fsk_password

        # Sign in chunks
        for i in range(0, len(files), sign_chunk):
            subprocess.check_output(shlex.split(cmd + ' '.join(files[i:i+sign_chunk])), stderr=subprocess.STDOUT)

    def detach_sign(self, input_file, keyid, passphrase_file, passphrase=None, armor=True, output_suffix=None, use_sha256=False):
        """Create a detached signature of a file"""

        if passphrase_file and passphrase:
            raise Exception("You should use either passphrase_file of passphrase, not both")

        cmd = self.gpg_cmd + ['--detach-sign', '--no-permission-warning', '--batch',
               '--no-tty', '--yes', '--passphrase-fd', '0', '-u', keyid]

        if self.gpg_path:
            cmd += ['--homedir', self.gpg_path]
        if armor:
            cmd += ['--armor']
        if use_sha256:
            cmd += ['--digest-algo', "SHA256"]

        #gpg > 2.1 supports password pipes only through the loopback interface
        #gpg < 2.1 errors out if given unknown parameters
        if self.gpg_version > (2,1,):
            cmd += ['--pinentry-mode', 'loopback']

        try:
            if passphrase_file:
                with open(passphrase_file) as fobj:
                    passphrase = fobj.readline();

            if not output_suffix:
                output_suffix = 'asc' if armor else 'sig'
            output_file = input_file + "." + output_suffix
            with tempfile.TemporaryDirectory(dir=os.path.dirname(output_file)) as tmp_dir:
                tmp_file = os.path.join(tmp_dir, os.path.basename(output_file))
                cmd += ['-o', tmp_file]

                cmd += [input_file]

                job = subprocess.Popen(cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
                (_, stderr) = job.communicate(passphrase.encode("utf-8"))

                if job.returncode:
                    bb.fatal("GPG exited with code %d: %s" % (job.returncode, stderr.decode("utf-8")))

                os.rename(tmp_file, output_file)
        except IOError as e:
            bb.error("IO error (%s): %s" % (e.errno, e.strerror))
            raise Exception("Failed to sign '%s'" % input_file)

        except OSError as e:
            bb.error("OS error (%s): %s" % (e.errno, e.strerror))
            raise Exception("Failed to sign '%s" % input_file)


    def get_gpg_version(self):
        """Return the gpg version as a tuple of ints"""
        try:
            cmd = self.gpg_cmd + ["--version", "--no-permission-warning"]
            ver_str = subprocess.check_output(cmd).split()[2].decode("utf-8")
            return tuple([int(i) for i in ver_str.split("-")[0].split('.')])
        except subprocess.CalledProcessError as e:
            bb.fatal("Could not get gpg version: %s" % e)


    def verify(self, sig_file, valid_sigs = ''):
        """Verify signature"""
        cmd = self.gpg_cmd + ["--verify", "--no-permission-warning", "--status-fd", "1"]
        if self.gpg_path:
            cmd += ["--homedir", self.gpg_path]

        cmd += [sig_file]
        status = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        # Valid if any key matches if unspecified
        if not valid_sigs:
            ret = False if status.returncode else True
            return ret

        import re
        goodsigs = []
        sigre = re.compile(r'^\[GNUPG:\] GOODSIG (\S+)\s(.*)$')
        for l in status.stdout.decode("utf-8").splitlines():
            s = sigre.match(l)
            if s:
                goodsigs += [s.group(1)]

        for sig in valid_sigs.split():
            if sig in goodsigs:
                return True
        if len(goodsigs):
            bb.warn('No accepted signatures found. Good signatures found: %s.' % ' '.join(goodsigs))
        return False


def get_signer(d, backend):
    """Get signer object for the specified backend"""
    # Use local signing by default
    if backend == 'local':
        return LocalSigner(d)
    else:
        bb.fatal("Unsupported signing backend '%s'" % backend)
