From 7cbe045476f5fbc3827daa881ffaf706b2818eca Mon Sep 17 00:00:00 2001 From: Francois Fleuret Date: Tue, 1 Aug 2017 00:34:52 +0200 Subject: [PATCH] Initial commit. --- luks_toolbox.sh | 262 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100755 luks_toolbox.sh diff --git a/luks_toolbox.sh b/luks_toolbox.sh new file mode 100755 index 0000000..ac4e3a2 --- /dev/null +++ b/luks_toolbox.sh @@ -0,0 +1,262 @@ +#!/bin/bash + +######################################################################### +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the version 3 of the GNU General Public License # +# as published by the Free Software Foundation. # +# # +# This program 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 this program. If not, see . # +# # +# Written by and Copyright (C) Francois Fleuret # +# Contact for comments & bug reports # +######################################################################### + +set -e +# set -o pipefail + +function print_help () { + cat < | fsck [-f] | mount | umount ] + +clean + + 1. umounts all the volumes using a /dev/dm-* device + 2. LUKS-close all the volumes appearing in /dev/mapper + 3. Delete all the loop devices + +sync + + Mounts both files as LUKS volumes, runs a dry-run rsync, and asks for + interactive confirmation before synchronizing. + +fsck + + LUKS-open the provided file and run fsck on it. + +mount|umount + + Automagically figures out from /etc/fstab what is the /dev/mapper/ + device associated to the dir, and both LUKS-opens/mounts or + umount/LUKS-closes it. + +EOF +} + +###################################################################### + +if [[ "$@" == "" ]]; then + print_help >&2 + exit 1 +fi + +if [[ ! $(id -u) == 0 ]]; then + echo "This command should be run as root (no offense, but you are $(id -un))." >&2 + exit 1 +fi + +###################################################################### + +case $1 in + + clean) + + # mount | grep ^'/dev/dm-[0-9]*' | sed -e 's/^.* on \([^ ]*\) .*$/\1/' | \ + + mount | grep ^'/dev/mapper' | sed -e 's/^.* on \([^ ]*\) .*$/\1/' | \ + while read line; do + echo "umount ${line}" + umount ${line} + done + + \ls /dev/mapper | grep -v ^control$ | \ + while read line; do + echo "cryptsetup luksClose ${line[0]}" + cryptsetup luksClose "${line[0]}" + done + + losetup -a | sed -e "s/:.*$//" | \ + while read line; do + echo "losetup -d ${line}" + losetup -d ${line} + done + + exit 0 + + ;; + + ###################################################################### + + sync) + + shift + + [[ -f "$1" ]] && [[ -f "$2" ]] || (echo "$(basename $0) sync " >&2 && exit 1) + + [[ -e "/dev/mapper/crypt-src" ]] && (echo "/dev/mapper/crypt-src already exists." >&2 && exit 1) + + [[ -e "/dev/mapper/crypt-dst" ]] && (echo "/dev/mapper/crypt-dst already exists." >&2 && exit 1) + + ###################################################################### + # Mount the volumes + + echo "Please confirm that $2 can be modified (press 'y')" + + read -n 1 KEY + + if [[ ! "${KEY}" == "y" ]]; then + echo "Cancelled!" + exit 1 + fi + + echo + + LOOP_SRC="$(losetup -f)" + losetup "${LOOP_SRC}" "$1" + cryptsetup luksOpen "${LOOP_SRC}" crypt-src + DIR_MOUNT_SRC="$(mktemp -d /tmp/sync-luks.XXXXXX)" + mount -o ro /dev/mapper/crypt-src "${DIR_MOUNT_SRC}" + + LOOP_DST="$(losetup -f)" + losetup "${LOOP_DST}" "$2" + cryptsetup luksOpen "${LOOP_DST}" crypt-dst + DIR_MOUNT_DST="$(mktemp -d /tmp/sync-luks.XXXXXX)" + mount /dev/mapper/crypt-dst "${DIR_MOUNT_DST}" + + ###################################################################### + # First, show the changes + + echo "**********************************************************************" + echo "* Dry-run" + + rsync -n --itemize-changes --delete --progress -axz "${DIR_MOUNT_SRC}/" "${DIR_MOUNT_DST}/" + + ###################################################################### + # Ask for confirmation and synchronize + + echo "**********************************************************************" + echo "* Press 'y' to synchronize, anything else to cancel." + + read -n 1 KEY + + if [[ "${KEY}" == "y" ]]; then + echo + rsync --itemize-changes --delete --progress -axz "${DIR_MOUNT_SRC}/" "${DIR_MOUNT_DST}/" + else + echo "No synchronization." + fi + + umount "${DIR_MOUNT_SRC}" && rmdir "${DIR_MOUNT_SRC}" && unset DIR_MOUNT_SRC + cryptsetup luksClose crypt-src + losetup -d "${LOOP_SRC}" && unset LOOP_SRC + + umount "${DIR_MOUNT_DST}" && rmdir "${DIR_MOUNT_DST}" && unset DIR_MOUNT_DST + cryptsetup luksClose crypt-dst + losetup -d "${LOOP_DST}" && unset LOOP_DST + + exit 0 + + ;; + + + ###################################################################### + + fsck) + + shift + + if [[ "$1" == "-f" ]]; then + force="-f" + shift + fi + + if [[ ! -a "$1" ]]; then + echo "Cannot find file \`$1'." >&2 + exit 1 + fi + + [[ -e "/dev/mapper/crypt-dst" ]] && (echo "/dev/mapper/crypt-dst already exists." >&2 && exit 1) + + if [[ -f "$1" ]]; then + LOOP_DST="$(losetup -f)" + losetup "${LOOP_DST}" "$1" + DEVICE="${LOOP_DST}" + else + DEVICE="$1" + fi + + cryptsetup luksOpen "${DEVICE}" crypt-dst + + fsck ${force} /dev/mapper/crypt-dst + + sleep 1 + + cryptsetup luksClose crypt-dst + + if [[ "${LOOP_DST}" ]]; then + losetup -d "${LOOP_DST}" && unset LOOP_DST + fi + + exit 0 + + ;; + + ###################################################################### + + mount|umount) + + if [[ "$1" == "umount" ]]; then + umount=yes + fi + + shift + + mount_point=$(echo $1 | sed -e "s;/*$;;") + device=$(grep ^/ /etc/fstab | awk '{ print $2" "$1 }' | grep ^${mount_point} | cut -f 2 -d " ") + + if [[ ${device} =~ ^/dev/mapper ]]; then + + mapped_device=${device/'/dev/mapper/'/} + + if [[ ${umount} ]]; then + cat <&2 + ;; + +esac -- 2.20.1