diriv: use "DirIV" flag to discern and support mounting old filesystems
This commit is contained in:
parent
b3d96b6a20
commit
fe7355f9ee
@ -47,8 +47,11 @@ func CreateConfFile(filename string, password string, plaintextNames bool) error
|
||||
// This sets ScryptObject and EncryptedKey
|
||||
cf.EncryptKey(key, password)
|
||||
|
||||
// Set defaults
|
||||
cf.Version = HEADER_CURRENT_VERSION
|
||||
cf.FeatureFlags = []string{FlagDirIV}
|
||||
|
||||
// Set values chosen by the user
|
||||
if plaintextNames {
|
||||
cf.FeatureFlags = append(cf.FeatureFlags, FlagPlaintextNames)
|
||||
}
|
||||
|
@ -22,8 +22,9 @@ func (be *CryptFS) readDirIV(dir string) (iv []byte, err error) {
|
||||
}
|
||||
|
||||
// WriteDirIV - create diriv file inside "dir" (absolute path)
|
||||
// This function is exported because it is used from pathfs_frontend
|
||||
func (be *CryptFS) WriteDirIV(dir string) error {
|
||||
// This function is exported because it is used from pathfs_frontend, main,
|
||||
// and also the automated tests.
|
||||
func WriteDirIV(dir string) error {
|
||||
iv := RandBytes(DIRIV_LEN)
|
||||
file := filepath.Join(dir, DIRIV_FILENAME)
|
||||
// 0444 permissions: the file is not secret but should not be written to
|
||||
|
@ -36,7 +36,7 @@ func TestExampleFsNormal(t *testing.T) {
|
||||
checkStatusTxt(t, pDir+"status.txt")
|
||||
unmount(pDir)
|
||||
mount(cDir, pDir, "-masterkey", "74676e34-0b47c145-00dac61a-17a92316-"+
|
||||
"bb57044c-e205b71f-65f4fdca-7cabd4b3")
|
||||
"bb57044c-e205b71f-65f4fdca-7cabd4b3", "-diriv=false")
|
||||
checkStatusTxt(t, pDir+"status.txt")
|
||||
unmount(pDir)
|
||||
err = os.Remove(pDir)
|
||||
|
@ -8,6 +8,8 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
|
||||
"github.com/rfjakob/gocryptfs/cryptfs"
|
||||
)
|
||||
|
||||
// Note: the code assumes that all have a trailing slash
|
||||
@ -38,8 +40,7 @@ func resetTmpDir() {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
dirIV := make([]byte, 16)
|
||||
err = ioutil.WriteFile(defaultCipherDir+"gocryptfs.diriv", dirIV, 0444)
|
||||
err = cryptfs.WriteDirIV(defaultCipherDir)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
|
34
main.go
34
main.go
@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
@ -34,6 +33,15 @@ const (
|
||||
ERREXIT_MOUNTPOINT = 10
|
||||
)
|
||||
|
||||
type argContainer struct {
|
||||
debug, init, zerokey, fusedebug, openssl, passwd, foreground, version,
|
||||
plaintextnames, quiet, diriv bool
|
||||
masterkey, mountpoint, cipherdir, cpuprofile, config, extpass string
|
||||
notifypid int
|
||||
}
|
||||
|
||||
var flagSet *flag.FlagSet
|
||||
|
||||
// GitVersion will be set by the build script "build.bash"
|
||||
var GitVersion = "[version not set - please compile using ./build.bash]"
|
||||
|
||||
@ -45,11 +53,7 @@ func initDir(args *argContainer) {
|
||||
}
|
||||
|
||||
// Create gocryptfs.diriv in the root dir
|
||||
diriv := cryptfs.RandBytes(cryptfs.DIRIV_LEN)
|
||||
dirivPath := filepath.Join(args.cipherdir, cryptfs.DIRIV_FILENAME)
|
||||
cryptfs.Debug.Printf("Creating %s\n", dirivPath)
|
||||
// 0444 permissions: the file is not secret but should not be written to
|
||||
err = ioutil.WriteFile(dirivPath, diriv, 0444)
|
||||
err = cryptfs.WriteDirIV(args.cipherdir)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(ERREXIT_INIT)
|
||||
@ -76,15 +80,6 @@ func usageText() {
|
||||
flagSet.PrintDefaults()
|
||||
}
|
||||
|
||||
type argContainer struct {
|
||||
debug, init, zerokey, fusedebug, openssl, passwd, foreground, version,
|
||||
plaintextnames, quiet bool
|
||||
masterkey, mountpoint, cipherdir, cpuprofile, config, extpass string
|
||||
notifypid int
|
||||
}
|
||||
|
||||
var flagSet *flag.FlagSet
|
||||
|
||||
// loadConfig - load the config file "filename", prompting the user for the password
|
||||
func loadConfig(args *argContainer) (masterkey []byte, confFile *cryptfs.ConfFile) {
|
||||
// Check if the file exists at all before prompting for a password
|
||||
@ -133,9 +128,9 @@ func printVersion() {
|
||||
func main() {
|
||||
runtime.GOMAXPROCS(4)
|
||||
var err error
|
||||
var args argContainer
|
||||
|
||||
// Parse command line arguments
|
||||
var args argContainer
|
||||
flagSet = flag.NewFlagSet(PROGRAM_NAME, flag.ExitOnError)
|
||||
flagSet.Usage = usageText
|
||||
flagSet.BoolVar(&args.debug, "debug", false, "Enable debug output")
|
||||
@ -149,6 +144,7 @@ func main() {
|
||||
flagSet.BoolVar(&args.plaintextnames, "plaintextnames", false, "Do not encrypt "+
|
||||
"file names")
|
||||
flagSet.BoolVar(&args.quiet, "q", false, "Quiet - silence informational messages")
|
||||
flagSet.BoolVar(&args.diriv, "diriv", true, "Use per-directory file name IV")
|
||||
flagSet.StringVar(&args.masterkey, "masterkey", "", "Mount with explicit master key")
|
||||
flagSet.StringVar(&args.cpuprofile, "cpuprofile", "", "Write cpu profile to specified file")
|
||||
flagSet.StringVar(&args.config, "config", "", "Use specified config file instead of CIPHERDIR/gocryptfs.conf")
|
||||
@ -264,7 +260,9 @@ func main() {
|
||||
var confFile *cryptfs.ConfFile
|
||||
masterkey, confFile = loadConfig(&args)
|
||||
printMasterKey(masterkey)
|
||||
// Settings from the config file override command line args
|
||||
args.plaintextnames = confFile.IsFeatureFlagSet(cryptfs.FlagPlaintextNames)
|
||||
args.diriv = confFile.IsFeatureFlagSet(cryptfs.FlagDirIV)
|
||||
}
|
||||
// Initialize FUSE server
|
||||
srv := pathfsFrontend(masterkey, args)
|
||||
@ -285,7 +283,7 @@ func main() {
|
||||
// Calls os.Exit on errors
|
||||
func pathfsFrontend(key []byte, args argContainer) *fuse.Server {
|
||||
|
||||
finalFs := pathfs_frontend.NewFS(key, args.cipherdir, args.openssl, args.plaintextnames)
|
||||
finalFs := pathfs_frontend.NewFS(key, args.cipherdir, args.openssl, args.plaintextnames, args.diriv)
|
||||
pathFsOpts := &pathfs.PathNodeFsOptions{ClientInodes: true}
|
||||
pathFs := pathfs.NewPathNodeFs(finalFs, pathFsOpts)
|
||||
fuseOpts := &nodefs.Options{
|
||||
@ -309,7 +307,7 @@ func pathfsFrontend(key []byte, args argContainer) *fuse.Server {
|
||||
fmt.Printf("Mount failed: %v", err)
|
||||
os.Exit(ERREXIT_MOUNT)
|
||||
}
|
||||
srv.SetDebug(args.debug)
|
||||
srv.SetDebug(args.fusedebug)
|
||||
|
||||
return srv
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ type FS struct {
|
||||
*cryptfs.CryptFS
|
||||
pathfs.FileSystem // loopbackFileSystem, see go-fuse/fuse/pathfs/loopback.go
|
||||
backingDir string // Backing directory, cipherdir
|
||||
// Are per-directory filename IVs enabled?
|
||||
dirIV bool
|
||||
// dirIVLock: Lock()ed if any "gocryptfs.diriv" file is modified
|
||||
// Readers must RLock() it to prevent them from seeing intermediate
|
||||
// states
|
||||
@ -26,10 +28,11 @@ type FS struct {
|
||||
}
|
||||
|
||||
// Encrypted FUSE overlay filesystem
|
||||
func NewFS(key []byte, backing string, useOpenssl bool, plaintextNames bool) *FS {
|
||||
func NewFS(key []byte, backing string, useOpenssl bool, plaintextNames bool, dirIV bool) *FS {
|
||||
return &FS{
|
||||
CryptFS: cryptfs.NewCryptFS(key, useOpenssl, plaintextNames),
|
||||
FileSystem: pathfs.NewLoopbackFileSystem(backing),
|
||||
dirIV: dirIV,
|
||||
backingDir: backing,
|
||||
}
|
||||
}
|
||||
@ -82,8 +85,8 @@ func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, f
|
||||
// silently ignore "gocryptfs.conf" in the top level dir
|
||||
continue
|
||||
}
|
||||
if cName == cryptfs.DIRIV_FILENAME {
|
||||
// silently ignore "gocryptfs.diriv" everywhere
|
||||
if fs.dirIV && cName == cryptfs.DIRIV_FILENAME {
|
||||
// silently ignore "gocryptfs.diriv" everywhere if dirIV is enabled
|
||||
continue
|
||||
}
|
||||
name, err := fs.decryptPath(cName)
|
||||
@ -227,7 +230,7 @@ func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fu
|
||||
return fuse.ToStatus(err)
|
||||
}
|
||||
// Create gocryptfs.diriv inside
|
||||
err = fs.CryptFS.WriteDirIV(encPath)
|
||||
err = cryptfs.WriteDirIV(encPath)
|
||||
if err != nil {
|
||||
// This should not happen
|
||||
cryptfs.Warn.Printf("Creating %s in dir %s failed: %v\n", cryptfs.DIRIV_FILENAME, encPath, err)
|
||||
|
@ -1,14 +1,24 @@
|
||||
package pathfs_frontend
|
||||
|
||||
// This file handles filename encryption
|
||||
// This file forwards file encryption operations to cryptfs
|
||||
|
||||
import (
|
||||
"github.com/rfjakob/gocryptfs/cryptfs"
|
||||
)
|
||||
|
||||
func (fs *FS) encryptPath(plainPath string) (string, error) {
|
||||
if !fs.dirIV {
|
||||
return fs.CryptFS.TranslatePathZeroIV(plainPath, cryptfs.OpEncrypt)
|
||||
}
|
||||
fs.dirIVLock.RLock()
|
||||
defer fs.dirIVLock.RUnlock()
|
||||
return fs.CryptFS.EncryptPathDirIV(plainPath, fs.backingDir)
|
||||
}
|
||||
|
||||
func (fs *FS) decryptPath(cipherPath string) (string, error) {
|
||||
if !fs.dirIV {
|
||||
return fs.CryptFS.TranslatePathZeroIV(cipherPath, cryptfs.OpDecrypt)
|
||||
}
|
||||
fs.dirIVLock.RLock()
|
||||
defer fs.dirIVLock.RUnlock()
|
||||
return fs.CryptFS.DecryptPathDirIV(cipherPath, fs.backingDir)
|
||||
|
Loading…
Reference in New Issue
Block a user