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