diff options
| -rw-r--r-- | internal/fusefrontend/args.go | 9 | ||||
| -rw-r--r-- | internal/fusefrontend/fs.go | 12 | ||||
| -rw-r--r-- | internal/fusefrontend_reverse/rfs.go | 14 | ||||
| -rw-r--r-- | mount.go | 45 | 
4 files changed, 32 insertions, 48 deletions
| diff --git a/internal/fusefrontend/args.go b/internal/fusefrontend/args.go index fc9de73..8a64e99 100644 --- a/internal/fusefrontend/args.go +++ b/internal/fusefrontend/args.go @@ -2,7 +2,6 @@ package fusefrontend  import (  	"github.com/hanwen/go-fuse/fuse" -	"github.com/rfjakob/gocryptfs/internal/cryptocore"  )  // Args is a container for arguments that are passed from main() to fusefrontend @@ -10,7 +9,6 @@ type Args struct {  	// Cipherdir is the backing storage directory (absolute path).  	// For reverse mode, Cipherdir actually contains *plaintext* files.  	Cipherdir      string -	CryptoBackend  cryptocore.AEADTypeEnum  	PlaintextNames bool  	LongNames      bool  	// Should we chown a file after it has been created? @@ -26,15 +24,8 @@ type Args struct {  	// location. If it is false, reverse mode maps ".gocryptfs.reverse.conf"  	// to "gocryptfs.conf" in the plaintext dir.  	ConfigCustom bool -	// Raw64 is true when RawURLEncoding (without padding) should be used for -	// file names. -	// Corresponds to the Raw64 feature flag introduced in gocryptfs v1.2. -	Raw64 bool  	// NoPrealloc disables automatic preallocation before writing  	NoPrealloc bool -	// Use HKDF key derivation. -	// Corresponds to the HKDF feature flag introduced in gocryptfs v1.3. -	HKDF bool  	// Try to serialize read operations, "-serialize_reads"  	SerializeReads bool  	// Force decode even if integrity check fails (openSSL only) diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go index 8b0bb2e..b09ed83 100644 --- a/internal/fusefrontend/fs.go +++ b/internal/fusefrontend/fs.go @@ -17,7 +17,6 @@ import (  	"github.com/hanwen/go-fuse/fuse/pathfs"  	"github.com/rfjakob/gocryptfs/internal/contentenc" -	"github.com/rfjakob/gocryptfs/internal/cryptocore"  	"github.com/rfjakob/gocryptfs/internal/nametransform"  	"github.com/rfjakob/gocryptfs/internal/serialize_reads"  	"github.com/rfjakob/gocryptfs/internal/syscallcompat" @@ -44,20 +43,15 @@ type FS struct {  var _ pathfs.FileSystem = &FS{} // Verify that interface is implemented.  // NewFS returns a new encrypted FUSE overlay filesystem. -func NewFS(masterkey []byte, args Args) *FS { -	cryptoCore := cryptocore.New(masterkey, args.CryptoBackend, contentenc.DefaultIVBits, args.HKDF, args.ForceDecode) -	contentEnc := contentenc.New(cryptoCore, contentenc.DefaultBS, args.ForceDecode) -	nameTransform := nametransform.New(cryptoCore.EMECipher, args.LongNames, args.Raw64) - +func NewFS(args Args, c *contentenc.ContentEnc, n *nametransform.NameTransform) *FS {  	if args.SerializeReads {  		serialize_reads.InitSerializer()  	} -  	return &FS{  		FileSystem:    pathfs.NewLoopbackFileSystem(args.Cipherdir),  		args:          args, -		nameTransform: nameTransform, -		contentEnc:    contentEnc, +		nameTransform: n, +		contentEnc:    c,  	}  } diff --git a/internal/fusefrontend_reverse/rfs.go b/internal/fusefrontend_reverse/rfs.go index 1523c18..b281c76 100644 --- a/internal/fusefrontend_reverse/rfs.go +++ b/internal/fusefrontend_reverse/rfs.go @@ -2,7 +2,6 @@ package fusefrontend_reverse  import (  	"fmt" -	"log"  	"path/filepath"  	"syscall" @@ -42,22 +41,15 @@ var _ pathfs.FileSystem = &ReverseFS{}  // NewFS returns an encrypted FUSE overlay filesystem.  // In this case (reverse mode) the backing directory is plain-text and  // ReverseFS provides an encrypted view. -func NewFS(masterkey []byte, args fusefrontend.Args) *ReverseFS { -	if args.CryptoBackend != cryptocore.BackendAESSIV { -		log.Panic("reverse mode must use AES-SIV, everything else is insecure") -	} +func NewFS(args fusefrontend.Args, c *contentenc.ContentEnc, n *nametransform.NameTransform) *ReverseFS {  	initLongnameCache() -	cryptoCore := cryptocore.New(masterkey, args.CryptoBackend, contentenc.DefaultIVBits, args.HKDF, false) -	contentEnc := contentenc.New(cryptoCore, contentenc.DefaultBS, false) -	nameTransform := nametransform.New(cryptoCore.EMECipher, args.LongNames, args.Raw64) -  	return &ReverseFS{  		// pathfs.defaultFileSystem returns ENOSYS for all operations  		FileSystem:    pathfs.NewDefaultFileSystem(),  		loopbackfs:    pathfs.NewLoopbackFileSystem(args.Cipherdir),  		args:          args, -		nameTransform: nameTransform, -		contentEnc:    contentEnc, +		nameTransform: n, +		contentEnc:    c,  	}  } @@ -3,6 +3,7 @@ package main  import (  	"encoding/json"  	"fmt" +	"log"  	"log/syslog"  	"net"  	"os" @@ -21,11 +22,13 @@ import (  	"github.com/hanwen/go-fuse/fuse/pathfs"  	"github.com/rfjakob/gocryptfs/internal/configfile" +	"github.com/rfjakob/gocryptfs/internal/contentenc"  	"github.com/rfjakob/gocryptfs/internal/cryptocore"  	"github.com/rfjakob/gocryptfs/internal/ctlsock"  	"github.com/rfjakob/gocryptfs/internal/exitcodes"  	"github.com/rfjakob/gocryptfs/internal/fusefrontend"  	"github.com/rfjakob/gocryptfs/internal/fusefrontend_reverse" +	"github.com/rfjakob/gocryptfs/internal/nametransform"  	"github.com/rfjakob/gocryptfs/internal/readpassword"  	"github.com/rfjakob/gocryptfs/internal/tlog"  ) @@ -182,6 +185,13 @@ func setOpenFileLimit() {  	}  } +// ctlsockFs satisfies both the pathfs.FileSystem and the ctlsock.Interface +// interfaces +type ctlsockFs interface { +	pathfs.FileSystem +	ctlsock.Interface +} +  // initFuseFrontend - initialize gocryptfs/fusefrontend  // Calls os.Exit on errors  func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile.ConfFile) *fuse.Server { @@ -203,11 +213,8 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile  		Cipherdir:      args.cipherdir,  		PlaintextNames: args.plaintextnames,  		LongNames:      args.longnames, -		CryptoBackend:  cryptoBackend,  		ConfigCustom:   args._configCustom, -		Raw64:          args.raw64,  		NoPrealloc:     args.noprealloc, -		HKDF:           args.hkdf,  		SerializeReads: args.serialize_reads,  		ForceDecode:    args.forcedecode,  		ForceOwner:     args._forceOwner, @@ -216,10 +223,10 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile  	if confFile != nil {  		// Settings from the config file override command line args  		frontendArgs.PlaintextNames = confFile.IsFeatureFlagSet(configfile.FlagPlaintextNames) -		frontendArgs.Raw64 = confFile.IsFeatureFlagSet(configfile.FlagRaw64) -		frontendArgs.HKDF = confFile.IsFeatureFlagSet(configfile.FlagHKDF) +		args.raw64 = confFile.IsFeatureFlagSet(configfile.FlagRaw64) +		args.hkdf = confFile.IsFeatureFlagSet(configfile.FlagHKDF)  		if confFile.IsFeatureFlagSet(configfile.FlagAESSIV) { -			frontendArgs.CryptoBackend = cryptocore.BackendAESSIV +			cryptoBackend = cryptocore.BackendAESSIV  		} else if args.reverse {  			tlog.Fatal.Printf("AES-SIV is required by reverse mode, but not enabled in the config file")  			os.Exit(exitcodes.Usage) @@ -232,8 +239,6 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile  	}  	jsonBytes, _ := json.MarshalIndent(frontendArgs, "", "\t")  	tlog.Debug.Printf("frontendArgs: %s", string(jsonBytes)) -	var finalFs pathfs.FileSystem -	var ctlSockBackend ctlsock.Interface  	// pathFsOpts are passed into go-fuse/pathfs  	pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}  	if args.sharedstorage { @@ -242,21 +247,23 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile  		// https://github.com/rfjakob/gocryptfs/issues/156  		pathFsOpts.ClientInodes = false  	} +	// Init crypto backend +	cCore := cryptocore.New(masterkey, cryptoBackend, contentenc.DefaultIVBits, args.hkdf, args.forcedecode) +	cEnc := contentenc.New(cCore, contentenc.DefaultBS, args.forcedecode) +	nameTransform := nametransform.New(cCore.EMECipher, frontendArgs.LongNames, args.raw64) +	// Spawn fusefrontend +	var fs ctlsockFs  	if args.reverse { -		// The dance with the intermediate variables is because we need to -		// cast the FS into pathfs.FileSystem *and* ctlsock.Interface. This -		// avoids using interface{}. -		fs := fusefrontend_reverse.NewFS(masterkey, frontendArgs) -		finalFs = fs -		ctlSockBackend = fs +		if cryptoBackend != cryptocore.BackendAESSIV { +			log.Panic("reverse mode must use AES-SIV, everything else is insecure") +		} +		fs = fusefrontend_reverse.NewFS(frontendArgs, cEnc, nameTransform)  		// Reverse mode is read-only, so we don't need a working link().  		// Disable hard link tracking to avoid strange breakage on duplicate  		// inode numbers ( https://github.com/rfjakob/gocryptfs/issues/149 ).  		pathFsOpts.ClientInodes = false  	} else { -		fs := fusefrontend.NewFS(masterkey, frontendArgs) -		finalFs = fs -		ctlSockBackend = fs +		fs = fusefrontend.NewFS(frontendArgs, cEnc, nameTransform)  	}  	// fusefrontend / fusefrontend_reverse have initialized their crypto with  	// derived keys (HKDF), we can purge the master key from memory. @@ -266,9 +273,9 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile  	// We have opened the socket early so that we cannot fail here after  	// asking the user for the password  	if args._ctlsockFd != nil { -		go ctlsock.Serve(args._ctlsockFd, ctlSockBackend) +		go ctlsock.Serve(args._ctlsockFd, fs)  	} -	pathFs := pathfs.NewPathNodeFs(finalFs, pathFsOpts) +	pathFs := pathfs.NewPathNodeFs(fs, pathFsOpts)  	var fuseOpts *nodefs.Options  	if args.sharedstorage {  		// sharedstorage mode sets all cache timeouts to zero so changes to the | 
