commit 25d610c1495f5519f9434010fd962f3195c71371
Author: Cem Keylan <cem@ckyln.com>
Date: Tue, 10 Mar 2020 19:42:58 +0300
Move pm to its own repository
Diffstat:
11 files changed, 171 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,10 @@
+PREFIX = /usr/local
+BINDIR = ${PREFIX}/bin
+
+install:
+ install -Dm755 -t ${DESTDIR}${BINDIR} pm
+
+uninstall:
+ rm -f ${DESTDIR}${BINDIR}/pm
+
+.PHONY: install uninstall
diff --git a/README.md b/README.md
@@ -0,0 +1,64 @@
+# Password Manager
+
+Barebones password manager with absolutely no fancy features. By
+that I mean,
+
+- No password generation
+- No git integration
+- No questions asked
+- No grepping/finding passwords
+- No clipboard support
+- No tree view
+- Does not ask for password input (reads from stdin)
+- Does not check for 'sneaky paths?'
+
+Supports adding/deleting/listing/showing passwords. I don't
+intend on implementing any more features. You can wrap this
+script with something other to make use of it. See the contrib
+directory for that.
+
+Currently less than 35 SLOC. It's almost 20 times smaller
+than `pass` which has a little less than 600 SLOC.
+
+
+To install run, as root if necessary
+
+ make install
+
+You really do think that asking for password for twice blah
+blah is a really important feature? Okay, then add a function
+to your shellrc/profile like this.
+
+ pmask() {
+ [ "$1" ] || return 1
+ printf 'Enter your password: '
+ read pass
+ printf 'Enter your password again: '
+ read pass2
+ [ "$pass" = "$pass2" ] && {
+ printf '%s' "$pass" | pm a "$1" && return 0
+ }
+ printf "Passwords don't match\n"
+ return 1
+ }
+
+You want to copy to clipboard? That's easy! You just need
+to do a `pm s passname | xclip -sel c`. You can still make
+it a function by doing this
+
+ copypass() {
+ [ "$1" ] || return 1
+ pm s "$1" | xclip -sel c
+ }
+
+The whole rationale is that you can already do that with simple
+commands. Why complicate (and possibly break) things by introducing
+them into a single script? If you want some function that is
+a must for you, implement it yourself with some script or
+a shell function. This way, it works just as you intended it. Or use
+helper functions that are located in contrib.
+
+You can install contrib scripts by running
+
+ make -C contrib install
+
diff --git a/contrib/Makefile b/contrib/Makefile
@@ -0,0 +1,10 @@
+PREFIX = /usr/local
+BINDIR = ${PREFIX}/bin
+contrib = pm-add-dmenu pm-ask pm-copy pm-copy-dmenu pm-git pm-tree
+
+install:
+ install -Dm755 -t ${DESTDIR}${BINDIR} ${contrib}
+
+uninstall:
+ for bin in ${contrib} ; do \
+ rm -f ${DESTDIR}${BINDIR}/$$bin ; done
diff --git a/contrib/README b/contrib/README
@@ -0,0 +1,5 @@
+contrib scripts
+===============
+
+These are some example ways you can adapt
+pm into your own scripts.
diff --git a/contrib/pm-add-dmenu b/contrib/pm-add-dmenu
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+name=$(dmenu -p "Give a name to your password" <&-)
+pass=" "
+
+while ! [ "$pass" = "$pass2" ] ; do
+ pass=$(dmenu -nb black -nf black -p "Enter your password" <&-)
+ pass2=$(dmenu -nb black -nf black -p "Enter your password again" <&-)
+done
+
+printf '%s' "$pass" | pm a "$name"
diff --git a/contrib/pm-ask b/contrib/pm-ask
@@ -0,0 +1,13 @@
+#!/bin/sh
+[ "$1" ] || exit 1
+stty -echo
+printf 'Enter your password for %s: ' "$1"
+read pass
+printf '\nEnter your password again: '
+read pass2
+printf '\n'
+stty echo
+[ "$pass" = "$pass2" ] && { printf '%s' "$pass" | pm a "$1" ;} || {
+ printf "Passwords don't match\n"
+ exit 1
+}
diff --git a/contrib/pm-copy b/contrib/pm-copy
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+[ "$1" ] || exit 1
+pm s "$1" | xclip -sel c
diff --git a/contrib/pm-copy-dmenu b/contrib/pm-copy-dmenu
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+getpass() {
+ pm l | while read -r file ; do
+ basename "$file" | cut -d . -f 1
+ done
+}
+
+choice=$(getpass | dmenu -p "Choose the password that you would like to copy" -l 10)
+[ "$choice" ] && pm s "$choice" | xclip -sel c
diff --git a/contrib/pm-git b/contrib/pm-git
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+cd "${PM_DIR:-$HOME/.local/share/pm}" || exit 1
+git "$@"
diff --git a/contrib/pm-tree b/contrib/pm-tree
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+printf '%s\n' "Password Manager"
+tree -C -l --noreport "${PM_DIR:-$HOME/.local/share/pm}" | tail -n +2 | sed -E 's/\.asc(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' # remove .gpg at end of line, but keep colors
+
diff --git a/pm b/pm
@@ -0,0 +1,35 @@
+#!/bin/sh
+umask 077
+error() { printf '\033[1;31m!> \033[merror: %s\n' "$@" >&2 ;}
+die() { error "$1" ; exit 1 ;}
+
+PM_DIR="${PM_DIR:-$HOME/.local/share/pm}"
+usage() { printf '\033[1;36m-> \033[m%s\n' "usage: ${0##*/} [a|d|l|s] [options]" "" \
+ "[a]dd <name> - Reads the password from stdin to the given entry" \
+ "[d]el <name> - Deletes given enry" \
+ "[l]ist - Lists all the passwords" \
+ "[s]how <name> - Shows the given password" "" \
+ "VARIABLES:" "PM_DIR: $PM_DIR" "PM_GPG_USER: $PM_GPG_USER" >&2 ; exit "${1:-0}" ;}
+
+gpg="$(command -v gpg2 || command -v gpg)" || die "gnupg cannot be found"
+case "$1" in
+ a|add)
+ [ "$2" ] || usage 1
+ [ "$PM_GPG_USER" ] || die "Please set a \$PM_GPG_USER variable"
+ [ -e "$PM_DIR/$2.asc" ] && die "an entry for $2 already exists"
+ mkdir -p "$PM_DIR"
+ tr -d '\n' < /dev/stdin > "$PM_DIR/$2"
+ "$gpg" -e -a -r "$PM_GPG_USER" -- "$PM_DIR/$2" ||
+ error "Could not encrypt password"
+ rm -f "$PM_DIR/$2"
+ ;;
+ d|del) [ "$2" ] || usage 1 ; rm -f "$PM_DIR/$2.asc" ;;
+ l|ls|list) { find "$PM_DIR" -type f -name '*asc' 2>/dev/null || ls -1 "$PM_DIR"/*.asc ;} | sort ;;
+ s|show)
+ [ "$2" ] || usage 1
+ [ -r "$PM_DIR/$2.asc" ] ||
+ die "Entry for $2 doesn't exist or is not readable"
+ "$gpg" --decrypt "$PM_DIR/$2.asc" 2>/dev/null | tr -d '\n' ||
+ die "Could not decrypt $PM_DIR/$2.asc"
+ ;;
+ *) usage 0 ;; esac