From 445b5019e3f5a74409ca66c166cc1c3ccdd3dce7 Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 5 Mar 2017 22:59:25 +0100 Subject: [PATCH] nametransform: fix Raw64 not affecting symlink targets The symlink functions incorrectly hardcoded the padded base64 variant. --- internal/fusefrontend/fs.go | 5 ++--- internal/fusefrontend_reverse/rfs.go | 3 +-- internal/nametransform/longnames.go | 2 +- internal/nametransform/names.go | 11 ++++++----- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go index 020032b..9ffcff1 100644 --- a/internal/fusefrontend/fs.go +++ b/internal/fusefrontend/fs.go @@ -4,7 +4,6 @@ package fusefrontend // FUSE operations on paths import ( - "encoding/base64" "os" "path/filepath" "sync" @@ -298,7 +297,7 @@ func (fs *FS) Readlink(path string, context *fuse.Context) (out string, status f return cTarget, fuse.OK } // Symlinks are encrypted like file contents (GCM) and base64-encoded - cBinTarget, err := base64.URLEncoding.DecodeString(cTarget) + cBinTarget, err := fs.nameTransform.B64.DecodeString(cTarget) if err != nil { tlog.Warn.Printf("Readlink: %v", err) return "", fuse.EIO @@ -362,7 +361,7 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co } // Symlinks are encrypted like file contents (GCM) and base64-encoded cBinTarget := fs.contentEnc.EncryptBlock([]byte(target), 0, nil) - cTarget := base64.URLEncoding.EncodeToString(cBinTarget) + cTarget := fs.nameTransform.B64.EncodeToString(cBinTarget) // Handle long file name cName := filepath.Base(cPath) if nametransform.IsLongContent(cName) { diff --git a/internal/fusefrontend_reverse/rfs.go b/internal/fusefrontend_reverse/rfs.go index fab3027..f9a2979 100644 --- a/internal/fusefrontend_reverse/rfs.go +++ b/internal/fusefrontend_reverse/rfs.go @@ -1,7 +1,6 @@ package fusefrontend_reverse import ( - "encoding/base64" "fmt" "log" "os" @@ -355,6 +354,6 @@ func (rfs *ReverseFS) Readlink(cipherPath string, context *fuse.Context) (string nonce := derivePathIV(cipherPath, ivPurposeSymlinkIV) // Symlinks are encrypted like file contents and base64-encoded cBinTarget := rfs.contentEnc.EncryptBlockNonce([]byte(plainTarget), 0, nil, nonce) - cTarget := base64.URLEncoding.EncodeToString(cBinTarget) + cTarget := rfs.nameTransform.B64.EncodeToString(cBinTarget) return cTarget, fuse.OK } diff --git a/internal/nametransform/longnames.go b/internal/nametransform/longnames.go index f9ba848..54095a4 100644 --- a/internal/nametransform/longnames.go +++ b/internal/nametransform/longnames.go @@ -25,7 +25,7 @@ const ( // "gocryptfs.longname.[sha256]" func (n *NameTransform) HashLongName(name string) string { hashBin := sha256.Sum256([]byte(name)) - hashBase64 := n.b64.EncodeToString(hashBin[:]) + hashBase64 := n.B64.EncodeToString(hashBin[:]) return longNamePrefix + hashBase64 } diff --git a/internal/nametransform/names.go b/internal/nametransform/names.go index 83724fb..71c8cd3 100644 --- a/internal/nametransform/names.go +++ b/internal/nametransform/names.go @@ -16,8 +16,9 @@ type NameTransform struct { emeCipher *eme.EMECipher longNames bool DirIVCache dirIVCache - // b64 = either base64.URLEncoding or base64.RawURLEncoding - b64 *base64.Encoding + // B64 = either base64.URLEncoding or base64.RawURLEncoding, depeding + // on the Raw64 feature flag + B64 *base64.Encoding } // New returns a new NameTransform instance. @@ -29,7 +30,7 @@ func New(e *eme.EMECipher, longNames bool, raw64 bool) *NameTransform { return &NameTransform{ emeCipher: e, longNames: longNames, - b64: b64, + B64: b64, } } @@ -38,7 +39,7 @@ func New(e *eme.EMECipher, longNames bool, raw64 bool) *NameTransform { // This function is exported because it allows for a very efficient readdir // implementation (read IV once, decrypt all names using this function). func (n *NameTransform) DecryptName(cipherName string, iv []byte) (string, error) { - bin, err := n.b64.DecodeString(cipherName) + bin, err := n.B64.DecodeString(cipherName) if err != nil { return "", err } @@ -69,6 +70,6 @@ func (n *NameTransform) EncryptName(plainName string, iv []byte) (cipherName64 s bin := []byte(plainName) bin = pad16(bin) bin = n.emeCipher.Encrypt(iv, bin) - cipherName64 = n.b64.EncodeToString(bin) + cipherName64 = n.B64.EncodeToString(bin) return cipherName64 }