mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-09 03:36:48 +00:00
fix(console): the console page judges a TCP/TLS console by the running VM
The page's "listens only on its host" check read the VM's next-start definition, while novncd connects to the running VM's listener: after a listen address change on a running VM, the page refused a console novncd could reach, or let through one it could not. The page now reads the running VM's listener, as novncd does, with the same loopback test, which moves to vrtManager.util.
This commit is contained in:
parent
1d2de7404b
commit
976955fff8
4 changed files with 25 additions and 15 deletions
|
|
@ -4,7 +4,6 @@
|
|||
# through an SSH tunnel or a local Unix socket.
|
||||
|
||||
import argparse
|
||||
import ipaddress
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
|
|
@ -23,6 +22,7 @@ from websockify import ProxyRequestHandler, WebSocketProxy # noqa: E402
|
|||
|
||||
from console.sshtunnels import open_tunnel, tunnel_target # noqa: E402
|
||||
from vrtManager.connection import CONN_SOCKET, CONN_SSH # noqa: E402
|
||||
from vrtManager.util import is_loopback # noqa: E402
|
||||
from webvirtcloud.settings import WS_HOST, WS_PORT # noqa: E402
|
||||
|
||||
|
||||
|
|
@ -77,14 +77,6 @@ def get_connection_infos(token):
|
|||
WILDCARD = (None, "", "0.0.0.0", "::")
|
||||
|
||||
|
||||
def is_loopback(address):
|
||||
"""127.0.0.0/8, ::1 or localhost: reachable only on the compute itself."""
|
||||
try:
|
||||
return ipaddress.ip_address(address).is_loopback
|
||||
except ValueError:
|
||||
return address == "localhost"
|
||||
|
||||
|
||||
class ConsoleClient:
|
||||
"""What a console websocket is joined to; ConsoleProxyHandler is the
|
||||
websockify handler that runs it."""
|
||||
|
|
|
|||
|
|
@ -270,12 +270,18 @@ class ConsoleViewsTestCase(TestCase):
|
|||
|
||||
@patch("console.views.wvmInstance")
|
||||
def test_a_tcp_hosts_loopback_console_says_why_it_cannot_open(self, mock_wvm):
|
||||
# the running VM's listener decides, as for novncd, not its next-start settings
|
||||
Compute.objects.filter(pk=self.compute.pk).update(type=1)
|
||||
mock_wvm.return_value.get_console_type.return_value = "vnc"
|
||||
mock_wvm.return_value.console_listens_locally.return_value = True
|
||||
conn = mock_wvm.return_value
|
||||
conn.get_console_type.return_value = "vnc"
|
||||
conn.get_console_socket.return_value = None
|
||||
conn.console_listens_locally.return_value = False # next start: all interfaces
|
||||
self.client.force_login(self.admin_user)
|
||||
response = self.client.get(self.url)
|
||||
self.assertContains(response, "This console listens only on its host")
|
||||
for live, refused in (("127.0.0.1", True), ("::1", True), ("0.0.0.0", False), ("192.0.2.40", False)):
|
||||
with self.subTest(live=live):
|
||||
conn.get_console_listener_addr.return_value = live
|
||||
response = self.client.get(self.url)
|
||||
self.assertEqual("This console listens only on its host" in response.content.decode(), refused)
|
||||
|
||||
@patch("console.views.wvmInstance")
|
||||
def test_both_pages_connect_to_novncd_behind_the_panels_own_address(self, mock_wvm):
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from instances.utils import can_open_console
|
|||
from libvirt import libvirtError
|
||||
from vrtManager.connection import CONN_TCP, CONN_TLS
|
||||
from vrtManager.instance import wvmInstance
|
||||
from vrtManager.util import is_loopback
|
||||
|
||||
|
||||
def to_bool(val, default=False):
|
||||
|
|
@ -57,8 +58,10 @@ def console(request, compute_id, uuid):
|
|||
console_passwd = conn.get_console_passwd()
|
||||
running = conn.instance.isActive()
|
||||
# novncd reaches a console that listens on its host's loopback only
|
||||
# through SSH (or on this host)
|
||||
unreachable = instance.compute.type in (CONN_TCP, CONN_TLS) and conn.console_listens_locally()
|
||||
# through SSH (or on this host); the running VM's listener, as novncd sees it
|
||||
unreachable = instance.compute.type in (CONN_TCP, CONN_TLS) and bool(
|
||||
conn.get_console_socket() or is_loopback(conn.get_console_listener_addr())
|
||||
)
|
||||
except (libvirtError, ValueError, IndexError, Instance.DoesNotExist):
|
||||
running = unreachable = False
|
||||
console_type = None
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import ipaddress
|
||||
import random
|
||||
import secrets
|
||||
import re
|
||||
|
|
@ -224,3 +225,11 @@ def vol_driver_type(vol_format, pool_type=None):
|
|||
if pool_type == "disk" or vol_format in (None, "", "none", "unknown", "iso"):
|
||||
return "raw"
|
||||
return vol_format
|
||||
|
||||
|
||||
def is_loopback(address):
|
||||
"""127.0.0.0/8, ::1 or localhost: reachable only on that host itself."""
|
||||
try:
|
||||
return ipaddress.ip_address(address).is_loopback
|
||||
except ValueError:
|
||||
return address == "localhost"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue