v0.5.0 — Selectable chat-alert categories
Minor release. Adds the first user-configurable filter over chat alerts — enable_notification_type lets operators opt in to specific event categories (login_success, login_failed, session_open, session_close, brute_force, all) rather than receiving every PAM event. Requested by @huy-lv (#22) for the common deployment shape where the host's notable signal is "someone got in" rather than "someone tried." The filter gates chat dispatch only — journalctl -t pamsignal still records every event, so the forensic trail and threat-model assumptions are unchanged. Default is all, so existing deployments behave identically without touching their config. Beneath the new filter, the existing per-event suppression for sudo/su LOGIN_FAILED (only the brute-force aggregate fires for those services) is untouched. Also ships two transitive-dependency security bumps in the bundled example receivers (idna CVE-2026-45409 in the Python receiver, qs CVE-2026-8723 in the Node.js receiver) — neither affects the C daemon, but the examples need to install cleanly into their own ecosystems. Internal: 13 new CMocka cases (9 config + 4 notify gating), zero new build warnings, ASVS L1 pre-merge gate clean.
Features
-
enable_notification_typeconfig key — select which event categories fire a chat alert (#22). Reported by @huy-lv. Comma-separated list of tokens:login_success,login_failed,session_open,session_close,brute_force, orall. Default — when the key is omitted or set toall— is every category, so existing deployments behave unchanged. Filters only the chat dispatch (Telegram / Slack / Teams / WhatsApp / Discord / custom webhook); the localjournalctl -t pamsignaltrail records every event regardless, preserving the forensic record assumed bydocs/threat-model.md. Unknown tokens, empty values, and empty list elements are hard errors at config load (matches the strictness of the existing validators). Implemented as a 5-bit mask onps_config_t.enable_notification_type(PS_NOTIFY_LOGIN_SUCCESS,PS_NOTIFY_LOGIN_FAILED,PS_NOTIFY_SESSION_OPEN,PS_NOTIFY_SESSION_CLOSE,PS_NOTIFY_BRUTE_FORCE);ps_notify_eventgates on the per-event-type bit andps_notify_brute_force/ps_notify_local_brute_forcegate on the brute-force bit. The existing per-event suppression for sudo/suLOGIN_FAILEDinsrc/journal_watch.cis unchanged and layered beneath this filter. Parser handles arbitrary whitespace around list elements and is case-insensitive on token names. Tests: 9 new CMocka cases intests/test_config.c(default = all, single category, multi-category CSV,allsentinel, whitespace + case tolerance, full 5-category list, unknown token rejected, empty value rejected, empty list element rejected, omitted-key keeps default) and 4 new cases intests/test_notify.cexercising the dispatch gate via the file-static cooldown clock (event_notify_bitmapping, gated-off doesn't dispatch, gated-on does dispatch,PS_EVENT_UNKNOWNnever dispatches). Documented indocs/configuration.md(new "Notification-type filter" section with token table, scope note, examples) andpamsignal.conf.example.
Security
-
examples/nodejs-webhook/: bumpqs6.14.2 / 6.15.1 → 6.15.2 inpnpm-lock.yaml(Dependabot alert #2, CVE-2026-8723, CVSS v4 6.3 medium).qs >= 6.11.1, <= 6.15.1throwsTypeErrorsynchronously whenqs.stringifyis called with botharrayFormat: 'comma'andencodeValuesOnly: trueon an array containingnull/undefined— the rawencoderruns beforeskipNulls/strictNullHandlingget a chance to handle the bad element. Under Express the throw is caught by the framework error boundary and returns 500; outside a handler (background jobs, startup paths) it crashes the worker. PAMSignal itself is C and unaffected; the alert fires only on the Express example receiver's transitiveqs(viaexpress,body-parser,formidable,supertest). Pinned via pnpmoverridesinpnpm-workspace.yamlso both 6.14.2 (express 4.x) and 6.15.1 (body-parser / formidable) collapse to the patched 6.15.2;package.jsondirect deps unchanged. All 64 jest tests still pass. -
examples/python-webhook/: bumpidna3.14 → 3.15 inuv.lock(Dependabot alert #1, CVE-2026-45409, CVSS v4 6.9 medium).idna < 3.15is vulnerable to a DoS whenidna.encode()is called with crafted long inputs (e.g."٠" * N):valid_contextoruns before the length-rejection check, re-opening the gap that CVE-2024-3651 was supposed to close. PAMSignal itself is C and unaffected; the alert fires only on the Flask example receiver's transitive dep viarequests. Lockfile-only refresh viauv lock --upgrade-package idna;pyproject.tomlunchanged.