From fbccb160438aba6f1e16b26a982122c726afee1a Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Fri, 20 Aug 2021 17:06:18 +0200 Subject: -deterministic-names: implement for reverse mode, too --- internal/fusefrontend_reverse/ctlsock_interface.go | 3 +-- internal/fusefrontend_reverse/node_dir_ops.go | 19 +++++++------------ internal/fusefrontend_reverse/node_helpers.go | 7 ++++++- internal/fusefrontend_reverse/rpath.go | 14 +++++++++++++- internal/fusefrontend_reverse/virtualnode.go | 8 +++++--- 5 files changed, 32 insertions(+), 19 deletions(-) (limited to 'internal/fusefrontend_reverse') diff --git a/internal/fusefrontend_reverse/ctlsock_interface.go b/internal/fusefrontend_reverse/ctlsock_interface.go index 2157044..1cfdf3e 100644 --- a/internal/fusefrontend_reverse/ctlsock_interface.go +++ b/internal/fusefrontend_reverse/ctlsock_interface.go @@ -7,7 +7,6 @@ import ( "golang.org/x/sys/unix" "github.com/rfjakob/gocryptfs/internal/ctlsocksrv" - "github.com/rfjakob/gocryptfs/internal/pathiv" ) // Verify that the interface is implemented. @@ -22,7 +21,7 @@ func (rn *RootNode) EncryptPath(plainPath string) (string, error) { cipherPath := "" parts := strings.Split(plainPath, "/") for _, part := range parts { - dirIV := pathiv.Derive(cipherPath, pathiv.PurposeDirIV) + dirIV := rn.deriveDirIV(cipherPath) encryptedPart, err := rn.nameTransform.EncryptName(part, dirIV) if err != nil { return "", err diff --git a/internal/fusefrontend_reverse/node_dir_ops.go b/internal/fusefrontend_reverse/node_dir_ops.go index 21b9775..2592ebc 100644 --- a/internal/fusefrontend_reverse/node_dir_ops.go +++ b/internal/fusefrontend_reverse/node_dir_ops.go @@ -13,7 +13,6 @@ import ( "github.com/rfjakob/gocryptfs/internal/configfile" "github.com/rfjakob/gocryptfs/internal/cryptocore" "github.com/rfjakob/gocryptfs/internal/nametransform" - "github.com/rfjakob/gocryptfs/internal/pathiv" "github.com/rfjakob/gocryptfs/internal/syscallcompat" "github.com/rfjakob/gocryptfs/internal/tlog" ) @@ -23,20 +22,16 @@ import ( // This function is symlink-safe through use of openBackingDir() and // ReadDirIVAt(). func (n *Node) Readdir(ctx context.Context) (stream fs.DirStream, errno syscall.Errno) { - // Virtual files: at least one gocryptfs.diriv file - virtualFiles := []fuse.DirEntry{ - {Mode: virtualFileMode, Name: nametransform.DirIVFilename}, - } rn := n.rootNode() + // Should we present a virtual gocryptfs.diriv? + var virtualFiles []fuse.DirEntry + if !rn.args.PlaintextNames && !rn.args.DeterministicNames { + virtualFiles = append(virtualFiles, fuse.DirEntry{Mode: virtualFileMode, Name: nametransform.DirIVFilename}) + } // This directory is a mountpoint. Present it as empty. if rn.args.OneFileSystem && n.isOtherFilesystem { - if rn.args.PlaintextNames { - return fs.NewListDirStream(nil), 0 - } else { - // An "empty" directory still has a gocryptfs.diriv file! - return fs.NewListDirStream(virtualFiles), 0 - } + return fs.NewListDirStream(virtualFiles), 0 } d, errno := n.prepareAtSyscall("") @@ -64,7 +59,7 @@ func (n *Node) Readdir(ctx context.Context) (stream fs.DirStream, errno syscall. return n.readdirPlaintextnames(entries) } - dirIV := pathiv.Derive(d.cPath, pathiv.PurposeDirIV) + dirIV := rn.deriveDirIV(d.cPath) // Encrypt names for i := range entries { var cName string diff --git a/internal/fusefrontend_reverse/node_helpers.go b/internal/fusefrontend_reverse/node_helpers.go index 7b286a0..b7dc086 100644 --- a/internal/fusefrontend_reverse/node_helpers.go +++ b/internal/fusefrontend_reverse/node_helpers.go @@ -2,6 +2,7 @@ package fusefrontend_reverse import ( "context" + "log" "path/filepath" "syscall" @@ -129,8 +130,8 @@ func (n *Node) lookupLongnameName(ctx context.Context, nameFile string, out *fus return } defer syscall.Close(fd) - diriv := pathiv.Derive(d.cPath, pathiv.PurposeDirIV) rn := n.rootNode() + diriv := rn.deriveDirIV(d.cPath) pName, cFullname, errno := rn.findLongnameParent(fd, diriv, nameFile) if errno != 0 { return @@ -160,6 +161,10 @@ func (n *Node) lookupLongnameName(ctx context.Context, nameFile string, out *fus // lookupDiriv returns a new Inode for a gocryptfs.diriv file inside `n`. func (n *Node) lookupDiriv(ctx context.Context, out *fuse.EntryOut) (ch *fs.Inode, errno syscall.Errno) { + if rn := n.rootNode(); rn.args.DeterministicNames { + log.Panic("BUG: lookupDiriv called but DeterministicNames is set") + } + d, errno := n.prepareAtSyscall("") if errno != 0 { return diff --git a/internal/fusefrontend_reverse/rpath.go b/internal/fusefrontend_reverse/rpath.go index 199473b..7ebedd7 100644 --- a/internal/fusefrontend_reverse/rpath.go +++ b/internal/fusefrontend_reverse/rpath.go @@ -2,6 +2,7 @@ package fusefrontend_reverse import ( "encoding/base64" + "log" "path/filepath" "strings" "syscall" @@ -72,7 +73,7 @@ func (rn *RootNode) decryptPath(cPath string) (string, error) { // Start at the top and recurse currentCipherDir := filepath.Join(parts[:i]...) currentPlainDir := filepath.Join(transformedParts[:i]...) - dirIV := pathiv.Derive(currentCipherDir, pathiv.PurposeDirIV) + dirIV := rn.deriveDirIV(currentCipherDir) transformedPart, err := rn.rDecryptName(parts[i], dirIV, currentPlainDir) if err != nil { return "", err @@ -83,6 +84,17 @@ func (rn *RootNode) decryptPath(cPath string) (string, error) { return pRelPath, nil } +// deriveDirIV wraps pathiv.Derive but takes DeterministicNames into account. +func (rn *RootNode) deriveDirIV(cPath string) []byte { + if rn.args.PlaintextNames { + log.Panic("BUG: deriveDirIV called but PlaintextNames is set") + } + if rn.args.DeterministicNames { + return make([]byte, nametransform.DirIVLen) + } + return pathiv.Derive(cPath, pathiv.PurposeDirIV) +} + // openBackingDir receives an already decrypted relative path // "pRelPath", opens the directory that contains the target file/dir // and returns the fd to the directory and the decrypted name of the diff --git a/internal/fusefrontend_reverse/virtualnode.go b/internal/fusefrontend_reverse/virtualnode.go index 2ee9548..328f021 100644 --- a/internal/fusefrontend_reverse/virtualnode.go +++ b/internal/fusefrontend_reverse/virtualnode.go @@ -43,9 +43,11 @@ func (n *Node) lookupFileType(cName string) fileType { rn := n.rootNode() // In -plaintextname mode, neither diriv nor longname files exist. if !rn.args.PlaintextNames { - // Is it a gocryptfs.diriv file? - if cName == nametransform.DirIVFilename { - return typeDiriv + if !rn.args.DeterministicNames { + // Is it a gocryptfs.diriv file? + if cName == nametransform.DirIVFilename { + return typeDiriv + } } // Is it a gocryptfs.longname.*.name file? if t := nametransform.NameType(cName); t == nametransform.LongNameFilename { -- cgit v1.2.3