Add HTTP Basic auth on /upload, reading an Apache htpasswd file (bcrypt
only, `htpasswd -B`) via a new -htpasswd flag. This lets nginx drop to a
plain TLS-terminating reverse proxy with no auth of its own; the existing
bcrypt htpasswd file is reused unchanged.
auth.go:
- LoadHtpasswd parses user:hash lines, keeps bcrypt entries ($2a/$2b/$2y,
so Apache's $2y$ works), skips MD5/SHA/crypt with a warning.
- Unknown users still pay for one bcrypt comparison against a dummy hash,
so response timing can't enumerate valid usernames.
- Failed attempts draw from a token-bucket limiter (x/time/rate, ~1/s,
burst 10) returning 429 once drained; successful and bulk uploads never
touch it.
server.go guards both /upload routes (nil authenticator = passthrough for
local --serve). /health stays open. Empty -htpasswd disables auth and logs
a warning.
module.nix: new top-level services.photogallery.htpasswdFile, delivered to
the service via systemd LoadCredential (so a root-owned 0400 secret works).
Removed nginx.htpasswdFile and basic_auth from the vhost.
Both uploader apps already send Basic credentials, so no client change.
Deps: golang.org/x/crypto/bcrypt, golang.org/x/time/rate (vendorHash bump).