aboutsummaryrefslogtreecommitdiff
path: root/internal/nametransform/longnames.go
blob: e442b64ec871af1ef9a73bf88e53cba8d258c86c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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
}