diff options
author | DerDonut | 2020-05-19 13:34:58 +0200 |
---|---|---|
committer | Jakob Unterwurzacher | 2020-06-06 12:20:31 +0200 |
commit | a8230d271f394e130a8190d554eef2a86bc962d7 (patch) | |
tree | babb6d3c4d9d76bd2d5363a1a83728a4c063c4f7 | |
parent | a56e7cc5ac3ede528aaa05f912c865b09e942de4 (diff) |
Added auto decryption of invalid file names
Changed invalid file decoding and decryption. Function
DecryptName now shortens the filename until the filename is
decodable and decryptable. Will work with valid **and**
invalid Base64URL delimiter (valid delimiter [0-9a-zA-z_\\-].
If the filename is not decryptable at all, it returns the
original cipher name with flag suffix Changed cli tests to
generate decryptable and undecryptable file names with correct
encrypted content. Replacing #474, extends #393
-rw-r--r-- | internal/nametransform/names.go | 9 | ||||
-rw-r--r-- | tests/cli/cli_test.go | 68 |
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) } } |