// Package modules provides fucntionality to install and sign Linux kernel modules.
package modules

import (
	"bytes"
	"encoding/binary"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	log "github.com/golang/glog"
	"github.com/pkg/errors"

	"cos.googlesource.com/cos/tools.git/src/pkg/utils"
)

const (
	// PKEYIDPKCS7 is a constant defined in https://github.com/torvalds/linux/blob/master/scripts/sign-file.c
	PKEYIDPKCS7 = byte(2)
	// magicNumber is a constant defined in https://github.com/torvalds/linux/blob/master/scripts/sign-file.c
	magicNumber = "~Module signature appended~\n"
)

var (
	execCommand = exec.Command
)

// LoadModule loads a given kernel module to kernel.
func LoadModule(moduleName, modulePath string) error {
	loaded, err := isModuleLoaded(moduleName)
	if err != nil {
		return errors.Wrapf(err, "failed to load module %s (%s)", moduleName, modulePath)
	}
	if loaded {
		return nil
	}
	if err := loadModule(modulePath); err != nil {
		return errors.Wrapf(err, "failed to load module %s (%s)", moduleName, modulePath)
	}
	return nil
}

// UpdateHostLdCache updates the ld cache on host.
func UpdateHostLdCache(hostRootDir, moduleLibDir string) error {
	log.Info("Updating host's ld cache")
	ldPath := filepath.Join(hostRootDir, "/etc/ld.so.conf")
	f, err := os.OpenFile(ldPath, os.O_APPEND|os.O_WRONLY, 0644)
	if err != nil {
		return errors.Wrapf(err, "failed to open %s", ldPath)
	}
	defer f.Close()

	if _, err := f.WriteString(moduleLibDir + "\n"); err != nil {
		return errors.Wrapf(err, `failed to write "%s" to %s`, moduleLibDir, ldPath)
	}

	if err := execCommand("ldconfig", "-r", hostRootDir).Run(); err != nil {
		return errors.Wrapf(err, "failed to run `ldconfig -r %s`", hostRootDir)
	}

	return nil
}

// LoadPublicKey loads the given public key to the secondary keyring.
func LoadPublicKey(keyName, keyPath string) error {
	log.Infof("Loading %s to secondary system keyring", keyName)

	keyBytes, err := ioutil.ReadFile(keyPath)
	if err != nil {
		return errors.Wrapf(err, "failed to read key %s", keyPath)
	}

	cmd := execCommand("/bin/keyctl", "padd", "asymmetric", keyName, "%keyring:.secondary_trusted_keys")
	cmd.Stdin = bytes.NewBuffer(keyBytes)
	if err := cmd.Run(); err != nil {
		return errors.Wrapf(err, "failed to load %s to system keyring", keyName)
	}
	log.Infof("Successfully load key %s into secondary system keyring.", keyName)
	return nil
}

// AppendSignature appends a raw PKCS#7 signature to the end of a given kernel module.
// This is basically the Go implementation of `scripts/sign-file -s` in Linux upstream.
func AppendSignature(outfilePath, modulefilePath, sigfilePath string) error {
	tempFile, err := ioutil.TempFile("", "tempFile")
	if err != nil {
		return errors.Wrap(err, "failed to create temp file")
	}
	defer os.Remove(tempFile.Name())
	defer tempFile.Close()

	// Copy bytes of kernel module into the temp file.
	modulefile, err := os.Open(modulefilePath)
	if err != nil {
		return errors.Wrapf(err, "failed to open file %s", modulefilePath)
	}
	defer modulefile.Close()

	_, err = io.Copy(tempFile, modulefile)
	if err != nil {
		return errors.Wrap(err, "failed to copy file")
	}

	// Append bytes of module signature into the temp file.
	sigfile, err := os.Open(sigfilePath)
	if err != nil {
		return errors.Wrapf(err, "failed to open file %s", sigfilePath)
	}
	defer sigfile.Close()

	sigSize, err := io.Copy(tempFile, sigfile)
	if err != nil {
		return errors.Wrap(err, "failed to copy file")
	}

	// Append the marker and the PKCS#7 message.
	// moduleSignature is the struct module_signature defined in
	// https://github.com/torvalds/linux/blob/master/scripts/sign-file.c
	moduleSignature := [12]byte{}
	// moduleSignature[2] is the id_type of struct module_signature
	moduleSignature[2] = PKEYIDPKCS7
	// moduleSignature[8:12] is the sig_len of struct module_signature.
	// Using BigEndian as the sig_len should be in network byte order.
	binary.BigEndian.PutUint32(moduleSignature[8:12], uint32(sigSize))
	_, err = tempFile.Write(moduleSignature[:])
	if err != nil {
		return errors.Wrapf(err, "failed to write to file %s", tempFile.Name())
	}

	_, err = tempFile.Write([]byte(magicNumber))
	if err != nil {
		return errors.Wrapf(err, "failed to write to file %s", tempFile.Name())
	}

	if err := tempFile.Close(); err != nil {
		return errors.Wrapf(err, "failed to close file %s", tempFile.Name())
	}

	// Finally, move the outfile to specified location.
	// It overwrites the original module file if we are appending in place.
	if err := utils.MoveFile(tempFile.Name(), outfilePath); err != nil {
		return errors.Wrapf(err, "failed to rename file from %s to %s", tempFile.Name(), outfilePath)
	}

	return nil
}

func isModuleLoaded(moduleName string) (bool, error) {
	out, err := execCommand("lsmod").Output()
	if err != nil {
		return false, errors.Wrap(err, "failed to run command `lsmod`")
	}

	for _, line := range strings.Split(string(out), "\n") {
		fields := strings.Fields(line)
		if len(fields) > 0 && fields[0] == moduleName {
			return true, nil
		}
	}
	return false, nil
}

func loadModule(modulePath string) error {
	if err := execCommand("insmod", modulePath).Run(); err != nil {
		return errors.Wrapf(err, "failed to run command `insmod %s`", modulePath)
	}
	return nil
}
