package encfs import ( "os" "strings" "time" "github.com/spf13/afero" ) // copied from afero/os.go type EncryptionMasterKey struct { key []byte } type EncFs struct { key *EncryptionMasterKey } func NewEncFs(key *EncryptionMasterKey) afero.Fs { return &EncFs{ key: key, } } func (*EncFs) Name() string { return "EncFs" } func (encFs *EncFs) Create(name string) (afero.File, error) { if err := checkFileExt(name); err != nil { return nil, err } f, e := os.Create(name) if f == nil { // while this looks strange, we need to return a bare nil (of type nil) not // a nil value of type *os.File or nil won't be nil return nil, e } return convertOsFileToEncFile(name, f, e, encFs, true) } func (*EncFs) Mkdir(name string, perm os.FileMode) error { return os.Mkdir(name, perm) } func (*EncFs) MkdirAll(path string, perm os.FileMode) error { return os.MkdirAll(path, perm) } func (encFs *EncFs) Open(name string) (afero.File, error) { if err := checkFileExt(name); err != nil { return nil, err } f, e := os.Open(name) if f == nil { // while this looks strange, we need to return a bare nil (of type nil) not // a nil value of type *os.File or nil won't be nil return nil, e } return convertOsFileToEncFile(name, f, e, encFs, false) } func (encFs *EncFs) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error) { if err := checkFileExt(name); err != nil { return nil, err } f, e := os.OpenFile(name, flag, perm) if f == nil { // while this looks strange, we need to return a bare nil (of type nil) not // a nil value of type *os.File or nil won't be nil return nil, e } return convertOsFileToEncFile(name, f, e, encFs, false) } func (*EncFs) Remove(name string) error { encFileMetaName := name + EncFileExt _ = os.Remove(encFileMetaName) return os.Remove(name) } func (encFs *EncFs) RemoveAll(path string) error { fileInfo, err := os.Stat(path) if err == nil && !fileInfo.IsDir() { return encFs.Remove(path) } return os.RemoveAll(path) } func (*EncFs) Rename(oldname, newname string) error { oldEncFileMetaName := oldname + EncFileExt newEncFileMetaName := newname + EncFileExt _ = os.Rename(oldEncFileMetaName, newEncFileMetaName) return os.Rename(oldname, newname) } func (*EncFs) Stat(name string) (os.FileInfo, error) { return os.Stat(name) } func (*EncFs) Chmod(name string, mode os.FileMode) error { return os.Chmod(name, mode) } func (*EncFs) Chown(name string, uid, gid int) error { return os.Chown(name, uid, gid) } func (*EncFs) Chtimes(name string, atime time.Time, mtime time.Time) error { return os.Chtimes(name, atime, mtime) } func (*EncFs) LstatIfPossible(name string) (os.FileInfo, bool, error) { fi, err := os.Lstat(name) return fi, true, err } func (*EncFs) SymlinkIfPossible(oldname, newname string) error { return os.Symlink(oldname, newname) } func (*EncFs) ReadlinkIfPossible(name string) (string, error) { return os.Readlink(name) } func checkFileExt(name string) error { if strings.HasSuffix(name, EncFileExt) { return ErrFileForbiddenFileExt } return nil } func convertOsFileToEncFile(name string, file *os.File, e error, encFs *EncFs, isCreate bool) (afero.File, error) { if e != nil { return nil, e } encFile, err := NewEncFile(name, file, encFs, isCreate) if err != nil { return nil, err } return encFile, nil }