| 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 # Adds a the file at the given path to the whitelist. | |
| 51 # | |
| 52 # $1 - Path to file to add to whitelist. | |
| 53 add_to_whitelist() { | |
| 54 local path=$1 | |
| 55 local whitelist="$FLAGS_whitelist" | |
| 56 local file=$(basename "$path") | |
| 57 | |
| 58 local checksum=$(md5sum "$path" | awk '{ print $1 }') | |
| 59 if [ ! -f "$whitelist" ]; then | |
| 60 cat <<EOF > "$whitelist" | |
| 61 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | |
| 62 # Use of this source code is governed by a BSD-style license that can be | |
| 63 # found in the LICENSE file. | |
| 64 EOF | |
| 65 fi | |
| 66 | |
| 67 echo "$file $checksum" | \ | |
| 68 sort -u -o "${whitelist}.new" "$whitelist" - | |
| 69 mv "${whitelist}.new" "$whitelist" | |
| 70 } | |
| 71 | |
| 72 # Creates a template alternative maintainer script in the same directory | |
| 73 # as the whitelist file. This will run instead of the whitelisted package | |
| 74 # scripts using only build machine binaries and targeting a rootfs. | |
| 75 # | |
| 76 # $1 - The name of the template (like 'foo.postinst') | |
| 77 create_script_template() { | |
| 78 local file=$1 | |
| 79 | |
| 80 local whitelist_dir=$(dirname "$FLAGS_whitelist") | |
| 81 local path="${whitelist_dir}/${file}" | |
| 82 if [ -f "$path" ]; then | |
| 83 echo "Error: Alternative maintainer script '$path' already exists." | |
| 84 return | |
| 85 fi | |
| 86 | |
| 87 cat <<EOF > "$path" | |
| 88 #!/bin/bash | |
| 89 | |
| 90 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | |
| 91 # Use of this source code is governed by a BSD-style license that can be | |
| 92 # found in the LICENSE file. | |
| 93 | |
| 94 # $file | |
| 95 | |
| 96 set -e | |
| 97 | |
| 98 # \$ROOT - The path to the target root file system. | |
| 99 # \$SRC_ROOT - The path to the source tree. | |
| 100 | |
| 101 # TODO: The equivalent of $file running from outside of the target rootfs | |
| 102 # that only uses tools from the build machine and not from the target. | |
| 103 | |
| 104 exit 1 | |
| 105 | |
| 106 EOF | |
| 107 chmod 0750 "$path" | |
| 108 } | |
| 109 | |
| 110 # Show the script to the user for audit purposes. | |
| 111 # | |
| 112 # $1 - The script to show. | |
| 113 show_script() { | |
| 114 local path=$1 | |
| 115 local type=$(file -b "$path") | |
| 116 local is_text=$(echo "$type" | grep -c "text") | |
| 117 if [ $is_text -eq 0 ]; then | |
| 118 local file=$(basename "$path") | |
| 119 echo "Unable to view '$file'; not a text file. Type is '$type'" | |
| 120 else | |
| 121 local pager="/usr/bin/less" | |
| 122 if [ -n "$PAGER" ]; then | |
| 123 pager="$PAGER" | |
| 124 fi | |
| 125 $pager "$path" | |
| 126 fi | |
| 127 } | |
| 128 | |
| 129 # Process a given script for audit purposes. We show the script to the user | |
| 130 # and then prompt them with options. | |
| 131 # | |
| 132 # $1 - The script to process | |
| 133 audit_script() { | |
| 134 local path=$1 | |
| 135 local file=$(basename "$path") | |
| 136 local prompt="$file: (Q)uit, (S)kip, (V)iew, (W)hitelist, (C)reate template?" | |
| 137 | |
| 138 show_script "$path" | |
| 139 while true; do | |
| 140 read -n 1 -p "$prompt " ANSWER | |
| 141 echo "" | |
| 142 ANSWER="${ANSWER:0:1}" # Get just the first character | |
| 143 case $ANSWER in | |
| 144 Q*|q*) | |
| 145 exit 0 | |
| 146 ;; | |
| 147 S*|s*) | |
| 148 echo "Skipping: $file" | |
| 149 return | |
| 150 ;; | |
| 151 V*|v*) | |
| 152 show_script "$path" | |
| 153 ;; | |
| 154 W*|w*) | |
| 155 echo "Whitelisting: $file" | |
| 156 add_to_whitelist "$path" | |
| 157 return | |
| 158 ;; | |
| 159 C*|c*) | |
| 160 echo "Creating template for: $file" | |
| 161 create_script_template "$file" | |
| 162 ;; | |
| 163 *) | |
| 164 echo "Unknown response: '$ANSWER'" | |
| 165 ;; | |
| 166 esac | |
| 167 done | |
| 168 } | |
| 169 | |
| 170 # Audit all non-whitelisted script in $FLAGS_root | |
| 171 audit_all() { | |
| 172 echo "Auditing packages at: $FLAGS_root" | |
| 173 local dpkg_info="$FLAGS_root/var/lib/dpkg/info" | |
| 174 local scripts=$(ls "$dpkg_info"/$FLAGS_audit_pattern.preinst \ | |
| 175 "$dpkg_info"/$FLAGS_audit_pattern.postinst | sort -r) | |
| 176 | |
| 177 for s in $scripts; do | |
| 178 if ! is_whitelisted "$s"; then | |
| 179 audit_script "$s" | |
| 180 fi | |
| 181 done | |
| 182 } | |
| 183 | |
| 184 case $1 in | |
| 185 add) | |
| 186 if [ -z "$FLAGS_file" ]; then | |
| 187 echo "--file parameter is required for 'add' command." | |
| 188 exit 1 | |
| 189 fi | |
| 190 add_to_whitelist "$FLAGS_file" | |
| 191 ;; | |
| 192 audit) | |
| 193 if [ -n "$FLAGS_file" ]; then | |
| 194 audit_script "$FLAGS_file" | |
| 195 elif [ -n "$FLAGS_root" ]; then | |
| 196 audit_all | |
| 197 else | |
| 198 echo "Error: One of --file or --root is needed for audit command." | |
| 199 fi | |
| 200 ;; | |
| 201 check) | |
| 202 if [ -z "$FLAGS_file" ]; then | |
| 203 echo "--file parameter is required for 'check' command." | |
| 204 exit 1 | |
| 205 fi | |
| 206 if is_whitelisted "$FLAGS_file"; then | |
| 207 echo "Whitelisted" | |
| 208 else | |
| 209 echo "Not whitelisted" | |
| 210 fi | |
| 211 ;; | |
| 212 *) | |
| 213 echo "Unknown command." | |
| 214 ;; | |
| 215 esac | |
| OLD | NEW |