From 6ffc9457945a9484d2757cc4b01de35426502d0a Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 15 Dec 2019 19:31:39 -0800 Subject: keyring: support filesystem keyring with v1 encryption policies Linux v5.4 and later allows fscrypt keys to be added/removed directly to/from the filesystem via the new ioctls FS_IOC_ADD_ENCRYPTION_KEY and FS_IOC_REMOVE_ENCRYPTION_KEY. Among other benefits, these fix the key visibility problems that many users have been running into, where system services and containers can't access encrypted files. Allow the user to opt-in to using these new ioctls for their existing encrypted directories by setting in their /etc/fscrypt.conf: "use_fs_keyring_for_v1_policies": true Note that it can't really be on by default, since for v1 policies the ioctls require root, whereas user keyrings don't. I.e., setting this to true means that users will need to use 'sudo fscrypt unlock', not 'fscrypt unlock'. v2 policies won't have this restriction. --- cmd/fscrypt/status.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/fscrypt/status.go b/cmd/fscrypt/status.go index 375899b..3f7f577 100644 --- a/cmd/fscrypt/status.go +++ b/cmd/fscrypt/status.go @@ -31,6 +31,7 @@ import ( "github.com/google/fscrypt/actions" "github.com/google/fscrypt/filesystem" + "github.com/google/fscrypt/keyring" "github.com/google/fscrypt/metadata" ) @@ -65,6 +66,19 @@ func yesNoString(b bool) string { return "No" } +func policyUnlockedStatus(policy *actions.Policy) string { + switch policy.GetProvisioningStatus() { + case keyring.KeyPresent: + return "Yes" + case keyring.KeyAbsent: + return "No" + case keyring.KeyAbsentButFilesBusy: + return "Partially (incompletely locked)" + default: + return "Unknown" + } +} + // writeGlobalStatus prints all the filesystems that use (or could use) fscrypt. func writeGlobalStatus(w io.Writer) error { mounts, err := filesystem.AllFilesystems() @@ -160,7 +174,7 @@ func writeFilesystemStatus(w io.Writer, ctx *actions.Context) error { continue } - fmt.Fprintf(t, "%s\t%s\t%s\n", descriptor, yesNoString(policy.IsProvisioned()), + fmt.Fprintf(t, "%s\t%s\t%s\n", descriptor, policyUnlockedStatus(policy), strings.Join(policy.ProtectorDescriptors(), ", ")) } return t.Flush() @@ -180,7 +194,7 @@ func writePathStatus(w io.Writer, path string) error { fmt.Fprintln(w) fmt.Fprintf(w, "Policy: %s\n", policy.Descriptor()) fmt.Fprintf(w, "Options: %s\n", policy.Options()) - fmt.Fprintf(w, "Unlocked: %s\n", yesNoString(policy.IsProvisioned())) + fmt.Fprintf(w, "Unlocked: %s\n", policyUnlockedStatus(policy)) fmt.Fprintln(w) options := policy.ProtectorOptions() -- cgit v1.2.3