Skip to content

Last Bell 0.2.6

Choose a tag to compare

@github-actions github-actions released this 04 Sep 16:03
· 36 commits to main since this release

A hardening pass over the parts a careful reader checks first. Seven
changes; none alters what Last Bell watches or sends, and each closes a
gap between what the README promised and what the code guaranteed.

  • Dashboard: beyond loopback, other devices need a key. --host 0.0.0.0 used to put full names and the watcher list on the network
    with no login at all. Now requests from the machine itself still need
    nothing, and every other device needs the dashboard key once: a long
    random string generated on first widened start, kept in the settings
    file, printed as a link (http://raspberrypi.local:8321/?key=…) that
    sets a cookie. lastbell dashboard --show-key prints it again. Binding
    to a public address is refused (the key would cross the internet in the
    clear) unless LASTBELL_DASHBOARD_PUBLIC=1; the right shape there is
    loopback behind a TLS proxy with its own login.

  • Email: the mail server's certificate is now verified. starttls()
    with no context uses Python's unverified default, so anyone between
    the box and the mail server could have presented any certificate and
    read the SMTP password. Both STARTTLS and, new, implicit TLS on port
    465 now verify against the OS trust store.

  • Dashboard: DNS rebinding is refused. Binding to 127.0.0.1 kept the
    network out but not the reader's own browser: a web page could point a
    hostname it controls at 127.0.0.1 and read the dashboard, and the
    Origin check couldn't tell because Origin and Host then agree. The
    dashboard now answers only to loopback, IP literals, .local names,
    the bound address, and LASTBELL_DASHBOARD_HOSTNAMES; anything else
    gets a 421 page saying why and how to allow a name of your own.

  • Settings file: passwords with #, $, quotes, or edge spaces now
    survive the round trip.
    The wizard wrote values bare; python-dotenv
    reads abc #def as abc and expands ${VAR}. The wizard's own check
    used the in-memory value, so it said "go" and the boot-time service
    then failed to sign in. Values that need it are now quoted, the loader
    no longer interpolates, and the wizard reads the password back through
    dotenv before calling it saved.

  • Settings file: owner-only from the first byte. It was written under
    the umask and chmod-ed to 0600 afterwards. It is now written to a
    0600 temp file and moved into place, so a crash mid-write can't leave
    a truncated settings file either.

  • Docker: the compose file works. It mounted a secret that nothing
    read. LASTBELL_PASSWORD_FILE (and _SMTP_FILE, LASTBELL_CANVAS_TOKEN_FILE)
    now name a secret file, and the compose file runs the poller plus a
    loopback-only dashboard.

  • Preflight: the legacy SOAP probe no longer carries your password.
    The deprecation code districts return (UPD5304-00 and friends) comes
    back before any login, so a placeholder learns the same thing. The
    README's "sent to one destination" is now literally true.