tomb

the crypto undertaker
git clone git://parazyd.org/tomb.git
Log | Files | Refs | README | LICENSE

tomb-open (11238B)


      1 #!/bin/zsh
      2 #
      3 # Tomb, the Crypto Undertaker
      4 #
      5 # a tool to easily operate file encryption of private and secret data
      6 #
      7 # Copyleft (C) 2007-2011 Denis Roio <jaromil@dyne.org>
      8 #
      9 # This source  code is free  software; you can redistribute  it and/or
     10 # modify it under the terms of  the GNU Public License as published by
     11 # the Free  Software Foundation; either  version 3 of the  License, or
     12 # (at your option) any later version.
     13 #
     14 # This source code is distributed in  the hope that it will be useful,
     15 # but  WITHOUT ANY  WARRANTY;  without even  the  implied warranty  of
     16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     17 # Please refer to the GNU Public License for more details.
     18 #
     19 # You should have received a copy of the GNU Public License along with
     20 # this source code; if not, write to:
     21 # Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     22 
     23 # startup wrapper to open tombs
     24 
     25 TOMBEXEC="tomb"
     26 
     27 if [ "$0" = "./tomb-open" ]; then
     28 	TOMBEXEC="$PWD/tomb"
     29 fi
     30 
     31 # includes all shell functions in tomb
     32 source $TOMBEXEC source
     33 
     34 try() {
     35     which ${1} > /dev/null
     36     if [ $? = 0 ]; then 
     37 	return 0
     38     else 
     39 	return -1 
     40     fi
     41 }
     42 
     43 # popup notification
     44 tomb-notify() {
     45 
     46     which notify-send > /dev/null
     47     if [ $? != 0 ]; then return 1; fi
     48 
     49     # look for our icon in common prefixes
     50     if   [ -r /usr/share/pixmaps/monmort.xpm ];       then icon=/usr/share/pixmaps/monmort.xpm
     51     elif [ -r /usr/share/icons/monmort.xpm ];         then icon=/usr/share/icons/monmort.xpm
     52     elif [ -r /usr/local/share/pixmaps/monmort.xpm ]; then icon=/usr/local/share/pixmaps/monmort.xpm
     53     elif [ -r /usr/local/share/icons/monmort.xpm ];   then icon=/usr/local/share/icons/monmort.xpm
     54     elif [ -r /opt/share/pixmaps/monmort.xpm ];       then icon=/opt/share/pixmaps/monmort.xpm
     55     elif [ -r /sw/share/pixmaps/monmort.xpm ];        then icon=/sw/share/pixmaps/monmort.xpm
     56     fi
     57 
     58     if [ -z $1 ]; then
     59 	notify-send -i $icon \
     60 	    -u low -h string:App:Tomb \
     61 	    "Tomb version $VERSION" \
     62 	    "Hi, I'm the Undertaker.
     63 Let's start setting your Crypt?"
     64     else
     65 	notify-send -i $icon ${@}
     66     fi
     67 }
     68 
     69 
     70 # USB plug auto detect using dmesg
     71 # tested on ubuntu 10.04 and debian 6.0
     72 # please test and patch on other systems if you can.
     73 # TODO: use udev rules, see how archlinux folks document it:
     74 # https://wiki.archlinux.org/index.php/System_Encryption_with_LUKS_for_dm-crypt
     75 # here we could modularize the choice of methods using function pointers,
     76 # so that they are configurable when calling tomb.
     77 ask_usbkey() {
     78     unset usbkey_mount
     79     say "Waiting 1 minute for a usb key to connect"
     80     act -n "please insert your usb key "
     81     
     82     tomb-notify "Insert your USB KEY" \
     83 	"Tomb is waiting 30 seconds for you to insert an external key."
     84     
     85     plugged=false
     86     c=0
     87     while [ "$plugged" != "true" ]; do
     88 	dmesg | tail -n 12 | grep -q 'new.*USB device'
     89 	if [ $? = 0 ]; then plugged=true; fi
     90 	echo -n "."
     91 	sleep .5
     92 	c=`expr $c + 1`
     93 	if [ $c -gt 60 ]; then
     94 	    echo
     95 	    die "timeout"
     96 	fi
     97     done
     98 
     99     echo
    100     act -n "usb key inserted, attaching "
    101     
    102     c=0
    103     attached=false
    104     while [ "$attached" != "true" ]; do
    105         dmesg | tail -n 12| grep -q 'Attached.*removable disk'
    106         if [ $? = 0 ]; then attached=true; fi
    107         echo -n "."
    108         sleep  .5
    109         c=`expr $c + 1`
    110         if [ $c -gt 30 ]; then
    111             echo
    112             export usbkey_mount=none
    113             die "timeout"
    114         fi
    115     done
    116 
    117     echo
    118     act -n "usb attached, opening "
    119     
    120     # get the first partition
    121 #    usbpart=`dmesg |tail -n 12 | grep '  sd.:' |cut -d: -f2 |tr -d ' '`
    122     for i in $(seq 1 10); do
    123         usbpart=$(dmesg | tail -n 12 | sed '/  sd.:/!d;s/^.*: \(sd.[0-9]*\)/\1/')
    124         if [ -n "$usbpart" ]; then
    125             break
    126         elif [ $i -eq 10 ]; then
    127             die "timeout" 1
    128         else
    129             echo -n .
    130             sleep 1
    131         fi
    132     done
    133 
    134     mtmp=`$TOMBEXEC mktemp tomb`
    135     sudo mount /dev/$usbpart $mtmp
    136     if [ $? = 0 ]; then
    137         usbmount=$mtmp
    138     else
    139         die "cannot mount usbkey partition $usbmount"
    140     fi
    141 
    142     echo
    143     act "usb key mounted on $usbmount"
    144     usbkey_mount=$usbmount
    145     return 0
    146 }
    147 
    148 launch_status() {
    149     # calculates the correct arguments to launch tomb-status tray
    150     # applet; it takes the tomb name as an argument and should be
    151     # launched after a successful tomb mount.
    152     if ! [ $1 ]; then
    153         die "cannot launch status tray applet: we don't even know the name of our tomb."
    154     fi
    155 
    156     if [ $DISPLAY ]; then
    157 	tombname=${1}
    158     tombbase=`basename $tombname`
    159 	tombmap=`mount -l | awk "/\[${tombbase}\]\$/"' { print $1 } '`
    160 	tombmount=`mount -l | awk "/\[${tombbase}\]\$/"' { print $3 } '`
    161 	if [ -x ./tomb-status ]; then # launch from build dir
    162 	    ./tomb-status $tombmap $tombname $tombmount &!
    163 	else
    164 	    which tomb-status > /dev/null
    165 	    if [ $? = 0 ]; then
    166 		tomb-status $tombmap $tombname $tombmount &!
    167 	    fi
    168 	fi
    169     fi
    170 }
    171 
    172 # got an argument
    173 if [ $1 ]; then # is it a file?
    174 
    175     tombdir=`dirname $1`
    176     tombfile=`basename $1`
    177     tombname=${tombfile%%\.*}
    178 
    179     if [ -f ${tombdir}/${tombfile} ]; then
    180 
    181 	# is it a luks partition
    182 	file ${tombdir}/${tombfile} | grep -i LUKS > /dev/null
    183 	if [ $? = 0 ]; then # tomb is a valid LUKS file
    184         if [ -r ${tombdir}/${tombname}.tomb.key ]; then
    185             tombkey=${tombdir}/${tombname}.tomb.key
    186 	    else
    187 		ask_usbkey
    188         if ! [ $usbkey_mount ]; then # no usb key was mounted
    189             die "key not provided for tomb  $tombname: operation aborted" 1
    190         else # usb mounted, check key presence
    191             if [ -r ${usbkey_mount}/.tomb/${tombname}.tomb.key ]; then
    192                 tombkey=${usbkey_mount}/.tomb/${tombname}.tomb.key
    193             elif [ -r ${usbkey_mount}/.tomb ]; then
    194                 die "we can't find the right key, have a look yourself:\n$(ls -lha ${usbkey_mount}/.tomb)" 1
    195             else
    196                 die "there are no keys stored in your usb" 1
    197             fi
    198         fi
    199 	    fi
    200         if ! [ ${tombkey} ]; then # just to be sure
    201             die "key not found, operation aborted." 1
    202         else
    203 
    204             "${TOMBEXEC}" mount -k ${tombkey} ${tombdir}/${tombfile}
    205             success=$?
    206         fi
    207 
    208         if [ $usbkey_mount ]; then
    209             sudo umount ${usbkey_mount}
    210             rmdir  ${usbkey_mount}
    211             unset  usbkey_mount
    212         fi
    213 
    214         if [ $success = 0 ]; then	# mount was succesfull (with password and all)
    215             launch_status ${tombname}
    216             exit 0
    217         else
    218             tomb-notify "Tomb cannot open." "Are you knocking the wrong door?"
    219             exit 1
    220         fi
    221 	else
    222 	    tomb-notify "Not a real Tomb." "We found no real bones in there, or the tomb file permissions won't allow us in."
    223 	    exit 1
    224 	fi
    225 
    226 
    227     elif [ -d $1 ]; then # its a directory
    228 	
    229 # FIXME: somehow xdg-open loses mailcap mimes when executed by tomb-status
    230 #   try xdg-open; if [ $? = 0 ]; then xdg-open ${1}; exit 0; fi
    231 	try gnome-open; if [ $? = 0 ]; then gnome-open ${1}; exit 0; fi
    232 	try thunar; if [ $? = 0 ]; then thunar ${1}; exit 0; fi
    233 	try pcmanfm; if [ $? = 0 ]; then pcmanfm ${1}; exit 0; fi	
    234 	try rox; if [ $? = 0 ]; then rox ${1}; exit 0; fi
    235 	try fsviewer; if [ $? = 0 ]; then fsviewer ${1}; exit 0; fi
    236 #	try xnc; if [ $? = 0 ]; then xnc ${1}; exit 0; fi
    237 	tomb-notify "File manager not found." "Tomb cannot guess which filemanager you are using"
    238 	exit 1
    239     fi
    240 fi
    241 
    242 
    243 # no argument but on graphical display: creation dialog
    244 if [ "$1" != "wizard" ]; then
    245     if [ -z $DISPLAY ]; then
    246         no "tomb-open is a wrapper for the command 'tomb'"
    247         no "type 'tomb-open wizard' if you want to be guided"
    248         "${TOMBEXEC}" help
    249         exit 1
    250     fi
    251 fi
    252 
    253 # no arguments: start guided tomb creation
    254 tomb-notify
    255 # we do it on the desktop by default
    256 if [ -r $HOME/Desktop ]; then 
    257     cd $HOME/Desktop;
    258 # or inside HOME
    259 else cd $HOME; fi
    260 say "Tomb  -  simple commandline tool for encrypted storage"
    261 say "version $VERSION ($DATE) by Jaromil @ dyne.org"
    262 say "Guided creation of a new Tomb"
    263 cat <<EOF
    264 
    265   A Tomb is  a special folder that keeps files  safe using a password:
    266   it makes use  of strong encryption and helps you keep  the keys on a
    267   separate USB storage for safer transports.
    268 
    269   Inside a Tomb  you can store private informations  without fear that
    270   other people  possessing it will discover your  secrets, unless they
    271   have your USB key and your password.
    272 
    273   If you choose  to proceed now, we'll guide  you through the creation
    274   of a new Tomb.
    275 
    276   If you will, I'll be your Crypto Undertaker.
    277 
    278   Do you want to proceed, Master? (y/n)
    279 EOF
    280 echo -n "> "
    281 read -q
    282 if [ "$?" != 0 ]; then
    283     die "Operation aborted" 1
    284 fi
    285     # let's proceed
    286 say "Please type in the name for your new tomb file:"
    287 echo -n "> "
    288 read -u 1 tombname
    289 say "How big you want the Tomb to be?"
    290 act "Type a size number in Megabytes:"
    291 echo -n "> "
    292 read -u 1 tombsize
    293 if [[ "$tombsize" != <-> ]]; then
    294     die "Only digit allowed! Operation aborted"
    295 fi
    296 clear
    297 say "You have commanded the creation of this Tomb:"
    298 act "$tombname ( $tombsize MBytes )";
    299 echo
    300 cat <<EOF
    301   Please confirm if you want to proceed now:
    302 
    303   You will  need the super-user  (sudo) password for the  computer you
    304   are using, as well time available.
    305 
    306   Depending how big  your tomb will be, make sure  you are not running
    307   low on batteries.
    308 
    309   If  you are  remotely connected  to  a server,  make sure  to use  a
    310   detachable screen.
    311 
    312   Considering 1GB takes usually little less than an hour to be digged.
    313 
    314 EOF
    315 say "  Digging will take quite some time! Should we start? (y/n)"
    316 echo -n "> "
    317 read -q
    318 if [ $? != 0 ]; then
    319     die "Operation aborted." 1
    320 
    321 fi
    322 cat <<EOF
    323   Operation confirmed!  we will now call the undertaker to do its job,
    324   but in order to do so you will need to provide your sudo password:
    325 EOF
    326 
    327 tombfile=${tombname}.tomb
    328 "${TOMBEXEC}" create --ignore-swap -s $tombsize ${tombfile}
    329 
    330 if [ $? != 0 ]; then
    331     die "An error occurred creating tomb, operation aborted."
    332 fi
    333 
    334 tomb-notify "The Tomb is ready!" "We will now open your new Tomb for the first time."
    335 cat <<EOF
    336   Would you like to save the key on  an external usb device?
    337 
    338   This is recommended for safety:
    339   Always keep the key in a different place than the door!
    340 
    341   If you answer yes, you'll need a USB KEY now: (y/n)
    342 EOF
    343 # tomb-notify "Tomb has forged a key." "Would you like to save it on USB?" 
    344 echo -n " >  "
    345 read -q
    346 if [ $? = 0 ]; then
    347     ask_usbkey
    348     if [  ${usbkey_mount} ]; then
    349 
    350 	sudo mkdir -m 0700 -p ${usbkey_mount}/.tomb
    351 	sudo cp -v ${tombfile}.key ${usbkey_mount}/.tomb/
    352 	sudo chmod -R go-rwx ${usbkey_mount}/.tomb
    353 
    354 	yes "${tombname}.key succesfully saved on your USB"
    355 	act "now we'll proceed opening your brand new tomb"
    356 
    357 	"${TOMBEXEC}" open -k ${tombfile}.key ${tombfile}
    358 	if [ $? = 0 ]; then
    359 	    launch_status ${tombname}
    360 	fi
    361 
    362 	rm -f ${tombfile}.key
    363 
    364 	sudo umount ${usbkey_mount}
    365 	rmdir  ${usbkey_mount}
    366 	unset usbkey_mount
    367 
    368 	exit 0
    369     fi
    370 fi
    371 
    372 cat <<EOF
    373   Impossible to save the key on USB.
    374 
    375   We recommend to preserve the key  in a separate place!  You can move
    376   it yourself later, place it in a hidden directory named .tomb inside
    377   the first partition of an usb key.
    378 
    379 EOF
    380 
    381 "${TOMBEXEC}" open -k ${tombname}.tomb.key ${tombfile}
    382 if [ $? = 0 ]; then
    383     launch_status ${tombname}
    384 fi
    385 
    386 exit 0