diff options
| author | Aleksey Vasenev | 2024-11-17 23:14:36 +0300 |
|---|---|---|
| committer | Jakob Unterwurzacher | 2025-11-22 21:24:20 +0100 |
| commit | ed1c5e4a9f5ce1921f3ec03b32e591ce828ec5b9 (patch) | |
| tree | a2e1f64e772e2af169df3ce4ac955fbf3ec8c83b /internal/fusefrontend_reverse/root_node.go | |
| parent | be34b9822bea4ce3b717c1b9bf5076f1118427ec (diff) | |
Xattrs support in reverse mode
Fixes https://github.com/rfjakob/gocryptfs/issues/827
Diffstat (limited to 'internal/fusefrontend_reverse/root_node.go')
| -rw-r--r-- | internal/fusefrontend_reverse/root_node.go | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/internal/fusefrontend_reverse/root_node.go b/internal/fusefrontend_reverse/root_node.go index 9c2de28..420ed22 100644 --- a/internal/fusefrontend_reverse/root_node.go +++ b/internal/fusefrontend_reverse/root_node.go @@ -182,3 +182,38 @@ func (rn *RootNode) uniqueStableAttr(mode uint32, ino uint64) fs.StableAttr { func (rn *RootNode) RootIno() uint64 { return rn.rootIno } + +// encryptXattrValue encrypts the xattr value "data". +// The data is encrypted like a file content block, but without binding it to +// a file location (block number and file id are set to zero). +// Special case: an empty value is encrypted to an empty value. +func (rn *RootNode) encryptXattrValue(data []byte, nonce []byte) (cData []byte) { + if len(data) == 0 { + return []byte{} + } + return rn.contentEnc.EncryptBlockNonce(data, 0, nil, nonce) +} + +// encryptXattrName transforms "user.foo" to "user.gocryptfs.a5sAd4XAa47f5as6dAf" +func (rn *RootNode) encryptXattrName(attr string) (string, error) { + // xattr names are encrypted like file names, but with a fixed IV. + cAttr, err := rn.nameTransform.EncryptXattrName(attr) + if err != nil { + return "", err + } + return xattrStorePrefix + cAttr, nil +} + +func (rn *RootNode) decryptXattrName(cAttr string) (attr string, err error) { + // Reject anything that does not start with "user.gocryptfs." + if !strings.HasPrefix(cAttr, xattrStorePrefix) { + return "", syscall.EINVAL + } + // Strip "user.gocryptfs." prefix + cAttr = cAttr[len(xattrStorePrefix):] + attr, err = rn.nameTransform.DecryptXattrName(cAttr) + if err != nil { + return "", err + } + return attr, nil +} |
