mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-13 01:30:31 +08:00
vnc none auth support
This commit is contained in:
parent
b2c2244aa3
commit
a364e689c6
@ -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)
|
||||
|
||||
# =====
|
||||
|
||||
|
||||
@ -73,6 +73,7 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
|
||||
streamer: StreamerClient,
|
||||
|
||||
vnc_credentials: Dict[str, VncAuthKvmdCredentials],
|
||||
none_auth_only: bool,
|
||||
shared_params: _SharedParams,
|
||||
) -> None:
|
||||
|
||||
@ -84,6 +85,7 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
|
||||
tls_ciphers=tls_ciphers,
|
||||
tls_timeout=tls_timeout,
|
||||
vnc_passwds=list(vnc_credentials),
|
||||
none_auth_only=none_auth_only,
|
||||
**dataclasses.asdict(shared_params),
|
||||
)
|
||||
|
||||
@ -239,6 +241,11 @@ class _Client(RfbClient): # pylint: disable=too-many-instance-attributes
|
||||
return kc.user
|
||||
return ""
|
||||
|
||||
async def _on_authorized_none(self) -> bool:
|
||||
return (await self._authorize_userpass("", ""))
|
||||
|
||||
# =====
|
||||
|
||||
async def _on_key_event(self, code: int, state: bool) -> None:
|
||||
if (web_name := self.__symmap.get(code)) is not None: # noqa: E203,E231
|
||||
await self.__ws_writer_queue.put({
|
||||
@ -321,6 +328,7 @@ class VncServer: # pylint: disable=too-many-instance-attributes
|
||||
kvmd=kvmd,
|
||||
streamer=streamer,
|
||||
vnc_credentials=(await self.__vnc_auth_manager.read_credentials())[0],
|
||||
none_auth_only=(await kvmd.authorize("", "")),
|
||||
shared_params=shared_params,
|
||||
).run()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user