[do not merge] PoC for remote installation support#1274
Conversation
Integrates Cockpit custom authentication handler that enables PIN-based authentication for the installer web UI. Includes systemd socket activation units and authentication script. Co-Authored-By: Jelle van der Waa <jvanderwaa@redhat.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a custom PIN-based authentication mechanism for the Anaconda Web UI, integrating with Cockpit. It adds a new React-based login page, a Python authentication handler script, and the necessary systemd units and configuration files. Several critical issues were identified in the review: the authentication script incorrectly attempts to read from stdout instead of stdin, a missing function reference in the login entry point will cause a runtime error, and there are security concerns regarding hardcoded credentials and insecure logging to /tmp. Additionally, the use of the deprecated unescape function in the login page should be updated to a modern alternative.
|
|
||
|
|
||
| def read_auth_reply(): | ||
| data = read_frame(1) |
| const root = createRoot(document.getElementById("app")); | ||
| root.render(<LoginPage />); | ||
| document.documentElement.setAttribute("dir", cockpit.language_direction); | ||
| document.documentElement.setAttribute("lang", convertToCockpitLang({ lang: cockpit.language })); |
|
|
||
|
|
||
| def main(args): | ||
| logging.basicConfig(filename='/tmp/pin.log', encoding='utf-8', level=logging.DEBUG) |
There was a problem hiding this comment.
Logging to a fixed path in /tmp (e.g., /tmp/pin.log) is a security risk as it is vulnerable to symlink attacks. It is recommended to log to the system journal by writing to stderr (the default for basicConfig when no filename is provided) or to use a secure temporary file creation method.
| logging.basicConfig(filename='/tmp/pin.log', encoding='utf-8', level=logging.DEBUG) | |
| logging.basicConfig(level=logging.DEBUG) |
| setIsLoading(true); | ||
|
|
||
| const headers = { | ||
| Authorization: "Basic " + window.btoa(unescape(encodeURIComponent(pin))), |
| send_problem_init("internal-error", str(e), {}) | ||
| raise | ||
|
|
||
| if password != "1234": |
Context
Proof-of-concept for PIN-based authentication as part of the remote installation feature (INSTALLER-4395 / INSTALLER-3723).
Do not merge — keeping this open while the broader design is worked out. It was the basis for the team demo on April 8 and drove the architectural decisions we've aligned on since.
What This Demonstrates
Cockpit (the framework Anaconda's Web UI is built on) lets you replace its default login page and authentication handler with custom implementations. This PoC exercises both:
Custom login page
src/components/login/LoginPage.jsx, built intologin.html/login.js. A minimal PIN entry form — shows/hides the PIN, submits it as a Basic auth header (PIN as username). Cockpit routes that to the custom auth handler.Wired up via
[WebService] CustomLoginPageincockpit.conf.Custom auth handler
src/scripts/cockpit-pin-auth— a Python script that speaks Cockpit's auth protocol over a Unix socket. Receives the Basic auth credentials from Cockpit, validates the PIN, and if correct, exec'scockpit.bridgeto start the actual installer session.Deployed as a socket-activated systemd unit (
cockpit-pin-auth.socket+cockpit-pin-auth@.service), separate from the main cockpit-ws process. Each connection spawns a fresh instance. After the PIN is accepted, Cockpit's session cookie takes over.Cockpit config
src/config/cockpit.confsetsCustomLoginPageand overrides the[Basic]auth command. Currently installs to/etc/cockpit/cockpit.conf.Known issue: config path should move to an anaconda-owned path (e.g.,
/etc/anaconda/cockpit/) so it doesn't persist to the installed system. Tracked as a follow-up.How to Try It
Build an updates image and run it against a Fedora Rawhide boot ISO:
Then boot a Rawhide installer with
inst.updatespointing to the generatedupdates.img, for example withvirt-install:The PIN is hardcoded to
1234insrc/scripts/cockpit-pin-auth. Once the installer is running, point a browser at the VM's IP on port 80 — you'll get the custom login page. Enter1234to authenticate.Session behavior observed in the demo: tab close preserves the session (cookie survives), browser close requires re-login.
What's Deliberately Incomplete
1234. Real implementation would read from a boot parameter and display on the local console./etc/cockpit/— should be anaconda-owned.What We're Looking For
If you're looking at this from the Cockpit side: