OLD | NEW |
(Empty) | |
| 1 #!/bin/bash |
| 2 |
| 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. |
| 6 |
| 7 # This script is used to maintain the whitelist for package maintainer scripts. |
| 8 # If a package maintainer script is in the whitelist file then it is ok to skip |
| 9 # running that maintainer script when installing the package. Otherwise there |
| 10 # should be an equivalent script that can perform those operation on a target |
| 11 # root file system. |
| 12 # |
| 13 # The whitelist contains on entry per line which is the filename followed by |
| 14 # its md5sum. Ideally it is kept in sorted by package name like below: |
| 15 # bar.postinst MD5SUM1 |
| 16 # bar.postinst MD5SUM2 |
| 17 # bar.preinst MD5SUM3 |
| 18 # foo.postinst MD5SUM4 |
| 19 # |
| 20 # TODO: Should be able to whitelist on built packages and not just an already |
| 21 # created rootfs. |
| 22 |
| 23 . "$(dirname "$0")/common.sh" |
| 24 |
| 25 DEFINE_string whitelist "${SRC_ROOT}/package_scripts/package.whitelist" \ |
| 26 "The whitelist file to use." |
| 27 DEFINE_string file "" "The path to a presinst/postinst file for add/audit." |
| 28 DEFINE_string root "" \ |
| 29 "Mounted root on which to look for the maintainer scripts when using audit." |
| 30 DEFINE_string audit_pattern "*" \ |
| 31 "Package name pattern used when auditing all packages [ex: 'lib*']" |
| 32 |
| 33 FLAGS_HELP="Usage: $(basename $0) [options] add|audit|check |
| 34 |
| 35 Use this script to maintain the package scripts whitelist. It handles the |
| 36 following commands: |
| 37 |
| 38 add: Add the --file= specified file to the whitelist. |
| 39 audit: If no --file= is given, audit all non-whitelisted scripts in the |
| 40 given rootfs. This will show you the files in turn and give you |
| 41 the option to Skip/View/Whitelist/Create template for the script. |
| 42 If --file is given it will do the same for that one file. |
| 43 check: Checks if the --file= is in the whitelist. |
| 44 " |
| 45 |
| 46 # Parse command line |
| 47 FLAGS "$@" || exit 1 |
| 48 eval set -- "${FLAGS_ARGV}" |
| 49 |
| 50 # Returns true if the input file is whitelisted. |
| 51 # |
| 52 # $1 - The file to check |
| 53 is_whitelisted() { |
| 54 local file=$1 |
| 55 local whitelist="$FLAGS_whitelist" |
| 56 test -f "$whitelist" || return |
| 57 |
| 58 local checksum=$(md5sum "$file" | awk '{ print $1 }') |
| 59 local count=$(grep -c "$checksum" "${whitelist}" || /bin/true) |
| 60 test $count -ne 0 |
| 61 } |
| 62 |
| 63 # Adds a the file at the given path to the whitelist. |
| 64 # |
| 65 # $1 - Path to file to add to whitelist. |
| 66 add_to_whitelist() { |
| 67 local path=$1 |
| 68 local whitelist="$FLAGS_whitelist" |
| 69 local file=$(basename "$path") |
| 70 |
| 71 local checksum=$(md5sum "$path" | awk '{ print $1 }') |
| 72 if [ ! -f "$whitelist" ]; then |
| 73 cat <<EOF > "$whitelist" |
| 74 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 75 # Use of this source code is governed by a BSD-style license that can be |
| 76 # found in the LICENSE file. |
| 77 EOF |
| 78 fi |
| 79 |
| 80 echo "$file $checksum" | \ |
| 81 sort -u -o "${whitelist}.new" "$whitelist" - |
| 82 mv "${whitelist}.new" "$whitelist" |
| 83 } |
| 84 |
| 85 # Creates a template alternative maintainer script in the same directory |
| 86 # as the whitelist file. This will run instead of the whitelisted package |
| 87 # scripts using only build machine binaries and targeting a rootfs. |
| 88 # |
| 89 # $1 - The name of the template (like 'foo.postinst') |
| 90 create_script_template() { |
| 91 local file=$1 |
| 92 |
| 93 local whitelist_dir=$(dirname "$FLAGS_whitelist") |
| 94 local path="${whitelist_dir}/${file}" |
| 95 if [ -f "$path" ]; then |
| 96 echo "Error: Alternative maintainer script '$path' already exists." |
| 97 return |
| 98 fi |
| 99 |
| 100 cat <<EOF > "$path" |
| 101 #!/bin/bash |
| 102 |
| 103 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 104 # Use of this source code is governed by a BSD-style license that can be |
| 105 # found in the LICENSE file. |
| 106 |
| 107 # \$ROOT - The path to the target root file system. |
| 108 # \$SRC_ROOT - The path to the source tree. |
| 109 |
| 110 # $file |
| 111 |
| 112 # TODO: The equivalent of $file running from outside of the target rootfs |
| 113 # that only uses tools from the build machine and not from the target. |
| 114 EOF |
| 115 chmod 0750 "$path" |
| 116 } |
| 117 |
| 118 # Show the script to the user for audit purposes. |
| 119 # |
| 120 # $1 - The script to show. |
| 121 show_script() { |
| 122 local path=$1 |
| 123 local type=$(file -b "$path") |
| 124 local is_text=$(echo "$type" | grep -c "text") |
| 125 if [ $is_text -eq 0 ]; then |
| 126 local file=$(basename "$path") |
| 127 echo "Unable to view '$file'; not a text file. Type is '$type'" |
| 128 else |
| 129 local pager="/usr/bin/less" |
| 130 if [ -n "$PAGER" ]; then |
| 131 pager="$PAGER" |
| 132 fi |
| 133 $pager "$path" |
| 134 fi |
| 135 } |
| 136 |
| 137 # Process a given script for audit purposes. We show the script to the user |
| 138 # and then prompt them with options. |
| 139 # |
| 140 # $1 - The script to process |
| 141 audit_script() { |
| 142 local path=$1 |
| 143 local file=$(basename "$path") |
| 144 local prompt="$file: (Q)uit, (S)kip, (V)iew, (W)hitelist, (C)reate template?" |
| 145 |
| 146 show_script "$path" |
| 147 while true; do |
| 148 read -n 1 -p "$prompt " ANSWER |
| 149 echo "" |
| 150 ANSWER="${ANSWER:0:1}" # Get just the first character |
| 151 case $ANSWER in |
| 152 Q*|q*) |
| 153 exit 0 |
| 154 ;; |
| 155 S*|s*) |
| 156 echo "Skipping: $file" |
| 157 return |
| 158 ;; |
| 159 V*|v*) |
| 160 show_script "$path" |
| 161 ;; |
| 162 W*|w*) |
| 163 echo "Whitelisting: $file" |
| 164 add_to_whitelist "$path" |
| 165 return |
| 166 ;; |
| 167 C*|c*) |
| 168 echo "Creating template for: $file" |
| 169 create_script_template "$file" |
| 170 ;; |
| 171 *) |
| 172 echo "Unknown response: '$ANSWER'" |
| 173 ;; |
| 174 esac |
| 175 done |
| 176 } |
| 177 |
| 178 # Audit all non-whitelisted script in $FLAGS_root |
| 179 audit_all() { |
| 180 echo "Auditing packages at: $FLAGS_root" |
| 181 local dpkg_info="$FLAGS_root/var/lib/dpkg/info" |
| 182 local scripts=$(ls "$dpkg_info"/$FLAGS_audit_pattern.preinst \ |
| 183 "$dpkg_info"/$FLAGS_audit_pattern.postinst | sort -r) |
| 184 |
| 185 for s in $scripts; do |
| 186 if ! is_whitelisted "$s"; then |
| 187 audit_script "$s" |
| 188 fi |
| 189 done |
| 190 } |
| 191 |
| 192 case $1 in |
| 193 add) |
| 194 if [ -z "$FLAGS_file" ]; then |
| 195 echo "--file parameter is required for 'add' command." |
| 196 exit 1 |
| 197 fi |
| 198 add_to_whitelist "$FLAGS_file" |
| 199 ;; |
| 200 audit) |
| 201 if [ -n "$FLAGS_file" ]; then |
| 202 audit_script "$FLAGS_file" |
| 203 elif [ -n "$FLAGS_root" ]; then |
| 204 audit_all |
| 205 else |
| 206 echo "Error: One of --file or --root is needed for audit command." |
| 207 fi |
| 208 ;; |
| 209 check) |
| 210 if [ -z "$FLAGS_file" ]; then |
| 211 echo "--file parameter is required for 'check' command." |
| 212 exit 1 |
| 213 fi |
| 214 if is_whitelisted "$FLAGS_file"; then |
| 215 echo "Whitelisted" |
| 216 else |
| 217 echo "Not whitelisted" |
| 218 fi |
| 219 ;; |
| 220 *) |
| 221 echo "Unknown command." |
| 222 ;; |
| 223 esac |
OLD | NEW |