diff --git a/src/tomb b/src/tomb index 6122873..9c96de2 100755 --- a/src/tomb +++ b/src/tomb @@ -22,6 +22,7 @@ VERSION=1.0 DATE=Feb/2011 +TOMBEXEC=$0 # PATH=/usr/bin:/usr/sbin:/bin:/sbin @@ -43,11 +44,32 @@ fi # which wipe command to use which wipe > /dev/null if [ $? = 0 ]; then - WIPE=(wipe -f -s -q) + WIPE=(wipe -f -s) else WIPE=(rm -f) fi +# check for filesystem creation progs +which mkfs.ext4 > /dev/null +if [ $? = 0 ]; then + MKFS=(mkfs.ext4 -q -F -j -L) +else + MKFS=(mkfs.ext3 -q -F -j -L) +fi + +# check for sudo +which sudo > /dev/null +if [ $? != 0 ]; then + error "Cannot find sudo. Please install it" + exit 1 +fi + +# safe dir creation function +safe_dir() { + dir="/tmp/$1.$RANDOM.$RANDOM.$$" + (umask 077 && mkdir "$dir") || echo "-1" + echo "$dir" +} # we use pinentry now # comes from gpg project and is much more secure @@ -73,7 +95,6 @@ EOF } - # drop privileges exec_as_user() { @@ -83,14 +104,8 @@ exec_as_user() { fi func "exec_as_user '$SUDO_USER': ${(f)@}" - which sudo > /dev/null - if [ $? = 0 ]; then - sudo -u $SUDO_USER "${@[@]}" - return $? - else - error "Tomb requires sudo. please install it." - return 1 - fi + sudo -u $SUDO_USER "${@[@]}" + return $? } @@ -98,16 +113,10 @@ exec_as_user() { check_priv() { id | grep root > /dev/null if [ $? != 0 ]; then - which sudo > /dev/null - if [ $? != 0 ]; then - error "Tomb requires sudo. please install it." - exit 1 - fi - func "Using sudo for root execution of 'tomb ${(f)ARGS}'" # check if sudo has a timestamp active sudok=false - sudo -n tomb 2> /dev/null + sudo -n ${TOMBEXEC} 2> /dev/null if [ $? != 0 ]; then # if not then ask a password cat <&1 > /dev/null -if [ $? = 0 ]; then -fi - -ARGS=$@[@] - -OPTS=`getopt -o hvqDs:k:n -n 'tomb' -- "$@"` -while true; do - case "$1" in - -h) - cat <. EOF -exit 0 ;; +} + +############################ +### main() +### + +echo $@ | grep '\-D' 2>&1 > /dev/null +if [ $? = 0 ]; then +fi + +ARGS=$@[@] + +OPTS=`getopt -o hvqDs:k:n -n 'tomb' -- "$@"` +while true; do + case "$1" in + -h) + usage + exit 0 ;; -v) notice "Tomb - simple commandline tool for encrypted storage" act "version $VERSION ($DATE) by Jaromil @ dyne.org" @@ -238,7 +250,7 @@ BEGIN { license=0 } DEBUG=1; shift 1 ;; -s) SIZE=$2; shift 2 ;; -k) KEY=$2; shift 2 ;; - -b) NOBIND=1; shift 1 ;; + -n) NOBIND=1; shift 1 ;; --) shift; break ;; *) CMD=$1; FILE=$2; MOUNT=$3; # compat with old args @@ -246,8 +258,6 @@ BEGIN { license=0 } esac done - - if ! [ $CMD ]; then error "first argument missing, use -h for help" exit 0 @@ -304,15 +314,20 @@ create_tomb() { losetup -f ${tombdir}/${tombfile} # allocates the next loopback for our file # create the keyfile in tmpfs so that we leave less traces in RAM - keytmp=`tempfile -p tomb` - rm -f $keytmp - mkdir -p $keytmp - mount tmpfs ${keytmp} -t tmpfs -o size=1m + keytmp=`safe_dir tomb` + if [ "$keytmp" = "-1" ]; then + error "error creating temp dir" + exit 1 + fi + #rm -f $keytmp + # ?????? creo, cancello e ricreo ?????? + #mkdir -p $keytmp + mount tmpfs "${keytmp}" -t tmpfs -o size=1m if [ $? != 0 ]; then error "cannot mount tmpfs filesystem in volatile memory" error "operation aborted." losetup -d $nstloop - rm -r $keytmp + rm -r "${keytmp}" exit 1 fi act "Generating secret key..." @@ -334,9 +349,9 @@ create_tomb() { # here user is prompted for key password for c in 1 2 3; do # 3 tries to write two times a matching password - tombpass=`exec_as_user tomb askpass ${tombname}` + tombpass=`exec_as_user ${TOMBEXEC} askpass ${tombname}` tombpasstmp=$tombpass - tombpass=`exec_as_user tomb askpass "${tombname} (again)"` + tombpass=`exec_as_user ${TOMBEXEC} askpass "${tombname} (again)"` if [ "$tombpasstmp" = "$tombpass" ]; then break; fi @@ -384,9 +399,9 @@ create_tomb() { # cryptsetup luksDump ${nstloop} - act "formatting your Tomb with Ext4 filesystem" + act "formatting your Tomb with Ext3/Ext4 filesystem" - mkfs.ext4 -q -F -j -L ${tombname} /dev/mapper/tomb.tmp + ${MKFS} ${tombname} /dev/mapper/tomb.tmp if [ $? != 0 ]; then error "Tomb format returns error" @@ -432,6 +447,10 @@ mount_tomb() { mkdir -p $tombmount nstloop=`losetup -f` + if [ $? = 255 ]; then + error "too many tomb opened. Please close any of them to open another tomb" + exit 1 + fi losetup -f ${tombdir}/${tombfile} act "check for a valid LUKS encrypted device" @@ -455,9 +474,9 @@ mount_tomb() { for c in 1 2 3; do if [ $c = 1 ]; then - tombpass=`exec_as_user tomb askpass ${keyname}` + tombpass=`exec_as_user ${TOMBEXEC} askpass ${keyname}` else - tombpass=`exec_as_user tomb askpass "$keyname (retry $c)"` + tombpass=`exec_as_user ${TOMBEXEC} askpass "$keyname (retry $c)"` fi echo "${tombpass}" \ | gpg --batch --passphrase-fd 0 --no-tty --no-options \ @@ -799,26 +818,28 @@ umount_tomb() { return 0 fi - - if [ -r "$1" ]; then # accepts relative and absolute path - mapper="$1" - elif [ -r /dev/mapper/${1} ]; then - mapper=/dev/mapper/${1} - else + if ! [ -e "$1" ]; then error "tomb not found: $1" - error "please specify an existing /dev/mapper/tomb.*" + error "Please specify an existing tomb" return 0 fi - basemap=`basename $mapper` - tombname=`echo ${basemap} | cut -d. -f2` - tombmount=`mount | grep $mapper | awk '{print $3}'` + pathmap=`dirname "$1"` + if [ "${pathmap}" = "/dev/mapper" ]; then + mapper="$1" # $1 is /dev/mapper/tomb.* + tombname=`basename "$1"` # this is tomb.NAME.XXX.loopX + tombmount=`mount | grep "$mapper" | awk -F ' ' '{print $3}'` # tomb mount point + else + tombmount="$1" # $1 is the tomb mount point (e.g. /mnt) + mapper=`mount | grep -w "${tombmount%%/}" | awk -F ' ' '{print $1}'` + tombname=`basename "$mapper"` # this is tomb.NAME.XXX.loopX + fi # check if there are binded dirs and close them first - mount | grep "${tombmount}" 2>/dev/null | grep -v loop 2>&1 > /dev/null + mount | grep "${tombmount%%/}" 2>/dev/null | grep -v loop 2>&1 > /dev/null if [ $? = 0 ]; then act "closing bind hooks for tomb $tombname " - unbind=`mount | grep ${tombmount} | grep -v loop | awk ' + unbind=`mount | grep ${tombmount%%/} | grep -v loop | awk ' { print "umount " $3 "; " } '` eval $unbind @@ -828,27 +849,25 @@ umount_tomb() { # Execute post-hooks for eventual cleanup if ! [ $NOBIND ]; then - exec_post_hooks ${tombmount} close + exec_post_hooks ${tombmount%%/} close fi - act "closing tomb $tombname on dm-crypt $basemap" - mount | grep $mapper 2>&1 >/dev/null - if [ $? = 0 ]; then # still mounted - umount ${mapper} - if ! [ $? = 0 ]; then + act "closing tomb $tombname on dm-crypt $tombmount" + umount ${tombmount} + if ! [ $? = 0 ]; then # TODO: ask user if wanting to SLAM the tomb closed # then kill all processes found using it with fuser and lsof return 1 fi - fi - cryptsetup luksClose $basemap + cryptsetup luksClose $tombname if ! [ $? = 0 ]; then - error "error occurred in cryptsetup luksClose ${basemap}" + error "error occurred in cryptsetup luksClose ${mapper}" return 1 fi - losetup -d "/dev/`echo $basemap | cut -d. -f4`" + loopdev=`cut -d '.' -f4 <<< "$tombname"` + losetup -d "/dev/$loopdev" notice "Tomb $tombname closed: your bones will rest in peace." return 0