diff --git a/cryptfs/cryptfs_content.go b/cryptfs/cryptfs_content.go index b9dd61f..374b4f4 100644 --- a/cryptfs/cryptfs_content.go +++ b/cryptfs/cryptfs_content.go @@ -97,12 +97,20 @@ func (be *CryptFS) SplitRange(offset uint64, length uint64) []intraBlock { // PlainSize - calculate plaintext size from ciphertext size func (be *CryptFS) PlainSize(size uint64) uint64 { + // Zero sized files stay zero-sized - if size > 0 { - overhead := be.cipherBS - be.plainBS - nBlocks := (size + be.cipherBS - 1) / be.cipherBS - size -= nBlocks * overhead + if size == 0 { + return 0 } + + overhead := be.cipherBS - be.plainBS + nBlocks := (size + be.cipherBS - 1) / be.cipherBS + if nBlocks * overhead > size { + Warn.Printf("PlainSize: Negative size, returning 0 instead\n") + return 0 + } + size -= nBlocks * overhead + return size } diff --git a/cryptfs/log.go b/cryptfs/log.go index 03d1e29..d40aa3f 100644 --- a/cryptfs/log.go +++ b/cryptfs/log.go @@ -26,4 +26,5 @@ func (l *logChannel) Enable() { var Debug = logChannel{false} +var Notice = logChannel{true} var Warn = logChannel{true} diff --git a/main.go b/main.go index 4563b9c..30deb1e 100644 --- a/main.go +++ b/main.go @@ -64,10 +64,10 @@ func initDir(dirArg string) { func main() { // Parse command line arguments - var debug bool - var init bool - var zerokey bool + var debug, init, zerokey, fusedebug bool + flag.BoolVar(&debug, "debug", false, "Enable debug output") + flag.BoolVar(&fusedebug, "fusedebug", false, "Enable fuse library debug output") flag.BoolVar(&init, "init", false, "Initialize encrypted directory") flag.BoolVar(&zerokey, "zerokey", false, "Use all-zero dummy master key") flag.Parse() @@ -123,7 +123,7 @@ func main() { if USE_CLUEFS { cluefsFrontend(key, cipherdir, mountpoint) } else { - pathfsFrontend(key, cipherdir, mountpoint, debug) + pathfsFrontend(key, cipherdir, mountpoint, fusedebug) } } diff --git a/pathfs_frontend/file.go b/pathfs_frontend/file.go index 493a223..8cf070c 100644 --- a/pathfs_frontend/file.go +++ b/pathfs_frontend/file.go @@ -210,6 +210,7 @@ func (f *file) Chown(uid uint32, gid uint32) fuse.Status { } func (f *file) GetAttr(a *fuse.Attr) fuse.Status { + cryptfs.Debug.Printf("file.GetAttr()\n") st := syscall.Stat_t{} f.lock.Lock() err := syscall.Fstat(int(f.fd.Fd()), &st) diff --git a/pathfs_frontend/fs.go b/pathfs_frontend/fs.go index 85fbbaf..bf93766 100644 --- a/pathfs_frontend/fs.go +++ b/pathfs_frontend/fs.go @@ -34,16 +34,24 @@ func (fs *FS) GetPath(relPath string) string { } func (fs *FS) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) { - a, status := fs.FileSystem.GetAttr(fs.EncryptPath(name), context) + cryptfs.Debug.Printf("FS.GetAttr('%s')\n", name) + cName := fs.EncryptPath(name) + a, status := fs.FileSystem.GetAttr(cName, context) if a == nil { + cryptfs.Notice.Printf("FS.GetAttr failed: %s\n", status.String()) return a, status } - - a.Size = fs.PlainSize(a.Size) + if a.IsRegular() { + a.Size = fs.PlainSize(a.Size) + } else if a.IsSymlink() { + target, _ := fs.Readlink(name, context) + a.Size = uint64(len(target)) + } return a, status } func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, fuse.Status) { + cryptfs.Debug.Printf("OpenDir(%s)\n", dirName) cipherEntries, status := fs.FileSystem.OpenDir(fs.EncryptPath(dirName), context); var plain []fuse.DirEntry if cipherEntries != nil { @@ -137,7 +145,12 @@ func (fs *FS) Mkdir(path string, mode uint32, context *fuse.Context) (code fuse. } func (fs *FS) Unlink(name string, context *fuse.Context) (code fuse.Status) { - return fs.FileSystem.Unlink(fs.EncryptPath(name), context) + cName := fs.EncryptPath(name) + code = fs.FileSystem.Unlink(cName, context) + if code != fuse.OK { + cryptfs.Notice.Printf("Unlink failed on %s [%s], code=%s\n", name, cName, code.String()) + } + return code } func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {