aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/nametransform/names.go9
-rw-r--r--tests/cli/cli_test.go68
2 files changed, 65 insertions, 12 deletions
diff --git a/internal/nametransform/names.go b/internal/nametransform/names.go
index e9f9346..675ed34 100644
--- a/internal/nametransform/names.go
+++ b/internal/nametransform/names.go
@@ -61,7 +61,14 @@ func (n *NameTransform) DecryptName(cipherName string, iv []byte) (string, error
for _, pattern := range n.BadnamePatterns {
match, err := filepath.Match(pattern, cipherName)
if err == nil && match { // Pattern should have been validated already
- return "GOCRYPTFS_BAD_NAME " + cipherName, nil
+ //find longest decryptable substring
+ for charpos := len(cipherName) - 1; charpos > 0; charpos-- {
+ res, err = n.decryptName(cipherName[:charpos], iv)
+ if err == nil {
+ return res + cipherName[charpos:] + " GOCRYPTFS_BAD_NAME", nil
+ }
+ }
+ return cipherName + " GOCRYPTFS_BAD_NAME", nil
}
}
}
diff --git a/tests/cli/cli_test.go b/tests/cli/cli_test.go
index 2484cf3..08abed9 100644
--- a/tests/cli/cli_test.go
+++ b/tests/cli/cli_test.go
@@ -705,40 +705,86 @@ func TestSymlinkedCipherdir(t *testing.T) {
func TestBadname(t *testing.T) {
dir := test_helpers.InitFS(t)
mnt := dir + ".mnt"
+ validFileName := "file"
+ invalidSuffix := ".invalid_file"
+ //use static suffix for testing
test_helpers.MountOrFatal(t, dir, mnt, "-badname=*", "-extpass=echo test")
defer test_helpers.UnmountPanic(mnt)
- file := mnt + "/file"
+ //write one valid file
+ file := mnt + "/" + validFileName
err := ioutil.WriteFile(file, []byte("somecontent"), 0600)
if err != nil {
t.Fatal(err)
}
- invalid_file_name := "invalid_file"
- invalid_file := dir + "/" + invalid_file_name
- err = ioutil.WriteFile(invalid_file, []byte("somecontent"), 0600)
+ //read encrypted file name
+ fread, err := os.Open(dir)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer fread.Close()
+
+ encryptedfilename := ""
+ ciphernames, err := fread.Readdirnames(0)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for _, ciphername := range ciphernames {
+ if ciphername != "gocryptfs.conf" && ciphername != "gocryptfs.diriv" {
+ encryptedfilename = ciphername
+ //found cipher name of "file"
+ }
+ }
+
+ //Read encrypted file name to generated invalid filenames
+ fsource, err := os.Open(dir + "/" + encryptedfilename)
+ if err != nil {
+ t.Fatal(err)
+ }
+ content, err := ioutil.ReadAll(fsource)
+ if err != nil {
+ t.Fatal(err)
+ }
+ fsource.Close()
+ //write invalid file which should be decodable
+ err = ioutil.WriteFile(dir+"/"+encryptedfilename+invalidSuffix, content, 0600)
+ if err != nil {
+ t.Fatal(err)
+ }
+ //write invalid file which is not decodable (cropping the encrpyted file name)
+ err = ioutil.WriteFile(dir+"/"+encryptedfilename[:len(encryptedfilename)-2]+invalidSuffix, content, 0600)
if err != nil {
t.Fatal(err)
}
+ //check for filenames
f, err := os.Open(mnt)
if err != nil {
t.Fatal(err)
}
defer f.Close()
-
names, err := f.Readdirnames(0)
- found := false
+ if err != nil {
+ t.Fatal(err)
+ }
+ foundDecodable := false
+ foundUndecodable := false
for _, name := range names {
- if strings.Contains(name, invalid_file_name) {
- found = true
- break
+ if strings.Contains(name, validFileName+invalidSuffix+" GOCRYPTFS_BAD_NAME") {
+ foundDecodable = true
+ } else if strings.Contains(name, encryptedfilename[:len(encryptedfilename)-2]+invalidSuffix+" GOCRYPTFS_BAD_NAME") {
+ foundUndecodable = true
}
}
- if !found {
- t.Errorf("did not find invalid name %s in %v", invalid_file_name, names)
+ if !foundDecodable {
+ t.Errorf("did not find invalid name %s in %v", validFileName+invalidSuffix+" GOCRYPTFS_BAD_NAME", names)
+ }
+
+ if !foundUndecodable {
+ t.Errorf("did not find invalid name %s in %v", encryptedfilename[:len(encryptedfilename)-2]+invalidSuffix+" GOCRYPTFS_BAD_NAME", names)
}
}