test / test (push) Canceled after 0s
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>
44 lines
989 B
Go
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)
|
|
}
|
|
}
|
|
}
|