mirror of
https://github.com/shokinn/.files.git
synced 2025-01-18 21:22:25 +00:00
add helper for age
This commit is contained in:
parent
3577f88628
commit
c9fc52dc5c
|
@ -8,6 +8,156 @@
|
|||
# {{@@ header() @@}}
|
||||
#
|
||||
|
||||
# age encryption / decryption helpers
|
||||
# based on https://git.sr.ht/~digital/secretFiles
|
||||
if [[ $(command -v age) ]]; then
|
||||
# get recipients for age file to encrypt with
|
||||
ageGetRecipientsList() {
|
||||
local target="${1}"
|
||||
local search="${target}"
|
||||
local recipients=( "-R" "secrets/hostkeys/masterkey.pubkey" )
|
||||
local recip
|
||||
while true; do
|
||||
if test -d "${search}.recipients"; then
|
||||
for recip in $(ls ${search}.recipients) ; do
|
||||
if test -n "${recip}"; then
|
||||
recipients+=("-R" "${search}.recipients/${recip}")
|
||||
fi
|
||||
done
|
||||
elif test -f "${search}.recipients"; then
|
||||
recipients+=( "-R" "${search}.recipients")
|
||||
fi
|
||||
if test "$(realpath ${search})" = "$(realpath $(pwd))"; then
|
||||
break
|
||||
fi
|
||||
search=$(dirname "${search}")
|
||||
done
|
||||
echo "${recipients[@]}"
|
||||
}
|
||||
|
||||
age-gen-key() {
|
||||
set -efu -o pipefail
|
||||
|
||||
local keyname="${1}"
|
||||
|
||||
mkdir -p "secrets/hostkeys/"
|
||||
echo "generating new keys for host ${keyname}";
|
||||
age-keygen \
|
||||
2> "secrets/hostkeys/${keyname}.pubkey" \
|
||||
| age -p --armor -e -o "secrets/hostkeys/${keyname}.privkey"
|
||||
sed -i 's/Public key: //' "secrets/hostkeys/${keyname}.pubkey"
|
||||
|
||||
set +efu +o pipefail
|
||||
}
|
||||
|
||||
age-import-secret() {
|
||||
set -euf -o pipefail
|
||||
|
||||
local secret_path="${1}"
|
||||
local recipients_list=$(ageGetRecipientsList "${secret_path}")
|
||||
local dirname="$(dirname ${secret_path})"
|
||||
local identity="${MASTERKEY_FILE:-secrets/hostkeys/masterkey.privkey}"
|
||||
|
||||
mkdir -p "${dirname}"
|
||||
|
||||
age ${recipients_list[@]} --encrypt --armor --output "${secret_path}"
|
||||
|
||||
set +efu +o pipefail
|
||||
}
|
||||
|
||||
age-edit-file() {
|
||||
set -euf -o pipefail
|
||||
local current_umask=$(umask)
|
||||
umask 177
|
||||
|
||||
local secret_path="${1}"
|
||||
local tmp_path="$(mktemp -p /dev/shm)"
|
||||
local recipients_list=$(ageGetRecipientsList "${secret_path}")
|
||||
local identity="${MASTERKEY_FILE:-$([[ -f "$(realpath "secrets/hostkeys/masterkey.privkey")" ]] && echo -n "$(realpath "secrets/hostkeys/masterkey.privkey")" || echo -n "/dev/stdin")}"
|
||||
# [[ -f "$(realpath "secrets/hostkeys/masterkey.privkey")" ]] && local identity="$(realpath "secrets/hostkeys/masterkey.privkey")" ||
|
||||
|
||||
if test -e "${secret_path}"; then
|
||||
set +e +o pipefail
|
||||
|
||||
age \
|
||||
--decrypt \
|
||||
--identity "${identity}" \
|
||||
--output "${tmp_path}" \
|
||||
"${secret_path}" || local decrypt_failed=true
|
||||
|
||||
set -e -o pipefail
|
||||
else
|
||||
# if file descriptor 0 is not a terminal, ie if /dev/stdin is a pipe
|
||||
if [ ! -t 0 ]; then
|
||||
cat "${identity}" > /dev/null
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! ${decrypt_failed:-} ]]; then
|
||||
local mod_time_before=$(stat --format "%Y" "${tmp_path}")
|
||||
${EDITOR} "${tmp_path}"
|
||||
local mod_time_after=$(stat --format "%Y" "${tmp_path}")
|
||||
|
||||
if test "${mod_time_before}" != "${mod_time_after}"; then
|
||||
echo "change detected, reencrypting file" > /dev/stderr
|
||||
age ${recipients_list[@]} --encrypt --armor --output "${secret_path}" "${tmp_path}"
|
||||
else
|
||||
echo "no change detected, not reencrypting file" > /dev/stderr
|
||||
fi
|
||||
fi
|
||||
|
||||
rm "${tmp_path}"
|
||||
|
||||
umask ${current_umask}
|
||||
set +efu +o pipefail
|
||||
}
|
||||
|
||||
age-reencrypt-all() {
|
||||
set -euf -o pipefail
|
||||
local current_umask=$(umask)
|
||||
umask 177
|
||||
|
||||
local identity="${1:-/dev/stdin}"
|
||||
local identity_file="$(mktemp -u -p /dev/shm)"
|
||||
|
||||
# make the identity file reuseable, in case it actually is /dev/stdin
|
||||
umask 177
|
||||
cat "${identity}" > "${identity_file}"
|
||||
|
||||
find "secrets" -type f -not -name "*\.recipients" \
|
||||
| grep -v "^secrets/hostkeys/"| while read line; do
|
||||
if ! grep -q "^-----BEGIN AGE ENCRYPTED FILE-----$" "${line}"; then
|
||||
echo "skipping unecrypted file '${line}'"
|
||||
continue
|
||||
fi
|
||||
local recipients=$(ageGetRecipientsList "${line}")
|
||||
echo "reencrypting '${line}' for recipients ${recipients[@]}"
|
||||
local content="$(age --decrypt \
|
||||
--identity "${identity_file}" \
|
||||
"${line}" \
|
||||
)" || {
|
||||
echo "ERROR: failed decryption of '${line}'" > /dev/stderr
|
||||
echo "aborting and leaving secrets store in an inconsistent state" > /dev/stderr
|
||||
exit 2
|
||||
}
|
||||
if test $? -eq 0 ; then
|
||||
echo -n "${content}" \
|
||||
| age ${recipients[@]} \
|
||||
--encrypt \
|
||||
--armor \
|
||||
--output "${line}"
|
||||
fi
|
||||
done
|
||||
|
||||
rm "${identity_file}"
|
||||
|
||||
umask ${current_umask}
|
||||
set +efu +o pipefail
|
||||
|
||||
echo "SUCCESS" > /dev/stderr
|
||||
}
|
||||
fi
|
||||
|
||||
# eza - set aliasses for eza to use it as ls replacement
|
||||
if [[ $(command -v eza) ]]; then
|
||||
ezafunc() {
|
||||
|
|
Loading…
Reference in a new issue