summaryrefslogtreecommitdiffstats
path: root/VREF/gpg
blob: 07e1664915016c925b85eb00c6b475ee75027ceb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#!/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} <ref> <oldrev> <newrev>)" >&2
	exit 1
fi

if [ -z "${refname}" -o -z "${oldrev}" -o -z "${newrev}" ]; then
	echo "usage: ${0} <ref> <oldrev> <newrev>" >&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