diff options
Diffstat (limited to 'internal/nametransform')
-rw-r--r-- | internal/nametransform/longnames.go | 39 | ||||
-rw-r--r-- | internal/nametransform/name_api.go | 2 | ||||
-rw-r--r-- | internal/nametransform/names_diriv.go | 17 |
3 files changed, 43 insertions, 15 deletions
diff --git a/internal/nametransform/longnames.go b/internal/nametransform/longnames.go index e442b64..dad269b 100644 --- a/internal/nametransform/longnames.go +++ b/internal/nametransform/longnames.go @@ -1,12 +1,12 @@ package nametransform import ( - "syscall" - "path/filepath" - "io/ioutil" "crypto/sha256" "encoding/base64" + "io/ioutil" + "path/filepath" "strings" + "syscall" "github.com/rfjakob/gocryptfs/internal/toggledlog" ) @@ -39,28 +39,47 @@ func IsLongName(cName string) int { return 1 } -// ReadLongName - read "path".name +// ReadLongName - read path.name func ReadLongName(path string) (string, error) { - content, err := ioutil.ReadFile(path+longNameSuffix) + content, err := ioutil.ReadFile(path + longNameSuffix) if err != nil { toggledlog.Warn.Printf("ReadLongName: %v", err) } return string(content), err } -// WriteLongName - -func (n *NameTransform) WriteLongName(cDir string, hashedName string, plainName string) (err error) { - if len(plainName) > syscall.NAME_MAX { - return syscall.ENAMETOOLONG +// DeleteLongName - if cPath ends in "gocryptfs.longname.[sha256]", +// delete the "gocryptfs.longname.[sha256].name" file +func DeleteLongName(cPath string) error { + if IsLongName(filepath.Base(cPath)) == 1 { + err := syscall.Unlink(cPath + longNameSuffix) + if err != nil { + toggledlog.Warn.Printf("DeleteLongName: %v", err) + } + return err } + return nil +} +// WriteLongName - if cPath ends in "gocryptfs.longname.[sha256]", write the +// "gocryptfs.longname.[sha256].name" file +func (n *NameTransform) WriteLongName(cPath string, plainPath string) (err error) { + cHashedName := filepath.Base(cPath) + if IsLongName(cHashedName) != 1 { + // This is not a hashed file name, nothing to do + return nil + } + // Encrypt (but do not hash) the plaintext name + cDir := filepath.Dir(cPath) dirIV, err := ReadDirIV(cDir) if err != nil { toggledlog.Warn.Printf("WriteLongName: %v", err) return err } + plainName := filepath.Base(plainPath) cName := n.EncryptName(plainName, dirIV) - err = ioutil.WriteFile(filepath.Join(cDir, hashedName + longNameSuffix), []byte(cName), 0600) + // Write the encrypted name into gocryptfs.longname.[sha256].name + err = ioutil.WriteFile(filepath.Join(cDir, cHashedName+longNameSuffix), []byte(cName), 0600) if err != nil { toggledlog.Warn.Printf("WriteLongName: %v", err) } diff --git a/internal/nametransform/name_api.go b/internal/nametransform/name_api.go index 391a5ce..7ac7d26 100644 --- a/internal/nametransform/name_api.go +++ b/internal/nametransform/name_api.go @@ -12,7 +12,7 @@ type NameTransform struct { func New(c *cryptocore.CryptoCore, useEME bool, longNames bool) *NameTransform { return &NameTransform{ cryptoCore: c, - longNames: longNames, + longNames: longNames, useEME: useEME, } } diff --git a/internal/nametransform/names_diriv.go b/internal/nametransform/names_diriv.go index d45f91b..9336f5d 100644 --- a/internal/nametransform/names_diriv.go +++ b/internal/nametransform/names_diriv.go @@ -1,12 +1,12 @@ package nametransform import ( - "syscall" "fmt" "io/ioutil" "os" "path/filepath" "strings" + "syscall" "github.com/rfjakob/gocryptfs/internal/cryptocore" "github.com/rfjakob/gocryptfs/internal/toggledlog" @@ -54,17 +54,23 @@ func WriteDirIV(dir string) error { return ioutil.WriteFile(file, iv, 0444) } -// EncryptPathDirIV - encrypt path using EME with DirIV +// EncryptPathDirIV - encrypt relative plaintext path using EME with DirIV. +// Components that are longer than 255 bytes are hashed. func (be *NameTransform) EncryptPathDirIV(plainPath string, rootDir string) (cipherPath string, err error) { // Empty string means root directory if plainPath == "" { return plainPath, nil } + // Reject names longer than 255 bytes already here. This relieves everybody + // who uses hashed long names from checking for that later. + baseName := filepath.Base(plainPath) + if len(baseName) > syscall.NAME_MAX { + return "", syscall.ENAMETOOLONG + } // Check if the DirIV is cached parentDir := filepath.Dir(plainPath) found, iv, cParentDir := be.DirIVCache.lookup(parentDir) if found { - baseName := filepath.Base(plainPath) cBaseName := be.EncryptName(baseName, iv) if be.longNames && len(cBaseName) > syscall.NAME_MAX { cBaseName = HashLongName(cBaseName) @@ -72,7 +78,7 @@ func (be *NameTransform) EncryptPathDirIV(plainPath string, rootDir string) (cip cipherPath = cParentDir + "/" + cBaseName return cipherPath, nil } - // Walk the directory tree + // Not cached - walk the directory tree var wd = rootDir var encryptedNames []string plainNames := strings.Split(plainPath, "/") @@ -96,6 +102,9 @@ func (be *NameTransform) EncryptPathDirIV(plainPath string, rootDir string) (cip } // DecryptPathDirIV - decrypt path using EME with DirIV +// +// TODO This has only a single user, Readlink(), and only for compatability with +// gocryptfs v0.5. Drop? func (be *NameTransform) DecryptPathDirIV(encryptedPath string, rootDir string) (string, error) { var wd = rootDir var plainNames []string |