134 Commits

Author SHA1 Message Date
michael
fb4322fd33 Committing local changes before initial push to remote
Some checks failed
CI / rust (push) Has been cancelled
CI / pam (push) Has been cancelled
CI / deb (push) Has been cancelled
2026-05-01 07:12:11 -07:00
michael
f5879e1541 docs: phase 13 closeout notes 2026-04-27 20:03:07 -07:00
michael
6cef32df4d feat(pkg): bump changelog UNRELEASED -> noble; urgency=medium (Phase 13 release) 2026-04-27 20:02:01 -07:00
michael
21bf1f5a3f docs(pkg): piuparts test recipe — Ubuntu 24.04, install/remove/purge cycle 2026-04-27 19:54:47 -07:00
michael
c1b8dd6cb0 chore(pkg): lintian sweep — fix obsolete polkit dep, drop dup systemd path, command -v in pam hooks; override deferred manpages and PPA-only warnings
Real fixes:
- authforge-daemon Depends: policykit-1 -> polkitd | policykit-1
  (policykit-1 was renamed; old name is obsolete on noble).
- debian/rules: drop manual install of authforge-daemon.service to
  /lib/systemd/system/ — dh_installsystemd auto-installs to
  /usr/lib/systemd/system/, the manual line caused a file-in-root-and-usr
  duplicate flagged by usrmerge.
- authforge-pam.{postinst,prerm}: replace [ -x /usr/sbin/pam-auth-update ]
  with command -v pam-auth-update — lintian flags hard-coded paths in
  test syntax; command -v is the portable idiom.

Overrides (with rationale in each file):
- no-manual-page on the three binaries — manpages deferred to Phase 18.
- desktop-command-not-in-package authforge in gnome-integration —
  command lives in authforge-gui (cross-package Depends).
- initial-upload-closes-no-bugs on every package — AuthForge ships
  via PPA, not the Debian archive, so there is no ITP to close.

After fixes, lintian on the five binary debs is silent (zero W/E).
2026-04-27 19:54:15 -07:00
michael
0dc108220d feat(pkg): metapackage postinst seeds /etc/authforge/policy.d/00-debconf.conf from debconf answer 2026-04-27 19:33:52 -07:00
michael
753bf54aad feat(pkg): debconf prompt for initial AuthForge policy on metapackage install 2026-04-27 19:19:12 -07:00
michael
cccca786f7 feat(pkg): authforge-daemon postrm purges /etc/authforge and /var/lib/authforge 2026-04-27 18:29:29 -07:00
michael
f9af34cbb3 feat(pkg): authforge-pam prerm calls pam-auth-update --remove on uninstall 2026-04-27 17:36:39 -07:00
michael
41ea0a1af8 feat(pkg): authforge-pam postinst calls pam-auth-update --package 2026-04-27 17:29:15 -07:00
michael
ea75c03f55 feat(pkg): ship baseline pam-configs profile (Default: no, pending-flag only) 2026-04-27 13:34:17 -07:00
michael
129024829b docs(plan): step-level Phase 13 plan — deb finalization (postinst, debconf, purge, lintian) 2026-04-27 13:13:15 -07:00
michael
831fd0152c docs(plan): refresh post-Phase-11 — diagram, sequential-tail status, fanout lesson
ASCII diagram now marks 9/10/11 as  and Phase 13 as next-open.
'What's parallel-safe right now' section replaced with a brief
'all parallelism collected, sequential tail open' note. The deferred-
gates list updated to reflect that Phase 6 + Phase 12-backend pamtester
smoke tests 1-3 ran locally on 2026-04-27 (test 4 still deferred).
Lessons-learned gains a bullet on the prep-lane + 3-worktree fanout.
2026-04-27 13:06:51 -07:00
michael
789ff2b38e docs: refresh README status — Phases 0-12 + 15/16 done; 13/14/17/18 remain 2026-04-27 13:04:42 -07:00
michael
22653ff4ff docs(pam): clarify safe_user contract — pre-filter, not authoritative boundary
x..y is correctly NOT rejected by the slash/dot/empty/NUL guard; the
recipe now documents this as an intentional regression test against
over-rejection. Frames canonicalize-then-verify as Phase 17 follow-up
hardening.
2026-04-27 13:00:11 -07:00
michael
ef70c465b8 docs(pam): correct journalctl recipe — tag is caller-set, grep is universal 2026-04-27 12:57:26 -07:00
michael
99cde28bd2 Merge branch 'feature/phase-11-totp' 2026-04-27 12:22:44 -07:00
michael
974514038f style(daemon): rustfmt reorder TotpEnrollment import alphabetically 2026-04-27 12:20:58 -07:00
michael
0d99498c26 style(gui): rustfmt collapse QR QrCode::new line in totp_page 2026-04-27 12:20:47 -07:00
michael
4b6b95c350 docs: phase 11 closeout notes 2026-04-27 12:15:33 -07:00
michael
334fa5e20b feat(cli): authforgectl totp enroll/status/revoke 2026-04-27 12:12:02 -07:00
michael
8060364973 feat(gui): TOTP tab with QR code modal + revoke (feature-gated) 2026-04-27 12:10:54 -07:00
michael
85c8f29b68 feat(daemon): render pam_google_authenticator.so when TOTP-required stack present 2026-04-27 12:06:05 -07:00
michael
8acf3f8f45 feat(daemon): EnrollTotp + IsTotpEnrolled + RevokeTotp D-Bus methods 2026-04-27 12:06:05 -07:00
michael
5fa81e5757 feat(daemon): wire TotpStore into AppState behind feature gate 2026-04-27 12:06:05 -07:00
michael
c56ed0c9a1 feat(daemon): TotpStore with atomic 0600 writes in pam_google_authenticator format
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 12:06:05 -07:00
michael
e753a33ee4 feat(daemon): TOTP secret generation + base32 + otpauth URI (feature-gated)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 12:06:05 -07:00
michael
30e36ccf5d chore: add totp feature gate (default-on) + data-encoding + qrcode deps
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 12:06:05 -07:00
michael
c64068c4b5 Merge branch 'feature/phase-10-firstrun' 2026-04-27 12:05:18 -07:00
michael
f2e113e403 Merge branch 'feature/phase-9-and-12-gui' 2026-04-27 12:03:49 -07:00
michael
0dd4aaf082 docs(gui): VM smoke recipe for the first-run modal 2026-04-27 11:28:33 -07:00
michael
85dd0c7111 docs: phase 10 closeout notes 2026-04-27 11:28:12 -07:00
michael
611174859c feat(gui): firstrun modal shows Skip button on daemon-unreachable 2026-04-27 11:27:31 -07:00
michael
9021ff0b3c feat(pkg): autostart .desktop entry running authforge --first-run on GNOME login
GNOME-only autostart entry installed to /etc/xdg/autostart/. Uses
X-GNOME-Autostart-Phase=Initialization so it runs before user
autostarts but after GDM hands the session off. NoDisplay=true keeps
it out of the apps menu — autostart-only.

Plan deviation: project uses debian/rules for installation (no
debian/authforge-gui.install file exists), so the install line goes
there instead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:23:28 -07:00
michael
cef468ae7e feat(gui): first-run modal with enrollment + 60s idle watchdog
Replace the prep-lane stub with the real Flow C: a fullscreen,
undecorated adw::ApplicationWindow that queries the daemon's pending
flag for the current user, presents an AdwStatusPage "Get started"
button when a flag is set, runs the Phase 8 enrollment dialog, calls
ClearPendingFlag on success, and exits. A 60s idle watchdog (5s tick)
falls back to gnome-session-quit --logout. EventControllerKey and
GestureClick poke the WatchdogState on activity; missing pending flag
short-circuits to immediate exit so the autostart cost is one D-Bus
call.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:22:40 -07:00
michael
3b519578c5 feat(gui): WatchdogState pure-logic helper for first-run modal
Convert gui/src/firstrun.rs to a module dir with watchdog.rs, the
pure-logic WatchdogState helper that the GTK widget code in Task 2
will poll. Three unit tests cover fresh/expired/poke transitions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:19:46 -07:00
michael
b23df83a2b docs: phase 9 + phase 12 GUI closeout notes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:19:45 -07:00
michael
25eed8ff94 docs(gui): smoke-test recipes for Policy and Recovery tabs
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:18:50 -07:00
michael
008dc160bd feat(gui): Recovery tab with list / generate / revoke + one-shot copy dialog
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:18:29 -07:00
michael
e19ffc9c9b feat(gui): advanced expander surfaces non-master PAM stacks in Policy tab
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:16:51 -07:00
michael
ae372df577 feat(gui): PolicyPage subscribes to PolicyChanged for live refresh
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:16:18 -07:00
michael
a28b5c9ebe feat(gui): Policy tab with three master stacks and lockout-violation banner
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:15:50 -07:00
michael
b2771e73fa feat(gui): pure-logic helpers for Policy tab (mode mapping, violation grouping)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:13:53 -07:00
michael
ec22188440 feat(gui): bus client policy + recovery method wrappers
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 11:12:54 -07:00
michael
712c1e9c1d Merge branch 'feature/prep-shell-and-pending' 2026-04-27 10:56:14 -07:00
michael
2ed95d21da style(daemon): rustfmt collapse get_pending_status match arm
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 10:55:51 -07:00
michael
b8e8368a25 feat(gui): bus::Daemon::{get_pending_status,clear_pending_flag} client wrappers
clear_pending_flag is added alongside get_pending_status because Phase 10
needs both — its first-login modal checks status on startup and clears
the flag on successful enrollment. Bundling here keeps the Phase 10 lane
free of bus.rs edits.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 10:52:14 -07:00
michael
1976971bb5 feat(daemon): GetPendingStatus D-Bus method + 2 integration tests
Drops the #[allow(dead_code)] on AppState::get_pending_status — it's now
called from the D-Bus dispatch. Two new p2p tests cover the absent and
the round-trip cases.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 10:51:25 -07:00
michael
86e3ffe8d5 feat(daemon): AppState::get_pending_status returns wire-friendly bool+flag
has_pending stays #[cfg(test)] because production GUI reads via the new
get_pending_status (one round-trip carries both presence and flag);
production PAM module reads the file directly. Method gated with
#[allow(dead_code)] until Task 5 wires D-Bus.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 10:49:53 -07:00
michael
e1542d6d1f feat(common): PendingStatus wire type + Default impl on PendingFlag
PendingStatus carries an explicit 'present' bool next to a PendingFlag
because zvariant doesn't support Option<T>. Two new serde tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 10:47:01 -07:00