From a6a7b424f8e8a0f8ddd1c94b7463250ef1337811 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Thu, 22 Sep 2016 23:28:11 +0200 Subject: reverse: resolve long names in Open and GetAttr The last patch added functionality for generating gocryptfs.longname.* files, this patch adds support for mapping them back to the full filenames. Note that resolving a long name needs a full readdir. A cache will be implemented later on to improve performance. --- internal/fusefrontend_reverse/reverse_longnames.go | 61 ++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 internal/fusefrontend_reverse/reverse_longnames.go (limited to 'internal/fusefrontend_reverse/reverse_longnames.go') diff --git a/internal/fusefrontend_reverse/reverse_longnames.go b/internal/fusefrontend_reverse/reverse_longnames.go new file mode 100644 index 0000000..46e1791 --- /dev/null +++ b/internal/fusefrontend_reverse/reverse_longnames.go @@ -0,0 +1,61 @@ +package fusefrontend_reverse + +import ( + "os" + "path/filepath" + "syscall" + + "github.com/hanwen/go-fuse/fuse" + "github.com/hanwen/go-fuse/fuse/nodefs" + + "github.com/rfjakob/gocryptfs/internal/nametransform" +) + +const ( + shortNameMax = 176 +) + +func (rfs *reverseFS) findLongnameParent(dir string, dirIV []byte, longname string) (string, error) { + absDir := filepath.Join(rfs.args.Cipherdir, dir) + dirfd, err := os.Open(absDir) + if err != nil { + return "", err + } + dirEntries, err := dirfd.Readdirnames(-1) + if err != nil { + return "", err + } + for _, e := range dirEntries { + if len(e) <= shortNameMax { + continue + } + cName := rfs.nameTransform.EncryptName(e, dirIV) + if len(cName) <= syscall.NAME_MAX { + panic("logic error or wrong shortNameMax constant?") + } + hName := nametransform.HashLongName(cName) + if longname == hName { + return e, nil + } + } + return "", syscall.ENOENT +} + +func (rfs *reverseFS) newNameFile(relPath string) (nodefs.File, fuse.Status) { + dotName := filepath.Base(relPath) // gocryptfs.longname.XYZ.name + longname := dotName[:len(dotName)-len(nametransform.LongNameSuffix)] // gocryptfs.longname.XYZ + + cDir := saneDir(relPath) + pDir, err := rfs.decryptPath(cDir) + if err != nil { + return nil, fuse.ToStatus(err) + } + dirIV := deriveDirIV(cDir) + e, err := rfs.findLongnameParent(pDir, dirIV, longname) + if err != nil { + return nil, fuse.ToStatus(err) + } + content := []byte(rfs.nameTransform.EncryptName(e, dirIV)) + parentFile := filepath.Join(rfs.args.Cipherdir, pDir) + return rfs.NewVirtualFile(content, parentFile) +} -- cgit v1.2.3