Skip to content

Commit 719693e

Browse files
committed
fusefrontend[_reverse]: move crypto init up to caller
Both fusefrontend and fusefrontend_reverse were doing essentially the same thing, move it into main's initFuseFrontend. A side-effect is that we have a reference to cryptocore in main, which will help with wiping the keys on exit (#211).
1 parent eeed4b4 commit 719693e

File tree

4 files changed

+32
-48
lines changed

4 files changed

+32
-48
lines changed

internal/fusefrontend/args.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@ package fusefrontend
22

33
import (
44
"github.com/hanwen/go-fuse/fuse"
5-
"github.com/rfjakob/gocryptfs/internal/cryptocore"
65
)
76

87
// Args is a container for arguments that are passed from main() to fusefrontend
98
type Args struct {
109
// Cipherdir is the backing storage directory (absolute path).
1110
// For reverse mode, Cipherdir actually contains *plaintext* files.
1211
Cipherdir string
13-
CryptoBackend cryptocore.AEADTypeEnum
1412
PlaintextNames bool
1513
LongNames bool
1614
// Should we chown a file after it has been created?
@@ -26,15 +24,8 @@ type Args struct {
2624
// location. If it is false, reverse mode maps ".gocryptfs.reverse.conf"
2725
// to "gocryptfs.conf" in the plaintext dir.
2826
ConfigCustom bool
29-
// Raw64 is true when RawURLEncoding (without padding) should be used for
30-
// file names.
31-
// Corresponds to the Raw64 feature flag introduced in gocryptfs v1.2.
32-
Raw64 bool
3327
// NoPrealloc disables automatic preallocation before writing
3428
NoPrealloc bool
35-
// Use HKDF key derivation.
36-
// Corresponds to the HKDF feature flag introduced in gocryptfs v1.3.
37-
HKDF bool
3829
// Try to serialize read operations, "-serialize_reads"
3930
SerializeReads bool
4031
// Force decode even if integrity check fails (openSSL only)

internal/fusefrontend/fs.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import (
1717
"github.com/hanwen/go-fuse/fuse/pathfs"
1818

1919
"github.com/rfjakob/gocryptfs/internal/contentenc"
20-
"github.com/rfjakob/gocryptfs/internal/cryptocore"
2120
"github.com/rfjakob/gocryptfs/internal/nametransform"
2221
"github.com/rfjakob/gocryptfs/internal/serialize_reads"
2322
"github.com/rfjakob/gocryptfs/internal/syscallcompat"
@@ -44,20 +43,15 @@ type FS struct {
4443
var _ pathfs.FileSystem = &FS{} // Verify that interface is implemented.
4544

4645
// NewFS returns a new encrypted FUSE overlay filesystem.
47-
func NewFS(masterkey []byte, args Args) *FS {
48-
cryptoCore := cryptocore.New(masterkey, args.CryptoBackend, contentenc.DefaultIVBits, args.HKDF, args.ForceDecode)
49-
contentEnc := contentenc.New(cryptoCore, contentenc.DefaultBS, args.ForceDecode)
50-
nameTransform := nametransform.New(cryptoCore.EMECipher, args.LongNames, args.Raw64)
51-
46+
func NewFS(args Args, c *contentenc.ContentEnc, n *nametransform.NameTransform) *FS {
5247
if args.SerializeReads {
5348
serialize_reads.InitSerializer()
5449
}
55-
5650
return &FS{
5751
FileSystem: pathfs.NewLoopbackFileSystem(args.Cipherdir),
5852
args: args,
59-
nameTransform: nameTransform,
60-
contentEnc: contentEnc,
53+
nameTransform: n,
54+
contentEnc: c,
6155
}
6256
}
6357

internal/fusefrontend_reverse/rfs.go

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package fusefrontend_reverse
22

33
import (
44
"fmt"
5-
"log"
65
"path/filepath"
76
"syscall"
87

@@ -42,22 +41,15 @@ var _ pathfs.FileSystem = &ReverseFS{}
4241
// NewFS returns an encrypted FUSE overlay filesystem.
4342
// In this case (reverse mode) the backing directory is plain-text and
4443
// ReverseFS provides an encrypted view.
45-
func NewFS(masterkey []byte, args fusefrontend.Args) *ReverseFS {
46-
if args.CryptoBackend != cryptocore.BackendAESSIV {
47-
log.Panic("reverse mode must use AES-SIV, everything else is insecure")
48-
}
44+
func NewFS(args fusefrontend.Args, c *contentenc.ContentEnc, n *nametransform.NameTransform) *ReverseFS {
4945
initLongnameCache()
50-
cryptoCore := cryptocore.New(masterkey, args.CryptoBackend, contentenc.DefaultIVBits, args.HKDF, false)
51-
contentEnc := contentenc.New(cryptoCore, contentenc.DefaultBS, false)
52-
nameTransform := nametransform.New(cryptoCore.EMECipher, args.LongNames, args.Raw64)
53-
5446
return &ReverseFS{
5547
// pathfs.defaultFileSystem returns ENOSYS for all operations
5648
FileSystem: pathfs.NewDefaultFileSystem(),
5749
loopbackfs: pathfs.NewLoopbackFileSystem(args.Cipherdir),
5850
args: args,
59-
nameTransform: nameTransform,
60-
contentEnc: contentEnc,
51+
nameTransform: n,
52+
contentEnc: c,
6153
}
6254
}
6355

mount.go

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"encoding/json"
55
"fmt"
6+
"log"
67
"log/syslog"
78
"net"
89
"os"
@@ -21,11 +22,13 @@ import (
2122
"github.com/hanwen/go-fuse/fuse/pathfs"
2223

2324
"github.com/rfjakob/gocryptfs/internal/configfile"
25+
"github.com/rfjakob/gocryptfs/internal/contentenc"
2426
"github.com/rfjakob/gocryptfs/internal/cryptocore"
2527
"github.com/rfjakob/gocryptfs/internal/ctlsock"
2628
"github.com/rfjakob/gocryptfs/internal/exitcodes"
2729
"github.com/rfjakob/gocryptfs/internal/fusefrontend"
2830
"github.com/rfjakob/gocryptfs/internal/fusefrontend_reverse"
31+
"github.com/rfjakob/gocryptfs/internal/nametransform"
2932
"github.com/rfjakob/gocryptfs/internal/readpassword"
3033
"github.com/rfjakob/gocryptfs/internal/tlog"
3134
)
@@ -182,6 +185,13 @@ func setOpenFileLimit() {
182185
}
183186
}
184187

188+
// ctlsockFs satisfies both the pathfs.FileSystem and the ctlsock.Interface
189+
// interfaces
190+
type ctlsockFs interface {
191+
pathfs.FileSystem
192+
ctlsock.Interface
193+
}
194+
185195
// initFuseFrontend - initialize gocryptfs/fusefrontend
186196
// Calls os.Exit on errors
187197
func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile.ConfFile) *fuse.Server {
@@ -203,11 +213,8 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile
203213
Cipherdir: args.cipherdir,
204214
PlaintextNames: args.plaintextnames,
205215
LongNames: args.longnames,
206-
CryptoBackend: cryptoBackend,
207216
ConfigCustom: args._configCustom,
208-
Raw64: args.raw64,
209217
NoPrealloc: args.noprealloc,
210-
HKDF: args.hkdf,
211218
SerializeReads: args.serialize_reads,
212219
ForceDecode: args.forcedecode,
213220
ForceOwner: args._forceOwner,
@@ -216,10 +223,10 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile
216223
if confFile != nil {
217224
// Settings from the config file override command line args
218225
frontendArgs.PlaintextNames = confFile.IsFeatureFlagSet(configfile.FlagPlaintextNames)
219-
frontendArgs.Raw64 = confFile.IsFeatureFlagSet(configfile.FlagRaw64)
220-
frontendArgs.HKDF = confFile.IsFeatureFlagSet(configfile.FlagHKDF)
226+
args.raw64 = confFile.IsFeatureFlagSet(configfile.FlagRaw64)
227+
args.hkdf = confFile.IsFeatureFlagSet(configfile.FlagHKDF)
221228
if confFile.IsFeatureFlagSet(configfile.FlagAESSIV) {
222-
frontendArgs.CryptoBackend = cryptocore.BackendAESSIV
229+
cryptoBackend = cryptocore.BackendAESSIV
223230
} else if args.reverse {
224231
tlog.Fatal.Printf("AES-SIV is required by reverse mode, but not enabled in the config file")
225232
os.Exit(exitcodes.Usage)
@@ -232,8 +239,6 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile
232239
}
233240
jsonBytes, _ := json.MarshalIndent(frontendArgs, "", "\t")
234241
tlog.Debug.Printf("frontendArgs: %s", string(jsonBytes))
235-
var finalFs pathfs.FileSystem
236-
var ctlSockBackend ctlsock.Interface
237242
// pathFsOpts are passed into go-fuse/pathfs
238243
pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}
239244
if args.sharedstorage {
@@ -242,21 +247,23 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile
242247
// https://github.com/rfjakob/gocryptfs/issues/156
243248
pathFsOpts.ClientInodes = false
244249
}
250+
// Init crypto backend
251+
cCore := cryptocore.New(masterkey, cryptoBackend, contentenc.DefaultIVBits, args.hkdf, args.forcedecode)
252+
cEnc := contentenc.New(cCore, contentenc.DefaultBS, args.forcedecode)
253+
nameTransform := nametransform.New(cCore.EMECipher, frontendArgs.LongNames, args.raw64)
254+
// Spawn fusefrontend
255+
var fs ctlsockFs
245256
if args.reverse {
246-
// The dance with the intermediate variables is because we need to
247-
// cast the FS into pathfs.FileSystem *and* ctlsock.Interface. This
248-
// avoids using interface{}.
249-
fs := fusefrontend_reverse.NewFS(masterkey, frontendArgs)
250-
finalFs = fs
251-
ctlSockBackend = fs
257+
if cryptoBackend != cryptocore.BackendAESSIV {
258+
log.Panic("reverse mode must use AES-SIV, everything else is insecure")
259+
}
260+
fs = fusefrontend_reverse.NewFS(frontendArgs, cEnc, nameTransform)
252261
// Reverse mode is read-only, so we don't need a working link().
253262
// Disable hard link tracking to avoid strange breakage on duplicate
254263
// inode numbers ( https://github.com/rfjakob/gocryptfs/issues/149 ).
255264
pathFsOpts.ClientInodes = false
256265
} else {
257-
fs := fusefrontend.NewFS(masterkey, frontendArgs)
258-
finalFs = fs
259-
ctlSockBackend = fs
266+
fs = fusefrontend.NewFS(frontendArgs, cEnc, nameTransform)
260267
}
261268
// fusefrontend / fusefrontend_reverse have initialized their crypto with
262269
// derived keys (HKDF), we can purge the master key from memory.
@@ -266,9 +273,9 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile
266273
// We have opened the socket early so that we cannot fail here after
267274
// asking the user for the password
268275
if args._ctlsockFd != nil {
269-
go ctlsock.Serve(args._ctlsockFd, ctlSockBackend)
276+
go ctlsock.Serve(args._ctlsockFd, fs)
270277
}
271-
pathFs := pathfs.NewPathNodeFs(finalFs, pathFsOpts)
278+
pathFs := pathfs.NewPathNodeFs(fs, pathFsOpts)
272279
var fuseOpts *nodefs.Options
273280
if args.sharedstorage {
274281
// sharedstorage mode sets all cache timeouts to zero so changes to the

0 commit comments

Comments
 (0)