barneygale / asyncvnc Goto Github PK
View Code? Open in Web Editor NEWAsynchronous VNC for Python
License: GNU General Public License v3.0
Asynchronous VNC for Python
License: GNU General Public License v3.0
Traceback (most recent call last):
File "/home/goodboy/repos/piker/snippets/async_vnc.py", line 21, in <module>
asyncio.run(run_client())
File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
return future.result()
File "/home/goodboy/repos/piker/snippets/async_vnc.py", line 5, in run_client
async with asyncvnc.connect(
File "/usr/lib/python3.10/contextlib.py", line 199, in __aenter__
return await anext(self.gen)
File "/home/goodboy/repos/piker/310/lib/python3.10/site-packages/asyncvnc.py", line 501, in connect
client = await Client.create(reader, writer, username, password)
File "/home/goodboy/repos/piker/310/lib/python3.10/site-packages/asyncvnc.py", line 420, in create
raise ValueError(f'unsupported security types: {security_types}')
ValueError: unsupported security types: {2}
Is there a way to know what each sec type maps to and how you must change your server config to make the connection work?
In an effort to get #4 (which helped get the fix to #2 ๐ฅณ) running in CI we need to figure out getting x11vnc
installed on the vm instance.
There are some details in #4 but likely we'll want to just do this:
Actions config will just need something like:
- name: Install x11vnc
run: sudo apt-get install -y x11vnc
When running the following script against the following server command:
x11vnc -display :0 -noipv6 -forever -noxdamage -ncache_cr
target script:
async def run_client():
async with asyncvnc.connect(
'localhost',
port=5901,
) as client:
print(client)
asyncio.run(run_client())
output error:
File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
return future.result()
File "/home/goodboy/repos/piker/snippets/async_vnc.py", line 8, in run_client
async with asyncvnc.connect(
File "/usr/lib/python3.10/contextlib.py", line 199, in __aenter__
return await anext(self.gen)
File "/home/goodboy/repos/asyncvnc/asyncvnc.py", line 563, in connect
client = await Client.create(reader, writer, username, password, host_key)
File "/home/goodboy/repos/asyncvnc/asyncvnc.py", line 514, in create
video=await Video.create(reader, writer))
File "/home/goodboy/repos/asyncvnc/asyncvnc.py", line 292, in create
mode = video_modes[await reader.readexactly(13)]
KeyError: b' \x18\x00\xff\x00\xff\x00\xff\x00\xff\x10\x08\x00'
Feels like a full "system test" where you spawn x11vnc
and run a client against it would be handy ๐
Hi there,
I've found some odd behavior when connecting to Tight- or UltraVNC using VNC authentication. The authentication always failed, even when the password was correct.
Thus I've taken a look at aardwolf and how they do it. And found those lines.
I've stitched them into the create method like shown below and the authentication passes. I've testet against X11VNC Ultra- and TightVNC and all can authenticate.
import asyncio
import asyncvnc
from os import urandom
from typing import Optional
from asyncvnc import Client, Clipboard, Keyboard, Mouse, Video, read_int
from cryptography.hazmat.primitives.asymmetric import padding, rsa
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives.serialization import load_der_public_key
from unicrypto.symmetric import DES, MODE_ECB
def pack_ard(data):
data = data.encode("utf-8") + b"\x00"
if len(data) < 64:
data += urandom(64 - len(data))
else:
data = data[:64]
return data
@classmethod
async def create(
cls,
reader: asyncio.StreamReader,
writer: asyncio.StreamWriter,
username: Optional[str] = None,
password: Optional[str] = None,
host_key: Optional[rsa.RSAPublicKey] = None,
) -> Client:
intro = await reader.readline()
if intro[:4] != b"RFB ":
raise ValueError("not a VNC server")
writer.write(b"RFB 003.008\n")
auth_types = set(await reader.readexactly(await read_int(reader, 1)))
for auth_type in (33, 1, 2):
if auth_type in auth_types:
writer.write(auth_type.to_bytes(1, "big"))
break
else:
raise ValueError(f"unsupported auth types: {auth_types}")
# Apple authentication
if auth_type == 33:
if username is None or password is None:
raise ValueError("server requires username and password")
if host_key is None:
writer.write(b"\x00\x00\x00\x0a\x01\x00RSA1\x00\x00\x00\x00")
await reader.readexactly(4) # packet length
await reader.readexactly(2) # packet version
host_key_length = await read_int(reader, 4)
host_key = await reader.readexactly(host_key_length)
host_key = load_der_public_key(host_key)
await reader.readexactly(1) # unknown
aes_key = urandom(16)
cipher = Cipher(algorithms.AES(aes_key), modes.ECB())
encryptor = cipher.encryptor()
credentials = pack_ard(username) + pack_ard(password)
writer.write(
b"\x00\x00\x01\x8a\x01\x00RSA1"
+ b"\x00\x01"
+ encryptor.update(credentials)
+ b"\x00\x01"
+ host_key.encrypt(aes_key, padding=padding.PKCS1v15())
)
await reader.readexactly(4) # unknown
# VNC authentication
if auth_type == 2:
if password is None:
raise ValueError("server requires password")
des_key = password.encode("ascii")[:8].ljust(8, b"\x00")
des_key = bytes(int(bin(n)[:1:-1], 2) for n in des_key)
encryptor = Cipher(algorithms.TripleDES(des_key), modes.ECB()).encryptor()
challenge = await reader.readexactly(16)
password = password.ljust(8, "\x00").encode("ascii")
password = password[:8]
# converting password to key
newkey = b""
for ki in range(len(password)):
bsrc = password[ki]
btgt = 0
for i in range(8):
if bsrc & (1 << i):
btgt = btgt | (1 << 7 - i)
newkey += bytes([btgt])
ctx = DES(newkey, mode=MODE_ECB, IV=None)
_aardwolf_response = ctx.encrypt(challenge)
_asyncvnc_response = encryptor.update(challenge) + encryptor.finalize()
print("aardwolf: ", _aardwolf_response, "\nasyncvnc: ", _asyncvnc_response)
writer.write(_aardwolf_response)
auth_result = await read_int(reader, 4)
if auth_result == 0:
return cls(
reader=reader,
writer=writer,
host_key=host_key,
clipboard=Clipboard(writer),
keyboard=Keyboard(writer),
mouse=Mouse(writer),
video=await Video.create(reader, writer),
)
elif auth_result == 1:
raise PermissionError("Auth failed")
elif auth_result == 2:
raise PermissionError("Auth failed (too many attempts)")
else:
reason = await reader.readexactly(auth_result)
raise PermissionError(reason.decode("utf-8"))
Client.create = create
async def run_client():
async with asyncvnc.connect("10.9.0.9", port=5900, password="epsa"):
pass
asyncio.run(run_client())
Whilst I really don't know whats going on there ... ๐ ... I just want to let you know.
Best regards and thanks for your time and implementation!
Befedo
Is there anyway to take faster screenshots?
i was using vncdotool to handle with vnc servers but this time a need to to with concurrency.
waiting about 1 or 2 seconds to take a screenshot is really painful.
Is there any workaround to do this job faster?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.