Always save incoming attachments
ober
87382c110d98cddf9d0e58b688280f604e58ef94
--- a/docs/credential-handling.md +++ b/docs/credential-handling.md @@ -41,9 +41,8 @@ delete them after debugging. ## Attachments -Automatic attachment export is off by default. Set -`JERBOA_SIGNAL_AUTO_EXPORT_ATTACHMENTS=1` to copy from the local `signal-cli` -attachment cache to `~/Downloads/jerboa-signal/` or an absolute +Incoming attachments are always copied from the local `signal-cli` attachment +cache to `~/Downloads/jerboa-signal/`, or to the absolute path specified by `JERBOA_SIGNAL_DOWNLOAD_DIR`. Destination names are sanitized, files are created exclusively at mode `0600`, --- a/docs/threat-model.md +++ b/docs/threat-model.md @@ -36,8 +36,7 @@ delegated to `signal-cli`. `JERBOA_SIGNAL_TRACE_SENSITIVE`, `JERBOA_SIGNAL_DB_KEY`, `JERBOA_SIGNAL_DB_KEY_FD`, `JERBOA_SIGNAL_LOG_BACKEND`, `JERBOA_SIGNAL_LOG_PERSIST`, - log batch/retention limits, `JERBOA_SIGNAL_AUTO_EXPORT_ATTACHMENTS`, - attachment quotas, `JERBOA_SIGNAL_DOWNLOAD_DIR`, and + log batch/retention limits, attachment quotas, `JERBOA_SIGNAL_DOWNLOAD_DIR`, and `JERBOA_SIGNAL_CLI_DATA_DIR`. - Local files: `signal-cli` account state, attachments, encrypted logs, migration backups, trace files, removed-conversation state, and themes. @@ -55,7 +54,7 @@ delegated to `signal-cli`. - Write state and trace files through checked paths and safe wrappers. State files created by this app must use mode `0600` when they contain account or preference state. -- Keep automatic attachment export opt-in; enforce count, file, conversation, +- Always export inbound attachments while enforcing count, file, conversation, total, and free-space quotas. Pin regular sources without following symlinks, create mode-0600 destinations exclusively, and reject symlinked roots. - Bound every child stdout/stderr line before JSON parsing or diagnostic output; --- a/signal/attach-save.ss +++ b/signal/attach-save.ss @@ -3,7 +3,7 @@ ;;; ;;; signal-cli already downloads every received attachment into its data dir ;;; (<XDG_DATA_HOME or ~/.local/share>/signal-cli/attachments/<id>[.ext]). This -;;; module can copy those files, when explicitly enabled, into +;;; module copies those files into ;;; ;;; ~/Downloads/jerboa-signal/<conversation>/<original-name> ;;; @@ -36,16 +36,10 @@ (def *export-scan-entry-limit* 100000) (def *copy-collision-limit* 128) - (def (truthy-env? name) - (let ([value (getenv name)]) - (and (string? value) - (or (string-ci=? value "1") - (string-ci=? value "on") - (string-ci=? value "true") - (string-ci=? value "yes"))))) - + ;; Incoming attachments are always exported. This is intentionally not gated by + ;; an environment variable: the TUI tells the user where each file was saved. (def (attachment-auto-export-enabled?) - (truthy-env? "JERBOA_SIGNAL_AUTO_EXPORT_ATTACHMENTS")) + #t) ;; --- entry points ------------------------------------------------------- --- a/tests/test-attachments.ss +++ b/tests/test-attachments.ss @@ -1,5 +1,5 @@ #!chezscheme -;;; Adversarial and concurrent checks for opt-in attachment export. +;;; Adversarial and concurrent checks for always-on attachment export. (import (except (scheme) make-hash-table hash-table? @@ -99,12 +99,12 @@ (configure-export! base data-dir) -;; Export is disabled unless the operator explicitly opts in. +;; Incoming attachments are exported without an opt-in environment setting. (putenv "JERBOA_SIGNAL_AUTO_EXPORT_ATTACHMENTS" "") -(check "attachment export is opt-in" - (null? (save-envelope-attachments! - (envelope "Alice" (list (attachment "id-1" "report.txt")))))) -(check "disabled export creates no destination root" (not (file-exists? base))) +(let ([saved (save-envelope-attachments! + (envelope "Alice" (list (attachment "id-3" "always.txt"))))]) + (check "attachment export is always enabled" (= (length saved) 1)) + (check "always-enabled export creates destination root" (file-exists? base))) (putenv "JERBOA_SIGNAL_AUTO_EXPORT_ATTACHMENTS" "1") ;; Concurrent duplicate notifications produce one restrictive destination.