aboutsummaryrefslogtreecommitdiff
path: root/cmd/fscrypt/status.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/fscrypt/status.go')
-rw-r--r--cmd/fscrypt/status.go72
1 files changed, 57 insertions, 15 deletions
diff --git a/cmd/fscrypt/status.go b/cmd/fscrypt/status.go
index 1465a4e..bc8f1ee 100644
--- a/cmd/fscrypt/status.go
+++ b/cmd/fscrypt/status.go
@@ -27,11 +27,9 @@ import (
"strings"
"text/tabwriter"
- "github.com/pkg/errors"
-
"github.com/google/fscrypt/actions"
"github.com/google/fscrypt/filesystem"
- "github.com/google/fscrypt/metadata"
+ "github.com/google/fscrypt/keyring"
)
// Creates a writer which correctly aligns tabs with the specified header.
@@ -45,12 +43,13 @@ func makeTableWriter(w io.Writer, header string) *tabwriter.Writer {
// 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:
+ if err == nil {
return "supported"
- case metadata.ErrEncryptionNotEnabled:
+ }
+ switch err.(type) {
+ case *filesystem.ErrEncryptionNotEnabled:
return "not enabled"
- case metadata.ErrEncryptionNotSupported:
+ case *filesystem.ErrEncryptionNotSupported:
return "not supported"
default:
// Unknown error regarding support
@@ -65,7 +64,31 @@ func yesNoString(b bool) string {
return "No"
}
-// writeGlobalStatus prints all the filesystem that use (or could use) fscrypt.
+func policyUnlockedStatus(policy *actions.Policy, path string) string {
+ status := policy.GetProvisioningStatus()
+
+ // Due to a limitation in the old kernel API for fscrypt, for v1
+ // policies using the user keyring that are incompletely locked or are
+ // unlocked by another user, we'll get KeyAbsent. If we have a
+ // directory path, use a heuristic to try to detect these cases.
+ if status == keyring.KeyAbsent && policy.NeedsUserKeyring() &&
+ path != "" && isDirUnlockedHeuristic(path) {
+ return "Partially (incompletely locked, or unlocked by another user)"
+ }
+
+ switch status {
+ case keyring.KeyPresent, keyring.KeyPresentButOnlyOtherUsers:
+ 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()
if err != nil {
@@ -78,7 +101,7 @@ func writeGlobalStatus(w io.Writer) error {
t := makeTableWriter(w, "MOUNTPOINT\tDEVICE\tFILESYSTEM\tENCRYPTION\tFSCRYPT")
for _, mount := range mounts {
// Only print mountpoints backed by devices or using fscrypt.
- usingFscrypt := mount.CheckSetup() == nil
+ usingFscrypt := mount.CheckSetup(nil) == nil
if !usingFscrypt && mount.Device == "" {
continue
}
@@ -91,7 +114,10 @@ func writeGlobalStatus(w io.Writer) error {
continue
}
- fmt.Fprintf(t, "%s\t%s\t%s\t%s\t%s\n", mount.Path, mount.Device, mount.Filesystem,
+ fmt.Fprintf(t, "%s\t%s\t%s\t%s\t%s\n",
+ filesystem.EscapeString(mount.Path),
+ filesystem.EscapeString(mount.Device),
+ filesystem.EscapeString(mount.FilesystemType),
supportString, yesNoString(usingFscrypt))
if supportErr == nil {
@@ -134,13 +160,27 @@ func writeFilesystemStatus(w io.Writer, ctx *actions.Context) error {
return err
}
- policyDescriptors, err := ctx.Mount.ListPolicies()
+ policyDescriptors, err := ctx.Mount.ListPolicies(ctx.TrustedUser)
if err != nil {
return err
}
- fmt.Fprintf(w, "%s filesystem %q has %s and %s\n\n", ctx.Mount.Filesystem, ctx.Mount.Path,
- pluralize(len(options), "protector"), pluralize(len(policyDescriptors), "policy"))
+ filterDescription := ""
+ if ctx.TrustedUser != nil {
+ filterDescription = fmt.Sprintf(" (only including ones owned by %s or root)", ctx.TrustedUser.Username)
+ }
+ fmt.Fprintf(w, "%s filesystem %q has %s and %s%s.\n", ctx.Mount.FilesystemType,
+ ctx.Mount.Path, pluralize(len(options), "protector"),
+ pluralize(len(policyDescriptors), "policy"), filterDescription)
+ if setupMode, user, err := ctx.Mount.GetSetupMode(); err == nil {
+ switch setupMode {
+ case filesystem.WorldWritable:
+ fmt.Fprintf(w, "All users can create fscrypt metadata on this filesystem.\n")
+ case filesystem.SingleUserWritable:
+ fmt.Fprintf(w, "Only %s can create fscrypt metadata on this filesystem.\n", user.Username)
+ }
+ }
+ fmt.Fprintf(w, "\n")
if len(options) > 0 {
writeOptions(w, options)
@@ -159,7 +199,8 @@ 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()
@@ -178,7 +219,8 @@ func writePathStatus(w io.Writer, path string) error {
fmt.Fprintf(w, "%q is encrypted with fscrypt.\n", path)
fmt.Fprintln(w)
fmt.Fprintf(w, "Policy: %s\n", policy.Descriptor())
- fmt.Fprintf(w, "Unlocked: %s\n", yesNoString(policy.IsProvisioned()))
+ fmt.Fprintf(w, "Options: %s\n", policy.Options())
+ fmt.Fprintf(w, "Unlocked: %s\n", policyUnlockedStatus(policy, path))
fmt.Fprintln(w)
options := policy.ProtectorOptions()