added fs encryption overlay

This commit is contained in:
ston1th 2022-04-06 01:08:19 +02:00
commit fd1e8118a4
28 changed files with 3994 additions and 30 deletions

186
pkg/provider/crypto/file.go Normal file
View file

@ -0,0 +1,186 @@
package crypto
import (
"cachefs/pkg/provider"
"io"
"io/fs"
)
var _ provider.File = (*file)(nil)
type file struct {
provider.File
fs *FS
r *reader
w *writer
nonce [NonceSize]byte
offset int64
name string
}
func newFile(key []byte, name string, fs *FS, f provider.File) (ef provider.File, err error) {
nonce, err := initNonce(f)
if err != nil {
return
}
skey := streamKey(key, nonce)
w, err := newWriter(skey, f)
if err != nil {
return
}
r, err := newReader(skey, f)
if err != nil {
return
}
return &file{
File: f,
fs: fs,
w: w,
r: r,
name: name,
}, nil
}
func (f *file) Stat() (fs.FileInfo, error) {
fi, err := f.File.Stat()
return stat{FileInfo: fi, name: f.name}, err
}
func (f *file) Name() string {
return f.name
}
func (file) Fd() uintptr {
return 0
}
type stat struct {
fs.FileInfo
name string
}
func (s stat) Size() int64 {
return RealSize(s.FileInfo.Size())
}
func (s stat) Name() string {
return s.name
}
func (f *file) Close() error {
e1 := f.w.Close()
e2 := f.File.Close()
if e1 != nil {
return e1
}
return e2
}
func (f *file) Seek(offset int64, whence int) (n int64, err error) {
var cn, off, roff int64
switch whence {
case io.SeekStart:
cn, off, roff = align(offset)
f.offset = KDFNonceSize + off
n, err = f.File.Seek(f.offset, whence)
case io.SeekCurrent:
if f.offset == 0 {
f.offset = KDFNonceSize
}
cn, off, roff = align(f.offset + f.r.off + offset)
f.offset = off
_, err = f.File.Seek(f.offset, io.SeekStart)
n = offset
}
f.nonce = [NonceSize]byte{}
inc(&f.nonce, cn)
f.r.nonce = f.nonce
f.r.off = roff
f.r.err = nil
f.w.nonce = f.nonce
f.r.unread = f.r.unread[:0]
return
}
func (f *file) Read(p []byte) (n int, err error) {
n, err = f.r.Read(p)
return
}
func (f *file) Write(p []byte) (n int, err error) {
n, err = f.w.Write(p)
return
}
func (f *file) ReadAt(p []byte, pos int64) (n int, err error) {
_, _, roff := align(pos)
//cn, off, roff := align(pos)
f.Seek(pos, io.SeekStart)
//fmt.Println("readAt:", cn, off+KDFNonceSize, roff, pos)
_, err = f.r.readChunk()
if err != nil {
return
}
n = copy(p, f.r.unread[roff:])
return
}
func (f *file) WriteAt(data []byte, pos int64) (n int, err error) {
cn, off, woff := align(pos)
//fmt.Println("writeAt:", cn, off+KDFNonceSize, woff, pos)
c, ok := f.w.cm[cn]
if !ok {
c = &chunkWriter{offset: off + KDFNonceSize, w: f.w, cn: cn}
inc(&c.nonce, cn)
f.w.cm[cn] = c
if f.w.last == nil {
f.w.last = c
} else if cn > f.w.last.cn {
f.w.last = c
}
}
n, err = c.writeAt(data, woff)
if c.full() {
_, err = c.flush(notLastChunk)
//fmt.Println("flush:", cn)
delete(f.w.cm, cn)
}
return
}
func (f *file) Readdir(n int) ([]fs.FileInfo, error) {
fis, err := f.File.Readdir(n)
if err != nil {
return nil, err
}
fio := make([]fs.FileInfo, len(fis))
for i, fi := range fis {
p, err := f.fs.decPath(fi.Name())
if err != nil {
continue
}
fio[i] = dir{FileInfo: fi, name: p}
}
return fio, nil
}
func (f *file) ReadDir(n int) ([]fs.DirEntry, error) {
fis, err := f.Readdir(n)
if err != nil {
return nil, err
}
fio := make([]fs.DirEntry, len(fis))
for i, fi := range fis {
fio[i] = fs.FileInfoToDirEntry(fi)
}
return fio, nil
}
type dir struct {
fs.FileInfo
name string
}
func (d dir) Name() string {
return d.name
}