Skip to content

Commit 6ebd5a5

Browse files
committed
cmd/fscrypt: don't load protector in remove-protector-from-policy
Make remove-protector-from-policy work even if the protector cannot be loaded (for example, due to having been deleted already). Fixes #258 Fixes #272
1 parent 57be034 commit 6ebd5a5

5 files changed

Lines changed: 70 additions & 15 deletions

File tree

actions/policy.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -461,14 +461,15 @@ func (policy *Policy) AddProtector(protector *Protector) error {
461461
}
462462

463463
// RemoveProtector updates the data that is wrapping the Policy Key so that the
464-
// provided Protector is no longer protecting the specified Policy. If an error
465-
// is returned, no data has been changed. Note that no protector links are
464+
// protector with the given descriptor is no longer protecting the specified
465+
// Policy. If an error is returned, no data has been changed. Note that the
466+
// protector itself won't be removed, nor will a link to the protector be
466467
// removed (in the case where the protector and policy are on different
467-
// filesystems). The policy and protector can be locked or unlocked.
468-
func (policy *Policy) RemoveProtector(protector *Protector) error {
469-
idx, ok := policy.findWrappedKeyIndex(protector.Descriptor())
468+
// filesystems). The policy can be locked or unlocked.
469+
func (policy *Policy) RemoveProtector(protectorDescriptor string) error {
470+
idx, ok := policy.findWrappedKeyIndex(protectorDescriptor)
470471
if !ok {
471-
return &ErrNotProtected{policy.Descriptor(), protector.Descriptor()}
472+
return &ErrNotProtected{policy.Descriptor(), protectorDescriptor}
472473
}
473474

474475
if len(policy.data.WrappedPolicyKeys) == 1 {

actions/policy_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ func TestPolicyGoodRemoveProtector(t *testing.T) {
114114
t.Fatal(err)
115115
}
116116

117-
err = pol.RemoveProtector(pro1)
117+
err = pol.RemoveProtector(pro1.Descriptor())
118118
if err != nil {
119119
t.Error(err)
120120
}
@@ -135,11 +135,11 @@ func TestPolicyBadRemoveProtector(t *testing.T) {
135135
}
136136
defer cleanupProtector(pro2)
137137

138-
if pol.RemoveProtector(pro2) == nil {
138+
if pol.RemoveProtector(pro2.Descriptor()) == nil {
139139
t.Error("we should not be able to remove a protector we did not add")
140140
}
141141

142-
if pol.RemoveProtector(pro1) == nil {
142+
if pol.RemoveProtector(pro1.Descriptor()) == nil {
143143
t.Error("we should not be able to remove all the protectors from a policy")
144144
}
145145
}

cli-tests/t_metadata.out

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
ext4 filesystem "MNT" has 3 protectors and 1 policy
2+
3+
PROTECTOR LINKED DESCRIPTION
4+
desc1 No custom protector "foo"
5+
desc2 No custom protector "bar"
6+
desc3 No custom protector "baz"
7+
8+
POLICY UNLOCKED PROTECTORS
9+
desc4 No desc1, desc2, desc3
10+
ext4 filesystem "MNT" has 2 protectors and 1 policy
11+
12+
PROTECTOR LINKED DESCRIPTION
13+
desc1 No custom protector "foo"
14+
desc2 No custom protector "bar"
15+
16+
POLICY UNLOCKED PROTECTORS
17+
desc4 No desc1

cli-tests/t_metadata.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/bash
2+
3+
# Test 'fscrypt metadata'.
4+
5+
cd "$(dirname "$0")"
6+
. common.sh
7+
8+
# Create three protectors, and a policy protected by them.
9+
echo foo | fscrypt metadata create protector "$MNT" \
10+
--quiet --name=foo --source=custom_passphrase
11+
echo bar | fscrypt metadata create protector "$MNT" \
12+
--quiet --name=bar --source=custom_passphrase
13+
echo baz | fscrypt metadata create protector "$MNT" \
14+
--quiet --name=baz --source=custom_passphrase
15+
prot_foo=$MNT:$(_get_protector_descriptor "$MNT" custom foo)
16+
prot_bar=$MNT:$(_get_protector_descriptor "$MNT" custom bar)
17+
desc_baz=$(_get_protector_descriptor "$MNT" custom baz)
18+
prot_baz=$MNT:$desc_baz
19+
echo foo | fscrypt metadata create policy "$MNT" --quiet \
20+
--protector="$prot_foo"
21+
policy=$MNT:$(fscrypt status "$MNT" | grep -A10 "^POLICY" | \
22+
tail -1 | awk '{print $1}')
23+
echo -e "bar\nfoo" | fscrypt metadata add-protector-to-policy --quiet \
24+
--policy="$policy" --protector="$prot_bar"
25+
echo -e "baz\nfoo" | fscrypt metadata add-protector-to-policy --quiet \
26+
--policy="$policy" --protector="$prot_baz" --unlock-with="$prot_foo"
27+
fscrypt status "$MNT"
28+
29+
# Remove two of the protectors from the policy.
30+
# Make sure that this works even if the protector was already deleted.
31+
fscrypt metadata remove-protector-from-policy --quiet --force \
32+
--policy="$policy" --protector="$prot_bar"
33+
rm "$MNT/.fscrypt/protectors/$desc_baz"
34+
fscrypt metadata remove-protector-from-policy --quiet --force \
35+
--policy="$policy" --protector="$prot_baz"
36+
fscrypt status "$MNT"

cmd/fscrypt/commands.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,29 +1083,30 @@ func removeProtectorAction(c *cli.Context) error {
10831083
return err
10841084
}
10851085

1086-
// We do not need to unlock anything for this operation
1087-
protector, err := getProtectorFromFlag(protectorFlag.Value, nil)
1086+
// We only need the protector descriptor, not the protector itself.
1087+
ctx, protectorDescriptor, err := parseMetadataFlag(protectorFlag.Value, nil)
10881088
if err != nil {
10891089
return newExitError(c, err)
10901090
}
1091-
policy, err := getPolicyFromFlag(policyFlag.Value, protector.Context.TargetUser)
1091+
// We don't need to unlock the policy for this operation.
1092+
policy, err := getPolicyFromFlag(policyFlag.Value, ctx.TargetUser)
10921093
if err != nil {
10931094
return newExitError(c, err)
10941095
}
10951096

10961097
prompt := fmt.Sprintf("Stop protecting policy %s with protector %s?",
1097-
policy.Descriptor(), protector.Descriptor())
1098+
policy.Descriptor(), protectorDescriptor)
10981099
warning := "All files using this policy will NO LONGER be accessible with this protector!!"
10991100
if err := askConfirmation(prompt, false, warning); err != nil {
11001101
return newExitError(c, err)
11011102
}
11021103

1103-
if err := policy.RemoveProtector(protector); err != nil {
1104+
if err := policy.RemoveProtector(protectorDescriptor); err != nil {
11041105
return newExitError(c, err)
11051106
}
11061107

11071108
fmt.Fprintf(c.App.Writer, "Protector %s no longer protecting policy %s.\n",
1108-
protector.Descriptor(), policy.Descriptor())
1109+
protectorDescriptor, policy.Descriptor())
11091110
return nil
11101111
}
11111112

0 commit comments

Comments
 (0)