diff options
Diffstat (limited to 'internal/fusefrontend')
-rw-r--r-- | internal/fusefrontend/fs.go | 55 | ||||
-rw-r--r-- | internal/fusefrontend/fs_dir.go | 11 |
2 files changed, 57 insertions, 9 deletions
diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go index f11c05e..fb82c6b 100644 --- a/internal/fusefrontend/fs.go +++ b/internal/fusefrontend/fs.go @@ -5,7 +5,6 @@ package fusefrontend import ( "encoding/base64" "os" - "path/filepath" "sync" "syscall" "time" @@ -14,7 +13,6 @@ import ( "github.com/hanwen/go-fuse/fuse/nodefs" "github.com/hanwen/go-fuse/fuse/pathfs" - "github.com/rfjakob/gocryptfs/internal/configfile" "github.com/rfjakob/gocryptfs/internal/contentenc" "github.com/rfjakob/gocryptfs/internal/cryptocore" "github.com/rfjakob/gocryptfs/internal/nametransform" @@ -113,10 +111,9 @@ func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Conte if err != nil { return nil, fuse.ToStatus(err) } - cBaseName := filepath.Base(cPath) - if fs.args.LongNames && nametransform.IsLongName(cBaseName) == 1 { - // Create the ".name" file before creating the content - err = fs.nameTransform.WriteLongName(filepath.Dir(cPath), cBaseName, filepath.Base(path)) + // Create .name file to store the long file name if needed + if !fs.args.PlaintextNames { + err = fs.nameTransform.WriteLongName(cPath, path) if err != nil { return nil, fuse.ToStatus(err) } @@ -158,6 +155,13 @@ func (fs *FS) Mknod(path string, mode uint32, dev uint32, context *fuse.Context) if err != nil { return fuse.ToStatus(err) } + if !fs.args.PlaintextNames { + // Create .name file to store the long file name if needed + err = fs.nameTransform.WriteLongName(cPath, path) + if err != nil { + return fuse.ToStatus(err) + } + } return fs.FileSystem.Mknod(cPath, mode, dev, context) } @@ -223,7 +227,12 @@ func (fs *FS) Unlink(path string, context *fuse.Context) (code fuse.Status) { if err != nil { return fuse.ToStatus(err) } - return fuse.ToStatus(syscall.Unlink(cPath)) + err = syscall.Unlink(cPath) + // Delete .name file + if err == nil && !fs.args.PlaintextNames { + nametransform.DeleteLongName(cPath) + } + return fuse.ToStatus(err) } func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (code fuse.Status) { @@ -236,6 +245,7 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co return fuse.ToStatus(err) } // Old filesystem: symlinks are encrypted like paths (CBC) + // TODO drop compatibility and simplify code if !fs.args.DirIV { cTarget, err := fs.encryptPath(target) if err != nil { @@ -248,7 +258,13 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co // Since gocryptfs v0.5 symlinks are encrypted like file contents (GCM) cBinTarget := fs.contentEnc.EncryptBlock([]byte(target), 0, nil) cTarget := base64.URLEncoding.EncodeToString(cBinTarget) - + if !fs.args.PlaintextNames { + // Create .name file to store the long file name if needed + err = fs.nameTransform.WriteLongName(cPath, linkName) + if err != nil { + return fuse.ToStatus(err) + } + } err = os.Symlink(cTarget, cPath) toggledlog.Debug.Printf("Symlink: os.Symlink(%s, %s) = %v", cTarget, cPath, err) return fuse.ToStatus(err) @@ -270,6 +286,15 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod // That directory may still be in the DirIV cache, clear it. fs.nameTransform.DirIVCache.Clear() + if !fs.args.PlaintextNames { + // Create .name file to store the new long file name if needed + err = fs.nameTransform.WriteLongName(cNewPath, newPath) + if err != nil { + return fuse.ToStatus(err) + } + } + + // Actual rename err = os.Rename(cOldPath, cNewPath) if lerr, ok := err.(*os.LinkError); ok && lerr.Err == syscall.ENOTEMPTY { @@ -281,6 +306,13 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod err = os.Rename(cOldPath, cNewPath) } } + if err == nil { + // Rename succeeded - delete old long name file + nametransform.DeleteLongName(cOldPath) + } else { + // Rename has failed - undo long name file creation + nametransform.DeleteLongName(cNewPath) + } return fuse.ToStatus(err) } @@ -297,6 +329,13 @@ func (fs *FS) Link(oldPath string, newPath string, context *fuse.Context) (code if err != nil { return fuse.ToStatus(err) } + if !fs.args.PlaintextNames { + // Create .name file to store the long file name if needed + err = fs.nameTransform.WriteLongName(cNewPath, newPath) + if err != nil { + return fuse.ToStatus(err) + } + } return fuse.ToStatus(os.Link(cOldPath, cNewPath)) } diff --git a/internal/fusefrontend/fs_dir.go b/internal/fusefrontend/fs_dir.go index f1ade25..ebf7015 100644 --- a/internal/fusefrontend/fs_dir.go +++ b/internal/fusefrontend/fs_dir.go @@ -10,6 +10,7 @@ import ( "github.com/hanwen/go-fuse/fuse" + "github.com/rfjakob/gocryptfs/internal/configfile" "github.com/rfjakob/gocryptfs/internal/cryptocore" "github.com/rfjakob/gocryptfs/internal/nametransform" "github.com/rfjakob/gocryptfs/internal/toggledlog" @@ -30,7 +31,11 @@ func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fu // We need write and execute permissions to create gocryptfs.diriv origMode := mode mode = mode | 0300 - + // Create .name file to store the long file name if needed + err = fs.nameTransform.WriteLongName(encPath, relPath) + if err != nil { + return fuse.ToStatus(err) + } // The new directory may take the place of an older one that is still in the cache fs.nameTransform.DirIVCache.Clear() // Create directory @@ -151,6 +156,10 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) { if err != nil { toggledlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err) } + err = nametransform.DeleteLongName(encPath) + if err != nil { + toggledlog.Warn.Printf("Rmdir: Could not delete long name file: %v", err) + } // The now-deleted directory may have been in the DirIV cache. Clear it. fs.nameTransform.DirIVCache.Clear() return fuse.OK |