diff options
| author | Jakob Unterwurzacher | 2020-07-04 21:42:04 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2020-07-04 21:42:04 +0200 | 
| commit | 1f4e554168a25151e0c21375921376fd2b6c53de (patch) | |
| tree | 42440abca60085fd366c7e4a1e84d66f43695dd5 | |
| parent | d2139e18ef184afbd99759d07cc28c0642cdc4ae (diff) | |
v2api: merge openBackingDir into root_node.go
| -rw-r--r-- | internal/fusefrontend/node_openbackingdir.go | 68 | ||||
| -rw-r--r-- | internal/fusefrontend/root_node.go | 60 | 
2 files changed, 60 insertions, 68 deletions
| diff --git a/internal/fusefrontend/node_openbackingdir.go b/internal/fusefrontend/node_openbackingdir.go deleted file mode 100644 index 733c239..0000000 --- a/internal/fusefrontend/node_openbackingdir.go +++ /dev/null @@ -1,68 +0,0 @@ -package fusefrontend - -import ( -	"path/filepath" -	"strings" -	"syscall" - -	"github.com/rfjakob/gocryptfs/internal/nametransform" -	"github.com/rfjakob/gocryptfs/internal/syscallcompat" -) - -// openBackingDir opens the parent ciphertext directory of plaintext path -// "relPath". It returns the dirfd (opened with O_PATH) and the encrypted -// basename. -// -// The caller should then use Openat(dirfd, cName, ...) and friends. -// For convenience, if relPath is "", cName is going to be ".". -// -// openBackingDir is secure against symlink races by using Openat and -// ReadDirIVAt. -func (rn *RootNode) openBackingDir(relPath string) (dirfd int, cName string, err error) { -	dirRelPath := nametransform.Dir(relPath) -	// With PlaintextNames, we don't need to read DirIVs. Easy. -	if rn.args.PlaintextNames { -		dirfd, err = syscallcompat.OpenDirNofollow(rn.args.Cipherdir, dirRelPath) -		if err != nil { -			return -1, "", err -		} -		// If relPath is empty, cName is ".". -		cName = filepath.Base(relPath) -		return dirfd, cName, nil -	} -	// Open cipherdir (following symlinks) -	dirfd, err = syscall.Open(rn.args.Cipherdir, syscall.O_DIRECTORY|syscallcompat.O_PATH, 0) -	if err != nil { -		return -1, "", err -	} -	// If relPath is empty, cName is ".". -	if relPath == "" { -		return dirfd, ".", nil -	} -	// Walk the directory tree -	parts := strings.Split(relPath, "/") -	for i, name := range parts { -		iv, err := nametransform.ReadDirIVAt(dirfd) -		if err != nil { -			syscall.Close(dirfd) -			return -1, "", err -		} -		cName, err = rn.nameTransform.EncryptAndHashName(name, iv) -		if err != nil { -			syscall.Close(dirfd) -			return -1, "", err -		} -		// Last part? We are done. -		if i == len(parts)-1 { -			break -		} -		// Not the last part? Descend into next directory. -		dirfd2, err := syscallcompat.Openat(dirfd, cName, syscall.O_NOFOLLOW|syscall.O_DIRECTORY|syscallcompat.O_PATH, 0) -		syscall.Close(dirfd) -		if err != nil { -			return -1, "", err -		} -		dirfd = dirfd2 -	} -	return dirfd, cName, nil -} diff --git a/internal/fusefrontend/root_node.go b/internal/fusefrontend/root_node.go index 2689e05..cf23169 100644 --- a/internal/fusefrontend/root_node.go +++ b/internal/fusefrontend/root_node.go @@ -2,6 +2,8 @@ package fusefrontend  import (  	"os" +	"path/filepath" +	"strings"  	"sync"  	"sync/atomic"  	"syscall" @@ -185,3 +187,61 @@ func (rn *RootNode) openWriteOnlyFile(dirfd int, cName string, newFlags int) (rw  	}()  	return syscallcompat.Openat(dirfd, cName, newFlags, 0)  } + +// openBackingDir opens the parent ciphertext directory of plaintext path +// "relPath". It returns the dirfd (opened with O_PATH) and the encrypted +// basename. +// +// The caller should then use Openat(dirfd, cName, ...) and friends. +// For convenience, if relPath is "", cName is going to be ".". +// +// openBackingDir is secure against symlink races by using Openat and +// ReadDirIVAt. +func (rn *RootNode) openBackingDir(relPath string) (dirfd int, cName string, err error) { +	dirRelPath := nametransform.Dir(relPath) +	// With PlaintextNames, we don't need to read DirIVs. Easy. +	if rn.args.PlaintextNames { +		dirfd, err = syscallcompat.OpenDirNofollow(rn.args.Cipherdir, dirRelPath) +		if err != nil { +			return -1, "", err +		} +		// If relPath is empty, cName is ".". +		cName = filepath.Base(relPath) +		return dirfd, cName, nil +	} +	// Open cipherdir (following symlinks) +	dirfd, err = syscall.Open(rn.args.Cipherdir, syscall.O_DIRECTORY|syscallcompat.O_PATH, 0) +	if err != nil { +		return -1, "", err +	} +	// If relPath is empty, cName is ".". +	if relPath == "" { +		return dirfd, ".", nil +	} +	// Walk the directory tree +	parts := strings.Split(relPath, "/") +	for i, name := range parts { +		iv, err := nametransform.ReadDirIVAt(dirfd) +		if err != nil { +			syscall.Close(dirfd) +			return -1, "", err +		} +		cName, err = rn.nameTransform.EncryptAndHashName(name, iv) +		if err != nil { +			syscall.Close(dirfd) +			return -1, "", err +		} +		// Last part? We are done. +		if i == len(parts)-1 { +			break +		} +		// Not the last part? Descend into next directory. +		dirfd2, err := syscallcompat.Openat(dirfd, cName, syscall.O_NOFOLLOW|syscall.O_DIRECTORY|syscallcompat.O_PATH, 0) +		syscall.Close(dirfd) +		if err != nil { +			return -1, "", err +		} +		dirfd = dirfd2 +	} +	return dirfd, cName, nil +} | 
