summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2015-09-09 19:32:59 +0200
committerJakob Unterwurzacher2015-09-09 19:32:59 +0200
commite7ba3c61f1055d740539d608cc521d816d07cddd (patch)
tree576c202f47457e2e2faad3f139efc65667cdc11e
parent80935a0e1b3848608bcc8e1e1497435801ac9940 (diff)
Fix File.GettAttr() size reporting
The too-large reported value broke mmap (applications saw appended zero bytes) Also * Add locking for all fd operations * Add "--debug" command line switch
-rw-r--r--cryptfs/log.go12
-rw-r--r--main.go21
-rw-r--r--pathfs_frontend/file.go6
-rw-r--r--pathfs_frontend/fs.go13
4 files changed, 46 insertions, 6 deletions
diff --git a/cryptfs/log.go b/cryptfs/log.go
index f9c46c8..03d1e29 100644
--- a/cryptfs/log.go
+++ b/cryptfs/log.go
@@ -2,18 +2,28 @@ package cryptfs
import (
"fmt"
+ "strings"
)
type logChannel struct {
enabled bool
}
-func (l logChannel) Printf(format string, args ...interface{}) {
+func (l *logChannel) Printf(format string, args ...interface{}) {
if l.enabled == true {
fmt.Printf(format, args...)
}
}
+func (l *logChannel) Dump(d []byte) {
+ s := string(d)
+ fmt.Println(strings.Replace(s, "\000", "\\0", -1))
+}
+
+func (l *logChannel) Enable() {
+ l.enabled = true
+}
+
var Debug = logChannel{false}
var Warn = logChannel{true}
diff --git a/main.go b/main.go
index 624b2f5..70f0b53 100644
--- a/main.go
+++ b/main.go
@@ -9,6 +9,7 @@ import (
"github.com/rfjakob/gocryptfs/cluefs_frontend"
"github.com/rfjakob/gocryptfs/pathfs_frontend"
+ "github.com/rfjakob/gocryptfs/cryptfs"
bazilfuse "bazil.org/fuse"
bazilfusefs "bazil.org/fuse/fs"
@@ -31,11 +32,18 @@ const (
ERREXIT_MOUNT = 3
ERREXIT_SERVE = 4
ERREXIT_MOUNT2 = 5
+ ERREXIT_CIPHERDIR = 6
)
func main() {
// Parse command line arguments
+ var debug bool
+ flag.BoolVar(&debug, "debug", false, "Enable debug output")
flag.Parse()
+ if debug {
+ cryptfs.Debug.Enable()
+ cryptfs.Debug.Printf("Debug output enabled\n")
+ }
if flag.NArg() < 2 {
fmt.Printf("NArg=%d\n", flag.NArg())
fmt.Printf("usage: %s CIPHERDIR MOUNTPOINT\n", PROGRAM_NAME)
@@ -43,13 +51,20 @@ func main() {
}
cipherdir, _ := filepath.Abs(flag.Arg(0))
mountpoint, _ := filepath.Abs(flag.Arg(1))
+ cryptfs.Debug.Printf("cipherdir=%s\nmountpoint=%s\n", cipherdir, mountpoint)
+
+ _, err := os.Stat(cipherdir)
+ if err != nil {
+ fmt.Printf("Cipherdir: %s\n", err.Error())
+ os.Exit(ERREXIT_CIPHERDIR)
+ }
var key [16]byte
if USE_CLUEFS {
cluefsFrontend(key, cipherdir, mountpoint)
} else {
- pathfsFrontend(key, cipherdir, mountpoint)
+ pathfsFrontend(key, cipherdir, mountpoint, debug)
}
}
@@ -92,7 +107,7 @@ func cluefsFrontend(key [16]byte, cipherdir string, mountpoint string) {
os.Exit(0)
}
-func pathfsFrontend(key [16]byte, cipherdir string, mountpoint string){
+func pathfsFrontend(key [16]byte, cipherdir string, mountpoint string, debug bool){
finalFs := pathfs_frontend.NewFS(key, cipherdir, USE_OPENSSL)
@@ -113,7 +128,7 @@ func pathfsFrontend(key [16]byte, cipherdir string, mountpoint string){
fmt.Printf("Mount fail: %v\n", err)
os.Exit(1)
}
- state.SetDebug(PATHFS_DEBUG)
+ state.SetDebug(debug)
fmt.Println("Mounted!")
state.Serve()
diff --git a/pathfs_frontend/file.go b/pathfs_frontend/file.go
index 8fdd4b2..493a223 100644
--- a/pathfs_frontend/file.go
+++ b/pathfs_frontend/file.go
@@ -58,7 +58,9 @@ func (f *file) doRead(off uint64, length uint64) ([]byte, fuse.Status) {
alignedOffset, alignedLength, skip := f.cfs.CiphertextRange(off, length)
cryptfs.Debug.Printf("CiphertextRange(%d, %d) -> %d, %d, %d\n", off, length, alignedOffset, alignedLength, skip)
ciphertext := make([]byte, int(alignedLength))
+ f.lock.Lock()
n, err := f.fd.ReadAt(ciphertext, int64(alignedOffset))
+ f.lock.Unlock()
ciphertext = ciphertext[0:n]
if err != nil && err != io.EOF {
cryptfs.Warn.Printf("read: ReadAt: %s\n", err.Error())
@@ -131,11 +133,14 @@ func (f *file) Write(data []byte, off int64) (uint32, fuse.Status) {
blockData = f.cfs.MergeBlocks(oldData, blockData, int(b.Offset))
cryptfs.Debug.Printf("len(oldData)=%d len(blockData)=%d\n", len(oldData), len(blockData))
}
+
// Write
blockOffset, _ := b.CiphertextRange()
blockData = f.cfs.EncryptBlock(blockData)
cryptfs.Debug.Printf("WriteAt offset=%d length=%d\n", blockOffset, len(blockData))
+ f.lock.Lock()
_, err := f.fd.WriteAt(blockData, int64(blockOffset))
+ f.lock.Unlock()
if err != nil {
cryptfs.Warn.Printf("Write failed: %s\n", err.Error())
@@ -213,6 +218,7 @@ func (f *file) GetAttr(a *fuse.Attr) fuse.Status {
return fuse.ToStatus(err)
}
a.FromStat(&st)
+ a.Size = f.cfs.PlainSize(a.Size)
return fuse.OK
}
diff --git a/pathfs_frontend/fs.go b/pathfs_frontend/fs.go
index 0c1d879..1e4a1f3 100644
--- a/pathfs_frontend/fs.go
+++ b/pathfs_frontend/fs.go
@@ -112,8 +112,17 @@ func (fs *FS) Utimens(path string, Atime *time.Time, Mtime *time.Time, context *
return fs.FileSystem.Utimens(fs.EncryptPath(path), Atime, Mtime, context)
}
-func (fs *FS) Readlink(name string, context *fuse.Context) (out string, code fuse.Status) {
- return fs.FileSystem.Readlink(fs.EncryptPath(name), context)
+func (fs *FS) Readlink(name string, context *fuse.Context) (out string, status fuse.Status) {
+ dst, status := fs.FileSystem.Readlink(fs.EncryptPath(name), context)
+ if status != fuse.OK {
+ return "", status
+ }
+ dstPlain, err := fs.DecryptPath(dst)
+ if err != nil {
+ cryptfs.Warn.Printf("Failed decrypting symlink: %s\n", err.Error())
+ return "", fuse.EIO
+ }
+ return dstPlain, status
}
func (fs *FS) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) (code fuse.Status) {