|
1 | 1 | #!/bin/bash |
2 | 2 |
|
3 | | -urisize=$(curl -s -L --head "$PT_source" | sed -n 's/Content-Length: \([0-9]\+\)/\1/p' | tr -d '\012\015') |
4 | | -filesize=$(stat -c%s "$PT_path" 2>/dev/null) |
| 3 | +# Exit code indicating "a service is unavailable", from |
| 4 | +# /usr/include/sysexits.h. The verify-file function will return this code if |
| 5 | +# prerequisites for verification are unavailable. |
| 6 | +EX_UNAVAILABLE=69 |
5 | 7 |
|
6 | | -# Assume that if the file exists and is the same size, we don't have to |
7 | | -# re-download. |
8 | | -if [[ ! -z "$urisize" && ! -z "$filesize" && "$filesize" -eq "$urisize" ]]; then |
9 | | - exit 0 |
10 | | -else |
11 | | - printf '%s\n' "Downloading: ${PT_source}" >&2 |
12 | | - curl -f -L -o "$PT_path" "$PT_source" |
13 | | -fi |
| 8 | +verify-file() { |
| 9 | + local sig="$1" |
| 10 | + local doc="$2" |
14 | 11 |
|
15 | | -if [[ "$PT_check_download" == "false" ]]; then |
16 | | - exit 0 |
17 | | -fi |
| 12 | + # The GPG binary is required to be present in order to perform file download |
| 13 | + # verification. If it is not present, return EX_UNAVAILABLE. |
| 14 | + if ! command -v gpg >/dev/null; then |
| 15 | + echo "gpg binary not found; required in path for checking download" |
| 16 | + return "$EX_UNAVAILABLE" |
| 17 | + fi |
18 | 18 |
|
19 | | -if ! which -s gpg ; then |
20 | | - echo "gpg binary required in path for checking download. Skipping check." |
21 | | - exit 0 |
22 | | -fi |
| 19 | + # The verification key must be present, or it must be possible to download it |
| 20 | + # from the keyserver to perform file verification. If it is not present, |
| 21 | + # return EX_UNAVAILABLE. |
| 22 | + if ! { gpg --list-keys "$PT_key_id" || gpg --keyserver "$PT_key_server" --recv-key "$PT_key_id"; } then |
| 23 | + echo "Unable to download verification key ${PT_key_id}" |
| 24 | + return "$EX_UNAVAILABLE" |
| 25 | + fi |
23 | 26 |
|
24 | | -echo "Importing Puppet gpg public key" |
25 | | -gpg --keyserver hkp://keyserver.ubuntu.com:11371 --recv-key 4528B6CD9E61EF26 |
26 | | -if gpg --list-key --fingerprint 4528B6CD9E61EF26 | grep -q -E "D681 +1ED3 +ADEE +B844 +1AF5 +AA8F +4528 +B6CD +9E61 +EF26" ; then |
27 | | - echo "gpg public key imported successfully." |
28 | | -else |
29 | | - echo "Could not import gpg public key - wrong fingerprint." |
30 | | - exit 1 |
31 | | -fi |
| 27 | + # Perform the verification and return success or failure. |
| 28 | + if gpg --verify "$sig" "$doc"; then |
| 29 | + echo "Signature verification succeeded" |
| 30 | + return 0 |
| 31 | + else |
| 32 | + echo "Signature verification failed" |
| 33 | + return 1 |
| 34 | + fi |
| 35 | +} |
| 36 | + |
| 37 | +download() { |
| 38 | + printf '%s\n' "Downloading: ${1}" |
| 39 | + curl -s -f -L -o "$2" "$1" |
| 40 | +} |
| 41 | + |
| 42 | +download-size-verify() { |
| 43 | + local source="$1" |
| 44 | + local path="$2" |
| 45 | + |
| 46 | + urisize=$(curl -s -L --head "$source" | sed -rn 's/Content-Length: ([0-9]+)/\1/p' | tr -d '\012\015') |
| 47 | + filesize=$(stat -c%s "$path" 2>/dev/null || stat -f%z "$path" 2>/dev/null) |
| 48 | + |
| 49 | + echo "Filesize: ${filesize}" |
| 50 | + echo "Content-Length header: ${urisize}" |
| 51 | + |
| 52 | + # Assume that if the file exists and is the same size, we don't have to |
| 53 | + # re-download. |
| 54 | + if [[ ! -z "$urisize" && ! -z "$filesize" && "$filesize" -eq "$urisize" ]]; then |
| 55 | + echo "File size matches HTTP Content-Length header. Using file as-is." |
| 56 | + exit 0 |
| 57 | + else |
| 58 | + download "$source" "$path" |
| 59 | + fi |
| 60 | +} |
| 61 | + |
| 62 | +download-signature-verify() { |
| 63 | + local source="$1" |
| 64 | + local path="$2" |
| 65 | + |
| 66 | + if ! download "${source}.asc" "${path}.asc" ; then |
| 67 | + echo "Unable to download ${source}.asc. Skipping verification." |
| 68 | + download-size-verify "$source" "$path" |
| 69 | + return "$?" |
| 70 | + fi |
32 | 71 |
|
33 | | -sigpath=${PT_path}.asc |
34 | | -sigsource=${PT_source}.asc |
| 72 | + echo "Verifying ${path}..." |
| 73 | + verify_output=$(verify-file "${path}.asc" "$path"); |
| 74 | + verify_exit="$?" |
| 75 | + if [[ "$verify_exit" -eq "$EX_UNAVAILABLE" ]]; then |
| 76 | + echo "Verification unavailable. ${verify_output}. Skipping verification." |
| 77 | + download-size-verify "$source" "$path" |
| 78 | + elif [[ "$verify_exit" -eq "1" ]]; then |
| 79 | + echo "$verify_output" |
| 80 | + download "$source" "$path" |
| 81 | + echo "Verifying ${path}..." |
| 82 | + verify-file "${path}.asc" "$path" |
| 83 | + fi |
| 84 | +} |
35 | 85 |
|
36 | | -echo "Downloading tarball signature from ${sigsource}..." |
37 | | -curl -f -L -o "${sigpath}" "${sigsource}" |
38 | | -echo "Downloaded tarball signature to ${sigpath}." |
39 | | -echo "Checking tarball signature at ${sigpath}..." |
40 | | -if gpg --verify "${sigpath}" "${PT_path}" ; then |
41 | | - echo "Signature verification succeeded." |
| 86 | +if [[ "$PT_verify_download" == "true" ]]; then |
| 87 | + download-signature-verify "$PT_source" "$PT_path" |
42 | 88 | else |
43 | | - echo "Signature verification failed, please re-run the installation." |
44 | | - exit 1 |
| 89 | + download-size-verify "$PT_source" "$PT_path" |
45 | 90 | fi |
0 commit comments