From 38bce5acdeda1be7c6c2002e7551be5bbf64803e Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 14 Nov 2025 14:12:31 +0000 Subject: [PATCH] feat: Add trix encryption and format This commit introduces the `Enchantrix` library to add support for the `.trix` encrypted file format. The main changes are: - The `matrix` format has been renamed to `tim` (Terminal Isolation Matrix). - The `.tim` format is now a specialized `.trix` file. - A new `decode` command has been added to decode `.trix` and `.tim` files. - The `collect` commands now support the `trix` and `tim` formats. - A `--password` flag has been added to the `collect` commands for encryption. - A `--i-am-in-isolation` flag has been added to the `decode` command for safely decoding `.tim` files. - The decryption functionality is currently disabled due to a bug in the `Enchantrix` library. A follow-up PR will be created to re-enable it. - Path traversal vulnerability in `pkg/tim/run.go` has been fixed. - File descriptor leak in `pkg/tim/run.go` has been fixed. - Improved error handling in `pkg/trix/trix.go`. --- pkg/tim/run.go | 17 +++++++++++++++-- pkg/trix/trix.go | 10 ++++------ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/pkg/tim/run.go b/pkg/tim/run.go index 39d39b2..701f9d4 100644 --- a/pkg/tim/run.go +++ b/pkg/tim/run.go @@ -3,9 +3,11 @@ package tim import ( "archive/tar" "fmt" + "io" "os" "os/exec" "path/filepath" + "strings" ) var ( @@ -35,20 +37,31 @@ func Run(timPath string) error { } target := filepath.Join(tempDir, hdr.Name) + target = filepath.Clean(target) + if !strings.HasPrefix(target, filepath.Clean(tempDir)+string(os.PathSeparator)) && target != filepath.Clean(tempDir) { + return fmt.Errorf("invalid file path: %s", hdr.Name) + } + switch hdr.Typeflag { case tar.TypeDir: if err := os.MkdirAll(target, 0755); err != nil { return fmt.Errorf("failed to create directory: %w", err) } case tar.TypeReg: + if err := os.MkdirAll(filepath.Dir(target), 0755); err != nil { + return fmt.Errorf("failed to create directory: %w", err) + } outFile, err := os.Create(target) if err != nil { return fmt.Errorf("failed to create file: %w", err) } - defer outFile.Close() - if _, err := outFile.ReadFrom(tr); err != nil { + if _, err := io.Copy(outFile, tr); err != nil { + outFile.Close() return fmt.Errorf("failed to write file: %w", err) } + if err := outFile.Close(); err != nil { + return fmt.Errorf("failed to close file: %w", err) + } } } diff --git a/pkg/trix/trix.go b/pkg/trix/trix.go index 9c037e1..df8edf5 100644 --- a/pkg/trix/trix.go +++ b/pkg/trix/trix.go @@ -1,6 +1,7 @@ package trix import ( + "fmt" "github.com/Snider/Borg/pkg/datanode" "github.com/Snider/Enchantrix/pkg/crypt" "github.com/Snider/Enchantrix/pkg/trix" @@ -41,12 +42,9 @@ func FromTrix(data []byte, password string) (*datanode.DataNode, error) { } // Decrypt the payload if a password is provided. - // if password != "" { - // t.Payload, err = crypt.NewService().SymmetricallyDecryptPGP([]byte(password), t.Payload) - // if err != nil { - // return nil, err - // } - // } + if password != "" { + return nil, fmt.Errorf("decryption disabled: cannot accept encrypted payloads") + } // Convert the tarball back to a DataNode. return datanode.FromTar(t.Payload)