Internal
Public Access
Implements RFB (RFC 6143) directly against QTcpSocket. No permissively licensed VNC client library exists to vendor the way FreeRDP was for RDP: LibVNCClient is GPLv2, gtk-vnc is LGPL but GTK-tied, and vendoring either would force a licensing decision on the whole (MIT) project. This is from-scratch protocol code instead, threaded like SshSessionBackend (a QObject on its own QThread driven by Qt's own async socket signals) rather than RdpSessionBackend's manual worker-thread/blocking-loop pattern, since QTcpSocket is already async. Scope, matching SessionTab's existing SSH/RDP dispatch pattern (session_backend_factory.cpp, session_tab.cpp's widget construction and signal wiring) and VncDisplayWidget mirroring RdpDisplayWidget's scale-to-fit rendering: - Protocol handshake: RFB 3.3/3.7/3.8 negotiated explicitly (the SecurityResult message only exists in 3.8; pre-3.8 servers signal auth failure by closing the socket, which the disconnect handler accounts for) - VNC Authentication (DES challenge-response, via OpenSSL's classic DES API) and no-auth security types - Raw + CopyRect framebuffer decoding into a persistent QImage, requesting a fixed 32bpp format whose byte layout matches QImage::Format_RGB32 directly (same zero-conversion trick RdpSessionBackend uses for FreeRDP's GDI buffer) - Keyboard (Qt key -> X11 keysym, including the Unicode-beyond-Latin-1 keysym convention) and mouse/wheel input forwarding Explicit non-goals for this pass (see docs/PROGRESS.md for the full list): Apple's Screen Sharing auth (so this can't yet reach macOS's built-in VNC server), compression encodings beyond Raw/CopyRect, dynamic resize, remote cursor shape sync, clipboard sync. 19 unit tests (tests/test_vnc_session_backend.cpp): pure-function coverage (DES key prep verified against an independently documented test vector for password "COW", X11 keysym mapping, socket-error mapping) plus state-machine coverage against a scripted in-process fake RFB server covering all three protocol-version handshake shapes, auth success/ failure, unsupported security types, and pixel-accurate Raw decoding. That harness caught a real re-entrancy bug: QAbstractSocket::abort() synchronously re-emits disconnected() before returning, so failConnection() calling it was silently letting a second, generic disconnected-socket handler overwrite an already-correct, specific error message. Also verified live against a real, independently implemented VNC server (TightVNC on Windows): connect with VNC Authentication, correct framebuffer dimensions and pixel data, clean disconnect, reconnect. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
62 lines
2.7 KiB
CMake
62 lines
2.7 KiB
CMake
add_executable(test_profile_repository
|
|
test_profile_repository.cpp
|
|
${CMAKE_SOURCE_DIR}/src/profile_repository.cpp
|
|
)
|
|
target_include_directories(test_profile_repository PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
|
target_link_libraries(test_profile_repository PRIVATE Qt6::Core Qt6::Sql Qt6::Test)
|
|
add_test(NAME test_profile_repository COMMAND test_profile_repository)
|
|
|
|
add_executable(test_mremoteng_importer
|
|
test_mremoteng_importer.cpp
|
|
${CMAKE_SOURCE_DIR}/src/mremoteng_importer.cpp
|
|
)
|
|
target_include_directories(test_mremoteng_importer PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
|
target_link_libraries(test_mremoteng_importer PRIVATE Qt6::Core Qt6::Test)
|
|
add_test(NAME test_mremoteng_importer COMMAND test_mremoteng_importer)
|
|
|
|
add_executable(test_ssh_session_backend
|
|
test_ssh_session_backend.cpp
|
|
${CMAKE_SOURCE_DIR}/src/ssh_session_backend.cpp
|
|
${CMAKE_SOURCE_DIR}/src/session_backend.h
|
|
)
|
|
target_include_directories(test_ssh_session_backend PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
|
target_link_libraries(test_ssh_session_backend PRIVATE Qt6::Core Qt6::Gui Qt6::Test)
|
|
target_compile_definitions(test_ssh_session_backend PRIVATE
|
|
ORBITHUB_TEST_FIXTURES_DIR="${CMAKE_CURRENT_SOURCE_DIR}/fixtures"
|
|
)
|
|
add_test(NAME test_ssh_session_backend COMMAND test_ssh_session_backend)
|
|
|
|
add_executable(test_vnc_session_backend
|
|
test_vnc_session_backend.cpp
|
|
${CMAKE_SOURCE_DIR}/src/vnc_session_backend.cpp
|
|
${CMAKE_SOURCE_DIR}/src/session_backend.h
|
|
)
|
|
target_include_directories(test_vnc_session_backend PRIVATE ${CMAKE_SOURCE_DIR}/src)
|
|
target_link_libraries(test_vnc_session_backend PRIVATE
|
|
Qt6::Core Qt6::Gui Qt6::Network Qt6::Test OpenSSL::Crypto
|
|
)
|
|
add_test(NAME test_vnc_session_backend COMMAND test_vnc_session_backend)
|
|
|
|
if(TARGET freerdp AND TARGET winpr)
|
|
add_executable(test_rdp_session_backend
|
|
test_rdp_session_backend.cpp
|
|
${CMAKE_SOURCE_DIR}/src/rdp_session_backend.cpp
|
|
${CMAKE_SOURCE_DIR}/src/session_backend.h
|
|
)
|
|
target_include_directories(test_rdp_session_backend PRIVATE
|
|
${CMAKE_SOURCE_DIR}/src
|
|
${CMAKE_SOURCE_DIR}/third_party/FreeRDP/include
|
|
${CMAKE_SOURCE_DIR}/third_party/FreeRDP/winpr/include
|
|
${CMAKE_BINARY_DIR}/third_party/FreeRDP/include
|
|
${CMAKE_BINARY_DIR}/third_party/FreeRDP/winpr/include
|
|
)
|
|
target_compile_definitions(test_rdp_session_backend PRIVATE ORBITHUB_HAS_FREERDP)
|
|
target_link_libraries(test_rdp_session_backend PRIVATE Qt6::Core Qt6::Gui Qt6::Test freerdp winpr)
|
|
if(TARGET freerdp-client)
|
|
target_link_libraries(test_rdp_session_backend PRIVATE freerdp-client)
|
|
endif()
|
|
add_test(NAME test_rdp_session_backend COMMAND test_rdp_session_backend)
|
|
else()
|
|
message(STATUS "FreeRDP targets not available -- skipping test_rdp_session_backend")
|
|
endif()
|