new tomb command 'passwd' can change a key password

usage: tomb passwd /path/to/keyfile.key
 documented in man page
 adds feature #46
 adds internal func safe_file()
 adds parameters for askpass() function messaging
This commit is contained in:
Anathema 2011-11-03 15:13:49 +01:00 committed by Jaromil
parent 30c862e36f
commit 9b6a716672
4 changed files with 167 additions and 11 deletions

View File

@ -66,6 +66,12 @@ command will list them on the terminal. The special
fails if the tomb is in use by running processes, the command fails if the tomb is in use by running processes, the command
\fIslam\fR can be used to force close. \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 .B
.IP "slam" .IP "slam"
Closes a tomb like the command \fIclose\fR does, but in case it is in Closes a tomb like the command \fIclose\fR does, but in case it is in
@ -135,8 +141,12 @@ Display version and quit
.B .B
.IP "-q" .IP "-q"
Run more quietly Run more quietly
.B
.IP "-D" .IP "-D"
Print more information while running, for debugging purposes 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 .SH HOOKS

View File

@ -66,6 +66,12 @@ command will list them on the terminal. The special
fails if the tomb is in use by running processes, the command fails if the tomb is in use by running processes, the command
\fIslam\fR can be used to force close. \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 .B
.IP "slam" .IP "slam"
Closes a tomb like the command \fIclose\fR does, but in case it is in Closes a tomb like the command \fIclose\fR does, but in case it is in
@ -135,8 +141,12 @@ Display version and quit
.B .B
.IP "-q" .IP "-q"
Run more quietly Run more quietly
.B
.IP "-D" .IP "-D"
Print more information while running, for debugging purposes 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 .SH HOOKS

View File

@ -66,6 +66,12 @@ command will list them on the terminal. The special
fails if the tomb is in use by running processes, the command fails if the tomb is in use by running processes, the command
\fIslam\fR can be used to force close. \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 .B
.IP "slam" .IP "slam"
Closes a tomb like the command \fIclose\fR does, but in case it is in Closes a tomb like the command \fIclose\fR does, but in case it is in

152
src/tomb
View File

@ -27,6 +27,7 @@ TOMBOPENEXEC="tomb-open"
typeset -a OLDARGS typeset -a OLDARGS
for arg in ${argv}; do OLDARGS+=($arg); done for arg in ${argv}; do OLDARGS+=($arg); done
STEGHIDE=1 STEGHIDE=1
MKTEMP=1
MOUNTOPTS="rw,noatime,nodev" MOUNTOPTS="rw,noatime,nodev"
#declare global variables #declare global variables
@ -102,6 +103,11 @@ check_bin() {
exit 1 exit 1
fi fi
which mktemp > /dev/null
if [ $?! = 0 ]; then
MKTEMP=0
fi
# check for tomb-open script # check for tomb-open script
if [ "$0" = "./tomb" ]; then if [ "$0" = "./tomb" ]; then
TOMBOPENEXEC="./tomb-open" TOMBOPENEXEC="./tomb-open"
@ -122,6 +128,19 @@ safe_dir() {
print "$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 if there is swap activated
check_swap() { check_swap() {
# Return 0 if NO swap is used, 1 if swap is used # Return 0 if NO swap is used, 1 if swap is used
@ -152,11 +171,14 @@ ask_password() {
GTK2_RC=/usr/share/themes/tomb/gtk-2.0-key/gtkrc GTK2_RC=/usr/share/themes/tomb/gtk-2.0-key/gtkrc
fi 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 }' cat <<EOF | GTK2_RC_FILES=${GTK2_RC} pinentry 2>/dev/null | awk '/^D / { sub(/^D /, ""); print }'
OPTION ttyname=$TTY OPTION ttyname=$TTY
OPTION lc-ctype=$LANG OPTION lc-ctype=$LANG
SETTITLE Insert tomb password SETTITLE $title
SETDESC Open tomb: $1 SETDESC $1
SETPROMPT Password: SETPROMPT Password:
GETPIN GETPIN
EOF EOF
@ -216,6 +238,7 @@ Commands:
list list all open tombs or the one called FILE list list all open tombs or the one called FILE
close close the open tomb called FILE (or all) close close the open tomb called FILE (or all)
slam close tomb FILE and kill all pids using it slam close tomb FILE and kill all pids using it
passwd change the password of a tomb key FILE
EOF EOF
if [ "$STEGHIDE" = 1 ]; then if [ "$STEGHIDE" = 1 ]; then
cat <<EOF cat <<EOF
@ -394,9 +417,9 @@ create_tomb() {
# here user is prompted for key password # here user is prompted for key password
for c in 1 2 3; do for c in 1 2 3; do
# 3 tries to write two times a matching password # 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 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 if [ "$tombpasstmp" = "$tombpass" ]; then
break; break;
fi fi
@ -569,9 +592,9 @@ mount_tomb() {
notice "Password is required for key ${keyname}" notice "Password is required for key ${keyname}"
for c in 1 2 3; do for c in 1 2 3; do
if [ $c = 1 ]; then if [ $c = 1 ]; then
tombpass=`exec_as_user ${TOMBEXEC} askpass ${keyname}` tombpass=`exec_as_user ${TOMBEXEC} askpass "Open tomb ${keyname}"`
else else
tombpass=`exec_as_user ${TOMBEXEC} askpass "$keyname (retry $c)"` tombpass=`exec_as_user ${TOMBEXEC} askpass "Open tomb $keyname (retry $c)"`
fi fi
(gpg --batch --passphrase-fd 0 --no-tty --no-options \ (gpg --batch --passphrase-fd 0 --no-tty --no-options \
-d "${tombkey}" 2> /dev/null <<< ${tombpass} ) \ -d "${tombkey}" 2> /dev/null <<< ${tombpass} ) \
@ -637,9 +660,9 @@ encode_key() {
# here user is prompted for key password # here user is prompted for key password
for c in 1 2 3; do for c in 1 2 3; do
# 3 tries to write two times a matching password # 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 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 if [ "$tombpasstmp" = "$tombpass" ]; then
break; break;
fi fi
@ -690,9 +713,9 @@ decode_key() {
notice "Trying to exhume a key out of image $imagefile" notice "Trying to exhume a key out of image $imagefile"
for c in 1 2 3; do for c in 1 2 3; do
if [ $c = 1 ]; then if [ $c = 1 ]; then
tombpass=`exec_as_user ${TOMBEXEC} askpass ${keyfile}` tombpass=`exec_as_user ${TOMBEXEC} askpass "Steg password for ${keyfile}"`
else else
tombpass=`exec_as_user ${TOMBEXEC} askpass "$keyfile (retry $c)"` tombpass=`exec_as_user ${TOMBEXEC} askpass "Steg password for $keyfile (retry $c)"`
fi fi
steghide extract -sf ${imagefile} -p ${tombpass} -xf - \ steghide extract -sf ${imagefile} -p ${tombpass} -xf - \
| awk ' | awk '
@ -985,6 +1008,111 @@ umount_tomb() {
return 0 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 all tombs mounted in a readable format
list_tombs() { list_tombs() {
if [ $1 ]; then if [ $1 ]; then
@ -1251,6 +1379,7 @@ main() {
subcommands_opts[open]="n -nohook=n k: -key=k o: -mount-options=o -ignore-swap" subcommands_opts[open]="n -nohook=n k: -key=k o: -mount-options=o -ignore-swap"
subcommands_opts[mount]=${subcommands_opts[open]} subcommands_opts[mount]=${subcommands_opts[open]}
subcommands_opts[create]="s: -size=s -ignore-swap k: -key=k" subcommands_opts[create]="s: -size=s -ignore-swap k: -key=k"
subcommands_opts[passwd]="-ignore-swap"
subcommands_opts[close]="" subcommands_opts[close]=""
subcommands_opts[help]="" subcommands_opts[help]=""
subcommands_opts[slam]="" subcommands_opts[slam]=""
@ -1345,6 +1474,7 @@ main() {
umount) check_priv ; umount_tomb ${CMD2} ;; umount) check_priv ; umount_tomb ${CMD2} ;;
close) check_priv ; umount_tomb ${CMD2} ;; close) check_priv ; umount_tomb ${CMD2} ;;
slam) check_priv ; SLAM=1; umount_tomb ${CMD2} ;; slam) check_priv ; SLAM=1; umount_tomb ${CMD2} ;;
passwd) check_priv ; change_passwd ${CMD2} ;;
list) list_tombs ${CMD2} ;; list) list_tombs ${CMD2} ;;
status) launch_status ${CMD2} ;; status) launch_status ${CMD2} ;;
help) usage ;; help) usage ;;
@ -1361,7 +1491,7 @@ main() {
# internal commands useful to developers # internal commands useful to developers
'source') return 0 ;; 'source') return 0 ;;
install) check_priv ; install_tomb ;; install) check_priv ; install_tomb ;;
askpass) ask_password $CMD2 ;; askpass) ask_password ${CMD2} ${CMD3} ;;
mktemp) safe_dir ${CMD2} ;; mktemp) safe_dir ${CMD2} ;;
translate) generate_translatable_strings ;; translate) generate_translatable_strings ;;
__default) __default)