package/dhcp/S80dhcp-server: allow empty INTERFACES
[buildroot-gz.git] / support / download / check-hash
blobc1ff53c02b5cf2253b248896380084bdffe5a21f
1 #!/usr/bin/env bash
2 set -e
4 # Helper to check a file matches its known hash
5 # Call it with:
6 # $1: the path of the file containing all the expected hashes
7 # $2: the full path to the temporary file that was downloaded, and
8 # that is to be checked
9 # $3: the final basename of the file, to which it will be ultimately
10 # saved as, to be able to match it to the corresponding hashes
11 # in the .hash file
13 # Exit codes:
14 # 0: the hash file exists and the file to check matches all its hashes,
15 # or the hash file does not exist
16 # 1: unknown command-line option
17 # 2: the hash file exists and the file to check does not match at least
18 # one of its hashes
19 # 3: the hash file exists and there was no hash to check the file against
20 # 4: the hash file exists and at least one hash type is unknown
22 while getopts :q OPT; do
23 case "${OPT}" in
24 q) exec >/dev/null;;
25 \?) exit 1;;
26 esac
27 done
28 shift $((OPTIND-1))
30 h_file="${1}"
31 file="${2}"
32 base="${3}"
34 # Bail early if no hash to check
35 if [ -z "${h_file}" ]; then
36 exit 0
38 # Does the hash-file exist?
39 if [ ! -f "${h_file}" ]; then
40 printf "WARNING: no hash file for %s\n" "${base}" >&2
41 exit 0
44 # Check one hash for a file
45 # $1: known hash
46 # $2: file (full path)
47 check_one_hash() {
48 _h="${1}"
49 _known="${2}"
50 _file="${3}"
52 # Note: md5 is supported, but undocumented on purpose.
53 # Note: sha3 is not supported, since there is currently no implementation
54 # (the NIST has yet to publish the parameters).
55 # Note: 'none' means there is explicitly no hash for that file.
56 case "${_h}" in
57 none)
58 return 0
60 md5|sha1) ;;
61 sha224|sha256|sha384|sha512) ;;
62 *) # Unknown hash, exit with error
63 printf "ERROR: unknown hash '%s' for '%s'\n" \
64 "${_h}" "${base}" >&2
65 exit 4
67 esac
69 # Do the hashes match?
70 _hash=$( ${_h}sum "${_file}" |cut -d ' ' -f 1 )
71 if [ "${_hash}" = "${_known}" ]; then
72 printf "%s: OK (%s: %s)\n" "${base}" "${_h}" "${_hash}"
73 return 0
76 printf "ERROR: %s has wrong %s hash:\n" "${base}" "${_h}" >&2
77 printf "ERROR: expected: %s\n" "${_known}" >&2
78 printf "ERROR: got : %s\n" "${_hash}" >&2
79 printf "ERROR: Incomplete download, or man-in-the-middle (MITM) attack\n" >&2
81 exit 2
84 # Do we know one or more hashes for that file?
85 nb_checks=0
86 while read t h f; do
87 case "${t}" in
88 ''|'#'*)
89 # Skip comments and empty lines
90 continue
93 if [ "${f}" = "${base}" ]; then
94 check_one_hash "${t}" "${h}" "${file}"
95 : $((nb_checks++))
98 esac
99 done <"${h_file}"
101 if [ ${nb_checks} -eq 0 ]; then
102 case " ${BR_NO_CHECK_HASH_FOR} " in
103 *" ${base} "*)
104 # File explicitly has no hash
105 exit 0
107 esac
108 printf "ERROR: No hash found for %s\n" "${base}" >&2
109 exit 3