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
This commit is contained in:
parent
a56e7cc5ac
commit
a8230d271f
@ -61,7 +61,14 @@ func (n *NameTransform) DecryptName(cipherName string, iv []byte) (string, error
|
|||||||
for _, pattern := range n.BadnamePatterns {
|
for _, pattern := range n.BadnamePatterns {
|
||||||
match, err := filepath.Match(pattern, cipherName)
|
match, err := filepath.Match(pattern, cipherName)
|
||||||
if err == nil && match { // Pattern should have been validated already
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -705,40 +705,86 @@ func TestSymlinkedCipherdir(t *testing.T) {
|
|||||||
func TestBadname(t *testing.T) {
|
func TestBadname(t *testing.T) {
|
||||||
dir := test_helpers.InitFS(t)
|
dir := test_helpers.InitFS(t)
|
||||||
mnt := dir + ".mnt"
|
mnt := dir + ".mnt"
|
||||||
|
validFileName := "file"
|
||||||
|
invalidSuffix := ".invalid_file"
|
||||||
|
|
||||||
|
//use static suffix for testing
|
||||||
test_helpers.MountOrFatal(t, dir, mnt, "-badname=*", "-extpass=echo test")
|
test_helpers.MountOrFatal(t, dir, mnt, "-badname=*", "-extpass=echo test")
|
||||||
defer test_helpers.UnmountPanic(mnt)
|
defer test_helpers.UnmountPanic(mnt)
|
||||||
|
|
||||||
file := mnt + "/file"
|
//write one valid file
|
||||||
|
file := mnt + "/" + validFileName
|
||||||
err := ioutil.WriteFile(file, []byte("somecontent"), 0600)
|
err := ioutil.WriteFile(file, []byte("somecontent"), 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
invalid_file_name := "invalid_file"
|
//read encrypted file name
|
||||||
invalid_file := dir + "/" + invalid_file_name
|
fread, err := os.Open(dir)
|
||||||
err = ioutil.WriteFile(invalid_file, []byte("somecontent"), 0600)
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//check for filenames
|
||||||
f, err := os.Open(mnt)
|
f, err := os.Open(mnt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
names, err := f.Readdirnames(0)
|
names, err := f.Readdirnames(0)
|
||||||
found := false
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
foundDecodable := false
|
||||||
|
foundUndecodable := false
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
if strings.Contains(name, invalid_file_name) {
|
if strings.Contains(name, validFileName+invalidSuffix+" GOCRYPTFS_BAD_NAME") {
|
||||||
found = true
|
foundDecodable = true
|
||||||
break
|
} else if strings.Contains(name, encryptedfilename[:len(encryptedfilename)-2]+invalidSuffix+" GOCRYPTFS_BAD_NAME") {
|
||||||
|
foundUndecodable = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found {
|
if !foundDecodable {
|
||||||
t.Errorf("did not find invalid name %s in %v", invalid_file_name, names)
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user