aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2015-11-27 23:34:55 +0100
committerJakob Unterwurzacher2015-11-28 18:38:06 +0100
commitfe7355f9ee4ae8e52a9b76202e90032d78824f21 (patch)
treeffa2eed00a684b9985a249654e72bba3f82710db
parentb3d96b6a208e7679a0e7dc936d76bcec271ecddf (diff)
diriv: use "DirIV" flag to discern and support mounting old filesystems
-rw-r--r--cryptfs/config_file.go3
-rw-r--r--cryptfs/names_diriv.go5
-rw-r--r--integration_tests/example_filesystems_test.go2
-rw-r--r--integration_tests/helpers.go5
-rw-r--r--main.go34
-rw-r--r--pathfs_frontend/fs.go11
-rw-r--r--pathfs_frontend/names.go12
7 files changed, 44 insertions, 28 deletions
diff --git a/cryptfs/config_file.go b/cryptfs/config_file.go
index 1e7e3b3..a0ab218 100644
--- a/cryptfs/config_file.go
+++ b/cryptfs/config_file.go
@@ -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)
}
diff --git a/cryptfs/names_diriv.go b/cryptfs/names_diriv.go
index ab039f0..6346bc2 100644
--- a/cryptfs/names_diriv.go
+++ b/cryptfs/names_diriv.go
@@ -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
diff --git a/integration_tests/example_filesystems_test.go b/integration_tests/example_filesystems_test.go
index 644f8e7..7924736 100644
--- a/integration_tests/example_filesystems_test.go
+++ b/integration_tests/example_filesystems_test.go
@@ -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)
diff --git a/integration_tests/helpers.go b/integration_tests/helpers.go
index 6fc65cf..bff4e5b 100644
--- a/integration_tests/helpers.go
+++ b/integration_tests/helpers.go
@@ -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)
diff --git a/main.go b/main.go
index a6131e1..b3944cc 100644
--- a/main.go
+++ b/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
}
diff --git a/pathfs_frontend/fs.go b/pathfs_frontend/fs.go
index 680b08c..c2b80a3 100644
--- a/pathfs_frontend/fs.go
+++ b/pathfs_frontend/fs.go
@@ -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)
diff --git a/pathfs_frontend/names.go b/pathfs_frontend/names.go
index 9c6e010..122b3dd 100644
--- a/pathfs_frontend/names.go
+++ b/pathfs_frontend/names.go
@@ -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)