Files
mixandClaude Opus 5.5 a3050afb66
test / test (push) Canceled after 0s
base-trixie: findings of the reviews
Security review (1c6e04b):
- The panel's database and its -wal/-shm were 0644 under a traversable
  /data, holding the panel users' password hashes and session token
  hashes. store.Open now makes them 0600 (SQLite gives the next -wal/-shm
  the database's mode: findCreateFileMode(), unixOpenSharedMemory());
  TestOpenKeepsTheDatabasePrivate.
- The entrypoint removes a symbolic link the panel user could leave where
  a /data directory, table, map, the queue or mail.log is expected, before
  its root steps chmod or create them (drop_links).
- The panel user is 10999:10999, outside the system range: in trixie
  useradd gave it group 998, the host's systemd-network on the test
  server; bookworm's 999 was the host's systemd-journal.
- security.md said the database was 0640; it was 0644.

Technical review (1c6e04b):
- mail_helpers.go: smtp-sink does add a Received: header, "(smtp-sink)"
  (smtp-sink.c:520-531); the "(Postfix)" filter leaves it out.
- CHANGELOG/roadmap: OpenDKIM's signing and From:-parsing code is
  unchanged, not all of it; the retry-policy bug predates 3.9 (any
  postconf warning); three entries moved from Fixed to Changed, as no
  released image had them.
- internal/app/sasl.go: db_dump's stdout alone is parsed.
- mynetworks comment: postinst:180, fset_all_changed.

Tests: on the server, make e2e exit 0 (712 s), go vet + go test 27
packages ok.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 20:05:01 +03:00

44 lines
989 B
Go

package store
import (
"os"
"path/filepath"
"runtime"
"testing"
)
// The database and its WAL and shared-memory files are the panel's alone:
// a file that was 0644 is 0600 after Open, and the -wal and -shm files
// SQLite opens are 0600 too (keepPrivate).
func TestOpenKeepsTheDatabasePrivate(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("file modes are POSIX")
}
path := filepath.Join(t.TempDir(), "selfpost.db")
st, err := Open(path)
if err != nil {
t.Fatal(err)
}
st.Close()
if err := os.Chmod(path, 0o644); err != nil {
t.Fatal(err)
}
st, err = Open(path)
if err != nil {
t.Fatal(err)
}
defer st.Close()
if _, err := st.db.Exec(`PRAGMA user_version`); err != nil {
t.Fatal(err)
}
for _, p := range []string{path, path + "-wal", path + "-shm"} {
fi, err := os.Stat(p)
if err != nil {
t.Fatalf("%s: %v", filepath.Base(p), err)
}
if m := fi.Mode().Perm(); m != 0o600 {
t.Errorf("%s mode %o, want 600", filepath.Base(p), m)
}
}
}