Separate flags from positional args with --

This prevents interpreting filenames with leading `-` as flags.

Add a regression test for this behavior.

Fixes https://github.com/ryantm/agenix/issues/325
This commit is contained in:
Nathan Henrie 2025-05-03 11:49:36 -06:00
parent 96e078c646
commit af991e8dc3
4 changed files with 24 additions and 12 deletions

View file

@ -0,0 +1,7 @@
age-encryption.org/v1
-> ssh-ed25519 V3XmEA zirqdzZZ1E+sedBn7fbEHq4ntLEkokZ4GctarBBOHXY
Rvs5YHaAUeCZyNwPedubPcHClWYIuXXWA5zadXPWY6w
-> ssh-ed25519 KLPP8w BVp4rDkOYSQyn8oVeHFeinSqW+pdVtxBF9+5VM1yORY
bMwppAi8Nhz0328taU4AzUkTVyWtSLvFZG6c5W/Fs78
--- xCbqLhXAcOziO2wmbjTiSQfZvt5Rlsc4SCvF+iEzpQA
ôKB£î/²ZÅÈrÙ%¾à4¡´—Mq5×Ô_ÌÂ݆ã„Ò11 ܨqM;& ¢‡LríÂÒføû”]>N

View file

@ -5,4 +5,5 @@ in {
"secret1.age".publicKeys = [user1 system1];
"secret2.age".publicKeys = [user1];
"passwordfile-user1.age".publicKeys = [user1 system1];
"-leading-hyphen-filename.age".publicKeys = [user1 system1];
}

View file

@ -105,11 +105,11 @@ RULES=${RULES:-./secrets.nix}
function cleanup {
if [ -n "${CLEARTEXT_DIR+x}" ]
then
rm -rf "$CLEARTEXT_DIR"
rm -rf -- "$CLEARTEXT_DIR"
fi
if [ -n "${REENCRYPTED_DIR+x}" ]
then
rm -rf "$REENCRYPTED_DIR"
rm -rf -- "$REENCRYPTED_DIR"
fi
}
trap "cleanup" 0 2 3 15
@ -141,7 +141,7 @@ function decrypt {
err "No identity found to decrypt $FILE. Try adding an SSH key at $HOME/.ssh/id_rsa or $HOME/.ssh/id_ed25519 or using the --identity flag to specify a file."
fi
@ageBin@ "${DECRYPT[@]}" "$FILE" || exit 1
@ageBin@ "${DECRYPT[@]}" -- "$FILE" || exit 1
fi
}
@ -150,14 +150,14 @@ function edit {
KEYS=$(keys "$FILE") || exit 1
CLEARTEXT_DIR=$(@mktempBin@ -d)
CLEARTEXT_FILE="$CLEARTEXT_DIR/$(basename "$FILE")"
CLEARTEXT_FILE="$CLEARTEXT_DIR/$(basename -- "$FILE")"
DEFAULT_DECRYPT+=(-o "$CLEARTEXT_FILE")
decrypt "$FILE" "$KEYS" || exit 1
[ ! -f "$CLEARTEXT_FILE" ] || cp "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before"
[ ! -f "$CLEARTEXT_FILE" ] || cp -- "$CLEARTEXT_FILE" "$CLEARTEXT_FILE.before"
[ -t 0 ] || EDITOR='cp /dev/stdin'
[ -t 0 ] || EDITOR='cp -- /dev/stdin'
$EDITOR "$CLEARTEXT_FILE"
@ -166,7 +166,7 @@ function edit {
warn "$FILE wasn't created."
return
fi
[ -f "$FILE" ] && [ "$EDITOR" != ":" ] && @diffBin@ -q "$CLEARTEXT_FILE.before" "$CLEARTEXT_FILE" && warn "$FILE wasn't changed, skipping re-encryption." && return
[ -f "$FILE" ] && [ "$EDITOR" != ":" ] && @diffBin@ -q -- "$CLEARTEXT_FILE.before" "$CLEARTEXT_FILE" && warn "$FILE wasn't changed, skipping re-encryption." && return
ENCRYPT=()
while IFS= read -r key
@ -177,15 +177,15 @@ function edit {
done <<< "$KEYS"
REENCRYPTED_DIR=$(@mktempBin@ -d)
REENCRYPTED_FILE="$REENCRYPTED_DIR/$(basename "$FILE")"
REENCRYPTED_FILE="$REENCRYPTED_DIR/$(basename -- "$FILE")"
ENCRYPT+=(-o "$REENCRYPTED_FILE")
@ageBin@ "${ENCRYPT[@]}" <"$CLEARTEXT_FILE" || exit 1
mkdir -p "$(dirname "$FILE")"
mkdir -p -- "$(dirname -- "$FILE")"
mv -f "$REENCRYPTED_FILE" "$FILE"
mv -f -- "$REENCRYPTED_FILE" "$FILE"
}
function rekey {

View file

@ -24,8 +24,9 @@ pkgs.nixosTest {
services.openssh.enable = true;
age.secrets.passwordfile-user1 = {
file = ../example/passwordfile-user1.age;
age.secrets = {
passwordfile-user1.file = ../example/passwordfile-user1.age;
leading-hyphen.file = ../example/-leading-hyphen-filename.age;
};
age.identityPaths = options.age.identityPaths.default ++ ["/etc/ssh/this_key_wont_exist"];
@ -71,6 +72,7 @@ pkgs.nixosTest {
user = "user1";
password = "password1234";
secret2 = "world!";
hyphen-secret = "filename started with hyphen";
in ''
system1.wait_for_unit("multi-user.target")
system1.wait_until_succeeds("pgrep -f 'agetty.*tty1'")
@ -92,6 +94,8 @@ pkgs.nixosTest {
system1.wait_for_file("/tmp/2")
assert "${secret2}" in system1.succeed("cat /tmp/2")
assert "${hyphen-secret}" in system1.succeed("cat /run/agenix/leading-hyphen")
userDo = lambda input : f"sudo -u user1 -- bash -c 'set -eou pipefail; cd /tmp/secrets; {input}'"
before_hash = system1.succeed(userDo('sha256sum passwordfile-user1.age')).split()