docs, comments: the drift the audit listed (audit 2026-10-17, stage 6)
The lines under "Doc and comment drift" that the findings' own commits did not already fix: - security.md: a newer confirmation link replaces the older, a reset link is not replaced; html/template renders every page (no themes); the container keeps eight capabilities, named, not "KILL". - architecture.md: ImportKey writes over a name's key, as an import must; the error text reaches the browser on the Backup page's import refusal. - guide: with Caddy the key is in Caddy's data, so a full backup refuses until certs/ holds a copy (or back up caddy-data). - comments: sasldb2 holds application passwords in the clear (store, app/password.go); texthash folds ASCII (sender.go); the supervisor socket's group is supervisor (rpc.go); cert-reload's OpenSSL measurement was 3.0.x of bookworm; sendReset's limits (links.go). Migration 0013's comment stays as shipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,8 @@ const passwordBytes = 24
|
||||
|
||||
// generatePassword returns a strong, URL-safe random password for an
|
||||
// application's SASL account. The panel generates it, shows it once and never
|
||||
// stores the plaintext (security.md); sasldb2 keeps only the hashed form.
|
||||
// stores it in its own database; sasldb2 keeps it, in the clear, as Cyrus
|
||||
// does for PLAIN and LOGIN (security.md).
|
||||
//
|
||||
// base64url output keeps the password to a safe ASCII alphabet with no shell or
|
||||
// SMTP-special characters, so it survives being typed into client configuration
|
||||
|
||||
@@ -202,11 +202,12 @@ func splitTableLine(line string) (key, value string, ok bool) {
|
||||
// tries for a local domain is never a key here: every key the panel writes
|
||||
// has an "@" (internal/postfix renderSenderLoginMaps).
|
||||
//
|
||||
// Case is folded in ASCII only. Postfix folds as Unicode (src/util/casefold.c
|
||||
// with ICU, which Debian builds with), but every key and login the panel
|
||||
// writes is ASCII; a Unicode fold would only let a look-alike pass - the
|
||||
// Kelvin sign for "k" - for an address that is not the domain's (review of
|
||||
// stage 2c).
|
||||
// Case is folded in ASCII only, as Postfix folds the keys of the texthash
|
||||
// map the panel writes (src/util/dict_thash.c:113 and dict_ht.c:58-64,
|
||||
// lowercase(): ASCII; security audit 2026-10-17 corrected this comment, which
|
||||
// said Unicode). Every key and login the panel writes is ASCII; a Unicode fold
|
||||
// would only let a look-alike pass - the Kelvin sign for "k" - for an address
|
||||
// that is not the domain's (review of stage 2c).
|
||||
func (b *Bindings) Allowed(login, addr string) (bool, error) {
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
@@ -29,8 +29,8 @@ const (
|
||||
|
||||
// Application is a SASL account bound to a single domain (product.md §
|
||||
// Multi-domain model). The password is never stored here — only in sasldb2,
|
||||
// hashed — so it can be shown exactly once at creation/regeneration
|
||||
// (security.md). Addresses is populated only in 'list' mode.
|
||||
// which Cyrus keeps in the clear (PLAIN and LOGIN need it; security.md) — so
|
||||
// it can be shown exactly once at creation/regeneration. Addresses is populated only in 'list' mode.
|
||||
type Application struct {
|
||||
ID int64
|
||||
DomainID int64
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
// socketPath is supervisord's control socket: build/supervisord.conf,
|
||||
// [unix_http_server] file=, group selfpost, which the panel is in.
|
||||
// [unix_http_server] file=, group supervisor, whose one member is the panel.
|
||||
const socketPath = "/run/supervisor.sock"
|
||||
|
||||
// runOnceFor bounds RunOnce: a reload that is still running after it is
|
||||
|
||||
@@ -168,7 +168,8 @@ func (m *Module) HandleReset(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// sendReset mails the account named username a reset link if its address is
|
||||
// confirmed, at most three an hour.
|
||||
// confirmed: not within resetSpacing of the last, five a day (then one
|
||||
// notice) and five an hour.
|
||||
func (m *Module) sendReset(username string) {
|
||||
if username == "" || m.mailer == nil || m.cfg.Hostname == "" {
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user