aboutsummaryrefslogtreecommitdiff
path: root/tests/plaintextnames/plaintextnames_test.go
blob: 4de07307bf69194501521345335a67cdb48ac3d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package plaintextnames

// integration tests that target plaintextnames specifically

import (
	"fmt"
	"io/ioutil"
	"os"
	"syscall"
	"testing"

	"github.com/rfjakob/gocryptfs/v2/internal/configfile"

	"github.com/rfjakob/gocryptfs/v2/tests/test_helpers"
)

var cDir string
var pDir string

var testPw = []byte("test")

// Create and mount "-plaintextnames" fs
func TestMain(m *testing.M) {
	cDir = test_helpers.InitFS(nil, "-plaintextnames")
	pDir = cDir + ".mnt"
	test_helpers.MountOrExit(cDir, pDir, "-extpass", "echo test")
	r := m.Run()
	test_helpers.UnmountPanic(pDir)
	os.Exit(r)
}

// Only the PlaintextNames feature flag should be set
func TestFlags(t *testing.T) {
	_, cf, err := configfile.LoadAndDecrypt(cDir+"/gocryptfs.conf", testPw)
	if err != nil {
		t.Fatal(err)
	}
	if !cf.IsFeatureFlagSet(configfile.FlagPlaintextNames) {
		t.Error("PlaintextNames flag should be set but isn't")
	}
	if cf.IsFeatureFlagSet(configfile.FlagEMENames) || cf.IsFeatureFlagSet(configfile.FlagDirIV) {
		t.Error("FlagEMENames and FlagDirIV should be not set")
	}
}

// gocryptfs.diriv should NOT be created
func TestDirIV(t *testing.T) {
	_, err := os.Stat(cDir + "/gocryptfs.diriv")
	if err == nil {
		t.Errorf("gocryptfs.diriv should not be created in the top directory")
	}
	err = os.Mkdir(pDir+"/dir1", 0777)
	if err != nil {
		t.Error(err)
	}
	_, err = os.Stat(pDir + "/dir1/gocryptfs.diriv")
	if err == nil {
		t.Errorf("gocryptfs.diriv should not be created in a subdirectory")
	}
}

// With "-plaintextnames", the name "/gocryptfs.conf" is reserved, but everything
// else should work.
func TestFiltered(t *testing.T) {
	filteredFile := pDir + "/gocryptfs.conf"
	err := ioutil.WriteFile(filteredFile, []byte("foo"), 0777)
	if err == nil {
		t.Errorf("should have failed but didn't")
	}
	err = os.Remove(filteredFile)
	if err == nil {
		t.Errorf("should have failed but didn't")
	}
	err = ioutil.WriteFile(pDir+"/gocryptfs.diriv", []byte("foo"), 0777)
	if err != nil {
		t.Error(err)
	}
	subDir, err := ioutil.TempDir(pDir, "")
	if err != nil {
		t.Fatal(err)
	}
	fd, err := os.Create(subDir + "/gocryptfs.conf")
	if err != nil {
		t.Error(err)
	} else {
		fd.Close()
	}
}

// TestInoReuseEvil makes it appear that a directory and a file share the
// same inode number.
// Only works on filesystems that recycle inode numbers (ext4 does),
// and then the test causes a hang with these messages:
//
//	go-fuse: blocked for 5 seconds waiting for FORGET on i4329366
//	go-fuse: blocked for 11 seconds waiting for FORGET on i4329366
//	go-fuse: blocked for 17 seconds waiting for FORGET on i4329366
//	[...]
//
// The test runs with -plaintextnames because that makes it easier to manipulate
// cipherdir directly.
func TestInoReuseEvil(t *testing.T) {
	for i := 0; i < 2; i++ {
		n := fmt.Sprintf("%s.%d", t.Name(), i)
		pPath := pDir + "/" + n
		cPath := cDir + "/" + n
		if err := syscall.Mkdir(pPath, 0700); err != nil {
			t.Fatal(err)
		}
		var st syscall.Stat_t
		syscall.Stat(pPath, &st)
		t.Logf("dir  ino = %d", st.Ino)
		// delete the dir "behind our back"
		if err := syscall.Rmdir(cPath); err != nil {
			t.Fatal(err)
		}
		// create a new file that will likely get the same inode number
		pPath2 := pPath + "2"
		fd, err := syscall.Open(pPath2, syscall.O_CREAT|syscall.O_WRONLY|syscall.O_TRUNC, 0600)
		if err != nil {
			t.Fatal(err)
		}
		defer syscall.Close(fd)
		syscall.Fstat(fd, &st)
		t.Logf("file ino = %d", st.Ino)
	}
}

// TestRootIno checks that inode number of the root dir is set
// https://github.com/hanwen/go-fuse/issues/399
func TestRootIno(t *testing.T) {
	var st syscall.Stat_t
	syscall.Stat(cDir, &st)
	if st.Ino == 0 {
		t.Errorf("inode number of root dir is zero")
	}
}