#!/bin/bash # # Name: pam_panic_config # Description: Create a pam_panic configuration. # Author: Bandie # CONFIGFILE="/etc/pam.d/pampanic" LHBU="$HOME/LUKSHeaderBackup" # Set on build time SECUREDIR="__SECURELIBDIR__" if [ $EUID -ne 0 ]; then echo "Please run this script as root or using sudo." exit 1 fi # Call when using the Cancel button function cancel(){ rm -f .pam_panic_media_choice clear echo "Bye! :)" exit 0 } # Call when CTRL+C trap "cancel" INT # Check, if $1 is a gpt formatted device function checkGPT(){ blkid $1 -t PTTYPE=gpt >> /dev/null return $? } # Get the GPT PartitionUUID function getPARTUUID(){ blkid $1 | awk '{print $4;}' | sed 's/PARTUUID="//;s/"//' } # Get the LUKS-Device's UUId function getLUKSDevice(){ if [ "$1" = "UUID" ]; then blkid /dev/sda*[1-9] | grep "crypto_LUKS" | awk '{print $2;}' | sed 's/UUID="//;s/"//' fi if [ "$1" = "NAME" ]; then blkid /dev/sda*[1-9] | grep "crypto_LUKS" | awk '{print $1;}' | sed 's/://' fi } # Generic dialog question function ask(){ dialog --backtitle "pam_panic's Configuration Generator" --title "$1" --yesno "$2" 8 80 return $? } # Generic message box msg() { dialog --backtitle "pam_panic's Configuration Generator" --title "$1" --msgbox "$2" 8 80 } # Generate a two dimensional flat array of all GPT devices from sdb-sdz function getMediaDevice(){ local i=0 local uuid for dev in $(ls /dev/sd[b-z] 2> /dev/null); do if $(checkGPT $dev); then for part in $(ls $dev*[1-9]); do echo -n "$i $part[$(getPARTUUID $part)] " (( i++ )) done fi done } # Hint for GPT formatted key before searching for it function chooseMediumPre(){ local title="Removable media: $1 device" dialog --backtitle "pam_panic's Configuration Generator" --title "$title" --yes-label "OK" --no-label "Cancel" --yesno "Please remove all media devices before your continue.\nNote, if you device doesn't show up it might not be a GPT formatted device.\n\nPlease insert the device you want to use as $1 device and press OK." 10 80 if [ $? -eq 1 ]; then cancel fi } # Choosing a GPT formatted key function chooseMedium(){ local ans local title="Removable media: $1 device" dialog --backtitle "pam_panic's Configuration Generator" --title "$title" --menu "Choose your device:" 10 80 5 $media 2> .pam_panic_media_choice if [ $? -eq 1 ]; then cancel fi ans=$(cat .pam_panic_media_choice) (( ans=(2*ans)+1 )) rm -f .pam_panic_media_choice return $ans } # A "Detecting devices...", assures to use a more up to date device list function showDetectDev(){ dialog --backtitle "pam_panic's Configuration Generator" \ --title "$title" \ --infobox "Detecting devices..." 3 80 # Prevention for impatient beings sleep 2 } # Welcome dialog --backtitle "pam_panic's Configuration Generator" \ --title "Welcome" \ --ok-label "Yip!" \ --msgbox "Welcome to pam_panic's Configuration Generator.\n\nIt will help you to create a valid pam_panic setup. It will also generate a Linux' PAM configuration file.\n\nAfter you're done with this Configuration Generator, you will see some hints how to integrate the new PAM configuration file in your system." 20 80 # Authentication mode auth_mode=2 while [ $auth_mode -eq 2 ]; do dialog --backtitle "pam_panic's Configuration Generator" \ --title "Authentication mode" \ --help-button \ --extra-button --extra-label "Passwords" \ --ok-label "Removable Media" \ --yesno "You can choose between the \"two removable media\" option and the \"two passwords\" option.\nSee \"Help\" to learn what it is.\n\nRemovable media or passwords?" 10 80 auth_mode=$? case $auth_mode in "0") # Removable media # Authentication while [ -z $media ]; do chooseMediumPre Authentication showDetectDev media=$(getMediaDevice) read -r -a mediaArray <<< "$media" done chooseMedium Authentication auth_dev=$(echo ${mediaArray[$?]} | sed 's/\/dev\/sd[b-z]*[0-1]\[//;s/\]//') msg "Removable media: Authentication device" "Authentication device chosen with UUID $auth_dev." # Panic unset media while [ -z $media ]; do chooseMediumPre Panic showDetectDev media=$(getMediaDevice) read -r -a mediaArray <<< "$media" done chooseMedium Panic panic_dev=$(echo ${mediaArray[$?]} | sed 's/\/dev\/sd[b-z]*[0-1]\[//;s/\]//') msg "Removable media: Panic device" "Panic device chosen with UUID $panic_dev." ;; "3") # Passwords ask "Passwords" "Do you want to set the passwords now?" setpw=$? case $setpw in "0") clear pam_panic_pw if [ $? -ne 0 ]; then clear echo "Failed to set a password. :(" exit 1 fi ;; esac ;; "2") # Help man pam_panic ;; "1") # Cancel cancel ;; esac done # serious flag ask "pam_panic's behaviour" "Do you wish to destroy your LUKS header in case of emergency?\nThis means that your encrypted root device won't be readable anymore. After this question you will be asked to make a backup of this header." serious=$? if [ $serious -eq 0 ]; then serious_dev=$(getLUKSDevice UUID) if [ ! -z $serious_dev ]; then msg "pam_panic's behaviour" "We will destroy $(getLUKSDevice NAME) [$serious_dev] when you trigger the panic function." # LUKS header backup ask "LUKS Header backup" "Do you want to make a LUKS-Header backup now?\nIt will be saved at \"$LHBU\"." bu=$? case $bu in "0") cryptsetup luksHeaderBackup $(getLUKSDevice NAME) --header-backup-file "$LHBU" msg "LUKS Header backup" "LUKSHeader backup has been saved here: $LHBU" ;; esac else msg "pam_panic's behaviour" "ERROR: There is no encrypted root device on /dev/sda." serious=1 fi fi # poweroff / reboot behaviour dialog --backtitle "pam_panic's Configuration Generator" \ --title "pam_panic's behaviour" \ --ok-label "Reboot" \ --extra-button --extra-label "Shutdown" \ --cancel-label "Nothing" \ --yesno "Do you wish a reboot or a shutdown after issuing the panic function? n for nothing of those? " 10 80 power=$? # Configuration generation dialog --backtitle "pam_panic's Configuration Generator" \ --infobox "Generating configuration..." 3 40 config="#%PAM-1.0\nauth requisite $SECUREDIR/pam_panic.so" case $power in "0") config="$config reboot" ;; "3") config="$config poweroff" ;; esac case $auth_mode in "3") config="$config password" ;; "0") config="$config allow=$auth_dev reject=$panic_dev" ;; esac case $serious in "0") config="$config serious=$serious_dev" ;; esac config="$config\naccount requisite $SECUREDIR/pam_panic.so" # Write config file writeout=0 if [ -f $CONFIGFILE ]; then ask "Configfile exist" "$CONFIGFILE exists. Overwrite it?" writeout=$? case $writeout in "0") echo -e "$config" > $CONFIGFILE ;; esac else echo -e "$config" > $CONFIGFILE fi # Finished message clear [ $writeout -eq 0 ] && echo "Done! <3" || echo "Nothing done!