Giter VIP home page Giter VIP logo

asyncvnc's People

Contributors

barneygale avatar goodboy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

asyncvnc's Issues

Sec type `2` unsupported? Auth with password fails..

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?

Add `x11vnc` to actions instance

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

Unsupported video mode: `b' \x18\x00\xff\x00\xff\x00\xff\x00\xff\x10\x08\x00'`

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 ๐Ÿ˜„

Could not connect to Tight-/UltraVNC.

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

Faster Screenshots?

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.