2 # Copyright (C) 2013-2016 Sören Tempel
3 # Copyright (C) 2017 Matthias Schmidt
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 GPG_OPTS="--quiet --yes"
30 PASSWORD_STORE_KEY=${PASSWORD_STORE_KEY:-""}
38 readonly STORE_DIR="${HOME}/.password-store"
39 readonly PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
45 if [ -r "${STORE_DIR}/.gpg-id" ] && [ -z "${PASSWORD_STORE_KEY}" ]; then
46 read -r PASSWORD_STORE_KEY < "${STORE_DIR}/.gpg-id"
50 echo "Usage: $(basename $0) [option] [argument]"
52 echo "Option can be one of the following"
54 echo " show <entry> Shows password <entry>"
55 echo " insert <entry> Inserts new <entry>"
56 echo " find <entry> Searches for <entry>"
57 echo " rm <entry> Removes <entry>"
59 echo "If you do not specify an option, all entries will be shown"
64 echo "$(basename ${0}): ${1}" 1>&2
70 if [ -z "$(which gpg2 2> /dev/null)" ]; then
71 if [ -z "$(which gpg 2> /dev/null)" ]; then
72 abort "gpg or gpg2 not found. Please install."
78 if [ -n "${PASSWORD_STORE_KEY}" ]; then
79 ${GPGB} ${GPG_OPTS} --recipient "${PASSWORD_STORE_KEY}" "$@"
81 ${GPGB} ${GPG_OPTS} --default-recipient-self "$@"
98 local _entry_name="${1}"
99 local _entry_path="${STORE_DIR}/${_entry_name}.gpg"
101 if [ ! -f "${_entry_path}" ]; then
102 abort "The requested entry doesn't exist."
107 # Create the temp file on a shared memory fs if available
108 if [ -d "/dev/shm" -a -k "/dev/shm" ]; then
116 if [ -n ${OSV} ]; then
117 if [ "${OSV}" = "Linux" ]; then
118 if [[ -z "$(which shred 2> /dev/null)" ]]; then
119 echo "Cannot find shred. Using rm"
123 elif [ "${OSV}" = "OpenBSD" -o "${OSV}" = "FreeBSD" -o "${OSV}" = "DragonFly" -o "${OSV}" = "NetBSD" ]; then
134 local _entry_name="${1}"
135 local _entry_path="${STORE_DIR}/${_entry_name}.gpg"
137 if [ -z "${_entry_name}" ]; then
138 abort "show needs an argument"
141 entry_exists ${_entry_name}
143 mygpg --decrypt "${_entry_path}" || abort "Cannot open entry"
147 local _entry_name="${1}"
148 local _entry_path="${STORE_DIR}/${_entry_name}.gpg"
150 if [ -z "${_entry_name}" ]; then
151 abort "insert needs an argument"
154 if [ -f "${_entry_path}" ]; then
155 abort "This entry already exists"
159 readpw "Password for '${_entry_name}': " password
164 if [ -z "${password}" ]; then
165 abort "You didn't specify a password."
168 command mkdir -p "${_entry_path%/*}" || abort "Cannot create password entry"
169 printf '%s\n' "${password}" | mygpg --encrypt \
170 --output "${_entry_path}"
174 ${TREE} -l -x --noreport $TOPTS "${STORE_DIR}" -P "*.gpg" --prune | sed 's/\.gpg//'
178 local _entry_name="${1}" _answer
180 [ -z "${_entry_name}" ] && abort "rm needs an argument"
182 entry_exists ${_entry_name}
186 echo -n "$0: Really remove ${_entry_name} [y/N]? "
189 [yY]) command ${NUKE} -f "${STORE_DIR}/${_entry_name}.gpg" ;;
195 local _entry_name="${1}"
197 [ -z "${_entry_name}" ] && abort "find needs an argument"
198 ${TREE} -l -x --noreport $TOPTS "${STORE_DIR}/" -P "*${_entry_name}*" --prune \
199 --matchdirs --ignore-case | sed 's/\.gpg//'
204 local _entry_name="${1}" _tmpfile
206 [ -z "${_entry_name}" ] && abort "edit needs an argument"
208 entry_exists ${_entry_name}
213 _tmpfile=$(mktemp ${TMPDIR}/tpm.XXXXXXXXXX) || abort "Cannot create temporary file"
214 trap "${NUKE} -f ${_tmpfile}; exit 0" 0 1 2 3 15
216 mygpg --output ${_tmpfile} --decrypt "${STORE_DIR}/${_entry_name}.gpg" || \
217 abort "Cannot edit file"
219 if [ -n "${EDITOR}" ]; then
220 ${EDITOR} ${_tmpfile} || abort "Cannot open file using \$EDITOR"
222 vi ${_tmpfile} || abort "Neither vi or an editor in \$EDITOR was found"
225 mygpg --output "${STORE_DIR}/${_entry_name}.gpg" --encrypt ${_tmpfile} || \
226 abort "Cannot re-encrypt temporary file"
228 # If the file is there, remove it
229 [ -e "${_tmpfile}" ] && ${NUKE} -f "${_tmpfile}"
237 [ "${1}" != "insert" -a ! -d "${STORE_DIR}" ] && abort "Password directory does not exist."
239 # Disable colors for colortree if NO_COLOR is set
240 [[ -n $NO_COLOR ]] && TOPTS="-n"
243 if [ ! -z "$(which colortree 2> /dev/null)" ]; then
245 elif [ ! -z "$(which tree 2> /dev/null)" ]; then
248 abort "tpm needs tree or colortree to run. Please install"
251 if [ $# -eq 0 ]; then
254 elif [ $# -gt 2 ]; then
255 abort "tpm doesn't accept more than two arguments."
259 "show") show "${2}" ;;
260 "insert") insert "${2}" ;;
261 "find") find_entry "${2}" ;;
262 "rm") remove_entry "${2}" ;;
263 "edit") edit_entry "${2}" ;;