Skip to content

Commit

Permalink
oem-factory-reset: Improve prompt flow formatting flash drive
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
JonathonHall-Purism committed Nov 13, 2023
1 parent e924a8a commit a925219
Show file tree
Hide file tree
Showing 2 changed files with 143 additions and 96 deletions.
101 changes: 51 additions & 50 deletions initrd/bin/oem-factory-reset
Original file line number Diff line number Diff line change
Expand Up @@ -307,22 +307,12 @@ keytocard_subkeys_to_smartcard() {
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
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 $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"
}

Expand Down Expand Up @@ -412,10 +402,13 @@ export_public_key_to_thumbdrive_public_partition() {
TRACE "oem-factory-reset:export_public_key_to_thumbdrive_public_partition done"
}

#Wipe a thumb drive and export master key and subkeys to it
wipe_thumb_drive_and_copy_gpg_key_material() {
# Select thumb drive and LUKS container size for GPG key export
# 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"
prompt_disconnect_external_USB_storage_device

#enable usb storage
enable_usb
enable_usb_storage
Expand All @@ -426,41 +419,32 @@ wipe_thumb_drive_and_copy_gpg_key_material() {
prompt_insert_to_be_wiped_thumb_drive
#list usb storage devices
list_usb_storage disks >/tmp/usb_disk_list
if [ $(cat /tmp/usb_disk_list | wc -l) -gt 0 ]; then
file_selector "/tmp/usb_disk_list" "Select USB device to partition"
if [ "$FILE" == "" ]; then
#No USB storage device selected
warn "No USB storage device selected!"
else
# Obtain size of thumb drive to be wiped with fdisk
disk_size_bytes="$(blockdev --getsize64 "$FILE")"
#Convert disk size to GB
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 "LUKS container needs to be at least 8mb!"
warn "If the next operation fails, try with a bigger thumb drive"
fi
else
thumb_drive_size_message="$thumb_drive_size_gb GB"
fi

# 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
if [ $? -ne 0 ]; then
warn "Thumb drive wipe aborted by user!"
continue
fi

#User chose and confirmed a thumb drive and its size to be wiped
thumb_drive=$FILE
# Abort if:
# - no disks found (prevent file_selector's nonsense prompt)
# - file_selector fails for any reason
# - user aborts (file_selector succeeds but FILE is empty)
if [ $(cat /tmp/usb_disk_list | wc -l) -gt 0 ] &&
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
disk_size_bytes="$(blockdev --getsize64 "$FILE")"
if [ "$disk_size_bytes" -lt "$((128*1024*1024))" ]; then
warn "Thumb drive size is less than 128MB!"
warn "LUKS container needs to be at least 8MB!"
warn "If the next operation fails, try with a bigger thumb drive"
fi

thumb_drive_size_message="$(display_size "$disk_size_bytes")"
# 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
if [ $? -ne 0 ]; then
warn "Thumb drive wipe aborted by user!"
continue
fi

#User chose and confirmed a thumb drive and its size to be wiped
thumb_drive=$FILE
else
#No USB storage device detected
warn "No USB storage device detected! Aborting OEM Factory Reset / Re-Ownership"
Expand All @@ -470,8 +454,21 @@ wipe_thumb_drive_and_copy_gpg_key_material() {
done

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)
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_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
Expand Down Expand Up @@ -1068,6 +1065,10 @@ if [ "$use_defaults" == "n" -o "$use_defaults" == "N" ]; then
}
done
fi

if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then
select_thumb_drive_for_key_material
fi
fi

# If nothing is stored in custom variables, we set them to their defaults
Expand Down Expand Up @@ -1184,7 +1185,7 @@ if [ "$GPG_GEN_KEY_IN_MEMORY" = "y" ]; then
else
die "Unsupported GPG_ALGO: $GPG_ALGO"
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"
if [ "$GPG_GEN_KEY_IN_MEMORY_COPY_TO_SMARTCARD" = "y" ]; then
keytocard_subkeys_to_smartcard
Expand Down
138 changes: 92 additions & 46 deletions initrd/etc/gui_functions
Original file line number Diff line number Diff line change
Expand Up @@ -34,54 +34,100 @@ mount_usb()
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()
{
TRACE "under gui_functions:file_selector"
FILE=""
FILE_LIST=$1
MENU_MSG=${2:-"Choose the file"}
MENU_TITLE=${3:-"Select your File"}

# create file menu options
if [ `cat "$FILE_LIST" | wc -l` -gt 0 ]; then
option=""
while [ -z "$option" ]
do
MENU_OPTIONS=""
n=0
while read option
do
n=`expr $n + 1`
option=$(echo $option | tr " " "_")
MENU_OPTIONS="$MENU_OPTIONS $n ${option}"
done < $FILE_LIST

MENU_OPTIONS="$MENU_OPTIONS a Abort"
whiptail --title "${MENU_TITLE}" \
--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

option=`head -n $option_index $FILE_LIST | tail -1`
if [ "$option" == "a" ]; then
return
fi
done
if [ -n "$option" ]; then
FILE=$option
fi
else
whiptail $BG_COLOR_ERROR --title 'ERROR: No Files Found' \
--msgbox "No Files found matching the pattern. Aborting." 0 80
exit 1
fi
TRACE "under gui_functions:file_selector"

local FILE_LIST MENU_MSG MENU_TITLE CHOICE_ARGS SHOW_SIZE OPTION_SIZE option_index

FILE=""

if [ "$1" = "--show-size" ]; then
SHOW_SIZE=y
shift
fi

FILE_LIST=$1
MENU_MSG=${2:-"Choose the file"}
MENU_TITLE=${3:-"Select your File"}

CHOICE_ARGS=()
n=0
while read option; do
n="$((++n))"

if [ "$SHOW_SIZE" = "y" ] && OPTION_SIZE="$(display_block_device_size "$option")"; then
option="$option - $OPTION_SIZE"
fi
CHOICE_ARGS+=("$n" "$option")
done < "$FILE_LIST"

if [ "${#CHOICE_ARGS[@]}" -eq 0 ]; then
whiptail $BG_COLOR_ERROR --title 'ERROR: No Files Found' \
--msgbox "No Files found matching the pattern. Aborting." 0 80
exit 1
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()
Expand Down

0 comments on commit a925219

Please sign in to comment.