Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

beiboot: feature parity with cockpit-ssh #19401

Merged
merged 9 commits into from
Sep 23, 2024

Commits on Sep 19, 2024

  1. doc: Clean up Ssh-Login in authentication.md

    Consistently spell the section "Ssh-Login". This makes it easier to
    grep.
    
    Document the current behaviour that the specified `host` will not have
    its host key checked.
    
    Fix indentation of the `connectToUnknownHosts` paragraph.
    martinpitt committed Sep 19, 2024
    Configuration menu
    Copy the full SHA
    48afe00 View commit details
    Browse the repository at this point in the history
  2. login: Refactor host key database API

    We only ever need to get or update the keys for a particular host. So
    replace the current direct database manipulation with
    `{get,set}_hostkeys()`. This will come in handy in the next commits
    when we need to update the host keys from multiple places.
    martinpitt committed Sep 19, 2024
    Configuration menu
    Copy the full SHA
    38140e6 View commit details
    Browse the repository at this point in the history
  3. beiboot: support for temporary UserKnownHostsFile

    In the bastion host case, create a temporary UserKnownHostsFile for ssh
    and populate it with data from the authorization (if provided).  On
    successful login, send the updated key data back to the user via the
    long-disused `x-login-data` mechanism.  That'll get it added to the JSON
    blob that is sent as the reply to the `GET /login` request. On failed
    login, send the key data as part of the Cockpit protocol error, in a
    `known-hosts` attribute.
    
    Co-Authored-By: Martin Pitt <[email protected]>
    allisonkarlitskaya and martinpitt committed Sep 19, 2024
    Configuration menu
    Copy the full SHA
    e3d5b0e View commit details
    Browse the repository at this point in the history
  4. test: Make TestClient use beiboot's "flatpak" code path

    Mock enough of the flatpak environment (/.flatpak-info and
    `flatpak-spawn` wrapper) to make beiboot.py take its
    `connect_from_flatpak()` code path. This makes the test more realistic.
    martinpitt committed Sep 19, 2024
    Configuration menu
    Copy the full SHA
    2c15eb8 View commit details
    Browse the repository at this point in the history
  5. beiboot: Don't retry bad password three times

    In bastion mode, we previously used the default 3 password prompts, and
    sending the same password every time. This just unnecessarily trigges
    `faillock` and takes too long. Do the same as in "remote channel" bridge
    mode (`SshPeer` in remote.py).
    
    This can be dropped if/when we rework the whole machinery to not restart
    ssh from scratch with each new authentication attempt, and just follow
    the conversation.
    martinpitt committed Sep 19, 2024
    Configuration menu
    Copy the full SHA
    b59c570 View commit details
    Browse the repository at this point in the history
  6. beiboot: Use distinct X-Conversation nonces

    Using a constant `-` for the authorization challenge is problematic: The
    login page load always starts with an initial generic auth challenge,
    which gets cleaned up (in `cockpit_session_reset()`) after some time.
    When the second challenge (for e.g. an unknown host key) then uses the
    same `-` challenge, ws fails with "Invalid conversation token: -".
    
    Avoid this by using an *actual* nonce: Combine the pid and time to a
    value that is reasonably unique to avoid collisions.
    
    Also add an assertion that the returned challenge is the one that we
    actually sent.
    martinpitt committed Sep 19, 2024
    Configuration menu
    Copy the full SHA
    0005471 View commit details
    Browse the repository at this point in the history

Commits on Sep 20, 2024

  1. bridge: Fix beiboot's IPv6 address parsing

    Teach `via_ssh()` to correctly treat IPv6 addresses like `::1`, i.e.
    don't consider a double :: as a port separator.
    
    For IPv6 addresses with a port, the usual syntax is `[A::B:C]:22`, but
    `ssh` does not recognize the brackets. Strip them off after separating
    the port.
    
    (Both covered by `TestLogin.testServer`)
    martinpitt committed Sep 20, 2024
    Configuration menu
    Copy the full SHA
    0b9bc90 View commit details
    Browse the repository at this point in the history
  2. beiboot: Send initial authorize request

    In order to use cockpit.beiboot as cockpit-ssh replacement from the
    bastion host (not Client mode) login page, it needs to consider the given
    username and password. cockpit-ssh sends an initial `authorize` message
    for that and checks for "Basic" auth. If that fails, it aborts
    immediately with `authentication-failed`. Implement the same in
    cockpit.beiboot.
    
    Note: The UI does not currently get along with multiple password
    attempts. Once we drop cockpit-ssh, we should fix the UI and
    cockpit.beiboot to behave like the flatpak, keep the initial SSH
    running, and just answer the "try again" prompts.
    
    Cover this in a new `TestLogin.testLoginSshBeiboot`. Once we generally
    replace cockpit-ssh with cockpit.beiboot, this will get absorbed by
    TestLogin and TestMultiMachine* and can be dropped again.
    martinpitt committed Sep 20, 2024
    Configuration menu
    Copy the full SHA
    339a893 View commit details
    Browse the repository at this point in the history
  3. beiboot: Handle ssh host key prompts

    Stop treating host key prompts as generic conversation messages. We want
    the UI to handle them properly, with some verbiage/buttons and the
    UI/recipe for confirming/validating host keys, instead of letting the
    user type "yes". The login page recognizes these through the presence of
    the `host-key` authorize field.
    
    We can't use ferny's builtin `do_hostkey()` responder for this, as that
    requires `ferny.Session(handle_host_key=True)`, and that API is not
    flexible enough to handle our ssh command modifications and the extra
    beiboot_helper handler. This needs some bigger redesign, see cockpit-project#19668.
    
    So just recognize and parse SSH's host key prompts, and rely on our
    integration tests to spot breakage in future distro releases.
    
    While cockpit-ssh gave us the full host key right away during
    conversation, ssh (and thus ferny/beiboot) don't work that way: During
    conversation we only get the fingerprint. So for the sending direction,
    utilize the recently introduced temporary UserKnownHostsFile feature of
    beiboot, and send the known_hosts entry for the given host as part of
    the `Authorization:` header. For the receiving direction we need to
    handle three cases:
    
     * For a previously unknown host and a successful login, we only get the
       full host key as part of the GET /login's `login-data` response. So
       defer updating our localStorage's `known_hosts` database during the
       conversation until that happens.
    
     * For a failed login (like wrong password) after already confirming the
       key change, get the host key from the protocol error message.
    
     * ssh (and thus ferny/beiboot) don't report changed host keys as part
       of conversation, but immediatley abort. So remember that state in
       `ssh_host_key_change_host`, and re-attempt the login without sending
       known_hosts data. Our usual logic in `do_hostkey_verification()` will
       notice the change and present the correct dialog.
    
    Adjust TestLogin.testLoginSshBeiboot to only expect the host key on the
    first login attempt. Add testing of changed host key behaviour.
    martinpitt committed Sep 20, 2024
    Configuration menu
    Copy the full SHA
    db8d88c View commit details
    Browse the repository at this point in the history