aboutsummaryrefslogtreecommitdiff
path: root/keyring
diff options
context:
space:
mode:
Diffstat (limited to 'keyring')
-rw-r--r--keyring/fs_keyring.go29
-rw-r--r--keyring/keyring.go8
-rw-r--r--keyring/keyring_test.go50
3 files changed, 63 insertions, 24 deletions
diff --git a/keyring/fs_keyring.go b/keyring/fs_keyring.go
index 970105e..42c1648 100644
--- a/keyring/fs_keyring.go
+++ b/keyring/fs_keyring.go
@@ -228,16 +228,23 @@ func fsRemoveEncryptionKey(descriptor string, mount *filesystem.Mount,
return err
}
- savedPrivs, err := dropPrivsIfNeeded(user, &arg.Key_spec)
- if err != nil {
- return err
+ ioc := unix.FS_IOC_REMOVE_ENCRYPTION_KEY
+ iocName := "FS_IOC_REMOVE_ENCRYPTION_KEY"
+ var savedPrivs *savedPrivs
+ if user == nil {
+ ioc = unix.FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS
+ iocName = "FS_IOC_REMOVE_ENCRYPTION_KEY_ALL_USERS"
+ } else {
+ savedPrivs, err = dropPrivsIfNeeded(user, &arg.Key_spec)
+ if err != nil {
+ return err
+ }
}
- _, _, errno := unix.Syscall(unix.SYS_IOCTL, dir.Fd(),
- unix.FS_IOC_REMOVE_ENCRYPTION_KEY, uintptr(unsafe.Pointer(&arg)))
+ _, _, errno := unix.Syscall(unix.SYS_IOCTL, dir.Fd(), uintptr(ioc), uintptr(unsafe.Pointer(&arg)))
restorePrivs(savedPrivs)
- log.Printf("FS_IOC_REMOVE_ENCRYPTION_KEY(%q, %s) = %v, removal_status_flags=0x%x",
- mount.Path, descriptor, errno, arg.Removal_status_flags)
+ log.Printf("%s(%q, %s) = %v, removal_status_flags=0x%x",
+ iocName, mount.Path, descriptor, errno, arg.Removal_status_flags)
switch errno {
case 0:
switch {
@@ -251,9 +258,11 @@ func fsRemoveEncryptionKey(descriptor string, mount *filesystem.Mount,
// ENOKEY means either the key is completely missing or that the
// current user doesn't have a claim to it. Distinguish between
// these two cases by getting the key status.
- status, _ := fsGetEncryptionKeyStatus(descriptor, mount, user)
- if status == KeyPresentButOnlyOtherUsers {
- return ErrKeyAddedByOtherUsers
+ if user != nil {
+ status, _ := fsGetEncryptionKeyStatus(descriptor, mount, user)
+ if status == KeyPresentButOnlyOtherUsers {
+ return ErrKeyAddedByOtherUsers
+ }
}
return ErrKeyNotPresent
default:
diff --git a/keyring/keyring.go b/keyring/keyring.go
index 925d059..5a75153 100644
--- a/keyring/keyring.go
+++ b/keyring/keyring.go
@@ -100,9 +100,13 @@ func AddEncryptionKey(key *crypto.Key, descriptor string, options *Options) erro
// RemoveEncryptionKey removes an encryption policy key from a kernel keyring.
// It uses either the filesystem keyring for the target Mount or the user
// keyring for the target User.
-func RemoveEncryptionKey(descriptor string, options *Options) error {
+func RemoveEncryptionKey(descriptor string, options *Options, allUsers bool) error {
if shouldUseFsKeyring(descriptor, options) {
- return fsRemoveEncryptionKey(descriptor, options.Mount, options.User)
+ user := options.User
+ if allUsers {
+ user = nil
+ }
+ return fsRemoveEncryptionKey(descriptor, options.Mount, user)
}
return userRemoveKey(options.Service+descriptor, options.User)
}
diff --git a/keyring/keyring_test.go b/keyring/keyring_test.go
index a675a70..8912556 100644
--- a/keyring/keyring_test.go
+++ b/keyring/keyring_test.go
@@ -139,11 +139,11 @@ func testAddAndRemoveKey(t *testing.T, descriptor string, options *Options) {
t.Error(err)
}
assertKeyStatus(t, descriptor, options, KeyPresent)
- if err := RemoveEncryptionKey(descriptor, options); err != nil {
+ if err := RemoveEncryptionKey(descriptor, options, false); err != nil {
t.Error(err)
}
assertKeyStatus(t, descriptor, options, KeyAbsent)
- err := RemoveEncryptionKey(descriptor, options)
+ err := RemoveEncryptionKey(descriptor, options, false)
if err != ErrKeyNotPresent {
t.Error(err)
}
@@ -155,12 +155,12 @@ func testAddAndRemoveKey(t *testing.T, descriptor string, options *Options) {
if err := AddEncryptionKey(fakeValidPolicyKey, descriptor, options); err != nil {
t.Error("AddEncryptionKey should not fail if key already exists")
}
- RemoveEncryptionKey(descriptor, options)
+ RemoveEncryptionKey(descriptor, options, false)
assertKeyStatus(t, descriptor, options, KeyAbsent)
// Adding a key with wrong length should fail
if err := AddEncryptionKey(fakeInvalidPolicyKey, descriptor, options); err == nil {
- RemoveEncryptionKey(descriptor, options)
+ RemoveEncryptionKey(descriptor, options, false)
t.Error("AddEncryptionKey should fail with wrong-length key")
}
assertKeyStatus(t, descriptor, options, KeyAbsent)
@@ -227,14 +227,14 @@ func TestV2PolicyKeyCannotBeRemovedByAnotherUser(t *testing.T) {
assertKeyStatus(t, fakeV2Descriptor, rootOptions, KeyPresentButOnlyOtherUsers)
// Key shouldn't be removable by another user, even root.
- err := RemoveEncryptionKey(fakeV2Descriptor, user2Options)
+ err := RemoveEncryptionKey(fakeV2Descriptor, user2Options, false)
if err != ErrKeyAddedByOtherUsers {
t.Error(err)
}
assertKeyStatus(t, fakeV2Descriptor, user1Options, KeyPresent)
assertKeyStatus(t, fakeV2Descriptor, user2Options, KeyPresentButOnlyOtherUsers)
assertKeyStatus(t, fakeV2Descriptor, rootOptions, KeyPresentButOnlyOtherUsers)
- err = RemoveEncryptionKey(fakeV2Descriptor, rootOptions)
+ err = RemoveEncryptionKey(fakeV2Descriptor, rootOptions, false)
if err != ErrKeyAddedByOtherUsers {
t.Error(err)
}
@@ -242,7 +242,7 @@ func TestV2PolicyKeyCannotBeRemovedByAnotherUser(t *testing.T) {
assertKeyStatus(t, fakeV2Descriptor, user2Options, KeyPresentButOnlyOtherUsers)
assertKeyStatus(t, fakeV2Descriptor, rootOptions, KeyPresentButOnlyOtherUsers)
- if err := RemoveEncryptionKey(fakeV2Descriptor, user1Options); err != nil {
+ if err := RemoveEncryptionKey(fakeV2Descriptor, user1Options, false); err != nil {
t.Error(err)
}
assertKeyStatus(t, fakeV2Descriptor, user1Options, KeyAbsent)
@@ -267,7 +267,7 @@ func TestV2PolicyKeyMultipleUsers(t *testing.T) {
assertKeyStatus(t, fakeV2Descriptor, rootOptions, KeyPresentButOnlyOtherUsers)
// Remove key as one user.
- err := RemoveEncryptionKey(fakeV2Descriptor, user1Options)
+ err := RemoveEncryptionKey(fakeV2Descriptor, user1Options, false)
if err != ErrKeyAddedByOtherUsers {
t.Error(err)
}
@@ -276,7 +276,7 @@ func TestV2PolicyKeyMultipleUsers(t *testing.T) {
assertKeyStatus(t, fakeV2Descriptor, rootOptions, KeyPresentButOnlyOtherUsers)
// Remove key as the other user.
- err = RemoveEncryptionKey(fakeV2Descriptor, user2Options)
+ err = RemoveEncryptionKey(fakeV2Descriptor, user2Options, false)
if err != nil {
t.Error(err)
}
@@ -296,7 +296,7 @@ func TestV2PolicyKeyWrongDescriptor(t *testing.T) {
for _, desc := range wrongV2Descriptors {
if err := AddEncryptionKey(fakeValidPolicyKey, desc, options); err == nil {
- RemoveEncryptionKey(desc, options)
+ RemoveEncryptionKey(desc, options, false)
t.Error("For v2 policy keys, AddEncryptionKey should fail if the descriptor is wrong")
}
}
@@ -308,10 +308,10 @@ func TestV2PolicyKeyBadMount(t *testing.T) {
User: testUser,
}
if err := AddEncryptionKey(fakeValidPolicyKey, fakeV2Descriptor, options); err == nil {
- RemoveEncryptionKey(fakeV2Descriptor, options)
+ RemoveEncryptionKey(fakeV2Descriptor, options, false)
t.Error("AddEncryptionKey should have failed with bad mount!")
}
- if err := RemoveEncryptionKey(fakeV2Descriptor, options); err == nil {
+ if err := RemoveEncryptionKey(fakeV2Descriptor, options, false); err == nil {
t.Error("RemoveEncryptionKey should have failed with bad mount!")
}
status, err := GetEncryptionKeyStatus(fakeV2Descriptor, options)
@@ -322,3 +322,29 @@ func TestV2PolicyKeyBadMount(t *testing.T) {
t.Error("GetEncryptionKeyStatus should have returned unknown status!")
}
}
+
+func TestV2PolicyKeyRemoveForAllUsers(t *testing.T) {
+ rootOptions, userOptions := getOptionsForFsKeyringUsers(t, 2)
+ user1Options := userOptions[0]
+ user2Options := userOptions[1]
+
+ // Add key as two non-root users.
+ if err := AddEncryptionKey(fakeValidPolicyKey, fakeV2Descriptor, user1Options); err != nil {
+ t.Error(err)
+ }
+ if err := AddEncryptionKey(fakeValidPolicyKey, fakeV2Descriptor, user2Options); err != nil {
+ t.Error(err)
+ }
+ assertKeyStatus(t, fakeV2Descriptor, user1Options, KeyPresent)
+ assertKeyStatus(t, fakeV2Descriptor, user2Options, KeyPresent)
+ assertKeyStatus(t, fakeV2Descriptor, rootOptions, KeyPresentButOnlyOtherUsers)
+
+ // Remove key for all users as root.
+ err := RemoveEncryptionKey(fakeV2Descriptor, rootOptions, true)
+ if err != nil {
+ t.Error(err)
+ }
+ assertKeyStatus(t, fakeV2Descriptor, user1Options, KeyAbsent)
+ assertKeyStatus(t, fakeV2Descriptor, user2Options, KeyAbsent)
+ assertKeyStatus(t, fakeV2Descriptor, rootOptions, KeyAbsent)
+}