#!/bin/sh

# This hook was based and adapted from:
# /usr/share/live/build/examples/hooks/all_chroot_losetup-lukshome.sh 
# part of DEBIAN package live-build (3.0~a51-1)
# based and adapted from:
# http://lists.debian.org/debian-live/2009/04/msg00186.html
# ---------------------------------------------------------
# NOTE: if using an USB key, it will eventualy end up failing someday.
# You should backup the encrypted disk image file itself (persistence) to
# prevent loosing your data.
#
# This hook will create 1 files:
#
# /usr/local/sbin/makePersistenceLuksEncryptedImage.sh
#       script to create an disk file image (persistence) with a
#       LUKS encrypted ext2 filesystem inside to be placed in a
#       arbitrary labeled partition.
#
# HOWTO
# -----
#
# First build your live system with this hook inside and the option 
# --bootappend-live "persistence persistence-encryption=luks,none
#
# After booting your (re)built live system, setup the encrypted losetup
# filesystem to be used as /home using the instructions present in the
# makePersistenceLuksEncryptedImage.sh script.
#
# Reboot and add the boot options ( if not set during build ) 
# "persistence persistence-encryption=luks,none" 

# install needed packages (in case apt recommends are off)
# make sure that cryptsetup is installed
echo "I: checking for cryptsetup."
if [ ! -x /sbin/cryptsetup ]
then
        echo "I: installing cryptsetup."
        apt-get install --yes --no-install-recommends cryptsetup
fi

echo "I: to see how to use this hook run makePersistenceLuksEncryptedImage.sh as root."
echo "I: creating script makePersistenceLuksEncryptedImage.sh"
cat > /usr/local/sbin/makePersistenceLuksEncryptedImage.sh << 'EOF'
#! /bin/bash
# This script will create an encrypted filesystem in a file to
# be used as persistence in a Debian live system 
#
# This script will only create the image file. Next are details of how
# to use this script.
#
# CAUTION! THIS CAN WIPE YOUR DATA, backup first!
# Be sure to understand what you will do, or you can end up
# wiping disks or partitions you don't want to!
#
# Login as root:
#       $ sudo -i
#
# Create a mountpoint (don't use /mnt, it will be used by this script):
#       # mkdir /media/target
#
# !!! ***  Skip the next line if you don't want to wipe a partition  *** !!!
# Create an ext2 filesystem in a partition with arbitrary label:
#       # mkfs.ext2 -L DEBIAN-HOME /dev/the_partition_to_be_used
#
# Mount the partition and cd into it:
#       # mount /dev/the_partition_to_be_used /media/target
#       # cd /media/target
#
# Create the encrypted file:
#       # makePersitenceLuksEncryptedImage.sh
#
# The script is located in /usr/local/sbin/, so it's in root $PATH.
# It will copy /home and create the file persistence.conf 
# into the image file.
# Now return to $HOME to be able to umount the target partition:
#       # cd
#
# Umount the target partition:
#       # umount /media/target
#
# Press Shift-PgUp/Shift-PgDn to scrool the instructions on the screen.
scriptfile=$_

# check if root/sudo
if [ "${USER}" != "root" ]
then
        echo " ** Please run this script as root or with sudo."
        exit 1
fi

# check if /mnt is available and empty
mount | grep "/mnt" > /dev/null
MNT_IS_MOUNTED=${?}
if [ "${MNT_IS_MOUNTED}" == 0 ]
then
        echo "** ERROR: /mnt is mounted at the moment. Please umount it to use this script."
        exit 1
fi
if [ "$(ls -A /mnt)" ]
then
        echo "** ERROR: /mnt is not empty. An empty /mnt is needed to use this script."
        exit 1
fi

# check if /dev/mapper/persistence is available
if [ -f /dev/mapper/persistence ]
then
        echo "** ERROR: /dev/mapper/persistence is being used at the moment. Please run «cryptsetup remove persistence» to use this script."
        exit 1
fi

# show instructions
echo ""
echo "** Instructions to use makePersistenceLuksEncyptedImage.sh (this script):"
sed -n '2,39p' $scriptfile | sed 's/^.//'
echo ""

# proceed?
echo "** Do you want to proceed with this script? (y/N)"
read CONFIRM

case "${CONFIRM}" in
        y*|Y*)
                echo ""
        ;;
        *)
                exit 0
        ;;
esac

# create file
echo ""
echo "** Please type the size of the file disk image."
echo "Size of the file in MB: "
read FILE_SIZE

echo ""
echo "** Creating image file persistence."
echo "** Filling file image with /dev/urandom output. It will take some time."
echo "(Edit this script to use /dev/random. It's known to be more secure but "
echo "it will take a *very* long time to complete."
dd if=/dev/urandom of=persistence bs=1M count=${FILE_SIZE}
# To use /dev/random comment the line above and uncomment the next line
#dd if=/dev/random of=luks-home.img ibs=128 obs=128 count=$((8192*${FILE_SIZE}))
# You might have to increase kernel entropy by moving the mouse, typing keyboard,
# make the computer read the disk or use network connections.
echo "** Done."
echo ""

# losetup
FREE_LOSETUP=$(losetup -f)
echo "** Using ${FREE_LOSETUP} to open persistence image"
losetup ${FREE_LOSETUP} ./persistence
echo "** Done."
echo ""

# cryptsetup
echo "** Running cryptsetup."
echo ""
echo "** luksFormat"
cryptsetup luksFormat ${FREE_LOSETUP}
EXIT_CODE=${?}
if [ "${EXIT_CODE}" != 0 ]
then
        echo "** ERROR: Error while trying to format disk file image."
        losetup -d ${FREE_LOSETUP}
        exit 1
fi
echo ""

echo "** luksOpen"
cryptsetup luksOpen ${FREE_LOSETUP} persistence
EXIT_CODE=${?}
if [ "${EXIT_CODE}" != 0 ]
then
        echo "** ERROR: Error while trying to open persistence file image."
        losetup -d ${FREE_LOSETUP}
        exit 1
fi
echo ""

# format encrypted filesystem
echo "** Now formating /dev/mapper/persistence"
mkfs.ext2 -L persistence /dev/mapper/persistence
EXIT_CODE=${?}
if [ "${EXIT_CODE}" != 0 ]
then
        echo "** ERROR: Error while trying to format LUKS file."
        cryptsetup remove persistence
        losetup -d ${FREE_LOSETUP}
        exit 1
fi
echo ""

# mount in /mnt
echo "** Now mounting persistence image in /mnt"
mount /dev/mapper/persistence /mnt
EXIT_CODE=${?}
if [ "${EXIT_CODE}" != 0 ]
then
        echo "** ERROR: Error while trying to mount image file in /mnt."
        umount /mnt
        cryptsetup remove persistence
        losetup -d ${FREE_LOSETUP}
        exit 1
fi
echo ""

# copy files
HOME_DIR="/home"

echo "** Copying ${HOME_DIR}."
# create file persistence.conf
echo "/home" > /mnt/persistence.conf
cp -rav ${HOME_DIR} /mnt
EXIT_CODE=${?}
if [ "${EXIT_CODE}" != 0 ]
then
        echo "** ERROR: Error while trying to copy files to /mnt."
        umount /mnt
        cryptsetup remove  persistence
        losetup -d ${FREE_LOSETUP}
        exit 1
fi
echo "** Done."
echo ""

echo "** All done."
echo "** Closing losetup, cryptsetup and mounted /mnt."
# umount and close
umount /mnt
cryptsetup remove persistence
losetup -d ${FREE_LOSETUP}
echo "** The luks-encrypted disk file image persistence is done and ready. **"
echo "** to use it reboot with boot options persistence persistence-encryption=luks,none" 
echo ""

EOF

chmod 0755 /usr/local/sbin/makePersistenceLuksEncryptedImage.sh
