commit 188f5231486e8a07fa3da27d750bc67d3acbef43 Author: Peter Cai Date: Mon Oct 10 11:05:41 2022 -0400 Initial implementation of the gocrypt plugin diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2ae2839 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +pass diff --git a/gocrypt.bash b/gocrypt.bash new file mode 100755 index 0000000..11d7538 --- /dev/null +++ b/gocrypt.bash @@ -0,0 +1,107 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: GPL-3.0-only +# Copyright (C) 2022 Peter Cai + +readonly gocrypt_dir=".gocrypt" +readonly gocrypt_dec_dir="gocrypt" +readonly gocrypt_passwd_file="gocrypt-passwd" + +gocrypt_sys_check() { + which gocryptfs > /dev/null || gocrypt_die "gocryptfs not found in PATH" +} + +gocrypt_env_check() { + gocrypt_sys_check + [ ! -d "$gocrypt_dir" ] && gocrypt_die "gocrypt plugin not initialized" +} + +gocrypt_open_check() { + gocrypt_env_check + [ ! -f "$gocrypt_dec_dir"/.pass-gocrypt ] && gocrypt_die "gocrypt not opened" +} + +gocrypt_die() { + printf "Error: %s\n" "$1" >&2 + exit 1 +} + +gocrypt_init() { + gocrypt_sys_check + if [ -d "$gocrypt_dir" ] || [ -f "$gocrypt_dir" ]; then + gocrypt_die "gocrypt plugin already initialized for your password store" + fi + + pass generate "$gocrypt_passwd_file" 32 + + # Initialize gocryptfs + mkdir "$gocrypt_dir" + gocryptfs -passfile /dev/stdin -init "$gocrypt_dir" <<< "$(pass show "$gocrypt_passwd_file")" + + # Mount the gocryptfs subdirectory and initialze what is inside of it + gocrypt_open + touch "$gocrypt_dec_dir"/.pass-gocrypt + # By default, we use the same gpg-id inside, but the user can decide to use a different one later by doing it manually + ln -s ../.gpg-id "$gocrypt_dec_dir"/.gpg-id + + # Add the decrypted path to gitignore + echo >> .gitignore + echo "# Gocrypt" >> .gitignore + echo "gocrypt" >> .gitignore + + pass git add .gitignore + pass git add "$gocrypt_dir" + pass git commit -m "Initialized encrypted storage for gocrypt plugin" +} + +gocrypt_open() { + gocrypt_env_check + mkdir -p "$gocrypt_dec_dir" + + gocryptfs -passfile /dev/stdin "$gocrypt_dir" "$gocrypt_dec_dir" <<< "$(pass show "$gocrypt_passwd_file")" +} + +gocrypt_close() { + gocrypt_open_check + fusermount -u "$gocrypt_dec_dir" +} + +gocrypt_delegate() { + gocrypt_open_check + # Delegate command to another `pass` instance that manages what is inside of the mountpoint + PASSWORD_STORE_DIR="$PWD/$gocrypt_dec_dir" pass $@ + # Commit if there has been changes due to this operation + pass git add "$gocrypt_dir" + pass git commit -m "Encrypted pass operation inside gocrypt" "$gocrypt_dir" || echo "No git commit created" +} + +if [ $# -eq 0 ]; then + gocrypt_die "Unknown command for gocrypt" +fi + +if [ ! -d "$PREFIX" ]; then + gocrypt_die "Cannot open password store" +fi + +# cd into the password store prefix +cd "$PREFIX" + +case "$1" in + init) + shift + gocrypt_init $@ + ;; + open) + shift + gocrypt_open $@ + ;; + close) + shift + gocrypt_close $@ + ;; + ls|list|grep|find|search|show|insert|add|edit|generate|rm|remove|delete|mv|rename|cp|copy|git) + # No shift here since we need to delegate these commands to another pass instance + gocrypt_delegate $@ + ;; + *) + gocrypt_die "Unknown command $1 for gocrypt" +esac diff --git a/pass-test b/pass-test new file mode 100755 index 0000000..22def5a --- /dev/null +++ b/pass-test @@ -0,0 +1,3 @@ +#!/usr/bin/env sh + +PASSWORD_STORE_DIR=$PWD/pass PASSWORD_STORE_EXTENSIONS_DIR=$PWD PASSWORD_STORE_ENABLE_EXTENSIONS=true pass $@