Add -c option to create or replace a file without decrypting it first

This commit is contained in:
Joshua McQuistan 2024-07-19 11:11:24 +01:00
parent de96bd907d
commit a995c0d606
3 changed files with 32 additions and 5 deletions

View file

@ -55,6 +55,7 @@ in
) )
cd $HOME/secrets cd $HOME/secrets
echo hello | ${bin} -c secret1.age
test $(${bin} -d secret1.age) = "hello" test $(${bin} -d secret1.age) = "hello"
''; '';

View file

@ -6,12 +6,15 @@ PACKAGE="agenix"
function show_help () { function show_help () {
echo "$PACKAGE - edit and rekey age secret files" echo "$PACKAGE - edit and rekey age secret files"
echo " " echo " "
echo "$PACKAGE -c FILE"
echo "$PACKAGE -e FILE [-i PRIVATE_KEY]" echo "$PACKAGE -e FILE [-i PRIVATE_KEY]"
echo "$PACKAGE -r [-i PRIVATE_KEY]" echo "$PACKAGE -r [-i PRIVATE_KEY]"
echo ' ' echo ' '
echo 'options:' echo 'options:'
echo '-h, --help show help' echo '-h, --help show help'
# shellcheck disable=SC2016 # shellcheck disable=SC2016
echo '-c, --create FILE create or replace FILE using $EDITOR'
# shellcheck disable=SC2016
echo '-e, --edit FILE edits FILE using $EDITOR' echo '-e, --edit FILE edits FILE using $EDITOR'
echo '-r, --rekey re-encrypts all secrets with specified recipients' echo '-r, --rekey re-encrypts all secrets with specified recipients'
echo '-d, --decrypt FILE decrypts FILE to STDOUT' echo '-d, --decrypt FILE decrypts FILE to STDOUT'
@ -46,6 +49,7 @@ function err() {
test $# -eq 0 && (show_help && exit 1) test $# -eq 0 && (show_help && exit 1)
REKEY=0 REKEY=0
ENCRYPT_ONLY=0
DECRYPT_ONLY=0 DECRYPT_ONLY=0
DEFAULT_DECRYPT=(--decrypt) DEFAULT_DECRYPT=(--decrypt)
@ -55,6 +59,17 @@ while test $# -gt 0; do
show_help show_help
exit 0 exit 0
;; ;;
-c|--create)
shift
ENCRYPT_ONLY=1
if test $# -gt 0; then
export FILE=$1
else
echo "no FILE specified"
exit 1
fi
shift
;;
-e|--edit) -e|--edit)
shift shift
if test $# -gt 0; then if test $# -gt 0; then
@ -153,22 +168,29 @@ function edit {
CLEARTEXT_FILE="$CLEARTEXT_DIR/$(basename "$FILE")" CLEARTEXT_FILE="$CLEARTEXT_DIR/$(basename "$FILE")"
DEFAULT_DECRYPT+=(-o "$CLEARTEXT_FILE") DEFAULT_DECRYPT+=(-o "$CLEARTEXT_FILE")
# Decrypt file
if [ $ENCRYPT_ONLY -eq 0 ]
then
decrypt "$FILE" "$KEYS" || exit 1 decrypt "$FILE" "$KEYS" || exit 1
[ ! -f "$CLEARTEXT_FILE" ] || cp "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before" [ ! -f "$CLEARTEXT_FILE" ] || cp "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before"
else
touch "$CLEARTEXT_FILE.before"
fi
# Prompt file edit
[ -t 0 ] || EDITOR='cp /dev/stdin' [ -t 0 ] || EDITOR='cp /dev/stdin'
$EDITOR "$CLEARTEXT_FILE" $EDITOR "$CLEARTEXT_FILE"
# Check file status
if [ ! -f "$CLEARTEXT_FILE" ] if [ ! -f "$CLEARTEXT_FILE" ]
then then
warn "$FILE wasn't created." warn "$FILE wasn't created."
return return
fi fi
[ -f "$FILE" ] && [ "$EDITOR" != ":" ] && @diffBin@ -q "$CLEARTEXT_FILE.before" "$CLEARTEXT_FILE" && warn "$FILE wasn't changed, skipping re-encryption." && return [ $ENCRYPT_ONLY -eq 0 ] && [ -f "$FILE" ] && [ "$EDITOR" != ":" ] && @diffBin@ -q "$CLEARTEXT_FILE.before" "$CLEARTEXT_FILE" && warn "$FILE wasn't changed, skipping re-encryption." && return
ENCRYPT=() ENCRYPT=()
# Build recipient list
while IFS= read -r key while IFS= read -r key
do do
if [ -n "$key" ]; then if [ -n "$key" ]; then

View file

@ -120,6 +120,10 @@ pkgs.nixosTest {
# and get it back out via --decrypt # and get it back out via --decrypt
assert "secret1234" in system1.succeed(userDo("agenix -d passwordfile-user1.age")) assert "secret1234" in system1.succeed(userDo("agenix -d passwordfile-user1.age"))
# user1 can recreate the secret without decrypting it
system1.succeed(userDo("echo 'secret5678' | agenix -c passwordfile-user1.age"))
assert "secret5678" in system1.succeed(userDo("agenix -d passwordfile-user1.age"))
# finally, the plain text should not linger around anywhere in the filesystem. # finally, the plain text should not linger around anywhere in the filesystem.
system1.fail("grep -r secret1234 /tmp") system1.fail("grep -r secret1234 /tmp")
''; '';