reverse mode: add --exclude option
https://github.com/rfjakob/gocryptfs/issues/235
This commit is contained in:
parent
eaa5aecd42
commit
ec2fdc19cf
@ -70,12 +70,18 @@ Enable (`-dev`) or disable (`-nodev`) device files in a gocryptfs mount
|
|||||||
You need root permissions to use `-dev`.
|
You need root permissions to use `-dev`.
|
||||||
|
|
||||||
#### -devrandom
|
#### -devrandom
|
||||||
Use /dev/random for generating the master key instead of the default Go
|
Use `/dev/random` for generating the master key instead of the default Go
|
||||||
implementation. This is especially useful on embedded systems with Go versions
|
implementation. This is especially useful on embedded systems with Go versions
|
||||||
prior to 1.9, which fall back to weak random data when the getrandom syscall
|
prior to 1.9, which fall back to weak random data when the getrandom syscall
|
||||||
is blocking. Using this option can block indefinitely when the kernel cannot
|
is blocking. Using this option can block indefinitely when the kernel cannot
|
||||||
harvest enough entropy.
|
harvest enough entropy.
|
||||||
|
|
||||||
|
#### -exclude PATH
|
||||||
|
Only for reverse mode: exclude relative plaintext path from the encrypted
|
||||||
|
view. Can be passed multiple times. Example:
|
||||||
|
|
||||||
|
gocryptfs -reverse -exclude Music -exclude Movies /home/user /mnt/user.encrypted
|
||||||
|
|
||||||
#### -exec, -noexec
|
#### -exec, -noexec
|
||||||
Enable (`-exec`) or disable (`-noexec`) executables in a gocryptfs mount
|
Enable (`-exec`) or disable (`-noexec`) executables in a gocryptfs mount
|
||||||
(default: `-exec`). If both are specified, `-noexec` takes precedence.
|
(default: `-exec`). If both are specified, `-noexec` takes precedence.
|
||||||
|
@ -155,6 +155,7 @@ Changelog
|
|||||||
vNEXT, in progress
|
vNEXT, in progress
|
||||||
* Fall back to buffered IO even when passed `O_DIRECT`
|
* Fall back to buffered IO even when passed `O_DIRECT`
|
||||||
([commit](https://github.com/rfjakob/gocryptfs/commit/893e41149ed353f355047003b89eeff456990e76))
|
([commit](https://github.com/rfjakob/gocryptfs/commit/893e41149ed353f355047003b89eeff456990e76))
|
||||||
|
* Add `-exclude` option for reverse mode
|
||||||
|
|
||||||
v1.5, 2018-06-12
|
v1.5, 2018-06-12
|
||||||
* **Support extended attributes (xattr)** in forward mode
|
* **Support extended attributes (xattr)** in forward mode
|
||||||
|
@ -27,6 +27,8 @@ type argContainer struct {
|
|||||||
dev, nodev, suid, nosuid, exec, noexec, rw, ro bool
|
dev, nodev, suid, nosuid, exec, noexec, rw, ro bool
|
||||||
masterkey, mountpoint, cipherdir, cpuprofile, extpass,
|
masterkey, mountpoint, cipherdir, cpuprofile, extpass,
|
||||||
memprofile, ko, passfile, ctlsock, fsname, force_owner, trace string
|
memprofile, ko, passfile, ctlsock, fsname, force_owner, trace string
|
||||||
|
// For reverse mode, --exclude is available. It can be specified multiple times.
|
||||||
|
exclude multipleStrings
|
||||||
// Configuration file name override
|
// Configuration file name override
|
||||||
config string
|
config string
|
||||||
notifypid, scryptn int
|
notifypid, scryptn int
|
||||||
@ -173,6 +175,9 @@ func parseCliOpts() (args argContainer) {
|
|||||||
flagSet.StringVar(&args.fsname, "fsname", "", "Override the filesystem name")
|
flagSet.StringVar(&args.fsname, "fsname", "", "Override the filesystem name")
|
||||||
flagSet.StringVar(&args.force_owner, "force_owner", "", "uid:gid pair to coerce ownership")
|
flagSet.StringVar(&args.force_owner, "force_owner", "", "uid:gid pair to coerce ownership")
|
||||||
flagSet.StringVar(&args.trace, "trace", "", "Write execution trace to file")
|
flagSet.StringVar(&args.trace, "trace", "", "Write execution trace to file")
|
||||||
|
|
||||||
|
flagSet.Var(&args.exclude, "exclude", "Exclude relative path from reverse view")
|
||||||
|
|
||||||
flagSet.IntVar(&args.notifypid, "notifypid", 0, "Send USR1 to the specified process after "+
|
flagSet.IntVar(&args.notifypid, "notifypid", 0, "Send USR1 to the specified process after "+
|
||||||
"successful mount - used internally for daemonization")
|
"successful mount - used internally for daemonization")
|
||||||
flagSet.IntVar(&args.scryptn, "scryptn", configfile.ScryptDefaultLogN, "scrypt cost parameter logN. Possible values: 10-28. "+
|
flagSet.IntVar(&args.scryptn, "scryptn", configfile.ScryptDefaultLogN, "scrypt cost parameter logN. Possible values: 10-28. "+
|
||||||
|
@ -68,6 +68,8 @@ const (
|
|||||||
// TrezorError - an error was encountered while interacting with a Trezor
|
// TrezorError - an error was encountered while interacting with a Trezor
|
||||||
// device
|
// device
|
||||||
TrezorError = 28
|
TrezorError = 28
|
||||||
|
// ExcludeError - an error occoured while processing "-exclude"
|
||||||
|
ExcludeError = 29
|
||||||
)
|
)
|
||||||
|
|
||||||
// Err wraps an error with an associated numeric exit code
|
// Err wraps an error with an associated numeric exit code
|
||||||
|
@ -30,4 +30,6 @@ type Args struct {
|
|||||||
SerializeReads bool
|
SerializeReads bool
|
||||||
// Force decode even if integrity check fails (openSSL only)
|
// Force decode even if integrity check fails (openSSL only)
|
||||||
ForceDecode bool
|
ForceDecode bool
|
||||||
|
// Exclude is a list of paths to make inaccessible
|
||||||
|
Exclude []string
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,9 @@ func NewFS(args Args, c *contentenc.ContentEnc, n *nametransform.NameTransform)
|
|||||||
if args.SerializeReads {
|
if args.SerializeReads {
|
||||||
serialize_reads.InitSerializer()
|
serialize_reads.InitSerializer()
|
||||||
}
|
}
|
||||||
|
if len(args.Exclude) > 0 {
|
||||||
|
tlog.Warn.Printf("Forward mode does not support -exclude")
|
||||||
|
}
|
||||||
return &FS{
|
return &FS{
|
||||||
FileSystem: pathfs.NewLoopbackFileSystem(args.Cipherdir),
|
FileSystem: pathfs.NewLoopbackFileSystem(args.Cipherdir),
|
||||||
args: args,
|
args: args,
|
||||||
|
@ -36,6 +36,12 @@ var inodeTable syncmap.Map
|
|||||||
// newFile decrypts and opens the path "relPath" and returns a reverseFile
|
// newFile decrypts and opens the path "relPath" and returns a reverseFile
|
||||||
// object. The backing file descriptor is always read-only.
|
// object. The backing file descriptor is always read-only.
|
||||||
func (rfs *ReverseFS) newFile(relPath string) (*reverseFile, fuse.Status) {
|
func (rfs *ReverseFS) newFile(relPath string) (*reverseFile, fuse.Status) {
|
||||||
|
if rfs.isExcluded(relPath) {
|
||||||
|
// Excluded paths should have been filtered out beforehand. Better safe
|
||||||
|
// than sorry.
|
||||||
|
tlog.Warn.Printf("BUG: newFile: received excluded path %q. This should not happen.", relPath)
|
||||||
|
return nil, fuse.ENOENT
|
||||||
|
}
|
||||||
pRelPath, err := rfs.decryptPath(relPath)
|
pRelPath, err := rfs.decryptPath(relPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fuse.ToStatus(err)
|
return nil, fuse.ToStatus(err)
|
||||||
|
@ -2,7 +2,9 @@ package fusefrontend_reverse
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
@ -14,6 +16,8 @@ import (
|
|||||||
"github.com/rfjakob/gocryptfs/internal/configfile"
|
"github.com/rfjakob/gocryptfs/internal/configfile"
|
||||||
"github.com/rfjakob/gocryptfs/internal/contentenc"
|
"github.com/rfjakob/gocryptfs/internal/contentenc"
|
||||||
"github.com/rfjakob/gocryptfs/internal/cryptocore"
|
"github.com/rfjakob/gocryptfs/internal/cryptocore"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/ctlsock"
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/exitcodes"
|
||||||
"github.com/rfjakob/gocryptfs/internal/fusefrontend"
|
"github.com/rfjakob/gocryptfs/internal/fusefrontend"
|
||||||
"github.com/rfjakob/gocryptfs/internal/nametransform"
|
"github.com/rfjakob/gocryptfs/internal/nametransform"
|
||||||
"github.com/rfjakob/gocryptfs/internal/pathiv"
|
"github.com/rfjakob/gocryptfs/internal/pathiv"
|
||||||
@ -34,6 +38,8 @@ type ReverseFS struct {
|
|||||||
nameTransform *nametransform.NameTransform
|
nameTransform *nametransform.NameTransform
|
||||||
// Content encryption helper
|
// Content encryption helper
|
||||||
contentEnc *contentenc.ContentEnc
|
contentEnc *contentenc.ContentEnc
|
||||||
|
// Relative ciphertext paths to exclude (hide) from the user. Used by -exclude.
|
||||||
|
cExclude []string
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ pathfs.FileSystem = &ReverseFS{}
|
var _ pathfs.FileSystem = &ReverseFS{}
|
||||||
@ -43,7 +49,7 @@ var _ pathfs.FileSystem = &ReverseFS{}
|
|||||||
// ReverseFS provides an encrypted view.
|
// ReverseFS provides an encrypted view.
|
||||||
func NewFS(args fusefrontend.Args, c *contentenc.ContentEnc, n *nametransform.NameTransform) *ReverseFS {
|
func NewFS(args fusefrontend.Args, c *contentenc.ContentEnc, n *nametransform.NameTransform) *ReverseFS {
|
||||||
initLongnameCache()
|
initLongnameCache()
|
||||||
return &ReverseFS{
|
fs := &ReverseFS{
|
||||||
// pathfs.defaultFileSystem returns ENOSYS for all operations
|
// pathfs.defaultFileSystem returns ENOSYS for all operations
|
||||||
FileSystem: pathfs.NewDefaultFileSystem(),
|
FileSystem: pathfs.NewDefaultFileSystem(),
|
||||||
loopbackfs: pathfs.NewLoopbackFileSystem(args.Cipherdir),
|
loopbackfs: pathfs.NewLoopbackFileSystem(args.Cipherdir),
|
||||||
@ -51,6 +57,22 @@ func NewFS(args fusefrontend.Args, c *contentenc.ContentEnc, n *nametransform.Na
|
|||||||
nameTransform: n,
|
nameTransform: n,
|
||||||
contentEnc: c,
|
contentEnc: c,
|
||||||
}
|
}
|
||||||
|
if len(args.Exclude) > 0 {
|
||||||
|
for _, dirty := range args.Exclude {
|
||||||
|
clean := ctlsock.SanitizePath(dirty)
|
||||||
|
if clean != dirty {
|
||||||
|
tlog.Warn.Printf("-exclude: non-canonical path %q has been interpreted as %q", dirty, clean)
|
||||||
|
}
|
||||||
|
cPath, err := fs.EncryptPath(clean)
|
||||||
|
if err != nil {
|
||||||
|
tlog.Fatal.Printf("-exclude: EncryptPath %q failed: %v", clean, err)
|
||||||
|
os.Exit(exitcodes.ExcludeError)
|
||||||
|
}
|
||||||
|
fs.cExclude = append(fs.cExclude, cPath)
|
||||||
|
}
|
||||||
|
tlog.Debug.Printf("-exclude: %v -> %v", fs.args.Exclude, fs.cExclude)
|
||||||
|
}
|
||||||
|
return fs
|
||||||
}
|
}
|
||||||
|
|
||||||
// relDir is identical to filepath.Dir excepts that it returns "" when
|
// relDir is identical to filepath.Dir excepts that it returns "" when
|
||||||
@ -64,6 +86,21 @@ func relDir(path string) string {
|
|||||||
return dir
|
return dir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isExcluded finds out if relative ciphertext path "relPath" is excluded
|
||||||
|
// (used when -exclude is passed by the user)
|
||||||
|
func (rfs *ReverseFS) isExcluded(relPath string) bool {
|
||||||
|
for _, e := range rfs.cExclude {
|
||||||
|
if e == relPath {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// Files inside an excluded directory are also excluded
|
||||||
|
if strings.HasPrefix(relPath, e+"/") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// isDirIV determines if the path points to a gocryptfs.diriv file
|
// isDirIV determines if the path points to a gocryptfs.diriv file
|
||||||
func (rfs *ReverseFS) isDirIV(relPath string) bool {
|
func (rfs *ReverseFS) isDirIV(relPath string) bool {
|
||||||
if rfs.args.PlaintextNames {
|
if rfs.args.PlaintextNames {
|
||||||
@ -99,6 +136,9 @@ func (rfs *ReverseFS) isTranslatedConfig(relPath string) bool {
|
|||||||
// GetAttr - FUSE call
|
// GetAttr - FUSE call
|
||||||
// "relPath" is the relative ciphertext path
|
// "relPath" is the relative ciphertext path
|
||||||
func (rfs *ReverseFS) GetAttr(relPath string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
|
func (rfs *ReverseFS) GetAttr(relPath string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
|
||||||
|
if rfs.isExcluded(relPath) {
|
||||||
|
return nil, fuse.ENOENT
|
||||||
|
}
|
||||||
// Handle "gocryptfs.conf"
|
// Handle "gocryptfs.conf"
|
||||||
if rfs.isTranslatedConfig(relPath) {
|
if rfs.isTranslatedConfig(relPath) {
|
||||||
absConfPath, _ := rfs.abs(configfile.ConfReverseName, nil)
|
absConfPath, _ := rfs.abs(configfile.ConfReverseName, nil)
|
||||||
@ -180,6 +220,9 @@ func (rfs *ReverseFS) GetAttr(relPath string, context *fuse.Context) (*fuse.Attr
|
|||||||
|
|
||||||
// Access - FUSE call
|
// Access - FUSE call
|
||||||
func (rfs *ReverseFS) Access(relPath string, mode uint32, context *fuse.Context) fuse.Status {
|
func (rfs *ReverseFS) Access(relPath string, mode uint32, context *fuse.Context) fuse.Status {
|
||||||
|
if rfs.isExcluded(relPath) {
|
||||||
|
return fuse.ENOENT
|
||||||
|
}
|
||||||
if rfs.isTranslatedConfig(relPath) || rfs.isDirIV(relPath) || rfs.isNameFile(relPath) {
|
if rfs.isTranslatedConfig(relPath) || rfs.isDirIV(relPath) || rfs.isNameFile(relPath) {
|
||||||
// access(2) R_OK flag for checking if the file is readable, always 4 as defined in POSIX.
|
// access(2) R_OK flag for checking if the file is readable, always 4 as defined in POSIX.
|
||||||
ROK := uint32(0x4)
|
ROK := uint32(0x4)
|
||||||
@ -203,6 +246,9 @@ func (rfs *ReverseFS) Access(relPath string, mode uint32, context *fuse.Context)
|
|||||||
|
|
||||||
// Open - FUSE call
|
// Open - FUSE call
|
||||||
func (rfs *ReverseFS) Open(relPath string, flags uint32, context *fuse.Context) (fuseFile nodefs.File, status fuse.Status) {
|
func (rfs *ReverseFS) Open(relPath string, flags uint32, context *fuse.Context) (fuseFile nodefs.File, status fuse.Status) {
|
||||||
|
if rfs.isExcluded(relPath) {
|
||||||
|
return nil, fuse.ENOENT
|
||||||
|
}
|
||||||
if rfs.isTranslatedConfig(relPath) {
|
if rfs.isTranslatedConfig(relPath) {
|
||||||
return rfs.loopbackfs.Open(configfile.ConfReverseName, flags, context)
|
return rfs.loopbackfs.Open(configfile.ConfReverseName, flags, context)
|
||||||
}
|
}
|
||||||
@ -242,6 +288,9 @@ func (rfs *ReverseFS) openDirPlaintextnames(relPath string, entries []fuse.DirEn
|
|||||||
|
|
||||||
// OpenDir - FUSE readdir call
|
// OpenDir - FUSE readdir call
|
||||||
func (rfs *ReverseFS) OpenDir(cipherPath string, context *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
|
func (rfs *ReverseFS) OpenDir(cipherPath string, context *fuse.Context) ([]fuse.DirEntry, fuse.Status) {
|
||||||
|
if rfs.isExcluded(cipherPath) {
|
||||||
|
return nil, fuse.ENOENT
|
||||||
|
}
|
||||||
relPath, err := rfs.decryptPath(cipherPath)
|
relPath, err := rfs.decryptPath(cipherPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fuse.ToStatus(err)
|
return nil, fuse.ToStatus(err)
|
||||||
@ -292,6 +341,21 @@ func (rfs *ReverseFS) OpenDir(cipherPath string, context *fuse.Context) ([]fuse.
|
|||||||
}
|
}
|
||||||
entries[i].Name = cName
|
entries[i].Name = cName
|
||||||
}
|
}
|
||||||
|
// Filter out excluded entries
|
||||||
|
if rfs.cExclude != nil {
|
||||||
|
filtered := make([]fuse.DirEntry, 0, len(entries))
|
||||||
|
for _, entry := range entries {
|
||||||
|
// filepath.Join handles the case of cipherPath="" correctly:
|
||||||
|
// Join("", "foo") -> "foo". This does not: cipherPath + "/" + name"
|
||||||
|
p := filepath.Join(cipherPath, entry.Name)
|
||||||
|
if rfs.isExcluded(p) {
|
||||||
|
// Skip file
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filtered = append(filtered, entry)
|
||||||
|
}
|
||||||
|
entries = filtered
|
||||||
|
}
|
||||||
entries = append(entries, virtualFiles[:nVirtual]...)
|
entries = append(entries, virtualFiles[:nVirtual]...)
|
||||||
return entries, fuse.OK
|
return entries, fuse.OK
|
||||||
}
|
}
|
||||||
@ -301,7 +365,10 @@ func (rfs *ReverseFS) OpenDir(cipherPath string, context *fuse.Context) ([]fuse.
|
|||||||
// Securing statfs against symlink races seems to be more trouble than
|
// Securing statfs against symlink races seems to be more trouble than
|
||||||
// it's worth, so we just ignore the path and always return info about the
|
// it's worth, so we just ignore the path and always return info about the
|
||||||
// backing storage root dir.
|
// backing storage root dir.
|
||||||
func (rfs *ReverseFS) StatFs(path string) *fuse.StatfsOut {
|
func (rfs *ReverseFS) StatFs(relPath string) *fuse.StatfsOut {
|
||||||
|
if rfs.isExcluded(relPath) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
var s syscall.Statfs_t
|
var s syscall.Statfs_t
|
||||||
err := syscall.Statfs(rfs.args.Cipherdir, &s)
|
err := syscall.Statfs(rfs.args.Cipherdir, &s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -314,6 +381,9 @@ func (rfs *ReverseFS) StatFs(path string) *fuse.StatfsOut {
|
|||||||
|
|
||||||
// Readlink - FUSE call
|
// Readlink - FUSE call
|
||||||
func (rfs *ReverseFS) Readlink(relPath string, context *fuse.Context) (string, fuse.Status) {
|
func (rfs *ReverseFS) Readlink(relPath string, context *fuse.Context) (string, fuse.Status) {
|
||||||
|
if rfs.isExcluded(relPath) {
|
||||||
|
return "", fuse.ENOENT
|
||||||
|
}
|
||||||
dirfd, name, err := rfs.openBackingDir(relPath)
|
dirfd, name, err := rfs.openBackingDir(relPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fuse.ToStatus(err)
|
return "", fuse.ToStatus(err)
|
||||||
|
5
main.go
5
main.go
@ -212,6 +212,11 @@ func main() {
|
|||||||
// "-reverse" implies "-aessiv"
|
// "-reverse" implies "-aessiv"
|
||||||
if args.reverse {
|
if args.reverse {
|
||||||
args.aessiv = true
|
args.aessiv = true
|
||||||
|
} else {
|
||||||
|
if args.exclude != nil {
|
||||||
|
tlog.Fatal.Printf("-exclude only works in reverse mode")
|
||||||
|
os.Exit(exitcodes.ExcludeError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// "-config"
|
// "-config"
|
||||||
if args.config != "" {
|
if args.config != "" {
|
||||||
|
1
mount.go
1
mount.go
@ -196,6 +196,7 @@ func initFuseFrontend(args *argContainer) (pfs pathfs.FileSystem, wipeKeys func(
|
|||||||
SerializeReads: args.serialize_reads,
|
SerializeReads: args.serialize_reads,
|
||||||
ForceDecode: args.forcedecode,
|
ForceDecode: args.forcedecode,
|
||||||
ForceOwner: args._forceOwner,
|
ForceOwner: args._forceOwner,
|
||||||
|
Exclude: args.exclude,
|
||||||
}
|
}
|
||||||
// confFile is nil when "-zerokey" or "-masterkey" was used
|
// confFile is nil when "-zerokey" or "-masterkey" was used
|
||||||
if confFile != nil {
|
if confFile != nil {
|
||||||
|
@ -484,3 +484,14 @@ func TestMissingOArg(t *testing.T) {
|
|||||||
exitcodes.Usage, exitCode)
|
exitcodes.Usage, exitCode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -exclude must return an error in forward mode
|
||||||
|
func TestExcludeForward(t *testing.T) {
|
||||||
|
dir := test_helpers.InitFS(t)
|
||||||
|
mnt := dir + ".mnt"
|
||||||
|
err := test_helpers.Mount(dir, mnt, false, "-extpass", "echo test", "-exclude", "foo")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("-exclude in forward mode should fail")
|
||||||
|
}
|
||||||
|
t.Log(err)
|
||||||
|
}
|
||||||
|
104
tests/reverse/exclude_test.go
Normal file
104
tests/reverse/exclude_test.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package reverse_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/rfjakob/gocryptfs/internal/ctlsock"
|
||||||
|
"github.com/rfjakob/gocryptfs/tests/test_helpers"
|
||||||
|
)
|
||||||
|
|
||||||
|
const xxx = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
||||||
|
|
||||||
|
/*
|
||||||
|
tree exclude_test_fs
|
||||||
|
exclude_test_fs/
|
||||||
|
├── dir1
|
||||||
|
│ ├── file1
|
||||||
|
│ ├── file2
|
||||||
|
│ ├── longfile1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
│ └── longfile2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
├── dir2
|
||||||
|
│ ├── file
|
||||||
|
│ ├── longdir1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
│ │ └── file
|
||||||
|
│ ├── longfile.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
│ └── subdir
|
||||||
|
│ └── file
|
||||||
|
├── file1
|
||||||
|
├── file2
|
||||||
|
├── longdir1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
│ └── file
|
||||||
|
├── longdir2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
│ └── file
|
||||||
|
├── longfile1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
└── longfile2xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
*/
|
||||||
|
|
||||||
|
func ctlsockEncryptPath(t *testing.T, sock string, path string) string {
|
||||||
|
req := ctlsock.RequestStruct{EncryptPath: path}
|
||||||
|
response := test_helpers.QueryCtlSock(t, sock, req)
|
||||||
|
if response.ErrNo != 0 {
|
||||||
|
t.Fatal(response)
|
||||||
|
}
|
||||||
|
return response.Result
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExclude(t *testing.T) {
|
||||||
|
pOk := []string{
|
||||||
|
"file2",
|
||||||
|
"dir1/file1",
|
||||||
|
"dir1/longfile1" + xxx,
|
||||||
|
"longdir1" + xxx,
|
||||||
|
"longdir1" + xxx + "/file",
|
||||||
|
"longfile1" + xxx,
|
||||||
|
}
|
||||||
|
pExclude := []string{
|
||||||
|
"file1",
|
||||||
|
"dir1/file2",
|
||||||
|
"dir1/longfile2" + xxx,
|
||||||
|
"dir2",
|
||||||
|
"dir2/file",
|
||||||
|
"dir2/file/xxx",
|
||||||
|
"dir2/subdir",
|
||||||
|
"dir2/subdir/file",
|
||||||
|
"dir2/longdir1" + xxx + "/file",
|
||||||
|
"dir2/longfile." + xxx,
|
||||||
|
"longfile2" + xxx,
|
||||||
|
}
|
||||||
|
// Mount reverse fs
|
||||||
|
mnt, err := ioutil.TempDir(test_helpers.TmpDir, "TestExclude")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
sock := mnt + ".sock"
|
||||||
|
cliArgs := []string{"-reverse", "-extpass", "echo test", "-ctlsock", sock}
|
||||||
|
for _, v := range pExclude {
|
||||||
|
cliArgs = append(cliArgs, "-exclude", v)
|
||||||
|
}
|
||||||
|
if plaintextnames {
|
||||||
|
cliArgs = append(cliArgs, "-config", "exclude_test_fs/.gocryptfs.reverse.conf.plaintextnames")
|
||||||
|
}
|
||||||
|
test_helpers.MountOrFatal(t, "exclude_test_fs", mnt, cliArgs...)
|
||||||
|
defer test_helpers.UnmountPanic(mnt)
|
||||||
|
// Get encrypted version of "ok" and "excluded" paths
|
||||||
|
cOk := make([]string, len(pOk))
|
||||||
|
cExclude := make([]string, len(pExclude))
|
||||||
|
for i, v := range pOk {
|
||||||
|
cOk[i] = ctlsockEncryptPath(t, sock, v)
|
||||||
|
}
|
||||||
|
for i, v := range pExclude {
|
||||||
|
cExclude[i] = ctlsockEncryptPath(t, sock, v)
|
||||||
|
}
|
||||||
|
// Check that "excluded" paths are not there and "ok" paths are there
|
||||||
|
for i, v := range cExclude {
|
||||||
|
if test_helpers.VerifyExistence(mnt + "/" + v) {
|
||||||
|
t.Errorf("File %q / %q is visible, but should be excluded", pExclude[i], v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i, v := range cOk {
|
||||||
|
if !test_helpers.VerifyExistence(mnt + "/" + v) {
|
||||||
|
t.Errorf("File %q / %q is hidden, but should be visible", pOk[i], v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
tests/reverse/exclude_test_fs/.gocryptfs.reverse.conf
Normal file
21
tests/reverse/exclude_test_fs/.gocryptfs.reverse.conf
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"Creator": "gocryptfs v1.5-41-gf48b731-dirty",
|
||||||
|
"EncryptedKey": "FkACqloUeFZesem0UzRD3ezLXtPl8wIAxEHoIEfZxFdLMQeWOxqtw5xopJagDWE/GI1VFSUIrJIIIwwgMipmYA==",
|
||||||
|
"ScryptObject": {
|
||||||
|
"Salt": "UVfIgV31uj/voHWI4GqGwsTcbVKyYDOWvbleqJKhZbk=",
|
||||||
|
"N": 1024,
|
||||||
|
"R": 8,
|
||||||
|
"P": 1,
|
||||||
|
"KeyLen": 32
|
||||||
|
},
|
||||||
|
"Version": 2,
|
||||||
|
"FeatureFlags": [
|
||||||
|
"GCMIV128",
|
||||||
|
"HKDF",
|
||||||
|
"DirIV",
|
||||||
|
"EMENames",
|
||||||
|
"LongNames",
|
||||||
|
"Raw64",
|
||||||
|
"AESSIV"
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"Creator": "gocryptfs v1.5-41-gf48b731-dirty",
|
||||||
|
"EncryptedKey": "wAmckZb7QsIv/GCdkhb5ep8TwJa44qhnswn5tbER6Tifk8TbUmkwBTceaTtYfHAnTQ48q9mnIlcN9cfbNe5oPw==",
|
||||||
|
"ScryptObject": {
|
||||||
|
"Salt": "o5XJ78TgG85zZXRnU55ZqHhKLbPge6jsyDiqrLvSqe0=",
|
||||||
|
"N": 1024,
|
||||||
|
"R": 8,
|
||||||
|
"P": 1,
|
||||||
|
"KeyLen": 32
|
||||||
|
},
|
||||||
|
"Version": 2,
|
||||||
|
"FeatureFlags": [
|
||||||
|
"GCMIV128",
|
||||||
|
"HKDF",
|
||||||
|
"PlaintextNames",
|
||||||
|
"AESSIV"
|
||||||
|
]
|
||||||
|
}
|
0
tests/reverse/exclude_test_fs/dir1/file1
Normal file
0
tests/reverse/exclude_test_fs/dir1/file1
Normal file
0
tests/reverse/exclude_test_fs/dir1/file2
Normal file
0
tests/reverse/exclude_test_fs/dir1/file2
Normal file
0
tests/reverse/exclude_test_fs/dir2/file
Normal file
0
tests/reverse/exclude_test_fs/dir2/file
Normal file
0
tests/reverse/exclude_test_fs/dir2/subdir/file
Normal file
0
tests/reverse/exclude_test_fs/dir2/subdir/file
Normal file
0
tests/reverse/exclude_test_fs/file1
Normal file
0
tests/reverse/exclude_test_fs/file1
Normal file
0
tests/reverse/exclude_test_fs/file2
Normal file
0
tests/reverse/exclude_test_fs/file2
Normal file
Loading…
x
Reference in New Issue
Block a user