patternbashMinor
Simple Command Line Password Manager
Viewed 0 times
simplelinepasswordmanagercommand
Problem
Kruptos is a simple tool that encrypts and decrypts the
Goal
I have a couple main goals:
~/.kruptos directory with the password that is stored in ~/.kruptos/.phrazein. There are 3 commands:- e - Encrypt
- d - Decrypt
- i - Initialize
Goal
I have a couple main goals:
- Design: How could I make this more resilient to change?
- Readability: How could I make this more readable?
- Best Practices: Are there aspects of a bash command that I am missing?
# Minimalist password manager
function kruptos
{
# Decipher the flag
if [[ $# -eq 1 ]]; then
DOWHAT="$1"
else
DOWHAT="d"
fi
# Perform an action
if [[ $DOWHAT == "d" ]]; then
#Decrypt
pushd . &>/dev/null
cd ~/
openssl aes-256-cbc -d -in .kruptos.tar.gz.aes | tar -xz -f - --strip-components=2 && rm ~/.kruptos.tar.gz.aes
popd &>/dev/null
elif [[ $DOWHAT == "e" ]]; then
#Encrypt
tar -zcf - ~/.kruptos | openssl aes-256-cbc -out ~/.kruptos.tar.gz.aes -kfile ~/.kruptos/.phrazein && rm -r ~/.kruptos
elif [[ $DOWHAT == "i" ]]; then
#Initialize
mkdir ~/.kruptos
echo pswd > ~/.kruptos/.phrazein
else
echo "$DOWHAT is not an acceptable flag"
fi
}
Solution
I'll not address the security analysis; I'll assume you've done threat modelling and are happy with the overall approach.
Instead of a chain of
Note that I've sent the error message to error output (
In the decrypt code, you use
or use full paths. In this case, we want
Finally, you can avoid duplication by putting paths that are used more than once into variables. This protects you against mis-typing any of them, and makes it easier if you should ever want to change them.
Modified code
Here's what I have, after applying the above changes:
Instead of a chain of
if/elif all testing the same variable, the natural approach is a switch. I'll also take advantage of ${:-} to default the argument:case "${1:-d}" in
d)
# Decrypt
# (commands)
;;
e)
# Encrypt
# (commands)
;;
i)
# Initialize
# (commands)
;;
*)
# invalid
exec >&2
echo "Usage: $0 [option]"
echo "Options:"
echo " d - decrypt [default]"
echo " e - encrypt"
echo " i - initialize"
exit 1
;;
esacNote that I've sent the error message to error output (
&2) and exited with an error code. Actually, this should really be return 1 since it's a function rather than a complete script.In the decrypt code, you use
pushd and popd. These are suited to interactive use, but are best left alone in scripts or functions (that's why you discovered that you need to redirect their output). Instead, you can use a sub-shell:(cd ~; commands... )or use full paths. In this case, we want
tar to output to ~, and we can tell it to do so, using its -C option:openssl -in ~/.kruptos.tar.gz.aes | tar -C ~ -xz -f -Finally, you can avoid duplication by putting paths that are used more than once into variables. This protects you against mis-typing any of them, and makes it easier if you should ever want to change them.
Modified code
Here's what I have, after applying the above changes:
function kruptos
{
local dir=~/.kruptos
local file=~/.kruptos.tar.gz.aes
local keyfile="$dir/.phrazein"
case "${1:-d}" in
d)
# Decrypt
openssl aes-256-cbc -d -in \
| tar -C "$dir" xfz - \
&& rm "$file"
;;
e)
# Encrypt
tar -C "$dir" cfz - . \
| openssl aes-256-cbc -out "$file" -kfile "$keyfile" \
&& rm -r "$dir"
;;
i)
# Initialize
mkdir "$dir"
echo pswd >"$keyfile"
;;
*)
# invalid
exec >&2
echo "Usage: $0 [option]"
echo "Options:"
echo " d - decrypt [default]"
echo " e - encrypt"
echo " i - initialize"
return 1
;;
esac
}Code Snippets
case "${1:-d}" in
d)
# Decrypt
# (commands)
;;
e)
# Encrypt
# (commands)
;;
i)
# Initialize
# (commands)
;;
*)
# invalid
exec >&2
echo "Usage: $0 [option]"
echo "Options:"
echo " d - decrypt [default]"
echo " e - encrypt"
echo " i - initialize"
exit 1
;;
esac(cd ~; commands... )openssl -in ~/.kruptos.tar.gz.aes | tar -C ~ -xz -f -function kruptos
{
local dir=~/.kruptos
local file=~/.kruptos.tar.gz.aes
local keyfile="$dir/.phrazein"
case "${1:-d}" in
d)
# Decrypt
openssl aes-256-cbc -d -in \
| tar -C "$dir" xfz - \
&& rm "$file"
;;
e)
# Encrypt
tar -C "$dir" cfz - . \
| openssl aes-256-cbc -out "$file" -kfile "$keyfile" \
&& rm -r "$dir"
;;
i)
# Initialize
mkdir "$dir"
echo pswd >"$keyfile"
;;
*)
# invalid
exec >&2
echo "Usage: $0 [option]"
echo "Options:"
echo " d - decrypt [default]"
echo " e - encrypt"
echo " i - initialize"
return 1
;;
esac
}Context
StackExchange Code Review Q#157953, answer score: 3
Revisions (0)
No revisions yet.