diff options
Diffstat (limited to 'internal/fusefrontend/fs_dir.go')
-rw-r--r-- | internal/fusefrontend/fs_dir.go | 66 |
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 +} |