diff --git a/cli_args.go b/cli_args.go index 7743120..ce15448 100644 --- a/cli_args.go +++ b/cli_args.go @@ -10,6 +10,7 @@ import ( "fmt" "net" "os" + "path/filepath" "strconv" "strings" "time" @@ -290,6 +291,15 @@ func parseCliOpts() (args argContainer) { tlog.Fatal.Printf("Idle timeout cannot be less than 0") os.Exit(exitcodes.Usage) } + // Make sure all badname patterns are valid + for _, pattern := range args.badname { + _, err := filepath.Match(pattern, "") + if err != nil { + tlog.Fatal.Printf("-badname: invalid pattern %q supplied", pattern) + os.Exit(exitcodes.Usage) + } + } + return args } diff --git a/internal/fusefrontend/xattr_unit_test.go b/internal/fusefrontend/xattr_unit_test.go index a0cf4c8..c48781c 100644 --- a/internal/fusefrontend/xattr_unit_test.go +++ b/internal/fusefrontend/xattr_unit_test.go @@ -19,7 +19,7 @@ func newTestFS(args Args) *RootNode { key := make([]byte, cryptocore.KeyLen) cCore := cryptocore.New(key, cryptocore.BackendGoGCM, contentenc.DefaultIVBits, true, false) cEnc := contentenc.New(cCore, contentenc.DefaultBS, false) - n := nametransform.New(cCore.EMECipher, true, true) + n := nametransform.New(cCore.EMECipher, true, true, nil) rn := NewRootNode(args, cEnc, n) oneSec := time.Second options := &fs.Options{ diff --git a/internal/nametransform/names.go b/internal/nametransform/names.go index f730184..afc0f5d 100644 --- a/internal/nametransform/names.go +++ b/internal/nametransform/names.go @@ -44,19 +44,23 @@ type NameTransform struct { // on the Raw64 feature flag B64 *base64.Encoding // Patterns to bypass decryption - BadnamePatterns []string + badnamePatterns []string } // New returns a new NameTransform instance. -func New(e *eme.EMECipher, longNames bool, raw64 bool) *NameTransform { +func New(e *eme.EMECipher, longNames bool, raw64 bool, badname []string) *NameTransform { + tlog.Debug.Printf("nametransform.New: longNames=%v, raw64=%v, badname=%q", + longNames, raw64, badname) + b64 := base64.URLEncoding if raw64 { b64 = base64.RawURLEncoding } return &NameTransform{ - emeCipher: e, - longNames: longNames, - B64: b64, + emeCipher: e, + longNames: longNames, + B64: b64, + badnamePatterns: badname, } } @@ -65,7 +69,7 @@ func New(e *eme.EMECipher, longNames bool, raw64 bool) *NameTransform { func (n *NameTransform) DecryptName(cipherName string, iv []byte) (string, error) { res, err := n.decryptName(cipherName, iv) if err != nil { - for _, pattern := range n.BadnamePatterns { + for _, pattern := range n.badnamePatterns { match, err := filepath.Match(pattern, cipherName) if err == nil && match { // Pattern should have been validated already // Find longest decryptable substring @@ -142,5 +146,5 @@ func (n *NameTransform) B64DecodeString(s string) ([]byte, error) { // HaveBadnamePatterns returns true if BadName patterns were provided func (n *NameTransform) HaveBadnamePatterns() bool { - return len(n.BadnamePatterns) > 0 + return len(n.badnamePatterns) > 0 } diff --git a/mount.go b/mount.go index e35e6c2..7f818d1 100644 --- a/mount.go +++ b/mount.go @@ -313,18 +313,7 @@ func initFuseFrontend(args *argContainer) (rootNode fs.InodeEmbedder, wipeKeys f // Init crypto backend cCore := cryptocore.New(masterkey, cryptoBackend, contentenc.DefaultIVBits, args.hkdf, args.forcedecode) cEnc := contentenc.New(cCore, contentenc.DefaultBS, args.forcedecode) - nameTransform := nametransform.New(cCore.EMECipher, frontendArgs.LongNames, args.raw64) - // Init badname patterns - nameTransform.BadnamePatterns = make([]string, 0) - for _, pattern := range args.badname { - _, err := filepath.Match(pattern, "") // Make sure pattern is valid - if err != nil { - tlog.Fatal.Printf("-badname: invalid pattern %q supplied", pattern) - os.Exit(exitcodes.Usage) - } else { - nameTransform.BadnamePatterns = append(nameTransform.BadnamePatterns, pattern) - } - } + nameTransform := nametransform.New(cCore.EMECipher, frontendArgs.LongNames, args.raw64, []string(args.badname)) // After the crypto backend is initialized, // we can purge the master key from memory. for i := range masterkey {