From a41ec2028cf2ad24eafb531d661ea1fe0f751f39 Mon Sep 17 00:00:00 2001 From: Bolshevik Date: Mon, 7 May 2018 22:01:36 +0200 Subject: xattr: optimize storage, store as binary instead of bae64 Values a binary-safe, there is no need to base64-encode them. Old, base64-encoded values are supported transparently on reading. Writing xattr values now always writes them binary. --- tests/xattr/xattr_integration_test.go | 72 +++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'tests/xattr') diff --git a/tests/xattr/xattr_integration_test.go b/tests/xattr/xattr_integration_test.go index 50e7fb7..7d4c831 100644 --- a/tests/xattr/xattr_integration_test.go +++ b/tests/xattr/xattr_integration_test.go @@ -2,6 +2,7 @@ package defaults import ( "bytes" + "encoding/base64" "fmt" "io/ioutil" "os" @@ -11,6 +12,7 @@ import ( "github.com/pkg/xattr" + "github.com/rfjakob/gocryptfs/internal/cryptocore" "github.com/rfjakob/gocryptfs/tests/test_helpers" ) @@ -27,6 +29,14 @@ func TestMain(m *testing.M) { os.Exit(1) } test_helpers.ResetTmpDir(true) + // Write deterministic diriv so encrypted filenames are deterministic. + os.Remove(test_helpers.DefaultCipherDir + "/gocryptfs.diriv") + diriv := []byte("1234567890123456") + err := ioutil.WriteFile(test_helpers.DefaultCipherDir+"/gocryptfs.diriv", diriv, 0400) + if err != nil { + fmt.Println(err) + os.Exit(1) + } test_helpers.MountOrExit(test_helpers.DefaultCipherDir, test_helpers.DefaultPlainDir, "-zerokey") r := m.Run() test_helpers.UnmountPanic(test_helpers.DefaultPlainDir) @@ -161,3 +171,65 @@ func xattrSupported(path string) bool { } return true } + +func TestBase64XattrRead(t *testing.T) { + attrName := "user.test" + attrName2 := "user.test2" + encryptedAttrName := "user.gocryptfs.LB1kHHVrX1OEBdLmj3LTKw" + encryptedAttrName2 := "user.gocryptfs.d2yn5l7-0zUVqviADw-Oyw" + attrValue := fmt.Sprintf("test.%d", cryptocore.RandUint64()) + + fileName := "TestBase64Xattr" + encryptedFileName := "BaGak7jIoqAZQMlP0N5uCw" + + plainFn := test_helpers.DefaultPlainDir + "/" + fileName + encryptedFn := test_helpers.DefaultCipherDir + "/" + encryptedFileName + err := ioutil.WriteFile(plainFn, nil, 0700) + if err != nil { + t.Fatalf("creating empty file failed: %v", err) + } + if _, err2 := os.Stat(encryptedFn); os.IsNotExist(err2) { + t.Fatalf("encrypted file does not exist: %v", err2) + } + xattr.Set(plainFn, attrName, []byte(attrValue)) + + encryptedAttrValue, err1 := xattr.Get(encryptedFn, encryptedAttrName) + if err1 != nil { + t.Fatal(err1) + } + + xattr.Set(encryptedFn, encryptedAttrName2, encryptedAttrValue) + plainValue, err := xattr.Get(plainFn, attrName2) + + if err != nil || string(plainValue) != attrValue { + t.Fatalf("Attribute binary value decryption error %s != %s %v", string(plainValue), attrValue, err) + } + + encryptedAttrValue64 := base64.RawURLEncoding.EncodeToString(encryptedAttrValue) + xattr.Set(encryptedFn, encryptedAttrName2, []byte(encryptedAttrValue64)) + + plainValue, err = xattr.Get(plainFn, attrName2) + if err != nil || string(plainValue) != attrValue { + t.Fatalf("Attribute base64-encoded value decryption error %s != %s %v", string(plainValue), attrValue, err) + } + + // Remount with -wpanic=false so gocryptfs does not panics when it sees + // the broken xattrs + test_helpers.UnmountPanic(test_helpers.DefaultPlainDir) + test_helpers.MountOrExit(test_helpers.DefaultCipherDir, test_helpers.DefaultPlainDir, "-zerokey", "-wpanic=false") + + brokenVals := []string{ + "111", + "raw-test-long-block123", + "raw-test-long-block123-xyz11111111111111111111111111111111111111", + "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", + } + for _, val := range brokenVals { + xattr.Set(encryptedFn, encryptedAttrName2, []byte(val)) + plainValue, err = xattr.Get(plainFn, attrName2) + err2, _ := err.(*xattr.Error) + if err == nil || err2.Err != syscall.EIO { + t.Fatalf("Incorrect handling of broken data %s %v", string(plainValue), err) + } + } +} -- cgit v1.2.3