Skip to content

Commit

Permalink
1.0.6 (#9)
Browse files Browse the repository at this point in the history
**Arcane Protocol Update:** The protocol has been upgraded to version 5.0.2, bringing support for several server improvements, including dynamic display resolution updates, HDPI settings changes, and Secure Desktop support for Remote Desktop Streaming and Input (Mouse, Keyboard, Clipboard).]
  • Loading branch information
DarkCoderSc authored Sep 17, 2024
1 parent a5fc5d6 commit d80d6d8
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 134 deletions.
29 changes: 22 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ The client/viewer is a cross-platform application developed in Python, using the

The project was renamed to Arcane to avoid the generic nature of the previous name and to signify a major step in the project's development: the complete rewrite of the viewer to be cross-platform.

[![Demo Video](https://raw.githubusercontent.com/PhrozenIO/Arcane/main/resources/images/video.png)](https://www.youtube.com/watch?v=h6xePrsIcQY)

> Arcane is currently in beta and is not recommended for production environments.
[![Demo Video](https://raw.githubusercontent.com/PhrozenIO/Arcane/main/resources/images/video.png)](https://www.youtube.com/watch?v=TgklYPXEptY)

## Key Features

Expand All @@ -27,6 +25,8 @@ The project was renamed to Arcane to avoid the generic nature of the previous na
* **Session Concurrency**: Multiple viewers can connect to a single server at the same time, allowing multiple users to collaborate on the same remote desktop.
* **Sleep Mode Prevention**: To ensure that the remote desktop remains active and responsive, the module prevents the remote computer from entering sleep mode while it is waiting for viewers to connect.
* **Streaming Optimization**: To improve the streaming speed, the module only sends updated pieces of the desktop to the viewer, reducing the amount of data transmitted over the network.
* **Secure Desktop / LogonUI Integration**: When Arcane Server is run as an interactive SYSTEM process, it can access Secure Desktop features, such as Logon UI or UAC prompts, without relying on external processes or tools. Everything is handled within a single Arcane Server instance. Please note that exposing an interactive SYSTEM process can pose security risks; use this feature only if you understand the implications.
* **Dynamic Display Settings Update:** Arcane Server detects changes in display resolution or HDPI settings and keeps the Viewer updated with these adjustments.

## Coming Soon

Expand Down Expand Up @@ -71,9 +71,10 @@ For detailed instructions on how to use and configure the Arcane Server, please

## Version Table

| Version | Protocol Version | Release Date | Compatible Servers |
|---------|------------------|----------------|--------------------|
| 1.0.5b | 5.0.1 | 22 August 2024 | [1.0.4](https://github.com/PhrozenIO/ArcaneServer/releases/tag/1-0-4) |
| Version | Protocol Version | Release Date | Compatible Servers |
|---------|------------------|-------------------|--------------------|
| 1.0.5b | 5.0.1 | 22 August 2024 | [1.0.4](https://github.com/PhrozenIO/ArcaneServer/releases/tag/1-0-4) |
| 1.0.6 | 5.0.2 | 17 September 2024 | |

> ⓘ You can use any version of the viewer with any version of the server, as long as the protocol version matches. The protocol version ensures compatibility between the viewer and the server.
Expand Down Expand Up @@ -103,6 +104,10 @@ For detailed instructions on how to use and configure the Arcane Server, please

## Change Log

### Version 1.0.6

- [x] **Arcane Protocol Update:** The protocol has been upgraded to version 5.0.2, bringing support for several server improvements, including dynamic display resolution updates, HDPI settings changes, and Secure Desktop support for Remote Desktop Streaming and Input (Mouse, Keyboard, Clipboard).]

### Version 1.0.5 (Beta)

This release focuses on improving the code structure through extensive refactoring and resolving infrequent bugs caused by previously unhandled edge cases. Type hinting has been fully implemented, and the code is now nearly ready for production deployment.
Expand All @@ -115,7 +120,7 @@ This release focuses on improving the code structure through extensive refactori
### Version 1.0.3 (Beta)

- [x] The connection window interface has been streamlined, with additional options now accessible in a dedicated settings window.
- [x] Server certificate validation has been introduced. When connecting to a server for the first time, users will be prompted to trust the certificate and can choose to remember their decision.
- [x] Server certificate validation has been introduced. When co- nnecting to a server for the first time, users will be prompted to trust the certificate and can choose to remember their decision.
- [x] A new settings window has been implemented, offering support for additional remote desktop parameters and managing trusted server certificates, including options to add, edit, and remove certificates.
- [x] Various code refactoring and structural improvements have been made to enhance the overall performance and maintainability of the application.

Expand All @@ -126,6 +131,16 @@ This release focuses on improving the code structure through extensive refactori
- [x] HDPI and scaling support have been improved.
- [x] Arcane Viewer Virtual Desktop Window placement has been improved.

## Special Thanks

* [Mudpak (Mudsor MASOOD)](https://www.linkedin.com/in/mudsormasood/) - Official Beta / Quality Tester

Additionally, I extend my gratitude to those who contributed to enhancing the project's visibility:

* [Laurent Minne](https://www.linkedin.com/in/laurent-minne/)

*If you share Arcane with your community, please feel free to contact me to be recognized in this section. I am very grateful to those who contribute by sharing my research and projects.*

---

![HackTheBox Meetup France](https://raw.githubusercontent.com/PhrozenIO/Arcane/main/resources/images/htb_france.png)
Expand Down
4 changes: 2 additions & 2 deletions arcane_viewer/arcane/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ def get_asset_file(asset_name: str) -> str:


# Application Information
APP_VERSION = "1.0.5"
APP_VERSION = "1.0.6"
APP_NAME = "Arcane"
APP_ORGANIZATION_NAME = "Phrozen"
APP_DISPLAY_NAME = f"{APP_NAME} {APP_VERSION} (βeta)"
APP_DISPLAY_NAME = f"{APP_NAME} {APP_VERSION}"

# Remote Desktop Engine Hardcoded Values
VD_WINDOW_ADJUST_RATIO = 90
Expand Down
4 changes: 1 addition & 3 deletions arcane_viewer/arcane/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from enum import Enum, auto

PROTOCOL_VERSION = '5.0.1'
PROTOCOL_VERSION = '5.0.2'


class WorkerKind(Enum):
Expand All @@ -29,8 +29,6 @@ class ArcaneProtocolCommand(Enum):
BadRequest = 0x5
ResourceFound = 0x6
ResourceNotFound = 0x7
LogonUIAccessDenied = 0x8
LogonUIWrongSession = 0x9


class OutputEvent(Enum):
Expand Down
12 changes: 2 additions & 10 deletions arcane_viewer/arcane/threads/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,6 @@ def client_execute(self) -> None:
@pyqtSlot(int, int, arcane.MouseState, arcane.MouseButton)
def send_mouse_event(self, x: int, y: int, state: arcane.MouseState, button: arcane.MouseButton) -> None:
""" Send mouse event to the server """
if self.session.presentation:
return

if self.client is not None and self._connected:
self.client.write_json(
{
Expand All @@ -107,25 +104,20 @@ def send_mouse_event(self, x: int, y: int, state: arcane.MouseState, button: arc
)

@pyqtSlot(str)
def send_key_event(self, keys: str) -> None:
def send_key_event(self, keys: str, is_shortcut: bool) -> None:
""" Send keyboard event to the server """
if self.session.presentation:
return

if self.client is not None and self._connected:
self.client.write_json(
{
"Id": arcane.OutputEvent.Keyboard.name,
"IsShortcut": is_shortcut,
"Keys": keys,
}
)

@pyqtSlot(int)
def send_mouse_wheel_event(self, delta: int) -> None:
""" Send mouse wheel event to the server """
if self.session.presentation:
return

if self.client is not None and self._connected:
self.client.write_json(
{
Expand Down
32 changes: 20 additions & 12 deletions arcane_viewer/arcane/threads/v_desktop.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
Author: Jean-Pierre LESUEUR (@DarkCoderSc)
License: Apache License 2.0
More information about the LICENSE on the LICENSE file in the root directory of the project.
Todo:
- (0001) LogonUI Support
"""

import logging
Expand All @@ -25,15 +22,20 @@
class VirtualDesktopThread(ClientBaseThread):
""" Thread to handle remote desktop streaming, at quantum level """
open_cellar_door = pyqtSignal(arcane.Screen)
request_screen_selection = pyqtSignal(list)
chunk_received = pyqtSignal(QImage, int, int)
request_screen_selection_dialog_signal = pyqtSignal(list)
received_dirty_rect_signal = pyqtSignal(QImage, int, int)
start_events_worker_signal = pyqtSignal()

def __init__(self, session: arcane.Session) -> None:
super().__init__(session, arcane.WorkerKind.Desktop)

self.selected_screen: Optional[arcane.Screen] = None
self.event_loop: Optional[QEventLoop] = None

def open_or_refresh_cellar_door(self) -> None:
if self.selected_screen is not None:
self.open_cellar_door.emit(self.selected_screen)

"""`Destruction is a form of creation. So the fact they burn the money is ironic. They just want to see what happens
when they tear the world apart. They want to change things.`, Donnie Darko"""
def client_execute(self) -> None:
Expand Down Expand Up @@ -61,24 +63,30 @@ def client_execute(self) -> None:
"ImageCompressionQuality": self.session.option_image_quality,
"PacketSize": self.session.option_packet_size.value,
"BlockSize": self.session.option_block_size.value,
"LogonUI": False, # TODO: 0001
}
)

""" Open Cellar Door
`This famous linguist once said, of all the phrases in the English language, of all the endless combinations
of words in all of history, that 'cellar door' is the most beautiful.`, Karen Pomeroy"""
self.open_cellar_door.emit(
self.selected_screen
)
self.open_or_refresh_cellar_door()

self.start_events_worker_signal.emit()

packet_max_size = self.session.option_packet_size.value
while self._running:
try:
chunk_size, x, y = struct.unpack('III', self.client.conn.read(12))
chunk_size, x, y, screen_updated = struct.unpack('IIIB', self.client.conn.read(13))
except (Exception, ):
break

if bool(screen_updated):
self.selected_screen = arcane.Screen(self.client.read_json())

self.open_or_refresh_cellar_door()

continue

chunk_bytes = QByteArray()
bytes_read = 0
while bytes_read < chunk_size:
Expand All @@ -94,7 +102,7 @@ def client_execute(self) -> None:
chunk = QImage()
chunk.loadFromData(chunk_bytes)

self.chunk_received.emit(
self.received_dirty_rect_signal.emit(
chunk,
x,
y,
Expand All @@ -109,7 +117,7 @@ def stop(self) -> None:
def display_screen_selection_dialog(self, screens: List[arcane.Screen]) -> None:
self.event_loop = QEventLoop()

self.request_screen_selection.emit(screens)
self.request_screen_selection_dialog_signal.emit(screens)

self.event_loop.exec()

Expand Down
Loading

0 comments on commit d80d6d8

Please sign in to comment.