oem-factory-reset: Improve prompt flow formatting flash drive

Combine prompt to disconnect other devices with prompt to connect the
desired device.

Show block device sizes in MB/GB when selecting device so it is easier
to select.  file_selector now supports --show-size to include block
device sizes in menu.

Rework file_selector so menu options can contain spaces (use bash
array) and to simplify logic.

Prompt to select flash drive and LUKS percentage in OEM reset before
actually taking any actions, so aborting doesn't half-reset the system.

Abort OEM reset if user aborts the flash drive selection instead of
looping forever.  (Canceling the confirmation still loops to retry but
it is possible to exit by aborting the repeated menu.)

Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
This commit is contained in:
Jonathon Hall 2023-11-13 13:54:37 -05:00
parent e924a8afca
commit a925219efb
No known key found for this signature in database
GPG Key ID: 1E9C3CA91AE25114
2 changed files with 138 additions and 91 deletions

View File

@ -307,22 +307,12 @@ keytocard_subkeys_to_smartcard() {
TRACE "oem-factory-reset:keytocard_subkeys_to_smartcard done" TRACE "oem-factory-reset:keytocard_subkeys_to_smartcard done"
} }
#Whiptail prompt to disconnect any external USB storage device
prompt_disconnect_external_USB_storage_device() {
TRACE "Under oem-factory-reset:disconnect_external_USB_storage_device"
#Whiptail $BG_COLOR_WARNING warning about removing any external USB storage device currently connected
whiptail $BG_COLOR_WARNING --title 'WARNING: Please disconnect any external USB storage device' \
--msgbox "An external USB storage device will be WIPED next.\n\nPlease disconnect all external USB storage devices." 0 80 ||
die "Error displaying warning about removing any external USB storage device currently connected"
}
#Whiptail prompt to insert to be wiped thumb drive #Whiptail prompt to insert to be wiped thumb drive
prompt_insert_to_be_wiped_thumb_drive() { prompt_insert_to_be_wiped_thumb_drive() {
TRACE "Under oem-factory-reset:prompt_insert_to_be_wiped_thumb_drive" TRACE "Under oem-factory-reset:prompt_insert_to_be_wiped_thumb_drive"
#Whiptail warning about having only desired to be wiped thumb drive inserted #Whiptail warning about having only desired to be wiped thumb drive inserted
whiptail $BG_COLOR_WARNING --title 'WARNING: Please insert the thumb drive to be wiped' \ whiptail $BG_COLOR_WARNING --title 'WARNING: Please insert the thumb drive to be wiped' \
--msgbox "The thumb drive will be WIPED next.\n\nPlease have connected only the thumb drive to be wiped." 0 80 || --msgbox "The thumb drive will be WIPED next.\n\nPlease connect only the thumb drive to be wiped and disconnect others." 0 80 ||
die "Error displaying warning about having only desired to be wiped thumb drive inserted" die "Error displaying warning about having only desired to be wiped thumb drive inserted"
} }
@ -412,10 +402,13 @@ export_public_key_to_thumbdrive_public_partition() {
TRACE "oem-factory-reset:export_public_key_to_thumbdrive_public_partition done" TRACE "oem-factory-reset:export_public_key_to_thumbdrive_public_partition done"
} }
#Wipe a thumb drive and export master key and subkeys to it # Select thumb drive and LUKS container size for GPG key export
wipe_thumb_drive_and_copy_gpg_key_material() { # Sets variables containing selections:
# - thumb_drive
# - thumb_drive_luks_percent
select_thumb_drive_for_key_material() {
TRACE "Under oem-factory-reset:wipe_thumb_drive_and_copy_gpg_key_material" TRACE "Under oem-factory-reset:wipe_thumb_drive_and_copy_gpg_key_material"
prompt_disconnect_external_USB_storage_device
#enable usb storage #enable usb storage
enable_usb enable_usb
enable_usb_storage enable_usb_storage
@ -426,33 +419,25 @@ wipe_thumb_drive_and_copy_gpg_key_material() {
prompt_insert_to_be_wiped_thumb_drive prompt_insert_to_be_wiped_thumb_drive
#list usb storage devices #list usb storage devices
list_usb_storage disks >/tmp/usb_disk_list list_usb_storage disks >/tmp/usb_disk_list
if [ $(cat /tmp/usb_disk_list | wc -l) -gt 0 ]; then # Abort if:
file_selector "/tmp/usb_disk_list" "Select USB device to partition" # - no disks found (prevent file_selector's nonsense prompt)
if [ "$FILE" == "" ]; then # - file_selector fails for any reason
#No USB storage device selected # - user aborts (file_selector succeeds but FILE is empty)
warn "No USB storage device selected!" if [ $(cat /tmp/usb_disk_list | wc -l) -gt 0 ] &&
else file_selector --show-size "/tmp/usb_disk_list" "Select USB device to partition" &&
[ -n "$FILE" ]; then
# Obtain size of thumb drive to be wiped with fdisk # Obtain size of thumb drive to be wiped with fdisk
disk_size_bytes="$(blockdev --getsize64 "$FILE")" disk_size_bytes="$(blockdev --getsize64 "$FILE")"
#Convert disk size to GB if [ "$disk_size_bytes" -lt "$((128*1024*1024))" ]; then
thumb_drive_size_mb=$((disk_size_bytes / 1024 / 1024))
thumb_drive_size_gb=$((thumb_drive_size_mb / 1024 ))
#if thumb_drive_size_gb is 0, then disk size is less than 1GB
thumb_drive_size_message=""
if [ "$thumb_drive_size_gb" -eq 0 ]; then
thumb_drive_size_message="$thumb_drive_size_mb MB"
if [ "$thumb_drive_size_mb" -lt 128 ]; then
warn "Thumb drive size is less than 128MB!" warn "Thumb drive size is less than 128MB!"
warn "LUKS container needs to be at least 8mb!" warn "LUKS container needs to be at least 8MB!"
warn "If the next operation fails, try with a bigger thumb drive" warn "If the next operation fails, try with a bigger thumb drive"
fi fi
else
thumb_drive_size_message="$thumb_drive_size_gb GB"
fi
thumb_drive_size_message="$(display_size "$disk_size_bytes")"
# confirm with user size of thumb drive to be wiped # confirm with user size of thumb drive to be wiped
whiptail --title "Confirm thumb drive to be wiped" --yesno "Are you sure you want to wipe the following thumb drive?\n\n$FILE\n\nSize: $thumb_drive_size_message" 0 0 whiptail --title "Confirm thumb drive to be wiped" --yesno \
"Are you sure you want to wipe the following thumb drive?\n\n$FILE\n\nSize: $thumb_drive_size_message" 0 0
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
warn "Thumb drive wipe aborted by user!" warn "Thumb drive wipe aborted by user!"
continue continue
@ -460,7 +445,6 @@ wipe_thumb_drive_and_copy_gpg_key_material() {
#User chose and confirmed a thumb drive and its size to be wiped #User chose and confirmed a thumb drive and its size to be wiped
thumb_drive=$FILE thumb_drive=$FILE
fi
else else
#No USB storage device detected #No USB storage device detected
warn "No USB storage device detected! Aborting OEM Factory Reset / Re-Ownership" warn "No USB storage device detected! Aborting OEM Factory Reset / Re-Ownership"
@ -470,8 +454,21 @@ wipe_thumb_drive_and_copy_gpg_key_material() {
done done
select_luks_container_size_percent select_luks_container_size_percent
thumb_drive_luks_percent="$(cat /tmp/luks_container_size_percent)"
}
#Wipe a thumb drive and export master key and subkeys to it
# $1 - thumb drive block device
# $2 - LUKS container percentage [1-99]
wipe_thumb_drive_and_copy_gpg_key_material() {
TRACE "Under oem-factory-reset:wipe_thumb_drive_and_copy_gpg_key_material"
local thumb_drive thumb_drive_luks_percent
thumb_drive="$1"
thumb_drive_luks_percent="$2"
#Wipe thumb drive with a LUKS container of size $(cat /tmp/luks_container_size_percent) #Wipe thumb drive with a LUKS container of size $(cat /tmp/luks_container_size_percent)
prepare_thumb_drive --device "$thumb_drive" --percentage "$(cat /tmp/luks_container_size_percent)" --pass "${ADMIN_PIN}" prepare_thumb_drive --device "$thumb_drive" --percentage "$thumb_drive_luks_percent" --pass "${ADMIN_PIN}"
#Export master key and subkeys to thumb drive first partition #Export master key and subkeys to thumb drive first partition
export_master_key_subkeys_and_revocation_key_to_private_LUKS_container --mode rw --device "$thumb_drive"1 --mountpoint /media --pass "${ADMIN_PIN}" export_master_key_subkeys_and_revocation_key_to_private_LUKS_container --mode rw --device "$thumb_drive"1 --mountpoint /media --pass "${ADMIN_PIN}"
#Export public key to thumb drive's public partition #Export public key to thumb drive's public partition
@ -1068,6 +1065,10 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then
} }
done done
fi fi
if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then
select_thumb_drive_for_key_material
fi
fi fi
# If nothing is stored in custom variables, we set them to their defaults # If nothing is stored in custom variables, we set them to their defaults
@ -1184,7 +1185,7 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then
else else
die "Unsupported GPG_ALGO: $GPG_ALGO" die "Unsupported GPG_ALGO: $GPG_ALGO"
fi fi
wipe_thumb_drive_and_copy_gpg_key_material wipe_thumb_drive_and_copy_gpg_key_material "$thumb_drive" "$thumb_drive_luks_percent"
set_user_config "CONFIG_HAVE_GPG_KEY_BACKUP" "y" set_user_config "CONFIG_HAVE_GPG_KEY_BACKUP" "y"
if [ "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then if [ "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then
keytocard_subkeys_to_smartcard keytocard_subkeys_to_smartcard

View File

@ -34,54 +34,100 @@ mount_usb()
fi fi
} }
# Create display text for a size in bytes in either MB or GB, unit selected
# automatically, rounded to nearest
display_size() {
local size_bytes unit_divisor unit_symbol
size_bytes="$1"
# If it's less than 1 GB, display MB
if [ "$((size_bytes))" -lt "$((1024*1024*1024))" ]; then
unit_divisor=$((1024*1024))
unit_symbol="MB"
else
unit_divisor=$((1024*1024*1024))
unit_symbol="GB"
fi
# Divide by the unit divisor and round to nearest
echo "$(( (size_bytes + unit_divisor/2) / unit_divisor )) $unit_symbol"
}
# Create display text for the size of a block device using MB or GB, rounded to
# nearest
display_block_device_size() {
local block_dev disk_size_bytes
block_dev="$1"
# Obtain size of thumb drive to be wiped with fdisk
if ! disk_size_bytes="$(blockdev --getsize64 "$block_dev")"; then
exit 1
fi
display_size "$disk_size_bytes"
}
# Display a menu to select a file from a list. Pass the name of a file
# containing the list.
# --show-size: Append sizes of files listed. Currently only supports block
# devices.
# $1: Name of file listing files that can be chosen (one per line)
# $2: Optional prompt message
# $3: Optional prompt title
#
# Success: Sets FILE with the selected file
# User aborted: Exits successfully with FILE empty
# No entries in list: Displays error and exits unsuccessfully
file_selector() file_selector()
{ {
TRACE "under gui_functions:file_selector" TRACE "under gui_functions:file_selector"
local FILE_LIST MENU_MSG MENU_TITLE CHOICE_ARGS SHOW_SIZE OPTION_SIZE option_index
FILE="" FILE=""
if [ "$1" = "--show-size" ]; then
SHOW_SIZE=y
shift
fi
FILE_LIST=$1 FILE_LIST=$1
MENU_MSG=${2:-"Choose the file"} MENU_MSG=${2:-"Choose the file"}
MENU_TITLE=${3:-"Select your File"} MENU_TITLE=${3:-"Select your File"}
# create file menu options CHOICE_ARGS=()
if [ `cat "$FILE_LIST" | wc -l` -gt 0 ]; then
option=""
while [ -z "$option" ]
do
MENU_OPTIONS=""
n=0 n=0
while read option while read option; do
do n="$((++n))"
n=`expr $n + 1`
option=$(echo $option | tr " " "_")
MENU_OPTIONS="$MENU_OPTIONS $n ${option}"
done < $FILE_LIST
MENU_OPTIONS="$MENU_OPTIONS a Abort" if [ "$SHOW_SIZE" = "y" ] && OPTION_SIZE="$(display_block_device_size "$option")"; then
whiptail --title "${MENU_TITLE}" \ option="$option - $OPTION_SIZE"
--menu "${MENU_MSG} [1-$n, a to abort]:" 20 120 8 \
-- $MENU_OPTIONS \
2>/tmp/whiptail || die "Aborting"
option_index=$(cat /tmp/whiptail)
if [ "$option_index" = "a" ]; then
option="a"
return
fi fi
CHOICE_ARGS+=("$n" "$option")
done < "$FILE_LIST"
option=`head -n $option_index $FILE_LIST | tail -1` if [ "${#CHOICE_ARGS[@]}" -eq 0 ]; then
if [ "$option" == "a" ]; then
return
fi
done
if [ -n "$option" ]; then
FILE=$option
fi
else
whiptail $BG_COLOR_ERROR --title 'ERROR: No Files Found' \ whiptail $BG_COLOR_ERROR --title 'ERROR: No Files Found' \
--msgbox "No Files found matching the pattern. Aborting." 0 80 --msgbox "No Files found matching the pattern. Aborting." 0 80
exit 1 exit 1
fi fi
CHOICE_ARGS+=(a Abort)
# create file menu options
option_index=""
while [ -z "$option_index" ]; do
whiptail --title "${MENU_TITLE}" \
--menu "${MENU_MSG} [1-$n, a to abort]:" 20 120 8 \
-- "${CHOICE_ARGS[@]}" \
2>/tmp/whiptail || die "Aborting"
option_index=$(cat /tmp/whiptail)
if [ "$option_index" != "a" ]; then
FILE="$(head -n "$option_index" "$FILE_LIST" | tail -1)"
fi
done
} }
show_system_info() show_system_info()