diff options
author | Jakob Unterwurzacher | 2016-09-22 23:28:11 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2016-09-25 16:43:17 +0200 |
commit | a6a7b424f8e8a0f8ddd1c94b7463250ef1337811 (patch) | |
tree | 2281d7062d893d70209ecb7a82589e49decac164 /internal/fusefrontend_reverse/reverse_longnames.go | |
parent | 35bcc2dca2dc928e3b7c31e34d785b7a42c06722 (diff) |
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.
Diffstat (limited to 'internal/fusefrontend_reverse/reverse_longnames.go')
-rw-r--r-- | internal/fusefrontend_reverse/reverse_longnames.go | 61 |
1 files changed, 61 insertions, 0 deletions
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) +} |