27
27
import contextlib
28
28
29
29
import aiohttp
30
+ import async_lru
30
31
31
32
from ...logging import get_logger
32
33
55
56
from .rfb .stream import rfb_format_remote
56
57
from .rfb .errors import RfbError
57
58
58
- from .vncauth import VncAuthKvmdCredentials
59
- from .vncauth import VncAuthManager
60
-
61
59
from .render import make_text_jpeg
62
60
63
61
@@ -89,14 +87,13 @@ def __init__( # pylint: disable=too-many-arguments,too-many-locals
89
87
kvmd : KvmdClient ,
90
88
streamers : list [BaseStreamerClient ],
91
89
92
- vnc_credentials : dict [str , VncAuthKvmdCredentials ],
90
+ vncpasses : set [str ],
93
91
vencrypt : bool ,
94
92
none_auth_only : bool ,
93
+
95
94
shared_params : _SharedParams ,
96
95
) -> None :
97
96
98
- self .__vnc_credentials = vnc_credentials
99
-
100
97
super ().__init__ (
101
98
reader = reader ,
102
99
writer = writer ,
@@ -106,7 +103,7 @@ def __init__( # pylint: disable=too-many-arguments,too-many-locals
106
103
x509_key_path = x509_key_path ,
107
104
scroll_rate = scroll_rate ,
108
105
allow_cut_after = allow_cut_after ,
109
- vnc_passwds = list ( vnc_credentials ) ,
106
+ vncpasses = vncpasses ,
110
107
vencrypt = vencrypt ,
111
108
none_auth_only = none_auth_only ,
112
109
** dataclasses .asdict (shared_params ),
@@ -321,19 +318,17 @@ async def __fb_sender_task_loop(self) -> None: # pylint: disable=too-many-branc
321
318
# =====
322
319
323
320
async def _authorize_userpass (self , user : str , passwd : str ) -> bool :
324
- self .__kvmd_session = self .__kvmd .make_session (user , passwd )
325
- if (await self .__kvmd_session .auth .check ()):
321
+ self .__kvmd_session = self .__kvmd .make_session ()
322
+ if (await self .__kvmd_session .auth .check (user , passwd )):
326
323
self .__stage1_authorized .set_passed ()
327
324
return True
328
325
return False
329
326
330
- async def _on_authorized_vnc_passwd (self , passwd : str ) -> str :
331
- kc = self .__vnc_credentials [passwd ]
332
- if (await self ._authorize_userpass (kc .user , kc .passwd )):
333
- return kc .user
334
- return ""
327
+ async def _on_authorized_vncpass (self ) -> None :
328
+ self .__kvmd_session = self .__kvmd .make_session ()
329
+ self .__stage1_authorized .set_passed ()
335
330
336
- async def _on_authorized_none (self ) -> bool :
331
+ async def _authorize_none (self ) -> bool :
337
332
return (await self ._authorize_userpass ("" , "" ))
338
333
339
334
# =====
@@ -461,6 +456,8 @@ def __init__( # pylint: disable=too-many-arguments,too-many-locals
461
456
x509_cert_path : str ,
462
457
x509_key_path : str ,
463
458
459
+ vncpass_enabled : bool ,
460
+ vncpass_path : str ,
464
461
vencrypt_enabled : bool ,
465
462
466
463
desired_fps : int ,
@@ -471,7 +468,6 @@ def __init__( # pylint: disable=too-many-arguments,too-many-locals
471
468
472
469
kvmd : KvmdClient ,
473
470
streamers : list [BaseStreamerClient ],
474
- vnc_auth_manager : VncAuthManager ,
475
471
) -> None :
476
472
477
473
self .__host = network .get_listen_host (host )
@@ -481,7 +477,8 @@ def __init__( # pylint: disable=too-many-arguments,too-many-locals
481
477
keymap_name = os .path .basename (keymap_path )
482
478
symmap = build_symmap (keymap_path )
483
479
484
- self .__vnc_auth_manager = vnc_auth_manager
480
+ self .__vncpass_enabled = vncpass_enabled
481
+ self .__vncpass_path = vncpass_path
485
482
486
483
shared_params = _SharedParams ()
487
484
@@ -508,8 +505,8 @@ async def handle_client(reader: asyncio.StreamReader, writer: asyncio.StreamWrit
508
505
sock .setsockopt (socket .IPPROTO_TCP , socket .TCP_USER_TIMEOUT , timeout ) # type: ignore
509
506
510
507
try :
511
- async with kvmd .make_session ("" , "" ) as kvmd_session :
512
- none_auth_only = await kvmd_session .auth .check ()
508
+ async with kvmd .make_session () as kvmd_session :
509
+ none_auth_only = await kvmd_session .auth .check ("" , "" )
513
510
except (aiohttp .ClientError , asyncio .TimeoutError ) as ex :
514
511
logger .error ("%s [entry]: Can't check KVMD auth mode: %s" , remote , tools .efmt (ex ))
515
512
return
@@ -529,9 +526,9 @@ async def handle_client(reader: asyncio.StreamReader, writer: asyncio.StreamWrit
529
526
allow_cut_after = allow_cut_after ,
530
527
kvmd = kvmd ,
531
528
streamers = streamers ,
532
- vnc_credentials = (await self .__vnc_auth_manager .read_credentials ())[0 ],
533
- none_auth_only = none_auth_only ,
529
+ vncpasses = (await self .__read_vncpasses ()),
534
530
vencrypt = vencrypt_enabled ,
531
+ none_auth_only = none_auth_only ,
535
532
shared_params = shared_params ,
536
533
).run ()
537
534
except Exception :
@@ -542,9 +539,6 @@ async def handle_client(reader: asyncio.StreamReader, writer: asyncio.StreamWrit
542
539
self .__handle_client = handle_client
543
540
544
541
async def __inner_run (self ) -> None :
545
- if not (await self .__vnc_auth_manager .read_credentials ())[1 ]:
546
- raise SystemExit (1 )
547
-
548
542
get_logger (0 ).info ("Listening VNC on TCP [%s]:%d ..." , self .__host , self .__port )
549
543
(family , _ , _ , _ , addr ) = socket .getaddrinfo (self .__host , self .__port , type = socket .SOCK_STREAM )[0 ]
550
544
with contextlib .closing (socket .socket (family , socket .SOCK_STREAM )) as sock :
@@ -561,6 +555,21 @@ async def __inner_run(self) -> None:
561
555
async with server :
562
556
await server .serve_forever ()
563
557
558
+ @async_lru .alru_cache (maxsize = 1 , ttl = 1 )
559
+ async def __read_vncpasses (self ) -> set [str ]:
560
+ if self .__vncpass_enabled :
561
+ try :
562
+ vncpasses : set [str ] = set ()
563
+ for (_ , line ) in tools .passwds_splitted (await aiotools .read_file (self .__vncpass_path )):
564
+ if " -> " in line : # Compatibility with old ipmipasswd file format
565
+ line = line .split (" -> " , 1 )[0 ]
566
+ if len (line .strip ()) > 0 :
567
+ vncpasses .add (line )
568
+ return vncpasses
569
+ except Exception :
570
+ get_logger (0 ).exception ("Unhandled exception while reading VNCAuth passwd file" )
571
+ return set ()
572
+
564
573
def run (self ) -> None :
565
574
aiotools .run (self .__inner_run ())
566
575
get_logger ().info ("Bye-bye" )
0 commit comments