#! /bin/sh ### ### Mount an ephemeral filesystem ### ### (c) 2012 Mark Wooding ### ###----- Licensing notice --------------------------------------------------- ### ### This file is part of the distorted.org.uk key management suite. ### ### distorted-keys is free software; you can redistribute it and/or modify ### it under the terms of the GNU General Public License as published by ### the Free Software Foundation; either version 2 of the License, or ### (at your option) any later version. ### ### distorted-keys is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with distorted-keys; if not, write to the Free Software Foundation, ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. set -e QUIS=${0##*/} VERSION=1.0.0 USAGE="usage: $QUIS [-u] [-R RANDOM] [-n BYTES] [-C CIPHER] [-H HASH] [-l LABEL] [-t FSTYPE] [-b BACKING-FILE] MOUNTPOINT [SIZE]" ###-------------------------------------------------------------------------- ### Parse the command line. ## Set initial defaults. mode=mount cipher=aes-xts-plain hash=sha256 random=/dev/random randbytes=512 fail=nil backing=/tmp unset label ## Report version number. version () { echo "$QUIS, version $VERSION"; } ## Report help text. help () { version cat <&2 "$USAGE"; exit 1 ;; esac ## Default omitted arguments. case "${label+t}" in t) ;; *) label=${mntpt##*/} ;; esac ###-------------------------------------------------------------------------- ### Do the job. case $mode in mount) ## Mount the filesystem. ## Determine a name for the backing file. If BACKING is a directory then ## we should make a file there and delete it once we've created a ## mapping. The directory may be a shared bit of filesystem, so we must ## be very careful. rmbacking=nil if [ -d "$backing" ]; then i=0 while :; do gorp=$(openssl rand -base64 6) bkdir=$backing/mnteph.$$.$gorp if mkdir >/dev/null 2>&1 -m700 "$bkdir"; then break; fi i=$(( $i + 1 )) if [ $i -ge 100 ]; then echo >&2 "$QUIS: failed to create backing directory" exit 1 fi done backing=$bkdir/fs trap 'rc=$?; rm "$backing"; rmdir "$bkdir"; exit $rc' EXIT trap 'exit 127' INT TERM rmbacking=t fi ## Create the backing file. truncate -s"$size" "$backing" loop=$(losetup -f --show "$backing") ## Attach a device-mapper entry to the file. dd 2>/dev/null if="$random" bs=1 count="$randbytes" | cryptsetup \ --cipher="$cipher" --hash="$hash" \ --key-file=- \ create "$label" "$loop" ## Create the filesystem. if spew=$(mkfs 2>&1 "/dev/mapper/$label"); then : else rc=$? echo >&2 "$QUIS: mkfs failed (rc = $rc)" echo "$spew" | sed >&2 's/^/| /' exit $rc fi ## Mount. mount "/dev/mapper/$label" "$mntpt" ;; umount) ## Unmount a filesystem. ## Find the numbers of the loopback device. deps=$(dmsetup deps "/dev/mapper/$label") set -- $(echo "$deps" | sed 's!^.*:.*(\([0-9]\+\),[[:space:]]*\([0-9]\+\)).*$!\1 \2!') case "$#" in 2) ;; *) echo >&2 "$QUIS: unexpected answer from \`dmsetup deps'" echo "$deps" | sed >&2 's/^/| /' exit 1 ;; esac maj=$1 min=$2 ## Convert that into a name. dev=$(readlink /sys/dev/block/$maj:$min) dev=${dev##*/} case "$dev" in loop*) ;; *) echo >&2 "$QUIS: expected a loopback device; found \`$dev'" exit 1 ;; esac ## Unmount the filesystem. umount "$mntpt" ## Remove the cryptoloop mapping. if spew=$(cryptsetup 2>&1 remove "$label"); then : else rc=$? echo >&2 "$QUIS: cryptsetup failed (rc = $rc)" echo "$spew" | sed >&2 's/^/| /' exit $rc fi ## Disconnect the loopback device. losetup -d "/dev/$dev" ;; esac ###----- That's all, folks --------------------------------------------------