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`.
This commit is contained in:
google-labs-jules[bot] 2025-11-14 14:12:31 +00:00
parent 3398fabb14
commit 38bce5acde
2 changed files with 19 additions and 8 deletions

View file

@ -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)
}
}
}

View file

@ -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)