Skip to content

Commit 86e12d1

Browse files
Add utility script to generate new filevault recovery key
1 parent 21feee5 commit 86e12d1

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

lib/filevault.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,46 @@ EOF
221221
fi
222222
}
223223

224+
generate_new_filevault_recovery_key () {
225+
local output
226+
local password
227+
local serial_num
228+
229+
quote_string_for_use_within_expect_tcl_script_double_quotes "$2" password
230+
231+
output=$(execute_sudo "expect" << EOF
232+
#since we use expect inside a bash-script, we have to escape tcl-$.
233+
set timeout 180
234+
spawn fdesetup changerecovery --user $1 -personal
235+
expect {
236+
-re "Enter the password for (the )?user '$1':" {
237+
send "$password\r"
238+
}
239+
default {
240+
exit 2
241+
}
242+
}
243+
expect {
244+
"Error: User authentication failed." {
245+
exit 1
246+
}
247+
"Please reboot to complete the process." {
248+
exit 0
249+
}
250+
}
251+
exit 0
252+
EOF
253+
)
254+
255+
if [[ $? -eq 0 ]]; then
256+
# retrieve and store recovery key
257+
serial_num=$(ioreg -l | awk -F'"' '/IOPlatformSerialNumber/{print $4}')
258+
echo "$output" | grep "New personal recovery key" | sed "s/New personal recovery key = '\(.*\)'/\1/" > "${SCRIPT_DIR}/${serial_num}_$(date +"%Y-%m-%d_%H:%M_%p")"
259+
else
260+
abort "There was a problem generating a new FileVault personal recovery key."
261+
fi
262+
}
263+
224264
get_account_with_filevault_permissions () {
225265
local _filevault_user=$1
226266
local _filevault_password=$2
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/env zsh
2+
#
3+
# This script performs the following tasks:
4+
# * prompt for current user password
5+
# * prompt user for Pre-Boot Authentication password
6+
# * grant current user privileges to unlock FileVault
7+
#
8+
# Copyright (c) 2025 Doug Campbell. All rights reserved.
9+
10+
SCRIPT_DIR=$( cd -- "$( dirname -- "${(%):-%x}" )" &> /dev/null && pwd )
11+
12+
. "${SCRIPT_DIR}/lib/config.sh"
13+
. "${SCRIPT_DIR}/lib/display.sh"
14+
. "${SCRIPT_DIR}/lib/filevault.sh"
15+
. "${SCRIPT_DIR}/lib/globals.sh"
16+
. "${SCRIPT_DIR}/lib/input.sh"
17+
. "${SCRIPT_DIR}/lib/logging.sh"
18+
. "${SCRIPT_DIR}/lib/preboot.sh"
19+
. "${SCRIPT_DIR}/lib/quoting.sh"
20+
. "${SCRIPT_DIR}/lib/system.sh"
21+
. "${SCRIPT_DIR}/lib/util.sh"
22+
23+
SCRIPT_USER=$(logname)
24+
25+
TRAPEXIT() {
26+
[[ $SUDO_INVALIDATE_ON_EXIT -eq 0 ]] && /usr/bin/sudo -k
27+
}
28+
29+
main () {
30+
prepare_display_environment
31+
check_run_command_as_root
32+
check_run_command_as_admin
33+
34+
# get script user password
35+
# note: we get this separately because we need to have sudo prior to attempting to verify
36+
# the remaining accounts just in case they are currently disabled.
37+
ohai 'Getting password for account currently running this script.'
38+
get_account_password_aux $SCRIPT_USER
39+
printf '\n'
40+
41+
get_sudo "${PASSWORDS[$SCRIPT_USER]}"
42+
43+
if is_account_exist "preboot"; then
44+
ohai 'Getting password for Pre-Boot Authentication account.'
45+
get_account_password_aux "preboot"
46+
printf "\n"
47+
48+
# add current user to FileVault (temporarily)
49+
enable_account "preboot"
50+
grant_account_filevault_access "$SCRIPT_USER" "${PASSWORDS[$SCRIPT_USER]}" "preboot" "${PASSWORDS[preboot]}"
51+
enable_secure_token_for_account "$SCRIPT_USER" "${PASSWORDS[$SCRIPT_USER]}" "preboot" "${PASSWORDS[preboot]}"
52+
disable_account "preboot"
53+
fi
54+
55+
generate_new_filevault_recovery_key "$SCRIPT_USER" "${PASSWORDS[$SCRIPT_USER]}"
56+
57+
if is_account_exist "preboot"; then
58+
# remove current user from FileVault
59+
get_sudo "${PASSWORDS[$SCRIPT_USER]}"
60+
remove_filevault_unlock_for_other_users
61+
fi
62+
63+
printf '\n'
64+
display_warning "A FileVault recovery key has been generatered and stored in the same folder as this script. The filename begins with this device's serial # "$(ioreg -l | awk -F'"' '/IOPlatformSerialNumber/{print $4}')"."
65+
printf '\n'
66+
display_message "Copy this file to a safe location (e.g. Google Drive) before proceeding."
67+
68+
printf '\n'
69+
read -s -k '?Press any key to continue.'
70+
printf '\n'
71+
72+
kill `ps -A | grep -w Terminal.app | grep -v grep | awk '{print $1}'`
73+
}
74+
75+
main "$@"
76+
77+
exit 0

0 commit comments

Comments
 (0)