tomb

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

commit 505442c394ed3cdeaece2b9b37e2317433a1f70a
parent c00a1721c881860626b51fd1b11357395f3fa7e4
Author: Jaromil <jaromil@dyne.org>
Date:   Thu, 13 Jan 2011 14:37:52 +0100

tomb creation procedure
tomb-open wrapper and further fixes for desktop automatisms

Diffstat:
Msrc/tomb | 154+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/tomb-notify.cpp | 4++--
Msrc/tomb-open | 142++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Msrc/tomb-status.cpp | 62++++++++++++++++++++++++++++++++++++++++++++------------------
4 files changed, 260 insertions(+), 102 deletions(-)

diff --git a/src/tomb b/src/tomb @@ -1,18 +1,11 @@ #!/bin/zsh # -# Tomb +# Tomb, the Crypto Undertaker # -# a simple commandline tool to create and operate encrypted storage +# a tool to easily operate file encryption of private and secret data # # Copyleft (C) 2007-2011 Denis Roio <jaromil@dyne.org> # -# Tomb development is supported by: NOONE. -# Would you like to support it and engrave your name on this software? -# Contact me! -# -# thanks to Gabriele "Asbesto Molesto" Zaverio -# for suggesting the perfect name for this tool. -# # This source code is free software; you can redistribute it and/or # modify it under the terms of the GNU Public License as published by # the Free Software Foundation; either version 3 of the License, or @@ -58,8 +51,7 @@ fi # usb auto detect using dmesg # tested on ubuntu 10.04 - please test and patch on other systems if you can ask_usbkey() { - notice "looking for key $1 on usb" - exec_as_user tomb-notify "Tomb needs a key." "Plug your usb key in the computer to open $1" + notice "looking for usb key" echo -n " . please insert your usb key " plugged=false @@ -131,6 +123,7 @@ ask_password() { exec_as_user() { func "executing as user '$SUDO_USER': ${(f)@}" sudo -u $SUDO_USER ${@} & + disown } @@ -231,7 +224,7 @@ if ! [ -r ${tombtab} ]; then echo "# format here is similar to the system wide fstab" >> ${tombtab} echo "# <file system> <mount point> <type> <options> <key>" >> ${tombtab} fi - + create_tomb() { notice "Creating a new tomb in ${FILE}" @@ -239,8 +232,9 @@ create_tomb() { if [ $MOUNT ]; then SIZE=$MOUNT else - error "size is not specified, please use -s option when creating a tomb" - exit 0 + create_tomb_guided +# error "size is not specified, please use -s option when creating a tomb" +# exit 0 fi fi @@ -267,10 +261,12 @@ create_tomb() { losetup -f ${FILE} # allocates the next loopback for our file keytmp=`tempfile` act "Generating secret key..." - act "this operation takes time, computer use helps to gather more entropy." - cat /dev/random | dd bs=1 count=256 of=${keytmp} + act "this operation takes time, keep using this computer on other tasks," + act "once done you will be asked to choose a password for your tomb." + cat /dev/urandom | dd bs=1 count=256 of=${keytmp} notice "Setup your secret key file ${FILE}.gpg" + exec_as_user tomb-notify "The Tomb key is being forged:" "please set your password." # here user is prompted for key password gpg -o "${FILE}.gpg" --no-options --openpgp -c -a ${keytmp} while [ $? = 2 ]; do @@ -292,20 +288,27 @@ create_tomb() { cryptsetup --key-file ${keytmp} --cipher aes luksOpen ${nstloop} tomb.tmp - $WIPE ${keytmp} - - notice "Your tomb is read on ${FILE} and secured with key ${FILE}.gpg" - act "now plug an external usb device to save the key separately:" - ask_usbkey - if ! [ -w ${usbkey_mount} ]; then - error "cannot save the key in a separate place, move it yourself later." - else - mkdir -p ${usbkey_mount}/.tomb - cp -v ${FILE}.gpg ${usbkey_mount}/.tomb/ - chmod -R go-rwx ${usbkey_mount}/.tomb - rm -rf ${FILE}.gpg + ${WIPE} ${keytmp} + + notice "Your tomb is ready on ${FILE} and secured with key ${FILE}.gpg" + act "Would you like to save the key on an external usb device?" + act "This is recommended for safety:" + act "always keep the key in a different place than the door!" + act "If you answer yes, you'll need a USB KEY now: (yes/no)" + exec_as_user tomb-notify "Tomb has forged a key." "Would you like to save it on USB?" + echo -n " > " + read -q + if [ $? = 0 ]; then + ask_usbkey + if ! [ -w ${usbkey_mount} ]; then + error "cannot save the key in a separate place, move it yourself later." + else + mkdir -p ${usbkey_mount}/.tomb + cp -v ${FILE}.gpg ${usbkey_mount}/.tomb/ + chmod -R go-rwx ${usbkey_mount}/.tomb + rm -rf ${FILE}.gpg + fi fi - # cryptsetup luksDump ${nstloop} act "formatting your Tomb with Ext4 filesystem" @@ -324,6 +327,8 @@ create_tomb() { losetup -d ${nstloop} notice "done creating $FILE encrypted storage (using Luks dm-crypt AES/SHA256)" + exec_as_user tomb-notify "The Tomb is ready!" "We will now open your new Tomb for the first time." + tomb mount $FILE } @@ -337,12 +342,12 @@ mount_tomb() { notice "mounting $FILE on mountpoint $MOUNT" if [ -z $MOUNT ]; then - act "mountpoint not specified, using default: /media/$FILE" - MOUNT=/media/${FILE} + MOUNT=/media/`basename ${FILE}` + act "mountpoint not specified, using default: $MOUNT" mkdir -p $MOUNT elif ! [ -x $MOUNT ]; then error "mountpoint $MOUNT doesn't exist" - exit 0 + exit 1 fi # check if key file is present @@ -369,7 +374,7 @@ mount_tomb() { if [ $? != 0 ]; then # is it a LUKS encrypted nest? see cryptsetup(1) error "$FILE is not a valid Luks encrypted storage file" - exit 0 + exit 1 fi @@ -413,9 +418,7 @@ mount_tomb() { mount -t ext4 -o rw,noatime,nodev /dev/mapper/${mapper} ${MOUNT} notice "encrypted storage $FILE succesfully mounted on $MOUNT" - if [ $DISPLAY ]; then - exec_as_user tomb-status ${FILE} ${MOUNT} - fi + exec_as_user tomb-status ${mapper} ${FILE} ${MOUNT} } umount_tomb() { @@ -425,55 +428,58 @@ umount_tomb() { how_many_tombs="`ls /dev/mapper/tomb* 2>/dev/null | wc -w`" if [ $how_many_tombs = 0 ]; then error "there is no open tomb to be closed" - return + exit 0 elif [ $how_many_tombs = 1 ]; then mapper=`ls /dev/mapper/tomb* 2>/dev/null` FILE=`mount | grep $mapper | awk '{print $3}'` else error "too many tombs mounted, please specify which to unmount:" ls /dev/mapper/tomb* - echo - return + exit 1 fi else - if ! [ -r $FILE ]; then + if [ -r $FILE ]; then + mapper=$FILE + elif [ -r /dev/mapper/${FILE} ]; then + mapper=/dev/mapper/${FILE} + else error "tomb not found: $FILE" - error "please specify the full /dev/mapper/tomb* path" - return + error "please specify an existing /dev/mapper/tomb*" + exit 1 fi - mapper=$FILE - FILE=`mount | grep $mapper | awk '{print $3}'` +# FILE=`mount | grep $mapper | awk '{print $3}'` fi - if [ "$mapper" = "" ]; then - error "$FILE is not mounted" - return - fi + # if [ "$mapper" = "" ]; then + # error "$FILE is not mounted" + # return + # fi - mapper=`basename $mapper` + # mapper=`basename $mapper` - if ! [ -r /dev/mapper/${mapper} ]; then - error "tomb doesn't seems to be mounted:" - error "${mapper} is not present in /dev/mapper" - exit 1 - fi + # if ! [ -r /dev/mapper/${mapper} ]; then + # error "tomb doesn't seems to be mounted:" + # error "${mapper} is not present in /dev/mapper" + # exit 1 + # fi - umount ${FILE} - if ! [ $? = 0 ]; then - error "error occurred in umount ${FILE}" - exit 0 - fi + umount ${mapper} + # if ! [ $? = 0 ]; then + # error "error occurred in umount ${mapper}" + # fi + + basemap=`basename $mapper` - cryptsetup luksClose ${mapper} + cryptsetup luksClose $basemap if ! [ $? = 0 ]; then - error "error occurred in cryptsetup luksClose ${mapper}" + error "error occurred in cryptsetup luksClose ${basemap}" exit 0 fi - losetup -d "/dev/`echo $mapper | cut -d. -f4`" + losetup -d "/dev/`echo $basemap | cut -d. -f4`" # echo ${nstloop} | grep loop 1>/dev/null 2>/dev/null # # if it's a loopback then we need to do losetup -d @@ -486,16 +492,13 @@ umount_tomb() { # fi notice "crypt storage ${mapper} unmounted" - exec_as_user tomb-notify "Tomb closed:" "${FILE} -Rest In Peace." + exec_as_user tomb-notify "Tomb closed: `echo ${basemap} | cut -d. -f2`" "Your bones will Rest In Peace." } # install mime-types, bells and whistles for the desktop # see http://developers.sun.com/solaris/articles/integrating_gnome.html # and freedesktop specs install() { - notice "Installing Tomb on your desktop" - act "updating mimetypes..." cat <<EOF > /tmp/dyne-tomb.xml <?xml version="1.0"?> @@ -513,9 +516,9 @@ EOF xdg-mime install /tmp/dyne-tomb.xml xdg-icon-resource install --context mimetypes --size 32 monmort.xpm monmort xdg-icon-resource install --size 32 monmort.xpm dyne-monmort - + rm /tmp/dyne-tomb.xml - + act "updating desktop..." cat <<EOF > /usr/share/applications/tomb.desktop [Desktop Entry] @@ -527,11 +530,11 @@ Comment=Keep your bones safe Exec=tomb-open %U TryExec=tomb-open Icon=monmort.xpm -Terminal=true +Terminal=false Categories=Utility;Security;Archiving;Filesystem; MimeType=application/x-tomb-volume; EOF - update-desktop-database + update-desktop-database act "updating menus..." cat <<EOF > /etc/menu/tomb @@ -559,7 +562,7 @@ application/x-tomb-key ext: tomb.gpg EOF cat <<EOF > /usr/lib/mime/packages/tomb -application/x-tomb-volume; tomb '%s'; needsterminal; priority=8 +application/x-tomb-volume; tomb-open '%s'; priority=8 EOF update-mime @@ -571,13 +574,12 @@ tomb name=Tomb - Crypto Undertaker can_open_multiple_files=false expects_uris=false - requires_terminal=true + requires_terminal=false mime-types=application/x-tomb-volume,application/x-tomb-key EOF - + act "Tomb is now installed." } - case "$CMD" in create) create_tomb ;; @@ -595,5 +597,8 @@ case "$CMD" in *) error "command \"$CMD\" not recognized" act "try -h for help" + break ;; esac + +exit 1+ \ No newline at end of file diff --git a/src/tomb-notify.cpp b/src/tomb-notify.cpp @@ -25,7 +25,7 @@ #include <libnotify/notify.h> -/* The Tomb icon is an artwork by Jordi aka MonMort +/* The Tomb icon is an artwork by Jordi aka Món Mort a nomadic graffiti artist from Barcelona */ #include <monmort.xpm> @@ -44,7 +44,7 @@ int main(int argc, char **argv) { notify_init(PACKAGE); if(argc<3) - snprintf(body,511, "I'm the crypto undertaker.\nLet's start digging out bones."); + snprintf(body,511, "Hi, I'm the Undertaker.\nLet's start setting your Crypt?"); else snprintf(body,511, "%s", argv[2]); diff --git a/src/tomb-open b/src/tomb-open @@ -1,12 +1,139 @@ -#!/bin/sh +#!/bin/zsh +# +# Tomb, the Crypto Undertaker +# +# a tool to easily operate file encryption of private and secret data +# +# Copyleft (C) 2007-2011 Denis Roio <jaromil@dyne.org> +# +# This source code is free software; you can redistribute it and/or +# modify it under the terms of the GNU Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This source code 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. +# Please refer to the GNU Public License for more details. +# +# You should have received a copy of the GNU Public License along with +# this source code; if not, write to: +# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + # startup wrapper to open tombs -# got a tomb as argument -if [ $@ ]; then - tomb -S open $@ - exit $? +explore() { + which ${1} > /dev/null + if [ $? = 0 ]; then + ${1} ${2} + exit 0 + fi +} + +# if no arguments are given, run in terminal +if [ -z $1 ]; then + explore gnome-terminal -e "tomb-open create" + explore lxterm -bg black -fg white -e "tomb-open create" + explore urxvt -bg black -fg white -e "tomb-open create" + explore uxterm -bg black -fg white -e "tomb-open create" + explore xterm -bg black -fg white -e "tomb-open create" +fi + + +# got a directory as argument +if [ -d $1 ]; then + +# FIXME: somehow xdg-open loses mailcap mimes when executed by tomb-status +# explore xdg-open ${1} + + # try known file managers + explore gnome-open ${1} + explore thunar ${1} + explore rox ${1} + explore fsviewer ${1} + explore xnc ${1} + tomb-notify "File manager not found." "Tomb cannot guess which filemanager you are using" + exit 1 +fi + +# got a tomb as argument? +if [ -f $1 ]; then + file $1 | grep LUKS + if [ $? = 0 ]; then + tomb -S mount $1 + exit $? + else + tomb-notify "Not a real Tomb." "We found no real bones in there." + exit 1 + fi +fi + +# no argument but on graphical display: creation dialog +if [ -z $DISPLAY ]; then + echo "[!] tomb-open is a wrapper for the command 'tomb'" + tomb -h + exit 1 +fi + +if [ "$1" != "create" ]; then + exit 0 fi -tomb -h +# start guided tomb creation +tomb-notify +cat <<EOF +Create a new Tomb +================= + + A Tomb is a special folder that keeps files safe using a password: + it makes use of strong encryption and helps you keep the keys on a + separate USB storage for safer transports. + + Inside a Tomb you can store private informations without fear that + other people possessing it will discover your secrets, unless they + have your USB key and your password. + + If you choose to proceed now, we'll guide you through the creation + of a new Tomb, You will also need the super-user (sudo) password for + the computer you are using. + + If you will, I'll be your Crypto Undertaker. + Do you want to proceed, Master? (yes/no)" +EOF +echo -n "> " +read -q +if [ $? != 0 ]; then + echo "Operation aborted." + exit 1 +fi + # let's proceed +echo " Please type in the name for your new tomb file:" +echo -n "> " +read filename +echo " How big you want the Tomb to be?" +echo " Type a size number in Megabytes:" +echo -n "> " +read size +echo " You have commanded the creation of this Tomb:" +echo " $filename ( $size MBytes )"; +echo +echo " Please confirm if you want to proceed now," +echo " digging will take quite some time! (yes/no)" +echo -n "> " +read -q +if [ $? != 0 ]; then + echo "Operation aborted." + exit 1 +fi +cat <<EOF + Operation confirmed! we will now call the undertaker to do its + job, but in order to do so you will need to provide your sudo + password: +EOF +sudo tomb -S create ${filename}.tomb $size +if ! [ -r /usr/share/applications/tomb.desktop ]; then + echo " Well done!" + echo " Now the last thing to do is to install Tomb on your desktop:" + sudo tomb install +fi -sleep 10- \ No newline at end of file diff --git a/src/tomb-status.cpp b/src/tomb-status.cpp @@ -35,6 +35,7 @@ GtkMenu *menu_left, *menu_right; NotifyNotification *notice; GError *error; +char mapper[256]; char filename[256]; char mountpoint[256]; @@ -48,7 +49,6 @@ gboolean cb_about(GtkWidget *w, GdkEvent *e); int main(int argc, char **argv) { - GObject *tray; GtkWidget *item_close, *item_view, *item_about; gint menu_x, menu_y; gboolean push_in = true; @@ -59,11 +59,19 @@ int main(int argc, char **argv) { gtk_init(&argc, &argv); // get the information from commandline - if(argc<3) sprintf(mountpoint,"unknown"); - else snprintf(mountpoint,255, "%s", argv[2]); + if(argc<2) { + fprintf(stderr, "error: need at least one argument, the path to a dm-crypt device mapper\n"); + exit(1); + } else { + // TODO: check if mapper really exists + snprintf(mapper,255, "%s", argv[1]); + } - if(argc<2) sprintf(filename, "unknown"); - else snprintf(filename,255, "%s", argv[1]); + if(argc<3) sprintf(filename, "unknown"); + else snprintf(filename,255, "%s", argv[2]); + + if(argc<4) sprintf(mountpoint,"unknown"); + else snprintf(mountpoint,255, "%s", argv[3]); // libnotify notify_init(PACKAGE); @@ -78,7 +86,7 @@ int main(int argc, char **argv) { // LEFT click menu menu_left = (GtkMenu*) gtk_menu_new(); // view - item_view = gtk_menu_item_new_with_label("View"); + item_view = gtk_menu_item_new_with_label("Explore"); gtk_menu_attach(menu_left, item_view, 0, 1, 0, 1); g_signal_connect_swapped(item_view, "activate", G_CALLBACK(cb_view), NULL); gtk_widget_show(item_view); @@ -127,19 +135,37 @@ gboolean left_click(GtkWidget *w, GdkEvent *e) { 1, gtk_get_current_event_time()); } gboolean cb_view(GtkWidget *w, GdkEvent *e) { - GtkWidget *dialog = - gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_CLOSE, - "Tomb '%s' open on '%s'", filename, mountpoint); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - + // GtkWidget *dialog = + // gtk_message_dialog_new (NULL, + // GTK_DIALOG_DESTROY_WITH_PARENT, + // GTK_MESSAGE_INFO, + // GTK_BUTTONS_CLOSE, + // "Tomb '%s' open on '%s'\n" + // "device mapper: %s", filename, mountpoint, mapper); + // gtk_dialog_run (GTK_DIALOG (dialog)); + // gtk_widget_destroy (dialog); + pid_t cpid = fork(); + if (cpid == -1) { + fprintf(stderr,"error: problem forking process\n"); + return false; + } + if (cpid == 0) { // Child + execlp("tomb-open", "tomb-open", mountpoint ,(char*)NULL); + exit(1); + } + return true; } gboolean cb_close(GtkWidget *w, GdkEvent *e) { - execlp("tomb","tomb","-S","umount",NULL); + pid_t cpid = fork(); + if (cpid == -1) { + fprintf(stderr,"error: problem forking process\n"); + return false; + } + if (cpid == 0) { // Child + execlp("tomb","tomb","-S","umount",mapper,(char*)NULL); + exit(1); + } gtk_main_quit(); } @@ -151,8 +177,8 @@ gboolean right_click(GtkWidget *w, GdkEvent *e) { } gboolean cb_about(GtkWidget *w, GdkEvent *e) { const gchar *authors[] = {"Denis Roio aka Jaromil - http://jaromil.dyne.org",NULL}; - const gchar *artists[] = {"Jordi aka MonMort - http://monmort.blogspot.org", - "Gabriele Zaverio aka Asbesto - http://freaknet.org/asbesto", + const gchar *artists[] = {"Jordi aka Món Mort - http://monmort.blogspot.org", + "Asbesto Molesto - http://freaknet.org/asbesto", NULL}; GtkWidget *dialog = gtk_about_dialog_new(); gtk_about_dialog_set_name(GTK_ABOUT_DIALOG(dialog), PACKAGE);