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 |