From e8fd2a7b1c4df5c319f4b99b193f421c7806570e Mon Sep 17 00:00:00 2001 From: Dominik Schulz Date: Tue, 5 Jun 2018 16:51:38 +0200 Subject: [PATCH] Resolve key ids before adding or removing (#850) Fixes #793 --- commands.go | 4 ++++ pkg/action/recipients.go | 43 ++++++++++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/commands.go b/commands.go index fc8b0ce4de..6901498e87 100644 --- a/commands.go +++ b/commands.go @@ -878,6 +878,10 @@ func getCommands(ctx context.Context, action *ap.Action, app *cli.App) []cli.Com Name: "store", Usage: "Store to operate on", }, + cli.BoolFlag{ + Name: "force", + Usage: "Force adding non-existing keys", + }, }, }, { diff --git a/pkg/action/recipients.go b/pkg/action/recipients.go index 7072cff30f..6011915661 100644 --- a/pkg/action/recipients.go +++ b/pkg/action/recipients.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "sort" - "strings" "github.com/gopasspw/gopass/pkg/ctxutil" "github.com/gopasspw/gopass/pkg/cui" @@ -102,11 +101,16 @@ func (s *Action) RecipientsAdd(ctx context.Context, c *cli.Context) error { continue } - if !termio.AskForConfirmation(ctx, fmt.Sprintf("Do you want to add '%s' as an recipient to the store '%s'?", crypto.FormatKey(ctx, keys[0]), store)) { + recp := r + if len(keys) > 0 { + recp = crypto.Fingerprint(ctx, keys[0]) + } + + if !termio.AskForConfirmation(ctx, fmt.Sprintf("Do you want to add '%s' as an recipient to the store '%s'?", crypto.FormatKey(ctx, recp), store)) { continue } - if err := s.Store.AddRecipient(ctxutil.WithNoConfirm(ctx, true), store, keys[0]); err != nil { + if err := s.Store.AddRecipient(ctxutil.WithNoConfirm(ctx, true), store, recp); err != nil { return ExitError(ctx, ExitRecipients, err, "failed to add recipient '%s': %s", r, err) } added++ @@ -123,6 +127,8 @@ func (s *Action) RecipientsAdd(ctx context.Context, c *cli.Context) error { // RecipientsRemove removes recipients func (s *Action) RecipientsRemove(ctx context.Context, c *cli.Context) error { store := c.String("store") + force := c.Bool("force") + removed := 0 // select store if store == "" { @@ -141,7 +147,6 @@ func (s *Action) RecipientsRemove(ctx context.Context, c *cli.Context) error { recipients = rs } - removed := 0 for _, r := range recipients { kl, err := crypto.FindPrivateKeys(ctx, r) if err == nil { @@ -151,12 +156,38 @@ func (s *Action) RecipientsRemove(ctx context.Context, c *cli.Context) error { } } } - if err := s.Store.RemoveRecipient(ctxutil.WithNoConfirm(ctx, true), store, strings.TrimPrefix(r, "0x")); err != nil { - return ExitError(ctx, ExitRecipients, err, "failed to remove recipient '%s': %s", r, err) + + keys, err := crypto.FindPublicKeys(ctx, r) + if err != nil { + out.Cyan(ctx, "WARNING: Failed to list public key '%s': %s", r, err) + if !force { + continue + } + keys = []string{r} + } + if len(keys) < 1 && !force { + out.Cyan(ctx, "Warning: No matching valid key found. If the key is in your keyring you may need to validate it.") + out.Cyan(ctx, "If this is your key: gpg --edit-key %s; trust (set to ultimate); quit", r) + out.Cyan(ctx, "If this is not your key: gpg --edit-key %s; lsign; trust; save; quit", r) + out.Cyan(ctx, "You may need to run 'gpg --update-trustdb' afterwards") + continue + } + + recp := r + if len(keys) > 0 { + recp = crypto.Fingerprint(ctx, keys[0]) + } + fmt.Printf("r: %s - recp: %s\n", r, recp) + + if err := s.Store.RemoveRecipient(ctxutil.WithNoConfirm(ctx, true), store, recp); err != nil { + return ExitError(ctx, ExitRecipients, err, "failed to remove recipient '%s': %s", recp, err) } fmt.Fprintf(stdout, removalWarning, r) removed++ } + if removed < 1 { + return ExitError(ctx, ExitUnknown, nil, "no key removed") + } out.Green(ctx, "\nRemoved %d recipients", removed) out.Cyan(ctx, "You need to run 'gopass sync' to push these changes")