summaryrefslogtreecommitdiff
path: root/pathfs_frontend
diff options
context:
space:
mode:
authorJakob Unterwurzacher2016-02-06 19:20:54 +0100
committerJakob Unterwurzacher2016-02-06 19:22:35 +0100
commit2b8cbd944149afe51fadddbd67ee4499d1d86250 (patch)
tree76361984cc4394bbb9b19ae987aeaff71fb6073b /pathfs_frontend
parentadcfbd79a8b8bb85cbee25996ab622a05de0dbc1 (diff)
Major refactoring: Split up "cryptfs" into several internal packages
"git status" for reference: deleted: cryptfs/cryptfs.go deleted: cryptfs/names_core.go modified: integration_tests/cli_test.go modified: integration_tests/helpers.go renamed: cryptfs/config_file.go -> internal/configfile/config_file.go renamed: cryptfs/config_test.go -> internal/configfile/config_test.go renamed: cryptfs/config_test/.gitignore -> internal/configfile/config_test/.gitignore renamed: cryptfs/config_test/PlaintextNames.conf -> internal/configfile/config_test/PlaintextNames.conf renamed: cryptfs/config_test/StrangeFeature.conf -> internal/configfile/config_test/StrangeFeature.conf renamed: cryptfs/config_test/v1.conf -> internal/configfile/config_test/v1.conf renamed: cryptfs/config_test/v2.conf -> internal/configfile/config_test/v2.conf renamed: cryptfs/kdf.go -> internal/configfile/kdf.go renamed: cryptfs/kdf_test.go -> internal/configfile/kdf_test.go renamed: cryptfs/cryptfs_content.go -> internal/contentenc/content.go new file: internal/contentenc/content_api.go renamed: cryptfs/content_test.go -> internal/contentenc/content_test.go renamed: cryptfs/file_header.go -> internal/contentenc/file_header.go renamed: cryptfs/intrablock.go -> internal/contentenc/intrablock.go renamed: cryptfs/address_translation.go -> internal/contentenc/offsets.go new file: internal/cryptocore/crypto_api.go renamed: cryptfs/gcm_go1.4.go -> internal/cryptocore/gcm_go1.4.go renamed: cryptfs/gcm_go1.5.go -> internal/cryptocore/gcm_go1.5.go renamed: cryptfs/nonce.go -> internal/cryptocore/nonce.go renamed: cryptfs/openssl_aead.go -> internal/cryptocore/openssl_aead.go renamed: cryptfs/openssl_benchmark.bash -> internal/cryptocore/openssl_benchmark.bash renamed: cryptfs/openssl_test.go -> internal/cryptocore/openssl_test.go new file: internal/nametransform/name_api.go new file: internal/nametransform/names_core.go renamed: cryptfs/names_diriv.go -> internal/nametransform/names_diriv.go renamed: cryptfs/names_noiv.go -> internal/nametransform/names_noiv.go renamed: cryptfs/names_test.go -> internal/nametransform/names_test.go new file: internal/nametransform/pad16.go renamed: cryptfs/log.go -> internal/toggledlog/log.go renamed: cryptfs/log_go1.4.go -> internal/toggledlog/log_go1.4.go renamed: cryptfs/log_go1.5.go -> internal/toggledlog/log_go1.5.go modified: main.go modified: masterkey.go modified: pathfs_frontend/file.go modified: pathfs_frontend/file_holes.go modified: pathfs_frontend/fs.go modified: pathfs_frontend/fs_dir.go modified: pathfs_frontend/names.go modified: test.bash
Diffstat (limited to 'pathfs_frontend')
-rw-r--r--pathfs_frontend/file.go112
-rw-r--r--pathfs_frontend/file_holes.go13
-rw-r--r--pathfs_frontend/fs.go76
-rw-r--r--pathfs_frontend/fs_dir.go44
-rw-r--r--pathfs_frontend/names.go17
5 files changed, 143 insertions, 119 deletions
diff --git a/pathfs_frontend/file.go b/pathfs_frontend/file.go
index 33ad0c7..387eb35 100644
--- a/pathfs_frontend/file.go
+++ b/pathfs_frontend/file.go
@@ -13,7 +13,9 @@ import (
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/nodefs"
- "github.com/rfjakob/gocryptfs/cryptfs"
+
+ "github.com/rfjakob/gocryptfs/internal/contentenc"
+ "github.com/rfjakob/gocryptfs/internal/toggledlog"
)
// File - based on loopbackFile in go-fuse/fuse/nodefs/files.go
@@ -29,19 +31,19 @@ type file struct {
// Was the file opened O_WRONLY?
writeOnly bool
- // Parent CryptFS
- cfs *cryptfs.CryptFS
+ // Content encryption helper
+ contentEnc *contentenc.ContentEnc
// Inode number
ino uint64
// File header
- header *cryptfs.FileHeader
+ header *contentenc.FileHeader
forgotten bool
}
-func NewFile(fd *os.File, writeOnly bool, cfs *cryptfs.CryptFS) nodefs.File {
+func NewFile(fd *os.File, writeOnly bool, contentEnc *contentenc.ContentEnc) nodefs.File {
var st syscall.Stat_t
syscall.Fstat(int(fd.Fd()), &st)
wlock.register(st.Ino)
@@ -49,7 +51,7 @@ func NewFile(fd *os.File, writeOnly bool, cfs *cryptfs.CryptFS) nodefs.File {
return &file{
fd: fd,
writeOnly: writeOnly,
- cfs: cfs,
+ contentEnc: contentEnc,
ino: st.Ino,
}
}
@@ -71,12 +73,12 @@ func (f *file) SetInode(n *nodefs.Inode) {
//
// Returns io.EOF if the file is empty
func (f *file) readHeader() error {
- buf := make([]byte, cryptfs.HEADER_LEN)
+ buf := make([]byte, contentenc.HEADER_LEN)
_, err := f.fd.ReadAt(buf, 0)
if err != nil {
return err
}
- h, err := cryptfs.ParseHeader(buf)
+ h, err := contentenc.ParseHeader(buf)
if err != nil {
return err
}
@@ -87,13 +89,13 @@ func (f *file) readHeader() error {
// createHeader - create a new random header and write it to disk
func (f *file) createHeader() error {
- h := cryptfs.RandomHeader()
+ h := contentenc.RandomHeader()
buf := h.Pack()
// Prevent partially written (=corrupt) header by preallocating the space beforehand
- err := prealloc(int(f.fd.Fd()), 0, cryptfs.HEADER_LEN)
+ err := prealloc(int(f.fd.Fd()), 0, contentenc.HEADER_LEN)
if err != nil {
- cryptfs.Warn.Printf("ino%d: createHeader: prealloc failed: %s\n", f.ino, err.Error())
+ toggledlog.Warn.Printf("ino%d: createHeader: prealloc failed: %s\n", f.ino, err.Error())
return err
}
@@ -133,29 +135,29 @@ func (f *file) doRead(off uint64, length uint64) ([]byte, fuse.Status) {
}
// Read the backing ciphertext in one go
- blocks := f.cfs.ExplodePlainRange(off, length)
+ blocks := f.contentEnc.ExplodePlainRange(off, length)
alignedOffset, alignedLength := blocks[0].JointCiphertextRange(blocks)
skip := blocks[0].Skip
- cryptfs.Debug.Printf("JointCiphertextRange(%d, %d) -> %d, %d, %d", off, length, alignedOffset, alignedLength, skip)
+ toggledlog.Debug.Printf("JointCiphertextRange(%d, %d) -> %d, %d, %d", off, length, alignedOffset, alignedLength, skip)
ciphertext := make([]byte, int(alignedLength))
n, err := f.fd.ReadAt(ciphertext, int64(alignedOffset))
if err != nil && err != io.EOF {
- cryptfs.Warn.Printf("read: ReadAt: %s", err.Error())
+ toggledlog.Warn.Printf("read: ReadAt: %s", err.Error())
return nil, fuse.ToStatus(err)
}
// Truncate ciphertext buffer down to actually read bytes
ciphertext = ciphertext[0:n]
firstBlockNo := blocks[0].BlockNo
- cryptfs.Debug.Printf("ReadAt offset=%d bytes (%d blocks), want=%d, got=%d", alignedOffset, firstBlockNo, alignedLength, n)
+ toggledlog.Debug.Printf("ReadAt offset=%d bytes (%d blocks), want=%d, got=%d", alignedOffset, firstBlockNo, alignedLength, n)
// Decrypt it
- plaintext, err := f.cfs.DecryptBlocks(ciphertext, firstBlockNo, f.header.Id)
+ plaintext, err := f.contentEnc.DecryptBlocks(ciphertext, firstBlockNo, f.header.Id)
if err != nil {
- curruptBlockNo := firstBlockNo + f.cfs.PlainOffToBlockNo(uint64(len(plaintext)))
- cipherOff := f.cfs.BlockNoToCipherOff(curruptBlockNo)
- plainOff := f.cfs.BlockNoToPlainOff(curruptBlockNo)
- cryptfs.Warn.Printf("ino%d: doRead: corrupt block #%d (plainOff=%d, cipherOff=%d)",
+ curruptBlockNo := firstBlockNo + f.contentEnc.PlainOffToBlockNo(uint64(len(plaintext)))
+ cipherOff := f.contentEnc.BlockNoToCipherOff(curruptBlockNo)
+ plainOff := f.contentEnc.BlockNoToPlainOff(curruptBlockNo)
+ toggledlog.Warn.Printf("ino%d: doRead: corrupt block #%d (plainOff=%d, cipherOff=%d)",
f.ino, curruptBlockNo, plainOff, cipherOff)
return nil, fuse.EIO
}
@@ -179,23 +181,23 @@ func (f *file) Read(buf []byte, off int64) (resultData fuse.ReadResult, code fus
f.fdLock.RLock()
defer f.fdLock.RUnlock()
- cryptfs.Debug.Printf("ino%d: FUSE Read: offset=%d length=%d", f.ino, len(buf), off)
+ toggledlog.Debug.Printf("ino%d: FUSE Read: offset=%d length=%d", f.ino, len(buf), off)
if f.writeOnly {
- cryptfs.Warn.Printf("ino%d: Tried to read from write-only file", f.ino)
+ toggledlog.Warn.Printf("ino%d: Tried to read from write-only file", f.ino)
return nil, fuse.EBADF
}
out, status := f.doRead(uint64(off), uint64(len(buf)))
if status == fuse.EIO {
- cryptfs.Warn.Printf("ino%d: Read failed with EIO, offset=%d, length=%d", f.ino, len(buf), off)
+ toggledlog.Warn.Printf("ino%d: Read failed with EIO, offset=%d, length=%d", f.ino, len(buf), off)
}
if status != fuse.OK {
return nil, status
}
- cryptfs.Debug.Printf("ino%d: Read: status %v, returning %d bytes", f.ino, status, len(out))
+ toggledlog.Debug.Printf("ino%d: Read: status %v, returning %d bytes", f.ino, status, len(out))
return fuse.ReadResultData(out), status
}
@@ -225,7 +227,7 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
var written uint32
status := fuse.OK
dataBuf := bytes.NewBuffer(data)
- blocks := f.cfs.ExplodePlainRange(uint64(off), uint64(len(data)))
+ blocks := f.contentEnc.ExplodePlainRange(uint64(off), uint64(len(data)))
for _, b := range blocks {
blockData := dataBuf.Next(int(b.Length))
@@ -234,26 +236,26 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
if b.IsPartial() {
// Read
o, _ := b.PlaintextRange()
- oldData, status := f.doRead(o, f.cfs.PlainBS())
+ oldData, status := f.doRead(o, f.contentEnc.PlainBS())
if status != fuse.OK {
- cryptfs.Warn.Printf("ino%d fh%d: RMW read failed: %s", f.ino, f.intFd(), status.String())
+ toggledlog.Warn.Printf("ino%d fh%d: RMW read failed: %s", f.ino, f.intFd(), status.String())
return written, status
}
// Modify
- blockData = f.cfs.MergeBlocks(oldData, blockData, int(b.Skip))
- cryptfs.Debug.Printf("len(oldData)=%d len(blockData)=%d", len(oldData), len(blockData))
+ blockData = f.contentEnc.MergeBlocks(oldData, blockData, int(b.Skip))
+ toggledlog.Debug.Printf("len(oldData)=%d len(blockData)=%d", len(oldData), len(blockData))
}
// Encrypt
blockOffset, blockLen := b.CiphertextRange()
- blockData = f.cfs.EncryptBlock(blockData, b.BlockNo, f.header.Id)
- cryptfs.Debug.Printf("ino%d: Writing %d bytes to block #%d",
- f.ino, uint64(len(blockData))-f.cfs.BlockOverhead(), b.BlockNo)
+ blockData = f.contentEnc.EncryptBlock(blockData, b.BlockNo, f.header.Id)
+ toggledlog.Debug.Printf("ino%d: Writing %d bytes to block #%d",
+ f.ino, uint64(len(blockData))-f.contentEnc.BlockOverhead(), b.BlockNo)
// Prevent partially written (=corrupt) blocks by preallocating the space beforehand
err := prealloc(int(f.fd.Fd()), int64(blockOffset), int64(blockLen))
if err != nil {
- cryptfs.Warn.Printf("ino%d fh%d: doWrite: prealloc failed: %s", f.ino, f.intFd(), err.Error())
+ toggledlog.Warn.Printf("ino%d fh%d: doWrite: prealloc failed: %s", f.ino, f.intFd(), err.Error())
status = fuse.ToStatus(err)
break
}
@@ -262,7 +264,7 @@ func (f *file) doWrite(data []byte, off int64) (uint32, fuse.Status) {
_, err = f.fd.WriteAt(blockData, int64(blockOffset))
if err != nil {
- cryptfs.Warn.Printf("doWrite: Write failed: %s", err.Error())
+ toggledlog.Warn.Printf("doWrite: Write failed: %s", err.Error())
status = fuse.ToStatus(err)
break
}
@@ -278,18 +280,18 @@ func (f *file) Write(data []byte, off int64) (uint32, fuse.Status) {
wlock.lock(f.ino)
defer wlock.unlock(f.ino)
- cryptfs.Debug.Printf("ino%d: FUSE Write: offset=%d length=%d", f.ino, off, len(data))
+ toggledlog.Debug.Printf("ino%d: FUSE Write: offset=%d length=%d", f.ino, off, len(data))
fi, err := f.fd.Stat()
if err != nil {
- cryptfs.Warn.Printf("Write: Fstat failed: %v", err)
+ toggledlog.Warn.Printf("Write: Fstat failed: %v", err)
return 0, fuse.ToStatus(err)
}
- plainSize := f.cfs.CipherSizeToPlainSize(uint64(fi.Size()))
+ plainSize := f.contentEnc.CipherSizeToPlainSize(uint64(fi.Size()))
if f.createsHole(plainSize, off) {
status := f.zeroPad(plainSize)
if status != fuse.OK {
- cryptfs.Warn.Printf("zeroPad returned error %v", status)
+ toggledlog.Warn.Printf("zeroPad returned error %v", status)
return 0, status
}
}
@@ -337,14 +339,14 @@ func (f *file) Truncate(newSize uint64) fuse.Status {
defer wlock.unlock(f.ino)
if f.forgotten {
- cryptfs.Warn.Printf("ino%d fh%d: Truncate on forgotten file", f.ino, f.intFd())
+ toggledlog.Warn.Printf("ino%d fh%d: Truncate on forgotten file", f.ino, f.intFd())
}
// Common case first: Truncate to zero
if newSize == 0 {
err := syscall.Ftruncate(int(f.fd.Fd()), 0)
if err != nil {
- cryptfs.Warn.Printf("ino%d fh%d: Ftruncate(fd, 0) returned error: %v", f.ino, f.intFd(), err)
+ toggledlog.Warn.Printf("ino%d fh%d: Ftruncate(fd, 0) returned error: %v", f.ino, f.intFd(), err)
return fuse.ToStatus(err)
}
// Truncate to zero kills the file header
@@ -356,14 +358,14 @@ func (f *file) Truncate(newSize uint64) fuse.Status {
// the file
fi, err := f.fd.Stat()
if err != nil {
- cryptfs.Warn.Printf("ino%d fh%d: Truncate: Fstat failed: %v", f.ino, f.intFd(), err)
+ toggledlog.Warn.Printf("ino%d fh%d: Truncate: Fstat failed: %v", f.ino, f.intFd(), err)
return fuse.ToStatus(err)
}
- oldSize := f.cfs.CipherSizeToPlainSize(uint64(fi.Size()))
+ oldSize := f.contentEnc.CipherSizeToPlainSize(uint64(fi.Size()))
{
- oldB := float32(oldSize) / float32(f.cfs.PlainBS())
- newB := float32(newSize) / float32(f.cfs.PlainBS())
- cryptfs.Debug.Printf("ino%d: FUSE Truncate from %.2f to %.2f blocks (%d to %d bytes)", f.ino, oldB, newB, oldSize, newSize)
+ oldB := float32(oldSize) / float32(f.contentEnc.PlainBS())
+ newB := float32(newSize) / float32(f.contentEnc.PlainBS())
+ toggledlog.Debug.Printf("ino%d: FUSE Truncate from %.2f to %.2f blocks (%d to %d bytes)", f.ino, oldB, newB, oldSize, newSize)
}
// File size stays the same - nothing to do
@@ -382,7 +384,7 @@ func (f *file) Truncate(newSize uint64) fuse.Status {
}
}
- blocks := f.cfs.ExplodePlainRange(oldSize, newSize-oldSize)
+ blocks := f.contentEnc.ExplodePlainRange(oldSize, newSize-oldSize)
for _, b := range blocks {
// First and last block may be partial
if b.IsPartial() {
@@ -396,7 +398,7 @@ func (f *file) Truncate(newSize uint64) fuse.Status {
off, length := b.CiphertextRange()
err := syscall.Ftruncate(int(f.fd.Fd()), int64(off+length))
if err != nil {
- cryptfs.Warn.Printf("grow Ftruncate returned error: %v", err)
+ toggledlog.Warn.Printf("grow Ftruncate returned error: %v", err)
return fuse.ToStatus(err)
}
}
@@ -404,23 +406,23 @@ func (f *file) Truncate(newSize uint64) fuse.Status {
return fuse.OK
} else {
// File shrinks
- blockNo := f.cfs.PlainOffToBlockNo(newSize)
- cipherOff := f.cfs.BlockNoToCipherOff(blockNo)
- plainOff := f.cfs.BlockNoToPlainOff(blockNo)
+ blockNo := f.contentEnc.PlainOffToBlockNo(newSize)
+ cipherOff := f.contentEnc.BlockNoToCipherOff(blockNo)
+ plainOff := f.contentEnc.BlockNoToPlainOff(blockNo)
lastBlockLen := newSize - plainOff
var data []byte
if lastBlockLen > 0 {
var status fuse.Status
data, status = f.doRead(plainOff, lastBlockLen)
if status != fuse.OK {
- cryptfs.Warn.Printf("shrink doRead returned error: %v", err)
+ toggledlog.Warn.Printf("shrink doRead returned error: %v", err)
return status
}
}
// Truncate down to last complete block
err = syscall.Ftruncate(int(f.fd.Fd()), int64(cipherOff))
if err != nil {
- cryptfs.Warn.Printf("shrink Ftruncate returned error: %v", err)
+ toggledlog.Warn.Printf("shrink Ftruncate returned error: %v", err)
return fuse.ToStatus(err)
}
// Append partial block
@@ -450,14 +452,14 @@ func (f *file) GetAttr(a *fuse.Attr) fuse.Status {
f.fdLock.RLock()
defer f.fdLock.RUnlock()
- cryptfs.Debug.Printf("file.GetAttr()")
+ toggledlog.Debug.Printf("file.GetAttr()")
st := syscall.Stat_t{}
err := syscall.Fstat(int(f.fd.Fd()), &st)
if err != nil {
return fuse.ToStatus(err)
}
a.FromStat(&st)
- a.Size = f.cfs.CipherSizeToPlainSize(a.Size)
+ a.Size = f.contentEnc.CipherSizeToPlainSize(a.Size)
return fuse.OK
}
@@ -468,7 +470,7 @@ var allocateWarned bool
func (f *file) Allocate(off uint64, sz uint64, mode uint32) fuse.Status {
// Only warn once
if !allocateWarned {
- cryptfs.Warn.Printf("fallocate(2) is not supported, returning ENOSYS - see https://github.com/rfjakob/gocryptfs/issues/1")
+ toggledlog.Warn.Printf("fallocate(2) is not supported, returning ENOSYS - see https://github.com/rfjakob/gocryptfs/issues/1")
allocateWarned = true
}
return fuse.ENOSYS
diff --git a/pathfs_frontend/file_holes.go b/pathfs_frontend/file_holes.go
index fd2e2c1..a147deb 100644
--- a/pathfs_frontend/file_holes.go
+++ b/pathfs_frontend/file_holes.go
@@ -4,13 +4,14 @@ package pathfs_frontend
import (
"github.com/hanwen/go-fuse/fuse"
- "github.com/rfjakob/gocryptfs/cryptfs"
+
+ "github.com/rfjakob/gocryptfs/internal/toggledlog"
)
// Will a write to offset "off" create a file hole?
func (f *file) createsHole(plainSize uint64, off int64) bool {
- nextBlock := f.cfs.PlainOffToBlockNo(plainSize)
- targetBlock := f.cfs.PlainOffToBlockNo(uint64(off))
+ nextBlock := f.contentEnc.PlainOffToBlockNo(plainSize)
+ targetBlock := f.contentEnc.PlainOffToBlockNo(uint64(off))
if targetBlock > nextBlock {
return true
}
@@ -19,10 +20,10 @@ func (f *file) createsHole(plainSize uint64, off int64) bool {
// Zero-pad the file of size plainSize to the next block boundary
func (f *file) zeroPad(plainSize uint64) fuse.Status {
- lastBlockLen := plainSize % f.cfs.PlainBS()
- missing := f.cfs.PlainBS() - lastBlockLen
+ lastBlockLen := plainSize % f.contentEnc.PlainBS()
+ missing := f.contentEnc.PlainBS() - lastBlockLen
pad := make([]byte, missing)
- cryptfs.Debug.Printf("zeroPad: Writing %d bytes\n", missing)
+ toggledlog.Debug.Printf("zeroPad: Writing %d bytes\n", missing)
_, status := f.doWrite(pad, int64(plainSize))
return status
}
diff --git a/pathfs_frontend/fs.go b/pathfs_frontend/fs.go
index a00985d..212f0a7 100644
--- a/pathfs_frontend/fs.go
+++ b/pathfs_frontend/fs.go
@@ -13,25 +13,41 @@ import (
"github.com/hanwen/go-fuse/fuse"
"github.com/hanwen/go-fuse/fuse/nodefs"
"github.com/hanwen/go-fuse/fuse/pathfs"
- "github.com/rfjakob/gocryptfs/cryptfs"
+
+ "github.com/rfjakob/gocryptfs/internal/toggledlog"
+ "github.com/rfjakob/gocryptfs/internal/cryptocore"
+ "github.com/rfjakob/gocryptfs/internal/nametransform"
+ "github.com/rfjakob/gocryptfs/internal/contentenc"
+ "github.com/rfjakob/gocryptfs/internal/configfile"
)
+const plainBS = 4096
+
type FS struct {
- *cryptfs.CryptFS
pathfs.FileSystem // loopbackFileSystem, see go-fuse/fuse/pathfs/loopback.go
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
dirIVLock sync.RWMutex
+ // Filename encryption helper
+ nameTransform *nametransform.NameTransform
+ // Content encryption helper
+ contentEnc *contentenc.ContentEnc
}
// Encrypted FUSE overlay filesystem
func NewFS(args Args) *FS {
+
+ cryptoCore := cryptocore.New(args.Masterkey, args.OpenSSL, args.GCMIV128)
+ contentEnc := contentenc.New(cryptoCore, plainBS)
+ nameTransform := nametransform.New(cryptoCore, args.EMENames)
+
return &FS{
- CryptFS: cryptfs.NewCryptFS(args.Masterkey, args.OpenSSL, args.PlaintextNames, args.GCMIV128),
FileSystem: pathfs.NewLoopbackFileSystem(args.Cipherdir),
args: args,
+ nameTransform: nameTransform,
+ contentEnc: contentEnc,
}
}
@@ -43,12 +59,12 @@ func (fs *FS) getBackingPath(relPath string) (string, error) {
return "", err
}
cAbsPath := filepath.Join(fs.args.Cipherdir, cPath)
- cryptfs.Debug.Printf("getBackingPath: %s + %s -> %s", fs.args.Cipherdir, relPath, cAbsPath)
+ toggledlog.Debug.Printf("getBackingPath: %s + %s -> %s", fs.args.Cipherdir, relPath, cAbsPath)
return cAbsPath, nil
}
func (fs *FS) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
- cryptfs.Debug.Printf("FS.GetAttr('%s')", name)
+ toggledlog.Debug.Printf("FS.GetAttr('%s')", name)
if fs.isFiltered(name) {
return nil, fuse.EPERM
}
@@ -58,11 +74,11 @@ func (fs *FS) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Stat
}
a, status := fs.FileSystem.GetAttr(cName, context)
if a == nil {
- cryptfs.Debug.Printf("FS.GetAttr failed: %s", status.String())
+ toggledlog.Debug.Printf("FS.GetAttr failed: %s", status.String())
return a, status
}
if a.IsRegular() {
- a.Size = fs.CipherSizeToPlainSize(a.Size)
+ a.Size = fs.contentEnc.CipherSizeToPlainSize(a.Size)
} else if a.IsSymlink() {
target, _ := fs.Readlink(name, context)
a.Size = uint64(len(target))
@@ -71,7 +87,7 @@ func (fs *FS) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Stat
}
func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
- cryptfs.Debug.Printf("OpenDir(%s)", dirName)
+ toggledlog.Debug.Printf("OpenDir(%s)", dirName)
cDirName, err := fs.encryptPath(dirName)
if err != nil {
return nil, fuse.ToStatus(err)
@@ -81,12 +97,12 @@ func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, f
if cipherEntries == nil {
return nil, status
}
- // Get DirIV (stays zero if DirIV if off)
- cachedIV := make([]byte, cryptfs.DIRIV_LEN)
+ // Get DirIV (stays nil if DirIV if off)
+ var cachedIV []byte
if fs.args.DirIV {
// Read the DirIV once and use it for all later name decryptions
cDirAbsPath := filepath.Join(fs.args.Cipherdir, cDirName)
- cachedIV, err = fs.CryptFS.ReadDirIV(cDirAbsPath)
+ cachedIV, err = fs.nameTransform.ReadDirIV(cDirAbsPath)
if err != nil {
return nil, fuse.ToStatus(err)
}
@@ -95,19 +111,19 @@ func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, f
var plain []fuse.DirEntry
for i := range cipherEntries {
cName := cipherEntries[i].Name
- if dirName == "" && cName == cryptfs.ConfDefaultName {
+ if dirName == "" && cName == configfile.ConfDefaultName {
// silently ignore "gocryptfs.conf" in the top level dir
continue
}
- if fs.args.DirIV && cName == cryptfs.DIRIV_FILENAME {
+ if fs.args.DirIV && cName == nametransform.DirIVFilename {
// silently ignore "gocryptfs.diriv" everywhere if dirIV is enabled
continue
}
var name string = cName
if !fs.args.PlaintextNames {
- name, err = fs.CryptFS.DecryptName(cName, cachedIV, fs.args.EMENames)
+ name, err = fs.nameTransform.DecryptName(cName, cachedIV)
if err != nil {
- cryptfs.Warn.Printf("Invalid name \"%s\" in dir \"%s\": %s", cName, cDirName, err)
+ toggledlog.Warn.Printf("Invalid name \"%s\" in dir \"%s\": %s", cName, cDirName, err)
continue
}
}
@@ -137,16 +153,16 @@ func (fs *FS) Open(path string, flags uint32, context *fuse.Context) (fuseFile n
iflags, writeOnly := fs.mangleOpenFlags(flags)
cPath, err := fs.getBackingPath(path)
if err != nil {
- cryptfs.Debug.Printf("Open: getBackingPath: %v", err)
+ toggledlog.Debug.Printf("Open: getBackingPath: %v", err)
return nil, fuse.ToStatus(err)
}
- cryptfs.Debug.Printf("Open: %s", cPath)
+ toggledlog.Debug.Printf("Open: %s", cPath)
f, err := os.OpenFile(cPath, iflags, 0666)
if err != nil {
return nil, fuse.ToStatus(err)
}
- return NewFile(f, writeOnly, fs.CryptFS), fuse.OK
+ return NewFile(f, writeOnly, fs.contentEnc), fuse.OK
}
func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Context) (fuseFile nodefs.File, code fuse.Status) {
@@ -162,7 +178,7 @@ func (fs *FS) Create(path string, flags uint32, mode uint32, context *fuse.Conte
if err != nil {
return nil, fuse.ToStatus(err)
}
- return NewFile(f, writeOnly, fs.CryptFS), fuse.OK
+ return NewFile(f, writeOnly, fs.contentEnc), fuse.OK
}
func (fs *FS) Chmod(path string, mode uint32, context *fuse.Context) (code fuse.Status) {
@@ -203,7 +219,7 @@ var truncateWarned bool
func (fs *FS) Truncate(path string, offset uint64, context *fuse.Context) (code fuse.Status) {
// Only warn once
if !truncateWarned {
- cryptfs.Warn.Printf("truncate(2) is not supported, returning ENOSYS - use ftruncate(2)")
+ toggledlog.Warn.Printf("truncate(2) is not supported, returning ENOSYS - use ftruncate(2)")
truncateWarned = true
}
return fuse.ENOSYS
@@ -233,7 +249,7 @@ func (fs *FS) Readlink(path string, context *fuse.Context) (out string, status f
if !fs.args.DirIV {
target, err := fs.decryptPath(cTarget)
if err != nil {
- cryptfs.Warn.Printf("Readlink: CBC decryption failed: %v", err)
+ toggledlog.Warn.Printf("Readlink: CBC decryption failed: %v", err)
return "", fuse.EIO
}
return target, fuse.OK
@@ -241,12 +257,12 @@ func (fs *FS) Readlink(path string, context *fuse.Context) (out string, status f
// 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", err)
+ toggledlog.Warn.Printf("Readlink: %v", err)
return "", fuse.EIO
}
- target, err := fs.CryptFS.DecryptBlock([]byte(cBinTarget), 0, nil)
+ target, err := fs.contentEnc.DecryptBlock([]byte(cBinTarget), 0, nil)
if err != nil {
- cryptfs.Warn.Printf("Readlink: %v", err)
+ toggledlog.Warn.Printf("Readlink: %v", err)
return "", fuse.EIO
}
return string(target), fuse.OK
@@ -264,7 +280,7 @@ func (fs *FS) Unlink(path string, context *fuse.Context) (code fuse.Status) {
}
func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (code fuse.Status) {
- cryptfs.Debug.Printf("Symlink(\"%s\", \"%s\")", target, linkName)
+ toggledlog.Debug.Printf("Symlink(\"%s\", \"%s\")", target, linkName)
if fs.isFiltered(linkName) {
return fuse.EPERM
}
@@ -276,18 +292,18 @@ func (fs *FS) Symlink(target string, linkName string, context *fuse.Context) (co
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", err)
+ toggledlog.Warn.Printf("Symlink: BUG: we should not get an error here: %v", 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)
+ cBinTarget := fs.contentEnc.EncryptBlock([]byte(target), 0, nil)
cTarget := base64.URLEncoding.EncodeToString(cBinTarget)
err = os.Symlink(cTarget, cPath)
- cryptfs.Debug.Printf("Symlink: os.Symlink(%s, %s) = %v", cTarget, cPath, err)
+ toggledlog.Debug.Printf("Symlink: os.Symlink(%s, %s) = %v", cTarget, cPath, err)
return fuse.ToStatus(err)
}
@@ -305,7 +321,7 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod
}
// The Rename may cause a directory to take the place of another directory.
// That directory may still be in the DirIV cache, clear it.
- fs.CryptFS.DirIVCache.Clear()
+ fs.nameTransform.DirIVCache.Clear()
err = os.Rename(cOldPath, cNewPath)
@@ -313,7 +329,7 @@ func (fs *FS) Rename(oldPath string, newPath string, context *fuse.Context) (cod
// If an empty directory is overwritten we will always get
// ENOTEMPTY as the "empty" directory will still contain gocryptfs.diriv.
// Handle that case by removing the target directory and trying again.
- cryptfs.Debug.Printf("Rename: Handling ENOTEMPTY")
+ toggledlog.Debug.Printf("Rename: Handling ENOTEMPTY")
if fs.Rmdir(newPath, context) == fuse.OK {
err = os.Rename(cOldPath, cNewPath)
}
diff --git a/pathfs_frontend/fs_dir.go b/pathfs_frontend/fs_dir.go
index b1edd73..d378d28 100644
--- a/pathfs_frontend/fs_dir.go
+++ b/pathfs_frontend/fs_dir.go
@@ -9,7 +9,10 @@ import (
"syscall"
"github.com/hanwen/go-fuse/fuse"
- "github.com/rfjakob/gocryptfs/cryptfs"
+
+ "github.com/rfjakob/gocryptfs/internal/toggledlog"
+ "github.com/rfjakob/gocryptfs/internal/cryptocore"
+ "github.com/rfjakob/gocryptfs/internal/nametransform"
)
func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fuse.Status) {
@@ -29,7 +32,7 @@ func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fu
mode = mode | 0300
// The new directory may take the place of an older one that is still in the cache
- fs.CryptFS.DirIVCache.Clear()
+ fs.nameTransform.DirIVCache.Clear()
// Create directory
fs.dirIVLock.Lock()
defer fs.dirIVLock.Unlock()
@@ -38,13 +41,13 @@ func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fu
return fuse.ToStatus(err)
}
// Create gocryptfs.diriv inside
- err = cryptfs.WriteDirIV(encPath)
+ err = nametransform.WriteDirIV(encPath)
if err != nil {
// This should not happen
- cryptfs.Warn.Printf("Mkdir: WriteDirIV failed: %v", err)
+ toggledlog.Warn.Printf("Mkdir: WriteDirIV failed: %v", err)
err2 := syscall.Rmdir(encPath)
if err2 != nil {
- cryptfs.Warn.Printf("Mkdir: Rmdir rollback failed: %v", err2)
+ toggledlog.Warn.Printf("Mkdir: Rmdir rollback failed: %v", err2)
}
return fuse.ToStatus(err)
}
@@ -53,7 +56,7 @@ func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fu
if origMode != mode {
err = os.Chmod(encPath, os.FileMode(origMode))
if err != nil {
- cryptfs.Warn.Printf("Mkdir: Chmod failed: %v", err)
+ toggledlog.Warn.Printf("Mkdir: Chmod failed: %v", err)
}
}
@@ -74,17 +77,17 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
fd, err := os.Open(encPath)
if perr, ok := err.(*os.PathError); ok && perr.Err == syscall.EACCES {
// We need permission to read and modify the directory
- cryptfs.Debug.Printf("Rmdir: handling EACCESS")
+ toggledlog.Debug.Printf("Rmdir: handling EACCESS")
fi, err2 := os.Stat(encPath)
if err2 != nil {
- cryptfs.Debug.Printf("Rmdir: Stat: %v", err2)
+ toggledlog.Debug.Printf("Rmdir: Stat: %v", err2)
return fuse.ToStatus(err2)
}
origMode := fi.Mode()
newMode := origMode | 0700
err2 = os.Chmod(encPath, newMode)
if err2 != nil {
- cryptfs.Debug.Printf("Rmdir: Chmod failed: %v", err2)
+ toggledlog.Debug.Printf("Rmdir: Chmod failed: %v", err2)
return fuse.ToStatus(err)
}
defer func() {
@@ -92,7 +95,7 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
// Undo the chmod if removing the directory failed
err3 := os.Chmod(encPath, origMode)
if err3 != nil {
- cryptfs.Warn.Printf("Rmdir: Chmod rollback failed: %v", err2)
+ toggledlog.Warn.Printf("Rmdir: Chmod rollback failed: %v", err2)
}
}
}()
@@ -100,35 +103,36 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
fd, err = os.Open(encPath)
}
if err != nil {
- cryptfs.Debug.Printf("Rmdir: Open: %v", err)
+ toggledlog.Debug.Printf("Rmdir: Open: %v", err)
return fuse.ToStatus(err)
}
list, err := fd.Readdirnames(10)
fd.Close()
if err != nil {
- cryptfs.Debug.Printf("Rmdir: Readdirnames: %v", err)
+ toggledlog.Debug.Printf("Rmdir: Readdirnames: %v", err)
return fuse.ToStatus(err)
}
if len(list) > 1 {
return fuse.ToStatus(syscall.ENOTEMPTY)
} else if len(list) == 0 {
- cryptfs.Warn.Printf("Rmdir: gocryptfs.diriv missing, allowing deletion")
+ toggledlog.Warn.Printf("Rmdir: gocryptfs.diriv missing, allowing deletion")
return fuse.ToStatus(syscall.Rmdir(encPath))
}
// Move "gocryptfs.diriv" to the parent dir as "gocryptfs.diriv.rmdir.XYZ"
- dirivPath := filepath.Join(encPath, cryptfs.DIRIV_FILENAME)
+ dirivPath := filepath.Join(encPath, nametransform.DirIVFilename)
parentDir := filepath.Dir(encPath)
- tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", cryptfs.RandUint64())
+ tmpName := fmt.Sprintf("gocryptfs.diriv.rmdir.%d", cryptocore.RandUint64())
tmpDirivPath := filepath.Join(parentDir, tmpName)
- cryptfs.Debug.Printf("Rmdir: Renaming %s to %s", cryptfs.DIRIV_FILENAME, tmpDirivPath)
+ toggledlog.Debug.Printf("Rmdir: Renaming %s to %s", nametransform.DirIVFilename, tmpDirivPath)
// The directory is in an inconsistent state between rename and rmdir. Protect against
// concurrent readers.
fs.dirIVLock.Lock()
defer fs.dirIVLock.Unlock()
err = os.Rename(dirivPath, tmpDirivPath)
if err != nil {
- cryptfs.Warn.Printf("Rmdir: Renaming %s to %s failed: %v", cryptfs.DIRIV_FILENAME, tmpDirivPath, err)
+ toggledlog.Warn.Printf("Rmdir: Renaming %s to %s failed: %v",
+ nametransform.DirIVFilename, tmpDirivPath, err)
return fuse.ToStatus(err)
}
// Actual Rmdir
@@ -138,16 +142,16 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
// meantime, undo the rename
err2 := os.Rename(tmpDirivPath, dirivPath)
if err2 != nil {
- cryptfs.Warn.Printf("Rmdir: Rename rollback failed: %v", err2)
+ toggledlog.Warn.Printf("Rmdir: Rename rollback failed: %v", err2)
}
return fuse.ToStatus(err)
}
// Delete "gocryptfs.diriv.rmdir.INODENUMBER"
err = syscall.Unlink(tmpDirivPath)
if err != nil {
- cryptfs.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)
+ toggledlog.Warn.Printf("Rmdir: Could not clean up %s: %v", tmpName, err)
}
// The now-deleted directory may have been in the DirIV cache. Clear it.
- fs.CryptFS.DirIVCache.Clear()
+ fs.nameTransform.DirIVCache.Clear()
return fuse.OK
}
diff --git a/pathfs_frontend/names.go b/pathfs_frontend/names.go
index bd7a249..160fa0a 100644
--- a/pathfs_frontend/names.go
+++ b/pathfs_frontend/names.go
@@ -3,7 +3,8 @@ package pathfs_frontend
// This file forwards file encryption operations to cryptfs
import (
- "github.com/rfjakob/gocryptfs/cryptfs"
+ "github.com/rfjakob/gocryptfs/internal/configfile"
+ mylog "github.com/rfjakob/gocryptfs/internal/toggledlog"
)
// isFiltered - check if plaintext "path" should be forbidden
@@ -14,9 +15,9 @@ func (fs *FS) isFiltered(path string) bool {
return false
}
// gocryptfs.conf in the root directory is forbidden
- if path == cryptfs.ConfDefaultName {
- cryptfs.Info.Printf("The name /%s is reserved when -plaintextnames is used\n",
- cryptfs.ConfDefaultName)
+ if path == configfile.ConfDefaultName {
+ mylog.Info.Printf("The name /%s is reserved when -plaintextnames is used\n",
+ configfile.ConfDefaultName)
return true
}
// Note: gocryptfs.diriv is NOT forbidden because diriv and plaintextnames
@@ -30,11 +31,11 @@ func (fs *FS) encryptPath(plainPath string) (string, error) {
return plainPath, nil
}
if !fs.args.DirIV {
- return fs.CryptFS.EncryptPathNoIV(plainPath), nil
+ return fs.nameTransform.EncryptPathNoIV(plainPath), nil
}
fs.dirIVLock.RLock()
defer fs.dirIVLock.RUnlock()
- return fs.CryptFS.EncryptPathDirIV(plainPath, fs.args.Cipherdir, fs.args.EMENames)
+ return fs.nameTransform.EncryptPathDirIV(plainPath, fs.args.Cipherdir)
}
// decryptPath - decrypt relative ciphertext path
@@ -43,9 +44,9 @@ func (fs *FS) decryptPath(cipherPath string) (string, error) {
return cipherPath, nil
}
if !fs.args.DirIV {
- return fs.CryptFS.DecryptPathNoIV(cipherPath)
+ return fs.nameTransform.DecryptPathNoIV(cipherPath)
}
fs.dirIVLock.RLock()
defer fs.dirIVLock.RUnlock()
- return fs.CryptFS.DecryptPathDirIV(cipherPath, fs.args.Cipherdir, fs.args.EMENames)
+ return fs.nameTransform.DecryptPathDirIV(cipherPath, fs.args.Cipherdir, fs.args.EMENames)
}