#!/bin/bash
#
# This is an sdm plugin for: cryptroot
#
# The plugin is called three times: for Phase 0, Phase 1, and post-install.
#

function loadparams() {
    source $SDMPT/etc/sdm/sdm-readparams
}

function converty() {
    [ -v noauto ] && noauto=y
    [ -v nopwd ] && nopwd=y
    [ -v ssh ] && ssh=y
    [ -v sshbash ] && sshbash=y
    [ -v uniquesshkey ] && unisquesshkey=y
}

# $1 is the phase: "0", "1", or "post-install"
# $2 is the argument list: arg1=val1|arg2=val2|arg3=val3| ...
#
# Main code for the Plugin
#
phase=$1
pfx="$(basename $0)"     #For messages
args="$2"
loadparams
vldargs="|authkeys|crypto|dns|gateway|ihostname|ipaddr|keyfile|netmask|mapper|ssh|sshbash|sshport|sshtimeout|uniquesshkey|noauto|nopwd|"
rqdargs=""                   # |list|of|required|args|or|nullstring|
assetdir="$SDMPT/etc/sdm/assets/$pfx"

if [ "$phase" == "0" ]
then
    #
    # In Phase 0 all references to directories in the image must be preceded by $SDMPT
    #
    logtoboth "* Plugin $pfx: Start Phase 0"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs" || exit
    plugin_printkeys
    converty
    mkdir -p $assetdir
    if [ "$authkeys" != "" ]
    then
	if [ -f $authkeys ]
	then
	    logtoboth "> Plugin $pfx: Copy authkeys file '$authkeys' to $assetdir"
	    cp -a $authkeys $assetdir
	else
	    logtobothex "? Plugin $pfx: authkeys file '$authkeys' not found"
	fi
    else
	[ "$ssh" == "y" ] && logtobothex "? Plugin $pfx: 'ssh' requires 'authkeys'"
    fi
    if [ "$keyfile" != "" ]
    then
	[ -f $keyfile ] || logtobothex "? Plugin $pfx: keyfile '$keyfile' not found"
	logtoboth "> Plugin $pfx: Save keyfile to /etc/sdm/assets/cryptroot (deleted later)"
	cp $keyfile $assetdir
    else
	[ "$nopwd" == "y" ] && logtobothex "? Plugin $pfx: 'nopwd' requires 'keyfile'"
    fi
    if [ "$crypto" != "" ]
    then
	[[ "aes|xchacha" =~ "$crypto" ]] || [[ "$crypto" =~ "aes-" ]] || logtobothex "? Plugin $pfx: Supported cryptos: aes and xchacha"
    fi
    logtoboth "* Plugin $pfx: Complete Phase 0"
elif [ "$phase" == "1" ]
then
    #
    # Phase 1 (in nspawn)
    #
    logtoboth "* Plugin $pfx: Start Phase 1"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs"
    converty
    [ "$mappername" == "" ] && mappername="cryptroot"
    [ "$crypto" == "" ] && xcrypto="aes" || xcrypto=$crypto
    logtoboth "> Plugin $pfx: Copy sdm-cryptconfig and sdmcryptfs to /usr/local/bin"
    cp -a $src/sdm-cryptconfig /usr/local/bin
    cp -a $src/sdmcryptfs /usr/local/bin
    # These are only for tracking, not used by sdm-cryptconfig
    [ "$keyfile" != "" ] && keyfile="$(basename $keyfile)"
    echo "$mappername" > $assetdir/mappername
    echo "$xcrypto" > $assetdir/sdmcrypto
    echo "$keyfile" > $assetdir/keyfile

    logtoboth "> Plugin $pfx: Install cryptsetup cryptsetup-initramfs cryptsetup-bin"
    installpkgsif "cryptsetup cryptsetup-initramfs cryptsetup-bin"
    logtoboth "> Plugin $pfx: Enable sdm automatic disk encryption configuration with crypto '$xcrypto'"
    osw="--mappername $mappername"
    [ "$authkeys" != "" ] && osw="${osw} --authorized-keys $assetdir/$(basename $authkeys)"
    [ "$crypto" != "" ] && osw="${osw} --crypto $xcrypto"
    [ "$dns" != "" ] && osw="${osw} --dns $dns"
    [ "$gateway" != "" ] && osw="${osw} --gateway $gateway"
    [ "$ihostname" != "" ] && osw="${osw} --hostname $ihostname"
    [ "$ipaddr" != "" ] && osw="${osw} --ipaddr $ipaddr"
    [ "$keyfile" != "" ] && osw="${osw} --keyfile $keyfile"
    [ "$netmask" != "" ] && osw="${osw} --netmask $netmask"
    [ "$nopwd" == "y" ] && osw="${osw} --nopwd"
    [ "$ssh" != "" ] && osw="${osw} --ssh"
    [ "$sshbash" != "" ] && osw="${osw} --sshbash"
    [ "$sshport" != "" ] && osw="${osw} --sshport $sshport"
    [ "$sshtimeout" != "" ] && osw="${osw} --sshtimeout $sshtimeout"
    [ "$uniquesshkey" == "y" ] && osw="${osw} --unique-ssh"
    [ "$noauto" == "y" ] && escript0=".099-enable-auto-encrypt.sh" || escript0="099-enable-auto-encrypt.sh"
    cat > /etc/sdm/0piboot/$escript0 <<EOF
#!/bin/bash
logger "sdm FirstBoot: Create automatic disk encryption service"
cat > /etc/systemd/system/sdm-auto-encrypt.service <<ZEOF
[Unit]
Description=sdm cryptroot automatic encryption
After=multi-user.target

[Service]
Type=simple
ExecStart=/usr/local/bin/sdm-cryptconfig --sdm $osw --reboot
#ExecStart=/usr/local/bin/sdm-cryptconfig --sdm $osw

[Install]
WantedBy=multi-user.target
ZEOF
systemctl enable sdm-auto-encrypt
EOF
    if [ -f /etc/sdm/assets/gfxbbh ]
    then
	logtoboth "> Plugin $pfx: Configure boot behavior for disk encryption"
	mv /etc/sdm/assets/gfxbbh /etc/sdm/assets/cryptbbh
	echo "B1" > /etc/sdm/assets/gfxbbh
    fi
    logtoboth "* Plugin $pfx: Complete Phase 1"
elif [ "$phase" == "post-install" ]
then
    #
    # Plugin Post-install edits
    #
    logtoboth "* Plugin $pfx: Start Phase post-install"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs"
    converty
    used1k=$(getfsdf "/" used) 
    usedby=$((used1k*1024))
    logtoboth ""
    logtoboth " * IMPORTANT"
    logtoboth "   * When the system boot process begins you will need a scratch disk larger than $(getgbstr $usedby)"
    logtoboth ""
    plugin_addnote ""
    plugin_addnote "*** cryptroot notes ***"
    plugin_addnote ""
    if [ "$noauto" != "y" ]
    then
	plugin_addnote "* Next steps"
	plugin_addnote "  * When the system initial boot process has completed, the sdm-auto-encrypt service will run"
	plugin_addnote "  * It will adjust the configuration for an encrypted rootfs and reboot the system"
	plugin_addnote "  * The system will start to reboot, but hang trying to read rootfs"
	plugin_addnote "    It will try 30 times before giving up and dropping to the initramfs prompt: (initramfs)"
	plugin_addnote ""
	plugin_addnote "  * Ignore the 'ALERT! missing /dev/mapper' message. That is expected."
	plugin_addnote ""
	plugin_addnote "  * Once at this prompt, connect the SSD or SD Card that will be used as a scratch drive"
	plugin_addnote "    and find the drive name"
	plugin_addnote ""
	plugin_addnote "  * When you have the drive name enter the command:"
	plugin_addnote "    (initramfs) sdmcryptfs sd /dev/sdX"
	plugin_addnote ""
	plugin_addnote "  * Where:"
	plugin_addnote ""
	plugin_addnote "      'sd' is the name of your system disk (typically /dev/mmcblk0,  /dev/sda, or /dev/nvme0n1)"
	plugin_addnote "      '/dev/sdX' is the name of your scratch disk"
	plugin_addnote ""
	plugin_addnote "  * sdmcryptfs will:"
	plugin_addnote "    * Shrink and then print the size of the rootfs"
	plugin_addnote "    * Save the contents of rootfs to /dev/sdX"
	plugin_addnote "    * Enable encryption on rootfs"
	plugin_addnote "      You will be prompted to enter YES (all in upper case) to continue"
	if [ "$nopwd" != "y" ]
	then
	    plugin_addnote "    * You will then be prompted to provide the passphrase for rootfs"
	    plugin_addnote "      ** Be sure that your CapsLock is set correctly (in case you changed it to type YES)!!! **"
	    plugin_addnote "      ** And remember your passphrase as it is not recoverable **"
	    plugin_addnote "    * After a short pause you'll be prompted for the passphrase again to unlock rootfs"
	else
	    plugin_addnote "    * The provided keyfile will be used to encrypt and unlock the rootfs"
	    plugin_addnote "      * There is no passphrase so ** DON'T LOSE your ENCRYPTION KEY **"
	fi
	plugin_addnote "    * The saved rootfs content will be restored from /dev/sdX to the encrypted rootfs"
	plugin_addnote "    * When the restore finishes sdmcryptfs will exit and drop you to the (initramfs) prompt"
	plugin_addnote "    * Type 'exit' to continue the boot sequence"
	plugin_addnote ""
	plugin_addnote "    * Once the system boots the sdm-cryptfs-cleanup service will run which:"
	plugin_addnote "      * Removes some one-time content and rebuilds initramfs"
	plugin_addnote "      * Reboots the system one last time"
	plugin_addnote ""
	if [ "$nopwd" != "y" ]
	then
	    plugin_addnote "    * On the way back up you'll once again be prompted for the rootfs passphrase (Without the 30 tries)"
	    plugin_addnote "    * The system will ask for the rootfs passphrase in this manner every time the system boots"
	fi
	if [[ "$ssh" == "y" ]] || [[ "$keyfile" == "y" ]]
	then
	    plugin_addnote ""
	    plugin_addnote "    NOTE: You have configured SSH or a LUKS encryption keyfile"
	    plugin_addnote "          Please review https://github.com/gitbls/sdm/blob/master/Docs/Disk-Encryption.md for important information"
	fi
	plugin_addnote ""
    else
	plugin_addnote " * Manual steps"
	plugin_addnote "   * After the system completes the sdm boot process, login and run sdm-cryptoconfig:"
	plugin_addnote "     (Before starting review the sdm-cryptconfig switches: sudo /usr/local/sdm/sdm-cryptconfig --help)"
	plugin_addnote "     bash$ sudo /usr/local/sdm/sdm-cryptoconfig"
	plugin_addnote "   * Reboot the system"
	plugin_addnote "   * After looking for the root device 30 times initramfs will prompt"
	plugin_addnote "   * Plug in your spare SSD/SD Card and notice its device name"
	plugin_addnote "   * Enter:"
	plugin_addnote "     (initramfs) sdmcryptfs sdname sparesd"
	plugin_addnote "       Examples:"
	plugin_addnote "           sdmcryptfs /dev/mmcblk0 /dev/sda"
	plugin_addnote "           sdmcryptfs /dev/sda /dev/sdb"
	plugin_addnote ""
	if [ "$nopwd" != "y" ]
	then
	    plugin_addnote "   * You will be prompted for the partition passphrase; ** Remember what you enter here **"
	fi
	plugin_addnote "   * Type 'exit' to exit initramfs and continue the system boot"
	plugin_addnote "   * After the system finishes booting the sdm-cryptfs-cleanup script will run"
	plugin_addnote "     This script removes some one-time content, rebuilds initramfs, and reboots one final time"
	if [ "$nopwd" != "y" ]
	then
	   plugin_addnote "   * Every time the system starts you'll be prompted for the rootfs partition passphrase"
	fi
	plugin_addnote ""
    fi
    logtoboth "* Plugin $pfx: Complete Phase post-install"
fi
