diff options
Diffstat (limited to 'pathfs_frontend')
-rw-r--r-- | pathfs_frontend/args.go | 10 | ||||
-rw-r--r-- | pathfs_frontend/fs.go | 48 | ||||
-rw-r--r-- | pathfs_frontend/names.go | 8 |
3 files changed, 48 insertions, 18 deletions
diff --git a/pathfs_frontend/args.go b/pathfs_frontend/args.go new file mode 100644 index 0000000..7971b79 --- /dev/null +++ b/pathfs_frontend/args.go @@ -0,0 +1,10 @@ +package pathfs_frontend + +// Container for arguments that are passed from main() to pathfs_frontend +type Args struct { + Masterkey []byte + Cipherdir string + OpenSSL bool + PlaintextNames bool + DirIV bool +} diff --git a/pathfs_frontend/fs.go b/pathfs_frontend/fs.go index dbb6b10..e68e6bc 100644 --- a/pathfs_frontend/fs.go +++ b/pathfs_frontend/fs.go @@ -18,9 +18,7 @@ import ( type FS struct { *cryptfs.CryptFS pathfs.FileSystem // loopbackFileSystem, see go-fuse/fuse/pathfs/loopback.go - backingDir string // Backing directory, cipherdir - // Are per-directory filename IVs enabled? - dirIV bool + args Args // Stores configuration arguments // dirIVLock: Lock()ed if any "gocryptfs.diriv" file is modified // Readers must RLock() it to prevent them from seeing intermediate // states @@ -28,23 +26,24 @@ type FS struct { } // Encrypted FUSE overlay filesystem -func NewFS(key []byte, backing string, useOpenssl bool, plaintextNames bool, dirIV bool) *FS { +func NewFS(args Args) *FS { return &FS{ - CryptFS: cryptfs.NewCryptFS(key, useOpenssl, plaintextNames), - FileSystem: pathfs.NewLoopbackFileSystem(backing), - dirIV: dirIV, - backingDir: backing, + CryptFS: cryptfs.NewCryptFS(args.Masterkey, args.OpenSSL, args.PlaintextNames), + FileSystem: pathfs.NewLoopbackFileSystem(args.Cipherdir), + args: args, } } // GetBackingPath - get the absolute encrypted path of the backing file // from the relative plaintext path "relPath" func (fs *FS) getBackingPath(relPath string) (string, error) { - encrypted, err := fs.encryptPath(relPath) + cPath, err := fs.encryptPath(relPath) if err != nil { return "", err } - return filepath.Join(fs.backingDir, encrypted), nil + cAbsPath := filepath.Join(fs.args.Cipherdir, cPath) + cryptfs.Debug.Printf("getBackingPath: %s + %s -> %s\n", fs.args.Cipherdir, relPath, cAbsPath) + return cAbsPath, nil } func (fs *FS) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) { @@ -85,12 +84,12 @@ func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, f // silently ignore "gocryptfs.conf" in the top level dir continue } - if fs.dirIV && cName == cryptfs.DIRIV_FILENAME { + if fs.args.DirIV && cName == cryptfs.DIRIV_FILENAME { // silently ignore "gocryptfs.diriv" everywhere if dirIV is enabled continue } var name string - if !fs.dirIV { + if !fs.args.DirIV { name, err = fs.decryptPath(cName) } else { // When dirIV is enabled we need the full path to be able to decrypt it @@ -123,15 +122,16 @@ func (fs *FS) mangleOpenFlags(flags uint32) (newFlags int, writeOnly bool) { } func (fs *FS) Open(path string, flags uint32, context *fuse.Context) (fuseFile nodefs.File, status fuse.Status) { - cryptfs.Debug.Printf("Open(%s)\n", path) if fs.CryptFS.IsFiltered(path) { return nil, fuse.EPERM } iflags, writeOnly := fs.mangleOpenFlags(flags) cPath, err := fs.getBackingPath(path) if err != nil { + cryptfs.Debug.Printf("Open: getBackingPath: %v\n", err) return nil, fuse.ToStatus(err) } + cryptfs.Debug.Printf("Open: %s\n", cPath) f, err := os.OpenFile(cPath, iflags, 0666) if err != nil { return nil, fuse.ToStatus(err) @@ -214,6 +214,16 @@ func (fs *FS) Readlink(path string, context *fuse.Context) (out string, status f if status != fuse.OK { return "", status } + // Old filesystem: symlinks are encrypted like paths (CBC) + if !fs.args.DirIV { + target, err := fs.decryptPath(cTarget) + if err != nil { + cryptfs.Warn.Printf("Readlink: CBC decryption failed: %v", err) + return "", fuse.EIO + } + return target, fuse.OK + } + // Since gocryptfs v0.5 symlinks are encrypted like file contents (GCM) cBinTarget, err := base64.URLEncoding.DecodeString(cTarget) if err != nil { cryptfs.Warn.Printf("Readlink: %v\n", err) @@ -335,7 +345,17 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co if err != nil { return fuse.ToStatus(err) } - + // Old filesystem: symlinks are encrypted like paths (CBC) + if !fs.args.DirIV { + cTarget, err := fs.encryptPath(target) + if err != nil { + cryptfs.Warn.Printf("Symlink: BUG: we should not get an error here: %v\n", err) + return fuse.ToStatus(err) + } + err = os.Symlink(cTarget, cPath) + return fuse.ToStatus(err) + } + // Since gocryptfs v0.5 symlinks are encrypted like file contents (GCM) cBinTarget := fs.CryptFS.EncryptBlock([]byte(target), 0, nil) cTarget := base64.URLEncoding.EncodeToString(cBinTarget) diff --git a/pathfs_frontend/names.go b/pathfs_frontend/names.go index 122b3dd..bb73ff4 100644 --- a/pathfs_frontend/names.go +++ b/pathfs_frontend/names.go @@ -7,19 +7,19 @@ import ( ) func (fs *FS) encryptPath(plainPath string) (string, error) { - if !fs.dirIV { + if !fs.args.DirIV { return fs.CryptFS.TranslatePathZeroIV(plainPath, cryptfs.OpEncrypt) } fs.dirIVLock.RLock() defer fs.dirIVLock.RUnlock() - return fs.CryptFS.EncryptPathDirIV(plainPath, fs.backingDir) + return fs.CryptFS.EncryptPathDirIV(plainPath, fs.args.Cipherdir) } func (fs *FS) decryptPath(cipherPath string) (string, error) { - if !fs.dirIV { + if !fs.args.DirIV { return fs.CryptFS.TranslatePathZeroIV(cipherPath, cryptfs.OpDecrypt) } fs.dirIVLock.RLock() defer fs.dirIVLock.RUnlock() - return fs.CryptFS.DecryptPathDirIV(cipherPath, fs.backingDir) + return fs.CryptFS.DecryptPathDirIV(cipherPath, fs.args.Cipherdir) } |