aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/fusefrontend_reverse/rpath.go72
1 files changed, 40 insertions, 32 deletions
diff --git a/internal/fusefrontend_reverse/rpath.go b/internal/fusefrontend_reverse/rpath.go
index edffc1e..af49776 100644
--- a/internal/fusefrontend_reverse/rpath.go
+++ b/internal/fusefrontend_reverse/rpath.go
@@ -44,46 +44,54 @@ func (rfs *ReverseFS) abs(relPath string, err error) (string, error) {
return filepath.Join(rfs.args.Cipherdir, relPath), nil
}
+func (rfs *ReverseFS) rDecryptName(cName string, dirIV []byte, pDir string) (pName string, err error) {
+ nameType := nametransform.NameType(cName)
+ if nameType == nametransform.LongNameNone {
+ pName, err = rfs.nameTransform.DecryptName(cName, 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
+ }
+ // Stat attempts on the link target of encrypted symlinks.
+ // These are always valid base64 but the length is not a
+ // multiple of 16.
+ if err == syscall.EINVAL {
+ return "", syscall.ENOENT
+ }
+ return "", err
+ }
+ } else if nameType == nametransform.LongNameContent {
+ pName, err = rfs.findLongnameParent(pDir, dirIV, cName)
+ if err != nil {
+ return "", err
+ }
+ } else {
+ // It makes no sense to decrypt a ".name" file. This is a virtual file
+ // that has no represantation in the plaintext filesystem. ".name"
+ // files should have already been handled in virtualfile.go.
+ tlog.Warn.Printf("decryptPath: tried to decrypt %q!? Returning EINVAL.", cName)
+ return "", syscall.EINVAL
+ }
+ return pName, nil
+}
+
func (rfs *ReverseFS) decryptPath(relPath string) (string, error) {
if rfs.args.PlaintextNames || relPath == "" {
return relPath, nil
}
- var err error
- var transformedParts []string
parts := strings.Split(relPath, "/")
- for i, part := range parts {
+ var transformedParts []string
+ for i := range parts {
// Start at the top and recurse
currentCipherDir := filepath.Join(parts[:i]...)
- nameType := nametransform.NameType(part)
+ currentPlainDir := filepath.Join(transformedParts[:i]...)
dirIV := derivePathIV(currentCipherDir, ivPurposeDirIV)
- var transformedPart string
- 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
- }
- // Stat attempts on the link target of encrypted symlinks.
- // These are always valid base64 but the length is not a
- // multiple of 16.
- if err == syscall.EINVAL {
- return "", syscall.ENOENT
- }
- return "", err
- }
- } else if nameType == nametransform.LongNameContent {
- currentPlainDir := filepath.Join(transformedParts[:i]...)
- transformedPart, err = rfs.findLongnameParent(currentPlainDir, dirIV, part)
- if err != nil {
- return "", err
- }
- } else {
- // It makes no sense to decrypt a ".name" file
- tlog.Warn.Printf("decryptPath: tried to decrypt %q!? Returning EINVAL.", part)
- return "", syscall.EINVAL
+ transformedPart, err := rfs.rDecryptName(parts[i], dirIV, currentPlainDir)
+ if err != nil {
+ return "", err
}
transformedParts = append(transformedParts, transformedPart)
}