]>
Commit | Line | Data |
---|---|---|
a85b377d JH |
1 | #!/bin/sh |
2 | ||
3 | test_description='signed push' | |
4 | ||
5 | . ./test-lib.sh | |
6 | . "$TEST_DIRECTORY"/lib-gpg.sh | |
7 | ||
8 | prepare_dst () { | |
9 | rm -fr dst && | |
10 | test_create_repo dst && | |
11 | ||
12 | git push dst master:noop master:ff master:noff | |
13 | } | |
14 | ||
15 | test_expect_success setup ' | |
16 | # master, ff and noff branches pointing at the same commit | |
17 | test_tick && | |
18 | git commit --allow-empty -m initial && | |
19 | ||
20 | git checkout -b noop && | |
21 | git checkout -b ff && | |
22 | git checkout -b noff && | |
23 | ||
24 | # noop stays the same, ff advances, noff rewrites | |
25 | test_tick && | |
26 | git commit --allow-empty --amend -m rewritten && | |
27 | git checkout ff && | |
28 | ||
29 | test_tick && | |
30 | git commit --allow-empty -m second | |
31 | ' | |
32 | ||
33 | test_expect_success 'unsigned push does not send push certificate' ' | |
34 | prepare_dst && | |
35 | mkdir -p dst/.git/hooks && | |
36 | write_script dst/.git/hooks/post-receive <<-\EOF && | |
37 | # discard the update list | |
38 | cat >/dev/null | |
39 | # record the push certificate | |
40 | if test -n "${GIT_PUSH_CERT-}" | |
41 | then | |
42 | git cat-file blob $GIT_PUSH_CERT >../push-cert | |
43 | fi | |
44 | EOF | |
45 | ||
46 | git push dst noop ff +noff && | |
47 | ! test -f dst/push-cert | |
48 | ' | |
49 | ||
50 | test_expect_success 'talking with a receiver without push certificate support' ' | |
51 | prepare_dst && | |
52 | mkdir -p dst/.git/hooks && | |
a85b377d JH |
53 | write_script dst/.git/hooks/post-receive <<-\EOF && |
54 | # discard the update list | |
55 | cat >/dev/null | |
56 | # record the push certificate | |
57 | if test -n "${GIT_PUSH_CERT-}" | |
58 | then | |
59 | git cat-file blob $GIT_PUSH_CERT >../push-cert | |
60 | fi | |
61 | EOF | |
62 | ||
63 | git push dst noop ff +noff && | |
64 | ! test -f dst/push-cert | |
65 | ' | |
66 | ||
67 | test_expect_success 'push --signed fails with a receiver without push certificate support' ' | |
68 | prepare_dst && | |
69 | mkdir -p dst/.git/hooks && | |
a85b377d JH |
70 | test_must_fail git push --signed dst noop ff +noff 2>err && |
71 | test_i18ngrep "the receiving end does not support" err | |
72 | ' | |
73 | ||
46667418 | 74 | test_expect_success 'push --signed=1 is accepted' ' |
c4b71a77 MÅ |
75 | prepare_dst && |
76 | mkdir -p dst/.git/hooks && | |
77 | test_must_fail git push --signed=1 dst noop ff +noff 2>err && | |
78 | test_i18ngrep "the receiving end does not support" err | |
79 | ' | |
80 | ||
20a7558f JH |
81 | test_expect_success GPG 'no certificate for a signed push with no update' ' |
82 | prepare_dst && | |
83 | mkdir -p dst/.git/hooks && | |
84 | write_script dst/.git/hooks/post-receive <<-\EOF && | |
85 | if test -n "${GIT_PUSH_CERT-}" | |
86 | then | |
87 | git cat-file blob $GIT_PUSH_CERT >../push-cert | |
88 | fi | |
89 | EOF | |
90 | git push dst noop && | |
91 | ! test -f dst/push-cert | |
92 | ' | |
93 | ||
a85b377d JH |
94 | test_expect_success GPG 'signed push sends push certificate' ' |
95 | prepare_dst && | |
96 | mkdir -p dst/.git/hooks && | |
b89363e4 | 97 | git -C dst config receive.certnonceseed sekrit && |
a85b377d JH |
98 | write_script dst/.git/hooks/post-receive <<-\EOF && |
99 | # discard the update list | |
100 | cat >/dev/null | |
101 | # record the push certificate | |
102 | if test -n "${GIT_PUSH_CERT-}" | |
103 | then | |
104 | git cat-file blob $GIT_PUSH_CERT >../push-cert | |
d05b9618 JH |
105 | fi && |
106 | ||
107 | cat >../push-cert-status <<E_O_F | |
108 | SIGNER=${GIT_PUSH_CERT_SIGNER-nobody} | |
109 | KEY=${GIT_PUSH_CERT_KEY-nokey} | |
110 | STATUS=${GIT_PUSH_CERT_STATUS-nostatus} | |
b89363e4 JH |
111 | NONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus} |
112 | NONCE=${GIT_PUSH_CERT_NONCE-nononce} | |
d05b9618 JH |
113 | E_O_F |
114 | ||
115 | EOF | |
116 | ||
a85b377d | 117 | git push --signed dst noop ff +noff && |
b89363e4 JH |
118 | |
119 | ( | |
120 | cat <<-\EOF && | |
121 | SIGNER=C O Mitter <committer@example.com> | |
122 | KEY=13B6F51ECDDE430D | |
123 | STATUS=G | |
124 | NONCE_STATUS=OK | |
125 | EOF | |
126 | sed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" dst/push-cert | |
127 | ) >expect && | |
128 | ||
8722947e JS |
129 | noop=$(git rev-parse noop) && |
130 | ff=$(git rev-parse ff) && | |
131 | noff=$(git rev-parse noff) && | |
132 | grep "$noop $ff refs/heads/ff" dst/push-cert && | |
133 | grep "$noop $noff refs/heads/noff" dst/push-cert && | |
d05b9618 | 134 | test_cmp expect dst/push-cert-status |
a85b377d JH |
135 | ' |
136 | ||
cbaf82cc JT |
137 | test_expect_success GPG 'inconsistent push options in signed push not allowed' ' |
138 | # First, invoke receive-pack with dummy input to obtain its preamble. | |
139 | prepare_dst && | |
140 | git -C dst config receive.certnonceseed sekrit && | |
141 | git -C dst config receive.advertisepushoptions 1 && | |
142 | printf xxxx | test_might_fail git receive-pack dst >preamble && | |
143 | ||
144 | # Then, invoke push. Simulate a receive-pack that sends the preamble we | |
145 | # obtained, followed by a dummy packet. | |
146 | write_script myscript <<-\EOF && | |
147 | cat preamble && | |
148 | printf xxxx && | |
149 | cat >push | |
150 | EOF | |
151 | test_might_fail git push --push-option="foo" --push-option="bar" \ | |
152 | --receive-pack="\"$(pwd)/myscript\"" --signed dst --delete ff && | |
153 | ||
154 | # Replay the push output on a fresh dst, checking that ff is truly | |
155 | # deleted. | |
156 | prepare_dst && | |
157 | git -C dst config receive.certnonceseed sekrit && | |
158 | git -C dst config receive.advertisepushoptions 1 && | |
159 | git receive-pack dst <push && | |
160 | test_must_fail git -C dst rev-parse ff && | |
161 | ||
162 | # Tweak the push output to make the push option outside the cert | |
163 | # different, then replay it on a fresh dst, checking that ff is not | |
164 | # deleted. | |
165 | perl -pe "s/([^ ])bar/\$1baz/" push >push.tweak && | |
166 | prepare_dst && | |
167 | git -C dst config receive.certnonceseed sekrit && | |
168 | git -C dst config receive.advertisepushoptions 1 && | |
169 | git receive-pack dst <push.tweak >out && | |
170 | git -C dst rev-parse ff && | |
171 | grep "inconsistent push options" out | |
172 | ' | |
173 | ||
b9459019 MG |
174 | test_expect_success GPG 'fail without key and heed user.signingkey' ' |
175 | prepare_dst && | |
176 | mkdir -p dst/.git/hooks && | |
177 | git -C dst config receive.certnonceseed sekrit && | |
178 | write_script dst/.git/hooks/post-receive <<-\EOF && | |
179 | # discard the update list | |
180 | cat >/dev/null | |
181 | # record the push certificate | |
182 | if test -n "${GIT_PUSH_CERT-}" | |
183 | then | |
184 | git cat-file blob $GIT_PUSH_CERT >../push-cert | |
185 | fi && | |
186 | ||
187 | cat >../push-cert-status <<E_O_F | |
188 | SIGNER=${GIT_PUSH_CERT_SIGNER-nobody} | |
189 | KEY=${GIT_PUSH_CERT_KEY-nokey} | |
190 | STATUS=${GIT_PUSH_CERT_STATUS-nostatus} | |
191 | NONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus} | |
192 | NONCE=${GIT_PUSH_CERT_NONCE-nononce} | |
193 | E_O_F | |
194 | ||
195 | EOF | |
196 | ||
53fc9993 HS |
197 | test_config user.email hasnokey@nowhere.com && |
198 | ( | |
199 | sane_unset GIT_COMMITTER_EMAIL && | |
200 | test_must_fail git push --signed dst noop ff +noff | |
201 | ) && | |
202 | test_config user.signingkey $GIT_COMMITTER_EMAIL && | |
b9459019 MG |
203 | git push --signed dst noop ff +noff && |
204 | ||
205 | ( | |
206 | cat <<-\EOF && | |
207 | SIGNER=C O Mitter <committer@example.com> | |
208 | KEY=13B6F51ECDDE430D | |
209 | STATUS=G | |
210 | NONCE_STATUS=OK | |
211 | EOF | |
212 | sed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" dst/push-cert | |
213 | ) >expect && | |
214 | ||
8722947e JS |
215 | noop=$(git rev-parse noop) && |
216 | ff=$(git rev-parse ff) && | |
217 | noff=$(git rev-parse noff) && | |
218 | grep "$noop $ff refs/heads/ff" dst/push-cert && | |
219 | grep "$noop $noff refs/heads/noff" dst/push-cert && | |
b9459019 MG |
220 | test_cmp expect dst/push-cert-status |
221 | ' | |
222 | ||
53fc9993 HS |
223 | test_expect_success GPGSM 'fail without key and heed user.signingkey x509' ' |
224 | test_config gpg.format x509 && | |
225 | prepare_dst && | |
226 | mkdir -p dst/.git/hooks && | |
227 | git -C dst config receive.certnonceseed sekrit && | |
228 | write_script dst/.git/hooks/post-receive <<-\EOF && | |
229 | # discard the update list | |
230 | cat >/dev/null | |
231 | # record the push certificate | |
232 | if test -n "${GIT_PUSH_CERT-}" | |
233 | then | |
234 | git cat-file blob $GIT_PUSH_CERT >../push-cert | |
235 | fi && | |
236 | ||
237 | cat >../push-cert-status <<E_O_F | |
238 | SIGNER=${GIT_PUSH_CERT_SIGNER-nobody} | |
239 | KEY=${GIT_PUSH_CERT_KEY-nokey} | |
240 | STATUS=${GIT_PUSH_CERT_STATUS-nostatus} | |
241 | NONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus} | |
242 | NONCE=${GIT_PUSH_CERT_NONCE-nononce} | |
243 | E_O_F | |
244 | ||
245 | EOF | |
246 | ||
247 | test_config user.email hasnokey@nowhere.com && | |
248 | test_config user.signingkey "" && | |
249 | ( | |
250 | sane_unset GIT_COMMITTER_EMAIL && | |
251 | test_must_fail git push --signed dst noop ff +noff | |
252 | ) && | |
253 | test_config user.signingkey $GIT_COMMITTER_EMAIL && | |
254 | git push --signed dst noop ff +noff && | |
255 | ||
256 | ( | |
257 | cat <<-\EOF && | |
258 | SIGNER=/CN=C O Mitter/O=Example/SN=C O/GN=Mitter | |
259 | KEY= | |
260 | STATUS=G | |
261 | NONCE_STATUS=OK | |
262 | EOF | |
263 | sed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" dst/push-cert | |
264 | ) >expect.in && | |
265 | key=$(cat "${GNUPGHOME}/trustlist.txt" | cut -d" " -f1 | tr -d ":") && | |
266 | sed -e "s/^KEY=/KEY=${key}/" expect.in >expect && | |
267 | ||
268 | noop=$(git rev-parse noop) && | |
269 | ff=$(git rev-parse ff) && | |
270 | noff=$(git rev-parse noff) && | |
271 | grep "$noop $ff refs/heads/ff" dst/push-cert && | |
272 | grep "$noop $noff refs/heads/noff" dst/push-cert && | |
273 | test_cmp expect dst/push-cert-status | |
274 | ' | |
275 | ||
a85b377d | 276 | test_done |