#!/bin/bash # based on gentoo-infra: infra/githooks.git:update-02-gpg # --- Command line refname=${1} oldrev=${2} newrev=${3} # --- Safety check if [ -z "${GIT_DIR}" ]; then echo "Don't run this script from the command line." >&2 echo " (if you want, you could supply GIT_DIR then run" >&2 echo " ${0} )" >&2 exit 1 fi if [ -z "${refname}" -o -z "${oldrev}" -o -z "${newrev}" ]; then echo "usage: ${0} " >&2 exit 1 fi # branch names or 'all', or 'all-refs' for all refs SIGNED_BRANCHES=$(git config --get gpg.signed-branches) : ${SIGNED_BRANCHES:=master} VERIFY_SIGS=$(git config --get gpg.verify-signatures) : ${VERIFY_SIGS:=users} case ${VERIFY_SIGS} in users) ;; no) ;; *) echo "Invalid value of gpg.verify-signatures" >&2 exit 1 esac case ${SIGNED_BRANCHES} in all-refs) ;; all) [[ ${refname} == refs/heads/* ]] || exit 0 ;; *) [[ ${refname} == refs/heads/* ]] || exit 0 branch_found= for branch in ${SIGNED_BRANCHES}; do if [[ ${refname#refs/heads/} == ${branch} ]]; then branch_found=1 break fi done [[ ${branch_found} == 1 ]] || exit 0 esac IFS=' ' # special cases zeros=0000000000000000000000000000000000000000 # branch removal [[ ${newrev} == "${zeros}" ]] && exit 0 # new branch; try to find a merge base with master if [[ ${oldrev} == "${zeros}" && ${refname} != refs/heads/master ]]; then mergebase=$(git merge-base refs/heads/master "${newrev}") [[ -n ${mergebase} ]] && oldrev=${mergebase} fi rev_list_arg="${oldrev}..${newrev}" # new and no common commit? gotta check them all [[ ${oldrev} == "${zeros}" ]] && rev_list_arg="${newrev}" while read -r r; do committer=$(git show -q --pretty=format:'%ce' "${r}") signst=$(git show -q --pretty=format:'%G?' "${r}") case ${VERIFY_SIGS} in users) # user signatures must be Good [[ ${signst} == G ]] && continue ;; no) # additionally skip untrusted/impossible to check # when verification is disabled [[ ${signst} == [GUE] ]] && continue ;; esac # error reporting case ${signst} in U) echo "*** Untrusted signature on ${r}, refusing" exit 1 ;; B) echo "*** Bad signature on ${r}, refusing" exit 1 ;; N) echo "*** No signature on ${r}, refusing" exit 1 ;; E) echo "*** Signature cannot be checked on ${r}, refusing" exit 1 ;; *) echo "*** Unknown signature status '${signst}', refusing" exit 1 ;; esac done < <(git rev-list --first-parent "${rev_list_arg}") # --- Finished exit 0