/
cryptname.go
117 lines (101 loc) · 2.78 KB
/
cryptname.go
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package storage
import (
"encoding/base64"
"fmt"
"io"
"io/fs"
"os"
"github.com/stregato/master/woland/core"
"github.com/stregato/master/woland/security"
)
type encrypted struct {
Store Store
Key []byte
Nonce []byte
PropagateClose bool
}
func EncryptNames(s Store, key []byte, nonce []byte, propagateClose bool) Store {
return &encrypted{s, key, nonce, propagateClose}
}
func (s *encrypted) Url() string {
return s.Store.Url()
}
func (s *encrypted) ReadDir(name string, filter Filter) ([]fs.FileInfo, error) {
c, err := security.EncryptBlock(s.Key, s.Nonce, []byte(name))
if err != nil {
return nil, err
}
name = base64.StdEncoding.EncodeToString(c)
ls, err := s.Store.ReadDir(name, filter)
if err != nil {
return nil, err
}
var files []fs.FileInfo
for _, l := range ls {
data, err := base64.StdEncoding.DecodeString(l.Name())
if core.IsWarn(err, "cannot decode %s: %v", l.Name()) {
continue
}
d, err := security.DecryptBlock(s.Key, s.Nonce, data)
if core.IsWarn(err, "cannot decrypt %s: %v", l.Name()) {
continue
}
files = append(files, simpleFileInfo{
name: string(d),
size: l.Size(),
modTime: l.ModTime(),
isDir: l.IsDir(),
})
}
return files, nil
}
// Read reads data from a file into a writer
func (s *encrypted) Read(name string, rang *Range, dest io.Writer, progress chan int64) error {
c, err := security.EncryptBlock(s.Key, s.Nonce, []byte(name))
if err != nil {
return err
}
name = base64.StdEncoding.EncodeToString(c)
return s.Store.Read(name, rang, dest, progress)
}
// Write writes data to a file name. An existing file is overwritten
func (s *encrypted) Write(name string, source io.ReadSeeker, progress chan int64) error {
c, err := security.EncryptBlock(s.Key, s.Nonce, []byte(name))
if err != nil {
return err
}
name = base64.StdEncoding.EncodeToString(c)
return s.Store.Write(name, source, progress)
}
// Stat provides statistics about a file
func (s *encrypted) Stat(name string) (os.FileInfo, error) {
c, err := security.EncryptBlock(s.Key, s.Nonce, []byte(name))
if err != nil {
return nil, err
}
name = base64.StdEncoding.EncodeToString(c)
return s.Store.Stat(name)
}
// Delete deletes a file
func (s *encrypted) Delete(name string) error {
c, err := security.EncryptBlock(s.Key, s.Nonce, []byte(name))
if err != nil {
return err
}
name = base64.StdEncoding.EncodeToString(c)
return s.Store.Delete(name)
}
// Close closes the store
func (s *encrypted) Close() error {
if s.PropagateClose {
return s.Store.Close()
}
return nil
}
func (s *encrypted) Describe() Description {
return s.Store.Describe()
}
// String returns a human-readable representation of the storer (e.g. sftp://user@host/path)
func (s *encrypted) String() string {
return fmt.Sprintf("%s,enc", s.Store)
}