summaryrefslogtreecommitdiff
path: root/internal/fusefrontend/fs_dir.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/fusefrontend/fs_dir.go')
-rw-r--r--internal/fusefrontend/fs_dir.go66
1 files changed, 66 insertions, 0 deletions
diff --git a/internal/fusefrontend/fs_dir.go b/internal/fusefrontend/fs_dir.go
index aed501d..f1ade25 100644
--- a/internal/fusefrontend/fs_dir.go
+++ b/internal/fusefrontend/fs_dir.go
@@ -155,3 +155,69 @@ func (fs *FS) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
fs.nameTransform.DirIVCache.Clear()
return fuse.OK
}
+
+func (fs *FS) OpenDir(dirName string, context *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
+ toggledlog.Debug.Printf("OpenDir(%s)", dirName)
+ cDirName, err := fs.encryptPath(dirName)
+ if err != nil {
+ return nil, fuse.ToStatus(err)
+ }
+ // Read ciphertext directory
+ cipherEntries, status := fs.FileSystem.OpenDir(cDirName, context)
+ if cipherEntries == nil {
+ return nil, status
+ }
+ // Get DirIV (stays nil if DirIV if off)
+ var cachedIV []byte
+ var cDirAbsPath string
+ if fs.args.DirIV {
+ // Read the DirIV once and use it for all later name decryptions
+ cDirAbsPath = filepath.Join(fs.args.Cipherdir, cDirName)
+ cachedIV, err = nametransform.ReadDirIV(cDirAbsPath)
+ if err != nil {
+ return nil, fuse.ToStatus(err)
+ }
+ }
+ // Filter and decrypt filenames
+ var plain []fuse.DirEntry
+ for i := range cipherEntries {
+ cName := cipherEntries[i].Name
+ if dirName == "" && cName == configfile.ConfDefaultName {
+ // silently ignore "gocryptfs.conf" in the top level dir
+ continue
+ }
+ if fs.args.DirIV && cName == nametransform.DirIVFilename {
+ // silently ignore "gocryptfs.diriv" everywhere if dirIV is enabled
+ continue
+ }
+
+ if fs.args.PlaintextNames {
+ plain = append(plain, cipherEntries[i])
+ continue
+ }
+
+ if fs.args.LongNames {
+ isLong := nametransform.IsLongName(cName)
+ if isLong == 1 {
+ cNameLong, err := nametransform.ReadLongName(filepath.Join(cDirAbsPath, cName))
+ if err != nil {
+ toggledlog.Warn.Printf("Could not read long name for file %s, skipping file", cName)
+ continue
+ }
+ cName = cNameLong
+ } else if isLong == 2 {
+ // ignore "gocryptfs.longname.*.name"
+ continue
+ }
+ }
+ name, err := fs.nameTransform.DecryptName(cName, cachedIV)
+ if err != nil {
+ toggledlog.Warn.Printf("Skipping invalid name '%s' in dir '%s': %s", cName, cDirName, err)
+ continue
+ }
+
+ cipherEntries[i].Name = name
+ plain = append(plain, cipherEntries[i])
+ }
+ return plain, status
+}