]> git.saurik.com Git - apt.git/blob - test/integration/test-releasefile-verification
support Signed-By in Release files as a sort of HPKP
[apt.git] / test / integration / test-releasefile-verification
1 #!/bin/sh
2 set -e
3
4 TESTDIR="$(readlink -f "$(dirname "$0")")"
5 . "$TESTDIR/framework"
6
7 setupenvironment
8 configarchitecture "i386"
9
10 buildaptarchive
11 setupflataptarchive
12 changetowebserver
13
14 webserverconfig 'aptwebserver::support::range' 'false'
15
16 prepare() {
17 local DATE="${2:-now}"
18 if [ "$DATE" = 'now' ]; then
19 if [ "$1" = "${PKGFILE}-new" ]; then
20 DATE='now - 1 day'
21 else
22 DATE='now - 7 day'
23 fi
24 fi
25 for release in $(find rootdir/var/lib/apt/lists 2> /dev/null); do
26 touch -d 'now - 1 year' "$release"
27 done
28 aptget clean
29 cp "$1" aptarchive/Packages
30 find aptarchive -name 'Release' -delete
31 compressfile 'aptarchive/Packages' "$DATE"
32 generatereleasefiles "$DATE" 'now + 1 month'
33 }
34
35 installaptold() {
36 rm -rf rootdir/var/cache/apt/archives
37 testsuccessequal "Reading package lists...
38 Building dependency tree...
39 Suggested packages:
40 aptitude | synaptic | wajig dpkg-dev apt-doc bzip2 lzma python-apt
41 The following NEW packages will be installed:
42 apt
43 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
44 After this operation, 5370 kB of additional disk space will be used.
45 Get:1 http://localhost:${APTHTTPPORT} apt 0.7.25.3
46 Download complete and in download only mode" aptget install apt -dy
47 }
48
49 installaptnew() {
50 rm -rf rootdir/var/cache/apt/archives
51 testsuccessequal "Reading package lists...
52 Building dependency tree...
53 Suggested packages:
54 aptitude | synaptic | wajig dpkg-dev apt-doc bzip2 lzma python-apt
55 The following NEW packages will be installed:
56 apt
57 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
58 After this operation, 5808 kB of additional disk space will be used.
59 Get:1 http://localhost:${APTHTTPPORT} apt 0.8.0~pre1
60 Download complete and in download only mode" aptget install apt -dy
61 }
62
63 failaptold() {
64 testfailureequal 'Reading package lists...
65 Building dependency tree...
66 Suggested packages:
67 aptitude | synaptic | wajig dpkg-dev apt-doc bzip2 lzma python-apt
68 The following NEW packages will be installed:
69 apt
70 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
71 After this operation, 5370 kB of additional disk space will be used.
72 WARNING: The following packages cannot be authenticated!
73 apt
74 E: There were unauthenticated packages and -y was used without --allow-unauthenticated' aptget install apt -dy
75 }
76
77 failaptnew() {
78 testfailureequal 'Reading package lists...
79 Building dependency tree...
80 Suggested packages:
81 aptitude | synaptic | wajig dpkg-dev apt-doc bzip2 lzma python-apt
82 The following NEW packages will be installed:
83 apt
84 0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
85 After this operation, 5808 kB of additional disk space will be used.
86 WARNING: The following packages cannot be authenticated!
87 apt
88 E: There were unauthenticated packages and -y was used without --allow-unauthenticated' aptget install apt -dy
89 }
90
91 # fake our downloadable file
92 touch aptarchive/apt.deb
93
94 PKGFILE="${TESTDIR}/$(echo "$(basename "$0")" | sed 's#^test-#Packages-#')"
95
96 updatewithwarnings() {
97 testwarning aptget update -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1
98 testsuccess grep -E "$1" rootdir/tmp/testwarning.output
99 }
100
101 runtest() {
102 local DELETEFILE="$1"
103 msgmsg 'Cold archive signed by' 'Joe Sixpack'
104 prepare "${PKGFILE}"
105 rm -rf rootdir/var/lib/apt/lists
106 signreleasefiles 'Joe Sixpack'
107 find aptarchive/ -name "$DELETEFILE" -delete
108 successfulaptgetupdate
109 testsuccessequal "$(cat "${PKGFILE}")
110 " aptcache show apt
111 installaptold
112
113 msgmsg 'Good warm archive signed by' 'Joe Sixpack'
114 prepare "${PKGFILE}-new"
115 signreleasefiles 'Joe Sixpack'
116 find aptarchive/ -name "$DELETEFILE" -delete
117 successfulaptgetupdate
118 testsuccessequal "$(cat "${PKGFILE}-new")
119 " aptcache show apt
120 installaptnew
121
122 msgmsg 'Cold archive signed by' 'Rex Expired'
123 prepare "${PKGFILE}"
124 rm -rf rootdir/var/lib/apt/lists
125 cp keys/rexexpired.pub rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg
126 signreleasefiles 'Rex Expired'
127 find aptarchive/ -name "$DELETEFILE" -delete
128 updatewithwarnings '^W: .* EXPKEYSIG'
129 testsuccessequal "$(cat "${PKGFILE}")
130 " aptcache show apt
131 failaptold
132 rm -f rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg
133
134 msgmsg 'Cold archive expired signed by' 'Joe Sixpack'
135 if dpkg --compare-versions "$(aptkey adv --version | head -n 2 | tail -n 1 | cut -d' ' -f 3)" '>=' '2.1' >/dev/null 2>&1; then
136 touch rootdir/etc/apt/apt.conf.d/99gnupg2
137 elif gpg2 --version >/dev/null 2>&1; then
138 echo 'Apt::Key::gpgcommand "gpg2";' > rootdir/etc/apt/apt.conf.d/99gnupg2
139 if ! dpkg --compare-versions "$(aptkey adv --version | head -n 2 | tail -n 1 | cut -d' ' -f 3)" '>=' '2.1' >/dev/null 2>&1; then
140 rm rootdir/etc/apt/apt.conf.d/99gnupg2
141 fi
142 fi
143 if [ -e rootdir/etc/apt/apt.conf.d/99gnupg2 ]; then
144 prepare "${PKGFILE}"
145 rm -rf rootdir/var/lib/apt/lists
146 signreleasefiles 'Joe Sixpack' 'aptarchive' --faked-system-time "20070924T154812" --default-sig-expire 2016-04-01
147 find aptarchive/ -name "$DELETEFILE" -delete
148 updatewithwarnings '^W: .* EXPSIG'
149 testsuccessequal "$(cat "${PKGFILE}")
150 " aptcache show apt
151 failaptold
152 rm -f rootdir/etc/apt/apt.conf.d/99gnupg2
153 else
154 msgskip 'Not a new enough gpg available providing --fake-system-time'
155 fi
156
157 msgmsg 'Cold archive signed by' 'Joe Sixpack,Marvin Paranoid'
158 prepare "${PKGFILE}"
159 rm -rf rootdir/var/lib/apt/lists
160 signreleasefiles 'Joe Sixpack,Marvin Paranoid'
161 find aptarchive/ -name "$DELETEFILE" -delete
162 successfulaptgetupdate 'NO_PUBKEY'
163 testsuccessequal "$(cat "${PKGFILE}")
164 " aptcache show apt
165 installaptold
166
167 msgmsg 'Cold archive signed by' 'Joe Sixpack,Rex Expired'
168 prepare "${PKGFILE}"
169 rm -rf rootdir/var/lib/apt/lists
170 signreleasefiles 'Joe Sixpack,Rex Expired'
171 find aptarchive/ -name "$DELETEFILE" -delete
172 cp keys/rexexpired.pub rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg
173 successfulaptgetupdate 'EXPKEYSIG'
174 rm -f rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg
175 testsuccessequal "$(cat "${PKGFILE}")
176 " aptcache show apt
177 installaptold
178
179 msgmsg 'Cold archive signed by' 'Marvin Paranoid'
180 prepare "${PKGFILE}"
181 rm -rf rootdir/var/lib/apt/lists
182 signreleasefiles 'Marvin Paranoid'
183 find aptarchive/ -name "$DELETEFILE" -delete
184 updatewithwarnings '^W: .* NO_PUBKEY'
185 testsuccessequal "$(cat "${PKGFILE}")
186 " aptcache show apt
187 failaptold
188
189 msgmsg 'Bad warm archive signed by' 'Joe Sixpack'
190 prepare "${PKGFILE}-new"
191 signreleasefiles 'Joe Sixpack'
192 find aptarchive/ -name "$DELETEFILE" -delete
193 successfulaptgetupdate
194 testsuccessequal "$(cat "${PKGFILE}-new")
195 " aptcache show apt
196 installaptnew
197
198 msgmsg 'Cold archive signed by' 'Joe Sixpack'
199 prepare "${PKGFILE}"
200 rm -rf rootdir/var/lib/apt/lists
201 signreleasefiles 'Joe Sixpack'
202 find aptarchive/ -name "$DELETEFILE" -delete
203 successfulaptgetupdate
204 testsuccessequal "$(cat "${PKGFILE}")
205 " aptcache show apt
206 installaptold
207
208 msgmsg 'Good warm archive signed by' 'Marvin Paranoid'
209 prepare "${PKGFILE}-new"
210 signreleasefiles 'Marvin Paranoid'
211 find aptarchive/ -name "$DELETEFILE" -delete
212 updatewithwarnings '^W: .* NO_PUBKEY'
213 testsuccessequal "$(cat "${PKGFILE}")
214 " aptcache show apt
215 installaptold
216
217 msgmsg 'Good warm archive signed by' 'Rex Expired'
218 prepare "${PKGFILE}-new"
219 cp keys/rexexpired.pub rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg
220 signreleasefiles 'Rex Expired'
221 find aptarchive/ -name "$DELETEFILE" -delete
222 updatewithwarnings '^W: .* EXPKEYSIG'
223 testsuccessequal "$(cat "${PKGFILE}")
224 " aptcache show apt
225 installaptold
226 rm rootdir/etc/apt/trusted.gpg.d/rexexpired.gpg
227
228 msgmsg 'Good warm archive signed by' 'Joe Sixpack'
229 prepare "${PKGFILE}-new"
230 signreleasefiles
231 find aptarchive/ -name "$DELETEFILE" -delete
232 successfulaptgetupdate
233 testsuccessequal "$(cat "${PKGFILE}-new")
234 " aptcache show apt
235 installaptnew
236
237 msgmsg 'Cold archive signed by good keyring' 'Marvin Paranoid'
238 prepare "${PKGFILE}"
239 rm -rf rootdir/var/lib/apt/lists
240 signreleasefiles 'Marvin Paranoid'
241 find aptarchive/ -name "$DELETEFILE" -delete
242 local MARVIN="$(readlink -f keys/marvinparanoid.pub)"
243 sed -i "s#^\(deb\(-src\)\?\) #\1 [signed-by=$MARVIN] #" rootdir/etc/apt/sources.list.d/*
244 successfulaptgetupdate
245 testsuccessequal "$(cat "${PKGFILE}")
246 " aptcache show apt
247 installaptold
248
249 msgmsg 'Cold archive signed by bad keyring' 'Joe Sixpack'
250 rm -rf rootdir/var/lib/apt/lists
251 signreleasefiles 'Joe Sixpack'
252 find aptarchive/ -name "$DELETEFILE" -delete
253 updatewithwarnings '^W: .* NO_PUBKEY'
254 sed -i "s#^\(deb\(-src\)\?\) \[signed-by=$MARVIN\] #\1 #" rootdir/etc/apt/sources.list.d/*
255
256 local MARVIN="$(aptkey --keyring $MARVIN finger | grep 'Key fingerprint' | cut -d'=' -f 2 | tr -d ' ')"
257 msgmsg 'Cold archive signed by bad keyid' 'Joe Sixpack'
258 rm -rf rootdir/var/lib/apt/lists
259 signreleasefiles 'Joe Sixpack'
260 find aptarchive/ -name "$DELETEFILE" -delete
261 sed -i "s#^\(deb\(-src\)\?\) #\1 [signed-by=$MARVIN] #" rootdir/etc/apt/sources.list.d/*
262 updatewithwarnings '^W: .* be verified because the public key is not available: .*'
263
264 msgmsg 'Cold archive signed by good keyid' 'Marvin Paranoid'
265 rm -rf rootdir/var/lib/apt/lists
266 signreleasefiles 'Marvin Paranoid'
267 find aptarchive/ -name "$DELETEFILE" -delete
268 cp keys/marvinparanoid.pub rootdir/etc/apt/trusted.gpg.d/marvinparanoid.gpg
269 successfulaptgetupdate
270 testsuccessequal "$(cat "${PKGFILE}")
271 " aptcache show apt
272 installaptold
273
274 msgmsg 'Cold archive signed by good keyid' 'Marvin Paranoid,Joe Sixpack'
275 rm -rf rootdir/var/lib/apt/lists
276 signreleasefiles 'Marvin Paranoid,Joe Sixpack'
277 find aptarchive/ -name "$DELETEFILE" -delete
278 successfulaptgetupdate 'NoPubKey: GOODSIG'
279 testsuccessequal "$(cat "${PKGFILE}")
280 " aptcache show apt
281 installaptold
282
283 local SIXPACK="$(aptkey --keyring keys/joesixpack.pub finger | grep 'Key fingerprint' | cut -d'=' -f 2 | tr -d ' ')"
284 msgmsg 'Cold archive signed by good keyids' 'Joe Sixpack'
285 rm -rf rootdir/var/lib/apt/lists
286 signreleasefiles 'Joe Sixpack'
287 find aptarchive/ -name "$DELETEFILE" -delete
288 sed -i "s#^\(deb\(-src\)\?\) \[signed-by=$MARVIN\] #\1 [signed-by=${SIXPACK},${MARVIN}] #" rootdir/etc/apt/sources.list.d/*
289 successfulaptgetupdate
290 testsuccessequal "$(cat "${PKGFILE}")
291 " aptcache show apt
292 installaptold
293
294 local SIXPACK="$(aptkey --keyring keys/joesixpack.pub finger | grep 'Key fingerprint' | cut -d'=' -f 2 | tr -d ' ')"
295 msgmsg 'Cold archive signed by good keyids' 'Joe Sixpack'
296 rm -rf rootdir/var/lib/apt/lists
297 sed -i "s#^\(deb\(-src\)\?\) \[signed-by=${SIXPACK},${MARVIN}\] #\1 [signed-by=${MARVIN},${SIXPACK}] #" rootdir/etc/apt/sources.list.d/*
298 successfulaptgetupdate
299 testsuccessequal "$(cat "${PKGFILE}")
300 " aptcache show apt
301 installaptold
302 rm -f rootdir/etc/apt/trusted.gpg.d/marvinparanoid.gpg
303 sed -i "s#^\(deb\(-src\)\?\) \[signed-by=${MARVIN},${SIXPACK}\] #\1 #" rootdir/etc/apt/sources.list.d/*
304
305 rm -rf rootdir/var/lib/apt/lists-bak
306 cp -a rootdir/var/lib/apt/lists rootdir/var/lib/apt/lists-bak
307 prepare "${PKGFILE}-new"
308 signreleasefiles 'Joe Sixpack'
309 find aptarchive/ -name "$DELETEFILE" -delete
310
311 msgmsg 'Warm archive with signed-by' 'Joe Sixpack'
312 sed -i "/^Valid-Until: / a\
313 Signed-By: ${SIXPACK}" rootdir/var/lib/apt/lists/*Release
314 touch -d 'now - 1 year' rootdir/var/lib/apt/lists/*Release
315 successfulaptgetupdate
316 testsuccessequal "$(cat "${PKGFILE}-new")
317 " aptcache show apt
318 installaptnew
319
320 msgmsg 'Warm archive with signed-by' 'Marvin Paranoid'
321 rm -rf rootdir/var/lib/apt/lists
322 cp -a rootdir/var/lib/apt/lists-bak rootdir/var/lib/apt/lists
323 sed -i "/^Valid-Until: / a\
324 Signed-By: ${MARVIN}" rootdir/var/lib/apt/lists/*Release
325 touch -d 'now - 1 year' rootdir/var/lib/apt/lists/*Release
326 updatewithwarnings 'W: .* public key is not available: GOODSIG'
327 testsuccessequal "$(cat "${PKGFILE}")
328 " aptcache show apt
329 installaptold
330
331 msgmsg 'Warm archive with outdated signed-by' 'Marvin Paranoid'
332 rm -rf rootdir/var/lib/apt/lists
333 cp -a rootdir/var/lib/apt/lists-bak rootdir/var/lib/apt/lists
334 sed -i "/^Valid-Until: / a\
335 Valid-Until: $(date -u -d "now - 2min" '+%a, %d %b %Y %H:%M:%S %Z') \\
336 Signed-By: ${MARVIN}" rootdir/var/lib/apt/lists/*Release
337 touch -d 'now - 1 year' rootdir/var/lib/apt/lists/*Release
338 successfulaptgetupdate
339 testsuccessequal "$(cat "${PKGFILE}-new")
340 " aptcache show apt
341 installaptnew
342
343 msgmsg 'Warm archive with two signed-bys' 'Joe Sixpack'
344 rm -rf rootdir/var/lib/apt/lists
345 cp -a rootdir/var/lib/apt/lists-bak rootdir/var/lib/apt/lists
346 sed -i "/^Valid-Until: / a\
347 Signed-By: ${MARVIN} ${MARVIN}, \\
348 ${SIXPACK}" rootdir/var/lib/apt/lists/*Release
349 touch -d 'now - 1 year' rootdir/var/lib/apt/lists/*Release
350 successfulaptgetupdate
351 testsuccessequal "$(cat "${PKGFILE}-new")
352 " aptcache show apt
353 installaptnew
354 }
355
356 runtest2() {
357 msgmsg 'Cold archive signed by' 'Joe Sixpack'
358 prepare "${PKGFILE}"
359 rm -rf rootdir/var/lib/apt/lists
360 signreleasefiles 'Joe Sixpack'
361 successfulaptgetupdate
362
363 # New .deb but now an unsigned archive. For example MITM to circumvent
364 # package verification.
365 msgmsg 'Warm archive signed by' 'nobody'
366 prepare "${PKGFILE}-new"
367 find aptarchive/ -name InRelease -delete
368 find aptarchive/ -name Release.gpg -delete
369 updatewithwarnings 'W: .* no longer signed.'
370 testsuccessequal "$(cat "${PKGFILE}-new")
371 " aptcache show apt
372 failaptnew
373
374 # Unsigned archive from the beginning must also be detected.
375 msgmsg 'Cold archive signed by' 'nobody'
376 rm -rf rootdir/var/lib/apt/lists
377 updatewithwarnings 'W: .* is not signed.'
378 testsuccessequal "$(cat "${PKGFILE}-new")
379 " aptcache show apt
380 failaptnew
381 }
382
383 runtest3() {
384 echo "APT::Hashes::$APT_TESTS_DIGEST_ALGO::$1 \"yes\";" > rootdir/etc/apt/apt.conf.d/truststate
385 msgmsg "Running base test with $1 digest"
386 runtest2
387
388 for DELETEFILE in 'InRelease' 'Release.gpg'; do
389 msgmsg "Running test with deletion of $DELETEFILE and $1 digest"
390 runtest "$DELETEFILE"
391 done
392 }
393
394 # diable some protection by default and ensure we still do the verification
395 # correctly
396 cat > rootdir/etc/apt/apt.conf.d/weaken-security <<EOF
397 Acquire::AllowInsecureRepositories "1";
398 Acquire::AllowDowngradeToInsecureRepositories "1";
399 EOF
400 # the hash marked as configureable in our gpgv method
401 export APT_TESTS_DIGEST_ALGO='SHA224'
402
403 successfulaptgetupdate() {
404 testsuccess aptget update -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1
405 if [ -n "$1" ]; then
406 cp rootdir/tmp/testsuccess.output aptupdate.output
407 testsuccess grep "$1" aptupdate.output
408 fi
409 }
410 runtest3 'Trusted'
411
412 successfulaptgetupdate() {
413 testwarning aptget update -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1
414 if [ -n "$1" ]; then
415 testsuccess grep "$1" rootdir/tmp/testwarning.output
416 fi
417 testsuccess grep 'uses weak digest algorithm' rootdir/tmp/testwarning.output
418 }
419 runtest3 'Weak'
420
421 msgmsg "Running test with apt-untrusted digest"
422 echo "APT::Hashes::$APT_TESTS_DIGEST_ALGO::Untrusted \"yes\";" > rootdir/etc/apt/apt.conf.d/truststate
423 runfailure() {
424 for DELETEFILE in 'InRelease' 'Release.gpg'; do
425 msgmsg 'Cold archive signed by' 'Joe Sixpack'
426 prepare "${PKGFILE}"
427 rm -rf rootdir/var/lib/apt/lists
428 signreleasefiles 'Joe Sixpack'
429 find aptarchive/ -name "$DELETEFILE" -delete
430 testfailure aptget update --no-allow-insecure-repositories -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1
431 testsuccess grep 'The following signatures were invalid' rootdir/tmp/testfailure.output
432 testnopackage 'apt'
433 testwarning aptget update --allow-insecure-repositories -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1
434 failaptold
435
436 msgmsg 'Cold archive signed by' 'Marvin Paranoid'
437 prepare "${PKGFILE}"
438 rm -rf rootdir/var/lib/apt/lists
439 signreleasefiles 'Marvin Paranoid'
440 find aptarchive/ -name "$DELETEFILE" -delete
441 testfailure aptget update --no-allow-insecure-repositories -o Debug::pkgAcquire::Worker=1 -o Debug::Acquire::gpgv=1
442 testnopackage 'apt'
443 updatewithwarnings '^W: .* NO_PUBKEY'
444 testsuccessequal "$(cat "${PKGFILE}")
445 " aptcache show apt
446 failaptold
447 done
448 }
449 runfailure
450
451 msgmsg "Running test with gpgv-untrusted digest"
452 export APT_TESTS_DIGEST_ALGO='MD5'
453 runfailure