fusefronted: add PlaintextNames special-cases for Create & Rename

gocryptfs.longname.XXX files were considered magic in PlaintextNames
mode, which was wrong.

Fix that and add tests.

Fixes https://github.com/rfjakob/gocryptfs/issues/174
This commit is contained in:
Jakob Unterwurzacher 2018-01-17 00:23:09 +01:00
parent 36ffd813cd
commit 8951eb2472
2 changed files with 58 additions and 35 deletions

View File

@ -195,7 +195,7 @@ func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Conte
cName := filepath.Base(cPath) cName := filepath.Base(cPath)
// Handle long file name // Handle long file name
if nametransform.IsLongContent(cName) { if !fs.args.PlaintextNames && nametransform.IsLongContent(cName) {
var dirfd *os.File var dirfd *os.File
dirfd, err = os.Open(filepath.Dir(cPath)) dirfd, err = os.Open(filepath.Dir(cPath))
if err != nil { if err != nil {
@ -466,7 +466,10 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod
// The Rename may cause a directory to take the place of another directory. // The Rename may cause a directory to take the place of another directory.
// That directory may still be in the DirIV cache, clear it. // That directory may still be in the DirIV cache, clear it.
fs.nameTransform.DirIVCache.Clear() fs.nameTransform.DirIVCache.Clear()
// Easy case.
if fs.args.PlaintextNames {
return fuse.ToStatus(syscall.Rename(cOldPath, cNewPath))
}
// Handle long source file name // Handle long source file name
var oldDirFd *os.File var oldDirFd *os.File
var finalOldDirFd int var finalOldDirFd int

View File

@ -800,38 +800,58 @@ func TestMkfifo(t *testing.T) {
} }
} }
// Make sure the Symlink call works with paths starting with "gocryptfs.longname." // TestMagicNames verifies that "magic" names are handled correctly
func TestSymlink(t *testing.T) { // https://github.com/rfjakob/gocryptfs/issues/174
path := test_helpers.DefaultPlainDir + "/gocryptfs.longname.XXX" func TestMagicNames(t *testing.T) {
err := syscall.Symlink("target", path) names := []string{"gocryptfs.longname.QhUr5d9FHerwEs--muUs6_80cy6JRp89c1otLwp92Cs", "gocryptfs.diriv"}
for _, n := range names {
t.Logf("Testing n=%q", n)
p := test_helpers.DefaultPlainDir + "/" + n
// Create file
err := ioutil.WriteFile(p, []byte("xxxxxxx"), 0200)
if err != nil {
t.Fatalf("creating file %q failed: %v", n, err)
}
// Rename magic to normal
err = os.Rename(p, test_helpers.DefaultPlainDir+"/x")
if err != nil {
t.Fatalf("rename 1 failed: %v", err)
}
// Rename normal to magic
err = os.Rename(test_helpers.DefaultPlainDir+"/x", p)
if err != nil {
t.Fatalf("rename 2 failed: %v", err)
}
// Unlink
err = syscall.Unlink(p)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = os.Remove(path) // Mkdir
err = os.Mkdir(p, 0700)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
} // Rmdir
err = syscall.Rmdir(p)
// Make sure the Link call works with paths starting with "gocryptfs.longname." if err != nil {
func TestLink(t *testing.T) { t.Fatal(err)
}
// Symlink
err = syscall.Symlink("xxxyyyyzzz", p)
if err != nil {
t.Fatal(err)
}
syscall.Unlink(p)
// Link
target := test_helpers.DefaultPlainDir + "/linktarget" target := test_helpers.DefaultPlainDir + "/linktarget"
f, err := os.Create(target) err = ioutil.WriteFile(target, []byte("yyyyy"), 0200)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
f.Close() err = syscall.Link(target, p)
path := test_helpers.DefaultPlainDir + "/gocryptfs.longname.XXX"
err = syscall.Link(target, path)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
err = os.Remove(target)
if err != nil {
t.Fatal(err)
}
err = os.Remove(path)
if err != nil {
t.Fatal(err)
} }
} }