aboutsummaryrefslogtreecommitdiff
path: root/internal/nametransform/xattr.go
diff options
context:
space:
mode:
authorJakob Unterwurzacher2021-12-19 14:43:56 +0100
committerJakob Unterwurzacher2021-12-19 14:43:56 +0100
commit64be5de75f42e415198ff5e77de509680b69e0e1 (patch)
tree8897db6d0de0a4c11921bba72de621e30f0ce501 /internal/nametransform/xattr.go
parenteb42e541828336e9b19e1bc5e087a419835b0c85 (diff)
fusefrontend: allow slashes in xattr names
xattr names have fewer restrictions than file names, relax the validation. Fixes https://github.com/rfjakob/gocryptfs/issues/627
Diffstat (limited to 'internal/nametransform/xattr.go')
-rw-r--r--internal/nametransform/xattr.go47
1 files changed, 47 insertions, 0 deletions
diff --git a/internal/nametransform/xattr.go b/internal/nametransform/xattr.go
new file mode 100644
index 0000000..0aa0fd8
--- /dev/null
+++ b/internal/nametransform/xattr.go
@@ -0,0 +1,47 @@
+package nametransform
+
+import (
+ "fmt"
+ "strings"
+ "syscall"
+
+ "github.com/rfjakob/gocryptfs/v2/internal/tlog"
+)
+
+// xattr names are encrypted like file names, but with a fixed IV.
+// Padded with "_xx" for length 16.
+var xattrNameIV = []byte("xattr_name_iv_xx")
+
+func isValidXattrName(name string) error {
+ if name == "" {
+ return fmt.Errorf("empty input")
+ }
+ if strings.Contains(name, "\000") {
+ return fmt.Errorf("contains forbidden null byte")
+ }
+ return nil
+}
+
+// EncryptXattrName encrypts an extended attribute (xattr) name.
+// xattr names are encrypted like file names, but with a fixed IV, and fewer
+// naming restriction.
+func (n *NameTransform) EncryptXattrName(plainName string) (cipherName64 string, err error) {
+ if err := isValidXattrName(plainName); err != nil {
+ tlog.Warn.Printf("EncryptXattrName %q: invalid plainName: %v", plainName, err)
+ return "", syscall.EBADMSG
+ }
+ return n.encryptName(plainName, xattrNameIV), nil
+}
+
+// DecryptName calls decryptName to try and decrypt a base64-encoded encrypted
+// filename "cipherName", and failing that checks if it can be bypassed
+func (n *NameTransform) DecryptXattrName(cipherName string) (plainName string, err error) {
+ if plainName, err = n.decryptName(cipherName, xattrNameIV); err != nil {
+ return "", err
+ }
+ if err := isValidXattrName(plainName); err != nil {
+ tlog.Warn.Printf("DecryptXattrName %q: invalid name after decryption: %v", cipherName, err)
+ return "", syscall.EBADMSG
+ }
+ return plainName, err
+}