mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-11 04:36:48 +00:00
fix(console): socketiod refuses a request without a signed-in session
Engine.IO accepts a connection, and holds one of socketiod's 40 threads for it, from its first request; the console token is checked only in Socket.IO's connect(), which a client need never send. Anyone who could reach the panel, without an account, could open 40 websockets, answer their pings, and no serial console would open for anybody (checked: the 41st handshake got no answer until they were closed). The daemon's WSGI app now refuses a request whose session cookie names no signed-in user, with 403, before Engine.IO sees it; the page always sends that cookie. A token without its session no longer connects either, as for novncd. Checked again: 60 such websockets are each answered 403 at once and hold nothing. The process tests sign their client in with a session cookie, as a browser; python-socketio sends a custom Cookie header only with its first request, so the client gets a cookie jar instead.
This commit is contained in:
parent
bb490101fd
commit
4f7bca9754
3 changed files with 59 additions and 14 deletions
|
|
@ -15,7 +15,7 @@ from vrtManager.connection import connection_manager
|
|||
from accounts.models import UserInstance
|
||||
from computes.models import Compute
|
||||
from console import tokens
|
||||
from console.tests.test_socketiod_child import consoles, console, start_socketiod, socketio
|
||||
from console.tests.test_socketiod_child import consoles, console, session_key, start_socketiod, socketio
|
||||
from instances.models import Instance
|
||||
from vrtManager.tests import livetest
|
||||
|
||||
|
|
@ -65,22 +65,22 @@ class LiveSerialConsoleTestCase(TransactionTestCase):
|
|||
|
||||
def admin_token(self, token):
|
||||
host, uuid, _user, _type = tokens.SIGNER.unsign(token).split(":")
|
||||
admin, _ = get_user_model().objects.get_or_create(username="serial-live-admin", is_superuser=True)
|
||||
return tokens.sign(host, uuid, admin.id, "pty")
|
||||
self.admin, _ = get_user_model().objects.get_or_create(username="serial-live-admin", is_superuser=True)
|
||||
return tokens.sign(host, uuid, self.admin.id, "pty")
|
||||
|
||||
def test_the_console_of_a_running_vm_opens_once(self):
|
||||
for args in self.hosts:
|
||||
with self.subTest(host=args[0], type=args[3]):
|
||||
token, dom = self.token(*args)
|
||||
client, received = console(self.port, token)
|
||||
client, received = console(self.port, token, session_key(self.user))
|
||||
deadline = time.monotonic() + 30
|
||||
while "SeaBIOS" not in "".join(received["output"]) and time.monotonic() < deadline:
|
||||
time.sleep(0.2)
|
||||
self.assertIn("SeaBIOS", "".join(received["output"]))
|
||||
# one client per VM; a superuser takes a console left open over
|
||||
with self.assertRaises(socketio.exceptions.ConnectionError):
|
||||
console(self.port, token)
|
||||
admin_client, admin_received = console(self.port, self.admin_token(token))
|
||||
console(self.port, token, session_key(self.user))
|
||||
admin_client, admin_received = console(self.port, self.admin_token(token), session_key(self.admin))
|
||||
wait_for(lambda: received["taken_over"])
|
||||
self.assertEqual(received["taken_over"], ["serial-live-admin"])
|
||||
client.disconnect()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue