pm

barebones password manager
git clone git://git.ckyln.com/~cem/pm.git
Log | Files | Refs | README

commit 25d610c1495f5519f9434010fd962f3195c71371
Author: Cem Keylan <cem@ckyln.com>
Date:   Tue, 10 Mar 2020 19:42:58 +0300

Move pm to its own repository

Diffstat:
AMakefile | 10++++++++++
AREADME.md | 64++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Acontrib/Makefile | 10++++++++++
Acontrib/README | 5+++++
Acontrib/pm-add-dmenu | 11+++++++++++
Acontrib/pm-ask | 13+++++++++++++
Acontrib/pm-copy | 4++++
Acontrib/pm-copy-dmenu | 10++++++++++
Acontrib/pm-git | 4++++
Acontrib/pm-tree | 5+++++
Apm | 35+++++++++++++++++++++++++++++++++++
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