From 18b3bdb1584fd8e3dde89a95c0dfff910dd95ae1 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sat, 1 Aug 2020 20:48:32 +0200 Subject: v2api/reverse: start fusefrontend_reverse v2 API implementation --- internal/fusefrontend_reverse/excluder.go | 61 ++++++++++++++++++++++++++++++ internal/fusefrontend_reverse/node.go | 11 ++++++ internal/fusefrontend_reverse/root_node.go | 39 +++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 internal/fusefrontend_reverse/excluder.go create mode 100644 internal/fusefrontend_reverse/node.go create mode 100644 internal/fusefrontend_reverse/root_node.go diff --git a/internal/fusefrontend_reverse/excluder.go b/internal/fusefrontend_reverse/excluder.go new file mode 100644 index 0000000..337c3d2 --- /dev/null +++ b/internal/fusefrontend_reverse/excluder.go @@ -0,0 +1,61 @@ +package fusefrontend_reverse + +import ( + "io/ioutil" + "os" + "strings" + + "github.com/rfjakob/gocryptfs/internal/exitcodes" + "github.com/rfjakob/gocryptfs/internal/fusefrontend" + "github.com/rfjakob/gocryptfs/internal/tlog" + + "github.com/sabhiram/go-gitignore" +) + +// prepareExcluder creates an object to check if paths are excluded +// based on the patterns specified in the command line. +func prepareExcluder(args fusefrontend.Args) *ignore.GitIgnore { + if len(args.Exclude) > 0 || len(args.ExcludeWildcard) > 0 || len(args.ExcludeFrom) > 0 { + excluder, err := ignore.CompileIgnoreLines(getExclusionPatterns(args)...) + if err != nil { + tlog.Fatal.Printf("Error compiling exclusion rules: %q", err) + os.Exit(exitcodes.ExcludeError) + } + return excluder + } + return nil +} + +// getExclusionPatters prepares a list of patterns to be excluded. +// Patterns passed in the -exclude command line option are prefixed +// with a leading '/' to preserve backwards compatibility (before +// wildcard matching was implemented, exclusions always were matched +// against the full path). +func getExclusionPatterns(args fusefrontend.Args) []string { + patterns := make([]string, len(args.Exclude)+len(args.ExcludeWildcard)) + // add -exclude + for i, p := range args.Exclude { + patterns[i] = "/" + p + } + // add -exclude-wildcard + copy(patterns[len(args.Exclude):], args.ExcludeWildcard) + // add -exclude-from + for _, file := range args.ExcludeFrom { + lines, err := getLines(file) + if err != nil { + tlog.Fatal.Printf("Error reading exclusion patterns: %q", err) + os.Exit(exitcodes.ExcludeError) + } + patterns = append(patterns, lines...) + } + return patterns +} + +// getLines reads a file and splits it into lines +func getLines(file string) ([]string, error) { + buffer, err := ioutil.ReadFile(file) + if err != nil { + return nil, err + } + return strings.Split(string(buffer), "\n"), nil +} diff --git a/internal/fusefrontend_reverse/node.go b/internal/fusefrontend_reverse/node.go new file mode 100644 index 0000000..6a1294a --- /dev/null +++ b/internal/fusefrontend_reverse/node.go @@ -0,0 +1,11 @@ +package fusefrontend_reverse + +import ( + "github.com/hanwen/go-fuse/v2/fs" +) + +// Node is a file or directory in the filesystem tree +// in a `gocryptfs -reverse` mount. +type Node struct { + fs.Inode +} diff --git a/internal/fusefrontend_reverse/root_node.go b/internal/fusefrontend_reverse/root_node.go new file mode 100644 index 0000000..726380f --- /dev/null +++ b/internal/fusefrontend_reverse/root_node.go @@ -0,0 +1,39 @@ +package fusefrontend_reverse + +import ( + "github.com/rfjakob/gocryptfs/internal/contentenc" + "github.com/rfjakob/gocryptfs/internal/fusefrontend" + "github.com/rfjakob/gocryptfs/internal/inomap" + "github.com/rfjakob/gocryptfs/internal/nametransform" + + "github.com/sabhiram/go-gitignore" +) + +// RootNode is the root directory in a `gocryptfs -reverse` mount +type RootNode struct { + Node + // Stores configuration arguments + args fusefrontend.Args + // Filename encryption helper + nameTransform nametransform.NameTransformer + // Content encryption helper + contentEnc *contentenc.ContentEnc + // Tests whether a path is excluded (hiden) from the user. Used by -exclude. + excluder ignore.IgnoreParser + // inoMap translates inode numbers from different devices to unique inode + // numbers. + inoMap *inomap.InoMap +} + +// NewRootNode returns an encrypted FUSE overlay filesystem. +// In this case (reverse mode) the backing directory is plain-text and +// ReverseFS provides an encrypted view. +func NewRootNode(args fusefrontend.Args, c *contentenc.ContentEnc, n nametransform.NameTransformer) *RootNode { + return &RootNode{ + args: args, + nameTransform: n, + contentEnc: c, + inoMap: inomap.New(), + excluder: prepareExcluder(args), + } +} -- cgit v1.2.3