Skip to content

Commit

Permalink
Utilize age identity and recipient files
Browse files Browse the repository at this point in the history
- simplify some code
- add a few ugly backwards-compat lifts
- Rename "key.txt" to "identities" and move its location to the pa store
  dir
- Move passwords into a dedicated "passwords" dir

Co-authored-by: Alan Morgan <[email protected]>
  • Loading branch information
biox and alanxoc3 committed Dec 28, 2022
1 parent b32ce1a commit 7b16e8e
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 41 deletions.
4 changes: 2 additions & 2 deletions contrib/pa-bemenu
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
# - bemenu
# - pa

cd "${PA_DIR:-$HOME/.local/share/pa}"
cd "${PA_DIR:-$HOME/.local/share/pa/passwords}"
password_files="$(find * -type f | grep -v '/.git')"
password=$(printf '%s\n' "$password_files" | sed 's/.age//' | bemenu -b "$@")
password=$(printf '%s\n' "$password_files" | sed 's/.age//' | bemenu -c -W 0.2 -l 20 "$@")

pa show "$password" | head -n 1 | tr -d '\n' | wtype -
2 changes: 1 addition & 1 deletion contrib/pa-dmenu
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

cd "${PA_DIR:-$HOME/.local/share/pa}"
cd "${PA_DIR:-$HOME/.local/share/pa/passwords}"
password_files="$(find * -type f | grep -v '/.git')"
password=$(printf '%s\n' "$password_files" | sed 's/.age//' | dmenu "$@")

Expand Down
2 changes: 1 addition & 1 deletion contrib/pa-fuzzel
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#
# prompt for a password, then type the selected password

cd "${PA_DIR:-$HOME/.local/share/pa}"
cd "${PA_DIR:-$HOME/.local/share/pa/passwords}"
password_files="$(find * -type f | grep -v '/.git')"
password=$(printf '%s\n' "$password_files" | sed 's/.age//' | fuzzel -dmenu "$@")

Expand Down
2 changes: 1 addition & 1 deletion contrib/pa-rofi
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh

cd "${PA_DIR:-$HOME/.local/share/pa}"
cd "${PA_DIR:-$HOME/.local/share/pa/passwords}"
password_files="$(find * -type f | grep -v '/.git')"
password=$(printf '%s\n' "$password_files" | sed 's/.age//' | rofi -dmenu -i "$@")

Expand Down
84 changes: 48 additions & 36 deletions pa
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/sh
#
# pa - simple age-based password manager
# pa - a simple password manager based on age

pw_add() {
name=$1
Expand Down Expand Up @@ -43,7 +43,7 @@ pw_add() {
# Heredocs are sometimes implemented via temporary files,
# however this is typically done using 'mkstemp()' which
# is more secure than a leak in '/proc'.
age -r "$pubkey" -o "$name.age" <<-EOF &&
age -R "$recipients_file" -o "$name.age" <<-EOF &&
$pass
EOF
printf '%s\n' "Saved '$name' to the store."
Expand All @@ -67,15 +67,15 @@ pw_edit() {
mkdir -p "$tmpdir"
trap 'rm -rf /dev/shm/pa' EXIT

age -i ~/.age/key.txt --decrypt "$name.age" 2>/dev/null >"$tmpfile" ||
age -i "$identities_file" --decrypt "$name.age" 2>/dev/null >"$tmpfile" ||
die "Could not decrypt $name.age"

"${EDITOR:-vi}" "$tmpfile"

[ -f "$tmpfile" ] || die "New password not saved"

rm "$name.age"
age -r "$pubkey" -o "$name.age" "$tmpfile"
age -R "$recipients_file" -o "$name.age" "$tmpfile"
}

pw_del() {
Expand All @@ -90,26 +90,17 @@ pw_del() {
}

pw_show() {
age -i ~/.age/key.txt --decrypt "$1.age" 2>/dev/null ||
age -i "$identities_file" --decrypt "$1.age" 2>/dev/null ||
die "Could not decrypt $1.age"
}

pw_list() {
find . -type f -name \*.age | sed 's/..//;s/\.age$//'
}

pw_gen() {
if yn "$HOME/.age/key.txt not detected, generate a new one?"; then
mkdir -p ~/.age
age-keygen -o ~/.age/key.txt
fi
}

depends() {
for dep in $@; do
command -v "$dep" >/dev/null 2>&1 ||
die "$dep not found, install per https://github.com/FiloSottile/age"
done
dep() {
command -v "$1" >/dev/null 2>&1 ||
die "$1 not found, install per https://github.com/FiloSottile/age"
}

yn() {
Expand Down Expand Up @@ -167,29 +158,43 @@ die() {

usage() {
printf %s "\
pa 0.1.0 - age-based password manager
=> [a]dd [name] - Create a new password, randomly generated
=> [d]el [name] - Delete a password entry.
=> [e]dit [name] - Edit a password entry with $EDITOR.
=> [l]ist - List all entries.
=> [s]how [name] - Show password for an entry.
Password length: export PA_LENGTH=50
Password pattern: export PA_PATTERN=_A-Z-a-z-0-9
Store location: export PA_DIR=~/.local/share/pa
pa 0.1.1
a simple password manager based on age
commands:
[a]dd [name] - Create a new password, randomly generated
[d]el [name] - Delete a password entry.
[e]dit [name] - Edit a password entry with $EDITOR.
[l]ist - List all entries.
[s]how [name] - Show password for an entry.
default env vars:
Password length: export PA_LENGTH=50
Password pattern: export PA_PATTERN=_A-Z-a-z-0-9
Password/key dir: export PA_DIR=~/.local/share/pa
"
exit 0
}

main() {
: "${PA_DIR:=${XDG_DATA_HOME:=$HOME/.local/share}/pa}"

depends age age-keygen
password_dir="$PA_DIR/passwords"

mkdir -p "$password_dir" ||
die "Couldn't create password store"

mkdir -p "$PA_DIR" ||
die "Couldn't create password directory"
cd "$password_dir" ||
die "Can't access the password store"

cd "$PA_DIR" ||
die "Can't access password directory"
# Move any passwords hanging out in the old dir
# for backwards-compat reasons
set +f
mv ~/.local/share/pa/*.age "$password_dir" 2>/dev/null
set -f

glob "$1" '[aes]' &&
depends age

glob "$1" '[ades]*' && [ -z "$2" ] &&
die "Missing [name] argument"
Expand All @@ -213,8 +218,18 @@ main() {
# only the current user.
umask 077

[ -f ~/.age/key.txt ] || pw_gen
pubkey=$(sed -n 's/.*\(age\)/\1/p' ~/.age/key.txt)
identities_file="$PA_DIR/identities"
# Copy any existing identities files from the old
# storage location to the new one - backwards compat.
[ ! -f "$identities_file" ] && [ -f ~/.age/key.txt ] &&
cp ~/.age/key.txt "$identities_file"

[ ! -f "$identities_file" ] && dep age-keygen &&
age-keygen -o "$identities_file" 2>/dev/null

recipients_file="$PA_DIR/recipients"
[ ! -f "$recipients_file" ] && dep age-keygen &&
age-keygen -y -o "$recipients_file" "$identities_file" 2>/dev/null

# Ensure that we leave the terminal in a usable
# state on exit or Ctrl+C.
Expand All @@ -234,9 +249,6 @@ main() {
# prevent the password from leaking.
set +x

#
set -e

# Ensure that globbing is globally disabled
# to avoid insecurities with word-splitting.
set -f
Expand Down

0 comments on commit 7b16e8e

Please sign in to comment.