#!/bin/sh # Boot from a local disk installation CONFIG_BOOT_GUI_MENU_NAME='Heads Boot Menu' . /etc/functions . /etc/config mount_boot() { # Mount local disk if it is not already mounted if ! grep -q /boot /proc/mounts ; then mount -o ro /boot \ || recovery "Unable to mount /boot" fi } last_half=X while true; do MAIN_MENU_OPTIONS="" unset totp_confirm # update the TOTP code every thirty seconds date=`date "+%Y-%m-%d %H:%M:%S"` seconds=`date "+%s"` half=`expr \( $seconds % 60 \) / 30` if [ "$CONFIG_TPM" = n ]; then TOTP="NO TPM" elif [ "$half" != "$last_half" ]; then last_half=$half; TOTP=`unseal-totp` if [ $? -ne 0 ]; then whiptail --clear --title "ERROR: TOTP Generation Failed!" \ --menu "ERROR: Heads couldn't generate the TOTP code.\n\nIf you have just reflashed your BIOS, you will need to generate a new TOTP secret.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?" 20 60 4 \ 'g' ' Generate new TOTP secret' \ 'i' ' Ignore error and continue to default boot menu' \ 'x' ' Exit to recovery shell' \ 2>/tmp/whiptail || recovery "GUI menu failed" totp_confirm=$(cat /tmp/whiptail) fi fi if [ "$totp_confirm" = "i" -o -z "$totp_confirm" ]; then whiptail --clear --title "$CONFIG_BOOT_GUI_MENU_NAME" \ --menu "$date\nTOTP code: $TOTP" 20 60 8 \ 'y' ' Default boot' \ 'r' ' TOTP does not match, refresh code' \ 'n' ' TOTP does not match after refresh, troubleshoot' \ 'm' ' Show OS boot menu' \ 'u' ' USB boot' \ 'g' ' Generate new TOTP secret' \ 'x' ' Exit to recovery shell' \ 2>/tmp/whiptail || recovery "GUI menu failed" totp_confirm=$(cat /tmp/whiptail) fi if [ "$totp_confirm" = "x" ]; then recovery "User requested recovery shell" fi if [ "$totp_confirm" = "r" ]; then continue fi if [ "$totp_confirm" = "n" ]; then if (whiptail --title "TOTP code mismatched" \ --yesno "TOTP code mismatches could indicate either TPM tampering or clock drift:\n\nTo correct clock drift: 'date -s HH:MM:SS'\nand save it to the RTC: 'hwclock -w'\nthen reboot and try again.\n\nWould you like to exit to a recovery console?" 30 60) then echo "" echo "To correct clock drift: 'date -s HH:MM:SS'" echo "and save it to the RTC: 'hwclock -w'" echo "then reboot and try again" echo "" recovery "TOTP mismatch" else continue fi fi if [ "$totp_confirm" = "u" ]; then exec /bin/usb-init continue fi if [ "$totp_confirm" = "g" ]; then if (whiptail --title 'Generate new TOTP secret' \ --yesno "This will erase your old secret and replace it with a new one!\n\nDo you want to proceed?" 16 60) then echo "Scan the QR code to add the new TOTP secret" /bin/seal-totp echo "Once you have scanned the QR code, hit Enter to reboot" read /bin/reboot else echo "Returning to the main menu" fi continue fi if [ "$totp_confirm" = "m" ]; then # Try to select a kernel from the menu mount_boot kexec-select-boot -m -b /boot -c "grub.cfg" -g continue fi if [ "$totp_confirm" = "y" -o -n "$totp_confirm" ]; then # Try to boot the default mount_boot DEFAULT_FILE=`find /boot/kexec_default.*.txt 2>/dev/null | head -1` if [ -r "$DEFAULT_FILE" ]; then kexec-select-boot -b /boot -c "grub.cfg" \ || recovery "Failed default boot" else if (whiptail --title 'No Default Boot Option Configured' \ --yesno "There is no default boot option configured yet. Would you like to load a menu of boot options? Otherwise you will return to the main menu." 16 60) then kexec-select-boot -m -b /boot -c "grub.cfg" -g else echo "Returning to the main menu" fi continue fi fi done recovery "Something failed during boot"