Skip to content

Commit 453e106

Browse files
Clean up exported public keys if a recipient is removed (#2328)
Fixes #2315 RELEASE_NOTES=[BUGFIX] Remove exported public keys of removed recipients. Signed-off-by: Dominik Schulz <[email protected]> Signed-off-by: Dominik Schulz <[email protected]>
1 parent def69d3 commit 453e106

File tree

5 files changed

+51
-10
lines changed

5 files changed

+51
-10
lines changed

internal/action/clone.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ func (s *Action) cloneCheckDecryptionKeys(ctx context.Context, mount string) err
218218
var exported bool
219219
if sub, err := s.Store.GetSubStore(mount); err == nil {
220220
debug.Log("exporting public keys: %v", idSet.Elements())
221-
exported, err = sub.ExportMissingPublicKeys(ctx, idSet.Elements())
221+
exported, err = sub.UpdateExportedPublicKeys(ctx, idSet.Elements())
222222
if err != nil {
223223
debug.Log("failed to export missing public keys: %w", err)
224224
}

internal/action/sync.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ func syncExportKeys(ctx context.Context, sub *leaf.Store, name string) error {
217217

218218
return err
219219
}
220-
exported, err := sub.ExportMissingPublicKeys(ctx, rs)
220+
exported, err := sub.UpdateExportedPublicKeys(ctx, rs)
221221
if err != nil {
222222
out.Errorf(ctx, "Failed to export missing public keys for %q: %s", name, err)
223223

internal/backend/storage/fs/store.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ func (s *Store) List(ctx context.Context, prefix string) ([]string, error) {
157157
return err
158158
}
159159
relPath := strings.TrimPrefix(path, s.path+string(filepath.Separator)) + string(filepath.Separator)
160-
if info.IsDir() && strings.HasPrefix(info.Name(), ".") && path != s.path && !strings.HasPrefix(prefix, relPath) {
160+
if info.IsDir() && strings.HasPrefix(info.Name(), ".") && path != s.path && !strings.HasPrefix(prefix, relPath) && filepath.Base(path) != filepath.Base(prefix) {
161161
debug.Log("skipping dot dir (relPath: %s, prefix: %s)", relPath, prefix)
162162

163163
return filepath.SkipDir

internal/store/leaf/crypto.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ func (s *Store) exportPublicKey(ctx context.Context, exp keyExporter, r string)
133133
return "", fmt.Errorf("failed to write exported public key to store: %w", err)
134134
}
135135

136+
debug.Log("exported public keys for %s to %s", r, filename)
137+
136138
return filename, nil
137139
}
138140

internal/store/leaf/recipients.go

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -219,18 +219,24 @@ type keyExporter interface {
219219
ExportPublicKey(ctx context.Context, id string) ([]byte, error)
220220
}
221221

222-
// ExportMissingPublicKeys will export any possibly missing public keys to the
222+
// UpdateExportedPublicKeys will export any possibly missing public keys to the
223223
// stores .public-keys directory.
224-
func (s *Store) ExportMissingPublicKeys(ctx context.Context, rs []string) (bool, error) {
224+
func (s *Store) UpdateExportedPublicKeys(ctx context.Context, rs []string) (bool, error) {
225225
exp, ok := s.crypto.(keyExporter)
226226
if !ok {
227227
debug.Log("not exporting public keys for %T", s.crypto)
228228

229229
return false, nil
230230
}
231231

232-
var failed, exported bool
232+
recipients := make(map[string]bool, len(rs))
233233
for _, r := range rs {
234+
recipients[r] = true
235+
}
236+
237+
// add any missing keys
238+
var failed, exported bool
239+
for r := range recipients {
234240
if r == "" {
235241
continue
236242
}
@@ -258,13 +264,43 @@ func (s *Store) ExportMissingPublicKeys(ctx context.Context, rs []string) (bool,
258264

259265
continue
260266
}
267+
}
268+
269+
// remove any extra key files
270+
keys, err := s.storage.List(ctx, keyDir)
271+
if err != nil {
272+
failed = true
273+
274+
out.Errorf(ctx, "Failed to list keys: %s", err)
275+
}
276+
277+
debug.Log("Checking %q for extra keys that need to be removed", keys)
278+
for _, key := range keys {
279+
key := strings.TrimPrefix(key, keyDir+string(filepath.Separator))
280+
if !recipients[key] {
281+
if err := s.storage.Delete(ctx, filepath.Join(keyDir, key)); err != nil {
282+
out.Errorf(ctx, "Failed to remove extra key %q: %s", key, err)
283+
284+
continue
285+
}
286+
287+
if err := s.storage.Add(ctx, filepath.Join(keyDir, key)); err != nil {
288+
out.Errorf(ctx, "Failed to mark extra key for removal %q: %s", key, err)
289+
290+
continue
291+
}
292+
293+
// to ensure the commit
294+
exported = true
295+
debug.Log("Removed extra key %s", key)
296+
}
297+
}
261298

262-
if err := s.storage.Commit(ctx, fmt.Sprintf("Exported Public Keys %s", r)); err != nil && !errors.Is(err, store.ErrGitNothingToCommit) {
299+
if exported {
300+
if err := s.storage.Commit(ctx, fmt.Sprintf("Updated exported Public Keys")); err != nil && !errors.Is(err, store.ErrGitNothingToCommit) {
263301
failed = true
264302

265303
out.Errorf(ctx, "Failed to git commit: %s", err)
266-
267-
continue
268304
}
269305
}
270306

@@ -302,9 +338,12 @@ func (s *Store) saveRecipients(ctx context.Context, rs []string, msg string) err
302338

303339
// save all recipients public keys to the repo
304340
if ctxutil.IsExportKeys(ctx) {
305-
if _, err := s.ExportMissingPublicKeys(ctx, rs); err != nil {
341+
debug.Log("updating exported keys")
342+
if _, err := s.UpdateExportedPublicKeys(ctx, rs); err != nil {
306343
out.Errorf(ctx, "Failed to export missing public keys: %s", err)
307344
}
345+
} else {
346+
debug.Log("updating exported keys not requested")
308347
}
309348

310349
// push to remote repo

0 commit comments

Comments
 (0)