tomb

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

gtomb (21867B)


      1 #!/usr/bin/env zsh
      2 #
      3 # Copyright (c) 2015-2016 parazyd
      4 # gtomb is written and maintained by parazyd <parazyd@dyne.org>
      5 #
      6 # This file is part of gtomb
      7 #
      8 # This source code is free software: you can redistribute it and/or modify
      9 # it under the terms of the GNU General Public License as published by
     10 # the Free Software Foundation, either version 3 of the License, or
     11 # (at your option) any later version.
     12 #
     13 # This software is distributed in the hope that it will be useful,
     14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 # GNU General Public License for more details.
     17 #
     18 # You should have received a copy of the GNU General Public License
     19 # along with this source code. If not, see <http://www.gnu.org/licenses/>.
     20 
     21 ver="0.8"
     22 TOMBPATH="/usr/local/bin/tomb" # Set this to your tomb executable's path
     23 KDFPATH="/usr/local/bin/" # Set this to the path of your KDF binaries (if you're using them)
     24 # The ones below should not need changing
     25 HEXENC="$KDFPATH/tomb-kdb-hexencode"
     26 GENSALT="$KDFPATH/tomb-kdb-pbkdf2-gensalt"
     27 GETITER="$KDFPATH/tomb-kdb-pbkdf2-getiter"
     28 PBKDF="$KDFPATH/tomb-kdb-pbkdf2"
     29 _DD=/bin/dd
     30 
     31 # {{{ monmort icon
     32 MONMORT="/tmp/monmort.png"
     33 ICONB64="iVBORw0KGgoAAAANSUhEUgAAACAAAAAgEAQAAACJ4248AAAAAmJLR0T//xSrMc0AAAAJcEhZcwAA\n
     34 AEgAAABIAEbJaz4AAAAJdnBBZwAAACAAAAAgAIf6nJ0AAADrSURBVFjD5ZZBEsMgCEU/TO/l2XMx\n
     35 04VjQ1K1CDYswkwWJnH+E/EL4RP7jluDCACoim/bvfIpFQiKEJcQHCN9xEtLCgDMQM7f33sZrPNG\n
     36 /05loCXujfAtCAVgNgLwIuycjQAra8G9Fm823ADabPRA1QDelfZAVUZktWrNvL8ew5YTnsStx3Am\n
     37 AyOInJVbYF1prZuU+tsR1g9UMDqGuo5oFWhtSEQNEGmeVrqv73Tj0pIZirANMYqRhyw5Bb9MauSW\n
     38 SwA8l9OzG5LnAsiiDQGQRRvaEwInK54J390hndAIYIeQ4k6AAjE/h06ab0SjP08MA1xDAAAAJXRF\n
     39 WHRkYXRlOmNyZWF0ZQAyMDExLTAxLTEyVDA5OjM0OjI0KzAxOjAwo//d7wAAACV0RVh0ZGF0ZTpt\n
     40 b2RpZnkAMjAxMS0wMS0xMlQwOTozNDoyNCswMTowMNKiZVMAAAAASUVORK5CYII="
     41 echo -e "$ICONB64" | base64 --decode > $MONMORT
     42 # }}}
     43 
     44 # {{{ sudo functions
     45 function _sudo {
     46     sudoassword=$(ask_password "Insert sudo password for user $USER")
     47     echo -e "$sudoassword\n" | sudo -S -v
     48     _sudowrong
     49 }
     50 
     51 function _sudowrong {
     52     [[ $? = 0 ]] || {
     53         sudoassword=$(ask_password "Wrong password. Insert sudo password for user $USER")
     54         echo -e "$sudoassword\n" | sudo -S -v
     55         _sudowrong
     56     }
     57 }
     58 # }}}
     59 
     60 # {{{ Zenity dialogs
     61 function _zenques {
     62     zenity \
     63         --window-icon="$MONMORT" \
     64         --question \
     65         --text="$1"
     66 }
     67 function _fsel {
     68     zenity \
     69         --window-icon="$MONMORT" \
     70         --file-selection \
     71         --title="$1"
     72 }
     73 function _fsave {
     74     zenity \
     75         --window-icon="$MONMORT" \
     76         --file-selection \
     77         --save \
     78         --title="$1" \
     79         --filename="$2"
     80 }
     81 function _zenwarn {
     82     zenity \
     83         --window-icon="$MONMORT" \
     84         --warning \
     85         --title="$1" \
     86         --text="$2"
     87 }
     88 function _info {
     89     which notify-send > /dev/null
     90     if [[ $? == "0" ]]; then
     91         _zenotif $*
     92     else
     93         _zeninfo $*
     94     fi
     95 }
     96 function _zenotif {
     97     zenity \
     98         --window-icon="$MONMORT" \
     99         --notification \
    100         --title="$1" \
    101         --text="$2"
    102 }
    103 function _zeninfo {
    104     zenity \
    105         --window-icon="$MONMORT" \
    106         --info \
    107         --title="$1" \
    108         --text="$2"
    109 }
    110 function _zenerr {
    111     zenity \
    112         --window-icon="$MONMORT" \
    113         --error \
    114         --title="$1" \
    115         --text="$2"
    116 }
    117 function _zenprog {
    118     zenity \
    119         --window-icon="$MONMORT" \
    120         --progress \
    121         --auto-close \
    122         --pulsate \
    123         --title="$1" \
    124         --text="$2"
    125 }
    126 function _zenprognc {
    127     zenity \
    128         --window-icon="$MONMORT" \
    129         --progress \
    130         --auto-close \
    131         --no-cancel \
    132         --pulsate \
    133         --title="$1" \
    134         --text="$2"
    135 }
    136 function _zenentry {
    137     zenity \
    138         --window-icon="$MONMORT" \
    139         --entry \
    140         --title="$1" \
    141         --text="$2" \
    142         --entry-text="$3"
    143 }
    144 # }}}
    145 
    146 # {{{ Some pinentry code shamelessly stolen from tomb
    147 # Ask user for a password
    148 # Wraps around the pinentry command, from the GnuPG project, as it
    149 # provides better security and conveniently use the right toolkit.
    150 ask_password() {
    151     local description="$1"
    152     local title="${2:-Enter tomb password.}"
    153     local output
    154     local password
    155     local gtkrc
    156     local theme
    157 
    158     # Distributions have broken wrappers for pinentry: they do
    159     # implement fallback, but they disrupt the output somehow.  We are
    160     # better off relying on less intermediaries, so we implement our
    161     # own fallback mechanisms. Pinentry supported: curses, gtk-2, qt4
    162     # and x11.
    163 
    164     # make sure LANG is set, default to C
    165     LANG=${LANG:-C}
    166 
    167     _verbose "asking password with tty=$TTY lc-ctype=$LANG"
    168 
    169     if [[ "$DISPLAY" = "" ]]; then
    170 
    171         if _is_found "pinentry-curses"; then
    172             _verbose "using pinentry-curses"
    173             output=`cat <<EOF | pinentry-curses
    174 OPTION ttyname=$TTY
    175 OPTION lc-ctype=$LANG
    176 SETTITLE $title
    177 SETDESC $description
    178 SETPROMPT Password:
    179 GETPIN
    180 EOF`
    181         else
    182             _failure "Cannot find pinentry-curses and no DISPLAY detected."
    183         fi
    184 
    185     else # a DISPLAY is found to be active
    186 
    187         # customized gtk2 dialog with a skull (if extras are installed)
    188         if _is_found "pinentry-gtk-2"; then
    189             _verbose "using pinentry-gtk2"
    190 
    191             gtkrc=""
    192             theme=/share/themes/tomb/gtk-2.0-key/gtkrc
    193             for i in /usr/local /usr; do
    194                 [[ -r $i/$theme ]] && {
    195                     gtkrc="$i/$theme"
    196                     break
    197                 }
    198             done
    199             [[ "$gtkrc" = "" ]] || {
    200                 gtkrc_old="$GTK2_RC_FILES"
    201                 export GTK2_RC_FILES="$gtkrc"
    202             }
    203             output=`cat <<EOF | pinentry-gtk-2
    204 OPTION ttyname=$TTY
    205 OPTION lc-ctype=$LANG
    206 SETTITLE $title
    207 SETDESC $description
    208 SETPROMPT Password:
    209 GETPIN
    210 EOF`
    211             [[ "$gtkrc" = "" ]] || export GTK2_RC_FILES="$gtkrc_old"
    212 
    213             # TODO QT4 customization of dialog
    214         elif _is_found "pinentry-qt4"; then
    215             _verbose "using pinentry-qt4"
    216 
    217             output=`cat <<EOF | pinentry-qt4
    218 OPTION ttyname=$TTY
    219 OPTION lc-ctype=$LANG
    220 SETTITLE $title
    221 SETDESC $description
    222 SETPROMPT Password:
    223 GETPIN
    224 EOF`
    225 
    226             # TODO X11 customization of dialog
    227         elif _is_found "pinentry-x11"; then
    228             _verbose "using pinentry-x11"
    229 
    230             output=`cat <<EOF | pinentry-x11
    231 OPTION ttyname=$TTY
    232 OPTION lc-ctype=$LANG
    233 SETTITLE $title
    234 SETDESC $description
    235 SETPROMPT Password:
    236 GETPIN
    237 EOF`
    238 
    239         else
    240 
    241             if _is_found "pinentry-curses"; then
    242                 _verbose "using pinentry-curses"
    243 
    244                 _warning "Detected DISPLAY, but only pinentry-curses is found."
    245                 output=`cat <<EOF | pinentry-curses
    246 OPTION ttyname=$TTY
    247 OPTION lc-ctype=$LANG
    248 SETTITLE $title
    249 SETDESC $description
    250 SETPROMPT Password:
    251 GETPIN
    252 EOF`
    253             else
    254                 _failure "Cannot find any pinentry: impossible to ask for password."
    255             fi
    256 
    257         fi
    258 
    259     fi # end of DISPLAY block
    260 
    261     # parse the pinentry output
    262     for i in ${(f)output}; do
    263         [[ "$i" =~ "^ERR.*" ]] && {
    264             _warning "Pinentry error: ::1 error::" ${i[(w)3]}
    265             print "canceled"
    266             return 1 }
    267 
    268         # here the password is found
    269         [[ "$i" =~ "^D .*" ]] && password="${i##D }"
    270     done
    271 
    272     [[ "$password" = "" ]] && {
    273         _warning "Empty password"
    274         print "empty"
    275         return 1 }
    276 
    277     print "$password"
    278     return 0
    279 }
    280 
    281 _is_found() {
    282     # returns 0 if binary is found in path
    283     [[ "$1" = "" ]] && return 1
    284     command -v "$1" 1>/dev/null 2>/dev/null
    285     return $?
    286 }
    287 
    288 function _warning  no() {
    289     option_is_set -q || _msg warning $@
    290     return 1
    291 }
    292 
    293 function _verbose xxx() {
    294     option_is_set -D && _msg verbose $@
    295     return 0
    296 }
    297 
    298 function _failure die() {
    299     typeset -i exitcode=${exitv:-1}
    300     option_is_set -q || _msg failure $@
    301     # be sure we forget the secrets we were told
    302     exit $exitcode
    303 }
    304 # }}}
    305 
    306 # {{{ _clean - Clean function, removes sensitive stuff from memory
    307 function _clean {
    308     unset $?
    309     local rr="$RANDOM"
    310     while [[ ${#rr} -lt 500 ]]; do
    311         rr+="$RANDOM"
    312     done
    313 
    314     cmnd="$rr";         unset cmnd
    315     tombname="$rr";     unset tombname
    316     tombsize="$rr";     unset tombsize
    317     keyfile="$rr";      unset keyfile
    318     sudoassword="$rr";  unset sudoassword
    319     tombtmp="/tmp/tombtmp"
    320     if [ -f $tombtmp ]; then
    321         dd if=/dev/urandom of=$tombtmp bs=800 count=1
    322         rm -f $tombtmp
    323     fi
    324     tombtmp="$rr";      unset tombtmp
    325     newkey="$rr";       unset newkey
    326     jpegfile="$rr";     unset jpegfile
    327 }
    328 # }}}
    329 
    330 # {{{ _main - Main window
    331 function _main {
    332     _clean
    333     cmnd=`zenity \
    334         --window-icon="$MONMORT" \
    335         --title="gtomb" \
    336         --width=640 \
    337         --height=420 \
    338         --list \
    339         --hide-header \
    340         --text="gtomb v$ver\nThe GUI wrapper for Tomb, the crypto undertaker." \
    341         --separator=" & " \
    342         --column=Function \
    343         --column=Description \
    344         "dig" "Dig a new tomb of chosen size" \
    345         "forge" "Forge a new key used to lock tombs" \
    346         "lock" "Lock a non-locked tomb using an existing key" \
    347         "open" "Open an existing tomb" \
    348         "index" "Index the contents of all tombs." \
    349         "search" "Search the content of indexed tombs." \
    350         "list" "List all open tombs and information on them" \
    351         "close" "Close a specific tomb (or all)" \
    352         "slam" "Slam a tomb (or all) killing all programs using it" \
    353         "resize" "Resize a tomb to a new size (can only grow)" \
    354         "passwd" "Change the passphrase of a key" \
    355         "setkey" "Change the key of an existing tomb" \
    356         "engrave" "Generates a QR code of a key to be saved on paper" \
    357         "bury" "Hide a key inside a JPEG image" \
    358         "exhume" "Extract a key from a JPEG image"`
    359     eval "_$cmnd"
    360 }
    361 # }}}
    362 
    363 # {{{ dig - Dig a new tomb
    364 function _dig {
    365     tombname=`_fsave "Choose where to dig your tomb" "secret.tomb"`
    366     res=$?
    367 
    368     if [[ -f "$tombname" ]]; then
    369         _zenerr "Error" "This tomb already exists. I am not digging here."
    370         exec _main
    371     elif [[ -z "$tombname" ]]; then
    372         _info "gtomb" "Cancelled"
    373         exec _main
    374     fi
    375 
    376 	[[ $res = 0 ]] || exec _main
    377 
    378 	tombsize=`_zenentry "Tomb digging" "Enter the size of your tomb in MiB (min. 10 MiB)" "10"`
    379 	res=$?
    380 
    381 	re='^[0-9]+$'
    382 	if ! [[ $tombsize =~ $re ]]; then
    383 		_zenerr "Error" "Please choose a valid number."
    384 		exec _main
    385 	elif [[ -z $tombsize ]]; then
    386 		_info "gtomb" "Cancelled"
    387 		exec _main
    388 	fi
    389 
    390 	[[ $res = 0 ]] || { _zenwarn "Warning" "Tomb digging canceled." ; exec _main }
    391 
    392 	"$TOMBPATH" dig -s "$tombsize" "$tombname" | \
    393 		_zenprog "Digging new tomb" "Please wait while your tomb is being dug..." &
    394 
    395 	PID_ZEN=$(ps -C zenity h -o pid,command | awk '/Digging new tomb/ {print $1}')
    396 	while [ -n "$PID_ZEN" ]; do
    397 		PID_ZEN=$(ps h -o pid -p ${PID_ZEN})
    398 		PID_DD=$(ps -C $_DD h -o pid,command | awk -v tombtmp="$tombname" '$0~tombtmp{print $1}')
    399 		sleep 1
    400 	done
    401 
    402 	[[ -n "$PID_DD" && -z "$PID_ZEN" ]] && {
    403 		kill -9 $PID_DD
    404 		_zenwarn "Warning" "Tomb digging cancelled."
    405 		rm -f "$tombname"
    406 		exec _main
    407 	}
    408 
    409 	_info "Success" "Your tomb has been dug in $tombname"
    410 	exec _main
    411 }
    412 # }}}
    413 
    414 # {{{ forge - Forge a new key
    415 function _forge {
    416     keyfile=`_fsave "Choose where to forge your key" "secret.tomb.key"`
    417     res=$?
    418 
    419     if [[ -f $keyfile ]]; then
    420         _zenerr "Error" "This key already exists. I am not overwriting."
    421         exec _main
    422     elif [[ -z $keyfile ]]; then
    423         _info "gtomb" "Canceled"
    424         exec _main
    425     fi
    426 
    427     kdf=""
    428     kdfiter=""
    429     if [[ -x $HEXENC ]] && [[ -x $GENSALT ]] && [[ -x $GETITER ]] && [[ -x $PBKDF ]]; then
    430         _zenques "Do you want to use KDF? (Generates passwords armored against dictionary attacks)"
    431         [[ $? == "0" ]] && {
    432             kdf="--kdf"
    433             kdfiter=`_zenentry "Iterations" "Enter the delay (itertime) in seconds for each time \n\
    434 this key is used:" "2"`
    435 
    436             re='^[0-9]+$'
    437             if ! [[ $kdfiter =~ $re ]]; then
    438                 _zenerr "Error" "Please choose a valid number."
    439                 exec _main
    440             elif [[ -z $kdfiter ]]; then
    441                 _info "gtomb" "Canceled"
    442                 exec _main
    443             fi
    444         }
    445     else
    446         _zenotif "gtomb" "KDF binaries not found."
    447     fi
    448 
    449 	[[ $? = 0 ]] || exec _main
    450 
    451 	"$TOMBPATH" forge "$keyfile" "$kdf" "$kdfiter" | \
    452 		_zenprog "Forging key" "Please wait while your key is being forged...\n\
    453 You can move your mouse around and use your computer to speed up the process." &
    454 
    455 	PID_ZEN=$(ps -C zenity h -o pid,command | awk '/Forging key/ {print $1}')
    456 	while [ -n "$PID_ZEN" ]; do
    457 		PID_ZEN=$(ps h -o pid -p ${PID_ZEN})
    458 		PID_DD=$(ps -C $_DD h -o pid,command | awk '/ if/ {print $1}')
    459 		sleep 1
    460 	done
    461 	[[ -n "$PID_DD"  && -z "$PID_ZEN" ]] && {
    462 		kill -9 $PID_DD
    463 		_zenwarn "Warning" "Forging cancelled."
    464 		rm -f $keyfile
    465 		exec _main
    466 	}
    467 
    468 	_info "Success" "Your key is now forged in $keyfile"
    469 	exec _main
    470 }
    471 # }}}
    472 
    473 # {{{ lock - Lock a non-locked tomb
    474 function _lock {
    475     tombname=`_fsel "Select a tomb to lock"`
    476     [[ -n $tombname ]] || { _zenotif "gtomb" "Cancelled" ; exec _main }
    477 	[[ $? = 0 ]] || exec _main
    478 
    479 	keyfile=`_fsel "Choose the key for your tomb"`
    480 	[[ -n $keyfile ]] || { _zenotif "gtomb" "Cancelled" ; exec _main }
    481 	[[ $? = 0 ]] || exec _main
    482 
    483 	_sudo
    484 	"$TOMBPATH" lock "$tombname" -k "$keyfile" | \
    485 		_zenprognc "Locking your tomb" "Please wait while your tomb is being locked..."
    486 	_info "Success" "Your tomb is now locked."
    487 	exec _main
    488 }
    489 # }}}
    490 
    491 # {{{ open - Open an existing tomb
    492 function _open {
    493     tombname=`_fsel "Choose a tomb to open"`
    494 	[[ $? = 0 ]] || exec _main
    495 
    496 	keyfile=`_fsel "Choose the key for your tomb"`
    497 	[[ $? = 0 ]] || exec _main
    498 
    499 	_sudo
    500 	"$TOMBPATH" open "$tombname" -k "$keyfile"
    501 	_info "Success" "Your tomb is now open."
    502 	exec _main
    503 }
    504 # }}}
    505 
    506 # {{{ list - list all open tombs, along with their mountpoint
    507 function _list {
    508     tombtmp="/tmp/tombtmp"
    509     "$TOMBPATH" list --get-mountpoint > $tombtmp
    510     tombname=`cat $tombtmp | \
    511         sed 's/.*\/\([^\/]*\)$/\1\n &/' | \
    512         zenity \
    513             --title="Currently open tombs" \
    514             --window-icon="$MONMORT" \
    515             --width=640 --height=380 --list \
    516             --separator=" & " \
    517             --text="Here are your open tombs" \
    518             --column=Tomb \
    519             --column=Path `
    520 
    521     tombname=`echo "$tombname" | cut -c1-16`
    522 
    523 	[[ $? = 0 ]] || exec _main
    524 
    525 	listchoice=`zenity \
    526 		--title="Choose action" \
    527 		--window-icon="$MONMORT" \
    528 		--width=640 --height=400 --list \
    529 		--separator=" & " \
    530 		--text="What do you want to do with this tomb?" \
    531 		--column=Command \
    532 		--column=Description \
    533 		"disindex" "Disable indexing of this tomb." \
    534 		"enindex" "Enable indexing of this tomb."   \
    535 		"close" "Close the selected tomb." \
    536 		"slam" "Slam the selected tomb." \
    537 		"binds" "Edit current bind-hooks." \
    538 		"posts" "Edit current post-hooks."`
    539 
    540 	[[ $? = 0 ]] || exec _main
    541 
    542 	case $listchoice in
    543 		close)
    544 			_sudo
    545 			"$TOMBPATH" close "$tombname"
    546 			_zeninfo "Success" "Tomb closed successfully!"
    547 			exec _main
    548 			;;
    549 		slam)
    550 			_sudo
    551 			"$TOMBPATH" slam "$tombname"
    552 			_info "Success" "$tombname slammed successfully!"
    553 			exec _main
    554 			;;
    555 		disindex)
    556 			tombloc=`"$TOMBPATH" list "$tombname" --get-mountpoint`
    557 			touch "$tombloc/.noindex"
    558 			_info "Success" "Indexing disabled for this tomb."
    559 			exec _main
    560 			;;
    561 		enindex)
    562 			tombloc=`"$TOMBPATH" list "$tombname" --get-mountpoint`
    563 			rm -f "$tombloc/.noindex"
    564 			_info "Success" "Indexing of this tomb is now enabled."
    565 			exec _main
    566 			;;
    567 		binds)
    568 			tombloc=`"$TOMBPATH" list "$tombname" --get-mountpoint`
    569 			bindhooks=`zenity \
    570 				--text-info \
    571 				--filename="$tombloc/bind-hooks" \
    572 				--editable`
    573 			[[ $? = 0 ]] && {
    574 				echo "$bindhooks" > "$tombloc/bind-hooks"
    575 				_info "gtomb" "bind-hooks saved"
    576 			}
    577 			exec _main
    578 			;;
    579 		posts)
    580 			tombloc=`"$TOMBPATH" list "$tombname" --get-mountpoint`
    581 			posthooks=`zenity \
    582 				--text-info \
    583 				--filename="$tombloc/post-hooks" \
    584 				--editable`
    585 			[[ $? = 0 ]] && {
    586 				echo "$posthooks" > "$tombloc/post-hooks"
    587 				chmod +x "$tombloc/post-hooks"
    588 				_info "gtomb" "post-hooks saved"
    589 			}
    590 			exec _main
    591 			;;
    592 	esac
    593 }
    594 # }}}
    595 
    596 # {{{ close - Close open tomb(s)
    597 function _close {
    598     tombtmp="/tmp/tombtmp"
    599     "$TOMBPATH" list --get-mountpoint > $tombtmp
    600     echo "/all" >> $tombtmp
    601     tombname=`cat $tombtmp | \
    602         sed 's/.*\/\([^\/]*\)$/\1\n &/' | \
    603         zenity \
    604             --title="Choose a tomb to close" \
    605             --window-icon="$MONMORT" \
    606             --width=640 --height=380 --list \
    607             --separator=" & " \
    608             --column=Tomb \
    609             --column=Path `
    610 
    611 	[[ $? = 0 ]] || exec _main
    612 
    613 	_sudo
    614 	tombname=`echo "$tombname" | cut -c1-16`
    615 	"$TOMBPATH" close "$tombname"
    616 	_info "Success" "Closed successfully!"
    617 	exec _main
    618 }
    619 # }}}
    620 
    621 # {{{ slam - Slam open tombs
    622 function _slam {
    623     tombtmp="/tmp/tombtmp"
    624     "$TOMBPATH" list --get-mountpoint > $tombtmp
    625     echo "/all" >> $tombtmp
    626     tombname=`cat $tombtmp | \
    627         sed 's/.*\/\([^\/]*\)$/\1\n &/' | \
    628         zenity \
    629             --title="Choose a tomb to slam" \
    630             --window-icon="$MONMORT" \
    631             --width=640 --height=380 --list \
    632             --separator=" & " \
    633             --column=Tomb \
    634             --column=Path `
    635 
    636 	[[ $? = 0 ]] || exec _main
    637 
    638 	_sudo
    639 	tombname=`echo "$tombname" | cut -c1-16`
    640 	"$TOMBPATH" slam "$tombname"
    641 	_info "Success" "Slammed successfully!"
    642 	exec _main
    643 }
    644 # }}}
    645 
    646 # {{{ resize - Resize an existing *closed* tomb
    647 function _resize {
    648     tombname=`_fsel "Choose a tomb to resize"`
    649     res=$?
    650     _zenques "Is your tomb closed?"
    651 
    652 	[[ $? = 0 ]] || { _zenwarn "gtomb" "Please close the tomb before resizing." ; exec _main }
    653 
    654 	[[ $res = 0 ]] || exec _main
    655 
    656 	tombsize=`_zenentry "New tomb size" "Enter the new size of your tomb in MiB. Must be higher than the current size." "100"`
    657 	[[ -n $tombsize ]] || _zenotif "gtomb" "Cancelled"
    658 
    659 	re='^[0-9]+$'
    660 	if ! [[ $tombsize =~ $re ]]; then
    661 		_zenerr "Error" "Please choose a valid number."
    662 		exec _main
    663 	elif [[ -z $tombsize ]]; then
    664 		_info "gtomb" "Cancelled"
    665 		exec _main
    666 	fi
    667 
    668 	[[ $? = 0 ]] || exec _main
    669 
    670 	keyfile=`_fsel "Choose according keyfile"`
    671 	[[ $? = 0 ]] || exec _main
    672 
    673 	_sudo
    674 	"$TOMBPATH" resize "$tombname" -s "$tombsize" -k "$keyfile" | \
    675 		_zenprognc "Resizing tomb." "Please wait while your tomb is being resized..."
    676 	_info "Success" "Tomb resized successfully!"
    677 	exec _main
    678 }
    679 # }}}
    680 
    681 # {{{ passwd - Change existing key's passphrase
    682 function _passwd {
    683     keyfile=`_fsel "Choose a keyfile"`
    684 	[[ $? = 0 ]] || exec _main
    685 
    686 	"$TOMBPATH" passwd -k "$keyfile" | \
    687 		_zenprognc "Changing passphrase" "Please wait while your key's passphrase is being changed..."
    688 
    689 	_info "Success" "$keyfile passphrase changed successfully!"
    690 	exec _main
    691 }
    692 # }}}
    693 
    694 # {{{ setkey - Change a tomb's keyfile
    695 function _setkey {
    696     tombname=`_fsel "Choose a tomb to change its keyfile"`
    697 	[[ $? = 0 ]] || exec _main
    698 
    699 	keyfile=`_fsel "Chosse your tomb's old keyfile"`
    700 	 [[ $? = 0 ]] || exec _main
    701 
    702 	newkey=`_fsel "Choose your tomb's new keyfile"`
    703 	[[ $? = 0 ]] || exec _main
    704 
    705 	_sudo
    706     "$TOMBPATH" setkey -k "$newkey" "$keyfile" "$tombname" | \
    707 		_zenprognc "Changing key" "Please wait while your tomb's key is being changed..."
    708 
    709 	_info "Success" "$tombname keyfile successfully changed! Now using $newkey"
    710     exec _main
    711 }
    712 # }}}
    713 
    714 # {{{ engrave - generate QR code of a key
    715 function _engrave {
    716     which qrencode || _zenwarn "Warning" "qrencode is not installed. Install it and try again"
    717     keyfile=`_fsel "Choose a keyfile to engrave"`
    718 	[[ $? = 0 ]] || exec _main
    719 
    720 	jpegfile=`_fsave "Choose where to save your keyfile (PNG format)"`
    721 	[[ $? = 0 ]] || exec _main
    722 
    723 	awk '/^-----/ {next}; /^Version/ {next}; {print $0}' $keyfile \
    724 		| qrencode --size 4 --level H --casesensitive -o $jpegfile
    725 
    726 	_info "Success" "QR code generated in $jpegfile"
    727 	exec _main
    728 }
    729 # }}}
    730 
    731 # {{{ bury - hide a keyfile in a JPEG image
    732 function _bury {
    733     which steghide || _zenwarn "Warning" "steghide is not installed. Install it and try again"
    734     keyfile=`_fsel "Choose keyfile"`
    735 	[[ $? = 0 ]] || exec _main
    736 
    737 	jpegfile=`_fsel "Choose JPEG file"`
    738 	[[ $? = 0 ]] || exec _main
    739 
    740 	"$TOMBPATH" bury -k "$keyfile" "$jpegfile"
    741 	_info "Success" "Your key is now hidden in $jpegfile"
    742 	exec _main
    743 }
    744 # }}}
    745 
    746 # {{{ exhume - extract keyfile from JPEG
    747 function _exhume {
    748     which steghide || _zenwarn "Warning" "steghide is not installed. Install it and try again"
    749     jpegfile=`_fsel "Choose JPEG file"`
    750 	[[ $? = 0 ]] || exec _main
    751 
    752 	keyfile=`_fsave "Choose where to extract your key"`
    753 	[[ $? = 0 ]] || exec _main
    754 
    755 	"$TOMBPATH" exhume -k "$keyfile" "$jpegfile"
    756 	_info "Success" "Your keyfile is extracted to $keyfile"
    757 	exec _main
    758 }
    759 # }}}
    760 
    761 # {{{ index - index the contents of open tombs
    762 function _index {
    763     which locate || _zenwarn "Warning" "mlocate is not installed. Install it and try again"
    764     "$TOMBPATH" index | _zenprognc "Indexing" "Please wait while the open tombs are being indexed..."
    765     _info "Success" "Tombs indexed!"
    766     exec _main
    767 }
    768 # }}}
    769 
    770 # {{{ search - searches the contents of indexed tombs
    771 function _search {
    772     strings=""
    773     _searchstring
    774     exec _main
    775 }
    776 
    777 function _searchstring {
    778 	srchstring=`_zenentry "Search" "Enter an argument to search. Cancel to finish."`
    779 	res=$?
    780 	strings="$strings $srchstring"
    781 
    782 	if [[ $res = 1 ]]; then
    783 		tombtmp="/tmp/tombtmp"
    784 		_info "Success" "Search complete!"
    785 		"$TOMBPATH" search "$strings" > $tombtmp
    786 			zenity \
    787 				--text-info \
    788 				--width=800 --height=640 \
    789 				--title="Search results" \
    790 				--filename=$tombtmp
    791 	else
    792 		_searchstring
    793 	fi
    794 }
    795 
    796 
    797 # }}}
    798 
    799 function _ { _clean } # I like cleaning :)
    800 
    801 [[ -x $TOMBPATH ]] || {
    802     _zenwarn "Warning" "Tomb binary is not executable or doesn't exist in the current path. Install it or edit the script to point to the correct path."
    803 	exit 1 }
    804 
    805 _main