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
This commit is contained in:
parent
80935a0e1b
commit
e7ba3c61f1
@ -2,18 +2,28 @@ package cryptfs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type logChannel struct {
|
type logChannel struct {
|
||||||
enabled bool
|
enabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l logChannel) Printf(format string, args ...interface{}) {
|
func (l *logChannel) Printf(format string, args ...interface{}) {
|
||||||
if l.enabled == true {
|
if l.enabled == true {
|
||||||
fmt.Printf(format, args...)
|
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 Debug = logChannel{false}
|
||||||
var Warn = logChannel{true}
|
var Warn = logChannel{true}
|
||||||
|
21
main.go
21
main.go
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/rfjakob/gocryptfs/cluefs_frontend"
|
"github.com/rfjakob/gocryptfs/cluefs_frontend"
|
||||||
"github.com/rfjakob/gocryptfs/pathfs_frontend"
|
"github.com/rfjakob/gocryptfs/pathfs_frontend"
|
||||||
|
"github.com/rfjakob/gocryptfs/cryptfs"
|
||||||
|
|
||||||
bazilfuse "bazil.org/fuse"
|
bazilfuse "bazil.org/fuse"
|
||||||
bazilfusefs "bazil.org/fuse/fs"
|
bazilfusefs "bazil.org/fuse/fs"
|
||||||
@ -31,11 +32,18 @@ const (
|
|||||||
ERREXIT_MOUNT = 3
|
ERREXIT_MOUNT = 3
|
||||||
ERREXIT_SERVE = 4
|
ERREXIT_SERVE = 4
|
||||||
ERREXIT_MOUNT2 = 5
|
ERREXIT_MOUNT2 = 5
|
||||||
|
ERREXIT_CIPHERDIR = 6
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Parse command line arguments
|
// Parse command line arguments
|
||||||
|
var debug bool
|
||||||
|
flag.BoolVar(&debug, "debug", false, "Enable debug output")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
if debug {
|
||||||
|
cryptfs.Debug.Enable()
|
||||||
|
cryptfs.Debug.Printf("Debug output enabled\n")
|
||||||
|
}
|
||||||
if flag.NArg() < 2 {
|
if flag.NArg() < 2 {
|
||||||
fmt.Printf("NArg=%d\n", flag.NArg())
|
fmt.Printf("NArg=%d\n", flag.NArg())
|
||||||
fmt.Printf("usage: %s CIPHERDIR MOUNTPOINT\n", PROGRAM_NAME)
|
fmt.Printf("usage: %s CIPHERDIR MOUNTPOINT\n", PROGRAM_NAME)
|
||||||
@ -43,13 +51,20 @@ func main() {
|
|||||||
}
|
}
|
||||||
cipherdir, _ := filepath.Abs(flag.Arg(0))
|
cipherdir, _ := filepath.Abs(flag.Arg(0))
|
||||||
mountpoint, _ := filepath.Abs(flag.Arg(1))
|
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
|
var key [16]byte
|
||||||
|
|
||||||
if USE_CLUEFS {
|
if USE_CLUEFS {
|
||||||
cluefsFrontend(key, cipherdir, mountpoint)
|
cluefsFrontend(key, cipherdir, mountpoint)
|
||||||
} else {
|
} 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)
|
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)
|
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)
|
fmt.Printf("Mount fail: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
state.SetDebug(PATHFS_DEBUG)
|
state.SetDebug(debug)
|
||||||
|
|
||||||
fmt.Println("Mounted!")
|
fmt.Println("Mounted!")
|
||||||
state.Serve()
|
state.Serve()
|
||||||
|
@ -58,7 +58,9 @@ func (f *file) doRead(off uint64, length uint64) ([]byte, fuse.Status) {
|
|||||||
alignedOffset, alignedLength, skip := f.cfs.CiphertextRange(off, length)
|
alignedOffset, alignedLength, skip := f.cfs.CiphertextRange(off, length)
|
||||||
cryptfs.Debug.Printf("CiphertextRange(%d, %d) -> %d, %d, %d\n", off, length, alignedOffset, alignedLength, skip)
|
cryptfs.Debug.Printf("CiphertextRange(%d, %d) -> %d, %d, %d\n", off, length, alignedOffset, alignedLength, skip)
|
||||||
ciphertext := make([]byte, int(alignedLength))
|
ciphertext := make([]byte, int(alignedLength))
|
||||||
|
f.lock.Lock()
|
||||||
n, err := f.fd.ReadAt(ciphertext, int64(alignedOffset))
|
n, err := f.fd.ReadAt(ciphertext, int64(alignedOffset))
|
||||||
|
f.lock.Unlock()
|
||||||
ciphertext = ciphertext[0:n]
|
ciphertext = ciphertext[0:n]
|
||||||
if err != nil && err != io.EOF {
|
if err != nil && err != io.EOF {
|
||||||
cryptfs.Warn.Printf("read: ReadAt: %s\n", err.Error())
|
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))
|
blockData = f.cfs.MergeBlocks(oldData, blockData, int(b.Offset))
|
||||||
cryptfs.Debug.Printf("len(oldData)=%d len(blockData)=%d\n", len(oldData), len(blockData))
|
cryptfs.Debug.Printf("len(oldData)=%d len(blockData)=%d\n", len(oldData), len(blockData))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write
|
// Write
|
||||||
blockOffset, _ := b.CiphertextRange()
|
blockOffset, _ := b.CiphertextRange()
|
||||||
blockData = f.cfs.EncryptBlock(blockData)
|
blockData = f.cfs.EncryptBlock(blockData)
|
||||||
cryptfs.Debug.Printf("WriteAt offset=%d length=%d\n", blockOffset, len(blockData))
|
cryptfs.Debug.Printf("WriteAt offset=%d length=%d\n", blockOffset, len(blockData))
|
||||||
|
f.lock.Lock()
|
||||||
_, err := f.fd.WriteAt(blockData, int64(blockOffset))
|
_, err := f.fd.WriteAt(blockData, int64(blockOffset))
|
||||||
|
f.lock.Unlock()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cryptfs.Warn.Printf("Write failed: %s\n", err.Error())
|
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)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
a.FromStat(&st)
|
a.FromStat(&st)
|
||||||
|
a.Size = f.cfs.PlainSize(a.Size)
|
||||||
|
|
||||||
return fuse.OK
|
return fuse.OK
|
||||||
}
|
}
|
||||||
|
@ -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)
|
return fs.FileSystem.Utimens(fs.EncryptPath(path), Atime, Mtime, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FS) Readlink(name string, context *fuse.Context) (out string, code fuse.Status) {
|
func (fs *FS) Readlink(name string, context *fuse.Context) (out string, status fuse.Status) {
|
||||||
return fs.FileSystem.Readlink(fs.EncryptPath(name), context)
|
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) {
|
func (fs *FS) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) (code fuse.Status) {
|
||||||
|
Loading…
Reference in New Issue
Block a user