tMerge pull request #66 from jaromil/passwd - tomb - the crypto undertaker
 (HTM) git clone git://parazyd.org/tomb.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit c150424b728e713450d1420966ab2f68fc3364a2
 (DIR) parent b9722bf14e0a4853b1c1e97b483ecb59ae53c6be
 (HTM) Author: Jaromil <jaromil@dyne.org>
       Date:   Sat,  5 Nov 2011 10:29:15 -0700
       
       Merge pull request #66 from jaromil/passwd
       
       new tomb command 'passwd' can change a key password
       Diffstat:
         M doc/tomb-open.1                     |      10 ++++++++++
         M doc/tomb-status.1                   |      10 ++++++++++
         M doc/tomb.1                          |       6 ++++++
         M src/tomb                            |     152 ++++++++++++++++++++++++++++---
       
       4 files changed, 167 insertions(+), 11 deletions(-)
       ---
 (DIR) diff --git a/doc/tomb-open.1 b/doc/tomb-open.1
       t@@ -67,6 +67,12 @@ fails if the tomb is in use by running processes, the command
        \fIslam\fR can be used to force close.
        
        .B
       +.IP "passwd"
       +Changes the password of a tomb key file specified in the \fIfirst
       +argument\fR. It will need the old password to decode the key file, it
       +will then reencode it using the new password.
       +
       +.B
        .IP "slam"
        Closes a tomb like the command \fIclose\fR does, but in case it is in
        use looks for all the processes accessing its files and violently
       t@@ -135,8 +141,12 @@ Display version and quit
        .B
        .IP "-q"
        Run more quietly
       +.B
        .IP "-D"
        Print more information while running, for debugging purposes
       +.B
       +.IP "--no-color"
       +Don't use colors; useful for old terminals or integration in other scripts
        
        
        .SH HOOKS
 (DIR) diff --git a/doc/tomb-status.1 b/doc/tomb-status.1
       t@@ -67,6 +67,12 @@ fails if the tomb is in use by running processes, the command
        \fIslam\fR can be used to force close.
        
        .B
       +.IP "passwd"
       +Changes the password of a tomb key file specified in the \fIfirst
       +argument\fR. It will need the old password to decode the key file, it
       +will then reencode it using the new password.
       +
       +.B
        .IP "slam"
        Closes a tomb like the command \fIclose\fR does, but in case it is in
        use looks for all the processes accessing its files and violently
       t@@ -135,8 +141,12 @@ Display version and quit
        .B
        .IP "-q"
        Run more quietly
       +.B
        .IP "-D"
        Print more information while running, for debugging purposes
       +.B
       +.IP "--no-color"
       +Don't use colors; useful for old terminals or integration in other scripts
        
        
        .SH HOOKS
 (DIR) diff --git a/doc/tomb.1 b/doc/tomb.1
       t@@ -67,6 +67,12 @@ fails if the tomb is in use by running processes, the command
        \fIslam\fR can be used to force close.
        
        .B
       +.IP "passwd"
       +Changes the password of a tomb key file specified in the \fIfirst
       +argument\fR. It will need the old password to decode the key file, it
       +will then reencode it using the new password.
       +
       +.B
        .IP "slam"
        Closes a tomb like the command \fIclose\fR does, but in case it is in
        use looks for all the processes accessing its files and violently
 (DIR) diff --git a/src/tomb b/src/tomb
       t@@ -27,6 +27,7 @@ TOMBOPENEXEC="tomb-open"
        typeset -a OLDARGS
        for arg in ${argv}; do OLDARGS+=($arg); done
        STEGHIDE=1
       +MKTEMP=1
        MOUNTOPTS="rw,noatime,nodev"
        
        #declare global variables
       t@@ -102,6 +103,11 @@ check_bin() {
                exit 1
            fi
         
       +    which mktemp > /dev/null
       +    if [ $?! = 0 ]; then
       +        MKTEMP=0
       +    fi
       +    
            # check for tomb-open script
            if [ "$0" = "./tomb" ]; then
                TOMBOPENEXEC="./tomb-open"
       t@@ -122,6 +128,19 @@ safe_dir() {
            print "$dir"
        }
        
       +
       +safe_file() {
       +    local tmpdir tmpfile
       +    
       +    if [ "$MKTEMP" = "1" ]; then
       +        mktemp -u /dev/shm/$1.$$.XXXXXXX
       +        # this return needs to output ONLY the file
       +    else 
       +        tmpfile="/dev/shm/$1.$$.$RANDOM.$RANDOM"
       +        print $tmpfile
       +    fi
       +}
       +
        #check if there is swap activated
        check_swap() {
            # Return 0 if NO swap is used, 1 if swap is used
       t@@ -152,11 +171,14 @@ ask_password() {
                GTK2_RC=/usr/share/themes/tomb/gtk-2.0-key/gtkrc
            fi
        
       +    title="Insert tomb password"
       +    if [ $2 ]; then title="$2"; fi
       +
            cat <<EOF | GTK2_RC_FILES=${GTK2_RC} pinentry 2>/dev/null | awk '/^D / { sub(/^D /, ""); print }'
        OPTION ttyname=$TTY
        OPTION lc-ctype=$LANG
       -SETTITLE Insert tomb password
       -SETDESC Open tomb: $1
       +SETTITLE $title
       +SETDESC $1
        SETPROMPT Password:
        GETPIN
        EOF
       t@@ -216,6 +238,7 @@ Commands:
         list       list all open tombs or the one called FILE
         close      close the open tomb called FILE (or all)
         slam       close tomb FILE and kill all pids using it
       + passwd     change the password of a tomb key FILE
        EOF
        if [ "$STEGHIDE" = 1 ]; then
            cat <<EOF
       t@@ -394,9 +417,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 ${TOMBEXEC} askpass ${tombname}`
       +        tombpass=`exec_as_user ${TOMBEXEC} askpass "Secure key for ${tombname}"`
                tombpasstmp=$tombpass
       -        tombpass=`exec_as_user ${TOMBEXEC} askpass "${tombname} (again)"`
       +        tombpass=`exec_as_user ${TOMBEXEC} askpass "Secure key for ${tombname} (again)"`
                if [ "$tombpasstmp" = "$tombpass" ]; then
                    break;
                fi
       t@@ -569,9 +592,9 @@ mount_tomb() {
            notice "Password is required for key ${keyname}"
            for c in 1 2 3; do
                if [ $c = 1 ]; then
       -            tombpass=`exec_as_user ${TOMBEXEC} askpass ${keyname}`
       +            tombpass=`exec_as_user ${TOMBEXEC} askpass "Open tomb ${keyname}"`
                else
       -            tombpass=`exec_as_user ${TOMBEXEC} askpass "$keyname (retry $c)"`
       +            tombpass=`exec_as_user ${TOMBEXEC} askpass "Open tomb $keyname (retry $c)"`
                fi
            (gpg --batch --passphrase-fd 0 --no-tty --no-options \
                -d "${tombkey}" 2> /dev/null <<< ${tombpass} ) \
       t@@ -637,9 +660,9 @@ encode_key() {
            # 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 ${TOMBEXEC} askpass ${tombkey}`
       +        tombpass=`exec_as_user ${TOMBEXEC} askpass "Steg password for ${tombkey}"`
                tombpasstmp=$tombpass
       -        tombpass=`exec_as_user ${TOMBEXEC} askpass "${tombkey} (again)"`
       +        tombpass=`exec_as_user ${TOMBEXEC} askpass "Steg password for ${tombkey} (again)"`
                if [ "$tombpasstmp" = "$tombpass" ]; then
                    break;
                fi
       t@@ -690,9 +713,9 @@ decode_key() {
            notice "Trying to exhume a key out of image $imagefile"
            for c in 1 2 3; do
                if [ $c = 1 ]; then
       -            tombpass=`exec_as_user ${TOMBEXEC} askpass ${keyfile}`
       +            tombpass=`exec_as_user ${TOMBEXEC} askpass "Steg password for ${keyfile}"`
                else
       -            tombpass=`exec_as_user ${TOMBEXEC} askpass "$keyfile (retry $c)"`
       +            tombpass=`exec_as_user ${TOMBEXEC} askpass "Steg password for $keyfile (retry $c)"`
                fi
                steghide extract -sf ${imagefile} -p ${tombpass} -xf - \
                    | awk '
       t@@ -985,6 +1008,111 @@ umount_tomb() {
            return 0
        }
        
       +# change tomb key password
       +change_passwd() {
       +    if ! option_is_set --ignore-swap && [[ `check_swap out` == 1 ]]; then
       +        error "You have swap activated; use --ignore-swap if you want to skip this check"
       +        act "Using encryption with swap activated is very bad, because some files, or even your secret key, could be written on hard disk."
       +        act "However, it could be that your swap is encrypted. If this is case, this is ok. Then, use --ignore-swap to skip this check"
       +        act "You seem to be using `tail -n +2 /proc/swaps|wc -l` swaps:"
       +        tail -n +2 /proc/swaps
       +        return 1
       +    fi
       +    local keyfile="${1}"
       +
       +    # check the keyfile
       +    if ! [ -r $keyfile ]; then
       +            error "key not found: $keyfile"
       +            return 1
       +    fi
       +    
       +    file $keyfile | grep PGP > /dev/null
       +    if [ $? != 0 ]; then
       +            error "file doesn't seems to be a tomb key: $keyfile"
       +            error "operation aborted."
       +            return 1
       +    fi
       +
       +    local tmpnewkey tmpoldkey c tombpass tombpasstmp
       +    
       +    tmpnewkey=`safe_file tomb`
       +    tmpoldkey=`safe_file tomb`
       +    
       +
       +    notice "Changing password for $keyfile"
       +    keyname=`basename $keyfile`
       +    for c in 1 2 3; do
       +            if [ $c = 1 ]; then
       +                tombpass=`exec_as_user ${TOMBEXEC} askpass "Type old password for ${keyname}" "Change tomb key password"`
       +            else
       +                tombpass=`exec_as_user ${TOMBEXEC} askpass "Type old password for ${keyname} (retry $c)" "Change tomb key password"`
       +            fi
       +        gpg --batch --no-options --no-tty --passphrase-fd 0 -o "${tmpoldkey}" -d $keyfile <<< "$tombpass" &> /dev/null
       +        if [ $? = 0 ]; then
       +            tombpass="ok"
       +            break
       +        fi
       +    done
       +
       +    if [ "$tombpass" != "ok" ]; then
       +        error "You typed an Invalid old password. Operation aborted."
       +        # /dev/null because the file cannot exists
       +        ${WIPE[@]} "${tmpnewkey}" 2> /dev/null
       +        ${WIPE[@]} "${tmpoldkey}" 2> /dev/null
       +        return 1
       +    fi
       +
       +    for c in 1 2 3; do
       +            # 3 tries to write two times a matching password
       +            if [ $c = 1 ]; then
       +                tombpass=`exec_as_user ${TOMBEXEC} askpass "Type the new password for ${keyname}" "Change tomb key password"`
       +            else
       +                tombpass=`exec_as_user ${TOMBEXEC} askpass "Type the new password for ${keyname} (retry $c)" "Change tomb key password"`
       +            fi
       +            tombpasstmp=$tombpass
       +            tombpass=`exec_as_user ${TOMBEXEC} askpass "Type the new password again" "Change tomb key password"`
       +            if [ "$tombpasstmp" = "$tombpass" ]; then
       +                break;
       +            fi
       +            unset tombpasstmp
       +            unset tombpass
       +    done
       +
       +    if [ -z $tombpass ]; then
       +            error "You mistyped the new password. Operation aborted."
       +        # /dev/null because the file cannot exists
       +        ${WIPE[@]} "${tmpnewkey}" 2> /dev/null
       +        ${WIPE[@]} "${tmpoldkey}" 2> /dev/null
       +            return 1
       +    fi
       +
       +    gpg \
       +        --openpgp --batch --no-options --no-tty --passphrase-fd 0 \
       +        -o "${tmpnewkey}" -c -a ${tmpoldkey} <<< ${tombpass}
       +    
       +    if [ $? != 0 ]; then
       +        error "Cannot change your key passphrase"
       +        # /dev/null because the file cannot exists
       +        ${WIPE[@]} "${tmpnewkey}" 2> /dev/null
       +        ${WIPE[@]} "${tmpoldkey}" 2> /dev/null
       +        return 1
       +    fi
       +
       +    # wipe the previous, original, key
       +    ${WIPE[@]} "${keyfile}"
       +    # copy the new key as the original keyfile name
       +    cp "${tmpnewkey}" "${keyfile}"
       +
       +    act "Cleaning environment"
       +    # wipe all temp file
       +    ${WIPE[@]} "${tmpnewkey}"
       +    ${WIPE[@]} "${tmpoldkey}"
       +
       +    notice "Your passphrase was successfully updated."
       +
       +    return 0
       +}
       +
        # list all tombs mounted in a readable format
        list_tombs() {
            if [ $1 ]; then
       t@@ -1251,6 +1379,7 @@ main() {
            subcommands_opts[open]="n -nohook=n k: -key=k o: -mount-options=o -ignore-swap"
            subcommands_opts[mount]=${subcommands_opts[open]}
            subcommands_opts[create]="s: -size=s -ignore-swap k: -key=k"
       +    subcommands_opts[passwd]="-ignore-swap"
            subcommands_opts[close]=""
            subcommands_opts[help]=""
            subcommands_opts[slam]=""
       t@@ -1345,6 +1474,7 @@ main() {
                 umount) check_priv ; umount_tomb ${CMD2} ;;
                  close) check_priv ; umount_tomb ${CMD2} ;;
                   slam) check_priv ; SLAM=1; umount_tomb ${CMD2} ;;
       +         passwd) check_priv ; change_passwd ${CMD2} ;;
                   list) list_tombs ${CMD2} ;;
                 status) launch_status ${CMD2} ;;
                   help) usage ;;
       t@@ -1361,7 +1491,7 @@ main() {
                # internal commands useful to developers
               'source') return 0 ;;
                install) check_priv ; install_tomb ;;
       -        askpass) ask_password $CMD2 ;;
       +        askpass) ask_password ${CMD2} ${CMD3} ;;
                 mktemp) safe_dir ${CMD2} ;;
              translate) generate_translatable_strings ;;
              __default)