From c487e176bd517d815315583dfc795dc629ffb20a Mon Sep 17 00:00:00 2001 From: Jakob Unterwurzacher Date: Sun, 16 Oct 2016 18:17:28 +0200 Subject: main: allow password change with -masterkey Requested at https://github.com/rfjakob/gocryptfs/issues/28 --- Documentation/MANPAGE.md | 19 ++++++++++++++++--- internal/configfile/config_file.go | 6 +++++- main.go | 25 +++++++++++++++++++++---- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/Documentation/MANPAGE.md b/Documentation/MANPAGE.md index 1049703..4fa155a 100644 --- a/Documentation/MANPAGE.md +++ b/Documentation/MANPAGE.md @@ -80,10 +80,14 @@ This flag is useful when recovering old gocryptfs filesystems using "-masterkey". It is ignored (stays at the default) otherwise. **-masterkey string** -: Mount with explicit master key specified on the command line. This +: Use a explicit master key specified on the command line. This option can be used to mount a gocryptfs filesystem without a config file. Note that the command line, and with it the master key, is visible to anybody on the machine who can execute "ps -auxwww". +This is meant as a recovery option for emergencies, such as if you have +forgotten your password. + + Example master key: 6f717d8b-6b5f8e8a-fd0aa206-778ec093-62c5669b-abd229cd-241e00cd-b4d6713d **-memprofile string** : Write memory profile to specified file. This is useful when debugging @@ -91,7 +95,7 @@ memory usage of gocryptfs. **-nonempty** : Allow mounting over non-empty directories. FUSE by default disallows -this because to prevent accidential shadowing of files. +this to prevent accidential shadowing of files. **-nosyslog** : Diagnostic messages are normally redirected to syslog once gocryptfs @@ -113,7 +117,16 @@ option. specifying "-extpass /bin/cat FILE". **-passwd** -: Change password +: Change the password. Will ask for the old password, check if it is +correct, and ask for a new one. + + This can be used together with `-masterkey` if +you forgot the password but know the master key. Note that without the +old password, gocryptfs cannot tell if the master key is correct and will +overwrite the old one without mercy. It will, however, create a backup copy +of the old config file as `gocryptfs.conf.bak`. Delete it after +you have verified that you can access your files with the +new password. **-plaintextnames** : Do not encrypt file names and symlink targets diff --git a/internal/configfile/config_file.go b/internal/configfile/config_file.go index 79960e4..97a1f3a 100644 --- a/internal/configfile/config_file.go +++ b/internal/configfile/config_file.go @@ -139,7 +139,11 @@ func LoadConfFile(filename string, password string) ([]byte, *ConfFile, error) { return nil, nil, fmt.Errorf("Deprecated filesystem") } - + if password == "" { + // We have validated the config file, but without a password we cannot + // decrypt the master key. Return only the parsed config. + return nil, &cf, nil + } // Generate derived key from password scryptHash := cf.ScryptObject.DeriveKey(password) diff --git a/main.go b/main.go index c5675e2..3dc959f 100644 --- a/main.go +++ b/main.go @@ -59,9 +59,14 @@ func loadConfig(args *argContainer) (masterkey []byte, confFile *configfile.Conf os.Exit(ErrExitLoadConf) } fd.Close() - pw := readpassword.Once(args.extpass) - tlog.Info.Println("Decrypting master key") - masterkey, confFile, err = configfile.LoadConfFile(args.config, pw) + if args.masterkey != "" { + masterkey = parseMasterKey(args.masterkey) + _, confFile, err = configfile.LoadConfFile(args.config, "") + } else { + pw := readpassword.Once(args.extpass) + tlog.Info.Println("Decrypting master key") + masterkey, confFile, err = configfile.LoadConfFile(args.config, pw) + } if err != nil { tlog.Fatal.Println(err) os.Exit(ErrExitLoadConf) @@ -75,12 +80,24 @@ func changePassword(args *argContainer) { tlog.Info.Println("Please enter your new password.") newPw := readpassword.Twice(args.extpass) confFile.EncryptKey(masterkey, newPw, confFile.ScryptObject.LogN()) + if args.masterkey != "" { + bak := args.config + ".bak" + err := os.Link(args.config, bak) + if err != nil { + tlog.Fatal.Printf("Could not create backup file: %v", err) + os.Exit(ErrExitInit) + } + tlog.Info.Printf(tlog.ColorGrey+ + "A copy of the old config file has been created at %q.\n"+ + "Delete it after you have verified that you can access your files with the new password."+ + tlog.ColorReset, bak) + } err := confFile.WriteFile() if err != nil { tlog.Fatal.Println(err) os.Exit(ErrExitInit) } - tlog.Info.Printf("Password changed.") + tlog.Info.Printf(tlog.ColorGreen + "Password changed." + tlog.ColorReset) os.Exit(0) } -- cgit v1.2.3