diff --git a/initrd/bin/gui-init b/initrd/bin/gui-init index 1ab178f38..d004a4e88 100755 --- a/initrd/bin/gui-init +++ b/initrd/bin/gui-init @@ -62,81 +62,6 @@ mount_boot() done } -verify_global_hashes() -{ - TRACE "Under /bin/gui-init:verify_global_hashes" - # Check the hashes of all the files, ignoring signatures for now - check_config /boot force - TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" - TMP_TREE_FILE="/tmp/kexec/kexec_tree.txt" - TMP_PACKAGE_TRIGGER_PRE="/tmp/kexec/kexec_package_trigger_pre.txt" - TMP_PACKAGE_TRIGGER_POST="/tmp/kexec/kexec_package_trigger_post.txt" - - if verify_checksums /boot ; then - return 0 - elif [[ ! -f "$TMP_HASH_FILE" || ! -f "$TMP_TREE_FILE" ]] ; then - if (whiptail $BG_COLOR_ERROR --title 'ERROR: Missing File!' \ - --yesno "One of the files containing integrity information for /boot is missing!\n\nIf you are setting up heads for the first time or upgrading from an\nolder version, select Yes to create the missing files.\n\nOtherwise this could indicate a compromise and you should select No to\nreturn to the main menu.\n\nWould you like to create the missing files now?" 0 80) then - if update_checksums ; then - BG_COLOR_MAIN_MENU="" - return 0; - else - whiptail $BG_COLOR_ERROR --title 'ERROR' \ - --msgbox "Failed to update checksums / sign default config" 0 80 - fi - fi - BG_COLOR_MAIN_MENU=$BG_COLOR_ERROR - return 1 - else - CHANGED_FILES=$(grep -v 'OK$' /tmp/hash_output | cut -f1 -d ':' | tee -a /tmp/hash_output_mismatches) - CHANGED_FILES_COUNT=$(wc -l /tmp/hash_output_mismatches | cut -f1 -d ' ') - - # if files changed before package manager started, show stern warning - if [ -f "$TMP_PACKAGE_TRIGGER_PRE" ]; then - PRE_CHANGED_FILES=$(grep '^CHANGED_FILES' $TMP_PACKAGE_TRIGGER_POST | cut -f 2 -d '=' | tr -d '"') - TEXT="The following files failed the verification process BEFORE package updates ran:\n${PRE_CHANGED_FILES}\n\nCompare against the files $CONFIG_BRAND_NAME has detected have changed:\n${CHANGED_FILES}\n\nThis could indicate a compromise!\n\nWould you like to update your checksums anyway?" - - # if files changed after package manager started, probably caused by package manager - elif [ -f "$TMP_PACKAGE_TRIGGER_POST" ]; then - LAST_PACKAGE_LIST=$(grep -E "^(Install|Remove|Upgrade|Reinstall):" $TMP_PACKAGE_TRIGGER_POST) - UPDATE_INITRAMFS_PACKAGE=$(grep '^UPDATE_INITRAMFS_PACKAGE' $TMP_PACKAGE_TRIGGER_POST | cut -f 2 -d '=' | tr -d '"') - - if [ "$UPDATE_INITRAMFS_PACKAGE" != "" ]; then - TEXT="The following files failed the verification process AFTER package updates ran:\n${CHANGED_FILES}\n\nThis is likely due to package triggers in$UPDATE_INITRAMFS_PACKAGE.\n\nYou will need to update your checksums for all files in /boot.\n\nWould you like to update your checksums now?" - else - TEXT="The following files failed the verification process AFTER package updates ran:\n${CHANGED_FILES}\n\nThis might be due to the following package updates:\n$LAST_PACKAGE_LIST.\n\nYou will need to update your checksums for all files in /boot.\n\nWould you like to update your checksums now?" - fi - - else - if [ $CHANGED_FILES_COUNT -gt 10 ]; then - # drop to console to show full file list - whiptail $ERROR_BG_COLOR --title 'ERROR: Boot Hash Mismatch' \ - --msgbox "${CHANGED_FILES_COUNT} files failed the verification process!\\n\nThis could indicate a compromise!\n\nHit OK to review the list of files.\n\nType \"q\" to exit the list and return." 0 80 - - echo "Type \"q\" to exit the list and return." >> /tmp/hash_output_mismatches - less /tmp/hash_output_mismatches - #move outdated hash mismatch list - mv /tmp/hash_output_mismatches /tmp/hash_output_mismatch_old - TEXT="Would you like to update your checksums now?" - else - TEXT="The following files failed the verification process:\n\n${CHANGED_FILES}\n\nThis could indicate a compromise!\n\nWould you like to update your checksums now?" - fi - fi - - if (whiptail $BG_COLOR_ERROR --title 'ERROR: Boot Hash Mismatch' --yesno "$TEXT" 0 80) then - if update_checksums ; then - BG_COLOR_MAIN_MENU="" - return 0; - else - whiptail $BG_COLOR_ERROR --title 'ERROR' \ - --msgbox "Failed to update checksums / sign default config" 0 80 - fi - fi - BG_COLOR_MAIN_MENU=$BG_COLOR_ERROR - return 1 - fi -} - prompt_update_checksums() { TRACE "Under /bin/gui-init:prompt_update_checksums" @@ -210,6 +135,10 @@ update_totp() DEBUG "Show PCRs" DEBUG "$(pcrs)" + #In all cases where TPM is involved in TOTP/HOTP secret unsealing errors + # Show global integrity report first to show also /boot integrity reports + report_integrity_measurements + whiptail $BG_COLOR_ERROR --title "ERROR: TOTP Generation Failed!" \ --menu " ERROR: $CONFIG_BRAND_NAME couldn't generate the TOTP code.\n If you have just completed a Factory Reset, or just reflashed @@ -225,7 +154,7 @@ update_totp() 2>/tmp/whiptail || recovery "GUI menu failed" option=$(cat /tmp/whiptail) - case "$option" in + case "$option" in g ) if (whiptail $BG_COLOR_WARNING --title 'Generate new TOTP/HOTP secret' \ --yesno "This will erase your old secret and replace it with a new one!\n\nDo you want to proceed?" 0 80) then @@ -431,6 +360,7 @@ show_options_menu() 'b' ' Boot Options -->' \ 't' ' TPM/TOTP/HOTP Options -->' \ 'u' ' Update checksums and sign all files in /boot' \ + 'v' ' Verify checksums and signed /boot files' \ 'c' ' Change configuration settings -->' \ 'f' ' Flash/Update the BIOS -->' \ 'g' ' GPG Options -->' \ @@ -453,6 +383,9 @@ show_options_menu() u ) prompt_update_checksums ;; + v ) + verify_global_hashes update + ;; c ) config-gui.sh ;; @@ -606,7 +539,7 @@ select_os_boot_option() { TRACE "Under /bin/gui-init:select_os_boot_option" mount_boot - if verify_global_hashes ; then + if verify_global_hashes update ; then kexec-select-boot -m -b /boot -c "grub.cfg" -g fi } @@ -616,7 +549,7 @@ attempt_default_boot() TRACE "Under /bin/gui-init:attempt_default_boot" mount_boot - if ! verify_global_hashes; then + if ! verify_global_hashes update; then return fi DEFAULT_FILE=`find /boot/kexec_default.*.txt 2>/dev/null | head -1` diff --git a/initrd/bin/kexec-seal-key b/initrd/bin/kexec-seal-key index fe36808c3..880fb072f 100755 --- a/initrd/bin/kexec-seal-key +++ b/initrd/bin/kexec-seal-key @@ -91,7 +91,7 @@ done # Remove all the old keys from slot 1 for dev in $(cat "$KEY_DEVICES" | cut -d\ -f1); do - echo "++++++ $dev: Removing old key slot 1" + echo "++++++ $dev: Removing $dev LUKS' old key slot 1 with provided passphrase" cryptsetup luksKillSlot \ --key-file "$RECOVERY_KEY" \ $dev 1 || @@ -102,7 +102,7 @@ for dev in $(cat "$KEY_DEVICES" | cut -d\ -f1); do --key-file "$RECOVERY_KEY" \ --key-slot 1 \ $dev "$KEY_FILE" || - die "$dev: Unable to add key to slot 1" + die "$dev: Unable to add key to $dev LUKS's slot 1 with provided passphrase" done # Now that we have setup the new keys, measure the PCRs diff --git a/initrd/bin/kexec-select-boot b/initrd/bin/kexec-select-boot index 1562638c1..dd3e13fb1 100755 --- a/initrd/bin/kexec-select-boot +++ b/initrd/bin/kexec-select-boot @@ -66,41 +66,6 @@ if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then fi fi -verify_global_hashes() -{ - echo "+++ Checking verified boot hash file " - # Check the hashes of all the files - if verify_checksums "$bootdir" "$gui_menu" ; then - echo "+++ Verified boot hashes " - valid_hash='y' - valid_global_hash='y' - else - if [ "$gui_menu" = "y" ]; then - CHANGED_FILES=$(grep -v 'OK$' /tmp/hash_output | cut -f1 -d ':') - whiptail $BG_COLOR_ERROR --title 'ERROR: Boot Hash Mismatch' \ - --msgbox "The following files failed the verification process:\n${CHANGED_FILES}\nExiting to a recovery shell" 0 80 - fi - die "$TMP_HASH_FILE: boot hash mismatch" - fi - # If user enables it, check root hashes before boot as well - if [[ "$CONFIG_ROOT_CHECK_AT_BOOT" = "y" && "$force_menu" == "n" ]]; then - if root-hashes-gui.sh -c; then - echo "+++ Verified root hashes, continuing boot " - # if user re-signs, it wipes out saved options, so scan the boot directory and generate - if [ ! -r "$TMP_MENU_FILE" ]; then - scan_options - fi - else - # root-hashes-gui.sh handles the GUI error menu, just die here - if [ "$gui_menu" = "y" ]; then - whiptail $BG_COLOR_ERROR --title 'ERROR: Root Hash Mismatch' \ - --msgbox "The root hash check failed!\nExiting to a recovery shell" 0 80 - fi - die "root hash mismatch, see /tmp/hash_output_mismatches for details" - fi - fi -} - verify_rollback_counter() { TPM_COUNTER=`grep counter $TMP_ROLLBACK_FILE | cut -d- -f2` diff --git a/initrd/bin/oem-factory-reset b/initrd/bin/oem-factory-reset index 731583477..16f523798 100755 --- a/initrd/bin/oem-factory-reset +++ b/initrd/bin/oem-factory-reset @@ -321,63 +321,6 @@ set_default_boot_option() || whiptail_error_die "Failed to create hashes of boot files" } -report_integrity_measurements() -{ - #check for GPG key in keyring - GPG_KEY_COUNT=`gpg -k 2>/dev/null | wc -l` - if [ $GPG_KEY_COUNT -ne 0 ]; then - # Check and report TOTP - # update the TOTP code every thirty seconds - date=`date "+%Y-%m-%d %H:%M:%S %Z"` - seconds=`date "+%s"` - half=`expr \( $seconds % 60 \) / 30` - if [ "$CONFIG_TPM" != "y" ]; then - TOTP="NO TPM" - elif [ "$half" != "$last_half" ]; then - last_half=$half; - TOTP=`unseal-totp` > /dev/null 2>&1 - fi - - # Check and report on HOTP status - if [ -x /bin/hotp_verification ]; then - HOTP=`unseal-hotp` > /dev/null 2>&1 - enable_usb - if ! hotp_verification info > /dev/null 2>&1 ; then - whiptail $CONFIG_WARNING_BG_COLOR --title 'WARNING: Please insert your HOTP enabled USB Security dongle' --msgbox "Your HOTP enabled USB Security dongle was not detected.\n\nPlease remove it and insert it again." 0 80 - fi - # Don't output HOTP codes to screen, so as to make replay attacks harder - hotp_verification check $HOTP - case "$?" in - 0 ) - HOTP="Success" - ;; - 4 ) - HOTP="Invalid code" - MAIN_MENU_BG_COLOR=$CONFIG_ERROR_BG_COLOR - ;; - * ) - HOTP="Error checking code, Insert USB Security dongle and retry" - MAIN_MENU_BG_COLOR=$CONFIG_WARNING_BG_COLOR - ;; - esac - else - HOTP='N/A' - fi - # Check for detached signed digest and report on /boot integrity status - check_config /boot force - TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" - - if ( cd /boot && sha256sum -c "$TMP_HASH_FILE" > /tmp/hash_output ); then - HASH="OK" - else - HASH="ALTERED" - fi - - #Show results - whiptail $MAIN_MENU_BG_COLOR --title "Measured Integrity Report" --msgbox "$date\nTOTP: $TOTP | HOTP: $HOTP\n/BOOT INTEGRITY: $HASH\n\nPress OK to continue or Ctrl+Alt+Delete to reboot" 0 80 - fi -} - usb_security_token_capabilities_check() { TRACE "Under /bin/oem-factory-reset:usb_security_token_capabilities_check" diff --git a/initrd/etc/ash_functions b/initrd/etc/ash_functions index 768d4627e..dd98370fd 100644 --- a/initrd/etc/ash_functions +++ b/initrd/etc/ash_functions @@ -4,49 +4,51 @@ # busybox ash on legacy-flash boards, and with bash on all other boards. die() { - if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then - echo " !!! ERROR: $* !!!" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; + if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then + echo " !!! ERROR: $* !!!" | tee -a /tmp/debug.log /dev/kmsg >/dev/null else - echo >&2 "!!! ERROR: $* !!!"; + echo >&2 "!!! ERROR: $* !!!" fi - sleep 2; - exit 1; + sleep 2 + exit 1 } warn() { - if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then - echo " *** WARNING: $* ***" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; + if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then + echo " *** WARNING: $* ***" | tee -a /tmp/debug.log /dev/kmsg >/dev/null else - echo >&2 " *** WARNING: $* ***"; + echo >&2 " *** WARNING: $* ***" fi - sleep 1; + sleep 1 } DEBUG() { - if [ "$CONFIG_DEBUG_OUTPUT" = "y" ];then - echo "DEBUG: $*" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; + if [ "$CONFIG_DEBUG_OUTPUT" = "y" ]; then + echo "DEBUG: $*" | while read line; do + echo "$line" | tee -a /tmp/debug.log /dev/kmsg >/dev/null + done fi } TRACE() { - if [ "$CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" = "y" ];then - echo "TRACE: $*" | tee -a /tmp/debug.log /dev/kmsg > /dev/null; + if [ "$CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT" = "y" ]; then + echo "TRACE: $*" | tee -a /tmp/debug.log /dev/kmsg >/dev/null fi } preserve_rom() { TRACE "Under /etc/ash_functions:preserve_rom" new_rom="$1" - old_files=`cbfs -t 50 -l 2>/dev/null | grep "^heads/"` + old_files=$(cbfs -t 50 -l 2>/dev/null | grep "^heads/") - for old_file in `echo $old_files`; do - new_file=`cbfs.sh -o $1 -l | grep -x $old_file` + for old_file in $(echo $old_files); do + new_file=$(cbfs.sh -o $1 -l | grep -x $old_file) if [ -z "$new_file" ]; then echo "+++ Adding $old_file to $1" - cbfs -t 50 -r $old_file >/tmp/rom.$$ \ - || die "Failed to read cbfs file from ROM" - cbfs.sh -o $1 -a $old_file -f /tmp/rom.$$ \ - || die "Failed to write cbfs file to new ROM file" + cbfs -t 50 -r $old_file >/tmp/rom.$$ || + die "Failed to read cbfs file from ROM" + cbfs.sh -o $1 -a $old_file -f /tmp/rom.$$ || + die "Failed to write cbfs file to new ROM file" fi done } @@ -59,7 +61,7 @@ recovery() { # but recreate the directory so that new tools can use it. #safe to always be true. Otherwise "set -e" would make it exit here - shred -n 10 -z -u /tmp/secret/* 2> /dev/null || true + shred -n 10 -z -u /tmp/secret/* 2>/dev/null || true rm -rf /tmp/secret mkdir -p /tmp/secret @@ -76,8 +78,7 @@ recovery() { sleep 5 /bin/reboot fi - while [ true ] - do + while [ true ]; do echo >&2 "!!!!! Starting recovery shell" sleep 1 @@ -97,49 +98,48 @@ pause_recovery() { combine_configs() { TRACE "Under /etc/ash_functions:combine_configs" - cat /etc/config* > /tmp/config + cat /etc/config* >/tmp/config } -enable_usb() -{ +enable_usb() { TRACE "Under /etc/ash_functions:enable_usb" - #insmod ehci_hcd prior of uhdc_hcd and ohci_hcd to suppress dmesg warning + #insmod ehci_hcd prior of uhdc_hcd and ohci_hcd to suppress dmesg warning if ! lsmod | grep -q ehci_hcd; then - insmod /lib/modules/ehci-hcd.ko \ - || die "ehci_hcd: module load failed" + insmod /lib/modules/ehci-hcd.ko || + die "ehci_hcd: module load failed" fi if [ "$CONFIG_LINUX_USB_COMPANION_CONTROLLER" = y ]; then if ! lsmod | grep -q uhci_hcd; then - insmod /lib/modules/uhci-hcd.ko \ - || die "uhci_hcd: module load failed" + insmod /lib/modules/uhci-hcd.ko || + die "uhci_hcd: module load failed" fi if ! lsmod | grep -q ohci_hcd; then - insmod /lib/modules/ohci-hcd.ko \ - || die "ohci_hcd: module load failed" + insmod /lib/modules/ohci-hcd.ko || + die "ohci_hcd: module load failed" fi if ! lsmod | grep -q ohci_pci; then - insmod /lib/modules/ohci-pci.ko \ - || die "ohci_pci: module load failed" + insmod /lib/modules/ohci-pci.ko || + die "ohci_pci: module load failed" fi fi if ! lsmod | grep -q ehci_pci; then - insmod /lib/modules/ehci-pci.ko \ - || die "ehci_pci: module load failed" + insmod /lib/modules/ehci-pci.ko || + die "ehci_pci: module load failed" fi if ! lsmod | grep -q xhci_hcd; then - insmod /lib/modules/xhci-hcd.ko \ - || die "xhci_hcd: module load failed" + insmod /lib/modules/xhci-hcd.ko || + die "xhci_hcd: module load failed" fi if ! lsmod | grep -q xhci_pci; then - insmod /lib/modules/xhci-pci.ko \ - || die "xhci_pci: module load failed" + insmod /lib/modules/xhci-pci.ko || + die "xhci_pci: module load failed" sleep 2 fi if [ "$CONFIG_USB_KEYBOARD" = y ]; then if ! lsmod | grep -q usbhid; then - insmod /lib/modules/usbhid.ko \ - || die "usbhid: module load failed" + insmod /lib/modules/usbhid.ko || + die "usbhid: module load failed" fi fi } diff --git a/initrd/etc/functions b/initrd/etc/functions index 2163587b2..61c992854 100755 --- a/initrd/etc/functions +++ b/initrd/etc/functions @@ -35,9 +35,9 @@ DO_WITH_DEBUG() { pcrs() { if [ "$CONFIG_TPM2_TOOLS" = "y" ]; then - tpm2 pcrread sha256 + tpm2 pcrread sha256 || die "tpm2 pcrread failed" elif [ "$CONFIG_TPM" = "y" ]; then - head -8 /sys/class/tpm/tpm0/pcrs + cat /sys/class/tpm/tpm0/pcrs fi } @@ -322,7 +322,8 @@ check_config() { if [ "$2" != "force" ]; then if ! sha256sum $(find $1/kexec*.txt) | gpgv $1/kexec.sig -; then - die 'Invalid signature on kexec boot params' + warn "Invalid signature on $1/boot/kexec*.txt files" + die "Please verify hashes/signatures or use call check_config $1 force to check hashes without signature" fi fi @@ -440,6 +441,177 @@ update_checksums() { return $rv } +# Verify the checksums of all the files in /boot, show discrepancies, and +# prompt the user to update the checksums if they are incorrect. +verify_global_hashes() { + TRACE "Under /etc/functions:verify_global_hashes" + + #Parameters: optional update flag + if [ "$1" = "update" ]; then + DEBUG "Caller requested update of checksums" + UPDATE="y" + UPDATE_TEXT="\n\nWould you like to update your checksums now?" + else + DEBUG "Caller did not request update of checksums" + UPDATE="n" + UPDATE_TEXT="" + fi + + # Check the hashes of all the files, ignoring signatures for now + check_config /boot force + TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" + TMP_TREE_FILE="/tmp/kexec/kexec_tree.txt" + TMP_PACKAGE_TRIGGER_PRE="/tmp/kexec/kexec_package_trigger_pre.txt" + TMP_PACKAGE_TRIGGER_POST="/tmp/kexec/kexec_package_trigger_post.txt" + + if verify_checksums /boot; then + return 0 + elif [[ ! -f "$TMP_HASH_FILE" || ! -f "$TMP_TREE_FILE" ]]; then + # No hashes found, prompt to create them + if (whiptail $BG_COLOR_ERROR --title 'ERROR: Missing File!' \ + --yesno "One of the files containing integrity information for /boot is missing!\n\nIf you are setting up heads for the first time or upgrading from an\nolder version, select Yes to create the missing files.\n\nOtherwise this could indicate a compromise and you should select No to\nreturn to the main menu.\n\nWould you like to create the missing files now?" 0 80); then + if update_checksums; then + BG_COLOR_MAIN_MENU="" + return 0 + else + whiptail $BG_COLOR_ERROR --title 'ERROR' \ + --msgbox "Failed to update checksums / sign default config" 0 80 + fi + fi + BG_COLOR_MAIN_MENU=$BG_COLOR_ERROR + return 1 + else + # Hashes found + CHANGED_FILES=$(grep -v 'OK$' /tmp/hash_output | cut -f1 -d ':' | tee -a /tmp/hash_output_mismatches) + CHANGED_FILES_COUNT=$(wc -l /tmp/hash_output_mismatches | cut -f1 -d ' ') + + # if files changed before package manager started, show stern warning + if [ -f "$TMP_PACKAGE_TRIGGER_PRE" ]; then + PRE_CHANGED_FILES=$(grep '^CHANGED_FILES' $TMP_PACKAGE_TRIGGER_POST | cut -f 2 -d '=' | tr -d '"') + TEXT="The following files failed the verification process BEFORE package updates ran:\n${PRE_CHANGED_FILES}\n\nCompare against the files $CONFIG_BRAND_NAME has detected have changed:\n${CHANGED_FILES}\n\nThis could indicate a compromise!" + TEXT+="$UPDATE_TEXT" + # if files changed after package manager started, probably caused by package manager + elif [ -f "$TMP_PACKAGE_TRIGGER_POST" ]; then + LAST_PACKAGE_LIST=$(grep -E "^(Install|Remove|Upgrade|Reinstall):" $TMP_PACKAGE_TRIGGER_POST) + UPDATE_INITRAMFS_PACKAGE=$(grep '^UPDATE_INITRAMFS_PACKAGE' $TMP_PACKAGE_TRIGGER_POST | cut -f 2 -d '=' | tr -d '"') + + if [ "$UPDATE_INITRAMFS_PACKAGE" != "" ]; then + TEXT="The following files failed the verification process AFTER package updates ran:\n${CHANGED_FILES}\n\nThis is likely due to package triggers in$UPDATE_INITRAMFS_PACKAGE.\n\nYou will need to update your checksums for all files in /boot." + TEXT+="$UPDATE_TEXT" + else + TEXT="The following files failed the verification process AFTER package updates ran:\n${CHANGED_FILES}\n\nThis might be due to the following package updates:\n$LAST_PACKAGE_LIST.\n\nYou will need to update your checksums for all files in /boot." + TEXT+="$UPDATE_TEXT" + fi + else + #Standard case for Heads without package manager involvement in /boot + if [ $CHANGED_FILES_COUNT -gt 10 ]; then + # drop to console to show full file list + whiptail $ERROR_BG_COLOR --title 'ERROR: Boot Hash Mismatch' \ + --msgbox "${CHANGED_FILES_COUNT} files failed the verification process!\\n\nThis could indicate a compromise!\n\nHit OK to review the list of files.\n\nType \"q\" to exit the list and return." 0 80 + + echo "Type \"q\" to exit the list and return." >>/tmp/hash_output_mismatches + less /tmp/hash_output_mismatches + #move outdated hash mismatch list + mv /tmp/hash_output_mismatches /tmp/hash_output_mismatch_old + TEXT="" + TEXT+="$UPDATE_TEXT" + else + # show list of files direcly + TEXT="The following files failed the verification process:\n\n${CHANGED_FILES}\n\nThis could indicate a compromise!" + TEXT+="$UPDATE_TEXT" + fi + fi + + # If update of checksum is not optionally selected, show stern warning + if [ "$UPDATE" == "n" ]; then + DEBUG "Checksums update not selected by caller, showing stern warning" + whiptail $BG_COLOR_ERROR --title 'ERROR: Boot Hash Mismatch' \ + --msgbox "$TEXT" 0 80 + BG_COLOR_MAIN_MENU=$BG_COLOR_ERROR + return 1 + else + DEBUG "Checksums update selected by caller, showing stern warning with option to update" + if (whiptail $BG_COLOR_ERROR --title 'ERROR: Boot Hash Mismatch' --yesno "$TEXT" 0 80); then + if update_checksums; then + BG_COLOR_MAIN_MENU="" + return 0 + else + whiptail $BG_COLOR_ERROR --title 'ERROR' \ + --msgbox "Failed to update checksums / sign default config" 0 80 + BG_COLOR_MAIN_MENU=$BG_COLOR_ERROR + return 1 + fi + fi + fi + fi +} + +report_integrity_measurements() { + #check for GPG key in keyring + GPG_KEY_COUNT=$(gpg -k 2>/dev/null | wc -l) + if [ $GPG_KEY_COUNT -ne 0 ]; then + # Check and report TOTP + # update the TOTP code every thirty seconds + date=$(date "+%Y-%m-%d %H:%M:%S %Z") + seconds=$(date "+%s") + half=$(expr \( $seconds % 60 \) / 30) + if [ "$CONFIG_TPM" != "y" ]; then + TOTP="NO TPM" + elif [ "$half" != "$last_half" ]; then + last_half=$half + TOTP=$(unseal-totp) >/dev/null 2>&1 || TOTP="TPM UNSEALING OF TOTP/HOTP SECRET FAILED" + fi + + # Check and report on HOTP status + if [ -x /bin/hotp_verification ]; then + HOTP=$(unseal-hotp) >/dev/null 2>&1 + enable_usb + while ! hotp_verification info >/dev/null 2>&1; do + whiptail $CONFIG_WARNING_BG_COLOR --title 'WARNING: Please insert your HOTP enabled USB Security dongle' --msgbox "Your HOTP enabled USB Security dongle was not detected.\n\nPlease remove it and insert it again." 0 80 + done + # Don't output HOTP codes to screen, so as to make replay attacks harder + hotp_verification check $HOTP + case "$?" in + 0) + HOTP="Success" + ;; + 4) + HOTP="Invalid code" + MAIN_MENU_BG_COLOR=$CONFIG_ERROR_BG_COLOR + ;; + *) + HOTP="HOTP VERIFICATION FAILED. Returned error: $?" + MAIN_MENU_BG_COLOR=$CONFIG_WARNING_BG_COLOR + ;; + esac + else + HOTP='N/A' + fi + # Check for detached signed digest and report on /boot integrity status + SIGNED="OK" + (check_config /boot) || SIGNED="ALTERED" + + TMP_HASH_FILE="/tmp/kexec/kexec_hashes.txt" + + if (cd /boot && sha256sum -c "$TMP_HASH_FILE" >/tmp/hash_output); then + HASH="OK" + else + HASH="ALTERED" + fi + + #Show results + + #If the system is in a bad state, show the user a warning + whiptail $MAIN_MENU_BG_COLOR --title "Measured Integrity Report" --msgbox "$date\n\nTOTP: $TOTP\nHOTP: $HOTP\nBOOT INTEGRITY SIGNATURE: $SIGNED\nBOOT INTEGRITY HASHES: $HASH\n\nPress OK to continue with detailed information in case of errors" 0 80 + + #Show the user the detailed information + if [ "$SIGNED" != "OK" ] || [ "$HASH" != "OK" ]; then + # Show the user the detailed information of /boot integrity status (without asking to update them) + verify_global_hashes + fi + fi +} + print_tree() { TRACE "Under /etc/functions:print_tree" find ./ ! -path './kexec*' -print0 | sort -z