Skip to content

Commit

Permalink
login: Warn before logging into multiple hosts
Browse files Browse the repository at this point in the history
  • Loading branch information
mvollmer committed Jan 8, 2025
1 parent 809ed8a commit 50b915c
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 5 deletions.
8 changes: 8 additions & 0 deletions pkg/static/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@
<span id="banner-message" class="pf-v5-c-alert__description"></span>
</div>

<div id="multihost-warning" class="pf-v5-c-alert pf-m-info pf-m-inline dialog-error" aria-label="inline danger alert" hidden="true">
<svg fill="currentColor" viewBox="0 0 448 512" aria-hidden="true">
<path d="M224 512c35.32 0 63.97-28.65 63.97-64H160.03c0 35.35 28.65 64 63.97 64zm215.39-149.71c-19.32-20.76-55.47-51.99-55.47-154.29 0-77.7-54.48-139.9-127.94-155.16V32c0-17.67-14.32-32-31.98-32s-31.98 14.33-31.98 32v20.84C118.56 68.1 64.08 130.3 64.08 208c0 102.3-36.15 133.53-55.47 154.29-6 6.45-8.66 14.16-8.61 21.71.11 16.4 12.98 32 32.1 32h383.8c19.12 0 32-15.6 32.1-32 .05-7.55-2.61-15.27-8.61-21.71z" />
</svg>
<p id="multihost-message" class="pf-v5-c-alert__title"></p>
<button id="multihost-get-me-there" class="pf-v5-c-button">Go there</button>
</div>

<span id="badge"></span>

<div class="container" id="main">
Expand Down
12 changes: 10 additions & 2 deletions pkg/static/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,16 @@ function debug(...args) {
}
}

if (cur_machine && !environment.page.allow_multihost)
redirect_to_current_machine();
if (cur_machine) {
if (!environment.page.allow_multihost)
redirect_to_current_machine();
else {
id("multihost-message").textContent = format(_("You are already connected to '$0' in this browser session. Connecting to other hosts will allow them to execute arbitrary code on each other. Please be careful."),
cur_machine == "." ? "localhost" : cur_machine);
id("multihost-get-me-there").addEventListener("click", redirect_to_current_machine);
show('#multihost-warning');
}
}
}

function boot() {
Expand Down
4 changes: 2 additions & 2 deletions pkg/static/login.scss
Original file line number Diff line number Diff line change
Expand Up @@ -355,14 +355,14 @@ label.checkbox {
display: none;
}

.login-pf #banner {
.login-pf #banner, .login-pf #multihost-warning {
margin-block: 1rem 0.5rem;
margin-inline: 0;
grid-area: banner;
inline-size: 100%;
}

#banner-message {
#banner-message, #multihost-message {
white-space: pre-wrap;
max-block-size: 12em;
overflow: auto;
Expand Down
85 changes: 85 additions & 0 deletions test/verify/check-static-login
Original file line number Diff line number Diff line change
Expand Up @@ -1111,5 +1111,90 @@ matchrule = <SUBJECT>^DC=LAN,DC=COCKPIT,CN=alice$
check_store_hostkey(real_hostkey)


@testlib.skipBeiboot("host switching disabled in beiboot mode")
class TestLoginMultiHost(testlib.MachineCase):
def testBasic(self):
b = self.browser
m1 = self.machines["machine1"]

ip = "172.27.0.15"

# Disallow multiple sessions initially

if self.multihost_enabled:
m1.write("/etc/cockpit/cockpit.conf",
'[WebService]\nAllowMultiHost=no\n')

m1.start_cockpit()

# Log in via SSH

b.open(f"/={ip}/playground")
b.set_val('#login-user-input', "admin")
b.set_val('#login-password-input', "foobar")
b.click("#login-button")
b.wait_in_text("#hostkey-fingerprint", "SHA256:")
b.click("#login-button")
b.wait_visible('#content')
self.assertEqual(b.eval_js("window.location.pathname"), f"/={ip}/playground")

# Go back to login page. The SSH session from above will still
# be active (for some time until it times out) and the login
# page will immediately redirect us to it. We will end up on
# the Overview (instead of the playground).

b.eval_js("window.location = '/'") # b.go would run into a "navigation canceled error"
b.wait_js_cond(f"window.location.pathname == '/={ip}/system'")
b.wait_visible('#content')
b.logout()

# Enable host switcher for the rest of the test

if self.multihost_enabled:
# clean up AllowMultiHost=no from above
m1.execute("rm /etc/cockpit/cockpit.conf")
self.enable_multihost(m1)
m1.restart_cockpit()

# Log in via SSH

b.open("/")
b.set_val('#login-user-input', "admin")
b.set_val('#login-password-input', "foobar")
b.click("#show-other-login-options")
b.set_val("#server-field", ip)
b.click("#login-button")
b.wait_visible('#content')

# Go back to login page. The SSH session will still be active
# as before, but now the login page will merely warn us about
# it.

b.open("/")
b.wait_in_text("#multihost-warning", f"You are already connected to '{ip}' in this browser session")
b.assert_pixels("body", "warning")

# Clicking on the button should redirect us to that session

b.click("#multihost-warning button")
b.wait_visible('#content')
self.assertEqual(b.eval_js("window.location.pathname"), f"/={ip}/system")

# Go back to login and log in locally anyway.

b.open("/")
b.set_val('#login-user-input', "admin")
b.set_val('#login-password-input', "foobar")
b.click("#login-button")
b.wait_visible('#content')
self.assertEqual(b.eval_js("window.location.pathname"), "/system")

# Go back to first session, it should still be there

b.open(f"/={ip}")
b.wait_visible('#content')
self.assertEqual(b.eval_js("window.location.pathname"), f"/={ip}/system")


if __name__ == '__main__':
testlib.test_main()

0 comments on commit 50b915c

Please sign in to comment.