// initDir prepares a directory for use as a gocryptfs storage directory. // In forward mode, this means creating the gocryptfs.conf and gocryptfs.diriv // files in an empty directory. // In reverse mode, we create .gocryptfs.reverse.conf and the directory does // not to be empty. func initDir(args *argContainer) { var err error if args.reverse { _, err = os.Stat(args.config) if err == nil { tlog.Fatal.Printf("Config file %q already exists", args.config) os.Exit(ErrExitInit) } } else { err = checkDirEmpty(args.cipherdir) if err != nil { tlog.Fatal.Printf("Invalid cipherdir: %v", err) os.Exit(ErrExitInit) } } // Choose password for config file if args.extpass == "" { tlog.Info.Printf("Choose a password for protecting your files.") } password := readpassword.Twice(args.extpass) creator := tlog.ProgramName + " " + GitVersion err = configfile.CreateConfFile(args.config, password, args.plaintextnames, args.scryptn, creator, args.aessiv, args.raw64) if err != nil { tlog.Fatal.Println(err) os.Exit(ErrExitInit) } // Forward mode with filename encryption enabled needs a gocryptfs.diriv // in the root dir if !args.plaintextnames && !args.reverse { err = nametransform.WriteDirIV(args.cipherdir) if err != nil { tlog.Fatal.Println(err) os.Exit(ErrExitInit) } } mountArgs := "" fsName := "gocryptfs" if args.reverse { mountArgs = " -reverse" fsName = "gocryptfs-reverse" } tlog.Info.Printf(tlog.ColorGreen+"The %s filesystem has been created successfully."+tlog.ColorReset, fsName) wd, _ := os.Getwd() friendlyPath, _ := filepath.Rel(wd, args.cipherdir) if strings.HasPrefix(friendlyPath, "../") { // A relative path that starts with "../" is pretty unfriendly, just // keep the absolute path. friendlyPath = args.cipherdir } if strings.Contains(friendlyPath, " ") { friendlyPath = "\"" + friendlyPath + "\"" } tlog.Info.Printf(tlog.ColorGrey+"You can now mount it using: %s%s %s MOUNTPOINT"+tlog.ColorReset, tlog.ProgramName, mountArgs, friendlyPath) os.Exit(0) }
// ResetTmpDir deletes TmpDir, create new dir tree: // // TmpDir // |-- DefaultPlainDir // *-- DefaultCipherDir // *-- gocryptfs.diriv func ResetTmpDir(createDirIV bool) { // Try to unmount and delete everything entries, err := ioutil.ReadDir(TmpDir) if err == nil { for _, e := range entries { d := filepath.Join(TmpDir, e.Name()) err = os.Remove(d) if err != nil { pe := err.(*os.PathError) if pe.Err == syscall.EBUSY { if testing.Verbose() { fmt.Printf("Remove failed: %v. Maybe still mounted?\n", pe) } err = UnmountErr(d) if err != nil { panic(err) } } else if pe.Err != syscall.ENOTEMPTY { panic("Unhandled error: " + pe.Err.Error()) } err = os.RemoveAll(d) if err != nil { panic(err) } } } } err = os.Mkdir(DefaultPlainDir, 0700) if err != nil { panic(err) } err = os.Mkdir(DefaultCipherDir, 0700) if err != nil { panic(err) } if createDirIV { err = nametransform.WriteDirIV(DefaultCipherDir) if err != nil { panic(err) } } }
func (fs *FS) mkdirWithIv(cPath string, mode uint32) error { // Between the creation of the directory and the creation of gocryptfs.diriv // the directory is inconsistent. Take the lock to prevent other readers // from seeing it. fs.dirIVLock.Lock() // The new directory may take the place of an older one that is still in the cache fs.nameTransform.DirIVCache.Clear() defer fs.dirIVLock.Unlock() err := os.Mkdir(cPath, os.FileMode(mode)) if err != nil { return err } // Create gocryptfs.diriv err = nametransform.WriteDirIV(cPath) if err != nil { err2 := syscall.Rmdir(cPath) if err2 != nil { tlog.Warn.Printf("mkdirWithIv: rollback failed: %v", err2) } } return err }