Index: src/scripts/package_script_whitelist.sh |
diff --git a/src/scripts/package_script_whitelist.sh b/src/scripts/package_script_whitelist.sh |
new file mode 100755 |
index 0000000000000000000000000000000000000000..2d23fe0755d18c0b5d2a24f015789e52dcaf1173 |
--- /dev/null |
+++ b/src/scripts/package_script_whitelist.sh |
@@ -0,0 +1,223 @@ |
+#!/bin/bash |
+ |
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+# This script is used to maintain the whitelist for package maintainer scripts. |
+# If a package maintainer script is in the whitelist file then it is ok to skip |
+# running that maintainer script when installing the package. Otherwise there |
+# should be an equivalent script that can perform those operation on a target |
+# root file system. |
+# |
+# The whitelist contains on entry per line which is the filename followed by |
+# its md5sum. Ideally it is kept in sorted by package name like below: |
+# bar.postinst MD5SUM1 |
+# bar.postinst MD5SUM2 |
+# bar.preinst MD5SUM3 |
+# foo.postinst MD5SUM4 |
+# |
+# TODO: Should be able to whitelist on built packages and not just an already |
+# created rootfs. |
+ |
+. "$(dirname "$0")/common.sh" |
+ |
+DEFINE_string whitelist "${SRC_ROOT}/package_scripts/package.whitelist" \ |
+ "The whitelist file to use." |
+DEFINE_string file "" "The path to a presinst/postinst file for add/audit." |
+DEFINE_string root "" \ |
+ "Mounted root on which to look for the maintainer scripts when using audit." |
+DEFINE_string audit_pattern "*" \ |
+ "Package name pattern used when auditing all packages [ex: 'lib*']" |
+ |
+FLAGS_HELP="Usage: $(basename $0) [options] add|audit|check |
+ |
+Use this script to maintain the package scripts whitelist. It handles the |
+following commands: |
+ |
+ add: Add the --file= specified file to the whitelist. |
+ audit: If no --file= is given, audit all non-whitelisted scripts in the |
+ given rootfs. This will show you the files in turn and give you |
+ the option to Skip/View/Whitelist/Create template for the script. |
+ If --file is given it will do the same for that one file. |
+ check: Checks if the --file= is in the whitelist. |
+" |
+ |
+# Parse command line |
+FLAGS "$@" || exit 1 |
+eval set -- "${FLAGS_ARGV}" |
+ |
+# Returns true if the input file is whitelisted. |
+# |
+# $1 - The file to check |
+is_whitelisted() { |
+ local file=$1 |
+ local whitelist="$FLAGS_whitelist" |
+ test -f "$whitelist" || return |
+ |
+ local checksum=$(md5sum "$file" | awk '{ print $1 }') |
+ local count=$(grep -c "$checksum" "${whitelist}" || /bin/true) |
+ test $count -ne 0 |
+} |
+ |
+# Adds a the file at the given path to the whitelist. |
+# |
+# $1 - Path to file to add to whitelist. |
+add_to_whitelist() { |
+ local path=$1 |
+ local whitelist="$FLAGS_whitelist" |
+ local file=$(basename "$path") |
+ |
+ local checksum=$(md5sum "$path" | awk '{ print $1 }') |
+ if [ ! -f "$whitelist" ]; then |
+cat <<EOF > "$whitelist" |
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+EOF |
+ fi |
+ |
+ echo "$file $checksum" | \ |
+ sort -u -o "${whitelist}.new" "$whitelist" - |
+ mv "${whitelist}.new" "$whitelist" |
+} |
+ |
+# Creates a template alternative maintainer script in the same directory |
+# as the whitelist file. This will run instead of the whitelisted package |
+# scripts using only build machine binaries and targeting a rootfs. |
+# |
+# $1 - The name of the template (like 'foo.postinst') |
+create_script_template() { |
+ local file=$1 |
+ |
+ local whitelist_dir=$(dirname "$FLAGS_whitelist") |
+ local path="${whitelist_dir}/${file}" |
+ if [ -f "$path" ]; then |
+ echo "Error: Alternative maintainer script '$path' already exists." |
+ return |
+ fi |
+ |
+cat <<EOF > "$path" |
+#!/bin/bash |
+ |
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+# \$ROOT - The path to the target root file system. |
+# \$SRC_ROOT - The path to the source tree. |
+ |
+# $file |
+ |
+# TODO: The equivalent of $file running from outside of the target rootfs |
+# that only uses tools from the build machine and not from the target. |
+EOF |
+ chmod 0750 "$path" |
+} |
+ |
+# Show the script to the user for audit purposes. |
+# |
+# $1 - The script to show. |
+show_script() { |
+ local path=$1 |
+ local type=$(file -b "$path") |
+ local is_text=$(echo "$type" | grep -c "text") |
+ if [ $is_text -eq 0 ]; then |
+ local file=$(basename "$path") |
+ echo "Unable to view '$file'; not a text file. Type is '$type'" |
+ else |
+ local pager="/usr/bin/less" |
+ if [ -n "$PAGER" ]; then |
+ pager="$PAGER" |
+ fi |
+ $pager "$path" |
+ fi |
+} |
+ |
+# Process a given script for audit purposes. We show the script to the user |
+# and then prompt them with options. |
+# |
+# $1 - The script to process |
+audit_script() { |
+ local path=$1 |
+ local file=$(basename "$path") |
+ local prompt="$file: (Q)uit, (S)kip, (V)iew, (W)hitelist, (C)reate template?" |
+ |
+ show_script "$path" |
+ while true; do |
+ read -n 1 -p "$prompt " ANSWER |
+ echo "" |
+ ANSWER="${ANSWER:0:1}" # Get just the first character |
+ case $ANSWER in |
+ Q*|q*) |
+ exit 0 |
+ ;; |
+ S*|s*) |
+ echo "Skipping: $file" |
+ return |
+ ;; |
+ V*|v*) |
+ show_script "$path" |
+ ;; |
+ W*|w*) |
+ echo "Whitelisting: $file" |
+ add_to_whitelist "$path" |
+ return |
+ ;; |
+ C*|c*) |
+ echo "Creating template for: $file" |
+ create_script_template "$file" |
+ ;; |
+ *) |
+ echo "Unknown response: '$ANSWER'" |
+ ;; |
+ esac |
+ done |
+} |
+ |
+# Audit all non-whitelisted script in $FLAGS_root |
+audit_all() { |
+ echo "Auditing packages at: $FLAGS_root" |
+ local dpkg_info="$FLAGS_root/var/lib/dpkg/info" |
+ local scripts=$(ls "$dpkg_info"/$FLAGS_audit_pattern.preinst \ |
+ "$dpkg_info"/$FLAGS_audit_pattern.postinst | sort -r) |
+ |
+ for s in $scripts; do |
+ if ! is_whitelisted "$s"; then |
+ audit_script "$s" |
+ fi |
+ done |
+} |
+ |
+case $1 in |
+ add) |
+ if [ -z "$FLAGS_file" ]; then |
+ echo "--file parameter is required for 'add' command." |
+ exit 1 |
+ fi |
+ add_to_whitelist "$FLAGS_file" |
+ ;; |
+ audit) |
+ if [ -n "$FLAGS_file" ]; then |
+ audit_script "$FLAGS_file" |
+ elif [ -n "$FLAGS_root" ]; then |
+ audit_all |
+ else |
+ echo "Error: One of --file or --root is needed for audit command." |
+ fi |
+ ;; |
+ check) |
+ if [ -z "$FLAGS_file" ]; then |
+ echo "--file parameter is required for 'check' command." |
+ exit 1 |
+ fi |
+ if is_whitelisted "$FLAGS_file"; then |
+ echo "Whitelisted" |
+ else |
+ echo "Not whitelisted" |
+ fi |
+ ;; |
+ *) |
+ echo "Unknown command." |
+ ;; |
+esac |