summaryrefslogtreecommitdiff
path: root/kvmd/apps/vnc/rfb/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'kvmd/apps/vnc/rfb/__init__.py')
-rw-r--r--kvmd/apps/vnc/rfb/__init__.py29
1 files changed, 24 insertions, 5 deletions
diff --git a/kvmd/apps/vnc/rfb/__init__.py b/kvmd/apps/vnc/rfb/__init__.py
index 698b5084..77f29422 100644
--- a/kvmd/apps/vnc/rfb/__init__.py
+++ b/kvmd/apps/vnc/rfb/__init__.py
@@ -21,6 +21,7 @@
import asyncio
+import ssl
from typing import Tuple
from typing import List
@@ -45,7 +46,7 @@ from .stream import RfbClientStream
# =====
-class RfbClient(RfbClientStream):
+class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attributes
# https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst
# https://www.toptal.com/java/implementing-remote-framebuffer-server-java
# https://github.com/TigerVNC/tigervnc
@@ -54,6 +55,8 @@ class RfbClient(RfbClientStream):
self,
reader: asyncio.StreamReader,
writer: asyncio.StreamWriter,
+ tls_ciphers: str,
+ tls_timeout: float,
width: int,
height: int,
@@ -63,6 +66,9 @@ class RfbClient(RfbClientStream):
super().__init__(reader, writer)
+ self.__tls_ciphers = tls_ciphers
+ self.__tls_timeout = tls_timeout
+
self._width = width
self._height = height
self.__name = name
@@ -98,7 +104,7 @@ class RfbClient(RfbClientStream):
raise
except RfbConnectionError as err:
logger.info("[%s] Client %s: Gone (%s): Disconnected", name, self._remote, str(err))
- except RfbError as err:
+ except (RfbError, ssl.SSLError) as err:
logger.error("[%s] Client %s: %s: Disconnected", name, self._remote, str(err))
except Exception:
logger.exception("[%s] Unhandled exception with client %s: Disconnected", name, self._remote)
@@ -225,13 +231,19 @@ class RfbClient(RfbClientStream):
await self._write_struct("B", 0)
- auth_types = {256: ("VeNCrypt/Plain", self.__handshake_security_vencrypt_userpass)}
+ auth_types = {
+ 256: ("VeNCrypt/Plain", False, self.__handshake_security_vencrypt_userpass),
+ 259: ("VeNCrypt/TLSPlain", True, self.__handshake_security_vencrypt_userpass),
+ }
if self.__vnc_passwds:
# Vinagre не умеет работать с VNC Auth через VeNCrypt, но это его проблемы,
# так как он своеобразно трактует рекомендации VeNCrypt.
# Подробнее: https://bugzilla.redhat.com/show_bug.cgi?id=692048
# Hint: используйте любой другой нормальный VNC-клиент.
- auth_types[2] = ("VeNCrypt/VNCAuth", self.__handshake_security_vnc_auth)
+ auth_types.update({
+ 2: ("VeNCrypt/VNCAuth", False, self.__handshake_security_vnc_auth),
+ 258: ("VeNCrypt/TLSVNCAuth", True, self.__handshake_security_vnc_auth),
+ })
await self._write_struct("B" + "L" * len(auth_types), len(auth_types), *auth_types)
@@ -239,8 +251,15 @@ class RfbClient(RfbClientStream):
if auth_type not in auth_types:
raise RfbError(f"Invalid VeNCrypt auth type: {auth_type}")
- (auth_name, handler) = auth_types[auth_type]
+ (auth_name, tls, handler) = auth_types[auth_type]
get_logger(0).info("[main] Client %s: Using %s auth type", self._remote, auth_name)
+
+ if tls:
+ await self._write_struct("B", 1) # Ack
+ ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+ ssl_context.set_ciphers(self.__tls_ciphers)
+ await self._start_tls(ssl_context, self.__tls_timeout)
+
await handler()
async def __handshake_security_vencrypt_userpass(self) -> None: