Skip to content

Commit f1b0234

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 f1b0234

File tree

4 files changed

+28
-48
lines changed

4 files changed

+28
-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: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@ import (
2121
"github.com/hanwen/go-fuse/fuse/pathfs"
2222

2323
"github.com/rfjakob/gocryptfs/internal/configfile"
24+
"github.com/rfjakob/gocryptfs/internal/contentenc"
2425
"github.com/rfjakob/gocryptfs/internal/cryptocore"
2526
"github.com/rfjakob/gocryptfs/internal/ctlsock"
2627
"github.com/rfjakob/gocryptfs/internal/exitcodes"
2728
"github.com/rfjakob/gocryptfs/internal/fusefrontend"
2829
"github.com/rfjakob/gocryptfs/internal/fusefrontend_reverse"
30+
"github.com/rfjakob/gocryptfs/internal/nametransform"
2931
"github.com/rfjakob/gocryptfs/internal/readpassword"
3032
"github.com/rfjakob/gocryptfs/internal/tlog"
3133
)
@@ -182,6 +184,13 @@ func setOpenFileLimit() {
182184
}
183185
}
184186

187+
// ctlsockFs satisfies both the pathfs.FileSystem and the ctlsock.Interface
188+
// interfaces
189+
type ctlsockFs interface {
190+
pathfs.FileSystem
191+
ctlsock.Interface
192+
}
193+
185194
// initFuseFrontend - initialize gocryptfs/fusefrontend
186195
// Calls os.Exit on errors
187196
func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile.ConfFile) *fuse.Server {
@@ -203,11 +212,8 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile
203212
Cipherdir: args.cipherdir,
204213
PlaintextNames: args.plaintextnames,
205214
LongNames: args.longnames,
206-
CryptoBackend: cryptoBackend,
207215
ConfigCustom: args._configCustom,
208-
Raw64: args.raw64,
209216
NoPrealloc: args.noprealloc,
210-
HKDF: args.hkdf,
211217
SerializeReads: args.serialize_reads,
212218
ForceDecode: args.forcedecode,
213219
ForceOwner: args._forceOwner,
@@ -216,10 +222,10 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile
216222
if confFile != nil {
217223
// Settings from the config file override command line args
218224
frontendArgs.PlaintextNames = confFile.IsFeatureFlagSet(configfile.FlagPlaintextNames)
219-
frontendArgs.Raw64 = confFile.IsFeatureFlagSet(configfile.FlagRaw64)
220-
frontendArgs.HKDF = confFile.IsFeatureFlagSet(configfile.FlagHKDF)
225+
args.raw64 = confFile.IsFeatureFlagSet(configfile.FlagRaw64)
226+
args.hkdf = confFile.IsFeatureFlagSet(configfile.FlagHKDF)
221227
if confFile.IsFeatureFlagSet(configfile.FlagAESSIV) {
222-
frontendArgs.CryptoBackend = cryptocore.BackendAESSIV
228+
cryptoBackend = cryptocore.BackendAESSIV
223229
} else if args.reverse {
224230
tlog.Fatal.Printf("AES-SIV is required by reverse mode, but not enabled in the config file")
225231
os.Exit(exitcodes.Usage)
@@ -232,8 +238,6 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile
232238
}
233239
jsonBytes, _ := json.MarshalIndent(frontendArgs, "", "\t")
234240
tlog.Debug.Printf("frontendArgs: %s", string(jsonBytes))
235-
var finalFs pathfs.FileSystem
236-
var ctlSockBackend ctlsock.Interface
237241
// pathFsOpts are passed into go-fuse/pathfs
238242
pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}
239243
if args.sharedstorage {
@@ -242,21 +246,20 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile
242246
// https://github.com/rfjakob/gocryptfs/issues/156
243247
pathFsOpts.ClientInodes = false
244248
}
249+
// Init crypto backend
250+
cryptoCore := cryptocore.New(masterkey, cryptoBackend, contentenc.DefaultIVBits, args.hkdf, args.forcedecode)
251+
contentEnc := contentenc.New(cryptoCore, contentenc.DefaultBS, args.forcedecode)
252+
nameTransform := nametransform.New(cryptoCore.EMECipher, frontendArgs.LongNames, args.raw64)
253+
// Spawn fusefrontend
254+
var fs ctlsockFs
245255
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
256+
fs = fusefrontend_reverse.NewFS(frontendArgs, contentEnc, nameTransform)
252257
// Reverse mode is read-only, so we don't need a working link().
253258
// Disable hard link tracking to avoid strange breakage on duplicate
254259
// inode numbers ( https://github.com/rfjakob/gocryptfs/issues/149 ).
255260
pathFsOpts.ClientInodes = false
256261
} else {
257-
fs := fusefrontend.NewFS(masterkey, frontendArgs)
258-
finalFs = fs
259-
ctlSockBackend = fs
262+
fs = fusefrontend.NewFS(frontendArgs, contentEnc, nameTransform)
260263
}
261264
// fusefrontend / fusefrontend_reverse have initialized their crypto with
262265
// derived keys (HKDF), we can purge the master key from memory.
@@ -266,9 +269,9 @@ func initFuseFrontend(masterkey []byte, args *argContainer, confFile *configfile
266269
// We have opened the socket early so that we cannot fail here after
267270
// asking the user for the password
268271
if args._ctlsockFd != nil {
269-
go ctlsock.Serve(args._ctlsockFd, ctlSockBackend)
272+
go ctlsock.Serve(args._ctlsockFd, fs)
270273
}
271-
pathFs := pathfs.NewPathNodeFs(finalFs, pathFsOpts)
274+
pathFs := pathfs.NewPathNodeFs(fs, pathFsOpts)
272275
var fuseOpts *nodefs.Options
273276
if args.sharedstorage {
274277
// sharedstorage mode sets all cache timeouts to zero so changes to the

0 commit comments

Comments
 (0)