From ca24c206945266d6397aa0e7d136d5bdcbda777f Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sat, 8 Sep 2018 13:04:33 +0200 Subject: [PATCH] main: don't read the config file twice (fix pipe bug) Instead, first Load() the file, then DecryptMasterKey(). Fixes https://github.com/rfjakob/gocryptfs/issues/258 --- main.go | 14 +++++++------- mount.go | 2 +- tests/cli/cli_test.go | 23 +++++++++++++++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index ac12d2e..fe38a87 100644 --- a/main.go +++ b/main.go @@ -33,10 +33,10 @@ var BuildDate = "0000-00-00" var raceDetector bool // loadConfig loads the config file "args.config", prompting the user for the password -func loadConfig(args *argContainer) (masterkey []byte, confFile *configfile.ConfFile, err error) { +func loadConfig(args *argContainer) (masterkey []byte, cf *configfile.ConfFile, err error) { // First check if the file can be read at all, and find out if a Trezor should // be used instead of a password. - cf1, err := configfile.Load(args.config) + cf, err = configfile.Load(args.config) if err != nil { tlog.Fatal.Printf("Cannot open config file: %v", err) return nil, nil, err @@ -45,18 +45,18 @@ func loadConfig(args *argContainer) (masterkey []byte, confFile *configfile.Conf // he forgot the password). if args.masterkey != "" { masterkey = parseMasterKey(args.masterkey, false) - return masterkey, cf1, nil + return masterkey, cf, nil } var pw []byte - if cf1.IsFeatureFlagSet(configfile.FlagTrezor) { + if cf.IsFeatureFlagSet(configfile.FlagTrezor) { // Get binary data from from Trezor - pw = readpassword.Trezor(cf1.TrezorPayload) + pw = readpassword.Trezor(cf.TrezorPayload) } else { // Normal password entry pw = readpassword.Once(args.extpass, "") } tlog.Info.Println("Decrypting master key") - masterkey, confFile, err = configfile.LoadAndDecrypt(args.config, pw) + masterkey, err = cf.DecryptMasterKey(pw) for i := range pw { pw[i] = 0 } @@ -65,7 +65,7 @@ func loadConfig(args *argContainer) (masterkey []byte, confFile *configfile.Conf tlog.Fatal.Println(err) return nil, nil, err } - return masterkey, confFile, nil + return masterkey, cf, nil } // changePassword - change the password of config file "filename" diff --git a/mount.go b/mount.go index e9714d4..d050c60 100644 --- a/mount.go +++ b/mount.go @@ -94,7 +94,7 @@ func doMount(args *argContainer) { } // We cannot use JSON for pretty-printing as the fields are unexported tlog.Debug.Printf("cli args: %#v", args) - // Initialize gocryptfs + // Initialize gocryptfs (read config file, ask for password, ...) fs, wipeKeys := initFuseFrontend(args) // Initialize go-fuse FUSE server srv := initGoFuse(fs, args) diff --git a/tests/cli/cli_test.go b/tests/cli/cli_test.go index eaa92b6..bd22a43 100644 --- a/tests/cli/cli_test.go +++ b/tests/cli/cli_test.go @@ -495,3 +495,26 @@ func TestExcludeForward(t *testing.T) { } t.Log(err) } + +// Check that the config file can be read from a named pipe. +// Make sure bug https://github.com/rfjakob/gocryptfs/issues/258 does not come +// back. +func TestConfigPipe(t *testing.T) { + dir := test_helpers.InitFS(t) + mnt := dir + ".mnt" + err := os.Mkdir(mnt, 0700) + if err != nil { + t.Fatal(err) + } + bashLine := fmt.Sprintf("%s -q -extpass \"echo test\" -config <(cat %s/gocryptfs.conf) %s %s", test_helpers.GocryptfsBinary, dir, dir, mnt) + cmd := exec.Command("bash", "-c", bashLine) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stdout + err = cmd.Run() + exitCode := test_helpers.ExtractCmdExitCode(err) + if exitCode != 0 { + t.Errorf("bash command\n%q\nresulted in exit code %d", bashLine, exitCode) + return + } + test_helpers.UnmountPanic(mnt) +}