diff options
author | Jakob Unterwurzacher | 2016-02-06 22:54:14 +0100 |
---|---|---|
committer | Jakob Unterwurzacher | 2016-02-06 22:54:14 +0100 |
commit | e111e20649cfacd7b02dd454d75db879aa2ca53c (patch) | |
tree | 5020d3172bfa2462f05898473093dabd3688e64f /internal/nametransform/longnames.go | |
parent | 5abd9cec136bfb981c728eb3bf0f92b2282601c6 (diff) |
longnames part I: Create and OpenDir work with long filenames > 176 bytes
Todo: Rename, Unlink, Rmdir, Mknod, Mkdir
Diffstat (limited to 'internal/nametransform/longnames.go')
-rw-r--r-- | internal/nametransform/longnames.go | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/internal/nametransform/longnames.go b/internal/nametransform/longnames.go new file mode 100644 index 0000000..e442b64 --- /dev/null +++ b/internal/nametransform/longnames.go @@ -0,0 +1,68 @@ +package nametransform + +import ( + "syscall" + "path/filepath" + "io/ioutil" + "crypto/sha256" + "encoding/base64" + "strings" + + "github.com/rfjakob/gocryptfs/internal/toggledlog" +) + +// Files with long names are stored in two files: +// gocryptfs.longname.[sha256] <--- File content +// gocryptfs.longname.[sha256].name <--- File name +const longNamePrefix = "gocryptfs.longname." +const longNameSuffix = ".name" + +// HashLongName - take the hash of a long string "name" and return +// "gocryptfs.longname.[sha256]" +func HashLongName(name string) string { + hashBin := sha256.Sum256([]byte(name)) + hashBase64 := base64.URLEncoding.EncodeToString(hashBin[:]) + return longNamePrefix + hashBase64 +} + +// IsLongName - detect if cName is +// gocryptfs.longname.* ........ 1 +// gocryptfs.longname.*.name ... 2 +// else ........................ 0 +func IsLongName(cName string) int { + if !strings.HasPrefix(cName, longNamePrefix) { + return 0 + } + if strings.HasSuffix(cName, longNameSuffix) { + return 2 + } + return 1 +} + +// ReadLongName - read "path".name +func ReadLongName(path string) (string, error) { + 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 + } + + dirIV, err := ReadDirIV(cDir) + if err != nil { + toggledlog.Warn.Printf("WriteLongName: %v", err) + return err + } + cName := n.EncryptName(plainName, dirIV) + err = ioutil.WriteFile(filepath.Join(cDir, hashedName + longNameSuffix), []byte(cName), 0600) + if err != nil { + toggledlog.Warn.Printf("WriteLongName: %v", err) + } + return err +} |