diff options
author | Devaev Maxim <[email protected]> | 2020-05-15 14:14:12 +0300 |
---|---|---|
committer | Devaev Maxim <[email protected]> | 2020-05-15 14:14:12 +0300 |
commit | a364e689c6d944be90ce80ad34594b21309cdb05 (patch) | |
tree | 8dce4753afbaa284a764039a81d777cf886d278b /kvmd/apps/vnc/rfb/__init__.py | |
parent | b2c2244aa3e0cfe68b17668bb1d5950006da961e (diff) |
vnc none auth support
Diffstat (limited to 'kvmd/apps/vnc/rfb/__init__.py')
-rw-r--r-- | kvmd/apps/vnc/rfb/__init__.py | 70 |
1 files changed, 50 insertions, 20 deletions
diff --git a/kvmd/apps/vnc/rfb/__init__.py b/kvmd/apps/vnc/rfb/__init__.py index 2965bd4d..600920bf 100644 --- a/kvmd/apps/vnc/rfb/__init__.py +++ b/kvmd/apps/vnc/rfb/__init__.py @@ -62,6 +62,7 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute height: int, name: str, vnc_passwds: List[str], + none_auth_only: bool, ) -> None: super().__init__(reader, writer) @@ -73,6 +74,7 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute self._height = height self.__name = name self.__vnc_passwds = vnc_passwds + self.__none_auth_only = none_auth_only self.__rfb_version = 0 self._encodings = RfbClientEncodings(frozenset()) @@ -124,6 +126,11 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute async def _on_authorized_vnc_passwd(self, passwd: str) -> str: raise NotImplementedError + async def _on_authorized_none(self) -> bool: + raise NotImplementedError + + # ===== + async def _on_key_event(self, code: int, state: bool) -> None: raise NotImplementedError @@ -201,10 +208,12 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute sec_types: Dict[int, Tuple[str, Callable]] = {} if self.__rfb_version > 3: sec_types[19] = ("VeNCrypt", self.__handshake_security_vencrypt) - if self.__vnc_passwds: + if self.__none_auth_only: + sec_types[1] = ("None", self.__handshake_security_none) + elif self.__vnc_passwds: sec_types[2] = ("VNCAuth", self.__handshake_security_vnc_auth) if not sec_types: - msg = "The client uses a very old protocol 3.3 and VNCAuth is disabled" + msg = "The client uses a very old protocol 3.3 and VNCAuth or NoneAuth is disabled" await self._write_struct("L", 0, drain=False) # Refuse old clients using the invalid security type await self._write_reason(msg) raise RfbError(msg) @@ -229,19 +238,25 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute await self._write_struct("B", 0) - 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.update({ - 2: ("VeNCrypt/VNCAuth", False, self.__handshake_security_vnc_auth), - 258: ("VeNCrypt/TLSVNCAuth", True, self.__handshake_security_vnc_auth), - }) + if self.__none_auth_only: + auth_types = { + 1: ("VeNCrypt/None", False, self.__handshake_security_none), + 257: ("VeNCrypt/TLSNone", True, self.__handshake_security_none), + } + else: + 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.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) @@ -266,9 +281,12 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute passwd = await self._read_text(passwd_length) ok = await self._authorize_userpass(user, passwd) - await self.__handshake_security_send_result(ok, user) + async def __handshake_security_none(self) -> None: + ok = await self._on_authorized_none() + await self.__handshake_security_send_result(ok, "") + async def __handshake_security_vnc_auth(self) -> None: challenge = rfb_make_challenge() await self._write_struct("", challenge) @@ -287,14 +305,26 @@ class RfbClient(RfbClientStream): # pylint: disable=too-many-instance-attribute async def __handshake_security_send_result(self, ok: bool, user: str) -> None: if ok: - assert user - get_logger(0).info("[main] Client %s: Access granted for user %r", self._remote, user) + if self.__none_auth_only: + assert len(user) == 0 + get_logger(0).info("[main] Client %s: Anonymous access granted", self._remote) + else: + assert user + get_logger(0).info("[main] Client %s: Access granted for user %r", self._remote, user) await self._write_struct("L", 0) else: await self._write_struct("L", 1, drain=(self.__rfb_version < 8)) + if self.__none_auth_only: + reason = msg = "Anonymous access denied" + elif user: + reason = "Invalid username or password" + msg = f"Access denied for user {user!r}" + else: + reason = "Invalid password" + msg = "Access denied" if self.__rfb_version >= 8: - await self._write_reason("Invalid username or password" if user else "Invalid password") - raise RfbError(f"Access denied for user {user!r}" if user else "Access denied") + await self._write_reason(reason) + raise RfbError(msg) # ===== |