Current File : //proc/self/root/kunden/proc/thread-self/root/usr/libexec/pesign/pesign-rpmbuild-helper
#!/usr/bin/bash
# shellcheck shell=bash

set -eu
set -x

usage() {
    local status="${1}" && shift
    local out
    if [[ "${status}" -eq 0 ]] ; then
	out=/dev/stdout
    else
	out=/dev/stderr
    fi

    if [[ $# -gt 0 ]] ; then
	echo "${0}: error: $*" >>"${out}"
    fi
    echo "usage: ${0} TARGET_CPU PESIGN_BINARY PESIGN_CLIENT_BINARY [OPTIONS]" >>"${out}"
    exit "${status}"
}

is_efi_arch() {
    local arch="${1}"
    local arches=(aa64 ia32 x64)
    local x
    for x in "${arches[@]}" ; do
	if [[ "${arch}" = "${x}" ]] ; then
	    return 0
	fi
    done
    return 1
}

error_on_empty() {
    local f="${1}"
    if [[ ! -s "${f}" ]] ; then
	if [[ -e "${f}" ]] ; then
	    rm -f "${f}"
	fi
	echo "${0}: error: empty result file \"${f}\"">>/dev/stderr
	exit 1
    fi
}

main() {
    if [[ $# -lt 3 ]] ; then
	usage 1 not enough arguments
    fi
    local target_cpu="${1}" && shift
    local bin="${1}" && shift
    local client="${1}" && shift

    local rhelcafile="" || :
    local rhelcertfile="" || :

    local certout=() || :
    local sattrout=() || :
    local input=() || :
    local output=() || :
    local client_token=() || :
    local client_cert=() || :
    local token=() || :
    local cert=() || :
    local rhelcert=() || :
    local rhelver=0 || :
    local sign="" || :
    local arch="" || :
    local vendor="" || :
    local HOSTNAME="" || :

    while [[ $# -ge 2 ]] ; do
	case " ${1} " in
	" --rhelcafile ")
	    rhelcafile="${2}"
	    ;;
	" --rhelcertfile ")
	    rhelcertfile="${2}"
	    ;;
	" --hostname ")
	    HOSTNAME="${2}"
	    ;;
	" --certout ")
	    certout[0]=-C
	    certout[1]="${2}"
	    ;;
	" --sattrout ")
	    sattrout[0]=-e
	    sattrout[1]="${2}"
	    ;;
	" --client-token ")
	    client_token[0]=-t
	    client_token[1]="${2}"
	    ;;
	" --client-cert ")
	    client_cert[0]=-c
	    client_cert[1]="${2}"
	    ;;
	" --token ")
	    token[0]=-t
	    token[1]="${2}"
	    ;;
	" --cert ")
	    cert[0]=-c
	    cert[1]="${2}"
	    ;;
	" --rhelcert ")
	    rhelcert[0]=-c
	    rhelcert[1]="${2}"
	    ;;
	" --in ")
	    input[0]=-i
	    input[1]="${2}"
	    ;;
	" --out ")
	    output[0]=-o
	    output[1]="${2}"
	    ;;
	" --rhelver ")
	    rhelver="${2}"
	    ;;
	" --vendor ")
	    vendor="${2}"
	    ;;
	*)
	    break
	    ;;
	esac
	shift
	shift
    done
    if [[ $# -ge 1 ]] && [[ "${1}" = --sign ]] ; then
	sign=-s
	shift
    fi
    if [[ $# -ge 1 ]] ; then
	echo "$# extra unparsed arguments!">>/dev/stderr
	echo "Cowardly refusing to run">>/dev/stderr
	exit 1
    fi

    if [[ -z "${target_cpu}" ]] ; then
	target_cpu="$(uname -m)"
    fi

    target_cpu="${target_cpu/i?86/ia32}"
    target_cpu="${target_cpu/x86_64/x64}"
    target_cpu="${target_cpu/aarch64/aa64}"
    target_cpu="${target_cpu/arm*/arm/}"

    local nssdir=/etc/pki/pesign
    if [[ "${#cert[@]}" -eq 2 ]] &&
       [[ "${cert[1]}" == "Red Hat Test Certificate" ]] ; then
	nssdir=/etc/pki/pesign-rh-test
    fi

    # is_efi_arch is ultimately returning "is pesign configured to sign these
    # using the rpm macro", so if it isn't, we're just copying the input to
    # the output
    if [[ -x "${bin}" ]] && ! is_efi_arch "${target_cpu}" ; then
	if [[ -n "${input[*]}" ]] && [[ -n "${output[*]}" ]] ; then
	    cp -v "${input[1]}" "${output[1]}"
	elif [[ -n "${input[*]}" ]] && [[ -n "${sattrout[*]}" ]] ; then
	    touch "${sattrout[1]}"
	fi

	# if there's a 0-sized output file, delete it and error out
	error_on_empty "${output[1]}"
	return 0
    fi

    USERNAME="${USERNAME:-$(id -un)}"

    local socket="" || :
    if grep -q ID=fedora /etc/os-release \
       && [[ "${rhelver}" -lt 7 ]] \
       && [[ "${USERNAME}" = "mockbuild" ]] \
       && [[ "${vendor}" = "Fedora Project" ]] \
       && [[ "${HOSTNAME}" =~ bkernel.* ]]
    then
	if [[ -S /run/pesign/socket ]] ; then
	    socket=/run/pesign/socket
	elif [[ -S /var/run/pesign/socket ]]; then
	    socket=/var/run/pesign/socket
	else
	    echo "Warning: no pesign socket even though user is ${USERNAME}" 1>&2
	    echo "Warning: if this is a non-scratch koji build, this is wrong" 1>&2
	    ls -ld /run/pesign /var/run/pesign 1>&2 ||:
	    ls -l /run/pesign/socket /var/run/pesign/socket 1>&2 ||:
	    getfacl /run/pesign /run/pesign/socket /var/run/pesign /var/run/pesign/socket 1>&2 ||:
	    getfacl -n /run/pesign /run/pesign/socket /var/run/pesign /var/run/pesign/socket 1>&2 ||:
	fi
    fi

    if [[ "${rhelver}" -ge 7 ]] && which rpm-sign >&/dev/null ; then
	nssdir="$(mktemp -p "${PWD}" -d)"
	echo > "${nssdir}/pwfile"
	certutil -N -d "${nssdir}" -f "${nssdir}/pwfile"
	certutil -A -n "ca" -t "CTu,CTu,CTu" -i "${rhelcafile}" -d "${nssdir}"
	certutil -A -n "signer" -t "CTu,CTu,CTu" -i "${rhelcertfile}" -d "${nssdir}"
	sattrs="$(mktemp -p "${PWD}" --suffix=.der)"
	"${bin}" -E "${sattrs}" --certdir "${nssdir}" \
	    "${input[@]}" --force
	rpm-sign --key "${rhelcert[1]}" --rsadgstsign "${sattrs}"
	"${bin}" -R "${sattrs}.sig" -I "${sattrs}" \
	    --certdir "${nssdir}" -c signer \
	    "${input[@]}" "${output[@]}"
	rm -rf "${sattrs}" "${sattrs}.sig" "${nssdir}"
    elif [[ -n "${socket}" ]] ; then
	### welcome haaaaack city
	if [[ "${client_token[1]}" = "OpenSC Card (Fedora Signer)" ]] ; then
	    if [[ "${input[1]}" =~ (/|^)vmlinuz($|[_.-]) ]] \
	       || [[ "${input[1]}" =~ (/|^)bzImage($|[_.-]) ]] ; then
		if [[ "${rhelcertfile}" =~ redhatsecureboot501.* ]] \
		   || [[ "${rhelcertfile}" =~ redhatsecureboot401.* ]] \
		   || [[ "${rhelcertfile}" =~ centossecureboot201.* ]] ; then
		    client_cert[1]=kernel-signer
		elif [[ "${rhelcertfile}" =~ redhatsecureboot502.* ]] \
		   || [[ "${rhelcertfile}" =~ centossecureboot202.* ]] ; then
		    client_cert[1]=grub2-signer
		elif [[ "${rhelcertfile}" =~ redhatsecureboot503.* ]] \
		   || [[ "${rhelcertfile}" =~ centossecureboot203.* ]] ; then
		    client_cert[1]=fwupd-signer
		fi
	    fi
	fi
	"${client}" "${client_token[@]}" "${client_cert[@]}"    \
	    "${sattrout[@]}" "${certout[@]}"	\
	    ${sign} "${input[@]}" "${output[@]}"
    else
	"${bin}" --certdir "${nssdir}" "${token[@]}"	\
	    "${cert[@]}" ${sign} "${sattrout[@]}"	\
	    "${certout[@]}"    "${input[@]}" "${output[@]}"
    fi

    # if there's a 0-sized output file, delete it and error out
    if [[ "${#output[@]}" -eq 2 ]] ; then
	error_on_empty "${output[1]}"
    fi
}

main "${@}"

# vim:filetype=sh:fenc=utf-8:tw=78:sts=4:sw=4