From 8136a700fa6c3efb7a469e45d846e9db4ec9b4e2 Mon Sep 17 00:00:00 2001 From: "Joe Richey joerichey@google.com" Date: Mon, 17 Jul 2017 13:16:03 -0700 Subject: filesystem: Distinguish support and setup for fs This commit splits two pieces of functionality. Detecting if the fscrypt metadata exists is now in CheckSetup() and checking if the filesystem supports encryption is now in CheckSupport(). --- filesystem/filesystem.go | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index a85d24a..b5fedf9 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -171,13 +171,15 @@ func (m *Mount) err(err error) error { return errors.Wrapf(err, "filesystem %s", m.Path) } -// CheckSetup returns an error if this filesystem does not support fscrypt or -// all the fscrypt metadata directories do not exist. Will log any unexpected -// errors or incorrect permissions. +// CheckSupport returns an error if this filesystem does not support filesystem +// encryption. +func (m *Mount) CheckSupport() error { + return m.err(metadata.CheckSupport(m.Path)) +} + +// CheckSetup returns an error if all the fscrypt metadata directories do not +// exist. Will log any unexpected errors or incorrect permissions. func (m *Mount) CheckSetup() error { - if err := metadata.CheckSupport(m.Path); err != nil { - return m.err(err) - } // Run all the checks so we will always get all the warnings baseGood := isDirCheckPerm(m.BaseDir(), basePermissions) policyGood := isDirCheckPerm(m.PolicyDir(), dirPermissions) @@ -212,13 +214,8 @@ func (m *Mount) makeDirectories() error { // the filesystem's feature flags. This operation is atomic, it either succeeds // or no files in the baseDir are created. func (m *Mount) Setup() error { - switch err := m.CheckSetup(); errors.Cause(err) { - case ErrNotSetup: - break - case nil: + if m.CheckSetup() == nil { return m.err(ErrAlreadySetup) - default: - return err } // We build the directories under a temp Mount and then move into place. temp, err := m.tempMount() -- cgit v1.2.3 From d0efe1f27b4229011292c076b923db985bcb6de4 Mon Sep 17 00:00:00 2001 From: "Joe Richey joerichey@google.com" Date: Mon, 17 Jul 2017 13:19:43 -0700 Subject: cmd/fscrypt: Check support before encrypting Almost all actions only need to to check that the fscrypt metadata exists (this is handled by the Mount methods). Only "fscrypt encrypt" need to be sure the filesystem also supports encryption, so this check is added. --- cmd/fscrypt/commands.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmd/fscrypt/commands.go b/cmd/fscrypt/commands.go index 2049b57..4f53fe2 100644 --- a/cmd/fscrypt/commands.go +++ b/cmd/fscrypt/commands.go @@ -198,11 +198,12 @@ func checkEncryptable(ctx *actions.Context, path string) error { return errors.Wrap(ErrNotEmptyDir, path) } - log.Printf("ensuring %s is not encrypted and filesystem is using fscrypt", path) + log.Printf("ensuring %s supports encryption and filesystem is using fscrypt", path) switch _, err := actions.GetPolicyFromPath(ctx, path); errors.Cause(err) { case metadata.ErrNotEncrypted: - // We are not encrypted - return nil + // We are not encrypted. Finally, we check that the filesystem + // supports encryption + return ctx.Mount.CheckSupport() case nil: // We are encrypted return errors.Wrap(metadata.ErrEncrypted, path) -- cgit v1.2.3 From 5d727874440e4e451b45baba4ad7e277b9399730 Mon Sep 17 00:00:00 2001 From: "Joe Richey joerichey@google.com" Date: Mon, 17 Jul 2017 13:21:11 -0700 Subject: cmd/fscrypt: Improve "fscrypt status" Now that we can distinguish between lacking encryption support and lacking fscrypt metadata, "fscrypt status" can now display this additional information. --- cmd/fscrypt/status.go | 53 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/cmd/fscrypt/status.go b/cmd/fscrypt/status.go index 9a8604d..c2adad7 100644 --- a/cmd/fscrypt/status.go +++ b/cmd/fscrypt/status.go @@ -42,20 +42,18 @@ func makeTableWriter(w io.Writer, header string) *tabwriter.Writer { return tableWriter } -// statusString is what will be printed in the STATUS column. An empty string -// means a status should not be printed. -func statusString(mount *filesystem.Mount) string { - switch err := mount.CheckSetup(); errors.Cause(err) { +// encryptionStatus will be printed in the ENCRYPTION column. An empty string +// indicates the filesystem should not be printed. +func encryptionStatus(err error) string { + switch errors.Cause(err) { case nil: - return "setup with fscrypt" - case filesystem.ErrNotSetup: - return "not setup with fscrypt" + return "supported" case metadata.ErrEncryptionNotEnabled: - return "encryption not enabled" + return "not enabled" case metadata.ErrEncryptionNotSupported: - return "" + return "not supported" default: - log.Printf("Unexpected Error: %v", err) + // Unknown error regarding support return "" } } @@ -74,17 +72,38 @@ func writeGlobalStatus(w io.Writer) error { return err } - t := makeTableWriter(w, "MOUNTPOINT\tDEVICE\tFILESYSTEM\tSTATUS") supportCount := 0 + useCount := 0 + + t := makeTableWriter(w, "MOUNTPOINT\tDEVICE\tFILESYSTEM\tENCRYPTION\tFSCRYPT") for _, mount := range mounts { - if status := statusString(mount); status != "" { - fmt.Fprintf(t, "%s\t%s\t%s\t%s\n", - mount.Path, mount.Device, mount.Filesystem, status) + // Only print mountpoints backed by devices or using fscrypt. + usingFscrypt := mount.CheckSetup() == nil + if !usingFscrypt && mount.Device == "" { + continue + } + + // Only print a mountpoint if we can determine its support. + supportErr := mount.CheckSupport() + supportString := encryptionStatus(supportErr) + if supportString == "" { + log.Print(supportErr) + continue + } + + fmt.Fprintf(t, "%s\t%s\t%s\t%s\t%s\n", mount.Path, mount.Device, mount.Filesystem, + supportString, yesNoString(usingFscrypt)) + + if supportErr == nil { supportCount++ } + if usingFscrypt { + useCount++ + } } - fmt.Fprintf(w, "%s on this system support encryption\n\n", pluralize(supportCount, "filesystem")) + fmt.Fprintf(w, "filesystems supporting encryption: %d\n", supportCount) + fmt.Fprintf(w, "filesystems with fscrypt metadata: %d\n\n", useCount) return t.Flush() } @@ -93,7 +112,7 @@ func writeOptions(w io.Writer, options []*actions.ProtectorOption) { t := makeTableWriter(w, "PROTECTOR\tLINKED\tDESCRIPTION") for _, option := range options { if option.LoadError != nil { - fmt.Fprintf(t, "%s\t\tERROR: %v\n", option.Descriptor(), option.LoadError) + fmt.Fprintf(t, "%s\t\t[%s]\n", option.Descriptor(), option.LoadError) continue } @@ -136,7 +155,7 @@ func writeFilesystemStatus(w io.Writer, ctx *actions.Context) error { for _, descriptor := range policyDescriptors { policy, err := actions.GetPolicy(ctx, descriptor) if err != nil { - fmt.Fprintf(t, "%s\t\tERROR: %v\n", descriptor, err) + fmt.Fprintf(t, "%s\t\t[%s]\n", descriptor, err) continue } -- cgit v1.2.3