diriv: Move WriteDirIV() to cryptfs; add locking to Mkdir, Rmdir
This commit is contained in:
parent
decfc1ab79
commit
bdd9249a52
|
@ -21,6 +21,15 @@ func (be *CryptFS) readDirIV(dir string) (iv []byte, err error) {
|
||||||
return iv, nil
|
return iv, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteDirIV - create diriv file inside "dir" (absolute path)
|
||||||
|
// This function is exported because it is used from pathfs_frontend
|
||||||
|
func (be *CryptFS) WriteDirIV(dir string) error {
|
||||||
|
iv := RandBytes(DIRIV_LEN)
|
||||||
|
file := filepath.Join(dir, DIRIV_FILENAME)
|
||||||
|
// 0444 permissions: the file is not secret but should not be written to
|
||||||
|
return ioutil.WriteFile(file, iv, 0444)
|
||||||
|
}
|
||||||
|
|
||||||
// EncryptPathDirIV - encrypt path using CBC with DirIV
|
// EncryptPathDirIV - encrypt path using CBC with DirIV
|
||||||
func (be *CryptFS) EncryptPathDirIV(plainPath string, rootDir string) (string, error) {
|
func (be *CryptFS) EncryptPathDirIV(plainPath string, rootDir string) (string, error) {
|
||||||
if be.plaintextNames {
|
if be.plaintextNames {
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
@ -20,7 +19,11 @@ type FS struct {
|
||||||
*cryptfs.CryptFS
|
*cryptfs.CryptFS
|
||||||
pathfs.FileSystem // loopbackFileSystem, see go-fuse/fuse/pathfs/loopback.go
|
pathfs.FileSystem // loopbackFileSystem, see go-fuse/fuse/pathfs/loopback.go
|
||||||
backingDir string // Backing directory, cipherdir
|
backingDir string // Backing directory, cipherdir
|
||||||
dirivLock sync.RWMutex // Global lock that is taken if any "gocryptfs.diriv" file is modified
|
// dirIVLock: Lock()ed if any "gocryptfs.diriv" file is modified
|
||||||
|
// Readers must RLock() it to prevent them from seeing intermediate
|
||||||
|
// states
|
||||||
|
dirIVLock sync.RWMutex
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypted FUSE overlay filesystem
|
// Encrypted FUSE overlay filesystem
|
||||||
|
@ -217,16 +220,15 @@ func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fu
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
diriv := cryptfs.RandBytes(cryptfs.DIRIV_LEN)
|
|
||||||
dirivPath := filepath.Join(encPath, cryptfs.DIRIV_FILENAME)
|
|
||||||
// Create directory
|
// Create directory
|
||||||
|
fs.dirIVLock.Lock()
|
||||||
|
defer fs.dirIVLock.Unlock()
|
||||||
err = os.Mkdir(encPath, os.FileMode(mode))
|
err = os.Mkdir(encPath, os.FileMode(mode))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
// Create gocryptfs.diriv inside
|
// Create gocryptfs.diriv inside
|
||||||
// 0444 permissions: the file is not secret but should not be written to
|
err = fs.CryptFS.WriteDirIV(encPath)
|
||||||
err = ioutil.WriteFile(dirivPath, diriv, 0444)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// This should not happen
|
// This should not happen
|
||||||
cryptfs.Warn.Printf("Creating %s in dir %s failed: %v\n", cryptfs.DIRIV_FILENAME, encPath, err)
|
cryptfs.Warn.Printf("Creating %s in dir %s failed: %v\n", cryptfs.DIRIV_FILENAME, encPath, err)
|
||||||
|
@ -282,8 +284,8 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
|
||||||
tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", st.Ino)
|
tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", st.Ino)
|
||||||
tmpDirivPath := filepath.Join(parentDir, tmpName)
|
tmpDirivPath := filepath.Join(parentDir, tmpName)
|
||||||
cryptfs.Debug.Printf("Rmdir: Renaming %s to %s\n", cryptfs.DIRIV_FILENAME, tmpDirivPath)
|
cryptfs.Debug.Printf("Rmdir: Renaming %s to %s\n", cryptfs.DIRIV_FILENAME, tmpDirivPath)
|
||||||
fs.dirivLock.Lock() // directory will be in an inconsistent state after the rename
|
fs.dirIVLock.Lock() // directory will be in an inconsistent state after the rename
|
||||||
defer fs.dirivLock.Unlock()
|
defer fs.dirIVLock.Unlock()
|
||||||
err = os.Rename(dirivPath, tmpDirivPath)
|
err = os.Rename(dirivPath, tmpDirivPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("Rmdir: Renaming %s to %s failed: %v\n", cryptfs.DIRIV_FILENAME, tmpDirivPath, err)
|
cryptfs.Warn.Printf("Rmdir: Renaming %s to %s failed: %v\n", cryptfs.DIRIV_FILENAME, tmpDirivPath, err)
|
||||||
|
|
|
@ -3,9 +3,13 @@ package pathfs_frontend
|
||||||
// This file handles filename encryption
|
// This file handles filename encryption
|
||||||
|
|
||||||
func (fs *FS) encryptPath(plainPath string) (string, error) {
|
func (fs *FS) encryptPath(plainPath string) (string, error) {
|
||||||
|
fs.dirIVLock.RLock()
|
||||||
|
defer fs.dirIVLock.RUnlock()
|
||||||
return fs.CryptFS.EncryptPathDirIV(plainPath, fs.backingDir)
|
return fs.CryptFS.EncryptPathDirIV(plainPath, fs.backingDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FS) decryptPath(cipherPath string) (string, error) {
|
func (fs *FS) decryptPath(cipherPath string) (string, error) {
|
||||||
|
fs.dirIVLock.RLock()
|
||||||
|
defer fs.dirIVLock.RUnlock()
|
||||||
return fs.CryptFS.DecryptPathDirIV(cipherPath, fs.backingDir)
|
return fs.CryptFS.DecryptPathDirIV(cipherPath, fs.backingDir)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue