aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Unterwurzacher2015-11-25 19:30:32 +0100
committerJakob Unterwurzacher2015-11-25 20:57:16 +0100
commit4d466c3412918346144dff609d8f706c6f002581 (patch)
tree2624a1b9573295e6f70df6eb74be5d0f241436e7
parentd8bf6e7836a22c755fa0881f89d482b5e8f47e29 (diff)
diriv: Create gocryptfs.diriv in every directory
-rw-r--r--cryptfs/cryptfs.go2
-rw-r--r--cryptfs/cryptfs_names.go2
-rw-r--r--main.go13
-rw-r--r--password.go2
-rw-r--r--pathfs_frontend/fs.go39
5 files changed, 49 insertions, 9 deletions
diff --git a/cryptfs/cryptfs.go b/cryptfs/cryptfs.go
index 783bfb8..63febc3 100644
--- a/cryptfs/cryptfs.go
+++ b/cryptfs/cryptfs.go
@@ -14,6 +14,8 @@ const (
NONCE_LEN = 12
AUTH_TAG_LEN = 16
BLOCK_OVERHEAD = NONCE_LEN + AUTH_TAG_LEN
+ DIRIV_LEN = 16 // identical to AES block size
+ DIRIV_FILENAME = "gocryptfs.diriv"
)
type CryptFS struct {
diff --git a/cryptfs/cryptfs_names.go b/cryptfs/cryptfs_names.go
index a7a9a8c..1282f53 100644
--- a/cryptfs/cryptfs_names.go
+++ b/cryptfs/cryptfs_names.go
@@ -31,7 +31,7 @@ func (be *CryptFS) decryptName(cipherName string) (string, error) {
}
if len(bin)%aes.BlockSize != 0 {
- return "", errors.New(fmt.Sprintf("Name len=%d is not a multiple of 16", len(bin)))
+ return "", fmt.Errorf("Decoded length %d is not a multiple of the AES block size", len(bin))
}
iv := make([]byte, aes.BlockSize) // TODO ?
diff --git a/main.go b/main.go
index 8d8ef08..77b722a 100644
--- a/main.go
+++ b/main.go
@@ -1,6 +1,7 @@
package main
import (
+ "io/ioutil"
"flag"
"fmt"
"os"
@@ -43,6 +44,18 @@ func initDir(args *argContainer) {
os.Exit(ERREXIT_INIT)
}
+ // 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)
+ if err != nil {
+ fmt.Println(err)
+ os.Exit(ERREXIT_INIT)
+ }
+
+ // Create gocryptfs.conf
cryptfs.Info.Printf("Choose a password for protecting your files.\n")
password := readPasswordTwice(args.extpass)
err = cryptfs.CreateConfFile(args.config, password, args.plaintextnames)
diff --git a/password.go b/password.go
index ede65dd..45b0296 100644
--- a/password.go
+++ b/password.go
@@ -12,7 +12,7 @@ import (
func readPasswordTwice(extpass string) string {
fmt.Printf("Password: ")
p1 := readPassword(extpass)
- fmt.Printf("Repeat: ")
+ fmt.Printf("Repeat: ")
p2 := readPassword(extpass)
if p1 != p2 {
fmt.Printf("Passwords do not match\n")
diff --git a/pathfs_frontend/fs.go b/pathfs_frontend/fs.go
index c0a3a41..3d6d79c 100644
--- a/pathfs_frontend/fs.go
+++ b/pathfs_frontend/fs.go
@@ -1,7 +1,8 @@
package pathfs_frontend
import (
- "fmt"
+ "syscall"
+ "io/ioutil"
"os"
"path/filepath"
"time"
@@ -14,7 +15,7 @@ import (
type FS struct {
*cryptfs.CryptFS
- pathfs.FileSystem // loopbackFileSystem
+ pathfs.FileSystem // loopbackFileSystem, see go-fuse/fuse/pathfs/loopback.go
backing string // Backing directory
}
@@ -27,7 +28,8 @@ func NewFS(key []byte, backing string, useOpenssl bool, plaintextNames bool) *FS
}
}
-// GetPath - get the absolute path of the backing file
+// GetPath - get the absolute encrypted path of the backing file
+// from the relative plaintext path "relPath"
func (fs *FS) GetPath(relPath string) string {
return filepath.Join(fs.backing, fs.EncryptPath(relPath))
}
@@ -63,9 +65,13 @@ 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
+ continue
+ }
name, err := fs.DecryptPath(cName)
if err != nil {
- fmt.Printf("Invalid name \"%s\" in dir \"%s\": %s\n", cName, name, err)
+ cryptfs.Warn.Printf("Invalid name \"%s\" in dir \"%s\": %s\n", cName, dirName, err)
continue
}
cipherEntries[i].Name = name
@@ -160,11 +166,30 @@ func (fs *FS) Readlink(name string, context *fuse.Context) (out string, status f
return dstPlain, status
}
-func (fs *FS) Mkdir(path string, mode uint32, context *fuse.Context) (code fuse.Status) {
- if fs.CryptFS.IsFiltered(path) {
+func (fs *FS) Mkdir(relPath string, mode uint32, context *fuse.Context) (code fuse.Status) {
+ if fs.CryptFS.IsFiltered(relPath) {
return fuse.EPERM
}
- return fs.FileSystem.Mkdir(fs.EncryptPath(path), mode, context)
+ encPath := fs.GetPath(relPath)
+ diriv := cryptfs.RandBytes(cryptfs.DIRIV_LEN)
+ dirivPath := filepath.Join(encPath, cryptfs.DIRIV_FILENAME)
+ // Create directory
+ err := os.Mkdir(encPath, os.FileMode(mode))
+ if err != nil {
+ return fuse.ToStatus(err)
+ }
+ // Create gocryptfs.diriv inside
+ // 0444 permissions: the file is not secret but should not be written to
+ err = ioutil.WriteFile(dirivPath, diriv, 0444)
+ if err != nil {
+ cryptfs.Warn.Printf("Creating %s in dir %s failed: %v\n", cryptfs.DIRIV_FILENAME, encPath, err)
+ err2 := syscall.Rmdir(encPath)
+ if err2 != nil {
+ cryptfs.Warn.Printf("Removing broken directory failed: %v\n", err2)
+ }
+ return fuse.ToStatus(err)
+ }
+ return fuse.OK
}
func (fs *FS) Unlink(name string, context *fuse.Context) (code fuse.Status) {