From a0a176fa5dd534daaad29bf24a93b6a5c4c22ecc Mon Sep 17 00:00:00 2001 From: Josh Rabinowitz Date: Sat, 7 Mar 2020 13:07:03 -0600 Subject: [PATCH] Issue 552 508 revoked keys (#553) * warn about 'tell' on expired/revoked/invalid keys * error if 'tell' used on email with multiple keys * improve test of 'tell' with subdirs --- CHANGELOG.md | 8 ++-- man/man1/git-secret-add.1 | Bin 1629 -> 1627 bytes man/man1/git-secret-cat.1 | Bin 1469 -> 1467 bytes man/man1/git-secret-changes.1 | Bin 1669 -> 1667 bytes man/man1/git-secret-clean.1 | Bin 1099 -> 1097 bytes man/man1/git-secret-hide.1 | Bin 3106 -> 3104 bytes man/man1/git-secret-init.1 | Bin 1420 -> 1418 bytes man/man1/git-secret-killperson.1 | Bin 1007 -> 1005 bytes man/man1/git-secret-list.1 | Bin 1133 -> 1131 bytes man/man1/git-secret-remove.1 | Bin 1110 -> 1108 bytes man/man1/git-secret-reveal.1 | Bin 1760 -> 1758 bytes man/man1/git-secret-tell.1 | Bin 1748 -> 1930 bytes man/man1/git-secret-tell.1.ronn | 8 ++-- man/man1/git-secret-usage.1 | Bin 852 -> 850 bytes man/man1/git-secret-whoknows.1 | Bin 983 -> 981 bytes man/man7/git-secret.7 | Bin 9245 -> 9243 bytes src/_utils/_git_secret_tools.sh | 63 +++++++++++++++++++++---------- src/commands/git_secret_tell.sh | 2 +- tests/test_add.bats | 3 +- tests/test_expiration.bats | 9 ++++- 20 files changed, 63 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52d86f96..93385ed0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,12 @@ # Changelog -## {Next Version} +## {{Next Version}} ### Bugfixes -- Don't let reveal clobber secret files (#579) +- In 'tell', warn about disabled, revoked, expired, or invalid keys (#552, #508, #317, #290, #283, #238) +- Error if 'tell' is used on an email address with multiple keys (#552) +- Don't let 'reveal' clobber secret files (#579) ### Misc @@ -34,7 +36,7 @@ ### Features - Support SECRETS_PINENTRY env var for gnupg --pinentry-mode parameter (#221) -- Show output from gnupg if 'hide' fails (#516) +- Show output from gnupg if 'hide' fails (#516, #202, #317) - Add support for Busybox (#478) ### Bugfixes diff --git a/man/man1/git-secret-add.1 b/man/man1/git-secret-add.1 index 96f93441bdb050c38e4225b50c362816865a5bf4..fe29932a7e760abab80a1127e0d8ecbf40c6e7b2 100644 GIT binary patch delta 16 Xcmcc1bDL*E4y$isQF6w{;#aHyIqL?{ delta 18 Zcmcc3bC+jA4!c)kUTI=c<;KEStN=)s2fqLS diff --git a/man/man1/git-secret-cat.1 b/man/man1/git-secret-cat.1 index 41fbe2c1a620a225d62f6c314d21c3d664be542d..fcec3c13e148c87f5799d67fd16a9450ddd5830d 100644 GIT binary patch delta 16 XcmdnXy_ delta 18 ZcmeC;?%|%0%kGt!SDIKsKD$?9UTI=c<;IdMHULOX2TlM0 diff --git a/man/man1/git-secret-tell.1 b/man/man1/git-secret-tell.1 index 05f56a6c430d7f3c094caa33d136d02ade5101c5..d18ce63b256c658c0b335b8e579b36c54c2f0da7 100644 GIT binary patch delta 319 zcmXYsJx;_x422aUDung~NT#A;7X;!0hz2AmD5%nS6VJxVWE^>%4XNmAP|LClqSs{rjKlSY&AhCsuVj36^9LU{n~R0 z4UNFTWVhJ6$zGmFBTI-N4hna@VJnuAN+km$?+f<`=!_K3i`8YZx`2VbhXFMJuBEqG zE`rr)fJ#8m9V=C*ptO}{ZW5Oy79BWJ^4+56G{sN>`Y2bx4%*%ucb@*VW*H}aI&kS1 zAtv^;qZZi%R#i$g-Q~+HPD6flc55(5C{E_0O`@|Jxa~xZD)^8L68^nOqnri?OIo7GRQaN(+k7Q*g|yEKjT~)=|hTQ78v#1W`rV t3gww4848Jcl?wT3Ae{=usmVpDB{8}{Wocx3e%a0{}JiGiCq) diff --git a/man/man1/git-secret-tell.1.ronn b/man/man1/git-secret-tell.1.ronn index 352c7f3d..a86134d3 100644 --- a/man/man1/git-secret-tell.1.ronn +++ b/man/man1/git-secret-tell.1.ronn @@ -7,14 +7,16 @@ git-secret-tell - adds a person, who can access private data. ## DESCRIPTION -`git-secret-tell` receives an email addresses as an input, searches for the `gpg`-key in the `gpg`'s -`homedir` by these emails, then imports a person's public key into the `git-secret`'s inner keychain. +`git-secret-tell` receives one or more email addresses as an input, searches for the `gpg`-key in the `gpg` +`homedir` by these emails, then imports the corresponding public key into `git-secret`'s inner keychain. From this moment this person can encrypt new files with the keyring which contains their key, but they cannot decrypt the old files, which were already encrypted without their key. The files should be re-encrypted with the new keyring by someone who has the unencrypted files. -**Do not manually import secret key into `git-secret`**. Anyways, it won't work with any of the secret-keys imported. +Versions of `git-secret tell` after 0.3.2 will warn about keys that are expired, revoked, or otherwise invalid, +and also if multiple keys are found for a single email address. +**Do not manually import secret keys into `git-secret`**. It won't work with imported secret keys anyway. ## OPTIONS diff --git a/man/man1/git-secret-usage.1 b/man/man1/git-secret-usage.1 index 7f98210d48df1d970a4df8430bd85a0ffb631b6d..e7110a8723a549b57df44b6c9976c51b9caa26ca 100644 GIT binary patch delta 16 Xcmcb@c8P659; within field 10. (If there's no <>, then field is just an email address - # (and maybe a comment) and the regex just passes it through.) - # sed at the end removes any 'comment' that appears in parentheses, for #530 - # 3>&- closes fd 3 for bats, see https://github.com/bats-core/bats-core#file-descriptor-3-read-this-if-bats-hangs + ## We use --fixed-list-mode so older versions of gpg emit 'uid:' lines. + ## Gawk splits on colon as --with-colon, matches field 1 as 'uid', result=$($SECRETS_GPG_COMMAND "${args[@]}" --no-permission-warning --list-public-keys --with-colon --fixed-list-mode | \ - gawk -F: '$1~/uid/{print gensub(/.*<(.*)>.*/, "\\1", "g", $10); }' | \ - sed 's/([^)]*)//g' 3>&-) + gawk -F: '$1=="uid"' ) - echo "$result" + # For #508 / #552: warn user if gpg indicates keys are one of: + # i=invalid, d=disabled, r=revoked, e=expired, n=not valid + # See https://github.com/gpg/gnupg/blob/master/doc/DETAILS#field-2---validity # for more on gpg 'validity codes'. + local invalid_lines + invalid_lines=$(echo "$result" | gawk -F: '$2=="i" || $2=="d" || $2=="r" || $2=="e" || $2=="n"') + + local emails + emails=$(_extract_emails_from_gpg_output "$result") + + local emails_with_invalid_keys + emails_with_invalid_keys=$(_extract_emails_from_gpg_output "$invalid_lines") + + if [[ -n "$emails_with_invalid_keys" ]]; then + _warn "at least one key for email(s) is revoked, expired, or otherwise invalid: $emails_with_invalid_keys" + fi + + echo "$emails" } +function _extract_emails_from_gpg_output { + local result=$1 + + # gensub() outputs email from <> within field 10, "User-ID". If there's no <>, then field is just an email address + # (and maybe a comment) and we pass it through. + # Sed at the end removes any 'comment' that appears in parentheses, for #530 + # 3>&- closes fd 3 for bats, see https://github.com/bats-core/bats-core#file-descriptor-3-read-this-if-bats-hangs + local emails + emails=$(echo "$result" | gawk -F: '{print gensub(/.*<(.*)>.*/, "\\1", "g", $10); }' | sed 's/([^)]*)//g' 3>&-) + echo "$emails" +} function _get_users_in_gitsecret_keyring { # show the users in the gitsecret keyring. diff --git a/src/commands/git_secret_tell.sh b/src/commands/git_secret_tell.sh index af22db24..768b818d 100644 --- a/src/commands/git_secret_tell.sh +++ b/src/commands/git_secret_tell.sh @@ -64,7 +64,7 @@ function tell { if [[ "${#emails[@]}" -eq 0 ]]; then # If after possible addition of git_email, emails are still empty, # we should raise an exception. - _abort "you must provide at least one email address." + _abort "you must use -m or provide at least one email address." fi _assert_keychain_contains_emails "$homedir" "${emails[@]}" diff --git a/tests/test_add.bats b/tests/test_add.bats index a063d2d0..e2995bee 100644 --- a/tests/test_add.bats +++ b/tests/test_add.bats @@ -105,7 +105,8 @@ function teardown { run git secret add -i "$test_file" [ "$status" -eq 0 ] - run _file_has_line "$test_file" "../.gitignore" + [[ -f "$current_dir/.gitignore" ]] + run _file_has_line "$test_file" "$current_dir/.gitignore" [ "$status" -eq 0 ] # .gitignore was not created: diff --git a/tests/test_expiration.bats b/tests/test_expiration.bats index fcee482a..8a387cbe 100644 --- a/tests/test_expiration.bats +++ b/tests/test_expiration.bats @@ -18,7 +18,7 @@ function teardown { unset_current_state } -@test "test 'hide' using expired key" { +@test "run 'hide' using expired key" { FILE_TO_HIDE="$TEST_DEFAULT_FILENAME" FILE_CONTENTS="hidden content юникод" set_state_secret_add "$FILE_TO_HIDE" "$FILE_CONTENTS" @@ -34,6 +34,11 @@ function teardown { } +@test "run 'whoknows' using expired key" { + run git secret whoknows + [ $status -eq 0 ] +} + @test "run 'whoknows -l' on only expired user" { run git secret whoknows -l [ "$status" -eq 0 ] @@ -50,7 +55,7 @@ function teardown { -@test "run 'whoknows -l' on expired and normal user" { +@test "run 'whoknows -l' on normal key and expired key" { install_fixture_key "$TEST_DEFAULT_USER" set_state_secret_tell "$TEST_DEFAULT_USER"