-
Notifications
You must be signed in to change notification settings - Fork 80
/
croissant.sh
executable file
·368 lines (325 loc) · 16.6 KB
/
croissant.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
#!/bin/sh
#Script to install ChromeOS on top of ChromiumOS
#Can be used to install on a disk drive or applied to a ChromiumOS image
#If installing to a disk drive, you must run it from a different drive/USB
#Parameters:
#1 - ChromiumOS image, drive (ex: /dev/sda) or system partition (ex: /dev/sda3) (If partition: manually resize it to 4GB before running the script)
#2 - ChromeOS image file to be installed
#3 - [Optional] ChromeOS image from older device with TPM1.2 (ex: caroline image file) (needed for TPM2 images like eve to be able to login)
flag_vtpm=false
flag_tpm1=false
flag_disk=false
if ( ! test -z {,} ); then echo "Must be ran with \"sudo bash\""; exit 1; fi
if [ $(whoami) != "root" ]; then echo "Please run with sudo"; exit 1; fi
if [ -z "$2" ]; then echo "Missing parameters"; exit 1; fi
if [ -b "$1" ]; then flag_image=false; elif [ -f "$1" ]; then flag_image=true; else echo "Invalid image or partition: $1"; exit 1; fi
if [ ! -d /home/chronos ]; then mkdir /home/chronos; fi
if [ ! -d /home/chronos/image ]; then mkdir /home/chronos/image; fi
if [ ! -d /home/chronos/local ]; then mkdir /home/chronos/local; fi
if [ ! -d /home/chronos/tpm1image ]; then mkdir /home/chronos/tpm1image; fi
if [ ! -d /home/chronos/RAW ]; then mkdir /home/chronos/RAW; fi
function cleanup_chromefy {
sync
umount /home/chronos/image 2>/dev/null
umount /home/chronos/local 2>/dev/null
umount /home/chronos/tpm1image 2>/dev/null
losetup -d "$chromium_image" 2>/dev/null
losetup -d "$chromeos_image" 2>/dev/null
losetup -d "$chromeos_tpm1_image" 2>/dev/null
rm -rf /home/chronos/RAW/* &>/dev/null
}
function abort_chromefy {
echo "aborting...";
cleanup_chromefy
exit 1
}
function read_choice {
while read choice; do
case "$choice" in
[yY]|[yY][eE][sS] ) choice=true; break;;
[nN]|[nN][oO] ) choice=false; break;;
* ) echo "Invalid choice";;
esac
done
}
function cp_ext {
if [ -x "$(command -v rsync)" ]; then
rsync --info=progress2 -ah "$@"
else
cp -av "$@"
fi
}
function cp_ext_nodup {
if [ -x "$(command -v rsync)" ]; then
rsync --info=progress2 --ignore-existing -ah "$@"
else
cp -nav "$@"
fi
}
#Checks if images are valid and mounts them
if [ "$flag_image" = true ]; then
chromium_image=`losetup --show -fP "$1"`
mount "$chromium_image"p3 /home/chronos/local -o loop,rw 2>/dev/null
if [ ! $? -eq 0 ]; then echo "Image $1 does not have a system partition (corrupted?)"; abort_chromefy; fi
else chromium_image="$1"; fi
if [ ! -f "$2" ]; then echo "Image $2 not found"; abort_chromefy; fi
chromeos_image=`losetup --show -fP "$2"`
if [ -b "$chromeos_image"p3 ]; then
mount "$chromeos_image"p3 /home/chronos/image -o loop,ro 2>/dev/null
else
mount $2 /home/chronos/image -o loop,ro 2>/dev/null
fi
if [ ! $? -eq 0 ]; then echo "Image $2 does not have a system partition (corrupted?)"; abort_chromefy; fi
if [ ! -z "$3" ]; then
if tar -tf "$3" &>/dev/null && ! tar -ztf "$3" &>/dev/null; then
flag_vtpm=true
else
flag_tpm1=true
if [ ! -f "$3" ]; then echo "Image $3 not found"; abort_chromefy; fi
chromeos_tpm1_image=`losetup --show -fP "$3"`
mount "$chromeos_tpm1_image"p3 /home/chronos/tpm1image -o loop,ro 2>/dev/null
if [ ! $? -eq 0 ]; then echo "Image $3 does not have a system partition (corrupted?)"; abort_chromefy; fi
fi
fi
#Checks if disk or partition
PART_LIST=`sfdisk -lq "$chromium_image" 2>/dev/null`
PART_GRUB=`echo "$PART_LIST" | grep "^""$chromium_image""[^:]" | awk '{print $1}' | grep [^0-9]12$`
PART_B=`echo "$PART_LIST" | grep "^""$chromium_image""[^:]" | awk '{print $1}' | grep [^0-9]5$`
PART_A=`echo "$PART_LIST" | grep "^""$chromium_image""[^:]" | awk '{print $1}' | grep [^0-9]3$`
PART_STATE=`echo "$PART_LIST" | grep "^""$chromium_image""[^:]" | awk '{print $1}' | grep [^0-9]1$`
if [ "$flag_image" = false ]; then
if [ ! -z "$PART_LIST" ]; then
flag_disk=true
umount "$1"?* 2>/dev/null
if [ $(sudo sfdisk --part-type "$1" 3 2>/dev/null) != "3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC" ]
then echo "Invalid device (Chromium/Chrome not installed)"; abort_chromefy
fi
else
PART_A="$1"
fi
fi
#Checks VTPM support if third parameter is a tar file (TPM emulator)
if [ "$flag_image" = false ]; then mount "$PART_A" /home/chronos/local; fi
KERNEL_LOCAL=`ls /lib/modules/ | egrep "^([0-9]{1,}\.)+[0-9]{1,}[^ ]*$" | tail -1`
KERNEL_CHROMIUM=`ls /home/chronos/local/lib/modules/ | egrep "^([0-9]{1,}\.)+[0-9]{1,}[^ ]*$" | tail -1`
VTPM_BUILTIN=`cat /home/chronos/local/lib/modules/"$KERNEL_CHROMIUM"/modules.builtin 2>/dev/null | grep tpm_vtpm_proxy.ko`
VTPM_MODULE=`cat /home/chronos/local/lib/modules/"$KERNEL_CHROMIUM"/modules.dep 2>/dev/null | grep tpm_vtpm_proxy.ko`
if [ "$flag_vtpm" = true ] && [ -z "$VTPM_BUILTIN" ] && [ -z "$VTPM_MODULE" ]; then
echo "This Chromium image does not support VTPM proxy, use different image or TPM replacement method"; abort_chromefy
fi
if [ "$flag_vtpm" = true ]; then
tar -xvf "$3" -C /home/chronos/RAW/
fi
#Backups ChromiumOS /lib directory if needed
chromium_root_dir=""
flag_linux=true
choice=false
if [ -e "/usr/sbin/chromeos-install" ] && [ ! -z "$KERNEL_LOCAL" ] && [ "$KERNEL_LOCAL" = "$KERNEL_CHROMIUM" ]; then
echo "Local ChromiumOS installation detected; use local files (y/n)?"
read_choice
fi
if [ "$choice" = false ]; then
chromium_root_dir="/home/chronos/RAW"
flag_linux=false
mkdir -p /home/chronos/RAW/usr/lib64
echo "Backing up kernel modules..."
cp_ext /home/chronos/local/{lib,boot} /home/chronos/RAW/
cp_ext /home/chronos/local/usr/lib64/{dri,va} /home/chronos/RAW/usr/lib64/
if [ ! $? -eq 0 ]; then echo "Error while copying ChromiumOS files locally (insufficent disk space?)"; abort_chromefy; fi
fi
umount /home/chronos/local 2>/dev/null
#Increases ROOT_A partition's size (if flashing on image)
choice=false
if [ "$flag_image" = true ]; then choice=true;
elif [ "$flag_disk" = true ]; then echo "Resize the system partition (y/n)?"; read_choice; fi;
if [ "$choice" = true ]; then
START_NEWB=`expr $(sfdisk -o Device,End -lq "$chromium_image" | grep "^""$PART_GRUB"[[:space:]] | awk '{print $2}') + 1`
END_NEWB=`expr $START_NEWB + 8191`
UUID_B=`sfdisk --part-uuid "$chromium_image" 5`
START_NEWA=`expr $END_NEWB + 1`
END_NEWA=`expr $(sfdisk -o Device,Start -lq "$chromium_image" | grep "^""$PART_STATE"[[:space:]] | awk '{print $2}') - 1`
UUID_A=`sfdisk --part-uuid "$chromium_image" 3`
#Deletes third (ROOT_A) and fifth (ROOT_B) partitions
flock "$chromium_image" sfdisk --delete $chromium_image 5
flock "$chromium_image" sfdisk --delete $chromium_image 3
#Recreates the fifth partition with 4MB = 4194304
echo -e 'n\n5\n'"$START_NEWB"'\n'"$END_NEWB"'\nw' | flock "$chromium_image" fdisk "$chromium_image"
if [ -z "$PART_B" ]; then PART_B=`flock "$chromium_image" sfdisk -lq "$chromium_image" 2>/dev/null | grep "^""$chromium_image""[^:]" | awk '{print $1}' | grep [^0-9]5$`; fi
flock "$chromium_image" resize2fs "$PART_B"
flock "$chromium_image" sfdisk --part-label "$chromium_image" 5 "ROOT-B"
flock "$chromium_image" sfdisk --part-type "$chromium_image" 5 "3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC"
flock "$chromium_image" sfdisk --part-uuid "$chromium_image" 5 "$UUID_B"
flock "$chromium_image" e2label "$PART_B" "ROOT-B"
yes | mkfs.ext4 "$PART_B"
#Recreates the third partition with the remaining space
echo -e 'n\n3\n'"$START_NEWA"'\n'"$END_NEWA"'\nw' | flock "$chromium_image" fdisk "$chromium_image"
flock "$chromium_image" hdparm -z "$chromium_image"
# flock "$chromium_image" dd bs=512 count=`expr $END_NEWA + 1 - $START_NEWA` if=/dev/zero of="$PART_A"
flock "$chromium_image" yes | mke2fs -S "$PART_A"
flock "$chromium_image" e2fsck -y -v -C 0 "$PART_A"
flock "$chromium_image" resize2fs "$PART_A"
flock "$chromium_image" sfdisk --part-label "$chromium_image" 3 "ROOT-A"
flock "$chromium_image" sfdisk --part-type "$chromium_image" 3 "3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC"
flock "$chromium_image" sfdisk --part-uuid "$chromium_image" 3 "$UUID_A"
flock "$chromium_image" e2label "$PART_A" "ROOT-A"
yes | mkfs.ext4 "$PART_A"
#Searches and fixes errors at filesystem-3, then remounts
e2fsck -f -y -v -C 0 "$PART_A"
fi
#Mounts ChromiumOS system partition
if [ "$flag_image" = false ]; then
umount "$PART_A" 2>/dev/null
yes | mkfs.ext4 "$PART_A"
mount "$PART_A" /home/chronos/local
if [ ! $? -eq 0 ]; then echo "Partition $PART_A inexistent"; abort_chromefy; fi
else
mount "$PART_A" /home/chronos/local -o loop,rw,sync 2>/dev/null
if [ ! $? -eq 0 ]; then echo "Something went wrong while changing $1 partition table (corrupted?)"; abort_chromefy; fi
fi
#Copies all ChromeOS system files
echo "Copying ChromeOS system files..."
cp_ext /home/chronos/image/* /home/chronos/local
umount /home/chronos/image
#Copies modules and certificates from ChromiumOS
rm -rf /home/chronos/local/lib/firmware
rm -rf /home/chronos/local/lib/modules/
echo "Copying kernel modules..."
cp_ext "$chromium_root_dir"/{lib,boot} /home/chronos/local/
cp_ext_nodup "$chromium_root_dir"/usr/lib64/{dri,va} /home/chronos/local/usr/lib64/ #Extra GPU drivers
rm -rf /home/chronos/local/etc/modprobe.d/alsa*.conf
echo "Is your wireless card bcm43xx? Answer no if unsure (y/n)"
read_choice
if [ "$choice" = true ]; then
# enable bcm43xx wifi
cat > /home/chronos/local/lib/modprobe.d/blacklist.conf <<EOF
blacklist b43
install b43 /bin/true
blacklist b43legacy
install b43legacy /bin/true
blacklist ssb
install ssb /bin/true
blacklist bcm43xx
install bcm43xx /bin/true
blacklist brcm80211
install brcm80211 /bin/true
blacklist brcmfmac
install brcmfmac /bin/true
blacklist brcmsmac
install brcmsmac /bin/true
blacklist brcmutil
install brcmutil /bin/true
blacklist bcma
install bcma /bin/true
EOF
fi
if [ "$choice" = false ]; then # no point in asking what wireless card is if user just told us
echo "Is it ath10k? Answer no if unsure (y/n)"
read_choice
if [ "$choice" = true ] && [ -f /home/chronos/local/lib/firmware/ath10k/QCA9377/hw1.0/firmware-6.bin ]; then
unlink /home/chronos/local/lib/firmware/ath10k/QCA9377/hw1.0/firmware-6.bin
fi
fi
echo "Is your computer MacBook/Pro/Air? (y/n)"
read_choice
if [ "$choice" = true ]; then
# enable trackpad
cat > /home/chronos/local/lib/udev/rules.d/60-evdev-apple-touchpad.rules <<EOF
ACTION=="remove", GOTO="evdev_apple_end"
KERNEL!="event*", GOTO="evdev_apple_end"
ENV{ID_INPUT_TOUCHPAD}=="1", \
ATTRS{name}=="bcm5974", \
ENV{EVDEV_ABS_00}="::94", ENV{EVDEV_ABS_01}="::92", \
ENV{EVDEV_ABS_35}="::94", ENV{EVDEV_ABS_36}="::92", \
RUN{builtin}+="keyboard", GOTO="evdev_apple_end"
LABEL="evdev_apple_end"
EOF
cat > /home/chronos/local/lib/udev/rules.d/90-powerd-id-apple-touchpad.rules <<EOF
SUBSYSTEM=="input", ENV{ID_INPUT_TOUCHPAD}=="1", ATTRS{name}=="bcm5974", ENV{POWERD_ROLE}="internal_touchpad"
EOF
fi
echo; echo "Leave selinux on enforcing? (Won't break SafetyNet without developer mode, but might cause issues with android apps)"
echo "Answer no if unsure (y/n)"
read_choice
if [ "$choice" = false ]; then sed '0,/enforcing/s/enforcing/permissive/' -i /home/chronos/local/etc/selinux/config; fi
#Fix for TPM2 images (must pass third parameter) (TPM replacement method)
if [ "$flag_tpm1" = true ]; then
#Remove TPM 2.0 services
rm -rf /home/chronos/local/etc/init/{attestationd,cr50-metrics,cr50-result,cr50-update,tpm_managerd,trunksd,u2fd}.conf
#Copy TPM 1.2 file from tpm1image
echo "Copying TPM 1.2 files..."
cp -a /home/chronos/tpm1image/etc/init/{chapsd,cryptohomed,cryptohomed-client,tcsd,tpm-probe}.conf /home/chronos/local/etc/init/
cp -a /home/chronos/tpm1image/etc/tcsd.conf /home/chronos/local/etc/
cp -a /home/chronos/tpm1image/usr/bin/{tpmc,chaps_client} /home/chronos/local/usr/bin/
cp -a /home/chronos/tpm1image/usr/lib64/libtspi.so{,.1{,.2.0}} /home/chronos/local/usr/lib64/
cp -a /home/chronos/tpm1image/usr/sbin/{chapsd,cryptohome,cryptohomed,cryptohome-path,tcsd} /home/chronos/local/usr/sbin/
cp -a /home/chronos/tpm1image/usr/share/cros/init/{tcsd-pre-start,chapsd}.sh /home/chronos/local/usr/share/cros/init/
cp -a /home/chronos/tpm1image/etc/dbus-1/system.d/{Cryptohome,org.chromium.Chaps}.conf /home/chronos/local/etc/dbus-1/system.d/
if [ ! -f /home/chronos/local/usr/lib64/libecryptfs.so ] && [ -f /home/chronos/tpm1image/usr/lib64/libecryptfs.so ]; then
cp -a /home/chronos/tpm1image/usr/lib64/libecryptfs* /home/chronos/local/usr/lib64/
cp -a /home/chronos/tpm1image/usr/lib64/ecryptfs /home/chronos/local/usr/lib64/
fi
#Add tss user and group
echo 'tss:!:207:root,chaps,attestation,tpm_manager,trunks,bootlockboxd' | tee -a /home/chronos/local/etc/group
echo 'tss:!:207:207:trousers, TPM and TSS operations:/var/lib/tpm:/bin/false' | tee -a /home/chronos/local/etc/passwd
umount /home/chronos/tpm1image
fi
#Fix for TPM2 images (must pass third parameter) (TPM emulation method)
if [ "$flag_vtpm" = true ]; then
echo "Copying TPM 2 emulator..."
cp -a /home/chronos/RAW/swtpm/usr/sbin/* /home/chronos/local/usr/sbin
cp -a /home/chronos/RAW/swtpm/usr/lib64/* /home/chronos/local/usr/lib64
cd /home/chronos/local/usr/lib64
ln -s libswtpm_libtpms.so.0.0.0 libswtpm_libtpms.so.0
ln -s libswtpm_libtpms.so.0 libswtpm_libtpms.so
ln -s libtpms.so.0.6.0 libtpms.so.0
ln -s libtpms.so.0 libtpms.so
ln -s libtpm_unseal.so.1.0.0 libtpm_unseal.so.1
ln -s libtpm_unseal.so.1 libtpm_unseal.so
cat >/home/chronos/local/etc/init/_vtpm.conf <<EOL
start on started boot-services
script
mkdir -p /var/lib/trunks
modprobe tpm_vtpm_proxy
swtpm chardev --vtpm-proxy --tpm2 --tpmstate dir=/var/lib/trunks --ctrl type=tcp,port=10001
swtpm_ioctl --tcp :10001 -i
end script
EOL
fi
#Fix ChromeOS installer (Automatically skip postinstall and fix UUIDs)
read -r -d '' CHROMEOS_INSTALL_FIX_GRUB <<'EOF'
do_post_install; sync; cleanup; trap - EXIT
echo; echo "Changing GRUB UUIDs..."; umount /home/chronos/local 2>/dev/null; mkdir -p /home/chronos/local 2>/dev/null;SRC="${SRC}";DST="${DST}"
SRC_EFIPART=`flock "${SRC}" sfdisk -lq "${SRC}" 2>/dev/null | grep "^""${SRC}""[^:]" | awk '{print $1}' | grep [^0-9]12$`
EFIPART=`flock "${DST}" sfdisk -lq "${DST}" 2>/dev/null | grep "^""${DST}""[^:]" | awk '{print $1}' | grep [^0-9]12$`
dd if="${SRC_EFIPART}" of="${EFIPART}" bs=4k status=progress
mount "$EFIPART" /home/chronos/local 2>/dev/null
OLD_UUID=`cat /home/chronos/local/efi/boot/grub.cfg | grep -m 1 "PARTUUID=" | awk -v FS="(PARTUUID=)" '{print $2}' | awk '{print $1}'`
OLD_UUID_LEGACY=`cat /home/chronos/local/syslinux/usb.A.cfg | grep -m 1 "PARTUUID=" | awk -v FS="(PARTUUID=)" '{print $2}' | awk '{print $1}'`
PARTUUID=`flock "${DST}" sfdisk --part-uuid "${DST}" 3`; sed -i "s/$OLD_UUID/$PARTUUID/" /home/chronos/local/efi/boot/grub.cfg
sed -i "s/$OLD_UUID_LEGACY/$PARTUUID/" /home/chronos/local/syslinux/usb.A.cfg
sync; umount /home/chronos/local 2>/dev/null; rmdir /home/chronos/local 2>/dev/null
echo "EFI: Partition UUID $OLD_UUID changed to $PARTUUID"; echo "Legacy: Partition UUID $OLD_UUID_LEGACY changed to $PARTUUID"; echo
EOF
CHROMEOS_INSTALL_FIX_GRUB="${CHROMEOS_INSTALL_FIX_GRUB//\\/\\\\}"
CHROMEOS_INSTALL_FIX_GRUB="${CHROMEOS_INSTALL_FIX_GRUB//$'\n'/\\n}"
sed -i 's/DEFINE_boolean skip_postinstall ${FLAGS_FALSE}/DEFINE_boolean skip_postinstall ${FLAGS_TRUE}/g' /home/chronos/local/usr/sbin/chromeos-install
sed -i "s/^[ \t]*do_post_install[ \t]*\$/${CHROMEOS_INSTALL_FIX_GRUB////\\/}/g" /home/chronos/local/usr/sbin/chromeos-install
#Fix write_gpt.sh to create an ESP that's big enough
tmp_esp_size="$(grep 'PARTITION_SIZE_EFI_SYSTEM' /home/chronos/local/usr/sbin/write_gpt.sh|tail -n1)"
esp_size="${tmp_esp_size#*=}"
sed -i "s/$esp_size/536870912/g" /home/chronos/local/usr/sbin/write_gpt.sh
#Expose the internal camera to android container
internal_camera=`dmesg | grep uvcvideo -m 1 | awk -F '[()]' '{print $2}'`
original_camera=`sed -nr 's,^camera0.module0.usb_vid_pid=(.*),\1,p' /home/chronos/local/etc/camera/camera_characteristics.conf`
if [ ! -z $internal_camera ] && [ ! -z $original_camera ]
then
sudo sed -i -e "s/${original_camera%:*}/${internal_camera%:*}/" -e "s/${original_camera##*:}/${internal_camera##*:}/" /home/chronos/local/lib/udev/rules.d/50-camera.rules
sudo sed -i "s/$original_camera/$internal_camera/" /home/chronos/local/etc/camera/camera_characteristics.conf
fi
cleanup_chromefy
echo
if [ "$flag_image" = false ]; then
echo "ChromeOS installed, you can now reboot"
else
echo "ChromeOS image created: this is for personal use only, distribute at your own risk"
fi