From bb35cfd21f0683d17d29a5f51b22bab8047127de Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Wed, 27 Apr 2016 09:23:09 -0400 Subject: Implement encrypted cdrom ejection This allows the cdrom to be copied onto the outer filesystem (mounted in /outerfs) without storing unencrypted gpg keys there. e.g.: samizdat-eject.sh /outerfs/samizdat.iso This was necessary because the other method probably causes btrfs deadlocks. We do end up copying data twice this way (or three times, probably -- if the ISO is saved), but not _from the cdrom_. And we get to eject immediately after the first copy. Future copies will be from the hard drive. Not too bad. --- initrd-dependencies.txt | 1 + old-school/lvm-create.sh | 26 +++++++++++++++++++++++++- old-school/mdadm-dup.sh | 46 +++++++++++++++++++++++++++++++++++++++++++++- patchroot.sh | 2 +- samizdat-eject.sh | 2 +- 5 files changed, 73 insertions(+), 4 deletions(-) diff --git a/initrd-dependencies.txt b/initrd-dependencies.txt index 531c117..36bef76 100644 --- a/initrd-dependencies.txt +++ b/initrd-dependencies.txt @@ -8,3 +8,4 @@ ntfs-3g hfsplus isolinux nbd-client +cryptsetup diff --git a/old-school/lvm-create.sh b/old-school/lvm-create.sh index ce0862e..916b888 100644 --- a/old-school/lvm-create.sh +++ b/old-school/lvm-create.sh @@ -53,12 +53,35 @@ init_samizdat() btrfs device add "$blockdev" /root || return mount -o rw,remount /root || return + samizdat_movemounts "$imgfile" initialize_root_filesystem || return bootdone root-mounted } +samizdat_movemounts() +{ + local imgfile="$1" mountpoint + + mountpoint=$(mountpoint_of "$imgfile") || return + mkdir /root/cdrom /root/outerfs + mount -o move /cdrom /root/cdrom + mount -o move "$mountpoint" /root/outerfs + mkdir /run/initramfs/samizdat + mv /var/log /run/initramfs/samizdat/log +} + +mountpoint_of() +{ + local f="$1" + while ! mountpoint -q "$f"; do + f=$(dirname "$f") + [ "$f" != '.' ] || return 1 + done + printf '%s\n' "$f" +} + initialize_root_filesystem() { rm -r /root/root @@ -117,7 +140,7 @@ filesystem_incomplete() open_samizdat() { open_samizdat_blockdev "$@" || return - local blockdev=/dev/mapper/samizdatcrypt fs + local blockdev=/dev/mapper/samizdatcrypt imgfile="$1" fs # For this part, we don't necessarily need the cdrom. # Unfortunately the init_gpg code is still getting the GPG key there. @@ -127,6 +150,7 @@ open_samizdat() modprobe btrfs || return btrfs device scan || return mount -t btrfs -o subvol=ROOT "$blockdev" /root || return + samizdat_movemounts "$imgfile" LoSetup -D bootdone root-mounted } diff --git a/old-school/mdadm-dup.sh b/old-school/mdadm-dup.sh index 16e3dfd..fe18e92 100644 --- a/old-school/mdadm-dup.sh +++ b/old-school/mdadm-dup.sh @@ -116,7 +116,51 @@ mdadm_subdevices() mdadm -D "$md_dev" -Y | sed -ne 's/^MD_DEVICE_.*_DEV=//p' } -mdadm_copy_eject() # NOT INITRD; uses non-busybox "losetup" +cryptsetup_temp() +{ + local sectors="$1" cryptname="$2" temp_file="$3" parms=$- secret + set +x + # Add 4096 sectors for LUKS header + truncate -s $(((sectors + 4096) * 512)) "$temp_file" || return + cleartext_dev=$(LoSetup -f --show "$temp_file") || return + secret="$(head -c256 /dev/urandom)" || return + printf %s "$secret" | + cryptsetup luksFormat "$cleartext_dev" - || return + printf %s "$secret" | + cryptsetup --key-file - luksOpen "$cleartext_dev" "$cryptname" || return + unset secret + set $parms + + wait_for_dm_device /dev/mapper/"$cryptname" + echo /dev/mapper/"$cryptname" +} + +mdadm_copy_eject_crypt() +{ + local md_dev="$1" temp_file="$2" + + [ -b "$md_dev" ] || return + [ ! -e "$temp_file" ] || return + + local output_dev sectors + + old_subdev=$(mdadm_subdevices "$md_dev"|head -n1) || return + [ -b "$old_subdev" ] || return + # TODO: truncate to the ISO fs size if the device is larger + sectors=$(blockdev --getsz "$md_dev") || return + + output_dev=$(cryptsetup_temp "$sectors" samizdatiso "$temp_file") || return + + mdadm "$md_dev" --add "$output_dev" || return + mdadm "$md_dev" --grow -n2 || return + + mdadm_wait_remove "$md_dev" "$old_subdev" || return + + mdadm "$md_dev" --grow -n1 --force || return + dm_snapshot_teardown "$old_subdev" +} + +mdadm_copy_eject() { local md_dev="$1" output_file="$2" diff --git a/patchroot.sh b/patchroot.sh index 3efa8ec..4f05de6 100755 --- a/patchroot.sh +++ b/patchroot.sh @@ -2,7 +2,7 @@ pkgs='avahi-daemon git tmux btrfs-tools/jessie-backports sshfs eject' pkgs="$pkgs $(cat initrd-dependencies.txt)" -pkgs="$pkgs linux-image-$(uname -r)" +pkgs="$pkgs linux-image-$(uname -r)/jessie-backports" default_sources_list() { diff --git a/samizdat-eject.sh b/samizdat-eject.sh index f5360a7..ac2ebc3 100755 --- a/samizdat-eject.sh +++ b/samizdat-eject.sh @@ -27,7 +27,7 @@ done copy() { - mdadm_copy_eject /dev/md55 "$target" + mdadm_copy_eject_crypt /dev/md55 "$target" } remove() -- cgit v1.2.3