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/rpath.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/rpath.go')
-rw-r--r-- | internal/fusefrontend_reverse/rpath.go | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/internal/fusefrontend_reverse/rpath.go b/internal/fusefrontend_reverse/rpath.go index a15b31a..19539bb 100644 --- a/internal/fusefrontend_reverse/rpath.go +++ b/internal/fusefrontend_reverse/rpath.go @@ -5,8 +5,19 @@ import ( "path/filepath" "strings" "syscall" + + "github.com/rfjakob/gocryptfs/internal/nametransform" ) +// saneDir is like filepath.Dir but returns "" instead of "." +func saneDir(path string) string { + d := filepath.Dir(path) + if d == "." { + return "" + } + return d +} + func (rfs *reverseFS) abs(relPath string, err error) (string, error) { if err != nil { return "", err @@ -22,17 +33,29 @@ func (rfs *reverseFS) decryptPath(relPath string) (string, error) { var transformedParts []string parts := strings.Split(relPath, "/") for i, part := range parts { + // Start at the top and recurse + currentDir := filepath.Join(parts[:i]...) + nameType := nametransform.NameType(part) + dirIV := deriveDirIV(currentDir) var transformedPart string - dirIV := deriveDirIV(filepath.Join(parts[:i]...)) - transformedPart, err = rfs.nameTransform.DecryptName(part, dirIV) - if err != nil { - // We get lots of decrypt requests for names like ".Trash" that - // are invalid base64. Convert them to ENOENT so the correct - // error gets returned to the user. - if _, ok := err.(base64.CorruptInputError); ok { - return "", syscall.ENOENT + if nameType == nametransform.LongNameNone { + transformedPart, err = rfs.nameTransform.DecryptName(part, dirIV) + if err != nil { + // We get lots of decrypt requests for names like ".Trash" that + // are invalid base64. Convert them to ENOENT so the correct + // error gets returned to the user. + if _, ok := err.(base64.CorruptInputError); ok { + return "", syscall.ENOENT + } + return "", err + } + } else if nameType == nametransform.LongNameContent { + transformedPart, err = rfs.findLongnameParent(currentDir, dirIV, part) + if err != nil { + return "", err } - return "", err + } else { + panic("longname bug, .name files should have been handled earlier") } transformedParts = append(transformedParts, transformedPart) } |