summaryrefslogtreecommitdiff
path: root/internal/fusefrontend_reverse/rfs.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2016-09-02 23:45:52 +0200
committerJakob Unterwurzacher2016-09-25 16:43:17 +0200
commit10f38e88707f3a1f1ad69769219839a30a80c165 (patch)
treee8da4da52800f5f17c06e5c9cee7d2fab3c654d6 /internal/fusefrontend_reverse/rfs.go
parentac1221395e7475fa16f8f21f5badd93e300cb9d0 (diff)
reverse: generate file header for Read()
Also create virtual gocryptfs.diriv entries (no content yet).
Diffstat (limited to 'internal/fusefrontend_reverse/rfs.go')
-rw-r--r--internal/fusefrontend_reverse/rfs.go54
1 files changed, 52 insertions, 2 deletions
diff --git a/internal/fusefrontend_reverse/rfs.go b/internal/fusefrontend_reverse/rfs.go
index 68a5ac8..3243dfd 100644
--- a/internal/fusefrontend_reverse/rfs.go
+++ b/internal/fusefrontend_reverse/rfs.go
@@ -1,7 +1,10 @@
package fusefrontend_reverse
import (
+ "fmt"
"os"
+ "path"
+ "strings"
"syscall"
"github.com/hanwen/go-fuse/fuse"
@@ -14,6 +17,10 @@ import (
"github.com/rfjakob/gocryptfs/internal/nametransform"
)
+const (
+ DirIVMode = syscall.S_IFREG | 0400
+)
+
type reverseFS struct {
// Embed pathfs.defaultFileSystem for a ENOSYS implementation of all methods
pathfs.FileSystem
@@ -44,6 +51,46 @@ func NewFS(args fusefrontend.Args) *reverseFS {
}
func (rfs *reverseFS) GetAttr(relPath string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
+ // Handle gocryptfs.diriv
+ if relPath == nametransform.DirIVFilename ||
+ strings.HasSuffix(relPath, nametransform.DirIVFilename) {
+
+ fmt.Printf("Handling gocryptfs.diriv\n")
+
+ cDir := path.Dir(relPath)
+ if cDir == "." {
+ cDir = ""
+ }
+ dir, err := rfs.decryptPath(cDir)
+ if err != nil {
+ fmt.Printf("decrypt err %q\n", cDir)
+ return nil, fuse.ToStatus(err)
+ }
+ // Does the parent dir exist?
+ a, status := rfs.loopbackfs.GetAttr(dir, context)
+ if !status.Ok() {
+ fmt.Printf("missing parent\n")
+ return nil, status
+ }
+ // Is it a dir at all?
+ if !a.IsDir() {
+ fmt.Printf("not isdir\n")
+ return nil, fuse.ENOTDIR
+ }
+ // Does the user have execute permissions?
+ if a.Mode&syscall.S_IXUSR == 0 {
+ fmt.Printf("not exec")
+ return nil, fuse.EPERM
+ }
+ // All good. Let's fake the file.
+ // We use the inode number of the parent dir (can this cause problems?).
+ a.Mode = DirIVMode
+ a.Size = nametransform.DirIVLen
+ a.Nlink = 1
+
+ return a, fuse.OK
+ }
+
if rfs.isFiltered(relPath) {
return nil, fuse.EPERM
}
@@ -52,8 +99,8 @@ func (rfs *reverseFS) GetAttr(relPath string, context *fuse.Context) (*fuse.Attr
return nil, fuse.ToStatus(err)
}
a, status := rfs.loopbackfs.GetAttr(relPath, context)
- if a == nil {
- return a, status
+ if !status.Ok() {
+ return nil, status
}
// Calculate encrypted file size
if a.IsRegular() {
@@ -105,5 +152,8 @@ func (rfs *reverseFS) OpenDir(relPath string, context *fuse.Context) ([]fuse.Dir
return nil, fuse.ToStatus(err)
}
}
+ // Add virtual gocryptfs.diriv
+ entries = append(entries, fuse.DirEntry{syscall.S_IFREG | 0400, nametransform.DirIVFilename})
+
return entries, fuse.OK
}