mirror of
https://github.com/octoleo/Purse.git
synced 2024-12-28 03:45:04 +00:00
Merge pull request #7 from drduh/wip-26mar24
More config options, trap exits, stdout support
This commit is contained in:
commit
8f09cf87e3
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,3 @@
|
||||
purse.*.tar
|
||||
purse.index
|
||||
purse.index*
|
||||
safe/
|
||||
|
61
README.md
61
README.md
@ -1,43 +1,35 @@
|
||||
# Purse
|
||||
|
||||
Purse is a fork of [drduh/pwd.sh](https://github.com/drduh/pwd.sh).
|
||||
|
||||
Both programs are Bash shell scripts which use [GnuPG](https://www.gnupg.org/) to manage passwords and other secrets in encrypted text files. Purse is based on asymmetric (public-key) authentication, while pwd.sh is based on symmetric (password-based) authentication.
|
||||
|
||||
While both scripts use a trusted crypto implementation (GnuPG) and safely handle passwords (never saving plaintext to disk, only using shell built-ins), Purse eliminates the need to remember a master password - just plug in a YubiKey, enter the PIN, then touch it to decrypt a password to clipboard.
|
||||
While both scripts use a trusted crypto implementation (GnuPG) and safely handle passwords (never saving plaintext to disk, only using shell built-ins), Purse eliminates the need to remember a main passphrase - just plug in a YubiKey, enter the PIN, then touch it to decrypt a password to clipboard.
|
||||
|
||||
# Release notes
|
||||
# Install
|
||||
|
||||
See [Releases](https://github.com/drduh/Purse/releases)
|
||||
This script requires a GnuPG identity - see [drduh/YubiKey-Guide](https://github.com/drduh/YubiKey-Guide) to set one up.
|
||||
|
||||
# Use
|
||||
|
||||
This script requires a GnuPG identity - see [drduh/YubiKey-Guide](https://github.com/drduh/YubiKey-Guide) to set one up. Multiple identities stored on several YubiKeys are recommended for improved durability and reliability.
|
||||
|
||||
Clone the repository:
|
||||
For the latest version, clone the repository or download the script directly:
|
||||
|
||||
```console
|
||||
git clone https://github.com/drduh/Purse
|
||||
```
|
||||
|
||||
Or download the script directly:
|
||||
|
||||
```console
|
||||
wget https://github.com/drduh/Purse/blob/master/purse.sh
|
||||
```
|
||||
|
||||
Versioned [Releases](https://github.com/drduh/Purse/releases) are also available.
|
||||
|
||||
# Use
|
||||
|
||||
Run the script interactively using `./purse.sh` or symlink to a directory in `PATH`:
|
||||
|
||||
* Type `w` to write a password
|
||||
* Type `r` to read a password
|
||||
* Type `l` to list passwords
|
||||
* Type `b` to create an archive for backup
|
||||
* Type `h` to print the help text
|
||||
- `w` to write a password
|
||||
- `r` to read a password
|
||||
- `l` to list passwords
|
||||
- `b` to create an archive for backup
|
||||
- `h` to print the help text
|
||||
|
||||
Options can also be passed on the command line.
|
||||
|
||||
Example usage:
|
||||
|
||||
Create a 20-character password for `userName`:
|
||||
|
||||
```console
|
||||
@ -50,7 +42,7 @@ Read password for `userName`:
|
||||
./purse.sh r userName
|
||||
```
|
||||
|
||||
Passwords are stored with a timestamp for revision control. The most recent version is copied to clipboard on read. To list all passwords or read a specific version of a password:
|
||||
Passwords are stored with an epoch timestamp for revision control. The most recent version is copied to clipboard on read. To list all passwords or read a specific version of a password:
|
||||
|
||||
```console
|
||||
./purse.sh l
|
||||
@ -70,8 +62,27 @@ Restore an archive from backup:
|
||||
tar xvf purse*tar
|
||||
```
|
||||
|
||||
**Note** For additional privacy, the recipient key ID is **not** included in metadata (`throw-keyids` option).
|
||||
# Configure
|
||||
|
||||
The password index file can also be encrypted by changing the `encrypt_index` variable to `true` in the script, although two touches will be required for two separate decryption operations.
|
||||
Several customizable options and features are also available, and can be configured with environment variables, for example in the [shell rc](https://github.com/drduh/config/blob/master/zshrc) file:
|
||||
|
||||
See [config/gpg.conf](https://github.com/drduh/config/blob/master/gpg.conf) for additional configuration options.
|
||||
Variable | Description | Default | Values
|
||||
-|-|-|-
|
||||
`PURSE_TIME` | seconds to clear password from clipboard/screen | `10` | any valid integer
|
||||
`PURSE_LEN` | default generated password length | `14` | any valid integer
|
||||
`PURSE_COPY` | copy password to clipboard before write | unset (disabled) | `1` or `true` to enable
|
||||
`PURSE_DAILY` | create daily backup archive on write | unset (disabled) | `1` or `true` to enable
|
||||
`PURSE_ENCIX` | encrypt index for additional privacy; 2 YubiKey touches will be required for separate decryption operations | unset (disabled) | `1` or `true` to enable
|
||||
`PURSE_COMMENT` | **unencrypted** comment to include in index and safe files | unset | any valid string
|
||||
`PURSE_CHARS` | character set for passwords | `[:alnum:]!?@#$%^&*();:+=` | any valid characters
|
||||
`PURSE_DEST` | password output destination, will set to `screen` without clipboard | `clipboard` | `clipboard` or `screen`
|
||||
`PURSE_ECHO` | character used to echo password input | `*` | any valid character
|
||||
`PURSE_SAFE` | safe directory name | `safe` | any valid string
|
||||
`PURSE_INDEX` | index file name | `purse.index` | any valid string
|
||||
`PURSE_BACKUP` | backup archive file name | `purse.$hostname.$today.tar` | any valid string
|
||||
|
||||
**Note** For additional privacy, the recipient key ID is **not** included in metadata (GnuPG `throw-keyids` option).
|
||||
|
||||
|
||||
|
||||
See [config/gpg.conf](https://github.com/drduh/config/blob/master/gpg.conf) for additional GnuPG options.
|
||||
|
276
purse.sh
276
purse.sh
@ -1,54 +1,70 @@
|
||||
#!/usr/bin/env bash
|
||||
# https://github.com/drduh/Purse/blob/master/purse.sh
|
||||
#set -x # uncomment to debug
|
||||
set -o errtrace
|
||||
set -o nounset
|
||||
set -o pipefail
|
||||
#set -x # uncomment to debug
|
||||
|
||||
umask 077
|
||||
|
||||
cb_timeout=10 # seconds to keep password on clipboard
|
||||
daily_backup="false" # if true, create daily archive on write
|
||||
encrypt_index="false" # if true, requires 2 touches to decrypt
|
||||
pass_copy="false" # if true, keep password on clipboard before write
|
||||
pass_len=14 # default password length
|
||||
pass_chars="[:alnum:]!@#$%^&*();:+="
|
||||
|
||||
gpgconf="${HOME}/.gnupg/gpg.conf"
|
||||
backuptar="${PURSE_BACKUP:=purse.$(hostname).$(date +%F).tar}"
|
||||
safeix="${PURSE_INDEX:=purse.index}"
|
||||
safedir="${PURSE_SAFE:=safe}"
|
||||
export LC_ALL="C"
|
||||
|
||||
now="$(date +%s)"
|
||||
today="$(date +%F)"
|
||||
copy="$(command -v xclip || command -v pbcopy)"
|
||||
gpg="$(command -v gpg || command -v gpg2)"
|
||||
script="$(basename "${BASH_SOURCE}")"
|
||||
gpg_conf="${GNUPGHOME}/gpg.conf"
|
||||
|
||||
clip_dest="${PURSE_DEST:=clipboard}" # set to 'screen' to print to stdout
|
||||
clip_timeout="${PURSE_TIME:=10}" # seconds to clear clipboard/screen
|
||||
comment="${PURSE_COMMENT:=}" # *unencrypted* comment in files
|
||||
daily_backup="${PURSE_DAILY:=}" # daily backup archive on write
|
||||
encrypt_index="${PURSE_ENCIX:=}" # also keep index encrypted
|
||||
pass_copy="${PURSE_COPY:=}" # copy password before write
|
||||
pass_echo="${PURSE_ECHO:=*}" # show "*" when typing passwords
|
||||
pass_len="${PURSE_LEN:=14}" # default password length
|
||||
safe_dir="${PURSE_SAFE:=safe}" # safe directory name
|
||||
safe_ix="${PURSE_INDEX:=purse.index}" # index file name
|
||||
safe_backup="${PURSE_BACKUP:=purse.$(hostname).${today}.tar}"
|
||||
pass_chars="${PURSE_CHARS:='[:alnum:]!?@#$%^&*();:+='}"
|
||||
|
||||
trap cleanup EXIT INT TERM
|
||||
cleanup () {
|
||||
# "Lock" files on trapped exits.
|
||||
|
||||
ret=$?
|
||||
chmod -R 0000 \
|
||||
"${safe_dir}" "${safe_ix}" 2>/dev/null
|
||||
exit ${ret}
|
||||
}
|
||||
|
||||
fail () {
|
||||
# Print an error message and exit.
|
||||
# Print an error in red and exit.
|
||||
|
||||
tput setaf 1 ; printf "\nError: %s\n" "${1}" ; tput sgr0
|
||||
tput setaf 1 ; printf "\nERROR: %s\n" "${1}" ; tput sgr0
|
||||
exit 1
|
||||
}
|
||||
|
||||
warn () {
|
||||
# Print a warning in yellow.
|
||||
|
||||
tput setaf 3 ; printf "\nWARNING: %s\n" "${1}" ; tput sgr0
|
||||
}
|
||||
|
||||
get_pass () {
|
||||
# Prompt for a password.
|
||||
|
||||
password=""
|
||||
prompt="${1}"
|
||||
prompt=" ${1}"
|
||||
printf "\n"
|
||||
|
||||
while IFS= read -p "${prompt}" -r -s -n 1 char ; do
|
||||
if [[ ${char} == $'\0' ]] ; then
|
||||
break
|
||||
if [[ ${char} == $'\0' ]] ; then break
|
||||
elif [[ ${char} == $'\177' ]] ; then
|
||||
if [[ -z "${password}" ]] ; then
|
||||
prompt=""
|
||||
if [[ -z "${password}" ]] ; then prompt=""
|
||||
else
|
||||
prompt=$'\b \b'
|
||||
password="${password%?}"
|
||||
fi
|
||||
else
|
||||
prompt="*"
|
||||
prompt="${pass_echo}"
|
||||
password+="${char}"
|
||||
fi
|
||||
done
|
||||
@ -64,39 +80,35 @@ decrypt () {
|
||||
encrypt () {
|
||||
# Encrypt to a group of hidden recipients.
|
||||
|
||||
${gpg} --encrypt --armor --batch --yes --throw-keyids \
|
||||
${gpg} --encrypt --armor --batch --yes \
|
||||
--hidden-recipient "purse_keygroup" \
|
||||
--output "${1}" "${2}"
|
||||
--throw-keyids --comment "${comment}" \
|
||||
--output "${1}" "${2}" 2>/dev/null
|
||||
}
|
||||
|
||||
read_pass () {
|
||||
# Read a password from safe.
|
||||
|
||||
if [[ ! -s ${safeix} ]] ; then fail "${safeix} not found" ; fi
|
||||
if [[ ! -s "${safe_ix}" ]] ; then fail "${safe_ix} not found" ; fi
|
||||
|
||||
username=""
|
||||
while [[ -z "${username}" ]] ; do
|
||||
if [[ -z "${2+x}" ]] ; then read -r -p "
|
||||
Username: " username
|
||||
else username="${2}" ; fi
|
||||
done
|
||||
|
||||
if [[ "${encrypt_index}" = "true" ]] ; then
|
||||
prompt_key "index"
|
||||
|
||||
spath=$(decrypt "${safeix}" | \
|
||||
if [[ -n "${encrypt_index}" ]] ; then prompt_key "index"
|
||||
spath=$(decrypt "${safe_ix}" | \
|
||||
grep -F "${username}" | tail -1 | cut -d ":" -f2) || \
|
||||
fail "Decryption failed"
|
||||
else
|
||||
spath=$(grep -F "${username}" "${safeix}" | \
|
||||
tail -1 | cut -d ":" -f2)
|
||||
fail "Secret not available"
|
||||
else spath=$(grep -F "${username}" "${safe_ix}" | \
|
||||
tail -1 | cut -d ":" -f2)
|
||||
fi
|
||||
|
||||
prompt_key "password"
|
||||
|
||||
if [[ -s "${spath}" ]] ; then
|
||||
clip <(decrypt "${spath}" | head -1) || \
|
||||
fail "Decryption failed"
|
||||
fail "Failed to decrypt ${spath}"
|
||||
else fail "Secret not available"
|
||||
fi
|
||||
}
|
||||
@ -104,116 +116,114 @@ read_pass () {
|
||||
prompt_key () {
|
||||
# Print a message if safe file exists.
|
||||
|
||||
if [[ -f "${safeix}" ]] ; then
|
||||
if [[ -f "${safe_ix}" ]] ; then
|
||||
printf "\n Touch key to access %s ...\n" "${1}"
|
||||
fi
|
||||
}
|
||||
|
||||
gen_pass () {
|
||||
# Generate a password using GPG.
|
||||
# Generate a password from urandom.
|
||||
|
||||
if [[ -z "${3+x}" ]] ; then read -r -p "
|
||||
|
||||
Password length (default: ${pass_len}): " length
|
||||
else length="${3}" ; fi
|
||||
|
||||
if [[ ${length} =~ ^[0-9]+$ ]] ; then pass_len=${length} ; fi
|
||||
if [[ "${length}" =~ ^[0-9]+$ ]] ; then
|
||||
pass_len="${length}"
|
||||
fi
|
||||
|
||||
LC_LANG=C tr -dc "${pass_chars}" < /dev/urandom | \
|
||||
tr -dc "${pass_chars}" < /dev/urandom | \
|
||||
fold -w "${pass_len}" | head -1
|
||||
}
|
||||
|
||||
write_pass () {
|
||||
# Write a password and update the index.
|
||||
|
||||
if [[ "${pass_copy}" = "true" ]] ; then
|
||||
spath="${safe_dir}/$(tr -dc "[:lower:]" < /dev/urandom | \
|
||||
fold -w10 | head -1)"
|
||||
|
||||
if [[ -n "${pass_copy}" ]] ; then
|
||||
clip <(printf '%s' "${userpass}")
|
||||
fi
|
||||
|
||||
fpath="$(LC_LANG=C tr -dc '[:lower:]' < /dev/urandom | fold -w10 | head -1)"
|
||||
spath="${safedir}/${fpath}"
|
||||
printf '%s\n' "${userpass}" | \
|
||||
encrypt "${spath}" - || \
|
||||
fail "Failed to put ${spath}"
|
||||
userpass=""
|
||||
fail "Failed saving ${spath}"
|
||||
|
||||
if [[ "${encrypt_index}" = "true" ]] ; then
|
||||
if [[ -n "${encrypt_index}" ]] ; then
|
||||
prompt_key "index"
|
||||
|
||||
( if [[ -f "${safeix}" ]] ; then
|
||||
decrypt "${safeix}" || return ; fi
|
||||
( if [[ -f "${safe_ix}" ]] ; then
|
||||
decrypt "${safe_ix}" || return ; fi
|
||||
printf "%s@%s:%s\n" "${username}" "${now}" "${spath}") | \
|
||||
encrypt "${safeix}.${now}" - || \
|
||||
fail "Failed to put ${safeix}.${now}"
|
||||
mv "${safeix}.${now}" "${safeix}"
|
||||
encrypt "${safe_ix}.${now}" - && \
|
||||
mv "${safe_ix}.${now}" "${safe_ix}" || \
|
||||
fail "Failed saving ${safe_ix}.${now}"
|
||||
else
|
||||
printf "%s@%s:%s\n" "${username}" "${now}" "${spath}" >> "${safeix}"
|
||||
printf "%s@%s:%s\n" \
|
||||
"${username}" "${now}" "${spath}" >> "${safe_ix}"
|
||||
fi
|
||||
}
|
||||
|
||||
list_entry () {
|
||||
# Decrypt the index to list entries.
|
||||
|
||||
if [[ ! -s ${safeix} ]] ; then fail "${safeix} not found" ; fi
|
||||
if [[ ! -s "${safe_ix}" ]] ; then fail "${safe_ix} not found" ; fi
|
||||
|
||||
if [[ "${encrypt_index}" = "true" ]] ; then
|
||||
prompt_key "index"
|
||||
decrypt "${safeix}" || fail "Decryption failed"
|
||||
else
|
||||
printf "\n"
|
||||
cat "${safeix}"
|
||||
if [[ -n "${encrypt_index}" ]] ; then prompt_key "index"
|
||||
decrypt "${safe_ix}" || fail "${safe_ix} not available"
|
||||
else printf "\n" ; cat "${safe_ix}"
|
||||
fi
|
||||
}
|
||||
|
||||
backup () {
|
||||
# Archive index, safe and configuration.
|
||||
|
||||
if [[ -f "${safeix}" && -d "${safedir}" ]] ; then
|
||||
cp "${gpgconf}" "gpg.conf.${now}"
|
||||
tar --create --file "${backuptar}" \
|
||||
"${safeix}" "${safedir}" "gpg.conf.${now}" "${script}"
|
||||
rm "gpg.conf.${now}"
|
||||
else fail "Nothing to archive" ; fi
|
||||
|
||||
printf "\nArchived %s\n" "${backuptar}"
|
||||
if [[ ! -f ${safe_backup} ]] ; then
|
||||
if [[ -f "${safe_ix}" && -d "${safe_dir}" ]] ; then
|
||||
cp "${gpg_conf}" "gpg.conf.${today}"
|
||||
tar cf "${safe_backup}" "${safe_dir}" "${safe_ix}" \
|
||||
"${BASH_SOURCE}" "gpg.conf.${today}" && \
|
||||
printf "\nArchived %s\n" "${safe_backup}"
|
||||
rm -f "gpg.conf.${today}"
|
||||
else fail "Nothing to archive" ; fi
|
||||
else warn "${safe_backup} exists, skipping archive" ; fi
|
||||
}
|
||||
|
||||
clip () {
|
||||
# Use clipboard and clear after timeout.
|
||||
# Use clipboard or stdout and clear after timeout.
|
||||
|
||||
${copy} < "${1}"
|
||||
if [[ "${clip_dest}" = "screen" ]] ; then
|
||||
printf '\n%s\n' "$(cat ${1})"
|
||||
else "${copy}" < "${1}" ; fi
|
||||
|
||||
printf "\n"
|
||||
shift
|
||||
while [ $cb_timeout -gt 0 ] ; do
|
||||
printf "\r\033[KPassword on clipboard! Clearing in %.d" $((cb_timeout--))
|
||||
sleep 1
|
||||
while [[ "${clip_timeout}" -gt 0 ]] ; do
|
||||
printf "\r\033[K Password on %s! Clearing in %.d" \
|
||||
"${clip_dest}" "$((clip_timeout--))" ; sleep 1
|
||||
done
|
||||
printf "\r\033[K Clearing password from %s ..." "${clip_dest}"
|
||||
|
||||
printf "\n"
|
||||
printf "" | ${copy}
|
||||
if [[ "${clip_dest}" = "screen" ]] ; then clear
|
||||
else printf "\n" ; printf "" | "${copy}" ; fi
|
||||
}
|
||||
|
||||
setup_keygroup() {
|
||||
# Configure GPG keygroup.
|
||||
# Configure one or more recipients.
|
||||
|
||||
purse_keygroup="group purse_keygroup ="
|
||||
keyid=""
|
||||
recommend="$(${gpg} -K | grep "sec#" | \
|
||||
awk -F "/" '{print $2}' | cut -c-18 | tr "\n" " ")"
|
||||
|
||||
printf "\n Setting up GPG key group ...
|
||||
printf "\n Setting up keygroup ...\n
|
||||
Found recommended key IDs: %s\n
|
||||
Enter one or more key IDs, preferred one last\n" "${recommend}"
|
||||
|
||||
Found key IDs: %s
|
||||
|
||||
Enter backup key IDs first, preferred key IDs last.
|
||||
" "${recommend}"
|
||||
|
||||
while [[ -z "${keyid}" ]] ; do
|
||||
read -r -p "
|
||||
while [[ -z "${keyid}" ]] ; do read -r -p "
|
||||
Key ID or Enter to continue: " keyid
|
||||
if [[ -z "${keyid}" ]] ; then
|
||||
printf "%s\n" "$purse_keygroup" >> "${gpgconf}"
|
||||
printf "%s\n" "${purse_keygroup}" >> "${gpg_conf}"
|
||||
break
|
||||
fi
|
||||
purse_keygroup="${purse_keygroup} ${keyid}"
|
||||
@ -224,18 +234,18 @@ setup_keygroup() {
|
||||
new_entry () {
|
||||
# Prompt for username and password.
|
||||
|
||||
username=""
|
||||
while [[ -z "${username}" ]] ; do
|
||||
if [[ -z "${2+x}" ]] ; then read -r -p "
|
||||
Username: " username
|
||||
else username="${2}" ; fi
|
||||
done
|
||||
|
||||
if [[ -z "${3+x}" ]] ; then get_pass "
|
||||
Password for \"${username}\" (Enter to generate): "
|
||||
if [[ -z "${3+x}" ]] ; then
|
||||
get_pass "Password for \"${username}\" (Enter to generate): "
|
||||
userpass="${password}"
|
||||
fi
|
||||
|
||||
printf "\n"
|
||||
if [[ -z "${password}" ]] ; then
|
||||
userpass=$(gen_pass "$@")
|
||||
fi
|
||||
@ -245,82 +255,62 @@ print_help () {
|
||||
# Print help text.
|
||||
|
||||
printf """
|
||||
Purse is a Bash shell script to manage passwords with GnuPG asymmetric encryption. It is designed and recommended to be used with Yubikey as the secret key storage.
|
||||
|
||||
Purse can be used interactively or by passing one of the following options:
|
||||
|
||||
Purse is a Bash shell script to manage passwords with GnuPG asymmetric encryption. It is designed and recommended to be used with YubiKey as the secret key storage.\n
|
||||
Purse can be used interactively or by passing one of the following options:\n
|
||||
* 'w' to write a password
|
||||
* 'r' to read a password
|
||||
* 'l' to list passwords
|
||||
* 'b' to create an archive for backup
|
||||
|
||||
Example usage:
|
||||
|
||||
* Generate a 30 character password for 'userName':
|
||||
./purse.sh w userName 30
|
||||
|
||||
* Copy the password for 'userName' to clipboard:
|
||||
./purse.sh r userName
|
||||
|
||||
* List stored passwords and copy a specific version:
|
||||
./purse.sh l
|
||||
./purse.sh r userName@1574723625
|
||||
|
||||
* Create an archive for backup:
|
||||
./purse.sh b
|
||||
|
||||
* Restore an archive from backup:
|
||||
tar xvf purse*tar"""
|
||||
* 'b' to create an archive for backup\n
|
||||
Options can also be passed on the command line.\n
|
||||
* Create a 20-character password for userName:
|
||||
./purse.sh w userName 20\n
|
||||
* Read password for userName:
|
||||
./purse.sh r userName\n
|
||||
* Passwords are stored with an epoch timestamp for revision control. The most recent version is copied to clipboard on read. To list all passwords or read a specific version of a password:
|
||||
./purse.sh l
|
||||
./purse.sh r userName@1574723625\n
|
||||
* Create an archive for backup:
|
||||
./purse.sh b\n
|
||||
* Restore an archive from backup:
|
||||
tar xvf purse*tar\n"""
|
||||
}
|
||||
|
||||
if [[ -z ${gpg} && ! -x ${gpg} ]] ; then fail "GnuPG is not available" ; fi
|
||||
if [[ -z "${gpg}" || ! -x "${gpg}" ]] ; then fail "GnuPG is not available" ; fi
|
||||
|
||||
if [[ -z ${copy} && ! -x ${copy} ]] ; then fail "Clipboard is not available" ; fi
|
||||
if [[ ! -f "${gpg_conf}" ]] ; then fail "GnuPG config is not available" ; fi
|
||||
|
||||
if [[ ! -f ${gpgconf} ]] ; then fail "GnuPG config is not available" ; fi
|
||||
if [[ ! -d "${safe_dir}" ]] ; then mkdir -p "${safe_dir}" ; fi
|
||||
|
||||
if [[ ! -d "${safedir}" ]] ; then mkdir -p "${safedir}" ; fi
|
||||
chmod -R 0700 "${safe_dir}" "${safe_ix}" 2>/dev/null
|
||||
|
||||
chmod -R 0600 "${safeix}" 2>/dev/null
|
||||
chmod -R 0700 "${safedir}" 2>/dev/null
|
||||
if [[ -z "${copy}" || ! -x "${copy}" ]] ; then
|
||||
warn "Clipboard not available, passwords will print to screen/stdout!"
|
||||
clip_dest="screen"
|
||||
fi
|
||||
|
||||
username=""
|
||||
password=""
|
||||
action=""
|
||||
|
||||
if [[ -n "${1+x}" ]] ; then action="${1}" ; fi
|
||||
|
||||
while [[ -z "${action}" ]] ; do
|
||||
read -r -n 1 -p "
|
||||
while [[ -z "${action}" ]] ; do read -r -n 1 -p "
|
||||
Read or Write (or Help for more options): " action
|
||||
printf "\n"
|
||||
done
|
||||
|
||||
if [[ "${action}" =~ ^([hH])$ ]] ; then
|
||||
print_help
|
||||
|
||||
elif [[ "${action}" =~ ^([bB])$ ]] ; then
|
||||
backup
|
||||
|
||||
elif [[ "${action}" =~ ^([lL])$ ]] ; then
|
||||
list_entry
|
||||
|
||||
if [[ "${action}" =~ ^([rR])$ ]] ; then read_pass "$@"
|
||||
elif [[ "${action}" =~ ^([wW])$ ]] ; then
|
||||
purse_keygroup=$(grep "group purse_keygroup" "${gpgconf}")
|
||||
purse_keygroup="$(grep "group purse_keygroup" "${gpg_conf}")"
|
||||
if [[ -z "${purse_keygroup}" ]] ; then
|
||||
setup_keygroup
|
||||
fi
|
||||
printf "\n %s\n" "${purse_keygroup}"
|
||||
|
||||
new_entry "$@"
|
||||
write_pass
|
||||
|
||||
if [[ "${daily_backup}" = "true" ]] ; then
|
||||
if [[ ! -f ${backuptar} ]] ; then
|
||||
backup
|
||||
fi
|
||||
fi
|
||||
|
||||
else read_pass "$@" ; fi
|
||||
|
||||
chmod -R 0400 "${safeix}" "${safedir}" 2>/dev/null
|
||||
if [[ -n "${daily_backup}" ]] ; then backup ; fi
|
||||
elif [[ "${action}" =~ ^([lL])$ ]] ; then list_entry
|
||||
elif [[ "${action}" =~ ^([bB])$ ]] ; then backup
|
||||
else print_help ; fi
|
||||
|
||||
tput setaf 2 ; printf "\nDone\n" ; tput sgr0
|
||||
|
Loading…
Reference in New Issue
Block a user