#! /bin/sh
set -e

# Set up encrypted swap using ecryptfs-setup-swap.
# 
# This duplicates some code from user-setup-apply, but this is necessary;
# this operation involves disabling swap, can't be done until after the user
# page (normally well after partitioning, but may be before partitioning in
# noninteractive installs), and must be done before the slideshow starts to
# avoid out-of-memory problems.
# 
# Fortunately, in some ways it's simpler to use tools in the live filesystem
# to do this!

. /usr/share/debconf/confmodule

db_get user-setup/encrypt-home
[ "$RET" = true ] || exit 0

if [ "$(grep -c "^/" /proc/swaps)" -eq 0 ]; then
	# No swap partitions, so we can't and don't need to set up encrypted
	# swap.
	exit 0
fi

# We must allow partitioning to finish before we continue.  Unfortunately
# there is currently no hook that will reliably run after both the user page
# and partitioning, and the parallel questions arrangement makes it hard to
# construct one, so for now we have to poll.
while pidof -x ubiquity >/dev/null && \
      [ ! -e /var/lib/ubiquity/started-installing ]; do
	sleep 2
done
if ! pidof -x ubiquity; then
	exit 0
fi

for module in aes cbc ecb; do
	modprobe -q "$module" || true
done
apt-install ecryptfs-utils 2>/dev/null
apt-install cryptsetup 2>/dev/null

# Temporarily make sure that /etc/fstab and /etc/crypttab match the target
# system.
ln -f /etc/fstab /etc/fstab.ubiquity
if [ -e /etc/crypttab ]; then
	ln -f /etc/crypttab /etc/crypttab.ubiquity
else
	rm -f /etc/crypttab.ubiquity
fi
cleanup () {
	mv /etc/fstab.ubiquity /etc/fstab
	if [ -e /etc/crypttab.ubiquity ]; then
		mv /etc/crypttab.ubiquity /etc/crypttab
	else
		rm -f /etc/crypttab
	fi
}
trap cleanup EXIT
cp -a /target/etc/fstab /etc/fstab
if [ -e /target/etc/crypttab ]; then
	cp -a /target/etc/crypttab /etc/crypttab
else
	rm -f /etc/crypttab
fi

if ! log-output -t ubiquity ecryptfs-setup-swap -f -n; then
	echo "ecryptfs-setup-swap failed." >&2
	db_input critical user-setup/encrypt-home-failed || true
	db_go || true
	exit 0
fi

# Zero out all encrypted swap partitions.
#   cryptswap0 /dev/sda5 /dev/urandom swap,cipher=aes-cbc-essiv:sha256
# Ideally we would do some kind of progress thing here, but it's not clear
# that we can do that sensibly while on a question page.
while read name device source options; do
	if echo "$options" | grep -q "swap"; then
		case $device in
		    LABEL=*|UUID=*)
			device="$(blkid -l -o device -t "$device")"
			[ "$device" ] || continue
			;;
		esac
		if swapoff $device; then
			if [ ! -b $device ]; then
				ONE_MEG=$((1024*1024))
				size=$(($(stat -c %s ${device})/${ONE_MEG}))
				dd if=/dev/zero of=$device bs=${ONE_MEG} count=$size 2>/dev/null || true
			else
				# ensure to keep the original swap partition signature so
				# that we retain the UUID in /etc/crypttab; see corresponding
				# ecryptfs-setup-swap change in LP#953875
				dd if=/dev/zero of=$device bs=16M seek=1 2>/dev/null || true
				dd if=/dev/zero of=$device bs=4K seek=1 count=4096 2>/dev/null || true
			fi
			cryptdisks_start "$name" && swapon "/dev/mapper/$name" || true
		fi
	fi
done < /etc/crypttab

cp -a /etc/fstab /etc/crypttab /target/etc/

touch /var/lib/ubiquity/encrypted-swap
