pashage

Yet Another Opinionated Re-engineering of the Unix Password Store
git clone https://git.instinctive.eu/pashage.git
Log | Files | Refs | README | LICENSE

commit 48ed40851c85708dc0cfefd3245159adf7ef55a0
parent c52ac5c603f3f2340404b044e0eb996d93c13f2c
Author: Natasha Kerensikova <natgh@instinctive.eu>
Date:   Tue, 15 Oct 2024 18:39:16 +0000

Secrets with flag-like names are tested
Diffstat:
Mspec/pass_spec.sh | 253++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 233 insertions(+), 20 deletions(-)

diff --git a/spec/pass_spec.sh b/spec/pass_spec.sh @@ -58,6 +58,8 @@ Describe 'Pass-like command' setup_log() { %text #|Initial setup #| + #| -g.age | 2 ++ + #| -g.gpg | 2 ++ #| .gpg-id | 1 + #| extra/subdir/file.age | 2 ++ #| extra/subdir/file.gpg | 2 ++ @@ -75,7 +77,7 @@ Describe 'Pass-like command' #| stale.gpg | 3 +++ #| subdir/file.age | 2 ++ #| subdir/file.gpg | 2 ++ - #| 17 files changed, 47 insertions(+) + #| 19 files changed, 51 insertions(+) } setup_id() { @@ -127,6 +129,9 @@ Describe 'Pass-like command' #|Recipient:master #|Recipient:myself #|:0-password + %text | setup_secret '-g' + #|Recipient:myself + #|:-- @git -C "${PREFIX}" add . @git -C "${PREFIX}" commit -m 'Initial setup' >/dev/null @@ -304,19 +309,21 @@ Describe 'Pass-like command' %text #|Set age recipients at store root #| + #| -g.age | 2 +- #| .age-recipients | 1 + #| extra/subdir/file.age | 2 +- #| stale.age | 3 +-- #| subdir/file.age | 2 +- - #| 4 files changed, 4 insertions(+), 4 deletions(-) + #| 5 files changed, 5 insertions(+), 5 deletions(-) else %text:expand #|Reencrypt password store using new GPG id new-id. #| + #| -g.$1 | 2 +- #| extra/subdir/file.$1 | 2 +- #| stale.$1 | 3 +-- #| subdir/file.$1 | 2 +- - #| 3 files changed, 3 insertions(+), 4 deletions(-) + #| 4 files changed, 4 insertions(+), 5 deletions(-) #|Set GPG id to new-id. #| #| .gpg-id | 2 +- @@ -459,23 +466,25 @@ Describe 'Pass-like command' else The line 1 of output should equal 'Password Store' fi - The line 2 of output should include 'extra' - The line 3 of output should include 'subdir' - The line 4 of output should include 'file' - The line 5 of output should include 'file' - The line 6 of output should include 'fluff' - The line 7 of output should include 'one' - The line 8 of output should include 'one' - The line 9 of output should include 'three' - The line 10 of output should include 'three' - The line 11 of output should include 'two' - The line 12 of output should include 'two' - The line 13 of output should include 'shared' - The line 14 of output should include 'stale' - The line 15 of output should include 'stale' - The line 16 of output should include 'subdir' - The line 17 of output should include 'file' - The line 18 of output should include 'file' + The line 2 of output should include '-g' + The line 3 of output should include '-g' + The line 4 of output should include 'extra' + The line 5 of output should include 'subdir' + The line 6 of output should include 'file' + The line 7 of output should include 'file' + The line 8 of output should include 'fluff' + The line 9 of output should include 'one' + The line 10 of output should include 'one' + The line 11 of output should include 'three' + The line 12 of output should include 'three' + The line 13 of output should include 'two' + The line 14 of output should include 'two' + The line 15 of output should include 'shared' + The line 16 of output should include 'stale' + The line 17 of output should include 'stale' + The line 18 of output should include 'subdir' + The line 19 of output should include 'file' + The line 20 of output should include 'file' End It 'does not list a file masquerading as a directory' @@ -522,6 +531,20 @@ Describe 'Pass-like command' The output should equal 'p4ssw0rd' End + It 'fails to decrypt a flag' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 -g + The status should equal 1 + The output should be blank + The error should include 'Usage:' + End + + It 'decrypts a password file named like a flag' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 -- -g + The output should equal '--' + End + It 'decrypts a password file even when called as `list`' Skip if 'pass(age) needs bash' check_skip $2 When run script $1 ls subdir/file @@ -654,6 +677,37 @@ Describe 'Pass-like command' The contents of file "${GITLOG}" should equal "$(expected_log $3)" End + It 'fails to insert an unescaped flag' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 insert -h + The status should equal 1 + The output should be blank + The error should include 'Usage:' + The result of function git_log should be successful + The contents of file "${GITLOG}" should equal "$(setup_log)" + End + + It 'inserts a new single-line entry named like a flag' + Skip if 'pass(age) needs bash' check_skip $2 + Data + #|pass-word + #|pass-word + End + When run script $1 insert -- -h + The output should include '-h' + The contents of file "${PREFIX}/-h.$3" \ + should include "$3:pass-word" + expected_log() { %text:expand + #|Add given password for -h to store. + #| + #| -h.$1 | 2 ++ + #| 1 file changed, 2 insertions(+) + setup_log + } + The result of function git_log should be successful + The contents of file "${GITLOG}" should equal "$(expected_log $3)" + End + It 'inserts a new single-line entry with echo' Skip if 'pass(age) needs bash' check_skip $2 Data "pass-word" @@ -749,6 +803,34 @@ Describe 'Pass-like command' The contents of file "${GITLOG}" should equal "$(expected_log $3)" End + It 'creates a file named like a flag' + EDITOR='ed -c' + Skip if 'pass(age) needs bash' check_skip $2 + Data + #|a + #|New password + #|. + #|wq + End + When run script $1 edit -h + The file "${PREFIX}/-h.$3" should be exist + expected_file() { %text:expand + #|$1Recipient:myself + #|$1:New password + } + The contents of file "${PREFIX}/-h.$3" should \ + equal "$(expected_file "$3")" + expected_log() { %text:expand + #|Add password for -h using ed -c. + #| + #| -h.$1 | 2 ++ + #| 1 file changed, 2 insertions(+) + setup_log + } + The result of function git_log should be successful + The contents of file "${GITLOG}" should equal "$(expected_log $3)" + End + It 'updates a file using EDITOR' Skip if 'pass(age) needs bash' check_skip $2 Data @@ -855,6 +937,37 @@ Describe 'Pass-like command' The contents of file "${GITLOG}" should equal "$(expected_log $3)" End + It 'fails to generates a new file named like a flag without escape' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 generate -h + The status should equal 1 + The output should be blank + The error should include 'Usage:' + The result of function git_log should be successful + The contents of file "${GITLOG}" should equal "$(setup_log)" + End + + It 'generates a new file named like a flag' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 generate -- -h + The output should include 'The generated password for' + The file "${PREFIX}/-h.$3" should be exist + The lines of contents of file "${PREFIX}/-h.$3" should equal 2 + The line 1 of contents of file "${PREFIX}/-h.$3" should \ + equal "$3Recipient:myself" + The output should \ + include "$(@sed -n "2s/$3://p" "${PREFIX}/-h.$3")" + expected_log() { %text:expand + #|Add generated password for -h. + #| + #| -h.$1 | 2 ++ + #| 1 file changed, 2 insertions(+) + setup_log + } + The result of function git_log should be successful + The contents of file "${GITLOG}" should equal "$(expected_log $3)" + End + It 'generates a new file without symbols' Skip if 'pass(age) needs bash' check_skip $2 When run script $1 generate -n newfile 4 @@ -975,6 +1088,33 @@ Describe 'Pass-like command' The contents of file "${GITLOG}" should equal "$(expected_log $3)" End + It 'fails to remove a file named like a flag without escape' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 rm -f -g + The status should equal 1 + The output should be blank + The error should include 'Usage:' + The result of function git_log should be successful + The contents of file "${GITLOG}" should equal "$(setup_log)" + End + + It 'removes a file named like a flag' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 rm -f -- -g + The output should include '-g' + The error should be blank + The file "${PREFIX}/-g.$3" should not be exist + expected_log() { %text:expand + #|Remove -g from store. + #| + #| -g.$1 | 2 -- + #| 1 file changed, 2 deletions(-) + setup_log + } + The result of function git_log should be successful + The contents of file "${GITLOG}" should equal "$(expected_log $3)" + End + It 'does not remove a directory without `-r` even when forced' Skip if 'pass(age) needs bash' check_skip $2 When run script $1 rm -f fluff @@ -1037,6 +1177,43 @@ Describe 'Pass-like command' The contents of file "${GITLOG}" should equal "$(expected_log $3 $2)" End + It 'fails rename a file named like a flag without escape' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 mv -g safe-name + The status should equal 1 + The output should be blank + The error should include 'Usage:' + The result of function git_log should be successful + The contents of file "${GITLOG}" should equal "$(setup_log)" + End + + It 'renames a file named like a flag' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 mv -- -g -h + The error should be blank + The file "${PREFIX}/-g.$3" should not be exist + file_contents() { %text:expand + #|${1}Recipient:myself + #|${1}:-- + } + The contents of file "${PREFIX}/-h.$3" \ + should equal "$(file_contents "$3")" + expected_log() { + if [ "$2" = pashage ]; then + %putsn 'Move -g.age to -h.age' + else + %putsn 'Rename -g to -h.' + fi + %text:expand + #| + #| -g.$1 => -h.$1 | 0 + #| 1 file changed, 0 insertions(+), 0 deletions(-) + setup_log + } + The result of function git_log should be successful + The contents of file "${GITLOG}" should equal "$(expected_log $3 $2)" + End + It 'reencrypts a moved file' Skip if 'pass(age) needs bash' check_skip $2 When run script $1 mv subdir/file shared/renamed @@ -1227,6 +1404,42 @@ Describe 'Pass-like command' The contents of file "${GITLOG}" should equal "$(expected_log $3 $2)" End + It 'fails copy a file named like a flag without escape' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 cp -g safe-name + The status should equal 1 + The output should be blank + The error should not be blank + The error should include 'Usage:' + The contents of file "${GITLOG}" should equal "$(setup_log)" + End + + It 'copies a file named like a flag' + Skip if 'pass(age) needs bash' check_skip $2 + When run script $1 cp -- -g -h + The error should be blank + file_contents() { %text:expand + #|${1}Recipient:myself + #|${1}:-- + } + The contents of file "${PREFIX}/-h.$3" \ + should equal "$(file_contents "$3")" + expected_log() { + if [ "$2" = pashage ]; then + %putsn 'Copy -g.age to -h.age' + else + %putsn 'Copy -g to -h.' + fi + %text:expand + #| + #| -h.$1 | 2 ++ + #| 1 file changed, 2 insertions(+) + setup_log + } + The result of function git_log should be successful + The contents of file "${GITLOG}" should equal "$(expected_log $3 $2)" + End + It 'reencrypts a copied file' Skip if 'pass(age) needs bash' check_skip $2 When run script $1 cp subdir/file shared/copy