From 2b12bba274ba75f76ac8c2af3790e4190b32396f Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Wed, 2 Jan 2019 21:45:40 +0100 Subject: fusefronted: make EncryptPath symlink-safe Finally allows us to delete EncryptPathDirIV. --- internal/fusefrontend/ctlsock_interface.go | 28 ++++++++++++++++++++++++++-- internal/fusefrontend/names.go | 21 --------------------- 2 files changed, 26 insertions(+), 23 deletions(-) (limited to 'internal/fusefrontend') diff --git a/internal/fusefrontend/ctlsock_interface.go b/internal/fusefrontend/ctlsock_interface.go index b29d150..15345f3 100644 --- a/internal/fusefrontend/ctlsock_interface.go +++ b/internal/fusefrontend/ctlsock_interface.go @@ -3,21 +3,45 @@ package fusefrontend import ( "fmt" "path" + "path/filepath" "strings" "syscall" "github.com/rfjakob/gocryptfs/internal/ctlsock" "github.com/rfjakob/gocryptfs/internal/nametransform" "github.com/rfjakob/gocryptfs/internal/syscallcompat" + "github.com/rfjakob/gocryptfs/internal/tlog" ) var _ ctlsock.Interface = &FS{} // Verify that interface is implemented. // EncryptPath implements ctlsock.Backend // -// TODO: this function is NOT symlink-safe. +// Symlink-safe through openBackingDir(). func (fs *FS) EncryptPath(plainPath string) (string, error) { - return fs.encryptPath(plainPath) + if plainPath == "" { + // Empty string gets encrypted as empty string + return plainPath, nil + } + if fs.args.PlaintextNames { + return plainPath, nil + } + // Encrypt path level by level using openBackingDir. Pretty inefficient, + // but does not matter here. + parts := strings.Split(plainPath, "/") + wd := "" + cPath := "" + for _, part := range parts { + wd = filepath.Join(wd, part) + dirfd, cName, err := fs.openBackingDir(wd) + if err != nil { + return "", err + } + syscall.Close(dirfd) + cPath = filepath.Join(cPath, cName) + } + tlog.Debug.Printf("encryptPath '%s' -> '%s'", plainPath, cPath) + return cPath, nil } // DecryptPath implements ctlsock.Backend diff --git a/internal/fusefrontend/names.go b/internal/fusefrontend/names.go index 36185e2..63f2e84 100644 --- a/internal/fusefrontend/names.go +++ b/internal/fusefrontend/names.go @@ -83,24 +83,3 @@ func (fs *FS) openBackingDir(relPath string) (dirfd int, cName string, err error } return dirfd, cName, nil } - -// encryptPath - encrypt relative plaintext path -// -// TODO: this function is NOT symlink-safe because EncryptPathDirIV is not -// symlink-safe. -func (fs *FS) encryptPath(plainPath string) (string, error) { - if plainPath != "" { // Empty path gets encrypted all the time without actual file accesses. - fs.AccessedSinceLastCheck = 1 - } else { // Empty string gets encrypted as empty string - return plainPath, nil - } - if fs.args.PlaintextNames { - return plainPath, nil - } - - fs.dirIVLock.RLock() - cPath, err := fs.nameTransform.EncryptPathDirIV(plainPath, fs.args.Cipherdir) - tlog.Debug.Printf("encryptPath '%s' -> '%s' (err: %v)", plainPath, cPath, err) - fs.dirIVLock.RUnlock() - return cPath, err -} -- cgit v1.2.3