aboutsummaryrefslogtreecommitdiff
blob: dceb6203d96fdbd793409a2ff29b619d37b2544e (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/bin/sh

# --- 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

VERIFY_SIGS=$(git config --get gentoo.verify-signatures)
: ${VERIFY_SIGS:=gentoo-devs}

case ${VERIFY_SIGS} in
	gentoo-devs)
		if [[ ${GL_USER} != *@gentoo.org ]]; then
			echo "*** Pusher address is not @gentoo.org" >&2
			echo "    (it is ${GL_USER})" >&2
			echo "*** Please report this to infra" >&2
			exit 1
		fi

		# find key fingerprints in LDAP
		KEY_FPS=$(ldapsearch "uid=${GL_USER%@gentoo.org}" -D '' -Z -LLL \
			gpgfingerprint -o ldif-wrap=no | \
			sed -n -e '/^gpgfingerprint: /{s/^.*://;s/ //g;p}')
		# verify GLEP63 compliance
		GOOD_KEYS=()
		HAVE_NONCOMPLIANT=no
		for K in ${KEY_FPS}; do
			LC_CTYPE=en_US.UTF-8 \
			glep63-check -S glep63-2 -k "${K}" &&
				GOOD_KEYS+=( "${K}" ) ||
				HAVE_NONCOMPLIANT=yes
		done
		if [[ ${#GOOD_KEYS[@]} -eq 0 ]]; then
			echo "*** None of your keys comply with GLEP 63." >&2
			echo "    Please update the keys into conformance if you wish to continue" >&2
			echo "    using them. If not, please remove unused keys from LDAP." >&2
			exit 1
		elif [[ ${HAVE_NONCOMPLIANT} == yes ]]; then
			echo "*** Warning. One or more OpenPGP keys do not comply with GLEP 63." >&2
			echo "    Please update the keys into conformance if you wish to continue" >&2
			echo "    using them. If not, please remove unused keys from LDAP." >&2
		fi
		# create a dedicated GNUPGHOME
		TMPHOME=$(mktemp -d)
		trap 'rm -rf "${TMPHOME}"' EXIT
		# transfer the keys
		gpg -q --export "${GOOD_KEYS[@]}" | GNUPGHOME=${TMPHOME} gpg -q --import
		# use new GNUGPHOME to restrict to dev's keys
		export GNUPGHOME=${TMPHOME}
		;;
	no)
		;;
	*)
		echo "Invalid value of gentoo.verify-signatures" >&2
		exit 1
esac

# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
zero="0000000000000000000000000000000000000000"

case ${refname} in
	refs/heads/master)

		IFS='
'

		# verify that everything on the left-hand side of commit history is signed
		# (further branches of merges can be unsigned)
		revs=$(git rev-list --first-parent "${newrev}" "^${oldrev}")
		for r in ${revs}; do
			committer=$(git show -q --pretty=format:'%ce' "${r}")
			if [[ ${VERIFY_SIGS} == gentoo-devs && ${committer} != *@gentoo.org ]]; then
				echo "*** Committer address is not @gentoo.org, refusing"
				exit 1
			fi

			signst=$(git show -q --pretty=format:'%G?' "${r}")
			case ${VERIFY_SIGS} in
				gentoo-devs)
					# gentoo dev 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

		;;
	*)
		;;
esac

# --- Finished
exit 0