Merge tag 'upstream/2.0.0_gitb4b8239'
Upstream version 2.0.0~gitb4b8239
This commit is contained in:
commit
a12e58bec6
133
CMakeLists.txt
133
CMakeLists.txt
@ -81,17 +81,27 @@ else()
|
||||
endif()
|
||||
set(FREERDP_INCLUDE_DIR "include/freerdp${FREERDP_VERSION_MAJOR}/")
|
||||
|
||||
# Make paths absolute
|
||||
if (CMAKE_INSTALL_PREFIX)
|
||||
get_filename_component(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" ABSOLUTE)
|
||||
endif()
|
||||
if (FREERDP_EXTERNAL_PATH)
|
||||
get_filename_component (FREERDP_EXTERNAL_PATH "${FREERDP_EXTERNAL_PATH}" ABSOLUTE)
|
||||
endif()
|
||||
|
||||
# Allow to search the host machine for git
|
||||
if(ANDROID OR IOS)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
|
||||
endif(ANDROID OR IOS)
|
||||
|
||||
include(GetGitRevisionDescription)
|
||||
git_get_exact_tag(GIT_REVISION --tags --always)
|
||||
|
||||
if (${GIT_REVISION} STREQUAL "n/a")
|
||||
git_rev_parse(GIT_REVISION --short)
|
||||
git_rev_parse (GIT_REVISION --short)
|
||||
endif()
|
||||
if(ANDROID OR IOS)
|
||||
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
|
||||
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY)
|
||||
endif(ANDROID OR IOS)
|
||||
|
||||
message(STATUS "Git Revision ${GIT_REVISION}")
|
||||
@ -105,15 +115,17 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED BUILD_SHARED_LIBS)
|
||||
if(ANDROID OR IOS OR APPLE)
|
||||
if(IOS OR APPLE)
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
else()
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED EXPORT_ALL_SYMBOLS)
|
||||
set(EXPORT_ALL_SYMBOLS TRUE)
|
||||
if(BUILD_TESTING)
|
||||
set(EXPORT_ALL_SYMBOLS TRUE)
|
||||
elseif(NOT DEFINED EXPORT_ALL_SYMBOLS)
|
||||
set(EXPORT_ALL_SYMBOLS FALSE)
|
||||
endif()
|
||||
|
||||
# BSD
|
||||
@ -299,11 +311,11 @@ if(MSVC)
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR})
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR})
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Zi")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zi")
|
||||
endif()
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Zi")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zi")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
@ -361,8 +373,6 @@ if(NOT IOS)
|
||||
check_include_files(fcntl.h HAVE_FCNTL_H)
|
||||
check_include_files(unistd.h HAVE_UNISTD_H)
|
||||
check_include_files(execinfo.h HAVE_EXECINFO_H)
|
||||
check_include_files(stdint.h HAVE_STDINT_H)
|
||||
check_include_files(stdbool.h HAVE_STDBOOL_H)
|
||||
check_include_files(inttypes.h HAVE_INTTYPES_H)
|
||||
check_include_files(sys/modem.h HAVE_SYS_MODEM_H)
|
||||
check_include_files(sys/filio.h HAVE_SYS_FILIO_H)
|
||||
@ -373,8 +383,6 @@ if(NOT IOS)
|
||||
else()
|
||||
set(HAVE_FCNTL_H 1)
|
||||
set(HAVE_UNISTD_H 1)
|
||||
set(HAVE_STDINT_H 1)
|
||||
set(HAVE_STDBOOL_H 0)
|
||||
set(HAVE_INTTYPES_H 1)
|
||||
set(HAVE_SYS_FILIO_H 1)
|
||||
endif()
|
||||
@ -406,9 +414,9 @@ if(APPLE)
|
||||
|
||||
# Temporarily disabled, causes the cmake script to be reexecuted, causing the compilation to fail.
|
||||
# Workaround: specify the parameter in the command-line
|
||||
# if(WITH_CLANG)
|
||||
# set(CMAKE_C_COMPILER "clang")
|
||||
# endif()
|
||||
# if(WITH_CLANG)
|
||||
# set(CMAKE_C_COMPILER "clang")
|
||||
# endif()
|
||||
|
||||
if (WITH_VERBOSE)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -v")
|
||||
@ -420,14 +428,18 @@ endif(APPLE)
|
||||
if(OPENBSD)
|
||||
set(WITH_MANPAGES "ON")
|
||||
set(WITH_ALSA "OFF")
|
||||
set(WITH_PULSE "OFF")
|
||||
set(WITH_OSS "ON")
|
||||
set(WITH_PULSE "OFF")
|
||||
set(WITH_OSS "ON")
|
||||
set(WITH_WAYLAND "OFF")
|
||||
endif()
|
||||
|
||||
# Android
|
||||
if(ANDROID)
|
||||
set(WITH_LIBRARY_VERSIONING "OFF")
|
||||
set(WITH_LIBRARY_VERSIONING "OFF")
|
||||
|
||||
if (${ANDROID_ABI} STREQUAL "armeabi")
|
||||
set (WITH_NEON OFF)
|
||||
endif()
|
||||
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
add_definitions(-DNDK_DEBUG=1)
|
||||
@ -439,40 +451,23 @@ if(ANDROID)
|
||||
endif()
|
||||
set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -llog")
|
||||
|
||||
if (NOT FREERDP_EXTERNAL_JPEG_PATH)
|
||||
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/jpeg8d")
|
||||
set(FREERDP_EXTERNAL_JPEG_PATH "${CMAKE_CURRENT_SOURCE_DIR}/external/jpeg8d")
|
||||
if (NOT FREERDP_EXTERNAL_PATH)
|
||||
if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/")
|
||||
set (FREERDP_EXTERNAL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/external/")
|
||||
else()
|
||||
message(STATUS "FREERDP_EXTERNAL_SSL_PATH not set! - Needs to be set if openssl is not found in the android NDK (which usually isn't)")
|
||||
message(STATUS "FREERDP_EXTERNAL_PATH not set!")
|
||||
endif()
|
||||
endif()
|
||||
if (NOT FREERDP_EXTERNAL_SSL_PATH)
|
||||
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/openssl")
|
||||
set(FREERDP_EXTERNAL_SSL_PATH "${CMAKE_CURRENT_SOURCE_DIR}/external/openssl")
|
||||
else()
|
||||
message(STATUS "FREERDP_EXTERNAL_SSL_PATH not set! - Needs to be set if openssl is not found in the android NDK (which usually isn't)")
|
||||
endif()
|
||||
if(WITH_GPROF)
|
||||
if (NOT FREERDP_EXTERNAL_PROFILER_PATH)
|
||||
if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external/android-ndk-profiler")
|
||||
set(FREERDP_EXTERNAL_PROFILER_PATH
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/external/android-ndk-profiler")
|
||||
else()
|
||||
message(STATUS "FREERDP_EXTERNAL_PROFILER_PATH not set!")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_EXTERNAL_SSL_PATH} ${FREERDP_EXTERNAL_JPEG_PATH})
|
||||
set(CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH} ${FREERDP_EXTERNAL_PROFILER_PATH})
|
||||
|
||||
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/client/Android/FreeRDPCore/jni/${ANDROID_ABI})
|
||||
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/scripts/regenerate_jni_headers.sh.cmake
|
||||
${CMAKE_BINARY_DIR}/scripts/regenerate_jni_headers.sh @ONLY)
|
||||
list (APPEND CMAKE_INCLUDE_PATH ${FREERDP_EXTERNAL_PATH}/include)
|
||||
list (APPEND CMAKE_LIBRARY_PATH ${FREERDP_EXTERNAL_PATH}/${ANDROID_ABI}/ )
|
||||
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH )
|
||||
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH )
|
||||
|
||||
if (WITH_GPROF)
|
||||
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/scripts/gprof_generate.sh.cmake ${CMAKE_BINARY_DIR}/scripts/gprof_generate.sh @ONLY)
|
||||
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/scripts/gprof_generate.sh.cmake
|
||||
${CMAKE_BINARY_DIR}/scripts/gprof_generate.sh @ONLY)
|
||||
endif(WITH_GPROF)
|
||||
|
||||
endif()
|
||||
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
@ -486,9 +481,9 @@ if(NOT WIN32)
|
||||
endif()
|
||||
|
||||
if(WITH_VALGRIND_MEMCHECK)
|
||||
check_include_files(valgrind/memcheck.h HAVE_VALGRIND_MEMCHECK_H)
|
||||
check_include_files(valgrind/memcheck.h HAVE_VALGRIND_MEMCHECK_H)
|
||||
else()
|
||||
unset(HAVE_VALGRIND_MEMCHECK_H CACHE)
|
||||
unset(HAVE_VALGRIND_MEMCHECK_H CACHE)
|
||||
endif()
|
||||
|
||||
if(UNIX OR CYGWIN)
|
||||
@ -626,6 +621,21 @@ if(APPLE)
|
||||
set(OPENSLES_FEATURE_TYPE "DISABLED")
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT ANDROID)
|
||||
set(WLOG_SYSTEMD_JOURNAL_FEATURE_TYPE "RECOMMENDED")
|
||||
set(WLOG_SYSTEMD_JOURNAL_FEATURE_PURPOSE "systemd journal appender")
|
||||
set(WLOG_SYSTEMD_JOURNAL_FEATURE_DESCRIPTION "allows to export wLog to systemd journal")
|
||||
|
||||
#include(Findlibsystemd)
|
||||
find_feature(libsystemd ${WLOG_SYSTEMD_JOURNAL_FEATURE_TYPE} ${WLOG_SYSTEMD_JOURNAL_FEATURE_PURPOSE} ${WLOG_SYSTEMD_JOURNAL_FEATURE_DESCRIPTION})
|
||||
|
||||
if(LIBSYSTEMD_FOUND)
|
||||
set(HAVE_JOURNALD_H TRUE)
|
||||
else()
|
||||
unset(HAVE_JOURNALD_H)
|
||||
endif()
|
||||
endif(UNIX AND NOT ANDROID)
|
||||
|
||||
if(ANDROID)
|
||||
set(X11_FEATURE_TYPE "DISABLED")
|
||||
set(WAYLAND_FEATURE_TYPE "DISABLED")
|
||||
@ -641,21 +651,6 @@ if(ANDROID)
|
||||
set(OPENSLES_FEATURE_TYPE "REQUIRED")
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
set(WLOG_SYSTEMD_JOURNAL_FEATURE_TYPE "RECOMMENDED")
|
||||
set(WLOG_SYSTEMD_JOURNAL_FEATURE_PURPOSE "systemd journal appender")
|
||||
set(WLOG_SYSTEMD_JOURNAL_FEATURE_DESCRIPTION "allows to export wLog to systemd journal")
|
||||
|
||||
#include(Findlibsystemd)
|
||||
find_feature(libsystemd ${WLOG_SYSTEMD_JOURNAL_FEATURE_TYPE} ${WLOG_SYSTEMD_JOURNAL_FEATURE_PURPOSE} ${WLOG_SYSTEMD_JOURNAL_FEATURE_DESCRIPTION})
|
||||
|
||||
if(LIBSYSTEMD_FOUND)
|
||||
set(HAVE_JOURNALD_H TRUE)
|
||||
else()
|
||||
unset(HAVE_JOURNALD_H)
|
||||
endif()
|
||||
endif(UNIX)
|
||||
|
||||
find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION})
|
||||
find_feature(Wayland ${WAYLAND_FEATURE_TYPE} ${WAYLAND_FEATURE_PURPOSE} ${WAYLAND_FEATURE_DESCRIPTION})
|
||||
find_feature(DirectFB ${DIRECTFB_FEATURE_TYPE} ${DIRECTFB_FEATURE_PURPOSE} ${DIRECTFB_FEATURE_DESCRIPTION})
|
||||
@ -728,8 +723,8 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DI
|
||||
|
||||
# RPATH configuration
|
||||
if(CMAKE_SKIP_RPATH)
|
||||
set(CMAKE_SKIP_RPATH FALSE)
|
||||
set(CMAKE_SKIP_INSTALL_RPATH TRUE)
|
||||
set(CMAKE_SKIP_RPATH FALSE)
|
||||
set(CMAKE_SKIP_INSTALL_RPATH TRUE)
|
||||
endif()
|
||||
set(CMAKE_SKIP_BUILD_RPATH FALSE)
|
||||
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
@ -796,6 +791,10 @@ include_directories("${CMAKE_BINARY_DIR}/rdtk/include")
|
||||
|
||||
add_subdirectory(rdtk)
|
||||
|
||||
if(WAYLAND_FOUND)
|
||||
add_subdirectory(uwac)
|
||||
endif()
|
||||
|
||||
if(BSD)
|
||||
if(IS_DIRECTORY /usr/local/include)
|
||||
include_directories(/usr/local/include)
|
||||
|
||||
915
ChangeLog
915
ChangeLog
@ -1,12 +1,883 @@
|
||||
2016-02-29 17:39:18 +0100 Norbert Federa (b4b8239)
|
||||
|
||||
* Merge pull request #3176 from bmiklautz/shadow_subsystem (HEAD,
|
||||
origin/master, origin/HEAD, master)
|
||||
|
||||
2016-02-29 17:10:53 +0100 Bernhard Miklautz (014f31d)
|
||||
|
||||
* Merge pull request #3171 from akallabeth/crypto_simplification
|
||||
|
||||
2016-02-29 16:59:58 +0100 Bernhard Miklautz (2550634)
|
||||
|
||||
* Merge pull request #3168 from akallabeth/visibility_fixes
|
||||
|
||||
2016-02-29 16:25:04 +0100 Bernhard Miklautz (1688738)
|
||||
|
||||
* ci: build server side on windows
|
||||
|
||||
2016-02-29 16:22:24 +0100 Bernhard Miklautz (1b926f8)
|
||||
|
||||
* build: export freerdp-shadow
|
||||
|
||||
2016-02-29 16:02:13 +0100 Bernhard Miklautz (f15c050)
|
||||
|
||||
* shadow/subsystem: fix windows build
|
||||
|
||||
2016-02-29 16:00:35 +0100 Bernhard Miklautz (5a7ac96)
|
||||
|
||||
* build/win32: fix DLL version information
|
||||
|
||||
2016-02-29 15:24:07 +0100 Armin Novak (c182be0)
|
||||
|
||||
* Removed module.def from build config.
|
||||
|
||||
2016-02-29 15:21:22 +0100 Bernhard Miklautz (92de4cf)
|
||||
|
||||
* Merge pull request #3167 from
|
||||
realjiangms/shadow_export_default_subsystem
|
||||
|
||||
2016-02-29 15:18:47 +0100 Armin Novak (68c402a)
|
||||
|
||||
* Removed windows module.def files.
|
||||
|
||||
2016-02-29 15:18:19 +0100 Armin Novak (5acd80d)
|
||||
|
||||
* Exporting channel entry points.
|
||||
|
||||
2016-02-29 14:43:33 +0100 Armin Novak (4e4d2e1)
|
||||
|
||||
* Fixed crypto tests.
|
||||
|
||||
2016-02-29 11:12:32 +0100 Armin Novak (19568c6)
|
||||
|
||||
* Fixed indentation.
|
||||
|
||||
2016-02-29 11:10:15 +0100 Armin Novak (7e65013)
|
||||
|
||||
* Fixed memory leak.
|
||||
|
||||
2016-02-29 10:31:50 +0100 Hardening (da9d9ed)
|
||||
|
||||
* Merge pull request #3165 from akallabeth/printer_fix
|
||||
|
||||
2016-02-29 09:00:02 +0100 Armin Novak (b429d23)
|
||||
|
||||
* Refactored crypto *_New functions.
|
||||
|
||||
2016-02-28 11:12:17 +0100 Armin Novak (92c1578)
|
||||
|
||||
* Updated RC4 API, fixed crashing bug.
|
||||
|
||||
2016-02-28 10:33:25 +0100 akallabeth (e2a8083)
|
||||
|
||||
* Merge pull request #3169 from realjiangms/android_fix_sound
|
||||
|
||||
2016-02-27 01:07:30 +0800 zihao.jiang (176ad52)
|
||||
|
||||
* server/shadow: Export API to set built-in subsystem modules for
|
||||
freerdp-shadow-subsystem
|
||||
|
||||
2016-02-27 02:20:49 +0800 zihao.jiang (17139b9)
|
||||
|
||||
* android: Fix sound redirection. After #3097, the java side pass
|
||||
command line argument to JNI for freerdp settings. However
|
||||
there's several issues need to be fixed: 1. The argument
|
||||
/sound should be appended if freerdp is required to play
|
||||
sound at local device 2. The option value for "audio-mode"
|
||||
is not correct. It should match the definition in
|
||||
client/common/cmdline.c /* Audio Mode */ define
|
||||
AUDIO_MODE_REDIRECT 0 /* Bring to this computer */
|
||||
define AUDIO_MODE_PLAY_ON_SERVER 1 /* Leave at remote
|
||||
computer */ define AUDIO_MODE_NONE 2 /* Do not
|
||||
play */ 3. Uncomment support for WAVE_FORMAT_PCM in audin.
|
||||
I tested on my android phone and Nokia N1 tablet. It works
|
||||
on both device
|
||||
|
||||
2016-02-27 23:28:49 +0100 Armin Novak (238ff3b)
|
||||
|
||||
* Unified encryption functions.
|
||||
|
||||
2016-02-27 22:39:45 +0100 Armin Novak (5805ba8)
|
||||
|
||||
* Removed crypto_nonce.
|
||||
|
||||
2016-02-27 22:13:59 +0100 Armin Novak (86436bc)
|
||||
|
||||
* Added API export for uwac.
|
||||
|
||||
2016-02-27 11:36:34 +0100 Armin Novak (11c4425)
|
||||
|
||||
* Fixed dupliace FREERDP_API declarations.
|
||||
|
||||
2016-02-26 19:25:49 +0100 Armin Novak (1036f1e)
|
||||
|
||||
* Fixed default visibility.
|
||||
|
||||
2016-02-26 18:53:45 +0100 akallabeth (9d21117)
|
||||
|
||||
* Merge pull request #3157 from DavBfr/Fix-bad-malloc-size
|
||||
|
||||
2016-02-12 11:32:18 -0800 David PHAM-VAN (8ebe5b9)
|
||||
|
||||
* Fix bad malloc size in statvfs
|
||||
|
||||
2016-02-26 15:21:19 +0100 Armin Novak (b7187d0)
|
||||
|
||||
* Printer driver from command line now used.
|
||||
|
||||
2016-02-26 14:50:27 +0100 Armin Novak (dccf40c)
|
||||
|
||||
* Fixed duplicate loading of smartcard and printers.
|
||||
|
||||
2016-02-26 09:57:35 +0100 Martin Fleisz (4f22682)
|
||||
|
||||
* Merge pull request #3151 from akallabeth/timezone_refactor
|
||||
|
||||
2016-02-26 09:52:43 +0100 Hardening (4217262)
|
||||
|
||||
* Merge pull request #3156 from akallabeth/ssl_wrapper_merge
|
||||
|
||||
2016-02-26 09:28:54 +0100 Armin Novak (fe8f5de)
|
||||
|
||||
* Fixed indentation.
|
||||
|
||||
2016-02-26 09:27:53 +0100 Armin Novak (7a253ba)
|
||||
|
||||
* Replaced magic numbers with defines.
|
||||
|
||||
2016-02-26 09:23:34 +0100 akallabeth (f44f339)
|
||||
|
||||
* Merge pull request #3161 from bmiklautz/uwac_versioning
|
||||
|
||||
2016-02-25 23:47:32 +0100 Bernhard Miklautz (d5a43dd)
|
||||
|
||||
* uwac: generate .pc and cmake find-module
|
||||
|
||||
2016-02-25 23:46:56 +0100 Bernhard Miklautz (167907e)
|
||||
|
||||
* uwac: enable library versioning
|
||||
|
||||
2016-02-25 23:38:53 +0100 Bernhard Miklautz (71836f6)
|
||||
|
||||
* build winpr: export WINPR_API_VERSION
|
||||
|
||||
2016-02-25 21:57:56 +0100 Bernhard Miklautz (541abee)
|
||||
|
||||
* cmake/FindWayland: cleanup
|
||||
|
||||
2016-02-25 16:57:48 +0100 akallabeth (16ba8f3)
|
||||
|
||||
* Merge pull request #3159 from bmiklautz/disable_mipsel
|
||||
|
||||
2016-02-25 16:57:34 +0100 Bernhard Miklautz (8bdad1e)
|
||||
|
||||
* Merge pull request #3140 from hardening/printer_work
|
||||
|
||||
2016-02-25 16:31:20 +0100 Bernhard Miklautz (ae6c235)
|
||||
|
||||
* android: disable mips build
|
||||
|
||||
2016-02-25 15:03:14 +0100 David FORT (aa7fe1d)
|
||||
|
||||
* Fixed indentation
|
||||
|
||||
2016-02-25 09:02:46 +0100 Armin Novak (fd415cd)
|
||||
|
||||
* Fixed missing semicolon.
|
||||
|
||||
2016-02-25 09:00:50 +0100 akallabeth (70f9ebe)
|
||||
|
||||
* Merge pull request #3042 from hardening/uwac
|
||||
|
||||
2016-02-25 00:41:19 +0100 David FORT (2b18d25)
|
||||
|
||||
* Added some checks
|
||||
|
||||
2016-02-24 21:45:09 +0100 Armin Novak (f997421)
|
||||
|
||||
* Unified hmac functions.
|
||||
|
||||
2016-02-24 20:39:49 +0100 Armin Novak (4ca6b9b)
|
||||
|
||||
* Unified random functions and remaining MD5.
|
||||
|
||||
2016-02-24 20:32:20 +0100 Armin Novak (6e8ea34)
|
||||
|
||||
* Updated cryto wrapper API.
|
||||
|
||||
2016-02-24 20:16:33 +0100 Armin Novak (95058c6)
|
||||
|
||||
* Fixed argument checks and return values.
|
||||
|
||||
2016-02-24 20:16:19 +0100 Armin Novak (0bfe5ba)
|
||||
|
||||
* Fixed naming of static functions.
|
||||
|
||||
2016-02-24 17:04:03 +0100 Armin Novak (ada2b16)
|
||||
|
||||
* Unified RC4 functions.
|
||||
|
||||
2016-02-24 16:46:25 +0100 Armin Novak (06da644)
|
||||
|
||||
* Unified md5 functions.
|
||||
|
||||
2016-02-24 16:36:15 +0100 Armin Novak (0e4ea39)
|
||||
|
||||
* Unified sha1 functions.
|
||||
|
||||
2016-02-24 09:43:53 +0100 Armin Novak (7795ebd)
|
||||
|
||||
* Fixed return value for DST.
|
||||
|
||||
2016-02-24 09:42:12 +0100 Armin Novak (495df6d)
|
||||
|
||||
* Readded read timezone from link.
|
||||
|
||||
2016-02-23 18:15:25 +0100 Armin Novak (1cd6697)
|
||||
|
||||
* Implemented timezone detection for android
|
||||
|
||||
2016-02-23 18:08:18 +0100 Armin Novak (447ac23)
|
||||
|
||||
* Refactored timezone functions.
|
||||
|
||||
2016-02-23 20:23:52 +0100 akallabeth (7c5fcc9)
|
||||
|
||||
* Merge pull request #3149 from bmiklautz/feb22
|
||||
|
||||
2016-02-23 19:11:32 +0100 Bernhard Miklautz (ce51592)
|
||||
|
||||
* Merge pull request #3150 from xhaakon/subsystem-lib
|
||||
|
||||
2016-02-23 10:49:52 +0100 Jakub Adam (db44d27)
|
||||
|
||||
* server/shadow: Build libraries for shadow subsystems
|
||||
|
||||
2016-02-23 17:14:08 +0100 Bernhard Miklautz (738f55a)
|
||||
|
||||
* Merge pull request #3119 from akallabeth/abort_event_reset
|
||||
|
||||
2016-02-23 16:46:16 +0100 akallabeth (a53e4f4)
|
||||
|
||||
* Merge pull request #3015 from bmiklautz/pull/2936
|
||||
|
||||
2016-02-23 15:58:48 +0100 Armin Novak (d28cb6a)
|
||||
|
||||
* Removed function call with invalid arguments.
|
||||
|
||||
2016-02-10 11:20:52 +0100 Armin Novak (24c93e4)
|
||||
|
||||
* Resetting abortEvent only on connect and reconnect.
|
||||
|
||||
2016-02-23 16:25:05 +0100 Bernhard Miklautz (dd93fd2)
|
||||
|
||||
* timezon: add support for tz package
|
||||
|
||||
2016-02-23 15:34:58 +0100 Bernhard Miklautz (be02849)
|
||||
|
||||
* tcp: set the timeout to 9s
|
||||
|
||||
2015-10-19 18:29:30 +0000 volth (8b9c402)
|
||||
|
||||
* Increase TCP_USER_TIMEOUT to avoid disconnections.
|
||||
|
||||
2016-02-23 14:09:14 +0100 David FORT (0bf2fae)
|
||||
|
||||
* Fix compilation with out-of-tree builds
|
||||
|
||||
2016-02-23 09:22:15 +0100 David FORT (c1c43f9)
|
||||
|
||||
* Fixed detection of wayland libs
|
||||
|
||||
2016-02-22 16:03:57 +0100 David FORT (5dcb3df)
|
||||
|
||||
* Fix compilation and detection under debian/ubuntu
|
||||
|
||||
2016-01-18 15:55:33 +0100 David FORT (87d6caa)
|
||||
|
||||
* Integrate UWAC in to the FreeRDP source tree
|
||||
|
||||
2016-01-12 22:29:38 +0100 David FORT (bc31c00)
|
||||
|
||||
* Fixed detection of UWAC library
|
||||
|
||||
2016-01-06 23:56:05 +0100 David FORT (ded17d9)
|
||||
|
||||
* Move wayland client to UWAC
|
||||
|
||||
2016-02-23 11:44:58 +0100 Bernhard Miklautz (35faa8b)
|
||||
|
||||
* Merge pull request #3148 from mfleisz/win32_include_fix
|
||||
|
||||
2016-02-23 09:56:17 +0100 akallabeth (05aa425)
|
||||
|
||||
* Merge pull request #2851 from
|
||||
ilammy/x11-cliprdr/improve-format-support
|
||||
|
||||
2016-02-23 09:55:55 +0100 Martin Fleisz (1b881e4)
|
||||
|
||||
* winpr/file: Add missing include (io.h) for windows builds
|
||||
|
||||
2016-02-23 09:37:31 +0100 akallabeth (88fa29c)
|
||||
|
||||
* Merge pull request #3145 from giox069/master
|
||||
|
||||
2016-02-23 00:14:30 +0200 ilammy (93fc349)
|
||||
|
||||
* client/X11: harden xf_cliprdr_parse_server_format_list()
|
||||
|
||||
2016-02-22 17:01:43 +0100 Bernhard Miklautz (e6f013e)
|
||||
|
||||
* fix spelling
|
||||
|
||||
2016-02-22 13:54:08 +0100 akallabeth (4d85ade)
|
||||
|
||||
* Merge pull request #3136 from bmiklautz/winpr_version
|
||||
|
||||
2016-02-22 12:48:42 +0100 Bernhard Miklautz (8ac4998)
|
||||
|
||||
* Merge pull request #3147 from akallabeth/win_debug_symbol_fix
|
||||
|
||||
2016-02-22 10:27:50 +0100 Armin Novak (6c8de27)
|
||||
|
||||
* Installing debug symbols only if activated.
|
||||
|
||||
2016-02-21 17:52:52 +0100 Giovanni Panozzo (1dea980)
|
||||
|
||||
* Fix char signedness in glyph offset calculation, fixes #2137
|
||||
|
||||
2016-02-19 13:27:13 +0100 Bernhard Miklautz (503399f)
|
||||
|
||||
* Merge pull request #3143 from
|
||||
akallabeth/deny_cert_if_cred_from_stdin
|
||||
|
||||
2016-02-19 10:22:38 +0100 Armin Novak (ae4a1ee)
|
||||
|
||||
* Abort certificate accept if password is read from stdin.
|
||||
|
||||
2016-02-18 14:19:36 +0100 David FORT (1b2b1c4)
|
||||
|
||||
* Add support for saveSessionInfo PDU
|
||||
|
||||
2016-02-11 22:45:30 +0100 David FORT (a53cb81)
|
||||
|
||||
* Added missing checks
|
||||
|
||||
2016-02-03 10:26:59 +0100 David FORT (60fed9d)
|
||||
|
||||
* Mutualize definitions for the printer channel
|
||||
|
||||
2016-02-16 17:39:22 +0100 Bernhard Miklautz (12bd0ec)
|
||||
|
||||
* winpr: BUMP the API version to 1.2
|
||||
|
||||
2016-02-15 13:52:47 +0100 Hardening (2a3e999)
|
||||
|
||||
* Merge pull request #2710 from akallabeth/cert_temp_accept_v2
|
||||
|
||||
2016-02-14 14:18:26 +0100 Hardening (0092bcf)
|
||||
|
||||
* Merge pull request #3130 from pxx02134/patch-1
|
||||
|
||||
2016-02-14 14:17:52 +0100 Hardening (f524c4c)
|
||||
|
||||
* Merge pull request #3131 from pxx02134/patch-2
|
||||
|
||||
2016-02-12 21:19:13 +0100 Hardening (ef7c867)
|
||||
|
||||
* Merge pull request #3124 from nathankidd/region16_rects-handle-null
|
||||
|
||||
2016-02-11 19:34:48 -0500 Nathan Kidd (d68e58a)
|
||||
|
||||
* libfreerdp-codec: Make region16_rects() handle NULL nbRects
|
||||
|
||||
2016-02-12 10:43:25 +0100 Bernhard Miklautz (cf6ea23)
|
||||
|
||||
* Merge pull request #3123 from nfedera/fix-keyboardtype-7
|
||||
|
||||
2016-02-11 22:21:33 +0100 Hardening (cbd1ffa)
|
||||
|
||||
* Merge pull request #3110 from akallabeth/mac_os_ssl_warning_fix
|
||||
|
||||
2016-02-11 21:40:50 +0100 Norbert Federa (92aa21c)
|
||||
|
||||
* Several fixes for keyboard type 7 (japanese)
|
||||
|
||||
2016-02-11 12:24:47 +0900 pxx02134 (2bf525d)
|
||||
|
||||
* Update AndroidManifest.xml
|
||||
|
||||
2016-02-11 12:21:11 +0900 pxx02134 (2178245)
|
||||
|
||||
* Update BookmarkDB.java
|
||||
|
||||
2016-02-10 11:17:34 +0100 Hardening (8bbbbf3)
|
||||
|
||||
* Merge pull request #3116 from akallabeth/win_unicode_arg_fix
|
||||
|
||||
2016-02-09 09:36:00 +0100 Armin Novak (8be7b25)
|
||||
|
||||
* Printing help on invalid command line again.
|
||||
|
||||
2016-02-08 14:36:31 +0100 Armin Novak (d67614a)
|
||||
|
||||
* Reading unicode from command line.
|
||||
|
||||
2016-02-08 13:10:50 +0100 Norbert Federa (bb3882b)
|
||||
|
||||
* Merge pull request #3111 from colemickens/hidpi-cli
|
||||
|
||||
2015-03-04 09:37:25 -0500 Isaac Richter (1f6ba79)
|
||||
|
||||
* Enable display scaling in client
|
||||
|
||||
2016-02-05 11:52:07 +0100 Armin Novak (f456829)
|
||||
|
||||
* Fixed API for old openssl versions < 1.0.0
|
||||
|
||||
2016-02-05 11:12:48 +0100 Hardening (7534876)
|
||||
|
||||
* Merge pull request #3113 from akallabeth/remove_broken_rdpdr_check
|
||||
|
||||
2016-02-05 10:50:26 +0100 Armin Novak (c430d5e)
|
||||
|
||||
* Removed broken check, fixes #3112
|
||||
|
||||
2016-02-05 02:32:47 +0100 Armin Novak (80d7d63)
|
||||
|
||||
* Updated android API.
|
||||
|
||||
2015-12-18 10:36:28 +0100 Armin Novak (6b406bd)
|
||||
|
||||
* Not building GetLine on android and ios.
|
||||
|
||||
2015-12-18 09:45:44 +0100 Armin Novak (5e46a6e)
|
||||
|
||||
* Replaced getline with custom GetLine.
|
||||
|
||||
2015-12-17 16:43:55 +0100 Armin Novak (b35f665)
|
||||
|
||||
* Moved common code from cli clients to client lib.
|
||||
|
||||
2015-12-17 16:43:49 +0100 Armin Novak (0e2208e)
|
||||
|
||||
* Fixed warning.
|
||||
|
||||
2015-12-14 14:02:49 +0100 Armin Novak (cbf2892)
|
||||
|
||||
* Implemented temporary certificate accept.
|
||||
|
||||
2015-12-14 14:01:12 +0100 Armin Novak (1669900)
|
||||
|
||||
* Fixed allocation issue with common_name.
|
||||
|
||||
2016-02-04 16:20:59 +0100 Martin Fleisz (56a0c4c)
|
||||
|
||||
* Merge pull request #3097 from akallabeth/android_api_upgrade_v4
|
||||
|
||||
2016-02-04 16:09:49 +0100 Armin Novak (8fdf59a)
|
||||
|
||||
* Removed android SDK dependency for native build.
|
||||
|
||||
2016-02-04 15:05:07 +0100 Bernhard Miklautz (db77cff)
|
||||
|
||||
* Merge pull request #3108 from akallabeth/log_leve_adjust
|
||||
|
||||
2016-02-04 14:33:28 +0100 Armin Novak (1f81556)
|
||||
|
||||
* Removed hardcoded debug mode.
|
||||
|
||||
2016-02-04 13:56:33 +0100 Armin Novak (74f3ebf)
|
||||
|
||||
* Fixed argument for freerdp source.
|
||||
|
||||
2016-02-04 13:04:41 +0100 Norbert Federa (94565a0)
|
||||
|
||||
* Merge pull request #3109 from nfedera/fix-x11-xdgh-types-collision
|
||||
|
||||
2016-02-04 12:57:21 +0100 Armin Novak (b6b0f57)
|
||||
|
||||
* Fixed compiler warning about cast.
|
||||
|
||||
2016-02-04 12:55:11 +0100 Armin Novak (3b0f5b5)
|
||||
|
||||
* Removed obsolete APPLE preprocessor switch.
|
||||
|
||||
2016-02-03 21:32:55 +0100 Norbert Federa (099d488)
|
||||
|
||||
* fix X11/Xdg.h typedef collision fix
|
||||
|
||||
2016-02-04 11:41:54 +0100 Armin Novak (1b3ac98)
|
||||
|
||||
* rdp_print_errinfo now uses INFO log level.
|
||||
|
||||
2016-02-04 11:40:42 +0100 Armin Novak (cdadb58)
|
||||
|
||||
* Function freerdp_set_error_info fix
|
||||
|
||||
2016-02-04 11:39:57 +0100 Armin Novak (ad36a5c)
|
||||
|
||||
* Disconnect log message now uses debug level.
|
||||
|
||||
2016-02-04 09:56:52 +0100 akallabeth (eadfff8)
|
||||
|
||||
* Merge pull request #3107 from ccpp/tls-sni
|
||||
|
||||
2016-02-04 09:06:43 +0100 Hardening (13df05b)
|
||||
|
||||
* Merge pull request #3079 from akallabeth/drive_hotplug_fix
|
||||
|
||||
2016-02-04 08:34:51 +0100 Christian Plattner (c0226d6)
|
||||
|
||||
* Enable support for SNI on client side
|
||||
|
||||
2016-02-03 13:55:37 +0100 akallabeth (b769d84)
|
||||
|
||||
* Merge pull request #3105 from nfedera/fix-cmake-include-names
|
||||
|
||||
2016-02-03 13:37:35 +0100 Norbert Federa (24a2f2a)
|
||||
|
||||
* appropriate names in server & client cmake exports
|
||||
|
||||
2016-02-03 12:56:45 +0100 Norbert Federa (157d81b)
|
||||
|
||||
* Merge pull request #3104 from akallabeth/sign_mismatch_fixes
|
||||
|
||||
2016-02-03 12:46:02 +0100 Armin Novak (96bf6fc)
|
||||
|
||||
* Fixed inverted check.
|
||||
|
||||
2016-02-03 12:45:49 +0100 Armin Novak (f835744)
|
||||
|
||||
* Removed unused variable.
|
||||
|
||||
2016-02-03 12:45:31 +0100 Armin Novak (40519f0)
|
||||
|
||||
* Fixed initialization warning.
|
||||
|
||||
2016-02-03 12:11:27 +0100 akallabeth (c17c7de)
|
||||
|
||||
* Merge pull request #3094 from DavBfr/mac-adpcm
|
||||
|
||||
2016-02-03 11:55:23 +0100 Armin Novak (d267750)
|
||||
|
||||
* Fixed flac caps creation.
|
||||
|
||||
2016-02-03 11:51:31 +0100 Armin Novak (10956f3)
|
||||
|
||||
* Fixed constant definition.
|
||||
|
||||
2016-02-03 11:45:22 +0100 Armin Novak (22f704c)
|
||||
|
||||
* Fixed _socket error check.
|
||||
|
||||
2016-02-03 11:43:01 +0100 Armin Novak (c2d2ead)
|
||||
|
||||
* Fixed error check.
|
||||
|
||||
2016-02-03 11:30:15 +0100 Armin Novak (539be1f)
|
||||
|
||||
* Fixed unsigned underflow.
|
||||
|
||||
2016-02-03 11:23:41 +0100 Armin Novak (d1c59f7)
|
||||
|
||||
* Fixed invalid boolean check.
|
||||
|
||||
2016-02-03 11:22:27 +0100 Armin Novak (a1617c7)
|
||||
|
||||
* Fixed unused check.
|
||||
|
||||
2016-02-03 11:04:35 +0100 Armin Novak (511f9e8)
|
||||
|
||||
* Use ERROR_INVALID_DATA for short buffers.
|
||||
|
||||
2016-02-03 09:46:16 +0100 Martin Fleisz (9712509)
|
||||
|
||||
* Merge pull request #3103 from llyzs/memfix
|
||||
|
||||
2016-02-03 13:34:58 +0800 Vic Lee (73f895f)
|
||||
|
||||
* gcc: assigned string must not be freed.
|
||||
|
||||
2016-02-02 11:58:05 -0800 David PHAM-VAN (506749b)
|
||||
|
||||
* Activate WITH_MACAUDIO flag if the build is for OS X
|
||||
|
||||
2016-02-02 18:47:26 +0100 Martin Fleisz (220478e)
|
||||
|
||||
* Merge pull request #3101 from akallabeth/stdbool_detection_fix
|
||||
|
||||
2016-02-02 18:24:30 +0100 Armin Novak (9b0ef3a)
|
||||
|
||||
* Fixed stdint.h and stdbool.h detection.
|
||||
|
||||
2016-02-02 17:59:56 +0100 Armin Novak (96aecca)
|
||||
|
||||
* Fixed length check issue.
|
||||
|
||||
2016-02-02 16:10:33 +0100 Armin Novak (5c97075)
|
||||
|
||||
* Fixed stdbool.h and stdint.h detection.
|
||||
|
||||
2016-02-02 10:02:00 +0100 Martin Fleisz (c862ca3)
|
||||
|
||||
* Merge pull request #3099 from akallabeth/mac_fullscreen
|
||||
|
||||
2016-02-02 09:50:23 +0100 Armin Novak (c908b95)
|
||||
|
||||
* Reformatted patch.
|
||||
|
||||
2015-03-23 13:54:04 +0100 “John (8324b3d)
|
||||
|
||||
* Mac Fullscreen + window title
|
||||
|
||||
2016-02-01 16:01:32 +0100 Armin Novak (b8106a1)
|
||||
|
||||
* Updated documentation and default build config.
|
||||
|
||||
2016-02-01 15:25:40 +0100 Armin Novak (54a7d79)
|
||||
|
||||
* Restructured client project, moved to gradle build.
|
||||
|
||||
2016-02-01 15:22:10 +0100 Armin Novak (d04eb12)
|
||||
|
||||
* Added new android build scripts.
|
||||
|
||||
2016-02-01 15:21:07 +0100 Armin Novak (61633a1)
|
||||
|
||||
* Fixed android build issues.
|
||||
|
||||
2016-02-01 15:09:51 +0100 Armin Novak (cd05ea7)
|
||||
|
||||
* Fixed error checks for command line parser.
|
||||
|
||||
2016-02-01 13:02:38 +0100 Bernhard Miklautz (8ec3903)
|
||||
|
||||
* Merge pull request #3076 from
|
||||
akallabeth/remove_fixed_size_heap_strings
|
||||
|
||||
2016-02-01 13:00:23 +0100 akallabeth (cccc8b1)
|
||||
|
||||
* Merge pull request #3096 from bmiklautz/fix/nightlies
|
||||
|
||||
2016-02-01 12:47:00 +0100 Bernhard Miklautz (7b9881e)
|
||||
|
||||
* pkg/deb: fix nightly builds
|
||||
|
||||
2016-01-29 09:58:48 -0800 David PHAM-VAN (3f5ce2d)
|
||||
|
||||
* Refactor format_supported with a nice switch() statement
|
||||
|
||||
2016-01-25 13:53:19 -0800 David PHAM-VAN (8ef64ae)
|
||||
|
||||
* Add ADPCM codec for Mac client
|
||||
|
||||
2016-01-28 15:26:04 +0100 MartinHaimberger (e83f97b)
|
||||
|
||||
* Merge pull request #3093 from hardening/last_write_checks
|
||||
|
||||
2016-01-28 15:23:24 +0100 MartinHaimberger (83b706c)
|
||||
|
||||
* Merge pull request #3092 from akallabeth/get_build_config
|
||||
|
||||
2016-01-28 15:12:26 +0100 David FORT (b6dd7bb)
|
||||
|
||||
* Check more Stream_EnsureCapacity results when writing capabilities
|
||||
|
||||
2016-01-28 14:36:50 +0100 MartinHaimberger (99c0a73)
|
||||
|
||||
* Merge pull request #3091 from akallabeth/wlog_warning_fix
|
||||
|
||||
2016-01-28 14:30:18 +0100 akallabeth (5a2a2b8)
|
||||
|
||||
* Merge pull request #3090 from akallabeth/drdynvc_size_checks
|
||||
|
||||
2016-01-28 14:28:51 +0100 Hardening (a2aa56e)
|
||||
|
||||
* Merge pull request #3067 from akallabeth/reset_abort_event
|
||||
|
||||
2016-01-28 14:26:50 +0100 Armin Novak (035f127)
|
||||
|
||||
* Added get_build_config functions.
|
||||
|
||||
2016-01-28 12:25:44 +0100 Armin Novak (d847993)
|
||||
|
||||
* Using Stream_ReminingLength for read checks.
|
||||
|
||||
2016-01-28 12:08:57 +0100 Armin Novak (c251534)
|
||||
|
||||
* Fixed return value of WLog_FileAppender_WriteImageMessage
|
||||
|
||||
2016-01-28 12:05:14 +0100 Armin Novak (6f50589)
|
||||
|
||||
* Cleared up error code usage.
|
||||
|
||||
2016-01-28 11:45:06 +0100 Armin Novak (8595e39)
|
||||
|
||||
* Fixed size checks (thanks to @virtman)
|
||||
|
||||
2016-01-28 11:12:20 +0100 Armin Novak (57f1e26)
|
||||
|
||||
* Checking capability read return. Updated copyright headers.
|
||||
|
||||
2016-01-28 10:33:17 +0100 Martin Fleisz (7294a7f)
|
||||
|
||||
* Merge pull request #3078 from akallabeth/wlog_cmd_options
|
||||
|
||||
2016-01-28 10:32:14 +0100 Martin Fleisz (81f5060)
|
||||
|
||||
* Merge pull request #3088 from clangm/patch-1
|
||||
|
||||
2016-01-27 15:40:08 -0700 clangm (62a559a)
|
||||
|
||||
* fix typo
|
||||
|
||||
2016-01-27 23:02:11 +0100 Hardening (bb4a0c5)
|
||||
|
||||
* Merge pull request #3087 from DavBfr/fix-png-load
|
||||
|
||||
2016-01-13 15:09:03 -0800 David PHAM-VAN (3d22cbe)
|
||||
|
||||
* Fix png image loading that needed write access
|
||||
|
||||
2016-01-27 19:26:52 +0100 Armin Novak (e08ca73)
|
||||
|
||||
* Improved error checks.
|
||||
|
||||
2016-01-27 11:21:04 +0100 Armin Novak (06adbc9)
|
||||
|
||||
* Fixed realloc check, renamed filter variable.
|
||||
|
||||
2016-01-27 10:50:38 +0100 Hardening (d458bc2)
|
||||
|
||||
* Merge pull request #3073 from davewheel/cert_key_in_memory
|
||||
|
||||
2016-01-27 10:45:54 +0100 Hardening (7af1ec8)
|
||||
|
||||
* Merge pull request #3083 from akallabeth/capability_set_fix
|
||||
|
||||
2016-01-26 21:35:16 +0100 Armin Novak (974d2ef)
|
||||
|
||||
* Fix #3081, client string encoding.
|
||||
|
||||
2016-01-27 10:18:30 +0100 Martin Fleisz (a9e4ba0)
|
||||
|
||||
* Merge pull request #3069 from davewheel/4upstream-1
|
||||
|
||||
2016-01-27 10:13:32 +0100 Martin Fleisz (b2744f8)
|
||||
|
||||
* Merge pull request #3082 from
|
||||
hardening/check_client_and_server_capabilities
|
||||
|
||||
2016-01-26 16:14:48 +0100 David FORT (708d0cb)
|
||||
|
||||
* Check server and client capabilities
|
||||
|
||||
2016-01-26 09:56:01 +0100 Martin Fleisz (b6ad805)
|
||||
|
||||
* Merge pull request #3080 from hardening/capa_write
|
||||
|
||||
2016-01-26 09:34:22 +0100 Armin Novak (106479d)
|
||||
|
||||
* Fixed clientNameLen initialization.
|
||||
|
||||
2016-01-25 19:11:35 +0100 David FORT (137825e)
|
||||
|
||||
* Stream_EnsureCapacity return value aren't checked in
|
||||
capabilities_write
|
||||
|
||||
2016-01-24 15:21:06 +0100 Armin Novak (deffd0d)
|
||||
|
||||
* Fixed argument checks for drive channel.
|
||||
|
||||
2016-01-23 15:16:13 +0100 Armin Novak (46a079f)
|
||||
|
||||
* Added new command line options for logger.
|
||||
|
||||
2016-01-23 14:42:20 +0100 Hardening (507fba0)
|
||||
|
||||
* Merge pull request #3072 from giox069/master
|
||||
|
||||
2016-01-20 12:22:32 +0100 Giovanni Panozzo (c5a4ce7)
|
||||
|
||||
* Improve error logging after calling some BIO_ functions
|
||||
|
||||
2016-01-23 00:00:18 +0100 Hardening (bbf5c77)
|
||||
|
||||
* Merge pull request #3070 from davewheel/ntlm_attrs
|
||||
|
||||
2016-01-21 21:29:42 +0100 Bernhard Miklautz (ef6cb2b)
|
||||
|
||||
* Merge pull request #3075 from akallabeth/winpr_header_install_fix
|
||||
|
||||
2016-01-21 14:47:10 +0100 Armin Novak (73ec3d6)
|
||||
|
||||
* Removed fixed size strings.
|
||||
|
||||
2016-01-21 15:26:32 +0100 Armin Novak (78d3f45)
|
||||
|
||||
* Added cmake patch from @david-geiger
|
||||
|
||||
2016-01-21 00:17:59 +0100 davewheel (d5b8585)
|
||||
|
||||
* Allow to specify the raw content of crypto materials
|
||||
|
||||
2016-01-20 22:21:05 +0100 davewheel (a971f9e)
|
||||
|
||||
* Handle more NTLM attributes
|
||||
|
||||
2016-01-20 16:54:15 +0100 davewheel (121a234)
|
||||
|
||||
* Add better handling of monitors
|
||||
|
||||
2016-01-14 21:00:41 +0100 davewheel (ca9e908)
|
||||
|
||||
* Fix a security issue in monitors packet handling
|
||||
|
||||
2016-01-19 09:28:40 +0100 Martin Fleisz (3e19791)
|
||||
|
||||
* Merge pull request #3014 from bmiklautz/winpr_nt_file
|
||||
|
||||
2016-01-19 09:27:50 +0100 Martin Fleisz (07d5d16)
|
||||
|
||||
* Merge pull request #3059 from akallabeth/zlib_memleak_fix
|
||||
|
||||
2016-01-19 09:25:42 +0100 Martin Fleisz (059286d)
|
||||
|
||||
* Merge pull request #3066 from akallabeth/srccopy_fix
|
||||
|
||||
2016-01-19 09:24:22 +0100 Martin Fleisz (90783c7)
|
||||
|
||||
* Merge pull request #3068 from akallabeth/pkg_config_fix
|
||||
|
||||
2016-01-18 22:45:40 +0100 Armin Novak (20ada7d)
|
||||
|
||||
* Fix pkg-config generation.
|
||||
|
||||
2016-01-18 10:08:12 +0100 Armin Novak (5542fef)
|
||||
|
||||
* Resetting abort event on freerdp_connect.
|
||||
|
||||
2016-01-18 09:32:34 +0100 Armin Novak (93f3c06)
|
||||
|
||||
* Fixed memory overlap check.
|
||||
|
||||
2016-01-18 09:18:42 +0100 Armin Novak (123cd52)
|
||||
|
||||
* Fixed SRCCOPY, using memmove now.
|
||||
|
||||
2016-01-15 16:32:54 +0100 akallabeth (e2dbe5e)
|
||||
|
||||
* Merge pull request #3062 from bmiklautz/build_fix (HEAD,
|
||||
origin/master, origin/HEAD, master)
|
||||
* Merge pull request #3062 from bmiklautz/build_fix
|
||||
|
||||
2016-01-15 13:23:45 +0100 Bernhard Miklautz (ede0da3)
|
||||
|
||||
* build: fix a problem with cmake version 2.8.11
|
||||
|
||||
2016-01-15 10:16:08 +0100 Armin Novak (d2ab276)
|
||||
|
||||
* Fix memory leak in lodepng_zlib_compress
|
||||
|
||||
2016-01-15 09:51:51 +0100 Martin Fleisz (2db8c7e)
|
||||
|
||||
* Merge pull request #3052 from abma/fix3051
|
||||
@ -101,6 +972,10 @@
|
||||
|
||||
* Fixed broken duplicate define.
|
||||
|
||||
2015-12-16 16:25:09 +0100 Bernhard Miklautz (aa2709a)
|
||||
|
||||
* winpr: create a specific winpr nt file handle
|
||||
|
||||
2016-01-02 11:31:39 +0100 Bernhard Miklautz (c3ce0c3)
|
||||
|
||||
* Merge pull request #2871 from realjiangms/shadow_stand_alone2
|
||||
@ -405,6 +1280,42 @@
|
||||
|
||||
* pkg: update version infos to 2.0
|
||||
|
||||
2015-08-19 10:25:59 +0300 ilammy (7bce7ef)
|
||||
|
||||
* client/X11: transfer raw clipboard format data
|
||||
|
||||
2015-08-19 10:59:49 +0300 ilammy (391ed0d)
|
||||
|
||||
* client/X11: transfer raw clipboard format lists
|
||||
|
||||
2015-08-14 22:57:42 +0300 ilammy (626e40a)
|
||||
|
||||
* client/X11: add raw clipboard transfer indication
|
||||
|
||||
2015-08-18 17:07:38 +0300 ilammy (532371d)
|
||||
|
||||
* client/X11: remove unused function
|
||||
|
||||
2015-08-18 17:05:48 +0300 ilammy (46fb66e)
|
||||
|
||||
* client/X11: send clipboard format data errors correctly
|
||||
|
||||
2015-08-19 17:25:17 +0300 ilammy (d7c9a31)
|
||||
|
||||
* client/X11: correctly trim terminating null bytes from strings
|
||||
|
||||
2015-08-17 11:35:19 +0300 ilammy (b9a2973)
|
||||
|
||||
* client/X11: improve named clipboard format support
|
||||
|
||||
2015-08-16 11:56:36 +0300 ilammy (8434709)
|
||||
|
||||
* client/X11: improve clipboard format search functions
|
||||
|
||||
2015-08-15 00:15:44 +0300 ilammy (4b67513)
|
||||
|
||||
* winpr/clipboard: add CF_RAW clipboard format ID
|
||||
|
||||
2015-11-13 11:47:58 +0100 Armin Novak (f4a466b)
|
||||
|
||||
* Added mac implementation.
|
||||
|
||||
@ -771,6 +771,8 @@ static BOOL audin_process_addin_args(IWTSPlugin* pPlugin, ADDIN_ARGV* args)
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DVCPluginEntry audin_DVCPluginEntry
|
||||
#else
|
||||
#define DVCPluginEntry FREERDP_API DVCPluginEntry
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@ -218,8 +218,6 @@ static BOOL audin_opensles_format_supported(IAudinDevice* device, audinFormat* f
|
||||
|
||||
switch (format->wFormatTag)
|
||||
{
|
||||
/* TODO: Deactivated, untested */
|
||||
#if 0
|
||||
case WAVE_FORMAT_PCM: /* PCM */
|
||||
if (format->cbSize == 0 &&
|
||||
(format->nSamplesPerSec <= 48000) &&
|
||||
@ -229,7 +227,6 @@ static BOOL audin_opensles_format_supported(IAudinDevice* device, audinFormat* f
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
/* TODO: Deactivated format, does not work, find out why */
|
||||
// case WAVE_FORMAT_ADPCM: /* IMA ADPCM */
|
||||
case WAVE_FORMAT_DVI_ADPCM:
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
LIBRARY "cliprdr"
|
||||
EXPORTS
|
||||
VirtualChannelEntry @1
|
||||
@ -340,6 +340,8 @@ UINT disp_send_monitor_layout(DispClientContext* context, UINT32 NumMonitors, DI
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DVCPluginEntry disp_DVCPluginEntry
|
||||
#else
|
||||
#define DVCPluginEntry FREERDP_API DVCPluginEntry
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@ -728,7 +728,7 @@ UINT drdynvc_send(drdynvcPlugin* drdynvc, wStream* s)
|
||||
UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UINT32 dataSize)
|
||||
{
|
||||
wStream* data_out;
|
||||
unsigned long pos = 0;
|
||||
unsigned long pos;
|
||||
UINT32 cbChId;
|
||||
UINT32 cbLen;
|
||||
unsigned long chunkLength;
|
||||
@ -747,9 +747,9 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UI
|
||||
Stream_SetPosition(data_out, 1);
|
||||
cbChId = drdynvc_write_variable_uint(data_out, ChannelId);
|
||||
|
||||
pos = Stream_GetPosition(data_out);
|
||||
if (dataSize == 0)
|
||||
{
|
||||
pos = Stream_GetPosition(data_out);
|
||||
Stream_SetPosition(data_out, 0);
|
||||
Stream_Write_UINT8(data_out, 0x40 | cbChId);
|
||||
Stream_SetPosition(data_out, pos);
|
||||
@ -758,7 +758,6 @@ UINT drdynvc_write_data(drdynvcPlugin* drdynvc, UINT32 ChannelId, BYTE* data, UI
|
||||
}
|
||||
else if (dataSize <= CHANNEL_CHUNK_LENGTH - pos)
|
||||
{
|
||||
pos = Stream_GetPosition(data_out);
|
||||
Stream_SetPosition(data_out, 0);
|
||||
Stream_Write_UINT8(data_out, 0x30 | cbChId);
|
||||
Stream_SetPosition(data_out, pos);
|
||||
|
||||
@ -286,7 +286,7 @@ static struct dirent *readdir(DIR *dirp)
|
||||
return NULL;
|
||||
}
|
||||
if (FindNextFileA (dirp->search_handle, &dirp->find_data) == FALSE) {
|
||||
/* the very last entry has been processed or an error occured */
|
||||
/* the very last entry has been processed or an error occurred */
|
||||
FindClose (dirp->search_handle);
|
||||
dirp->search_handle = INVALID_HANDLE_VALUE;
|
||||
return NULL;
|
||||
|
||||
@ -859,6 +859,8 @@ out_error:
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DeviceServiceEntry drive_DeviceServiceEntry
|
||||
#else
|
||||
#define DeviceServiceEntry FREERDP_API DeviceServiceEntry
|
||||
#endif
|
||||
|
||||
UINT sys_code_page = 0;
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
LIBRARY "drive"
|
||||
EXPORTS
|
||||
DeviceServiceEntry @1
|
||||
@ -3,6 +3,8 @@
|
||||
* statvfs emulation for Windows
|
||||
*
|
||||
* Copyright 2012 Gerald Richter
|
||||
* Copyright 2016 Inuvika Inc.
|
||||
* Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -29,17 +31,18 @@ int statvfs(const char *path, struct statvfs *buf)
|
||||
{
|
||||
BOOL res;
|
||||
int len;
|
||||
LPWSTR unicodestr;
|
||||
LPWSTR unicodestr = NULL;
|
||||
DWORD lpSectorsPerCluster;
|
||||
DWORD lpBytesPerSector;
|
||||
DWORD lpNumberOfFreeClusters;
|
||||
DWORD lpTotalNumberOfClusters;
|
||||
|
||||
len = MultiByteToWideChar(CP_ACP, 0, path, -1, NULL, 0);
|
||||
unicodestr = (LPWSTR) malloc(len);
|
||||
MultiByteToWideChar(CP_ACP, 0, path, -1, unicodestr, len);
|
||||
len = ConvertToUnicode(CP_ACP, 0, path, -1, &unicodestr, 0);
|
||||
if (len <= 0)
|
||||
return -1;
|
||||
|
||||
res = GetDiskFreeSpace(unicodestr, &lpSectorsPerCluster, &lpBytesPerSector, &lpNumberOfFreeClusters, &lpTotalNumberOfClusters);
|
||||
res = GetDiskFreeSpaceW(unicodestr, &lpSectorsPerCluster, &lpBytesPerSector, &lpNumberOfFreeClusters, &lpTotalNumberOfClusters);
|
||||
free(unicodestr);
|
||||
|
||||
buf->f_bsize = lpBytesPerSector; /* file system block size */
|
||||
buf->f_frsize = 0; /* fragment size */
|
||||
|
||||
@ -162,6 +162,8 @@ static UINT echo_plugin_terminated(IWTSPlugin* pPlugin)
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DVCPluginEntry echo_DVCPluginEntry
|
||||
#else
|
||||
#define DVCPluginEntry FREERDP_API DVCPluginEntry
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@ -394,6 +394,8 @@ static UINT parallel_free(DEVICE* device)
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DeviceServiceEntry parallel_DeviceServiceEntry
|
||||
#else
|
||||
#define DeviceServiceEntry FREERDP_API DeviceServiceEntry
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -229,10 +230,12 @@ static void printer_cups_free_printer(rdpPrinter* printer)
|
||||
cups_printer->printjob->printjob.Close((rdpPrintJob*) cups_printer->printjob);
|
||||
|
||||
free(printer->name);
|
||||
free(printer->driver);
|
||||
free(printer);
|
||||
}
|
||||
|
||||
static rdpPrinter* printer_cups_new_printer(rdpCupsPrinterDriver* cups_driver, const char* name, BOOL is_default)
|
||||
static rdpPrinter* printer_cups_new_printer(rdpCupsPrinterDriver* cups_driver,
|
||||
const char* name, const char* driverName, BOOL is_default)
|
||||
{
|
||||
rdpCupsPrinter* cups_printer;
|
||||
|
||||
@ -247,8 +250,17 @@ static rdpPrinter* printer_cups_new_printer(rdpCupsPrinterDriver* cups_driver, c
|
||||
free(cups_printer);
|
||||
return NULL;
|
||||
}
|
||||
/* This is a generic PostScript printer driver developed by MS, so it should be good in most cases */
|
||||
cups_printer->printer.driver = "MS Publisher Imagesetter";
|
||||
|
||||
if (driverName)
|
||||
cups_printer->printer.driver = _strdup(driverName);
|
||||
else
|
||||
cups_printer->printer.driver = _strdup("MS Publisher Imagesetter");
|
||||
if (!cups_printer->printer.driver)
|
||||
{
|
||||
free(cups_printer->printer.name);
|
||||
free(cups_printer);
|
||||
return NULL;
|
||||
}
|
||||
cups_printer->printer.is_default = is_default;
|
||||
|
||||
cups_printer->printer.CreatePrintJob = printer_cups_create_printjob;
|
||||
@ -279,7 +291,7 @@ static rdpPrinter** printer_cups_enum_printers(rdpPrinterDriver* driver)
|
||||
if (dest->instance == NULL)
|
||||
{
|
||||
printers[num_printers++] = printer_cups_new_printer((rdpCupsPrinterDriver*) driver,
|
||||
dest->name, dest->is_default);
|
||||
dest->name, NULL, dest->is_default);
|
||||
}
|
||||
}
|
||||
cupsFreeDests(num_dests, dests);
|
||||
@ -287,11 +299,13 @@ static rdpPrinter** printer_cups_enum_printers(rdpPrinterDriver* driver)
|
||||
return printers;
|
||||
}
|
||||
|
||||
static rdpPrinter* printer_cups_get_printer(rdpPrinterDriver* driver, const char* name)
|
||||
static rdpPrinter* printer_cups_get_printer(rdpPrinterDriver* driver,
|
||||
const char* name, const char* driverName)
|
||||
{
|
||||
rdpCupsPrinterDriver* cups_driver = (rdpCupsPrinterDriver*) driver;
|
||||
|
||||
return printer_cups_new_printer(cups_driver, name, cups_driver->id_sequence == 1 ? TRUE : FALSE);
|
||||
return printer_cups_new_printer(cups_driver, name, driverName,
|
||||
cups_driver->id_sequence == 1 ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
static rdpCupsPrinterDriver* cups_driver = NULL;
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -36,6 +37,8 @@
|
||||
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
|
||||
#include "../printer.h"
|
||||
|
||||
#ifdef WITH_CUPS
|
||||
#include "printer_cups.h"
|
||||
#endif
|
||||
@ -449,6 +452,8 @@ error_out:
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DeviceServiceEntry printer_DeviceServiceEntry
|
||||
#else
|
||||
#define DeviceServiceEntry FREERDP_API DeviceServiceEntry
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -487,7 +492,7 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
|
||||
if (name && name[0])
|
||||
{
|
||||
printer = driver->GetPrinter(driver, name);
|
||||
printer = driver->GetPrinter(driver, name, driver_name);
|
||||
|
||||
if (!printer)
|
||||
{
|
||||
@ -495,9 +500,6 @@ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
|
||||
return CHANNEL_RC_INITIALIZATION_ERROR;
|
||||
}
|
||||
|
||||
if (driver_name && driver_name[0])
|
||||
printer->driver = driver_name;
|
||||
|
||||
if ((error = printer_register(pEntryPoints, printer)))
|
||||
{
|
||||
WLog_ERR(TAG, "printer_register failed with error %lu!", error);
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -24,25 +25,12 @@
|
||||
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
|
||||
/* SERVER_PRINTER_CACHE_EVENT.cachedata */
|
||||
#define RDPDR_ADD_PRINTER_EVENT 0x00000001
|
||||
#define RDPDR_UPDATE_PRINTER_EVENT 0x00000002
|
||||
#define RDPDR_DELETE_PRINTER_EVENT 0x00000003
|
||||
#define RDPDR_RENAME_PRINTER_EVENT 0x00000004
|
||||
|
||||
/* DR_PRN_DEVICE_ANNOUNCE.Flags */
|
||||
#define RDPDR_PRINTER_ANNOUNCE_FLAG_ASCII 0x00000001
|
||||
#define RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER 0x00000002
|
||||
#define RDPDR_PRINTER_ANNOUNCE_FLAG_NETWORKPRINTER 0x00000004
|
||||
#define RDPDR_PRINTER_ANNOUNCE_FLAG_TSPRINTER 0x00000008
|
||||
#define RDPDR_PRINTER_ANNOUNCE_FLAG_XPSFORMAT 0x00000010
|
||||
|
||||
typedef struct rdp_printer_driver rdpPrinterDriver;
|
||||
typedef struct rdp_printer rdpPrinter;
|
||||
typedef struct rdp_print_job rdpPrintJob;
|
||||
|
||||
typedef rdpPrinter** (*pcEnumPrinters) (rdpPrinterDriver* driver);
|
||||
typedef rdpPrinter* (*pcGetPrinter) (rdpPrinterDriver* driver, const char* name);
|
||||
typedef rdpPrinter* (*pcGetPrinter) (rdpPrinterDriver* driver, const char* name, const char* driverName);
|
||||
|
||||
struct rdp_printer_driver
|
||||
{
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
* Copyright 2012 Gerald Richter
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -175,10 +176,12 @@ static void printer_win_free_printer(rdpPrinter* printer)
|
||||
win_printer->printjob->printjob.Close((rdpPrintJob*) win_printer->printjob);
|
||||
|
||||
free(printer->name);
|
||||
free(printer->driver);
|
||||
free(printer);
|
||||
}
|
||||
|
||||
static rdpPrinter* printer_win_new_printer(rdpWinPrinterDriver* win_driver, const char* name, const wchar_t* drivername, BOOL is_default)
|
||||
static rdpPrinter* printer_win_new_printer(rdpWinPrinterDriver* win_driver,
|
||||
const char* name, const WCHAR* drivername, BOOL is_default)
|
||||
{
|
||||
rdpWinPrinter* win_printer;
|
||||
wchar_t wname[256];
|
||||
@ -216,7 +219,10 @@ static rdpPrinter* printer_win_new_printer(rdpWinPrinterDriver* win_driver, cons
|
||||
}
|
||||
GetPrinter(win_printer->hPrinter, 2, (LPBYTE) prninfo, needed, &needed);
|
||||
|
||||
win_printer->printer.driver = malloc(1000);
|
||||
if (drivername)
|
||||
win_printer->printer.driver = _wcsdup(drivername);
|
||||
else
|
||||
win_printer->printer.driver = _wcsdup(prninfo->pDriverName);
|
||||
if (!win_printer->printer.driver)
|
||||
{
|
||||
GlobalFree(prninfo);
|
||||
@ -224,7 +230,6 @@ static rdpPrinter* printer_win_new_printer(rdpWinPrinterDriver* win_driver, cons
|
||||
free(win_printer);
|
||||
return NULL;
|
||||
}
|
||||
wcstombs_s(&charsConverted, win_printer->printer.driver, 1000, prninfo->pDriverName, _TRUNCATE);
|
||||
|
||||
return (rdpPrinter*)win_printer;
|
||||
}
|
||||
@ -274,13 +279,24 @@ static rdpPrinter** printer_win_enum_printers(rdpPrinterDriver* driver)
|
||||
return printers;
|
||||
}
|
||||
|
||||
static rdpPrinter* printer_win_get_printer(rdpPrinterDriver* driver, const char* name)
|
||||
static rdpPrinter* printer_win_get_printer(rdpPrinterDriver* driver,
|
||||
const char* name, const char* driverName)
|
||||
{
|
||||
WCHAR* driverNameW = NULL;
|
||||
rdpWinPrinterDriver* win_driver = (rdpWinPrinterDriver*)driver;
|
||||
rdpPrinter *myPrinter = NULL;
|
||||
|
||||
myPrinter = printer_win_new_printer(win_driver, name, L"", win_driver->id_sequence == 1 ? TRUE : FALSE);
|
||||
|
||||
if (driverName)
|
||||
{
|
||||
ConvertToUnicode(CP_UTF8, 0, driverName, -1, &driverNameW, 0);
|
||||
if (!driverNameW)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
myPrinter = printer_win_new_printer(win_driver, name, driverNameW,
|
||||
win_driver->id_sequence == 1 ? TRUE : FALSE);
|
||||
free(driverNameW);
|
||||
|
||||
return myPrinter;
|
||||
}
|
||||
|
||||
|
||||
37
channels/printer/printer.h
Normal file
37
channels/printer/printer.h
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Definition for the printer channel
|
||||
*
|
||||
* Copyright 2016 David Fort <contact@hardening-consulting.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CHANNELS_PRINTER_PRINTER_H_
|
||||
#define __CHANNELS_PRINTER_PRINTER_H_
|
||||
|
||||
/* SERVER_PRINTER_CACHE_EVENT.cachedata */
|
||||
#define RDPDR_ADD_PRINTER_EVENT 0x00000001
|
||||
#define RDPDR_UPDATE_PRINTER_EVENT 0x00000002
|
||||
#define RDPDR_DELETE_PRINTER_EVENT 0x00000003
|
||||
#define RDPDR_RENAME_PRINTER_EVENT 0x00000004
|
||||
|
||||
/* DR_PRN_DEVICE_ANNOUNCE.Flags */
|
||||
#define RDPDR_PRINTER_ANNOUNCE_FLAG_ASCII 0x00000001
|
||||
#define RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER 0x00000002
|
||||
#define RDPDR_PRINTER_ANNOUNCE_FLAG_NETWORKPRINTER 0x00000004
|
||||
#define RDPDR_PRINTER_ANNOUNCE_FLAG_TSPRINTER 0x00000008
|
||||
#define RDPDR_PRINTER_ANNOUNCE_FLAG_XPSFORMAT 0x00000010
|
||||
|
||||
|
||||
#endif /* __CHANNELS_PRINTER_PRINTER_H_ */
|
||||
@ -6,6 +6,7 @@
|
||||
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -42,6 +43,9 @@
|
||||
|
||||
void devman_device_free(DEVICE* device)
|
||||
{
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
IFCALL(device->Free, device);
|
||||
}
|
||||
|
||||
@ -49,6 +53,9 @@ DEVMAN* devman_new(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
DEVMAN* devman;
|
||||
|
||||
if (!rdpdr)
|
||||
return NULL;
|
||||
|
||||
devman = (DEVMAN*) calloc(1, sizeof(DEVMAN));
|
||||
|
||||
if (!devman)
|
||||
@ -84,6 +91,9 @@ void devman_unregister_device(DEVMAN* devman, void* key)
|
||||
{
|
||||
DEVICE* device;
|
||||
|
||||
if (!devman || !key)
|
||||
return;
|
||||
|
||||
device = (DEVICE*) ListDictionary_Remove(devman->devices, key);
|
||||
|
||||
if (device)
|
||||
@ -99,6 +109,9 @@ static UINT devman_register_device(DEVMAN* devman, DEVICE* device)
|
||||
{
|
||||
void* key = NULL;
|
||||
|
||||
if (!devman || !device)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
device->id = devman->id_sequence++;
|
||||
key = (void*) (size_t) device->id;
|
||||
|
||||
@ -115,6 +128,9 @@ DEVICE* devman_get_device_by_id(DEVMAN* devman, UINT32 id)
|
||||
DEVICE* device = NULL;
|
||||
void* key = (void*) (size_t) id;
|
||||
|
||||
if (!devman)
|
||||
return NULL;
|
||||
|
||||
device = (DEVICE*) ListDictionary_GetItemValue(devman->devices, key);
|
||||
|
||||
return device;
|
||||
@ -137,6 +153,9 @@ UINT devman_load_device_service(DEVMAN* devman, RDPDR_DEVICE* device, rdpContext
|
||||
DEVICE_SERVICE_ENTRY_POINTS ep;
|
||||
PDEVICE_SERVICE_ENTRY entry = NULL;
|
||||
|
||||
if (!devman || !device || !rdpcontext)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (device->Type == RDPDR_DTYP_FILESYSTEM)
|
||||
ServiceName = DRIVE_SERVICE_NAME;
|
||||
else if (device->Type == RDPDR_DTYP_PRINT)
|
||||
|
||||
@ -77,18 +77,28 @@ static UINT irp_complete(IRP* irp)
|
||||
return error;
|
||||
}
|
||||
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s)
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error)
|
||||
{
|
||||
IRP* irp;
|
||||
DEVICE* device;
|
||||
UINT32 DeviceId;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 20)
|
||||
{
|
||||
if (error)
|
||||
*error = ERROR_INVALID_DATA;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, DeviceId); /* DeviceId (4 bytes) */
|
||||
device = devman_get_device_by_id(devman, DeviceId);
|
||||
|
||||
if (!device)
|
||||
{
|
||||
WLog_ERR(TAG, "devman_get_device_by_id failed!");
|
||||
WLog_WARN(TAG, "devman_get_device_by_id failed!");
|
||||
if (error)
|
||||
*error = CHANNEL_RC_OK;
|
||||
|
||||
return NULL;
|
||||
};
|
||||
|
||||
@ -97,6 +107,8 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
|
||||
if (!irp)
|
||||
{
|
||||
WLog_ERR(TAG, "_aligned_malloc failed!");
|
||||
if (error)
|
||||
*error = CHANNEL_RC_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -117,6 +129,8 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
_aligned_free(irp);
|
||||
if (error)
|
||||
*error = CHANNEL_RC_NO_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
Stream_Write_UINT16(irp->output, RDPDR_CTYP_CORE); /* Component (2 bytes) */
|
||||
@ -131,5 +145,8 @@ IRP* irp_new(DEVMAN* devman, wStream* s)
|
||||
irp->thread = NULL;
|
||||
irp->cancelled = FALSE;
|
||||
|
||||
if (error)
|
||||
*error = CHANNEL_RC_OK;
|
||||
|
||||
return irp;
|
||||
}
|
||||
|
||||
@ -23,6 +23,6 @@
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s);
|
||||
IRP* irp_new(DEVMAN* devman, wStream* s, UINT* error);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_IRP_H */
|
||||
|
||||
@ -4,8 +4,9 @@
|
||||
*
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015-2016 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -60,12 +61,21 @@ static void rdpdr_write_general_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
|
||||
/* Process device direction general capability set */
|
||||
static void rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_general_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 capabilityLength;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/* Output printer direction capability set */
|
||||
@ -75,12 +85,21 @@ static void rdpdr_write_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
|
||||
/* Process printer direction capability set */
|
||||
static void rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_printer_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 capabilityLength;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/* Output port redirection capability set */
|
||||
@ -90,12 +109,21 @@ static void rdpdr_write_port_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
|
||||
/* Process port redirection capability set */
|
||||
static void rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_port_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 capabilityLength;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/* Output drive redirection capability set */
|
||||
@ -105,12 +133,21 @@ static void rdpdr_write_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
|
||||
/* Process drive redirection capability set */
|
||||
static void rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_drive_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 capabilityLength;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/* Output smart card redirection capability set */
|
||||
@ -120,53 +157,77 @@ static void rdpdr_write_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
}
|
||||
|
||||
/* Process smartcard redirection capability set */
|
||||
static void rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_smartcard_capset(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 capabilityLength;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 2)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityLength);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < capabilityLength - 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Seek(s, capabilityLength - 4);
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT status = CHANNEL_RC_OK;
|
||||
UINT16 i;
|
||||
UINT16 numCapabilities;
|
||||
UINT16 capabilityType;
|
||||
|
||||
if (!rdpdr || !s)
|
||||
return CHANNEL_RC_NULL_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, numCapabilities);
|
||||
Stream_Seek(s, 2); /* pad (2 bytes) */
|
||||
|
||||
for (i = 0; i < numCapabilities; i++)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < sizeof(UINT16))
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, capabilityType);
|
||||
|
||||
switch (capabilityType)
|
||||
{
|
||||
case CAP_GENERAL_TYPE:
|
||||
rdpdr_process_general_capset(rdpdr, s);
|
||||
break;
|
||||
case CAP_GENERAL_TYPE:
|
||||
status = rdpdr_process_general_capset(rdpdr, s);
|
||||
break;
|
||||
|
||||
case CAP_PRINTER_TYPE:
|
||||
rdpdr_process_printer_capset(rdpdr, s);
|
||||
break;
|
||||
case CAP_PRINTER_TYPE:
|
||||
status = rdpdr_process_printer_capset(rdpdr, s);
|
||||
break;
|
||||
|
||||
case CAP_PORT_TYPE:
|
||||
rdpdr_process_port_capset(rdpdr, s);
|
||||
break;
|
||||
case CAP_PORT_TYPE:
|
||||
status = rdpdr_process_port_capset(rdpdr, s);
|
||||
break;
|
||||
|
||||
case CAP_DRIVE_TYPE:
|
||||
rdpdr_process_drive_capset(rdpdr, s);
|
||||
break;
|
||||
case CAP_DRIVE_TYPE:
|
||||
status = rdpdr_process_drive_capset(rdpdr, s);
|
||||
break;
|
||||
|
||||
case CAP_SMARTCARD_TYPE:
|
||||
rdpdr_process_smartcard_capset(rdpdr, s);
|
||||
break;
|
||||
case CAP_SMARTCARD_TYPE:
|
||||
status = rdpdr_process_smartcard_capset(rdpdr, s);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
return status;
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
||||
void rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s);
|
||||
UINT rdpdr_process_capability_request(rdpdrPlugin* rdpdr, wStream* s);
|
||||
UINT rdpdr_send_capability_response(rdpdrPlugin* rdpdr);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_RDPDR_CLIENT_CAPABILITIES_H */
|
||||
|
||||
@ -4,8 +4,9 @@
|
||||
*
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015-2016 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@thincast.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -81,7 +82,7 @@ static UINT rdpdr_send_device_list_remove_request(rdpdrPlugin* rdpdr, UINT32 cou
|
||||
UINT32 i;
|
||||
wStream* s;
|
||||
|
||||
s = Stream_New(NULL, 256);
|
||||
s = Stream_New(NULL, count * sizeof(UINT32) + 8);
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
@ -429,7 +430,7 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
BOOL dev_found = FALSE;
|
||||
|
||||
device_ext = (DEVICE_DRIVE_EXT *)ListDictionary_GetItemValue(rdpdr->devman->devices, (void *)keys[j]);
|
||||
if (!device_ext)
|
||||
if (!device_ext || !device_ext->path)
|
||||
continue;
|
||||
|
||||
/* not plugable device */
|
||||
@ -496,7 +497,6 @@ static UINT handle_hotplug(rdpdrPlugin* rdpdr)
|
||||
free(drive->Path);
|
||||
free(drive->Name);
|
||||
free(drive);
|
||||
error = CHANNEL_RC_NO_MEMORY;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
@ -517,15 +517,15 @@ static void* drive_hotplug_thread_func(void* arg)
|
||||
struct timeval tv;
|
||||
int rv;
|
||||
UINT error;
|
||||
DWORD status;
|
||||
DWORD status;
|
||||
|
||||
rdpdr = (rdpdrPlugin*) arg;
|
||||
|
||||
if (!(rdpdr->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
|
||||
{
|
||||
WLog_ERR(TAG, "CreateEvent failed!");
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mfd = open("/proc/mounts", O_RDONLY, 0);
|
||||
@ -533,8 +533,8 @@ static void* drive_hotplug_thread_func(void* arg)
|
||||
if (mfd < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "ERROR: Unable to open /proc/mounts.");
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
error = ERROR_INTERNAL_ERROR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
@ -545,18 +545,18 @@ static void* drive_hotplug_thread_func(void* arg)
|
||||
if ((error = handle_hotplug(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "handle_hotplug failed with error %lu!", error);
|
||||
goto out;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((rv = select(mfd+1, NULL, NULL, &rfds, &tv)) >= 0)
|
||||
{
|
||||
status = WaitForSingleObject(rdpdr->stopEvent, 0);
|
||||
if (status == WAIT_FAILED)
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
goto out;
|
||||
}
|
||||
status = WaitForSingleObject(rdpdr->stopEvent, 0);
|
||||
if (status == WAIT_FAILED)
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
goto out;
|
||||
}
|
||||
if (status == WAIT_OBJECT_0)
|
||||
break;
|
||||
|
||||
@ -566,7 +566,7 @@ static void* drive_hotplug_thread_func(void* arg)
|
||||
if ((error = handle_hotplug(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "handle_hotplug failed with error %lu!", error);
|
||||
goto out;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -577,11 +577,11 @@ static void* drive_hotplug_thread_func(void* arg)
|
||||
}
|
||||
|
||||
out:
|
||||
if (error && rdpdr->rdpcontext)
|
||||
setChannelError(rdpdr->rdpcontext, error, "drive_hotplug_thread_func reported an error");
|
||||
if (error && rdpdr->rdpcontext)
|
||||
setChannelError(rdpdr->rdpcontext, error, "drive_hotplug_thread_func reported an error");
|
||||
|
||||
ExitThread((DWORD)error);
|
||||
return NULL;
|
||||
ExitThread((DWORD)error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -591,21 +591,22 @@ out:
|
||||
*/
|
||||
static UINT drive_hotplug_thread_terminate(rdpdrPlugin* rdpdr)
|
||||
{
|
||||
UINT error;
|
||||
UINT error;
|
||||
|
||||
if (rdpdr->hotplugThread)
|
||||
{
|
||||
if (rdpdr->stopEvent)
|
||||
SetEvent(rdpdr->stopEvent);
|
||||
|
||||
if (WaitForSingleObject(rdpdr->hotplugThread, INFINITE) == WAIT_FAILED)
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
rdpdr->hotplugThread = NULL;
|
||||
}
|
||||
return CHANNEL_RC_OK;
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -661,13 +662,18 @@ static UINT rdpdr_process_connect(rdpdrPlugin* rdpdr)
|
||||
return error;
|
||||
}
|
||||
|
||||
static void rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_server_announce_request(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, rdpdr->versionMajor);
|
||||
Stream_Read_UINT16(s, rdpdr->versionMinor);
|
||||
Stream_Read_UINT32(s, rdpdr->clientID);
|
||||
|
||||
rdpdr->sequenceId++;
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -683,7 +689,7 @@ static UINT rdpdr_send_client_announce_reply(rdpdrPlugin* rdpdr)
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
return CHANNEL_RC_OK;
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
Stream_Write_UINT16(s, RDPDR_CTYP_CORE); /* Component (2 bytes) */
|
||||
@ -733,12 +739,15 @@ static UINT rdpdr_send_client_name_request(rdpdrPlugin* rdpdr)
|
||||
return rdpdr_send(rdpdr, s);
|
||||
}
|
||||
|
||||
static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s)
|
||||
static UINT rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
UINT16 versionMajor;
|
||||
UINT16 versionMinor;
|
||||
UINT32 clientID;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, versionMajor);
|
||||
Stream_Read_UINT16(s, versionMinor);
|
||||
Stream_Read_UINT32(s, clientID);
|
||||
@ -750,9 +759,9 @@ static void rdpdr_process_server_clientid_confirm(rdpdrPlugin* rdpdr, wStream* s
|
||||
}
|
||||
|
||||
if (clientID != rdpdr->clientID)
|
||||
{
|
||||
rdpdr->clientID = clientID;
|
||||
}
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -804,13 +813,13 @@ static UINT rdpdr_send_device_list_announce_request(rdpdrPlugin* rdpdr, BOOL use
|
||||
*/
|
||||
|
||||
if ((rdpdr->versionMinor == 0x0005) ||
|
||||
(device->type == RDPDR_DTYP_SMARTCARD) || userLoggedOn)
|
||||
(device->type == RDPDR_DTYP_SMARTCARD) || userLoggedOn)
|
||||
{
|
||||
data_len = (int) (device->data == NULL ? 0 : Stream_GetPosition(device->data));
|
||||
if (!Stream_EnsureRemainingCapacity(s, 20 + data_len))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(s, device->type); /* deviceType */
|
||||
@ -859,20 +868,20 @@ static UINT rdpdr_process_irp(rdpdrPlugin* rdpdr, wStream* s)
|
||||
IRP* irp;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
irp = irp_new(rdpdr->devman, s);
|
||||
irp = irp_new(rdpdr->devman, s, &error);
|
||||
|
||||
if (!irp)
|
||||
{
|
||||
WLog_ERR(TAG, "irp_new failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
WLog_ERR(TAG, "irp_new failed with %lu!", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
IFCALLRET(irp->device->IRPRequest, error, irp->device, irp);
|
||||
|
||||
if (error)
|
||||
WLog_ERR(TAG, "device->IRPRequest failed with error %lu", error);
|
||||
if (error)
|
||||
WLog_ERR(TAG, "device->IRPRequest failed with error %lu", error);
|
||||
|
||||
return error;
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -921,6 +930,12 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
UINT32 status;
|
||||
UINT error;
|
||||
|
||||
if (!rdpdr || !s)
|
||||
return CHANNEL_RC_NULL_DATA;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT16(s, component); /* Component (2 bytes) */
|
||||
Stream_Read_UINT16(s, packetId); /* PacketId (2 bytes) */
|
||||
|
||||
@ -928,70 +943,77 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
switch (packetId)
|
||||
{
|
||||
case PAKID_CORE_SERVER_ANNOUNCE:
|
||||
rdpdr_process_server_announce_request(rdpdr, s);
|
||||
if ((error = rdpdr_send_client_announce_reply(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_announce_reply failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
if ((error = rdpdr_send_client_name_request(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_name_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
if ((error = rdpdr_process_init(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_init failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
case PAKID_CORE_SERVER_ANNOUNCE:
|
||||
if ((error = rdpdr_process_server_announce_request(rdpdr, s)))
|
||||
return error;
|
||||
if ((error = rdpdr_send_client_announce_reply(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_announce_reply failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
if ((error = rdpdr_send_client_name_request(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_client_name_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
if ((error = rdpdr_process_init(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_init failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_CORE_SERVER_CAPABILITY:
|
||||
rdpdr_process_capability_request(rdpdr, s);
|
||||
if ((error = rdpdr_send_capability_response(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_capability_response failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
case PAKID_CORE_SERVER_CAPABILITY:
|
||||
if ((error = rdpdr_process_capability_request(rdpdr, s)))
|
||||
return error;
|
||||
if ((error = rdpdr_send_capability_response(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_capability_response failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_CORE_CLIENTID_CONFIRM:
|
||||
rdpdr_process_server_clientid_confirm(rdpdr, s);
|
||||
if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
case PAKID_CORE_CLIENTID_CONFIRM:
|
||||
if ((error = rdpdr_process_server_clientid_confirm(rdpdr, s)))
|
||||
return error;
|
||||
|
||||
case PAKID_CORE_USER_LOGGEDON:
|
||||
if ((error = rdpdr_send_device_list_announce_request(rdpdr, TRUE)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
if ((error = rdpdr_send_device_list_announce_request(rdpdr, FALSE)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_CORE_DEVICE_REPLY:
|
||||
/* connect to a specific resource */
|
||||
Stream_Read_UINT32(s, deviceId);
|
||||
Stream_Read_UINT32(s, status);
|
||||
break;
|
||||
case PAKID_CORE_USER_LOGGEDON:
|
||||
if ((error = rdpdr_send_device_list_announce_request(rdpdr, TRUE)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_send_device_list_announce_request failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_CORE_DEVICE_IOREQUEST:
|
||||
if ((error = rdpdr_process_irp(rdpdr, s)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_irp failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
s = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "RDPDR_CTYP_CORE unknown PacketId: 0x%04X", packetId);
|
||||
case PAKID_CORE_DEVICE_REPLY:
|
||||
/* connect to a specific resource */
|
||||
if (Stream_GetRemainingLength(s) < 8)
|
||||
return ERROR_INVALID_DATA;
|
||||
break;
|
||||
|
||||
Stream_Read_UINT32(s, deviceId);
|
||||
Stream_Read_UINT32(s, status);
|
||||
break;
|
||||
|
||||
case PAKID_CORE_DEVICE_IOREQUEST:
|
||||
if ((error = rdpdr_process_irp(rdpdr, s)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_irp failed with error %lu", error);
|
||||
return error;
|
||||
}
|
||||
s = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "RDPDR_CTYP_CORE unknown PacketId: 0x%04X", packetId);
|
||||
return ERROR_INVALID_DATA;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
@ -999,21 +1021,24 @@ static UINT rdpdr_process_receive(rdpdrPlugin* rdpdr, wStream* s)
|
||||
{
|
||||
switch (packetId)
|
||||
{
|
||||
case PAKID_PRN_CACHE_DATA:
|
||||
{
|
||||
UINT32 eventID;
|
||||
Stream_Read_UINT32(s, eventID);
|
||||
WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_CACHE_DATA (EventID: 0x%04X)", eventID);
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_PRN_USING_XPS:
|
||||
WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_USING_XPS");
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "Unknown printing component packetID: 0x%04X", packetId);
|
||||
case PAKID_PRN_CACHE_DATA:
|
||||
{
|
||||
UINT32 eventID;
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
Stream_Read_UINT32(s, eventID);
|
||||
WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_CACHE_DATA (EventID: 0x%04X)", eventID);
|
||||
}
|
||||
break;
|
||||
|
||||
case PAKID_PRN_USING_XPS:
|
||||
WLog_ERR(TAG, "Ignoring unhandled message PAKID_PRN_USING_XPS");
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "Unknown printing component packetID: 0x%04X", packetId);
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1132,14 +1157,15 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
|
||||
UINT status;
|
||||
rdpdrPlugin* plugin = (rdpdrPlugin*) rdpdr;
|
||||
|
||||
if (!rdpdr || !s)
|
||||
return CHANNEL_RC_NULL_DATA;
|
||||
|
||||
if (!plugin)
|
||||
{
|
||||
status = CHANNEL_RC_BAD_INIT_HANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = plugin->channelEntryPoints.pVirtualChannelWrite(plugin->OpenHandle,
|
||||
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
|
||||
Stream_Buffer(s), (UINT32) Stream_GetPosition(s), s);
|
||||
}
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
@ -1158,7 +1184,7 @@ UINT rdpdr_send(rdpdrPlugin* rdpdr, wStream* s)
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
|
||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
{
|
||||
wStream* data_in;
|
||||
|
||||
@ -1190,7 +1216,7 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
|
||||
if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
return ERROR_INVALID_DATA;
|
||||
}
|
||||
Stream_Write(data_in, pData, dataLength);
|
||||
|
||||
@ -1216,14 +1242,14 @@ static UINT rdpdr_virtual_channel_event_data_received(rdpdrPlugin* rdpdr,
|
||||
}
|
||||
|
||||
static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle, UINT event,
|
||||
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
LPVOID pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
|
||||
{
|
||||
rdpdrPlugin* rdpdr;
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
rdpdr = (rdpdrPlugin*) rdpdr_get_open_handle_data(openHandle);
|
||||
|
||||
if (!rdpdr)
|
||||
if (!rdpdr || !pData)
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_open_event: error no match");
|
||||
return;
|
||||
@ -1231,17 +1257,17 @@ static VOID VCAPITYPE rdpdr_virtual_channel_open_event(DWORD openHandle, UINT ev
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case CHANNEL_EVENT_DATA_RECEIVED:
|
||||
if ((error = rdpdr_virtual_channel_event_data_received(rdpdr, pData, dataLength, totalLength, dataFlags)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_data_received failed with error %lu!", error );
|
||||
break;
|
||||
case CHANNEL_EVENT_DATA_RECEIVED:
|
||||
if ((error = rdpdr_virtual_channel_event_data_received(rdpdr, pData, dataLength, totalLength, dataFlags)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_data_received failed with error %lu!", error );
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_WRITE_COMPLETE:
|
||||
Stream_Free((wStream*) pData, TRUE);
|
||||
break;
|
||||
case CHANNEL_EVENT_WRITE_COMPLETE:
|
||||
Stream_Free((wStream*) pData, TRUE);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_USER:
|
||||
break;
|
||||
case CHANNEL_EVENT_USER:
|
||||
break;
|
||||
}
|
||||
if (error && rdpdr->rdpcontext)
|
||||
setChannelError(rdpdr->rdpcontext, error, "rdpdr_virtual_channel_open_event reported an error");
|
||||
@ -1256,6 +1282,12 @@ static void* rdpdr_virtual_channel_client_thread(void* arg)
|
||||
rdpdrPlugin* rdpdr = (rdpdrPlugin*) arg;
|
||||
UINT error;
|
||||
|
||||
if (!rdpdr)
|
||||
{
|
||||
ExitThread((DWORD) CHANNEL_RC_NULL_DATA);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((error = rdpdr_process_connect(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_process_connect failed with error %lu!", error);
|
||||
@ -1305,16 +1337,16 @@ static UINT rdpdr_virtual_channel_event_connected(rdpdrPlugin* rdpdr, LPVOID pDa
|
||||
UINT error;
|
||||
|
||||
status = rdpdr->channelEntryPoints.pVirtualChannelOpen(rdpdr->InitHandle,
|
||||
&rdpdr->OpenHandle, rdpdr->channelDef.name, rdpdr_virtual_channel_open_event);
|
||||
&rdpdr->OpenHandle, rdpdr->channelDef.name, rdpdr_virtual_channel_open_event);
|
||||
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
|
||||
WTSErrorToString(status), status);
|
||||
return status;
|
||||
}
|
||||
if (status != CHANNEL_RC_OK)
|
||||
{
|
||||
WLog_ERR(TAG, "pVirtualChannelOpen failed with %s [%08X]",
|
||||
WTSErrorToString(status), status);
|
||||
return status;
|
||||
}
|
||||
|
||||
if ((error = rdpdr_add_open_handle_data(rdpdr->OpenHandle, rdpdr)))
|
||||
if ((error = rdpdr_add_open_handle_data(rdpdr->OpenHandle, rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "rdpdr_add_open_handle_data failed with error %lu!", error);
|
||||
return error;
|
||||
@ -1346,11 +1378,11 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr)
|
||||
UINT error;
|
||||
|
||||
if (MessageQueue_PostQuit(rdpdr->queue, 0) && (WaitForSingleObject(rdpdr->thread, INFINITE) == WAIT_FAILED))
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
{
|
||||
error = GetLastError();
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
MessageQueue_Free(rdpdr->queue);
|
||||
CloseHandle(rdpdr->thread);
|
||||
@ -1359,10 +1391,10 @@ static UINT rdpdr_virtual_channel_event_disconnected(rdpdrPlugin* rdpdr)
|
||||
rdpdr->thread = NULL;
|
||||
|
||||
if ((error = drive_hotplug_thread_terminate(rdpdr)))
|
||||
{
|
||||
WLog_ERR(TAG, "drive_hotplug_thread_terminate failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
{
|
||||
WLog_ERR(TAG, "drive_hotplug_thread_terminate failed with error %lu!", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = rdpdr->channelEntryPoints.pVirtualChannelClose(rdpdr->OpenHandle);
|
||||
if (CHANNEL_RC_OK != error)
|
||||
@ -1409,25 +1441,25 @@ static VOID VCAPITYPE rdpdr_virtual_channel_init_event(LPVOID pInitHandle, UINT
|
||||
|
||||
switch (event)
|
||||
{
|
||||
case CHANNEL_EVENT_INITIALIZED:
|
||||
break;
|
||||
case CHANNEL_EVENT_CONNECTED:
|
||||
if ((error = rdpdr_virtual_channel_event_connected(rdpdr, pData, dataLength)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_connected failed with error %lu!", error);
|
||||
break;
|
||||
case CHANNEL_EVENT_INITIALIZED:
|
||||
break;
|
||||
case CHANNEL_EVENT_CONNECTED:
|
||||
if ((error = rdpdr_virtual_channel_event_connected(rdpdr, pData, dataLength)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_connected failed with error %lu!", error);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_DISCONNECTED:
|
||||
if ((error = rdpdr_virtual_channel_event_disconnected(rdpdr)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_disconnected failed with error %lu!", error);
|
||||
break;
|
||||
case CHANNEL_EVENT_DISCONNECTED:
|
||||
if ((error = rdpdr_virtual_channel_event_disconnected(rdpdr)))
|
||||
WLog_ERR(TAG, "rdpdr_virtual_channel_event_disconnected failed with error %lu!", error);
|
||||
break;
|
||||
|
||||
case CHANNEL_EVENT_TERMINATED:
|
||||
rdpdr_virtual_channel_event_terminated(rdpdr);
|
||||
break;
|
||||
default:
|
||||
WLog_ERR(TAG, "unknown event %d!", event);
|
||||
error = ERROR_INVALID_DATA;
|
||||
break;
|
||||
case CHANNEL_EVENT_TERMINATED:
|
||||
rdpdr_virtual_channel_event_terminated(rdpdr);
|
||||
break;
|
||||
default:
|
||||
WLog_ERR(TAG, "unknown event %d!", event);
|
||||
error = ERROR_INVALID_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
if (error && rdpdr->rdpcontext)
|
||||
@ -1444,7 +1476,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
rdpdrPlugin* rdpdr;
|
||||
CHANNEL_ENTRY_POINTS_FREERDP* pEntryPointsEx;
|
||||
|
||||
|
||||
rdpdr = (rdpdrPlugin*) calloc(1, sizeof(rdpdrPlugin));
|
||||
|
||||
if (!rdpdr)
|
||||
@ -1473,7 +1504,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints)
|
||||
|
||||
CopyMemory(&(rdpdr->channelEntryPoints), pEntryPoints, sizeof(CHANNEL_ENTRY_POINTS_FREERDP));
|
||||
|
||||
|
||||
rc = rdpdr->channelEntryPoints.pVirtualChannelInit(&rdpdr->InitHandle,
|
||||
&rdpdr->channelDef, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, rdpdr_virtual_channel_init_event);
|
||||
|
||||
|
||||
@ -957,6 +957,8 @@ UINT rdpei_touch_end(RdpeiClientContext* context, int externalId, int x, int y,
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DVCPluginEntry rdpei_DVCPluginEntry
|
||||
#else
|
||||
#define DVCPluginEntry FREERDP_API DVCPluginEntry
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@ -1515,6 +1515,8 @@ void* rdpgfx_get_cache_slot_data(RdpgfxClientContext* context, UINT16 cacheSlot)
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DVCPluginEntry rdpgfx_DVCPluginEntry
|
||||
#else
|
||||
#define DVCPluginEntry FREERDP_API DVCPluginEntry
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@ -5,6 +5,8 @@
|
||||
* Copyright 2012 Laxmikant Rashinkar <LK.Rashinkar@gmail.com>
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||
* Copyright 2016 Inuvika Inc.
|
||||
* Copyright 2016 David PHAM-VAN <d.phamvan@inuvika.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -54,6 +56,12 @@ struct rdpsnd_mac_plugin
|
||||
AudioQueueRef audioQueue;
|
||||
AudioStreamBasicDescription audioFormat;
|
||||
AudioQueueBufferRef audioBuffers[MAC_AUDIO_QUEUE_NUM_BUFFERS];
|
||||
|
||||
Float64 lastStartTime;
|
||||
|
||||
int wformat;
|
||||
int block_size;
|
||||
FREERDP_DSP_CONTEXT* dsp_context;
|
||||
};
|
||||
typedef struct rdpsnd_mac_plugin rdpsndMacPlugin;
|
||||
|
||||
@ -69,6 +77,15 @@ static BOOL rdpsnd_mac_set_format(rdpsndDevicePlugin* device, AUDIO_FORMAT* form
|
||||
mac->latency = (UINT32) latency;
|
||||
CopyMemory(&(mac->format), format, sizeof(AUDIO_FORMAT));
|
||||
|
||||
mac->audioFormat.mSampleRate = format->nSamplesPerSec;
|
||||
mac->audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
|
||||
mac->audioFormat.mFramesPerPacket = 1;
|
||||
mac->audioFormat.mChannelsPerFrame = format->nChannels;
|
||||
mac->audioFormat.mBitsPerChannel = format->wBitsPerSample;
|
||||
mac->audioFormat.mBytesPerFrame = (format->wBitsPerSample * format->nChannels) / 8;
|
||||
mac->audioFormat.mBytesPerPacket = format->nBlockAlign;
|
||||
mac->audioFormat.mReserved = 0;
|
||||
|
||||
switch (format->wFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_ALAW:
|
||||
@ -83,6 +100,14 @@ static BOOL rdpsnd_mac_set_format(rdpsndDevicePlugin* device, AUDIO_FORMAT* form
|
||||
mac->audioFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
break;
|
||||
|
||||
case WAVE_FORMAT_ADPCM:
|
||||
case WAVE_FORMAT_DVI_ADPCM:
|
||||
mac->audioFormat.mFormatID = kAudioFormatLinearPCM;
|
||||
mac->audioFormat.mBitsPerChannel = 16;
|
||||
mac->audioFormat.mBytesPerFrame = (16 * format->nChannels) / 8;
|
||||
mac->audioFormat.mBytesPerPacket = mac->audioFormat.mFramesPerPacket * mac->audioFormat.mBytesPerFrame;
|
||||
break;
|
||||
|
||||
case WAVE_FORMAT_GSM610:
|
||||
mac->audioFormat.mFormatID = kAudioFormatMicrosoftGSM;
|
||||
break;
|
||||
@ -91,14 +116,8 @@ static BOOL rdpsnd_mac_set_format(rdpsndDevicePlugin* device, AUDIO_FORMAT* form
|
||||
break;
|
||||
}
|
||||
|
||||
mac->audioFormat.mSampleRate = format->nSamplesPerSec;
|
||||
mac->audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
|
||||
mac->audioFormat.mFramesPerPacket = 1;
|
||||
mac->audioFormat.mChannelsPerFrame = format->nChannels;
|
||||
mac->audioFormat.mBitsPerChannel = format->wBitsPerSample;
|
||||
mac->audioFormat.mBytesPerFrame = (format->wBitsPerSample * format->nChannels) / 8;
|
||||
mac->audioFormat.mBytesPerPacket = format->nBlockAlign;
|
||||
mac->audioFormat.mReserved = 0;
|
||||
mac->wformat = format->wFormatTag;
|
||||
mac->block_size = format->nBlockAlign;
|
||||
|
||||
rdpsnd_print_audio_format(format);
|
||||
return TRUE;
|
||||
@ -122,6 +141,8 @@ static BOOL rdpsnd_mac_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, in
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
freerdp_dsp_context_reset_adpcm(mac->dsp_context);
|
||||
|
||||
status = AudioQueueNewOutput(&(mac->audioFormat),
|
||||
mac_audio_queue_output_cb, mac,
|
||||
NULL, NULL, 0, &(mac->audioQueue));
|
||||
@ -156,7 +177,9 @@ static BOOL rdpsnd_mac_open(rdpsndDevicePlugin* device, AUDIO_FORMAT* format, in
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mac->lastStartTime = 0;
|
||||
|
||||
mac->isOpen = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
@ -184,27 +207,24 @@ static void rdpsnd_mac_free(rdpsndDevicePlugin* device)
|
||||
|
||||
device->Close(device);
|
||||
|
||||
freerdp_dsp_context_free(mac->dsp_context);
|
||||
|
||||
free(mac);
|
||||
}
|
||||
|
||||
static BOOL rdpsnd_mac_format_supported(rdpsndDevicePlugin* device, AUDIO_FORMAT* format)
|
||||
{
|
||||
if (format->wFormatTag == WAVE_FORMAT_PCM)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (format->wFormatTag == WAVE_FORMAT_ALAW)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (format->wFormatTag == WAVE_FORMAT_MULAW)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (format->wFormatTag == WAVE_FORMAT_GSM610)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
switch (format->wFormatTag)
|
||||
{
|
||||
case WAVE_FORMAT_PCM:
|
||||
case WAVE_FORMAT_ALAW:
|
||||
case WAVE_FORMAT_MULAW:
|
||||
case WAVE_FORMAT_ADPCM:
|
||||
case WAVE_FORMAT_DVI_ADPCM:
|
||||
return TRUE;
|
||||
case WAVE_FORMAT_GSM610:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -258,10 +278,42 @@ static void rdpsnd_mac_start(rdpsndDevicePlugin* device)
|
||||
}
|
||||
}
|
||||
|
||||
static void rdpsnd_mac_play(rdpsndDevicePlugin* device, BYTE* data, int size)
|
||||
static BOOL rdpsnd_mac_wave_decode(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
|
||||
{
|
||||
int length;
|
||||
BYTE* data;
|
||||
rdpsndMacPlugin* mac = (rdpsndMacPlugin*) device;
|
||||
|
||||
if (mac->wformat == WAVE_FORMAT_ADPCM)
|
||||
{
|
||||
mac->dsp_context->decode_ms_adpcm(mac->dsp_context, wave->data, wave->length, mac->format.nChannels, mac->block_size);
|
||||
length = mac->dsp_context->adpcm_size;
|
||||
data = mac->dsp_context->adpcm_buffer;
|
||||
}
|
||||
else if (mac->wformat == WAVE_FORMAT_DVI_ADPCM)
|
||||
{
|
||||
mac->dsp_context->decode_ima_adpcm(mac->dsp_context, wave->data, wave->length, mac->format.nChannels, mac->block_size);
|
||||
length = mac->dsp_context->adpcm_size;
|
||||
data = mac->dsp_context->adpcm_buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
length = wave->length;
|
||||
data = wave->data;
|
||||
}
|
||||
|
||||
wave->data = (BYTE*) malloc(length);
|
||||
CopyMemory(wave->data, data, length);
|
||||
wave->length = length;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void rdpsnd_mac_waveplay(rdpsndDevicePlugin* device, RDPSND_WAVE* wave)
|
||||
{
|
||||
int length;
|
||||
AudioQueueBufferRef audioBuffer;
|
||||
AudioTimeStamp outActualStartTime;
|
||||
rdpsndMacPlugin* mac = (rdpsndMacPlugin*) device;
|
||||
|
||||
if (!mac->isOpen)
|
||||
@ -269,13 +321,18 @@ static void rdpsnd_mac_play(rdpsndDevicePlugin* device, BYTE* data, int size)
|
||||
|
||||
audioBuffer = mac->audioBuffers[mac->audioBufferIndex];
|
||||
|
||||
length = size > audioBuffer->mAudioDataBytesCapacity ? audioBuffer->mAudioDataBytesCapacity : size;
|
||||
length = wave->length > audioBuffer->mAudioDataBytesCapacity ? audioBuffer->mAudioDataBytesCapacity : wave->length;
|
||||
|
||||
CopyMemory(audioBuffer->mAudioData, data, length);
|
||||
CopyMemory(audioBuffer->mAudioData, wave->data, length);
|
||||
audioBuffer->mAudioDataByteSize = length;
|
||||
|
||||
AudioQueueEnqueueBuffer(mac->audioQueue, audioBuffer, 0, 0);
|
||||
|
||||
audioBuffer->mUserData = wave;
|
||||
|
||||
AudioQueueEnqueueBufferWithParameters(mac->audioQueue, audioBuffer, 0, 0, 0, 0, 0, NULL, NULL, &outActualStartTime);
|
||||
UInt64 startTimeDelta = (outActualStartTime.mSampleTime - mac->lastStartTime) / 100.0;
|
||||
wave->wLocalTimeB = wave->wLocalTimeA + startTimeDelta + wave->wAudioLength;
|
||||
wave->wTimeStampB = wave->wTimeStampA + wave->wLocalTimeB - wave->wLocalTimeA;
|
||||
mac->lastStartTime = outActualStartTime.mSampleTime;
|
||||
|
||||
mac->audioBufferIndex++;
|
||||
|
||||
if (mac->audioBufferIndex >= MAC_AUDIO_QUEUE_NUM_BUFFERS)
|
||||
@ -308,10 +365,13 @@ UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS p
|
||||
mac->device.FormatSupported = rdpsnd_mac_format_supported;
|
||||
mac->device.SetFormat = rdpsnd_mac_set_format;
|
||||
mac->device.SetVolume = rdpsnd_mac_set_volume;
|
||||
mac->device.Play = rdpsnd_mac_play;
|
||||
mac->device.WaveDecode = rdpsnd_mac_wave_decode;
|
||||
mac->device.WavePlay = rdpsnd_mac_waveplay;
|
||||
mac->device.Start = rdpsnd_mac_start;
|
||||
mac->device.Close = rdpsnd_mac_close;
|
||||
mac->device.Free = rdpsnd_mac_free;
|
||||
|
||||
mac->dsp_context = freerdp_dsp_context_new();
|
||||
|
||||
pEntryPoints->pRegisterRdpsndDevice(pEntryPoints->rdpsnd, (rdpsndDevicePlugin*) mac);
|
||||
|
||||
|
||||
@ -813,6 +813,8 @@ static UINT serial_free(DEVICE* device)
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DeviceServiceEntry serial_DeviceServiceEntry
|
||||
#else
|
||||
#define DeviceServiceEntry FREERDP_API DeviceServiceEntry
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@ -489,8 +489,7 @@ static BOOL tsmf_gstreamer_set_format(ITSMFDecoder* decoder, TS_AM_MEDIA_TYPE* m
|
||||
NULL);
|
||||
break;
|
||||
case TSMF_SUB_TYPE_FLAC:
|
||||
mdecoder->gst_caps = gst_caps_new_simple("audio/x-flac",
|
||||
NULL);
|
||||
mdecoder->gst_caps = gst_caps_new_simple("audio/x-flac", "", NULL);
|
||||
break;
|
||||
default:
|
||||
WLog_ERR(TAG, "unknown format:(%d).", media_type->SubType);
|
||||
|
||||
@ -527,6 +527,8 @@ static UINT tsmf_process_addin_args(IWTSPlugin *pPlugin, ADDIN_ARGV *args)
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DVCPluginEntry tsmf_DVCPluginEntry
|
||||
#else
|
||||
#define DVCPluginEntry FREERDP_API DVCPluginEntry
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@ -548,6 +548,8 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample)
|
||||
int index = 0;
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
UINT64 time_diff;
|
||||
|
||||
temp_stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index);
|
||||
if (temp_stream->major_type == TSMF_MAJOR_TYPE_AUDIO)
|
||||
{
|
||||
@ -558,8 +560,14 @@ static BOOL tsmf_sample_playback(TSMF_SAMPLE* sample)
|
||||
if (video_time < audio_time)
|
||||
max_adjust = -VIDEO_ADJUST_MAX;
|
||||
|
||||
sample->start_time += abs(video_time - audio_time) < VIDEO_ADJUST_MAX ? (video_time - audio_time) : max_adjust;
|
||||
sample->end_time += abs(video_time - audio_time) < VIDEO_ADJUST_MAX ? (video_time - audio_time) : max_adjust;
|
||||
if (video_time > audio_time)
|
||||
time_diff = video_time - audio_time;
|
||||
else
|
||||
time_diff = audio_time - video_time;
|
||||
|
||||
time_diff = time_diff < VIDEO_ADJUST_MAX ? time_diff : max_adjust;
|
||||
sample->start_time += time_diff;
|
||||
sample->end_time += time_diff;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1215,11 +1223,11 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id,
|
||||
error_add:
|
||||
SetEvent(stream->stopEvent);
|
||||
if (WaitForSingleObject(stream->ack_thread, INFINITE) == WAIT_FAILED)
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError());
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError());
|
||||
error_ack_thread:
|
||||
SetEvent(stream->stopEvent);
|
||||
if (WaitForSingleObject(stream->play_thread, INFINITE) == WAIT_FAILED)
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError());
|
||||
WLog_ERR(TAG, "WaitForSingleObject failed with error %lu!", GetLastError());
|
||||
error_play_thread:
|
||||
Queue_Free(stream->sample_ack_list);
|
||||
error_sample_ack_list:
|
||||
|
||||
@ -1026,7 +1026,7 @@ static void* urbdrc_search_usb_device(void* arg)
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "No Device from receive_device(). An error occured.");
|
||||
WLog_ERR(TAG, "No Device from receive_device(). An error occurred.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1541,6 +1541,8 @@ static UINT urbdrc_process_addin_args(URBDRC_PLUGIN* urbdrc, ADDIN_ARGV* args)
|
||||
|
||||
#ifdef STATIC_CHANNELS
|
||||
#define DVCPluginEntry urbdrc_DVCPluginEntry
|
||||
#else
|
||||
#define DVCPluginEntry FREERDP_API DVCPluginEntry
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
message("PRELOADING windows cache")
|
||||
set (CMAKE_BUILD_TYPE "Debug" CACHE STRING "build type")
|
||||
set(WITH_SERVER "ON" CACHE BOOL "Build server binaries")
|
||||
#set (BUILD_TESTING ON CACHE BOOL "build testing")
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
set(FreeRDP_VERSION_MAJOR "@FREERDP_VERSION_MAJOR@")
|
||||
set(FreeRDP_VERSION_MINOR "@FREERDP_VERSION_MINOR@")
|
||||
set(FreeRDP_VERSION_REVISION "@FREERDP_VERSION_REVISION@")
|
||||
set(FreeRDP-Client_VERSION_MAJOR "@FREERDP_VERSION_MAJOR@")
|
||||
set(FreeRDP-Client_VERSION_MINOR "@FREERDP_VERSION_MINOR@")
|
||||
set(FreeRDP-Client_VERSION_REVISION "@FREERDP_VERSION_REVISION@")
|
||||
|
||||
set_and_check(FreeRDP_INCLUDE_DIR "@PACKAGE_FREERDP_INCLUDE_DIR@")
|
||||
set_and_check(FreeRDP-Client_INCLUDE_DIR "@PACKAGE_FREERDP_INCLUDE_DIR@")
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/FreeRDP-ClientTargets.cmake")
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
# FreeRDP Wayland Client cmake build script
|
||||
#
|
||||
# Copyright 2014 Manuel Bachmann <tarnyko@tarnyko.net>
|
||||
# Copyright 2015 David Fort <contact@hardening-consulting.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -18,22 +19,19 @@
|
||||
set(MODULE_NAME "wlfreerdp")
|
||||
set(MODULE_PREFIX "FREERDP_CLIENT_WAYLAND")
|
||||
|
||||
include_directories(${WAYLAND_INCLUDE_DIRS})
|
||||
include_directories(${CMAKE_SOURCE_DIR}/uwac/include)
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
wlf_display.c
|
||||
wlf_display.h
|
||||
wlf_window.c
|
||||
wlf_window.h
|
||||
wlfreerdp.c
|
||||
wlfreerdp.h
|
||||
wlf_input.c
|
||||
wlf_input.h
|
||||
wlfreerdp.c
|
||||
wlfreerdp.h)
|
||||
)
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${CMAKE_DL_LIBS})
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${WAYLAND_LIBRARIES} freerdp-client freerdp)
|
||||
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} freerdp-client freerdp uwac)
|
||||
target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
|
||||
|
||||
install(TARGETS ${MODULE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT client)
|
||||
|
||||
@ -1,112 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Wayland Displays
|
||||
*
|
||||
* Copyright 2014 Manuel Bachmann <tarnyko@tarnyko.net>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "wlf_display.h"
|
||||
|
||||
static void wl_registry_handle_global(void* data, struct wl_registry* registry, uint32_t id, const char *interface, uint32_t version)
|
||||
{
|
||||
wlfDisplay* display = data;
|
||||
|
||||
if (strcmp(interface, "wl_compositor") == 0)
|
||||
display->compositor = wl_registry_bind(registry, id, &wl_compositor_interface, 1);
|
||||
else if (strcmp(interface, "wl_shell") == 0)
|
||||
display->shell = wl_registry_bind(registry, id, &wl_shell_interface, 1);
|
||||
else if (strcmp(interface, "wl_shm") == 0)
|
||||
display->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
|
||||
else if (strcmp(interface, "wl_seat") == 0)
|
||||
display->seat = wl_registry_bind(registry, id, &wl_seat_interface, 1);
|
||||
}
|
||||
|
||||
static void wl_registry_handle_global_remove(void* data, struct wl_registry* registry, uint32_t name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener wl_registry_listener =
|
||||
{
|
||||
wl_registry_handle_global,
|
||||
wl_registry_handle_global_remove
|
||||
};
|
||||
|
||||
|
||||
wlfDisplay* wlf_CreateDisplay(void)
|
||||
{
|
||||
wlfDisplay* display;
|
||||
|
||||
display = (wlfDisplay*) calloc(1, sizeof(wlfDisplay));
|
||||
|
||||
if (display)
|
||||
{
|
||||
display->display = wl_display_connect(NULL);
|
||||
|
||||
if (!display->display)
|
||||
{
|
||||
WLog_ERR(TAG, "wl_pre_connect: failed to connect to Wayland compositor");
|
||||
WLog_ERR(TAG, "Please check that the XDG_RUNTIME_DIR environment variable is properly set.");
|
||||
free(display);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
display->registry = wl_display_get_registry(display->display);
|
||||
wl_registry_add_listener(display->registry, &wl_registry_listener, display);
|
||||
wl_display_roundtrip(display->display);
|
||||
|
||||
if (!display->compositor || !display->shell || !display->shm)
|
||||
{
|
||||
WLog_ERR(TAG, "wl_pre_connect: failed to find needed compositor interfaces");
|
||||
free(display);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return display;
|
||||
}
|
||||
|
||||
BOOL wlf_RefreshDisplay(wlfDisplay* display)
|
||||
{
|
||||
if (wl_display_dispatch(display->display) == -1)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void wlf_DestroyDisplay(wlfContext* wlfc, wlfDisplay* display)
|
||||
{
|
||||
if (display == NULL)
|
||||
return;
|
||||
|
||||
if (wlfc->display == display)
|
||||
wlfc->display = NULL;
|
||||
|
||||
if (display->seat)
|
||||
wl_seat_destroy(display->seat);
|
||||
if (display->shm)
|
||||
wl_shm_destroy(display->shm);
|
||||
if (display->shell)
|
||||
wl_shell_destroy(display->shell);
|
||||
if (display->compositor)
|
||||
wl_compositor_destroy(display->compositor);
|
||||
if (display->registry)
|
||||
wl_registry_destroy(display->registry);
|
||||
wl_display_disconnect(display->display);
|
||||
|
||||
free(display);
|
||||
}
|
||||
@ -1,43 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Wayland Displays
|
||||
*
|
||||
* Copyright 2014 Manuel Bachmann <tarnyko@tarnyko.net>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __WLF_DISPLAY_H
|
||||
#define __WLF_DISPLAY_H
|
||||
|
||||
#include <wayland-client.h>
|
||||
|
||||
typedef struct wlf_display wlfDisplay;
|
||||
|
||||
#include "wlfreerdp.h"
|
||||
|
||||
struct wlf_display
|
||||
{
|
||||
struct wl_display* display;
|
||||
struct wl_registry* registry;
|
||||
struct wl_compositor* compositor;
|
||||
struct wl_shell* shell;
|
||||
struct wl_shm* shm;
|
||||
struct wl_seat* seat;
|
||||
};
|
||||
|
||||
wlfDisplay* wlf_CreateDisplay(void);
|
||||
BOOL wlf_RefreshDisplay(wlfDisplay* display);
|
||||
void wlf_DestroyDisplay(wlfContext* wlfc, wlfDisplay* display);
|
||||
|
||||
#endif /* __WLF_DISPLAY_H */
|
||||
@ -3,6 +3,7 @@
|
||||
* Wayland Input
|
||||
*
|
||||
* Copyright 2014 Manuel Bachmann <tarnyko@tarnyko.net>
|
||||
* Copyright 2015 David Fort <contact@hardening-consulting.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -24,50 +25,30 @@
|
||||
|
||||
#include "wlf_input.h"
|
||||
|
||||
static void wl_pointer_enter(void* data, struct wl_pointer* pointer, uint32_t serial, struct wl_surface* surface, wl_fixed_t sx_w, wl_fixed_t sy_w)
|
||||
{
|
||||
BOOL wlf_handle_pointer_enter(freerdp *instance, UwacPointerEnterLeaveEvent *ev) {
|
||||
rdpInput* input = instance->input;
|
||||
|
||||
return input->MouseEvent(input, PTR_FLAGS_MOVE, ev->x, ev->y);
|
||||
}
|
||||
|
||||
static void wl_pointer_leave(void* data, struct wl_pointer* pointer, uint32_t serial, struct wl_surface* surface)
|
||||
{
|
||||
|
||||
BOOL wlf_handle_pointer_motion(freerdp *instance, UwacPointerMotionEvent *ev) {
|
||||
rdpInput* input = instance->input;
|
||||
|
||||
return input->MouseEvent(input, PTR_FLAGS_MOVE, ev->x, ev->y);
|
||||
}
|
||||
|
||||
static void wl_pointer_motion(void* data, struct wl_pointer* pointer, uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
|
||||
{
|
||||
wlfInput* input_w = data;
|
||||
BOOL wlf_handle_pointer_buttons(freerdp *instance, UwacPointerButtonEvent *ev) {
|
||||
rdpInput* input;
|
||||
UINT16 x;
|
||||
UINT16 y;
|
||||
|
||||
input = input_w->input;
|
||||
|
||||
x = (UINT16) wl_fixed_to_int(sx_w);
|
||||
y = (UINT16) wl_fixed_to_int(sy_w);
|
||||
|
||||
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
|
||||
|
||||
input_w->last_x = x;
|
||||
input_w->last_y = y;
|
||||
}
|
||||
|
||||
static void wl_pointer_button(void* data, struct wl_pointer* pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
|
||||
{
|
||||
wlfInput* input_w = data;
|
||||
rdpInput* input;
|
||||
UINT16 x;
|
||||
UINT16 y;
|
||||
UINT16 flags;
|
||||
|
||||
input = input_w->input;
|
||||
input = instance->input;
|
||||
|
||||
if (state == WL_POINTER_BUTTON_STATE_PRESSED)
|
||||
if (ev->state == WL_POINTER_BUTTON_STATE_PRESSED)
|
||||
flags = PTR_FLAGS_DOWN;
|
||||
else
|
||||
flags = 0;
|
||||
|
||||
switch (button)
|
||||
switch (ev->button)
|
||||
{
|
||||
case BTN_LEFT:
|
||||
flags |= PTR_FLAGS_BUTTON1;
|
||||
@ -79,175 +60,50 @@ static void wl_pointer_button(void* data, struct wl_pointer* pointer, uint32_t s
|
||||
flags |= PTR_FLAGS_BUTTON3;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
x = input_w->last_x;
|
||||
y = input_w->last_y;
|
||||
|
||||
input->MouseEvent(input, flags, x, y);
|
||||
return input->MouseEvent(input, flags, ev->x, ev->y);
|
||||
}
|
||||
|
||||
static void wl_pointer_axis(void* data, struct wl_pointer* pointer, uint32_t time, uint32_t axis, wl_fixed_t value)
|
||||
{
|
||||
wlfInput* input_w = data;
|
||||
|
||||
BOOL wlf_handle_pointer_axis(freerdp *instance, UwacPointerAxisEvent *ev) {
|
||||
rdpInput* input;
|
||||
UINT16 flags;
|
||||
int direction;
|
||||
|
||||
input = input_w->input;
|
||||
input = instance->input;
|
||||
|
||||
flags = PTR_FLAGS_WHEEL;
|
||||
|
||||
if (axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
||||
if (ev->axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
||||
{
|
||||
direction = wl_fixed_to_int(value);
|
||||
direction = wl_fixed_to_int(ev->value);
|
||||
if (direction < 0)
|
||||
flags |= 0x0078;
|
||||
else
|
||||
flags |= PTR_FLAGS_WHEEL_NEGATIVE | 0x0088;
|
||||
}
|
||||
|
||||
input->MouseEvent(input, flags, 0, 0);
|
||||
return input->MouseEvent(input, flags, ev->x, ev->y);
|
||||
}
|
||||
|
||||
static const struct wl_pointer_listener wl_pointer_listener =
|
||||
{
|
||||
wl_pointer_enter,
|
||||
wl_pointer_leave,
|
||||
wl_pointer_motion,
|
||||
wl_pointer_button,
|
||||
wl_pointer_axis
|
||||
};
|
||||
|
||||
static void wl_keyboard_keymap(void* data, struct wl_keyboard* keyboard, uint32_t format, int fd, uint32_t size)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void wl_keyboard_enter(void* data, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface, struct wl_array* keys)
|
||||
{
|
||||
wlfInput* input_w = data;
|
||||
rdpInput* input;
|
||||
UINT16 x;
|
||||
UINT16 y;
|
||||
|
||||
input = input_w->input;
|
||||
|
||||
x = input_w->last_x;
|
||||
y = input_w->last_y;
|
||||
|
||||
input->FocusInEvent(input, 0);
|
||||
input->MouseEvent(input, PTR_FLAGS_MOVE, x, y);
|
||||
}
|
||||
|
||||
static void wl_keyboard_leave(void* data, struct wl_keyboard* keyboard, uint32_t serial, struct wl_surface* surface)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void wl_keyboard_key(void* data, struct wl_keyboard* keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
|
||||
{
|
||||
wlfInput* input_w = data;
|
||||
rdpInput* input;
|
||||
BOOL key_down;
|
||||
BOOL wlf_handle_key(freerdp *instance, UwacKeyEvent *ev) {
|
||||
rdpInput* input = instance->input;
|
||||
DWORD rdp_scancode;
|
||||
|
||||
input = input_w->input;
|
||||
|
||||
if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
|
||||
key_down = TRUE;
|
||||
else
|
||||
key_down = FALSE;
|
||||
|
||||
rdp_scancode = (DWORD) key;
|
||||
rdp_scancode = (DWORD) ev->raw_key;
|
||||
|
||||
if (rdp_scancode == RDP_SCANCODE_UNKNOWN)
|
||||
return;
|
||||
return TRUE;
|
||||
|
||||
freerdp_input_send_keyboard_event_ex(input, key_down, rdp_scancode);
|
||||
return freerdp_input_send_keyboard_event_ex(input, ev->pressed, rdp_scancode);
|
||||
}
|
||||
|
||||
static void wl_keyboard_modifiers(void* data, struct wl_keyboard* keyboard, uint32_t serial, uint32_t mods_depr, uint32_t mods_latch, uint32_t mods_lock, uint32_t group)
|
||||
{
|
||||
BOOL wlf_keyboard_enter(freerdp *instance, UwacKeyboardEnterLeaveEvent *ev) {
|
||||
rdpInput* input = instance->input;
|
||||
|
||||
return input->FocusInEvent(input, 0) &&
|
||||
input->MouseEvent(input, PTR_FLAGS_MOVE, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
static const struct wl_keyboard_listener wl_keyboard_listener =
|
||||
{
|
||||
wl_keyboard_keymap,
|
||||
wl_keyboard_enter,
|
||||
wl_keyboard_leave,
|
||||
wl_keyboard_key,
|
||||
wl_keyboard_modifiers
|
||||
};
|
||||
|
||||
static void wl_seat_handle_capabilities(void* data, struct wl_seat* seat, enum wl_seat_capability capabilities)
|
||||
{
|
||||
wlfInput* input = data;
|
||||
struct wl_pointer* pointer;
|
||||
struct wl_keyboard* keyboard;
|
||||
|
||||
if (capabilities & WL_SEAT_CAPABILITY_POINTER)
|
||||
{
|
||||
pointer = wl_seat_get_pointer(seat);
|
||||
|
||||
input->pointer = pointer;
|
||||
wl_pointer_add_listener(pointer, &wl_pointer_listener, input);
|
||||
}
|
||||
|
||||
if (capabilities & WL_SEAT_CAPABILITY_KEYBOARD)
|
||||
{
|
||||
keyboard = wl_seat_get_keyboard(seat);
|
||||
|
||||
input->keyboard = keyboard;
|
||||
wl_keyboard_add_listener(keyboard, &wl_keyboard_listener, input);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static const struct wl_seat_listener wl_seat_listener = {
|
||||
wl_seat_handle_capabilities
|
||||
};
|
||||
|
||||
|
||||
wlfInput* wlf_CreateInput(wlfContext* wlfc)
|
||||
{
|
||||
wlfInput* input;
|
||||
struct wl_seat* seat;
|
||||
|
||||
if (!wlfc->display)
|
||||
return NULL;
|
||||
if (!wlfc->display->seat)
|
||||
return NULL;
|
||||
seat = wlfc->display->seat;
|
||||
|
||||
input = (wlfInput*) calloc(1, sizeof(wlfInput));
|
||||
|
||||
if (input)
|
||||
{
|
||||
input->input = wlfc->context.input;
|
||||
input->last_x = 0;
|
||||
input->last_y = 0;
|
||||
|
||||
wl_seat_add_listener(seat, &wl_seat_listener, input);
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
void wlf_DestroyInput(wlfContext* wlfc, wlfInput* input)
|
||||
{
|
||||
if (input == NULL)
|
||||
return;
|
||||
|
||||
if (wlfc->input == input)
|
||||
wlfc->input = NULL;
|
||||
|
||||
if (input->pointer)
|
||||
wl_pointer_release(input->pointer);
|
||||
if (input->keyboard)
|
||||
wl_keyboard_release(input->keyboard);
|
||||
|
||||
free(input);
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
* Wayland Input
|
||||
*
|
||||
* Copyright 2014 Manuel Bachmann <tarnyko@tarnyko.net>
|
||||
* Copyright 2015 David Fort <contact@hardening-consulting.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -20,23 +21,15 @@
|
||||
#ifndef __WLF_INPUT_H
|
||||
#define __WLF_INPUT_H
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <uwac/uwac.h>
|
||||
|
||||
typedef struct wlf_input wlfInput;
|
||||
BOOL wlf_handle_pointer_enter(freerdp* instance, UwacPointerEnterLeaveEvent *ev);
|
||||
BOOL wlf_handle_pointer_motion(freerdp* instance, UwacPointerMotionEvent *ev);
|
||||
BOOL wlf_handle_pointer_buttons(freerdp* instance, UwacPointerButtonEvent *ev);
|
||||
BOOL wlf_handle_pointer_axis(freerdp* instance, UwacPointerAxisEvent *ev);
|
||||
|
||||
#include "wlfreerdp.h"
|
||||
|
||||
struct wlf_input
|
||||
{
|
||||
rdpInput* input;
|
||||
UINT16 last_x;
|
||||
UINT16 last_y;
|
||||
|
||||
struct wl_pointer* pointer;
|
||||
struct wl_keyboard* keyboard;
|
||||
};
|
||||
|
||||
wlfInput* wlf_CreateInput(wlfContext* wlfc);
|
||||
void wlf_DestroyInput(wlfContext* wlfc, wlfInput* input);
|
||||
BOOL wlf_handle_key(freerdp* instance, UwacKeyEvent *ev);
|
||||
BOOL wlf_keyboard_enter(freerdp *instance, UwacKeyboardEnterLeaveEvent *ev);
|
||||
|
||||
#endif /* __WLF_INPUT_H */
|
||||
|
||||
@ -1,220 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Wayland Windows
|
||||
*
|
||||
* Copyright 2014 Manuel Bachmann <tarnyko@tarnyko.net>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "wlf_window.h"
|
||||
|
||||
static void wl_shell_surface_handle_ping(void* data, struct wl_shell_surface* shell_surface, uint32_t serial)
|
||||
{
|
||||
wl_shell_surface_pong(shell_surface, serial);
|
||||
}
|
||||
|
||||
static void wl_shell_surface_handle_configure(void* data, struct wl_shell_surface* shell_surface, unsigned int edges, int32_t width, int32_t height)
|
||||
{
|
||||
wlfWindow* window = data;
|
||||
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
}
|
||||
|
||||
static const struct wl_shell_surface_listener wl_shell_surface_listener =
|
||||
{
|
||||
wl_shell_surface_handle_ping,
|
||||
wl_shell_surface_handle_configure,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void wl_buffer_release(void* data, struct wl_buffer* wl_buffer)
|
||||
{
|
||||
wlfBuffer* buffer = data;
|
||||
|
||||
buffer->busy = FALSE;
|
||||
}
|
||||
|
||||
static const struct wl_buffer_listener wl_buffer_listener =
|
||||
{
|
||||
wl_buffer_release
|
||||
};
|
||||
|
||||
static const struct wl_callback_listener wl_callback_listener;
|
||||
|
||||
static void wl_callback_done(void* data, struct wl_callback* callback, uint32_t time)
|
||||
{
|
||||
wlfWindow* window = data;
|
||||
wlfBuffer* buffer;
|
||||
struct wl_shm_pool* shm_pool;
|
||||
void* shm_data;
|
||||
void* free_data;
|
||||
int fd;
|
||||
int fdt;
|
||||
|
||||
if (!window->buffers[0].busy)
|
||||
buffer = &window->buffers[0];
|
||||
else if (!window->buffers[1].busy)
|
||||
buffer = &window->buffers[1];
|
||||
else
|
||||
return;
|
||||
|
||||
if (!buffer->buffer) {
|
||||
fd = shm_open("/wlfreerdp_shm", O_CREAT | O_RDWR, 0666);
|
||||
fdt = ftruncate(fd, window->width * window->height * 4);
|
||||
if (fdt != 0)
|
||||
{
|
||||
WLog_ERR(TAG, "window_redraw: could not allocate memory");
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
shm_data = mmap(NULL, window->width * window->height * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (shm_data == MAP_FAILED)
|
||||
{
|
||||
WLog_ERR(TAG, "window_redraw: failed to memory map buffer");
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
shm_pool = wl_shm_create_pool(window->display->shm, fd, window->width * window->height * 4);
|
||||
buffer->buffer = wl_shm_pool_create_buffer(shm_pool, 0, window->width, window->height, window->width* 4, WL_SHM_FORMAT_XRGB8888);
|
||||
wl_buffer_add_listener(buffer->buffer, &wl_buffer_listener, buffer);
|
||||
wl_shm_pool_destroy(shm_pool);
|
||||
shm_unlink("/wlfreerdp_shm");
|
||||
close(fd);
|
||||
|
||||
free_data = buffer->shm_data;
|
||||
buffer->shm_data = shm_data;
|
||||
munmap(free_data, window->width * window->height * 4);
|
||||
}
|
||||
|
||||
/* this is the real surface data */
|
||||
memcpy(buffer->shm_data, (void*) window->data, window->width * window->height * 4);
|
||||
wl_surface_attach(window->surface, buffer->buffer, 0, 0);
|
||||
wl_surface_damage(window->surface, 0, 0, window->width, window->height);
|
||||
|
||||
if (callback) wl_callback_destroy(callback);
|
||||
window->callback = wl_surface_frame(window->surface);
|
||||
wl_callback_add_listener(window->callback, &wl_callback_listener, window);
|
||||
wl_surface_commit(window->surface);
|
||||
|
||||
buffer->busy = TRUE;
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener wl_callback_listener =
|
||||
{
|
||||
wl_callback_done
|
||||
};
|
||||
|
||||
|
||||
wlfWindow* wlf_CreateDesktopWindow(wlfContext* wlfc, char* name, int width, int height, BOOL decorations)
|
||||
{
|
||||
wlfWindow* window;
|
||||
|
||||
window = (wlfWindow*) calloc(1, sizeof(wlfWindow));
|
||||
|
||||
if (window)
|
||||
{
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
window->fullscreen = FALSE;
|
||||
window->buffers[0].busy = FALSE;
|
||||
window->buffers[1].busy = FALSE;
|
||||
window->callback = NULL;
|
||||
window->display = wlfc->display;
|
||||
|
||||
window->surface = wl_compositor_create_surface(window->display->compositor);
|
||||
window->shell_surface = wl_shell_get_shell_surface(window->display->shell, window->surface);
|
||||
wl_shell_surface_add_listener(window->shell_surface, &wl_shell_surface_listener, window);
|
||||
wl_shell_surface_set_toplevel(window->shell_surface);
|
||||
|
||||
wlf_ResizeDesktopWindow(wlfc, window, width, height);
|
||||
|
||||
wl_surface_damage(window->surface, 0, 0, window->width, window->height);
|
||||
|
||||
wlf_SetWindowText(wlfc, window, name);
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void wlf_ResizeDesktopWindow(wlfContext* wlfc, wlfWindow* window, int width, int height)
|
||||
{
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
}
|
||||
|
||||
void wlf_SetWindowText(wlfContext* wlfc, wlfWindow* window, char* name)
|
||||
{
|
||||
wl_shell_surface_set_title(window->shell_surface, name);
|
||||
}
|
||||
|
||||
void wlf_SetWindowFullscreen(wlfContext* wlfc, wlfWindow* window, BOOL fullscreen)
|
||||
{
|
||||
if (fullscreen)
|
||||
{
|
||||
wl_shell_surface_set_fullscreen(window->shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);
|
||||
window->fullscreen = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
void wlf_ShowWindow(wlfContext* wlfc, wlfWindow* window, BYTE state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case WINDOW_HIDE:
|
||||
case WINDOW_SHOW_MINIMIZED:
|
||||
/* xdg_surface_set_minimized(window->xdg_surface); */
|
||||
break;
|
||||
case WINDOW_SHOW_MAXIMIZED:
|
||||
wl_shell_surface_set_maximized(window->shell_surface, NULL);
|
||||
break;
|
||||
case WINDOW_SHOW:
|
||||
wl_shell_surface_set_toplevel(window->shell_surface);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void wlf_UpdateWindowArea(wlfContext* wlfc, wlfWindow* window, int x, int y, int width, int height)
|
||||
{
|
||||
wl_callback_done(window, NULL, 0);
|
||||
}
|
||||
|
||||
void wlf_DestroyWindow(wlfContext* wlfc, wlfWindow* window)
|
||||
{
|
||||
if (window == NULL)
|
||||
return;
|
||||
|
||||
if (wlfc->window == window)
|
||||
wlfc->window = NULL;
|
||||
|
||||
if (window->buffers[0].buffer)
|
||||
wl_buffer_destroy(window->buffers[0].buffer);
|
||||
if (window->buffers[1].buffer)
|
||||
wl_buffer_destroy(window->buffers[1].buffer);
|
||||
if (window->shell_surface)
|
||||
wl_shell_surface_destroy(window->shell_surface);
|
||||
if (window->surface)
|
||||
wl_surface_destroy(window->surface);
|
||||
|
||||
free(window->data);
|
||||
free(window);
|
||||
}
|
||||
@ -1,58 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Wayland Windows
|
||||
*
|
||||
* Copyright 2014 Manuel Bachmann <tarnyko@tarnyko.net>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __WLF_WINDOW_H
|
||||
#define __WLF_WINDOW_H
|
||||
|
||||
#include <wayland-client.h>
|
||||
|
||||
typedef struct wlf_window wlfWindow;
|
||||
|
||||
#include "wlfreerdp.h"
|
||||
|
||||
struct wlf_buffer
|
||||
{
|
||||
struct wl_buffer* buffer;
|
||||
void* shm_data;
|
||||
BOOL busy;
|
||||
};
|
||||
typedef struct wlf_buffer wlfBuffer;
|
||||
|
||||
struct wlf_window
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
struct wl_surface* surface;
|
||||
struct wl_shell_surface* shell_surface;
|
||||
struct wl_callback* callback;
|
||||
wlfBuffer buffers[2];
|
||||
wlfDisplay* display;
|
||||
void* data;
|
||||
BOOL fullscreen;
|
||||
};
|
||||
|
||||
wlfWindow* wlf_CreateDesktopWindow(wlfContext* wlfc, char* name, int width, int height, BOOL decorations);
|
||||
void wlf_ResizeDesktopWindow(wlfContext* wlfc, wlfWindow* window, int width, int height);
|
||||
void wlf_SetWindowText(wlfContext* wlfc, wlfWindow* window, char* name);
|
||||
void wlf_SetWindowFullscreen(wlfContext* wlfc, wlfWindow* window, BOOL fullscree);
|
||||
void wlf_ShowWindow(wlfContext* wlfc, wlfWindow* window, BYTE state);
|
||||
void wlf_UpdateWindowArea(wlfContext* wlfc, wlfWindow* window, int x, int y, int width, int height);
|
||||
void wlf_DestroyWindow(wlfContext* wlfc, wlfWindow* window);
|
||||
|
||||
#endif /* __WLF_WINDOW_H */
|
||||
@ -23,8 +23,13 @@
|
||||
#include <freerdp/client/cmdline.h>
|
||||
#include <freerdp/channels/channels.h>
|
||||
#include <freerdp/gdi/gdi.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include "wlfreerdp.h"
|
||||
#include "wlf_input.h"
|
||||
|
||||
UwacDisplay *g_display;
|
||||
HANDLE g_displayHandle;
|
||||
|
||||
static BOOL wl_context_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
@ -44,6 +49,18 @@ static void wl_context_free(freerdp* instance, rdpContext* context)
|
||||
}
|
||||
}
|
||||
|
||||
BOOL wl_update_content(wlfContext *context_w)
|
||||
{
|
||||
if (!context_w->waitingFrameDone && context_w->haveDamage)
|
||||
{
|
||||
UwacWindowSubmitBuffer(context_w->window, true);
|
||||
context_w->waitingFrameDone = TRUE;
|
||||
context_w->haveDamage = FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL wl_begin_paint(rdpContext* context)
|
||||
{
|
||||
rdpGdi* gdi;
|
||||
@ -53,12 +70,12 @@ static BOOL wl_begin_paint(rdpContext* context)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static BOOL wl_end_paint(rdpContext* context)
|
||||
{
|
||||
rdpGdi* gdi;
|
||||
wlfDisplay* display;
|
||||
wlfWindow* window;
|
||||
wlfContext* context_w;
|
||||
char *data;
|
||||
wlfContext *context_w;
|
||||
INT32 x, y;
|
||||
UINT32 w, h;
|
||||
int i;
|
||||
@ -73,21 +90,28 @@ static BOOL wl_end_paint(rdpContext* context)
|
||||
h = gdi->primary->hdc->hwnd->invalid->h;
|
||||
|
||||
context_w = (wlfContext*) context;
|
||||
display = context_w->display;
|
||||
window = context_w->window;
|
||||
|
||||
data = UwacWindowGetDrawingBuffer(context_w->window);
|
||||
if (!data)
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < h; i++)
|
||||
memcpy(window->data + ((i+y)*(gdi->width*4)) + x*4,
|
||||
{
|
||||
memcpy(data + ((i+y)*(gdi->width*4)) + x*4,
|
||||
gdi->primary_buffer + ((i+y)*(gdi->width*4)) + x*4,
|
||||
w*4);
|
||||
}
|
||||
|
||||
return wlf_RefreshDisplay(display);
|
||||
if (UwacWindowAddDamage(context_w->window, x, y, w, h) != UWAC_SUCCESS)
|
||||
return FALSE;
|
||||
|
||||
context_w->haveDamage = TRUE;
|
||||
return wl_update_content(context_w);
|
||||
}
|
||||
|
||||
|
||||
static BOOL wl_pre_connect(freerdp* instance)
|
||||
{
|
||||
wlfDisplay* display;
|
||||
wlfInput* input;
|
||||
wlfContext* context;
|
||||
|
||||
if (freerdp_channels_pre_connect(instance->context->channels, instance))
|
||||
@ -97,17 +121,7 @@ static BOOL wl_pre_connect(freerdp* instance)
|
||||
if (!context)
|
||||
return FALSE;
|
||||
|
||||
display = wlf_CreateDisplay();
|
||||
if (!display)
|
||||
return FALSE;
|
||||
|
||||
context->display = display;
|
||||
|
||||
input = wlf_CreateInput(context);
|
||||
if (!input)
|
||||
return FALSE;
|
||||
|
||||
context->input = input;
|
||||
context->display = g_display;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -115,7 +129,7 @@ static BOOL wl_pre_connect(freerdp* instance)
|
||||
static BOOL wl_post_connect(freerdp* instance)
|
||||
{
|
||||
rdpGdi* gdi;
|
||||
wlfWindow* window;
|
||||
UwacWindow* window;
|
||||
wlfContext* context;
|
||||
|
||||
if (!gdi_init(instance, CLRCONV_ALPHA | CLRBUF_32BPP, NULL))
|
||||
@ -126,28 +140,23 @@ static BOOL wl_post_connect(freerdp* instance)
|
||||
return FALSE;
|
||||
|
||||
context = (wlfContext*) instance->context;
|
||||
window = wlf_CreateDesktopWindow(context, "FreeRDP", gdi->width, gdi->height, FALSE);
|
||||
context->window = window = UwacCreateWindowShm(context->display, gdi->width, gdi->height, WL_SHM_FORMAT_XRGB8888);
|
||||
if (!window)
|
||||
return FALSE;
|
||||
|
||||
/* fill buffer with first image here */
|
||||
window->data = malloc (gdi->width * gdi->height *4);
|
||||
if (!window->data)
|
||||
return FALSE;
|
||||
UwacWindowSetTitle(window, "FreeRDP");
|
||||
|
||||
memcpy(window->data, (void*) gdi->primary_buffer, gdi->width * gdi->height * 4);
|
||||
instance->update->BeginPaint = wl_begin_paint;
|
||||
instance->update->EndPaint = wl_end_paint;
|
||||
|
||||
/* put Wayland data in the context here */
|
||||
context->window = window;
|
||||
|
||||
if (freerdp_channels_post_connect(instance->context->channels, instance) < 0)
|
||||
return FALSE;
|
||||
|
||||
wlf_UpdateWindowArea(context, window, 0, 0, gdi->width, gdi->height);
|
||||
|
||||
return TRUE;
|
||||
memcpy(UwacWindowGetDrawingBuffer(context->window), gdi->primary_buffer, gdi->width * gdi->height * 4);
|
||||
UwacWindowAddDamage(context->window, 0, 0, gdi->width, gdi->height);
|
||||
context->haveDamage = TRUE;
|
||||
return wl_update_content(context);
|
||||
}
|
||||
|
||||
static void wl_post_disconnect(freerdp* instance)
|
||||
@ -161,55 +170,67 @@ static void wl_post_disconnect(freerdp* instance)
|
||||
|
||||
context = (wlfContext*) instance->context;
|
||||
|
||||
if (context->display)
|
||||
wlf_DestroyDisplay(context, context->display);
|
||||
|
||||
if (context->input)
|
||||
wlf_DestroyInput(context, context->input);
|
||||
|
||||
gdi_free(instance);
|
||||
if (context->window)
|
||||
wlf_DestroyWindow(context, context->window);
|
||||
UwacDestroyWindow(&context->window);
|
||||
|
||||
if (context->display)
|
||||
UwacCloseDisplay(&context->display);
|
||||
|
||||
}
|
||||
|
||||
static BOOL wl_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
|
||||
{
|
||||
char answer;
|
||||
static BOOL handle_uwac_events(freerdp* instance, UwacDisplay *display) {
|
||||
UwacEvent event;
|
||||
wlfContext *context;
|
||||
|
||||
printf("Certificate details:\n");
|
||||
printf("\tSubject: %s\n", subject);
|
||||
printf("\tIssuer: %s\n", issuer);
|
||||
printf("\tThumbprint: %s\n", fingerprint);
|
||||
printf("The above X.509 certificate could not be verified, possibly because you do not have "
|
||||
"the CA certificate in your certificate store, or the certificate has expired. "
|
||||
"Please look at the documentation on how to create local certificate store for a private CA.\n");
|
||||
if (UwacDisplayDispatch(display, 1) < 0)
|
||||
return FALSE;
|
||||
|
||||
while (1)
|
||||
while (UwacHasEvent(display))
|
||||
{
|
||||
printf("Do you trust the above certificate? (Y/N) ");
|
||||
answer = fgetc(stdin);
|
||||
|
||||
if (feof(stdin))
|
||||
{
|
||||
printf("\nError: Could not read answer from stdin.");
|
||||
if (instance->settings->CredentialsFromStdin)
|
||||
printf(" - Run without parameter \"--from-stdin\" to set trust.");
|
||||
printf("\n");
|
||||
if (UwacNextEvent(display, &event) != UWAC_SUCCESS)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (answer == 'y' || answer == 'Y')
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (answer == 'n' || answer == 'N')
|
||||
{
|
||||
/*printf("UWAC event type %d\n", event.type);*/
|
||||
switch (event.type) {
|
||||
case UWAC_EVENT_FRAME_DONE:
|
||||
if (!instance)
|
||||
continue;
|
||||
|
||||
context = (wlfContext *)instance->context;
|
||||
context->waitingFrameDone = FALSE;
|
||||
if (context->haveDamage && !wl_end_paint(instance->context))
|
||||
return FALSE;
|
||||
break;
|
||||
case UWAC_EVENT_POINTER_ENTER:
|
||||
if (!wlf_handle_pointer_enter(instance, &event.mouse_enter_leave))
|
||||
return FALSE;
|
||||
break;
|
||||
case UWAC_EVENT_POINTER_MOTION:
|
||||
if (!wlf_handle_pointer_motion(instance, &event.mouse_motion))
|
||||
return FALSE;
|
||||
break;
|
||||
case UWAC_EVENT_POINTER_BUTTONS:
|
||||
if (!wlf_handle_pointer_buttons(instance, &event.mouse_button))
|
||||
return FALSE;
|
||||
break;
|
||||
case UWAC_EVENT_POINTER_AXIS:
|
||||
if (!wlf_handle_pointer_axis(instance, &event.mouse_axis))
|
||||
return FALSE;
|
||||
break;
|
||||
case UWAC_EVENT_KEY:
|
||||
if (!wlf_handle_key(instance, &event.key))
|
||||
return FALSE;
|
||||
break;
|
||||
case UWAC_EVENT_KEYBOARD_ENTER:
|
||||
if (!wlf_keyboard_enter(instance, &event.keyboard_enter_leave))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int wlfreerdp_run(freerdp* instance)
|
||||
@ -224,27 +245,39 @@ static int wlfreerdp_run(freerdp* instance)
|
||||
return -1;
|
||||
}
|
||||
|
||||
handle_uwac_events(instance, g_display);
|
||||
|
||||
while (!freerdp_shall_disconnect(instance))
|
||||
{
|
||||
count = freerdp_get_event_handles(instance->context, handles, 64);
|
||||
handles[0] = g_displayHandle;
|
||||
|
||||
count = freerdp_get_event_handles(instance->context, &handles[1], 63);
|
||||
if (!count)
|
||||
{
|
||||
printf("Failed to get FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
|
||||
status = WaitForMultipleObjects(count, handles, FALSE, INFINITE);
|
||||
status = WaitForMultipleObjects(count+1, handles, FALSE, INFINITE);
|
||||
if (WAIT_FAILED == status)
|
||||
{
|
||||
printf("%s: WaitForMultipleObjects failed\n", __FUNCTION__);
|
||||
break;
|
||||
}
|
||||
|
||||
if (freerdp_check_event_handles(instance->context) != TRUE)
|
||||
{
|
||||
printf("Failed to check FreeRDP file descriptor\n");
|
||||
if (!handle_uwac_events(instance, g_display)) {
|
||||
printf("error handling UWAC events\n");
|
||||
break;
|
||||
}
|
||||
|
||||
//if (WaitForMultipleObjects(count, &handles[1], FALSE, INFINITE)) {
|
||||
if (freerdp_check_event_handles(instance->context) != TRUE)
|
||||
{
|
||||
printf("Failed to check FreeRDP file descriptor\n");
|
||||
break;
|
||||
}
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
freerdp_channels_disconnect(instance->context->channels, instance);
|
||||
@ -255,14 +288,28 @@ static int wlfreerdp_run(freerdp* instance)
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int status;
|
||||
UwacReturnCode status;
|
||||
freerdp* instance;
|
||||
|
||||
g_display = UwacOpenDisplay(NULL, &status);
|
||||
if (!g_display)
|
||||
exit(1);
|
||||
|
||||
g_displayHandle = CreateFileDescriptorEvent(NULL, FALSE, FALSE, UwacDisplayGetFd(g_display), WINPR_FD_READ);
|
||||
if (!g_displayHandle)
|
||||
exit(1);
|
||||
|
||||
//if (!handle_uwac_events(NULL, g_display))
|
||||
// exit(1);
|
||||
|
||||
instance = freerdp_new();
|
||||
instance->PreConnect = wl_pre_connect;
|
||||
instance->PostConnect = wl_post_connect;
|
||||
instance->PostDisconnect = wl_post_disconnect;
|
||||
instance->VerifyCertificate = wl_verify_certificate;
|
||||
instance->Authenticate = client_cli_authenticate;
|
||||
instance->GatewayAuthenticate = client_cli_gw_authenticate;
|
||||
instance->VerifyCertificate = client_cli_verify_certificate;
|
||||
instance->VerifyChangedCertificate = client_cli_verify_changed_certificate;
|
||||
|
||||
instance->ContextSize = sizeof(wlfContext);
|
||||
instance->ContextNew = wl_context_new;
|
||||
|
||||
@ -23,22 +23,22 @@
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/log.h>
|
||||
#include <winpr/wtypes.h>
|
||||
#include <uwac/uwac.h>
|
||||
|
||||
#define TAG CLIENT_TAG("wayland")
|
||||
|
||||
typedef struct wlf_context wlfContext;
|
||||
|
||||
#include "wlf_display.h"
|
||||
#include "wlf_window.h"
|
||||
#include "wlf_input.h"
|
||||
|
||||
struct wlf_context
|
||||
{
|
||||
rdpContext context;
|
||||
|
||||
wlfDisplay* display;
|
||||
wlfWindow* window;
|
||||
wlfInput* input;
|
||||
UwacDisplay *display;
|
||||
UwacWindow *window;
|
||||
|
||||
BOOL waitingFrameDone;
|
||||
BOOL haveDamage;
|
||||
};
|
||||
|
||||
#endif /* __WLFREERDP_H */
|
||||
|
||||
@ -102,8 +102,6 @@
|
||||
#include <freerdp/log.h>
|
||||
#define TAG CLIENT_TAG("x11")
|
||||
|
||||
static const size_t password_size = 512;
|
||||
|
||||
static int (*_def_error_handler)(Display*, XErrorEvent*);
|
||||
static int _xf_error_handler(Display* d, XErrorEvent* ev);
|
||||
static void xf_check_extensions(xfContext* context);
|
||||
@ -1357,158 +1355,6 @@ static void xf_post_disconnect(freerdp* instance)
|
||||
xf_keyboard_free(xfc);
|
||||
}
|
||||
|
||||
/** Callback set in the rdp_freerdp structure, and used to get the user's password,
|
||||
* if required to establish the connection.
|
||||
* This function is actually called in credssp_ntlmssp_client_init()
|
||||
* @see rdp_server_accept_nego() and rdp_check_fds()
|
||||
* @param instance - pointer to the rdp_freerdp structure that contains the connection settings
|
||||
* @param username - unused
|
||||
* @param password - on return: pointer to a character string that will be filled by the password entered by the user.
|
||||
* Note that this character string will be allocated inside the function, and needs to be deallocated by the caller
|
||||
* using free(), even in case this function fails.
|
||||
* @param domain - unused
|
||||
* @return TRUE if a password was successfully entered. See freerdp_passphrase_read() for more details.
|
||||
*/
|
||||
static BOOL xf_authenticate_raw(freerdp* instance, BOOL gateway, char** username,
|
||||
char** password, char** domain)
|
||||
{
|
||||
const char* auth[] =
|
||||
{
|
||||
"Username: ",
|
||||
"Domain: ",
|
||||
"Password: "
|
||||
};
|
||||
const char* gw[] =
|
||||
{
|
||||
"GatewayUsername: ",
|
||||
"GatewayDomain: ",
|
||||
"GatewayPassword: "
|
||||
};
|
||||
const char** prompt = (gateway) ? gw : auth;
|
||||
|
||||
if (!username || !password || !domain)
|
||||
return FALSE;
|
||||
|
||||
if (!*username)
|
||||
{
|
||||
size_t username_size = 0;
|
||||
printf("%s", prompt[0]);
|
||||
if (getline(username, &username_size, stdin) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "getline returned %s [%d]", strerror(errno), errno);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (*username)
|
||||
{
|
||||
*username = StrSep(username, "\r");
|
||||
*username = StrSep(username, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!*domain)
|
||||
{
|
||||
size_t domain_size = 0;
|
||||
printf("%s", prompt[1]);
|
||||
if (getline(domain, &domain_size, stdin) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "getline returned %s [%d]", strerror(errno), errno);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (*domain)
|
||||
{
|
||||
*domain = StrSep(domain, "\r");
|
||||
*domain = StrSep(domain, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!*password)
|
||||
{
|
||||
*password = calloc(password_size, sizeof(char));
|
||||
if (!*password)
|
||||
goto fail;
|
||||
|
||||
if (freerdp_passphrase_read(prompt[2], *password, password_size,
|
||||
instance->settings->CredentialsFromStdin) == NULL)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
free(*username);
|
||||
free(*domain);
|
||||
free(*password);
|
||||
|
||||
*username = NULL;
|
||||
*domain = NULL;
|
||||
*password = NULL;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL xf_authenticate(freerdp* instance, char** username, char** password, char** domain)
|
||||
{
|
||||
return xf_authenticate_raw(instance, FALSE, username, password, domain);
|
||||
}
|
||||
|
||||
static BOOL xf_gw_authenticate(freerdp* instance, char** username, char** password, char** domain)
|
||||
{
|
||||
return xf_authenticate_raw(instance, TRUE, username, password, domain);
|
||||
}
|
||||
|
||||
/** Callback set in the rdp_freerdp structure, and used to make a certificate validation
|
||||
* when the connection requires it.
|
||||
* This function will actually be called by tls_verify_certificate().
|
||||
* @see rdp_client_connect() and tls_connect()
|
||||
* @param instance - pointer to the rdp_freerdp structure that contains the connection settings
|
||||
* @param subject
|
||||
* @param issuer
|
||||
* @param fingerprint
|
||||
* @return TRUE if the certificate is trusted. FALSE otherwise.
|
||||
*/
|
||||
BOOL xf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint)
|
||||
{
|
||||
char answer;
|
||||
|
||||
WLog_INFO(TAG, "Certificate details:");
|
||||
WLog_INFO(TAG, "\tSubject: %s", subject);
|
||||
WLog_INFO(TAG, "\tIssuer: %s", issuer);
|
||||
WLog_INFO(TAG, "\tThumbprint: %s", fingerprint);
|
||||
WLog_INFO(TAG, "The above X.509 certificate could not be verified, possibly because you do not have "
|
||||
"the CA certificate in your certificate store, or the certificate has expired. "
|
||||
"Please look at the documentation on how to create local certificate store for a private CA.");
|
||||
|
||||
while (1)
|
||||
{
|
||||
WLog_INFO(TAG, "Do you trust the above certificate? (Y/N) ");
|
||||
answer = fgetc(stdin);
|
||||
|
||||
if (feof(stdin))
|
||||
{
|
||||
WLog_INFO(TAG, "Error: Could not read answer from stdin.");
|
||||
if (instance->settings->CredentialsFromStdin)
|
||||
WLog_INFO(TAG, " - Run without parameter \"--from-stdin\" to set trust.");
|
||||
WLog_INFO(TAG, "");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (answer == 'y' || answer == 'Y')
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
else if (answer == 'n' || answer == 'N')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
WLog_INFO(TAG, "");
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int xf_logon_error_info(freerdp* instance, UINT32 data, UINT32 type)
|
||||
{
|
||||
xfContext* xfc = (xfContext*) instance->context;
|
||||
@ -1956,9 +1802,10 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context)
|
||||
instance->PreConnect = xf_pre_connect;
|
||||
instance->PostConnect = xf_post_connect;
|
||||
instance->PostDisconnect = xf_post_disconnect;
|
||||
instance->Authenticate = xf_authenticate;
|
||||
instance->GatewayAuthenticate = xf_gw_authenticate;
|
||||
instance->VerifyCertificate = xf_verify_certificate;
|
||||
instance->Authenticate = client_cli_authenticate;
|
||||
instance->GatewayAuthenticate = client_cli_gw_authenticate;
|
||||
instance->VerifyCertificate = client_cli_verify_certificate;
|
||||
instance->VerifyChangedCertificate = client_cli_verify_changed_certificate;
|
||||
instance->LogonErrorInfo = xf_logon_error_info;
|
||||
|
||||
settings = instance->settings;
|
||||
|
||||
@ -44,6 +44,8 @@
|
||||
|
||||
#define TAG CLIENT_TAG("x11")
|
||||
|
||||
#define MAX_CLIPBOARD_FORMATS 255
|
||||
|
||||
struct xf_cliprdr_format
|
||||
{
|
||||
Atom atom;
|
||||
@ -64,6 +66,9 @@ struct xf_clipboard
|
||||
Atom clipboard_atom;
|
||||
Atom property_atom;
|
||||
|
||||
Atom raw_transfer_atom;
|
||||
Atom raw_format_list_atom;
|
||||
|
||||
int numClientFormats;
|
||||
xfCliprdrFormat clientFormats[20];
|
||||
|
||||
@ -76,8 +81,9 @@ struct xf_clipboard
|
||||
int requestedFormatId;
|
||||
|
||||
BYTE* data;
|
||||
UINT32 data_format;
|
||||
UINT32 data_alt_format;
|
||||
BOOL data_raw_format;
|
||||
UINT32 data_format_id;
|
||||
const char* data_format_name;
|
||||
int data_length;
|
||||
XEvent* respond;
|
||||
|
||||
@ -122,9 +128,70 @@ static BOOL xf_cliprdr_is_self_owned(xfClipboard* clipboard)
|
||||
return XGetSelectionOwner(xfc->display, clipboard->clipboard_atom) == xfc->drawable;
|
||||
}
|
||||
|
||||
static xfCliprdrFormat* xf_cliprdr_get_format_by_id(xfClipboard* clipboard, UINT32 formatId)
|
||||
static void xf_cliprdr_set_raw_transfer_enabled(xfClipboard* clipboard, BOOL enabled)
|
||||
{
|
||||
UINT32 index;
|
||||
UINT32 data = enabled;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
XChangeProperty(xfc->display, xfc->drawable, clipboard->raw_transfer_atom,
|
||||
XA_INTEGER, 32, PropModeReplace, (BYTE*) &data, 1);
|
||||
}
|
||||
|
||||
static BOOL xf_cliprdr_is_raw_transfer_available(xfClipboard* clipboard)
|
||||
{
|
||||
Atom type;
|
||||
int format;
|
||||
int result = 0;
|
||||
unsigned long length;
|
||||
unsigned long bytes_left;
|
||||
UINT32* data = NULL;
|
||||
UINT32 is_enabled = 0;
|
||||
Window owner = None;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
owner = XGetSelectionOwner(xfc->display, clipboard->clipboard_atom);
|
||||
|
||||
if (owner != None)
|
||||
{
|
||||
result = XGetWindowProperty(xfc->display, owner,
|
||||
clipboard->raw_transfer_atom, 0, 4, 0, XA_INTEGER,
|
||||
&type, &format, &length, &bytes_left, (BYTE**) &data);
|
||||
}
|
||||
|
||||
if (data)
|
||||
{
|
||||
is_enabled = *data;
|
||||
XFree(data);
|
||||
}
|
||||
|
||||
if ((owner == None) || (owner == xfc->drawable))
|
||||
return FALSE;
|
||||
|
||||
if (result != Success)
|
||||
return FALSE;
|
||||
|
||||
return is_enabled ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static BOOL xf_cliprdr_formats_equal(const CLIPRDR_FORMAT* server, const xfCliprdrFormat* client)
|
||||
{
|
||||
if (server->formatName && client->formatName)
|
||||
{
|
||||
/* The server may be using short format names while we store them in full form. */
|
||||
return (0 == strncmp(server->formatName, client->formatName, strlen(server->formatName)));
|
||||
}
|
||||
|
||||
if (!server->formatName && !client->formatName)
|
||||
{
|
||||
return (server->formatId == client->formatId);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static xfCliprdrFormat* xf_cliprdr_get_client_format_by_id(xfClipboard* clipboard, UINT32 formatId)
|
||||
{
|
||||
int index;
|
||||
xfCliprdrFormat* format;
|
||||
|
||||
for (index = 0; index < clipboard->numClientFormats; index++)
|
||||
@ -138,25 +205,41 @@ static xfCliprdrFormat* xf_cliprdr_get_format_by_id(xfClipboard* clipboard, UINT
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static xfCliprdrFormat* xf_cliprdr_get_format_by_atom(xfClipboard* clipboard, Atom atom)
|
||||
static xfCliprdrFormat* xf_cliprdr_get_client_format_by_atom(xfClipboard* clipboard, Atom atom)
|
||||
{
|
||||
int i, j;
|
||||
int i;
|
||||
xfCliprdrFormat* format;
|
||||
|
||||
for (i = 0; i < clipboard->numClientFormats; i++)
|
||||
{
|
||||
format = &(clipboard->clientFormats[i]);
|
||||
|
||||
if (format->atom != atom)
|
||||
continue;
|
||||
|
||||
if (format->formatId == 0)
|
||||
if (format->atom == atom)
|
||||
return format;
|
||||
}
|
||||
|
||||
for (j = 0; j < clipboard->numServerFormats; j++)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CLIPRDR_FORMAT* xf_cliprdr_get_server_format_by_atom(xfClipboard* clipboard, Atom atom)
|
||||
{
|
||||
int i, j;
|
||||
xfCliprdrFormat* client_format;
|
||||
CLIPRDR_FORMAT* server_format;
|
||||
|
||||
for (i = 0; i < clipboard->numClientFormats; i++)
|
||||
{
|
||||
client_format = &(clipboard->clientFormats[i]);
|
||||
|
||||
if (client_format->atom == atom)
|
||||
{
|
||||
if (clipboard->serverFormats[j].formatId == format->formatId)
|
||||
return format;
|
||||
for (j = 0; j < clipboard->numServerFormats; j++)
|
||||
{
|
||||
server_format = &(clipboard->serverFormats[j]);
|
||||
|
||||
if (xf_cliprdr_formats_equal(server_format, client_format))
|
||||
return server_format;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,14 +273,170 @@ static UINT xf_cliprdr_send_data_response(xfClipboard* clipboard, BYTE* data, in
|
||||
|
||||
ZeroMemory(&response, sizeof(CLIPRDR_FORMAT_DATA_RESPONSE));
|
||||
|
||||
response.msgFlags = CB_RESPONSE_OK;
|
||||
response.msgFlags = (data) ? CB_RESPONSE_OK : CB_RESPONSE_FAIL;
|
||||
response.dataLen = size;
|
||||
response.requestedFormatData = data;
|
||||
|
||||
return clipboard->context->ClientFormatDataResponse(clipboard->context, &response);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
||||
static wStream* xf_cliprdr_serialize_server_format_list(xfClipboard* clipboard)
|
||||
{
|
||||
UINT32 i;
|
||||
UINT32 formatCount;
|
||||
wStream* s = NULL;
|
||||
|
||||
/* Typical MS Word format list is about 80 bytes long. */
|
||||
if (!(s = Stream_New(NULL, 128)))
|
||||
{
|
||||
WLog_ERR(TAG, "failed to allocate serialized format list");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* If present, the last format is always synthetic CF_RAW. Do not include it. */
|
||||
formatCount = (clipboard->numServerFormats > 0) ? clipboard->numServerFormats - 1 : 0;
|
||||
|
||||
Stream_Write_UINT32(s, formatCount);
|
||||
|
||||
for (i = 0; i < formatCount; i++)
|
||||
{
|
||||
CLIPRDR_FORMAT* format = &clipboard->serverFormats[i];
|
||||
size_t name_length = format->formatName ? strlen(format->formatName) : 0;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, sizeof(UINT32) + name_length + 1))
|
||||
{
|
||||
WLog_ERR(TAG, "failed to expand serialized format list");
|
||||
goto error;
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(s, format->formatId);
|
||||
Stream_Write(s, format->formatName, name_length);
|
||||
Stream_Write_UINT8(s, '\0');
|
||||
}
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
return s;
|
||||
|
||||
error:
|
||||
Stream_Free(s, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static CLIPRDR_FORMAT* xf_cliprdr_parse_server_format_list(BYTE* data, size_t length, UINT32* numFormats)
|
||||
{
|
||||
UINT32 i;
|
||||
wStream* s = NULL;
|
||||
CLIPRDR_FORMAT* formats = NULL;
|
||||
|
||||
if (!(s = Stream_New(data, length)))
|
||||
{
|
||||
WLog_ERR(TAG, "failed to allocate stream for parsing serialized format list");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (Stream_GetRemainingLength(s) < sizeof(UINT32))
|
||||
{
|
||||
WLog_ERR(TAG, "too short serialized format list");
|
||||
goto error;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, *numFormats);
|
||||
|
||||
if (*numFormats > MAX_CLIPBOARD_FORMATS)
|
||||
{
|
||||
WLog_ERR(TAG, "unexpectedly large number of formats: %u", *numFormats);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!(formats = (CLIPRDR_FORMAT*) calloc(*numFormats, sizeof(CLIPRDR_FORMAT))))
|
||||
{
|
||||
WLog_ERR(TAG, "failed to allocate format list");
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (i = 0; i < *numFormats; i++)
|
||||
{
|
||||
const char* formatName = NULL;
|
||||
size_t formatNameLength = 0;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < sizeof(UINT32))
|
||||
{
|
||||
WLog_ERR(TAG, "unexpected end of serialized format list");
|
||||
goto error;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, formats[i].formatId);
|
||||
|
||||
formatName = (const char*) Stream_Pointer(s);
|
||||
formatNameLength = strnlen(formatName, Stream_GetRemainingLength(s));
|
||||
|
||||
if (formatNameLength == Stream_GetRemainingLength(s))
|
||||
{
|
||||
WLog_ERR(TAG, "missing terminating null byte, %zu bytes left to read", formatNameLength);
|
||||
goto error;
|
||||
}
|
||||
|
||||
formats[i].formatName = strndup(formatName, formatNameLength);
|
||||
Stream_Seek(s, formatNameLength + 1);
|
||||
}
|
||||
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
return formats;
|
||||
|
||||
error:
|
||||
Stream_Free(s, FALSE);
|
||||
free(formats);
|
||||
*numFormats = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void xf_cliprdr_free_formats(CLIPRDR_FORMAT* formats, UINT32 numFormats)
|
||||
{
|
||||
UINT32 i;
|
||||
|
||||
for (i = 0; i < numFormats; i++)
|
||||
{
|
||||
free(formats[i].formatName);
|
||||
}
|
||||
|
||||
free(formats);
|
||||
}
|
||||
|
||||
static CLIPRDR_FORMAT* xf_cliprdr_get_raw_server_formats(xfClipboard* clipboard, UINT32* numFormats)
|
||||
{
|
||||
Atom type = None;
|
||||
int format = 0;
|
||||
unsigned long length = 0;
|
||||
unsigned long remaining;
|
||||
BYTE* data = NULL;
|
||||
CLIPRDR_FORMAT* formats = NULL;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
*numFormats = 0;
|
||||
|
||||
XGetWindowProperty(xfc->display, clipboard->owner, clipboard->raw_format_list_atom,
|
||||
0, 4096, False, clipboard->raw_format_list_atom, &type, &format,
|
||||
&length, &remaining, &data);
|
||||
|
||||
if (data && length > 0 && format == 8 && type == clipboard->raw_format_list_atom)
|
||||
{
|
||||
formats = xf_cliprdr_parse_server_format_list(data, length, numFormats);
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "failed to retrieve raw format list: data=%p, length=%lu, format=%d, type=%d (expected=%d)",
|
||||
data, length, format, type, clipboard->raw_format_list_atom);
|
||||
}
|
||||
|
||||
if (data)
|
||||
XFree(data);
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
static CLIPRDR_FORMAT* xf_cliprdr_get_formats_from_targets(xfClipboard* clipboard, UINT32* numFormats)
|
||||
{
|
||||
int i;
|
||||
Atom atom;
|
||||
@ -205,14 +444,11 @@ static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
||||
int format_property;
|
||||
unsigned long length;
|
||||
unsigned long bytes_left;
|
||||
UINT32 numFormats = 0;
|
||||
CLIPRDR_FORMAT_LIST formatList;
|
||||
xfCliprdrFormat* format = NULL;
|
||||
CLIPRDR_FORMAT* formats = NULL;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
if (!clipboard->numServerFormats)
|
||||
return; /* server format list was not yet received */
|
||||
*numFormats = 0;
|
||||
|
||||
XGetWindowProperty(xfc->display, xfc->drawable, clipboard->property_atom,
|
||||
0, 200, 0, XA_ATOM, &atom, &format_property, &length, &bytes_left, &data);
|
||||
@ -235,16 +471,73 @@ static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
||||
{
|
||||
atom = ((Atom*) data)[i];
|
||||
|
||||
format = xf_cliprdr_get_format_by_atom(clipboard, atom);
|
||||
format = xf_cliprdr_get_client_format_by_atom(clipboard, atom);
|
||||
|
||||
if (format)
|
||||
{
|
||||
formats[numFormats].formatId = format->formatId;
|
||||
formats[numFormats].formatName = format->formatName;
|
||||
numFormats++;
|
||||
formats[*numFormats].formatId = format->formatId;
|
||||
formats[*numFormats].formatName = _strdup(format->formatName);
|
||||
*numFormats += 1;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (data)
|
||||
XFree(data);
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
static CLIPRDR_FORMAT* xf_cliprdr_get_client_formats(xfClipboard* clipboard, UINT32* numFormats)
|
||||
{
|
||||
CLIPRDR_FORMAT* formats = NULL;
|
||||
|
||||
*numFormats = 0;
|
||||
|
||||
if (xf_cliprdr_is_raw_transfer_available(clipboard))
|
||||
{
|
||||
formats = xf_cliprdr_get_raw_server_formats(clipboard, numFormats);
|
||||
}
|
||||
|
||||
if (*numFormats == 0)
|
||||
{
|
||||
xf_cliprdr_free_formats(formats, *numFormats);
|
||||
|
||||
formats = xf_cliprdr_get_formats_from_targets(clipboard, numFormats);
|
||||
}
|
||||
|
||||
return formats;
|
||||
}
|
||||
|
||||
static void xf_cliprdr_provide_server_format_list(xfClipboard* clipboard)
|
||||
{
|
||||
wStream* formats = NULL;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
formats = xf_cliprdr_serialize_server_format_list(clipboard);
|
||||
|
||||
if (formats)
|
||||
{
|
||||
XChangeProperty(xfc->display, xfc->drawable, clipboard->raw_format_list_atom,
|
||||
clipboard->raw_format_list_atom, 8, PropModeReplace,
|
||||
Stream_Buffer(formats), Stream_Length(formats));
|
||||
}
|
||||
else
|
||||
{
|
||||
XDeleteProperty(xfc->display, xfc->drawable, clipboard->raw_format_list_atom);
|
||||
}
|
||||
|
||||
Stream_Free(formats, TRUE);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
||||
{
|
||||
UINT32 numFormats = 0;
|
||||
CLIPRDR_FORMAT* formats = NULL;
|
||||
CLIPRDR_FORMAT_LIST formatList;
|
||||
|
||||
formats = xf_cliprdr_get_client_formats(clipboard, &numFormats);
|
||||
|
||||
ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST));
|
||||
|
||||
formatList.msgFlags = CB_RESPONSE_OK;
|
||||
@ -253,10 +546,7 @@ static void xf_cliprdr_get_requested_targets(xfClipboard* clipboard)
|
||||
|
||||
clipboard->context->ClientFormatList(clipboard->context, &formatList);
|
||||
|
||||
out:
|
||||
if (data)
|
||||
XFree(data);
|
||||
free(formats);
|
||||
xf_cliprdr_free_formats(formats, numFormats);
|
||||
}
|
||||
|
||||
static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasData, BYTE* data, int size)
|
||||
@ -264,8 +554,8 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
|
||||
BOOL bSuccess;
|
||||
UINT32 SrcSize;
|
||||
UINT32 DstSize;
|
||||
UINT32 formatId;
|
||||
UINT32 altFormatId;
|
||||
UINT32 srcFormatId;
|
||||
UINT32 dstFormatId;
|
||||
BYTE* pSrcData = NULL;
|
||||
BYTE* pDstData = NULL;
|
||||
xfCliprdrFormat* format;
|
||||
@ -273,7 +563,7 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
|
||||
if (clipboard->incr_starts && hasData)
|
||||
return;
|
||||
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
format = xf_cliprdr_get_client_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (!hasData || !data || !format)
|
||||
{
|
||||
@ -281,25 +571,29 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
|
||||
return;
|
||||
}
|
||||
|
||||
formatId = 0;
|
||||
altFormatId = 0;
|
||||
srcFormatId = 0;
|
||||
dstFormatId = 0;
|
||||
|
||||
switch (format->formatId)
|
||||
{
|
||||
case CF_RAW:
|
||||
srcFormatId = CF_RAW;
|
||||
break;
|
||||
|
||||
case CF_TEXT:
|
||||
case CF_OEMTEXT:
|
||||
case CF_UNICODETEXT:
|
||||
size = strlen((char*) data) + 1;
|
||||
formatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING");
|
||||
srcFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING");
|
||||
break;
|
||||
|
||||
case CF_DIB:
|
||||
formatId = ClipboardGetFormatId(clipboard->system, "image/bmp");
|
||||
srcFormatId = ClipboardGetFormatId(clipboard->system, "image/bmp");
|
||||
break;
|
||||
|
||||
case CB_FORMAT_HTML:
|
||||
size = strlen((char*) data) + 1;
|
||||
formatId = ClipboardGetFormatId(clipboard->system, "text/html");
|
||||
srcFormatId = ClipboardGetFormatId(clipboard->system, "text/html");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -311,17 +605,24 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
|
||||
|
||||
CopyMemory(pSrcData, data, SrcSize);
|
||||
|
||||
bSuccess = ClipboardSetData(clipboard->system, formatId, (void*) pSrcData, SrcSize);
|
||||
bSuccess = ClipboardSetData(clipboard->system, srcFormatId, (void*) pSrcData, SrcSize);
|
||||
|
||||
if (!bSuccess)
|
||||
free(pSrcData);
|
||||
|
||||
altFormatId = clipboard->requestedFormatId;
|
||||
if (format->formatName)
|
||||
{
|
||||
dstFormatId = ClipboardGetFormatId(clipboard->system, format->formatName);
|
||||
}
|
||||
else
|
||||
{
|
||||
dstFormatId = format->formatId;
|
||||
}
|
||||
|
||||
if (bSuccess && altFormatId)
|
||||
if (bSuccess)
|
||||
{
|
||||
DstSize = 0;
|
||||
pDstData = (BYTE*) ClipboardGetData(clipboard->system, altFormatId, &DstSize);
|
||||
pDstData = (BYTE*) ClipboardGetData(clipboard->system, dstFormatId, &DstSize);
|
||||
}
|
||||
|
||||
if (!pDstData)
|
||||
@ -346,7 +647,7 @@ static BOOL xf_cliprdr_get_requested_data(xfClipboard* clipboard, Atom target)
|
||||
xfCliprdrFormat* format;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
format = xf_cliprdr_get_client_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (!format || (format->atom != target))
|
||||
{
|
||||
@ -495,13 +796,14 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
||||
int fmt;
|
||||
Atom type;
|
||||
UINT32 formatId;
|
||||
const char* formatName;
|
||||
XEvent* respond;
|
||||
UINT32 altFormatId;
|
||||
BYTE* data = NULL;
|
||||
BOOL delayRespond;
|
||||
BOOL rawTransfer;
|
||||
unsigned long length;
|
||||
unsigned long bytes_left;
|
||||
xfCliprdrFormat* format;
|
||||
CLIPRDR_FORMAT* format;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
if (xevent->xselectionrequest.owner != xfc->drawable)
|
||||
@ -535,14 +837,15 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
||||
}
|
||||
else
|
||||
{
|
||||
format = xf_cliprdr_get_format_by_atom(clipboard, xevent->xselectionrequest.target);
|
||||
format = xf_cliprdr_get_server_format_by_atom(clipboard, xevent->xselectionrequest.target);
|
||||
|
||||
if (format && (xevent->xselectionrequest.requestor != xfc->drawable))
|
||||
{
|
||||
formatId = format->formatId;
|
||||
altFormatId = formatId;
|
||||
formatName = format->formatName;
|
||||
rawTransfer = FALSE;
|
||||
|
||||
if (formatId == 0)
|
||||
if (formatId == CF_RAW)
|
||||
{
|
||||
if (XGetWindowProperty(xfc->display, xevent->xselectionrequest.requestor,
|
||||
clipboard->property_atom, 0, 4, 0, XA_INTEGER,
|
||||
@ -553,12 +856,13 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
||||
|
||||
if (data)
|
||||
{
|
||||
CopyMemory(&altFormatId, data, 4);
|
||||
rawTransfer = TRUE;
|
||||
CopyMemory(&formatId, data, 4);
|
||||
XFree(data);
|
||||
}
|
||||
}
|
||||
|
||||
if ((clipboard->data != 0) && (formatId == clipboard->data_format) && (altFormatId == clipboard->data_alt_format))
|
||||
if ((clipboard->data != 0) && (formatId == clipboard->data_format_id) && (formatName == clipboard->data_format_name))
|
||||
{
|
||||
/* Cached clipboard data available. Send it now */
|
||||
respond->xselection.property = xevent->xselectionrequest.property;
|
||||
@ -582,11 +886,12 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard, XEvent*
|
||||
|
||||
respond->xselection.property = xevent->xselectionrequest.property;
|
||||
clipboard->respond = respond;
|
||||
clipboard->data_format = formatId;
|
||||
clipboard->data_alt_format = altFormatId;
|
||||
clipboard->data_format_id = formatId;
|
||||
clipboard->data_format_name = formatName;
|
||||
clipboard->data_raw_format = rawTransfer;
|
||||
delayRespond = TRUE;
|
||||
|
||||
xf_cliprdr_send_data_request(clipboard, altFormatId);
|
||||
xf_cliprdr_send_data_request(clipboard, formatId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -631,7 +936,7 @@ static BOOL xf_cliprdr_process_property_notify(xfClipboard* clipboard, XEvent* x
|
||||
else if ((xevent->xproperty.window == xfc->drawable) &&
|
||||
(xevent->xproperty.state == PropertyNewValue) && clipboard->incr_starts)
|
||||
{
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
format = xf_cliprdr_get_client_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (format)
|
||||
xf_cliprdr_get_requested_data(clipboard, format->atom);
|
||||
@ -787,24 +1092,6 @@ UINT xf_cliprdr_send_client_format_list_response(xfClipboard* clipboard, BOOL st
|
||||
return clipboard->context->ClientFormatListResponse(clipboard->context, &formatListResponse);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
int xf_cliprdr_send_client_format_data_request(xfClipboard* clipboard, UINT32 formatId)
|
||||
{
|
||||
CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest;
|
||||
|
||||
formatDataRequest.msgType = CB_FORMAT_DATA_REQUEST;
|
||||
formatDataRequest.msgFlags = CB_RESPONSE_OK;
|
||||
|
||||
formatDataRequest.requestedFormatId = formatId;
|
||||
clipboard->requestedFormatId = formatId;
|
||||
|
||||
return clipboard->context->ClientFormatDataRequest(clipboard->context, &formatDataRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
@ -856,6 +1143,9 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR
|
||||
clipboard->data = NULL;
|
||||
}
|
||||
|
||||
clipboard->data_format_id = -1;
|
||||
clipboard->data_format_name = NULL;
|
||||
|
||||
if (clipboard->serverFormats)
|
||||
{
|
||||
for (i = 0; i < clipboard->numServerFormats; i++)
|
||||
@ -867,14 +1157,11 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR
|
||||
clipboard->numServerFormats = 0;
|
||||
}
|
||||
|
||||
clipboard->numServerFormats = formatList->numFormats;
|
||||
clipboard->numServerFormats = formatList->numFormats + 1; /* +1 for CF_RAW */
|
||||
|
||||
if (clipboard->numServerFormats)
|
||||
{
|
||||
if (!(clipboard->serverFormats = (CLIPRDR_FORMAT*) calloc(clipboard->numServerFormats, sizeof(CLIPRDR_FORMAT)))) {
|
||||
WLog_ERR(TAG, "failed to allocate %d CLIPRDR_FORMAT structs", clipboard->numServerFormats);
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
if (!(clipboard->serverFormats = (CLIPRDR_FORMAT*) calloc(clipboard->numServerFormats, sizeof(CLIPRDR_FORMAT)))) {
|
||||
WLog_ERR(TAG, "failed to allocate %d CLIPRDR_FORMAT structs", clipboard->numServerFormats);
|
||||
return CHANNEL_RC_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (i = 0; i < formatList->numFormats; i++)
|
||||
@ -897,6 +1184,13 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR
|
||||
}
|
||||
}
|
||||
|
||||
/* CF_RAW is always implicitly supported by the server */
|
||||
format = &clipboard->serverFormats[formatList->numFormats];
|
||||
format->formatId = CF_RAW;
|
||||
format->formatName = NULL;
|
||||
|
||||
xf_cliprdr_provide_server_format_list(clipboard);
|
||||
|
||||
clipboard->numTargets = 2;
|
||||
|
||||
for (i = 0; i < formatList->numFormats; i++)
|
||||
@ -905,7 +1199,7 @@ static UINT xf_cliprdr_server_format_list(CliprdrClientContext* context, CLIPRDR
|
||||
|
||||
for (j = 0; j < clipboard->numClientFormats; j++)
|
||||
{
|
||||
if (format->formatId == clipboard->clientFormats[j].formatId)
|
||||
if (xf_cliprdr_formats_equal(format, &clipboard->clientFormats[j]))
|
||||
{
|
||||
xf_cliprdr_append_target(clipboard, clipboard->clientFormats[j].atom);
|
||||
}
|
||||
@ -940,25 +1234,28 @@ static UINT xf_cliprdr_server_format_list_response(CliprdrClientContext* context
|
||||
*/
|
||||
static UINT xf_cliprdr_server_format_data_request(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest)
|
||||
{
|
||||
BOOL rawTransfer;
|
||||
xfCliprdrFormat* format = NULL;
|
||||
UINT32 formatId = formatDataRequest->requestedFormatId;
|
||||
xfClipboard* clipboard = (xfClipboard*) context->custom;
|
||||
xfContext* xfc = clipboard->xfc;
|
||||
|
||||
if (xf_cliprdr_is_self_owned(clipboard))
|
||||
rawTransfer = xf_cliprdr_is_raw_transfer_available(clipboard);
|
||||
|
||||
if (rawTransfer)
|
||||
{
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, 0);
|
||||
format = xf_cliprdr_get_client_format_by_id(clipboard, CF_RAW);
|
||||
|
||||
XChangeProperty(xfc->display, xfc->drawable, clipboard->property_atom,
|
||||
XA_INTEGER, 32, PropModeReplace, (BYTE*) &formatId, 1);
|
||||
}
|
||||
else
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, formatId);
|
||||
format = xf_cliprdr_get_client_format_by_id(clipboard, formatId);
|
||||
|
||||
if (!format)
|
||||
return xf_cliprdr_send_data_response(clipboard, NULL, 0);
|
||||
|
||||
clipboard->requestedFormatId = formatId;
|
||||
clipboard->requestedFormatId = rawTransfer ? CF_RAW : formatId;
|
||||
|
||||
XConvertSelection(xfc->display, clipboard->clipboard_atom,
|
||||
format->atom, clipboard->property_atom, xfc->drawable, CurrentTime);
|
||||
@ -982,9 +1279,8 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context
|
||||
BYTE* pDstData;
|
||||
UINT32 DstSize;
|
||||
UINT32 SrcSize;
|
||||
UINT32 formatId;
|
||||
UINT32 altFormatId;
|
||||
xfCliprdrFormat* format;
|
||||
UINT32 srcFormatId;
|
||||
UINT32 dstFormatId;
|
||||
BOOL nullTerminated = FALSE;
|
||||
UINT32 size = formatDataResponse->dataLen;
|
||||
BYTE* data = formatDataResponse->requestedFormatData;
|
||||
@ -994,8 +1290,6 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context
|
||||
if (!clipboard->respond)
|
||||
return CHANNEL_RC_OK;
|
||||
|
||||
format = xf_cliprdr_get_format_by_id(clipboard, clipboard->requestedFormatId);
|
||||
|
||||
if (clipboard->data)
|
||||
{
|
||||
free(clipboard->data);
|
||||
@ -1005,39 +1299,50 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context
|
||||
pDstData = NULL;
|
||||
DstSize = 0;
|
||||
|
||||
formatId = 0;
|
||||
altFormatId = 0;
|
||||
srcFormatId = 0;
|
||||
dstFormatId = 0;
|
||||
|
||||
switch (clipboard->data_format)
|
||||
if (clipboard->data_raw_format)
|
||||
{
|
||||
srcFormatId = CF_RAW;
|
||||
dstFormatId = CF_RAW;
|
||||
}
|
||||
else if (clipboard->data_format_name)
|
||||
{
|
||||
if (strcmp(clipboard->data_format_name, "HTML Format") == 0)
|
||||
{
|
||||
srcFormatId = ClipboardGetFormatId(clipboard->system, "HTML Format");
|
||||
dstFormatId = ClipboardGetFormatId(clipboard->system, "text/html");
|
||||
nullTerminated = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (clipboard->data_format_id)
|
||||
{
|
||||
case CF_TEXT:
|
||||
formatId = CF_TEXT;
|
||||
altFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING");
|
||||
srcFormatId = CF_TEXT;
|
||||
dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING");
|
||||
nullTerminated = TRUE;
|
||||
break;
|
||||
|
||||
case CF_OEMTEXT:
|
||||
formatId = CF_OEMTEXT;
|
||||
altFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING");
|
||||
srcFormatId = CF_OEMTEXT;
|
||||
dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING");
|
||||
nullTerminated = TRUE;
|
||||
break;
|
||||
|
||||
case CF_UNICODETEXT:
|
||||
formatId = CF_UNICODETEXT;
|
||||
altFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING");
|
||||
srcFormatId = CF_UNICODETEXT;
|
||||
dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING");
|
||||
nullTerminated = TRUE;
|
||||
break;
|
||||
|
||||
case CF_DIB:
|
||||
formatId = CF_DIB;
|
||||
altFormatId = ClipboardGetFormatId(clipboard->system, "image/bmp");
|
||||
break;
|
||||
|
||||
case CB_FORMAT_HTML:
|
||||
formatId = ClipboardGetFormatId(clipboard->system, "HTML Format");
|
||||
altFormatId = ClipboardGetFormatId(clipboard->system, "text/html");
|
||||
nullTerminated = TRUE;
|
||||
srcFormatId = CF_DIB;
|
||||
dstFormatId = ClipboardGetFormatId(clipboard->system, "image/bmp");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SrcSize = (UINT32) size;
|
||||
@ -1048,18 +1353,21 @@ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context
|
||||
|
||||
CopyMemory(pSrcData, data, SrcSize);
|
||||
|
||||
bSuccess = ClipboardSetData(clipboard->system, formatId, (void*) pSrcData, SrcSize);
|
||||
bSuccess = ClipboardSetData(clipboard->system, srcFormatId, (void*) pSrcData, SrcSize);
|
||||
|
||||
if (!bSuccess)
|
||||
free (pSrcData);
|
||||
|
||||
if (bSuccess && altFormatId)
|
||||
if (bSuccess)
|
||||
{
|
||||
DstSize = 0;
|
||||
pDstData = (BYTE*) ClipboardGetData(clipboard->system, altFormatId, &DstSize);
|
||||
pDstData = (BYTE*) ClipboardGetData(clipboard->system, dstFormatId, &DstSize);
|
||||
|
||||
if ((DstSize > 1) && nullTerminated)
|
||||
DstSize--;
|
||||
if (nullTerminated)
|
||||
{
|
||||
while (DstSize > 0 && pDstData[DstSize - 1] == '\0')
|
||||
DstSize--;
|
||||
}
|
||||
}
|
||||
|
||||
clipboard->data = pDstData;
|
||||
@ -1111,6 +1419,11 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
||||
|
||||
clipboard->property_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR", FALSE);
|
||||
|
||||
clipboard->raw_transfer_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR_RAW", FALSE);
|
||||
clipboard->raw_format_list_atom = XInternAtom(xfc->display, "_FREERDP_CLIPRDR_FORMATS", FALSE);
|
||||
|
||||
xf_cliprdr_set_raw_transfer_enabled(clipboard, TRUE);
|
||||
|
||||
XSelectInput(xfc->display, clipboard->root_window, PropertyChangeMask);
|
||||
|
||||
#ifdef WITH_XFIXES
|
||||
@ -1140,7 +1453,7 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
|
||||
n = 0;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "_FREERDP_RAW", False);
|
||||
clipboard->clientFormats[n].formatId = 0;
|
||||
clipboard->clientFormats[n].formatId = CF_RAW;
|
||||
n++;
|
||||
|
||||
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "UTF8_STRING", False);
|
||||
|
||||
@ -39,7 +39,7 @@ foreach(FREERDP_CHANNELS_CLIENT_SRC ${FREERDP_CHANNELS_CLIENT_SRCS})
|
||||
endforeach()
|
||||
|
||||
if(MSVC)
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def)
|
||||
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS})
|
||||
endif()
|
||||
|
||||
# On windows create dll version information.
|
||||
|
||||
@ -21,21 +21,28 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <freerdp/client.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/assistance.h>
|
||||
#include <freerdp/client/file.h>
|
||||
#include <freerdp/utils/passphrase.h>
|
||||
#include <freerdp/client/cmdline.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
|
||||
BOOL freerdp_client_common_new(freerdp* instance, rdpContext* context)
|
||||
#include <freerdp/log.h>
|
||||
#define TAG CLIENT_TAG("common")
|
||||
|
||||
static BOOL freerdp_client_common_new(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
RDP_CLIENT_ENTRY_POINTS* pEntryPoints = instance->pClientEntryPoints;
|
||||
return pEntryPoints->ClientNew(instance, context);
|
||||
}
|
||||
|
||||
void freerdp_client_common_free(freerdp* instance, rdpContext* context)
|
||||
static void freerdp_client_common_free(freerdp* instance, rdpContext* context)
|
||||
{
|
||||
RDP_CLIENT_ENTRY_POINTS* pEntryPoints = instance->pClientEntryPoints;
|
||||
pEntryPoints->ClientFree(instance, context);
|
||||
@ -152,7 +159,7 @@ static BOOL freerdp_client_settings_post_process(rdpSettings* settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Moved logic for Multimon and Span monitors to force fullscreen, so
|
||||
* that the rdp file also triggers this functionality */
|
||||
if (settings->SpanMonitors)
|
||||
@ -164,7 +171,7 @@ static BOOL freerdp_client_settings_post_process(rdpSettings* settings)
|
||||
{
|
||||
settings->Fullscreen = TRUE;
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
|
||||
out_error:
|
||||
@ -197,7 +204,7 @@ int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc,
|
||||
{
|
||||
status = freerdp_client_settings_parse_assistance_file(settings, settings->AssistanceFile);
|
||||
}
|
||||
|
||||
|
||||
/* Only call post processing if no status/error was returned*/
|
||||
if (status < 0)
|
||||
return status;
|
||||
@ -296,3 +303,213 @@ int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, const c
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Callback set in the rdp_freerdp structure, and used to get the user's password,
|
||||
* if required to establish the connection.
|
||||
* This function is actually called in credssp_ntlmssp_client_init()
|
||||
* @see rdp_server_accept_nego() and rdp_check_fds()
|
||||
* @param instance - pointer to the rdp_freerdp structure that contains the connection settings
|
||||
* @param username - unused
|
||||
* @param password - on return: pointer to a character string that will be filled by the password entered by the user.
|
||||
* Note that this character string will be allocated inside the function, and needs to be deallocated by the caller
|
||||
* using free(), even in case this function fails.
|
||||
* @param domain - unused
|
||||
* @return TRUE if a password was successfully entered. See freerdp_passphrase_read() for more details.
|
||||
*/
|
||||
static BOOL client_cli_authenticate_raw(freerdp* instance, BOOL gateway, char** username,
|
||||
char** password, char** domain)
|
||||
{
|
||||
static const size_t password_size = 512;
|
||||
const char* auth[] =
|
||||
{
|
||||
"Username: ",
|
||||
"Domain: ",
|
||||
"Password: "
|
||||
};
|
||||
const char* gw[] =
|
||||
{
|
||||
"GatewayUsername: ",
|
||||
"GatewayDomain: ",
|
||||
"GatewayPassword: "
|
||||
};
|
||||
const char** prompt = (gateway) ? gw : auth;
|
||||
|
||||
if (!username || !password || !domain)
|
||||
return FALSE;
|
||||
|
||||
if (!*username)
|
||||
{
|
||||
size_t username_size = 0;
|
||||
printf("%s", prompt[0]);
|
||||
if (GetLine(username, &username_size, stdin) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "GetLine returned %s [%d]", strerror(errno), errno);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (*username)
|
||||
{
|
||||
*username = StrSep(username, "\r");
|
||||
*username = StrSep(username, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!*domain)
|
||||
{
|
||||
size_t domain_size = 0;
|
||||
printf("%s", prompt[1]);
|
||||
if (GetLine(domain, &domain_size, stdin) < 0)
|
||||
{
|
||||
WLog_ERR(TAG, "GetLine returned %s [%d]", strerror(errno), errno);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (*domain)
|
||||
{
|
||||
*domain = StrSep(domain, "\r");
|
||||
*domain = StrSep(domain, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!*password)
|
||||
{
|
||||
*password = calloc(password_size, sizeof(char));
|
||||
if (!*password)
|
||||
goto fail;
|
||||
|
||||
if (freerdp_passphrase_read(prompt[2], *password, password_size,
|
||||
instance->settings->CredentialsFromStdin) == NULL)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
fail:
|
||||
free(*username);
|
||||
free(*domain);
|
||||
free(*password);
|
||||
|
||||
*username = NULL;
|
||||
*domain = NULL;
|
||||
*password = NULL;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL client_cli_authenticate(freerdp* instance, char** username, char** password, char** domain)
|
||||
{
|
||||
return client_cli_authenticate_raw(instance, FALSE, username, password, domain);
|
||||
}
|
||||
|
||||
BOOL client_cli_gw_authenticate(freerdp* instance, char** username, char** password, char** domain)
|
||||
{
|
||||
return client_cli_authenticate_raw(instance, TRUE, username, password, domain);
|
||||
}
|
||||
|
||||
static DWORD client_cli_accept_certificate(rdpSettings* settings)
|
||||
{
|
||||
char answer;
|
||||
|
||||
if (settings->CredentialsFromStdin)
|
||||
return 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
printf("Do you trust the above certificate? (Y/T/N) ");
|
||||
answer = fgetc(stdin);
|
||||
|
||||
if (feof(stdin))
|
||||
{
|
||||
printf("\nError: Could not read answer from stdin.");
|
||||
if (settings->CredentialsFromStdin)
|
||||
printf(" - Run without parameter \"--from-stdin\" to set trust.");
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(answer)
|
||||
{
|
||||
case 'y':
|
||||
case 'Y':
|
||||
return 1;
|
||||
case 't':
|
||||
case 'T':
|
||||
return 2;
|
||||
case 'n':
|
||||
case 'N':
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Callback set in the rdp_freerdp structure, and used to make a certificate validation
|
||||
* when the connection requires it.
|
||||
* This function will actually be called by tls_verify_certificate().
|
||||
* @see rdp_client_connect() and tls_connect()
|
||||
* @param instance - pointer to the rdp_freerdp structure that contains the connection settings
|
||||
* @param common_name
|
||||
* @param subject
|
||||
* @param issuer
|
||||
* @param fingerprint
|
||||
* @param host_mismatch Indicates the certificate host does not match.
|
||||
* @return 1 if the certificate is trusted, 2 if temporary trusted, 0 otherwise.
|
||||
*/
|
||||
DWORD client_cli_verify_certificate(freerdp* instance, const char* common_name,
|
||||
const char* subject, const char* issuer,
|
||||
const char* fingerprint, BOOL host_mismatch)
|
||||
{
|
||||
printf("Certificate details:\n");
|
||||
printf("\tSubject: %s\n", subject);
|
||||
printf("\tIssuer: %s\n", issuer);
|
||||
printf("\tThumbprint: %s\n", fingerprint);
|
||||
printf("The above X.509 certificate could not be verified, possibly because you do not have\n"
|
||||
"the CA certificate in your certificate store, or the certificate has expired.\n"
|
||||
"Please look at the documentation on how to create local certificate store for a private CA.\n");
|
||||
|
||||
return client_cli_accept_certificate(instance->settings);
|
||||
}
|
||||
|
||||
/** Callback set in the rdp_freerdp structure, and used to make a certificate validation
|
||||
* when a stored certificate does not match the remote counterpart.
|
||||
* This function will actually be called by tls_verify_certificate().
|
||||
* @see rdp_client_connect() and tls_connect()
|
||||
* @param instance - pointer to the rdp_freerdp structure that contains the connection settings
|
||||
* @param common_name
|
||||
* @param subject
|
||||
* @param issuer
|
||||
* @param fingerprint
|
||||
* @param old_subject
|
||||
* @param old_issuer
|
||||
* @param old_fingerprint
|
||||
* @return 1 if the certificate is trusted, 2 if temporary trusted, 0 otherwise.
|
||||
*/
|
||||
DWORD client_cli_verify_changed_certificate(freerdp* instance, const char* common_name,
|
||||
const char* subject, const char* issuer,
|
||||
const char* fingerprint,
|
||||
const char* old_subject, const char* old_issuer,
|
||||
const char* old_fingerprint)
|
||||
{
|
||||
printf("!!! Certificate has changed !!!\n");
|
||||
printf("\n");
|
||||
printf("New Certificate details:\n");
|
||||
printf("\tSubject: %s\n", subject);
|
||||
printf("\tIssuer: %s\n", issuer);
|
||||
printf("\tThumbprint: %s\n", fingerprint);
|
||||
printf("\n");
|
||||
printf("Old Certificate details:\n");
|
||||
printf("\tSubject: %s\n", old_subject);
|
||||
printf("\tIssuer: %s\n", old_issuer);
|
||||
printf("\tThumbprint: %s\n", old_fingerprint);
|
||||
printf("\n");
|
||||
printf("The above X.509 certificate does not match the certificate used for previous connections.\n"
|
||||
"This may indicate that the certificate has been tampered with.\n"
|
||||
"Please contact the administrator of the RDP server and clarify.\n");
|
||||
|
||||
return client_cli_accept_certificate(instance->settings);
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -880,7 +880,7 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
|
||||
char* user = NULL;
|
||||
char* domain = NULL;
|
||||
|
||||
if (freerdp_parse_username(file->Username, &user, &domain) != 0)
|
||||
if (!freerdp_parse_username(file->Username, &user, &domain))
|
||||
return FALSE;
|
||||
if (freerdp_set_param_string(settings, FreeRDP_Username, user) != 0)
|
||||
return FALSE;
|
||||
@ -900,7 +900,7 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
|
||||
int port = -1;
|
||||
char* host = NULL;
|
||||
|
||||
if (freerdp_parse_hostname(file->FullAddress, &host, &port) != 0)
|
||||
if (!freerdp_parse_hostname(file->FullAddress, &host, &port))
|
||||
return FALSE;
|
||||
|
||||
if (freerdp_set_param_string(settings, FreeRDP_ServerHostname, host) != 0)
|
||||
@ -1022,7 +1022,7 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
|
||||
int port = -1;
|
||||
char* host = NULL;
|
||||
|
||||
if (freerdp_parse_hostname(file->GatewayHostname, &host, &port) != 0)
|
||||
if (!freerdp_parse_hostname(file->GatewayHostname, &host, &port))
|
||||
return FALSE;
|
||||
|
||||
if (freerdp_set_param_string(settings, FreeRDP_GatewayHostname, host) != 0)
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
LIBRARY "freerdp-client"
|
||||
EXPORTS
|
||||
|
||||
@ -1627,7 +1627,7 @@ if(NOT _CMAKE_IN_TRY_COMPILE)
|
||||
else()
|
||||
set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" )
|
||||
endif()
|
||||
set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_OUTPUT_ABI_NAME}" CACHE PATH "path for android libs" )
|
||||
set( CMAKE_INSTALL_LIBDIR "${ANDROID_NDK_OUTPUT_ABI_NAME}" CACHE PATH "path for android libs" )
|
||||
endif()
|
||||
|
||||
# copy shaed stl library to build directory
|
||||
|
||||
@ -72,6 +72,8 @@ option(WITH_CHANNELS "Build virtual channel plugins" ON)
|
||||
cmake_dependent_option(WITH_CLIENT_CHANNELS "Build virtual channel plugins" ON
|
||||
"WITH_CLIENT_COMMON;WITH_CHANNELS" OFF)
|
||||
|
||||
cmake_dependent_option(WITH_MACAUDIO "Enable OSX sound backend" ON "APPLE;NOT IOS" OFF)
|
||||
|
||||
if(WITH_SERVER AND WITH_CHANNELS)
|
||||
option(WITH_SERVER_CHANNELS "Build virtual channel plugins" ON)
|
||||
endif()
|
||||
|
||||
@ -15,19 +15,8 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set(JAVA_DEBUG_DEFAULT "off")
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
|
||||
set(JAVA_DEBUG_DEFAULT "on")
|
||||
endif()
|
||||
|
||||
option(WITH_DEBUG_ANDROID_JNI "Enable debug output for android jni bindings" ${DEFAULT_DEBUG_OPTION})
|
||||
option(WITH_ANDROID_DEBUG_MENU "Enable debug output for android jni bindings" ${DEFAULT_DEBUG_OPTION})
|
||||
option(WITH_OPENSLES "Enable sound and microphone redirection using OpenSLES" ON)
|
||||
option(ANDROID_BUILD_JAVA "Automatically android java code - build type depends on CMAKE_BUILD_TYPE" ON)
|
||||
option(ANDROID_BUILD_JAVA_DEBUG "Create a android debug package" ${JAVA_DEBUG_DEFAULT})
|
||||
|
||||
set(ANDROID_APP_VERSION 3 CACHE STRING "Application version")
|
||||
set(ANDROID_APP_TARGET_SDK 21 CACHE STRING "Application target android SDK")
|
||||
set(ANDROID_APP_MIN_SDK 14 CACHE STRING "Application minimum android SDK requirement")
|
||||
set(ANDROID_APP_GOOGLE_TARGET_SDK "16" CACHE STRING "Application target google SDK")
|
||||
|
||||
|
||||
@ -1,19 +1,16 @@
|
||||
# - Find Wayland
|
||||
# Find the Wayland libraries
|
||||
# - Finds Wayland
|
||||
# Find the Wayland libraries that are needed for UWAC
|
||||
#
|
||||
# This module defines the following variables:
|
||||
# WAYLAND_FOUND - true if WAYLAND_INCLUDE_DIR & WAYLAND_LIBRARY are found
|
||||
# WAYLAND_LIBRARIES - Set when WAYLAND_LIBRARY is found
|
||||
# WAYLAND_INCLUDE_DIRS - Set when WAYLAND_INCLUDE_DIR is found
|
||||
#
|
||||
# WAYLAND_INCLUDE_DIR - where to find wayland-client.h, etc.
|
||||
# WAYLAND_LIBRARY - the Wayland client library
|
||||
# WAYLAND_VERSION - wayland client version if found and pkg-config was used
|
||||
# WAYLAND_FOUND - true if UWAC has been found
|
||||
# WAYLAND_LIBS - Set to the full path to wayland client libraries
|
||||
# WAYLAND_INCLUDE_DIR - Set to the include directories for wayland
|
||||
# XKBCOMMON_LIBS - Set to the full path to xkbcommon libraries
|
||||
# XKBCOMMON_INCLUDE_DIR - Set to the include directories for xkbcommon
|
||||
#
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2014 Manuel Bachmann <tarnyko@tarnyko.net>
|
||||
# Copyright 2015 Bernhard Miklautz <bernhard.miklautz@shacknet.at>
|
||||
# Copyright 2015 David Fort <contact@hardening-consulting.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@ -28,38 +25,35 @@
|
||||
# limitations under the License.
|
||||
#=============================================================================
|
||||
|
||||
set(REQUIRED_WAYLAND_CLIENT_VERSION 1.3.0)
|
||||
include(FindPkgConfig)
|
||||
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(WAYLAND wayland-client)
|
||||
pkg_check_modules(WAYLAND_SCANNER_PC wayland-scanner)
|
||||
pkg_check_modules(WAYLAND_CLIENT_PC wayland-client)
|
||||
pkg_check_modules(XKBCOMMON_PC xkbcommon)
|
||||
endif()
|
||||
|
||||
find_path(WAYLAND_INCLUDE_DIR NAMES wayland-client.h
|
||||
PATHS ${WAYLAND_INCLUDE_DIRS}
|
||||
DOC "The Wayland include directory"
|
||||
find_program(WAYLAND_SCANNER wayland-scanner
|
||||
HINTS "${WAYLAND_SCANNER_PC_PREFIX}/bin"
|
||||
)
|
||||
|
||||
find_library(WAYLAND_LIBRARY NAMES wayland-client
|
||||
PATHS ${WAYLAND_LIBRARY_DIRS}
|
||||
DOC "The Wayland client library"
|
||||
find_path(WAYLAND_INCLUDE_DIR wayland-client.h
|
||||
HINTS ${WAYLAND_CLIENT_PC_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(WAYLAND_LIBS
|
||||
NAMES "wayland-client"
|
||||
HINTS "${WAYLAND_CLIENT_PC_LIBRARY_DIRS}"
|
||||
)
|
||||
|
||||
find_path(XKBCOMMON_INCLUDE_DIR xkbcommon/xkbcommon.h
|
||||
HINTS ${XKBCOMMON_PC_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
find_library(XKBCOMMON_LIBS
|
||||
NAMES xkbcommon
|
||||
HINTS "${XKBCOMMON_PC_LIBRARY_DIRS}"
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_LIBRARY WAYLAND_INCLUDE_DIR)
|
||||
|
||||
if(WAYLAND_VERSION)
|
||||
if (${WAYLAND_VERSION} VERSION_LESS ${REQUIRED_WAYLAND_CLIENT_VERSION})
|
||||
message(WARNING "Installed wayland version ${WAYLAND_VERSION} is too old - minimum required version ${REQUIRED_WAYLAND_CLIENT_VERSION}")
|
||||
set(WAYLAND_FOUND FALSE)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Couldn't detect wayland version - no version check is done")
|
||||
endif()
|
||||
|
||||
if(WAYLAND_FOUND)
|
||||
set(WAYLAND_LIBRARIES ${WAYLAND_LIBRARY})
|
||||
set(WAYLAND_INCLUDE_DIRS ${WAYLAND_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(WAYLAND_INCLUDE_DIR WAYLAND_LIBRARY WAYLAND_VERSION)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WAYLAND DEFAULT_MSG WAYLAND_SCANNER WAYLAND_INCLUDE_DIR WAYLAND_LIBS XKBCOMMON_INCLUDE_DIR XKBCOMMON_LIBS)
|
||||
|
||||
@ -19,7 +19,7 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "@RC_VERSION_VENDOR@"
|
||||
VALUE "FileDescription", "@RC_VERSION_DESCRIPTION@"
|
||||
VALUE "FileVersion", "@RC_VERSION_MAJOR@,@RC_VERSION_MINOR@,@RC_VERSION_BUILD@,@RC_VERSION_PATCH@"
|
||||
VALUE "FileVersion", "@RC_VERSION_MAJOR@,@RC_VERSION_MINOR@,@RC_VERSION_PATCH@,@RC_VERSION_BUILD@"
|
||||
VALUE "InternalName", "@RC_VERSION_FILE@"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2011-@RC_VERSION_YEAR@"
|
||||
VALUE "OriginalFilename", "@RC_VERSION_FILE@"
|
||||
|
||||
@ -4,8 +4,6 @@
|
||||
/* Include files */
|
||||
#cmakedefine HAVE_FCNTL_H
|
||||
#cmakedefine HAVE_UNISTD_H
|
||||
#cmakedefine HAVE_STDINT_H
|
||||
#cmakedefine HAVE_STDBOOL_H
|
||||
#cmakedefine HAVE_INTTYPES_H
|
||||
#cmakedefine HAVE_SYS_MODEM_H
|
||||
#cmakedefine HAVE_SYS_FILIO_H
|
||||
@ -89,6 +87,5 @@
|
||||
#cmakedefine WITH_DEBUG_X11_CLIPRDR
|
||||
#cmakedefine WITH_DEBUG_X11_LOCAL_MOVESIZE
|
||||
#cmakedefine WITH_DEBUG_XV
|
||||
#cmakedefine WITH_DEBUG_ANDROID_JNI
|
||||
#cmakedefine WITH_DEBUG_RINGBUFFER
|
||||
#endif
|
||||
|
||||
@ -1,16 +1,11 @@
|
||||
Overview
|
||||
========
|
||||
|
||||
The FreeRDP Android port consists of two parts: the Android Java GUI (client/Android)
|
||||
and the JNI bindings (client/Android/jni) which are written in C and wrap FreeRDP to
|
||||
be used with Java. The JNI is directly integrated within FreeRDPs build system.
|
||||
For building the GUI part there are three possibilities:
|
||||
* integrated ant build - have cmake to operate ant and build everything
|
||||
* manual ant build - build JNI with cmake and invoke ant manually for the GUI
|
||||
* IDE builds using your favourite IDE - use cmake for building JNI and your IDE for GUI
|
||||
|
||||
Manual build and IDE build are mostly used for development.
|
||||
|
||||
The FreeRDP Android port consists of three parts:
|
||||
* Android Java GUI (client/Android/Studio)
|
||||
* FreeRDP library and its dependencies
|
||||
* JNI bindings (client/Android/android_freerdp.c
|
||||
and client/Android/Studio/freeRDPCore/src/main/java/com/freerdp/freerdpcore/services/LibFreeRDP.java)
|
||||
|
||||
Build requirements
|
||||
=================
|
||||
@ -19,196 +14,64 @@ For the Android port some additional dependencies need to be fulfilled:
|
||||
|
||||
* for JNI
|
||||
- Android NDK (>= r9)
|
||||
- prebuild static openssl libraries (see below)
|
||||
- prebuild openssl (optionally libjpeg and openh264)
|
||||
|
||||
* for the Java GUI (if build with ant)
|
||||
- ant
|
||||
- Android SDK Tools - version >= 21
|
||||
- Android Support Library (note: make sure ANDROID_APP_TARGET_SDK is set to be at
|
||||
least the API level required by the support library)
|
||||
* for the Java GUI
|
||||
- Android SDK
|
||||
|
||||
FreeRDP requires openssl libraries for building but they are not part of the
|
||||
FreeRDP requires openssl libraries for building but they are not part of the
|
||||
Android NDK and therefore they need to be prebuild manually.
|
||||
Multiple source versions and builds of static openssl libraries are floating around.
|
||||
At the time of writing we have tested and used:
|
||||
https://github.com/bmiklautz/Android-external-openssl-ndk-static
|
||||
https://github.com/akallabeth/openssl-android
|
||||
|
||||
For jpeg support https://github.com/akallabeth/jpeg8d has been tested and used.
|
||||
However, any other static builds should work as well.
|
||||
|
||||
Build openssl and jpeg
|
||||
Build native libraries:
|
||||
======================
|
||||
Set up ANDROID_NDK and ANDROID_SDK to the absolute paths on your machine.
|
||||
From the project root folder run './scripts/android_setup_build_env.sh'
|
||||
This will set up openssl and gprof helper libraries as required for FreeRDP.
|
||||
From the project root run the build script
|
||||
./scripts/android-build-freerdp.sh --ndk <ANDROID_NDK> --sdk <ANDROID_SDK>
|
||||
Set ANDROID_NDK and ANDROID_SDK to the absolute paths on your machine.
|
||||
This will fetch sources from git and build OpenSSL, OpenH264, libJPEG.
|
||||
The native FreeRDP libraries will also be build.
|
||||
|
||||
Currently the default script builds for:
|
||||
* armeabi
|
||||
* armeabi-v7a
|
||||
* x86
|
||||
* mips
|
||||
|
||||
Building
|
||||
========
|
||||
64 bit architectures will be added as soon as the OpenSSL build scripts
|
||||
support the android build for those.
|
||||
|
||||
Integrated build
|
||||
----------------
|
||||
When the script is finished the libraries are ready for android studio to
|
||||
be picked up in client/Android/Studio/freeRDPCore/src/main/jniLibs
|
||||
|
||||
Run the following commands in the top level freerdp directory. Don't
|
||||
forget to set ANDROID_NDK, ANDROID_SDK and FREERDP_EXTERNAL_SSL_PATH
|
||||
to the absolut paths on your machine:
|
||||
Building the APK (Android Studio)
|
||||
================
|
||||
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=cmake/AndroidToolchain.cmake \
|
||||
-DANDROID_NDK="_your_ndk_path_here_" \
|
||||
-DFREERDP_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \
|
||||
-DFREERDP_EXTERNAL_JPEG_PATH="_your_jpeg_build_root_path_" \
|
||||
-DANDROID_SDK="_your_sdk_path_here_" \
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
make
|
||||
* Import the folder client/Android/Studio in Android Studio
|
||||
* You are ready to go
|
||||
|
||||
After that you should have a client/Android/bin/aFreeRDP-debug.apk.
|
||||
|
||||
Manual ant builds
|
||||
-----------------
|
||||
First run cmake to prepare the build and build JNI.
|
||||
Don't forget to set ANDROID_NDK, ANDROID_SDK and FREERDP_EXTERNAL_SSL_PATH
|
||||
to the absolut paths on your machine:
|
||||
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=cmake/AndroidToolchain.cmake \
|
||||
-DANDROID_NDK="_your_ndk_path_here_" \
|
||||
-DFREERDP_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \
|
||||
-DFREERDP_EXTERNAL_JPEG_PATH="_your_jpeg_build_root_path_" \
|
||||
-DANDROID_SDK="_your_sdk_path_here_" -DANDROID_BUILD_JAVA=OFF \
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
make
|
||||
|
||||
Now you can run your favourite ant command in client/Android like this:
|
||||
|
||||
cd client/Android/aFreeRDP
|
||||
ant debug install
|
||||
|
||||
Using an IDE
|
||||
------------
|
||||
Here is an example on how to use Eclipse for developing/building the Java GUI.
|
||||
For this the "Android development tools for Eclipse" are required (available via
|
||||
the eclipse marketplace).
|
||||
|
||||
cmake -DCMAKE_TOOLCHAIN_FILE=cmake/AndroidToolchain.cmake \
|
||||
-DANDROID_NDK="_your_ndk_path_here_" \
|
||||
-DFREERDP_EXTERNAL_SSL_PATH="_your_ssl_build_root_path_" \
|
||||
-DCMAKE_BUILD_TYPE=Debug -DANDROID_BUILD_JAVA=OFF
|
||||
make
|
||||
|
||||
Open Eclipse and choose:
|
||||
File -> Import -> General -> Existing Projects into Workspace
|
||||
|
||||
Browse to the client/Android directory in your FreeRDP folder and click finish.
|
||||
If you get something like "Project 'aFreeRDP' is missing required source
|
||||
folder: 'gen'" just build the project once and you are good to go.
|
||||
|
||||
Side note: If you add -G "Eclipse CDT4 - Unix Makefiles" when running cmake
|
||||
you can also import FreeRDP into Eclipse too. Then you have one Java project and one c/c++
|
||||
project you can work on. This requires CDT to be installed in Eclipse.
|
||||
|
||||
Debugging native code
|
||||
---------------------
|
||||
|
||||
All CMake builds created with -DCMAKE_BUILD_TYPE=Debug will be ready to
|
||||
debug with ndk-gdb.
|
||||
|
||||
Eclipse projects are already configured to allow debugging in either Java
|
||||
or native code, no extra steps required.
|
||||
|
||||
cmake variables
|
||||
===============
|
||||
|
||||
JNI related
|
||||
-----------
|
||||
|
||||
CMAKE_TOOLCHAIN_FILE
|
||||
* the toolchain file to use must be cmake/AndroidToolchain.cmake
|
||||
|
||||
ANDROID_NDK (used from toolchain file)
|
||||
* absolute path to the NDK
|
||||
|
||||
ANDROID_ABI (used from toolchain file)
|
||||
* Android ABI to build for (default is armeabi-v7a)
|
||||
|
||||
FREERDP_EXTERNAL_SSL_PATH (used by FindOpenSSL)
|
||||
* absolut root path to the prebuild static openssl libraries
|
||||
|
||||
FREERDP_EXTERNAL_JPEG_PATH (used by FindJPEG)
|
||||
* absolute root path to the prebuild static jpeg libraries
|
||||
|
||||
WITH_DEBUG_ANDROID_JNI
|
||||
- enable debugging for JNI
|
||||
|
||||
The libraries must be located in obj/local/armeabi/ or obj/local/armeabi-v7a/.
|
||||
Cmake searches in armeabi first then armeabi-v7a. It is possible to build FreeRDP
|
||||
for armeabi-v7a and link against armeabi openssl but not the other way around.
|
||||
Therefore it is suggested to build openssl for armeabi.
|
||||
|
||||
Java GUI related
|
||||
----------------
|
||||
|
||||
ANDROID_BUILD_JAVA (used by client/Android/CMakeLists.txt)
|
||||
* can be ON/OFF (default OFF) whether or not to build the GUI with cmake
|
||||
|
||||
ANDROID_SDK (used by client/Android/CMakeLists.txt)
|
||||
* absolute path to the Android SDK to use
|
||||
|
||||
ANDROID_NDK
|
||||
* absolute path to the Android NDK to use.
|
||||
|
||||
WITH_DEBUG_ANDROID_JNI
|
||||
* enable logcat debug messages for JNI calls.
|
||||
|
||||
WITH_ANDROID_DEBUG_MENU
|
||||
* activate a debug menu in aFreeRDP to enable / disable runtime settings
|
||||
* not available in release.
|
||||
|
||||
WITH_OPENSLES
|
||||
* Enables / disables sound and microphone support for android using OpenSLES
|
||||
|
||||
ANDROID_BUILD_JAVA_DEBUG
|
||||
* Enable / disable debugging code in the java parts of the application.
|
||||
|
||||
ANDROID_APP_VERSION
|
||||
* The version the aFreeRDP-release.apk / aFreeRDP-debug.apk will have.
|
||||
|
||||
ANDROID_APP_TARGET_SDK
|
||||
* The target SDK version of the project.
|
||||
|
||||
ANDROID_APP_MIN_SDK
|
||||
* The lowest supported SDK version
|
||||
|
||||
ANDROID_NATIVE_API_LEVEL
|
||||
* The native API level to compile the native code against.
|
||||
* Should be equal to SDK level.
|
||||
|
||||
This is used to generate local.properties needed by ant. Needs to be set
|
||||
if you build manually with ant or do integrated builds.
|
||||
Building the APK (gradle)
|
||||
================
|
||||
|
||||
* change to directory client/Android/Studio
|
||||
* run ./gradlew build to build
|
||||
* run ./gradlew tasks for other gradle options
|
||||
|
||||
Development
|
||||
===========
|
||||
|
||||
Updating JNI headers
|
||||
--------------------
|
||||
Updating JNI
|
||||
------------
|
||||
|
||||
Whenever the FreeRDP API changes or you need some extra functionality in your Java
|
||||
GUI the JNI needs to be updated. The JNI headers are generated from the compiled
|
||||
Java classes:
|
||||
GUI the JNI needs to be updated.
|
||||
|
||||
* edit client/Android/src/com/freerdp/afreerdp/services/LibFreeRDP.Java to
|
||||
The JNI functions are defined in client/Android/android_freerdp.c
|
||||
Add the new functions to the methods struct.
|
||||
|
||||
* edit client/Android/src/com/freerdp/afreerdp/services/LibFreeRDP.Java to
|
||||
reflect your changes
|
||||
* build the Android Java project as described above
|
||||
* run ./scripts/regenerate_JNI_headers.sh from your FreeRDP checkout top level
|
||||
directory
|
||||
* edit client/Android/android_freerdp.c and adjust the methods struct to reflect
|
||||
the changes made.
|
||||
|
||||
After that you need to implement the functionality in client/Android/jni/android_freerdp.c and add
|
||||
the call to client/Android/jni/generated/android_freerdp_jni.c.
|
||||
After that FreeRDP and the Android package need to be rebuilt to include the latest libfreerdp-android in the package.
|
||||
|
||||
Android CMake related Variables
|
||||
-------------------------------
|
||||
|
||||
ANDROID_APP_TARGET_SDK ... specifies the desired android target SDK, currently 21
|
||||
ANDROID_APP_MIN_SDK ... specifies the minimum android SDK version supported, currently 14
|
||||
ANDROID_APP_GOOGLE_TARGET_SDK ... specifies the minimum google SDK requirement, currently 16
|
||||
|
||||
@ -94,6 +94,18 @@ FREERDP_API int freerdp_client_settings_write_connection_file(const rdpSettings*
|
||||
|
||||
FREERDP_API int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, const char* filename);
|
||||
|
||||
FREERDP_API BOOL client_cli_authenticate(freerdp* instance, char** username, char** password, char** domain);
|
||||
FREERDP_API BOOL client_cli_gw_authenticate(freerdp* instance, char** username, char** password, char** domain);
|
||||
|
||||
FREERDP_API DWORD client_cli_verify_certificate(freerdp* instance, const char* common_name,
|
||||
const char* subject, const char* issuer,
|
||||
const char* fingerprint, BOOL host_mismatch);
|
||||
|
||||
FREERDP_API DWORD client_cli_verify_changed_certificate(freerdp* instance, const char* common_name,
|
||||
const char* subject, const char* issuer,
|
||||
const char* fingerprint,
|
||||
const char* old_subject, const char* old_issuer,
|
||||
const char* old_fingerprint);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -30,18 +30,19 @@ extern "C" {
|
||||
FREERDP_API int freerdp_client_settings_parse_command_line_arguments(
|
||||
rdpSettings* settings, int argc, char** argv, BOOL allowUnknown);
|
||||
FREERDP_API int freerdp_client_settings_command_line_status_print(rdpSettings* settings, int status, int argc, char** argv);
|
||||
FREERDP_API int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings);
|
||||
FREERDP_API BOOL freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings);
|
||||
|
||||
FREERDP_API int freerdp_client_print_version(void);
|
||||
FREERDP_API int freerdp_client_print_command_line_help(int argc, char** argv);
|
||||
FREERDP_API BOOL freerdp_client_print_version(void);
|
||||
FREERDP_API BOOL freerdp_client_print_buildconfig(void);
|
||||
FREERDP_API BOOL freerdp_client_print_command_line_help(int argc, char** argv);
|
||||
|
||||
FREERDP_API int freerdp_parse_username(char* username, char** user, char** domain);
|
||||
FREERDP_API int freerdp_parse_hostname(char* hostname, char** host, int* port);
|
||||
FREERDP_API int freerdp_set_connection_type(rdpSettings* settings, int type);
|
||||
FREERDP_API BOOL freerdp_parse_username(char* username, char** user, char** domain);
|
||||
FREERDP_API BOOL freerdp_parse_hostname(char* hostname, char** host, int* port);
|
||||
FREERDP_API BOOL freerdp_set_connection_type(rdpSettings* settings, int type);
|
||||
|
||||
FREERDP_API int freerdp_client_add_device_channel(rdpSettings* settings, int count, char** params);
|
||||
FREERDP_API int freerdp_client_add_static_channel(rdpSettings* settings, int count, char** params);
|
||||
FREERDP_API int freerdp_client_add_dynamic_channel(rdpSettings* settings, int count, char** params);
|
||||
FREERDP_API BOOL freerdp_client_add_device_channel(rdpSettings* settings, int count, char** params);
|
||||
FREERDP_API BOOL freerdp_client_add_static_channel(rdpSettings* settings, int count, char** params);
|
||||
FREERDP_API BOOL freerdp_client_add_dynamic_channel(rdpSettings* settings, int count, char** params);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -73,10 +73,10 @@ FREERDP_API void region16_init(REGION16 *region);
|
||||
/** @return the number of rectangles of this region16 */
|
||||
FREERDP_API int region16_n_rects(const REGION16 *region);
|
||||
|
||||
/** returns a pointer on rectangles and the number of rectangles in this region.
|
||||
* nbRect can be set to NULL if not interested by the numnber of rectangles.
|
||||
/** returns a pointer to rectangles and the number of rectangles in this region.
|
||||
* nbRects can be set to NULL if not interested in the number of rectangles.
|
||||
* @param region the input region
|
||||
* @param nbRects a pointer that will be filled with the number of rectangles
|
||||
* @param nbRects if non-NULL returns the number of rectangles
|
||||
* @return a pointer on the rectangles
|
||||
*/
|
||||
FREERDP_API const RECTANGLE_16 *region16_rects(const REGION16 *region, int *nbRects);
|
||||
|
||||
@ -25,13 +25,8 @@
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/rc4.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800f)
|
||||
#define D2I_X509_CONST const
|
||||
@ -43,31 +38,7 @@
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
|
||||
struct crypto_sha1_struct
|
||||
{
|
||||
SHA_CTX sha_ctx;
|
||||
};
|
||||
|
||||
struct crypto_md5_struct
|
||||
{
|
||||
MD5_CTX md5_ctx;
|
||||
};
|
||||
|
||||
struct crypto_rc4_struct
|
||||
{
|
||||
RC4_KEY rc4_key;
|
||||
};
|
||||
|
||||
struct crypto_des3_struct
|
||||
{
|
||||
EVP_CIPHER_CTX des3_ctx;
|
||||
};
|
||||
|
||||
struct crypto_hmac_struct
|
||||
{
|
||||
HMAC_CTX hmac_ctx;
|
||||
};
|
||||
#include <freerdp/crypto/certificate.h>
|
||||
|
||||
struct crypto_cert_struct
|
||||
{
|
||||
@ -79,47 +50,8 @@ struct crypto_cert_struct
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CRYPTO_SHA1_DIGEST_LENGTH SHA_DIGEST_LENGTH
|
||||
typedef struct crypto_sha1_struct* CryptoSha1;
|
||||
|
||||
FREERDP_API CryptoSha1 crypto_sha1_init(void);
|
||||
FREERDP_API void crypto_sha1_update(CryptoSha1 sha1, const BYTE* data, UINT32 length);
|
||||
FREERDP_API void crypto_sha1_final(CryptoSha1 sha1, BYTE* out_data);
|
||||
|
||||
#define CRYPTO_MD5_DIGEST_LENGTH MD5_DIGEST_LENGTH
|
||||
typedef struct crypto_md5_struct* CryptoMd5;
|
||||
|
||||
FREERDP_API CryptoMd5 crypto_md5_init(void);
|
||||
FREERDP_API void crypto_md5_update(CryptoMd5 md5, const BYTE* data, UINT32 length);
|
||||
FREERDP_API void crypto_md5_final(CryptoMd5 md5, BYTE* out_data);
|
||||
|
||||
typedef struct crypto_rc4_struct* CryptoRc4;
|
||||
|
||||
FREERDP_API CryptoRc4 crypto_rc4_init(const BYTE* key, UINT32 length);
|
||||
FREERDP_API void crypto_rc4(CryptoRc4 rc4, UINT32 length, const BYTE* in_data, BYTE* out_data);
|
||||
FREERDP_API void crypto_rc4_free(CryptoRc4 rc4);
|
||||
|
||||
typedef struct crypto_des3_struct* CryptoDes3;
|
||||
|
||||
FREERDP_API CryptoDes3 crypto_des3_encrypt_init(const BYTE* key, const BYTE* ivec);
|
||||
FREERDP_API CryptoDes3 crypto_des3_decrypt_init(const BYTE* key, const BYTE* ivec);
|
||||
FREERDP_API BOOL crypto_des3_encrypt(CryptoDes3 des3, UINT32 length, const BYTE *in_data, BYTE *out_data);
|
||||
FREERDP_API BOOL crypto_des3_decrypt(CryptoDes3 des3, UINT32 length, const BYTE *in_data, BYTE* out_data);
|
||||
FREERDP_API void crypto_des3_free(CryptoDes3 des3);
|
||||
|
||||
typedef struct crypto_hmac_struct* CryptoHmac;
|
||||
|
||||
FREERDP_API CryptoHmac crypto_hmac_new(void);
|
||||
FREERDP_API BOOL crypto_hmac_sha1_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
||||
FREERDP_API BOOL crypto_hmac_md5_init(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
||||
FREERDP_API void crypto_hmac_update(CryptoHmac hmac, const BYTE *data, UINT32 length);
|
||||
FREERDP_API void crypto_hmac_final(CryptoHmac hmac, BYTE *out_data, UINT32 length);
|
||||
FREERDP_API void crypto_hmac_free(CryptoHmac hmac);
|
||||
|
||||
typedef struct crypto_cert_struct* CryptoCert;
|
||||
|
||||
#include <freerdp/crypto/certificate.h>
|
||||
|
||||
FREERDP_API CryptoCert crypto_cert_read(BYTE* data, UINT32 length);
|
||||
FREERDP_API char* crypto_cert_fingerprint(X509* xcert);
|
||||
FREERDP_API char* crypto_cert_subject(X509* xcert);
|
||||
@ -146,7 +78,6 @@ FREERDP_API int crypto_rsa_public_decrypt(const BYTE* input, int length, UINT32
|
||||
FREERDP_API int crypto_rsa_private_encrypt(const BYTE* input, int length, UINT32 key_length, const BYTE* modulus, const BYTE* private_exponent, BYTE* output);
|
||||
FREERDP_API int crypto_rsa_private_decrypt(const BYTE* input, int length, UINT32 key_length, const BYTE* modulus, const BYTE* private_exponent, BYTE* output);
|
||||
FREERDP_API void crypto_reverse(BYTE* data, int length);
|
||||
FREERDP_API void crypto_nonce(BYTE* nonce, int size);
|
||||
|
||||
FREERDP_API char* crypto_base64_encode(const BYTE* data, int length);
|
||||
FREERDP_API void crypto_base64_decode(const char* enc_data, int length, BYTE** dec_data, int* res_length);
|
||||
|
||||
@ -89,7 +89,7 @@ struct rdp_tls
|
||||
#endif
|
||||
|
||||
FREERDP_API int tls_connect(rdpTls* tls, BIO *underlying);
|
||||
FREERDP_API BOOL tls_accept(rdpTls* tls, BIO *underlying, const char* cert_file, const char* privatekey_file);
|
||||
FREERDP_API BOOL tls_accept(rdpTls* tls, BIO *underlying, rdpSettings *settings);
|
||||
FREERDP_API BOOL tls_send_alert(rdpTls* tls);
|
||||
|
||||
FREERDP_API int tls_write_all(rdpTls* tls, const BYTE* data, int length);
|
||||
|
||||
@ -65,13 +65,55 @@ typedef void (*pContextFree)(freerdp* instance, rdpContext* context);
|
||||
typedef BOOL (*pPreConnect)(freerdp* instance);
|
||||
typedef BOOL (*pPostConnect)(freerdp* instance);
|
||||
typedef void (*pPostDisconnect)(freerdp* instance);
|
||||
typedef BOOL (*pAuthenticate)(freerdp* instance, char** username, char** password, char** domain);
|
||||
typedef BOOL (*pVerifyCertificate)(freerdp* instance, char* subject, char* issuer, char* fingerprint);
|
||||
typedef BOOL (*pVerifyChangedCertificate)(freerdp* instance, char* subject,
|
||||
char* issuer, char* new_fingerprint,
|
||||
char* old_subject, char* old_issuer,
|
||||
char* old_fingerprint);
|
||||
typedef int (*pVerifyX509Certificate)(freerdp* instance, BYTE* data, int length, const char* hostname, int port, DWORD flags);
|
||||
typedef BOOL (*pAuthenticate)(freerdp* instance, char** username,
|
||||
char** password, char** domain);
|
||||
|
||||
/** @brief Callback used if user interaction is required to accept
|
||||
* an unknown certificate.
|
||||
*
|
||||
* @param common_name The certificate registered hostname.
|
||||
* @param subject The common name of the certificate.
|
||||
* @param issuer The issuer of the certificate.
|
||||
* @param fingerprint The fingerprint of the certificate.
|
||||
* @param host_mismatch A flag indicating the certificate
|
||||
* subject does not match the host connecting to.
|
||||
*
|
||||
* @return 1 to accept and store a certificate, 2 to accept
|
||||
* a certificate only for this session, 0 otherwise.
|
||||
*/
|
||||
typedef DWORD (*pVerifyCertificate)(freerdp* instance,
|
||||
const char* common_name,
|
||||
const char* subject,
|
||||
const char* issuer,
|
||||
const char* fingerprint,
|
||||
BOOL host_mismatch);
|
||||
|
||||
/** @brief Callback used if user interaction is required to accept
|
||||
* a changed certificate.
|
||||
*
|
||||
* @param common_name The certificate registered hostname.
|
||||
* @param subject The common name of the new certificate.
|
||||
* @param issuer The issuer of the new certificate.
|
||||
* @param fingerprint The fingerprint of the new certificate.
|
||||
* @param old_subject The common name of the old certificate.
|
||||
* @param old_issuer The issuer of the new certificate.
|
||||
* @param old_fingerprint The fingerprint of the old certificate.
|
||||
*
|
||||
* @return 1 to accept and store a certificate, 2 to accept
|
||||
* a certificate only for this session, 0 otherwise.
|
||||
*/
|
||||
|
||||
typedef DWORD (*pVerifyChangedCertificate)(freerdp* instance,
|
||||
const char* common_name,
|
||||
const char* subject,
|
||||
const char* issuer,
|
||||
const char* new_fingerprint,
|
||||
const char* old_subject,
|
||||
const char* old_issuer,
|
||||
const char* old_fingerprint);
|
||||
typedef int (*pVerifyX509Certificate)(freerdp* instance, BYTE* data,
|
||||
int length, const char* hostname,
|
||||
int port, DWORD flags);
|
||||
|
||||
typedef int (*pLogonErrorInfo)(freerdp* instance, UINT32 data, UINT32 type);
|
||||
|
||||
@ -272,6 +314,7 @@ FREERDP_API void freerdp_get_version(int* major, int* minor, int* revision);
|
||||
FREERDP_API const char* freerdp_get_version_string(void);
|
||||
FREERDP_API const char* freerdp_get_build_date(void);
|
||||
FREERDP_API const char* freerdp_get_build_revision(void);
|
||||
FREERDP_API const char* freerdp_get_build_config(void);
|
||||
|
||||
FREERDP_API freerdp* freerdp_new(void);
|
||||
FREERDP_API void freerdp_free(freerdp* instance);
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Time Zone Redirection
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_LOCALE_TIMEZONE_H
|
||||
#define FREERDP_LOCALE_TIMEZONE_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/settings.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FREERDP_API void freerdp_time_zone_detect(TIME_ZONE_INFO* clientTimeZone);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FREERDP_LOCALE_TIMEZONE_H */
|
||||
@ -277,7 +277,9 @@ typedef struct _SHADOW_MSG_OUT_AUDIO_OUT_VOLUME SHADOW_MSG_OUT_AUDIO_OUT_VOLUME;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FREERDP_API void shadow_subsystem_set_entry_builtin(const char* name);
|
||||
FREERDP_API void shadow_subsystem_set_entry(pfnShadowSubsystemEntry pEntry);
|
||||
|
||||
FREERDP_API int shadow_subsystem_pointer_convert_alpha_pointer_data(BYTE* pixels, BOOL premultiplied,
|
||||
UINT32 width, UINT32 height, SHADOW_MSG_OUT_POINTER_ALPHA_UPDATE* pointerColor);
|
||||
|
||||
|
||||
48
include/freerdp/session.h
Normal file
48
include/freerdp/session.h
Normal file
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Client Session Info
|
||||
*
|
||||
* Copyright 2016 David FORT <contact@hardening-consulting.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef __FREERDP_SESSION_H__
|
||||
#define __FREERDP_SESSION_H__
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
/* Logon Information Types */
|
||||
#define INFO_TYPE_LOGON 0x00000000
|
||||
#define INFO_TYPE_LOGON_LONG 0x00000001
|
||||
#define INFO_TYPE_LOGON_PLAIN_NOTIFY 0x00000002
|
||||
#define INFO_TYPE_LOGON_EXTENDED_INF 0x00000003
|
||||
|
||||
struct rdp_logon_info {
|
||||
UINT32 sessionId;
|
||||
char *username;
|
||||
char *domain;
|
||||
};
|
||||
typedef struct rdp_logon_info logon_info;
|
||||
|
||||
struct rdp_logon_info_ex {
|
||||
BOOL haveCookie;
|
||||
UINT32 LogonId;
|
||||
BYTE ArcRandomBits[16];
|
||||
|
||||
BOOL haveErrorInfo;
|
||||
UINT32 ErrorNotificationType;
|
||||
UINT32 ErrorNotificationData;
|
||||
};
|
||||
typedef struct rdp_logon_info_ex logon_info_ex;
|
||||
|
||||
#endif /* __FREERDP_SESSION_H__ */
|
||||
@ -4,6 +4,7 @@
|
||||
*
|
||||
* Copyright 2009-2011 Jay Sorg
|
||||
* Copyright 2010-2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -21,6 +22,8 @@
|
||||
#ifndef FREERDP_SETTINGS_H
|
||||
#define FREERDP_SETTINGS_H
|
||||
|
||||
#include <winpr/timezone.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
|
||||
@ -269,32 +272,6 @@ typedef struct _TARGET_NET_ADDRESS TARGET_NET_ADDRESS;
|
||||
#define ORIENTATION_LANDSCAPE_FLIPPED 180
|
||||
#define ORIENTATION_PORTRAIT_FLIPPED 270
|
||||
|
||||
/* SYSTEM_TIME */
|
||||
typedef struct
|
||||
{
|
||||
UINT16 wYear;
|
||||
UINT16 wMonth;
|
||||
UINT16 wDayOfWeek;
|
||||
UINT16 wDay;
|
||||
UINT16 wHour;
|
||||
UINT16 wMinute;
|
||||
UINT16 wSecond;
|
||||
UINT16 wMilliseconds;
|
||||
} SYSTEM_TIME;
|
||||
|
||||
/* TIME_ZONE_INFORMATION */
|
||||
struct _TIME_ZONE_INFO
|
||||
{
|
||||
UINT32 bias;
|
||||
char standardName[32];
|
||||
SYSTEM_TIME standardDate;
|
||||
UINT32 standardBias;
|
||||
char daylightName[32];
|
||||
SYSTEM_TIME daylightDate;
|
||||
UINT32 daylightBias;
|
||||
};
|
||||
typedef struct _TIME_ZONE_INFO TIME_ZONE_INFO;
|
||||
|
||||
/* ARC_CS_PRIVATE_PACKET */
|
||||
typedef struct
|
||||
{
|
||||
@ -655,6 +632,10 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_RdpServerRsaKey 1413
|
||||
#define FreeRDP_RdpServerCertificate 1414
|
||||
#define FreeRDP_ExternalCertificateManagement 1415
|
||||
#define FreeRDP_CertificateContent 1416
|
||||
#define FreeRDP_PrivateKeyContent 1417
|
||||
#define FreeRDP_RdpKeyContent 1418
|
||||
|
||||
#define FreeRDP_Workarea 1536
|
||||
#define FreeRDP_Fullscreen 1537
|
||||
#define FreeRDP_PercentScreen 1538
|
||||
@ -973,7 +954,7 @@ struct rdp_settings
|
||||
UINT64 padding0896[896 - 837]; /* 837 */
|
||||
|
||||
/* Client Info (Time Zone) */
|
||||
ALIGN64 TIME_ZONE_INFO* ClientTimeZone; /* 896 */
|
||||
ALIGN64 LPTIME_ZONE_INFORMATION ClientTimeZone; /* 896 */
|
||||
ALIGN64 char* DynamicDSTTimeZoneKeyName; /* 897 */
|
||||
ALIGN64 BOOL DynamicDaylightTimeDisabled; /* 898 */
|
||||
UINT64 padding0960[960 - 899]; /* 899 */
|
||||
@ -1071,7 +1052,10 @@ struct rdp_settings
|
||||
ALIGN64 rdpRsaKey* RdpServerRsaKey; /* 1413 */
|
||||
ALIGN64 rdpCertificate* RdpServerCertificate; /* 1414 */
|
||||
ALIGN64 BOOL ExternalCertificateManagement; /* 1415 */
|
||||
UINT64 padding1472[1472 - 1416]; /* 1416 */
|
||||
ALIGN64 char *CertificateContent; /* 1416 */
|
||||
ALIGN64 char *PrivateKeyContent; /* 1417 */
|
||||
ALIGN64 char* RdpKeyContent; /* 1418 */
|
||||
UINT64 padding1472[1472 - 1419]; /* 1419 */
|
||||
UINT64 padding1536[1536 - 1472]; /* 1472 */
|
||||
|
||||
/**
|
||||
@ -1452,6 +1436,7 @@ FREERDP_API int freerdp_addin_replace_argument_value(ADDIN_ARGV* args, char* pre
|
||||
|
||||
FREERDP_API BOOL freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device);
|
||||
FREERDP_API RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char* name);
|
||||
FREERDP_API RDPDR_DEVICE* freerdp_device_collection_find_type(rdpSettings* settings, UINT32 type);
|
||||
FREERDP_API RDPDR_DEVICE* freerdp_device_clone(RDPDR_DEVICE* device);
|
||||
FREERDP_API void freerdp_device_collection_free(rdpSettings* settings);
|
||||
|
||||
|
||||
@ -148,6 +148,7 @@ typedef BOOL (*pSetKeyboardIndicators)(rdpContext* context, UINT16 led_flags);
|
||||
|
||||
typedef BOOL (*pRefreshRect)(rdpContext* context, BYTE count, RECTANGLE_16* areas);
|
||||
typedef BOOL (*pSuppressOutput)(rdpContext* context, BYTE allow, RECTANGLE_16* area);
|
||||
typedef BOOL (*pRemoteMonitors)(rdpContext* context, UINT32 count, const MONITOR_DEF *monitors);
|
||||
|
||||
typedef BOOL (*pSurfaceCommand)(rdpContext* context, wStream* s);
|
||||
typedef BOOL (*pSurfaceBits)(rdpContext* context, SURFACE_BITS_COMMAND* surfaceBitsCommand);
|
||||
@ -155,6 +156,8 @@ typedef BOOL (*pSurfaceFrameMarker)(rdpContext* context, SURFACE_FRAME_MARKER* s
|
||||
typedef BOOL (*pSurfaceFrameBits)(rdpContext* context, SURFACE_BITS_COMMAND* cmd, BOOL first, BOOL last, UINT32 frameId);
|
||||
typedef BOOL (*pSurfaceFrameAcknowledge)(rdpContext* context, UINT32 frameId);
|
||||
|
||||
typedef BOOL (*pSaveSessionInfo)(rdpContext *context, UINT32 type, void *data);
|
||||
|
||||
struct rdp_update
|
||||
{
|
||||
rdpContext* context; /* 0 */
|
||||
@ -180,14 +183,16 @@ struct rdp_update
|
||||
|
||||
pRefreshRect RefreshRect; /* 48 */
|
||||
pSuppressOutput SuppressOutput; /* 49 */
|
||||
UINT32 paddingD[64 - 50]; /* 50 */
|
||||
pRemoteMonitors RemoteMonitors; /* 50 */
|
||||
UINT32 paddingD[64 - 51]; /* 51 */
|
||||
|
||||
pSurfaceCommand SurfaceCommand; /* 64 */
|
||||
pSurfaceBits SurfaceBits; /* 65 */
|
||||
pSurfaceFrameMarker SurfaceFrameMarker; /* 66 */
|
||||
pSurfaceFrameBits SurfaceFrameBits; /* 67 */
|
||||
pSurfaceFrameAcknowledge SurfaceFrameAcknowledge; /* 68 */
|
||||
UINT32 paddingE[80 - 69]; /* 69 */
|
||||
pSaveSessionInfo SaveSessionInfo; /* 69 */
|
||||
UINT32 paddingE[80 - 70]; /* 70 */
|
||||
|
||||
/* internal */
|
||||
|
||||
|
||||
2
libfreerdp/cache/glyph.c
vendored
2
libfreerdp/cache/glyph.c
vendored
@ -57,7 +57,7 @@ void update_process_glyph(rdpContext* context, BYTE* data, int* index,
|
||||
|
||||
if (offset & 0x80)
|
||||
{
|
||||
offset = data[*index + 1] | ((int)((char)data[*index + 2]) << 8);
|
||||
offset = data[*index + 1] | ((int)((signed char)data[*index + 2]) << 8);
|
||||
(*index)++;
|
||||
(*index)++;
|
||||
}
|
||||
|
||||
@ -26,10 +26,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <freerdp/codec/nsc.h>
|
||||
|
||||
@ -25,10 +25,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <freerdp/codec/nsc.h>
|
||||
|
||||
@ -94,17 +94,17 @@ const RECTANGLE_16 *region16_rects(const REGION16 *region, int *nbRects)
|
||||
REGION16_DATA *data;
|
||||
|
||||
assert(region);
|
||||
assert(region->data);
|
||||
|
||||
data = region->data;
|
||||
if (!data)
|
||||
{
|
||||
if (nbRects)
|
||||
*nbRects = 0;
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*nbRects = data->nbRects;
|
||||
if (nbRects)
|
||||
*nbRects = data->nbRects;
|
||||
return (RECTANGLE_16 *)(data + 1);
|
||||
}
|
||||
|
||||
|
||||
@ -28,10 +28,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/tchar.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
|
||||
@ -22,16 +22,13 @@
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/crypto.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/windows.h>
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/rc4.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
@ -523,7 +520,7 @@ char* freerdp_assistance_generate_pass_stub(DWORD flags)
|
||||
* Example: WB^6HsrIaFmEpi
|
||||
*/
|
||||
|
||||
RAND_bytes((BYTE*) nums, sizeof(nums));
|
||||
winpr_RAND((BYTE*) nums, sizeof(nums));
|
||||
|
||||
passStub[0] = set1[nums[0] % sizeof(set1)]; /* character 0 */
|
||||
passStub[1] = set2[nums[1] % sizeof(set2)]; /* character 1 */
|
||||
@ -547,11 +544,11 @@ char* freerdp_assistance_generate_pass_stub(DWORD flags)
|
||||
BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* passStub, int* pEncryptedSize)
|
||||
{
|
||||
int status;
|
||||
MD5_CTX md5Ctx;
|
||||
WINPR_MD5_CTX md5Ctx;
|
||||
int cbPasswordW;
|
||||
int cbPassStubW;
|
||||
int EncryptedSize;
|
||||
BYTE PasswordHash[16];
|
||||
BYTE PasswordHash[WINPR_MD5_DIGEST_LENGTH];
|
||||
EVP_CIPHER_CTX rc4Ctx;
|
||||
BYTE* pbIn, *pbOut;
|
||||
int cbOut, cbIn, cbFinal;
|
||||
@ -565,14 +562,29 @@ BYTE* freerdp_assistance_encrypt_pass_stub(const char* password, const char* pas
|
||||
|
||||
cbPasswordW = (status - 1) * 2;
|
||||
|
||||
MD5_Init(&md5Ctx);
|
||||
MD5_Update(&md5Ctx, PasswordW, cbPasswordW);
|
||||
MD5_Final((void*) PasswordHash, &md5Ctx);
|
||||
if (!winpr_MD5_Init(&md5Ctx))
|
||||
{
|
||||
free (PasswordW);
|
||||
return NULL;
|
||||
}
|
||||
if (!winpr_MD5_Update(&md5Ctx, (BYTE*)PasswordW, cbPasswordW))
|
||||
{
|
||||
free (PasswordW);
|
||||
return NULL;
|
||||
}
|
||||
if (!winpr_MD5_Final(&md5Ctx, (BYTE*) PasswordHash, sizeof(PasswordHash)))
|
||||
{
|
||||
free (PasswordW);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
status = ConvertToUnicode(CP_UTF8, 0, passStub, -1, &PassStubW, 0);
|
||||
|
||||
if (status <= 0)
|
||||
{
|
||||
free (PasswordW);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cbPassStubW = (status - 1) * 2;
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
* Settings Management
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2016 Armin Novak <armin.novak@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@ -208,6 +209,22 @@ RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char*
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RDPDR_DEVICE* freerdp_device_collection_find_type(rdpSettings* settings, UINT32 type)
|
||||
{
|
||||
UINT32 index;
|
||||
RDPDR_DEVICE* device;
|
||||
|
||||
for (index = 0; index < settings->DeviceCount; index++)
|
||||
{
|
||||
device = (RDPDR_DEVICE*) settings->DeviceArray[index];
|
||||
|
||||
if (device->Type == type)
|
||||
return device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RDPDR_DEVICE* freerdp_device_clone(RDPDR_DEVICE* device)
|
||||
{
|
||||
if (device->Type == RDPDR_DTYP_FILESYSTEM)
|
||||
@ -2381,6 +2398,15 @@ char* freerdp_get_param_string(rdpSettings* settings, int id)
|
||||
case FreeRDP_RdpKeyFile:
|
||||
return settings->RdpKeyFile;
|
||||
|
||||
case FreeRDP_CertificateContent:
|
||||
return settings->CertificateContent;
|
||||
|
||||
case FreeRDP_PrivateKeyContent:
|
||||
return settings->PrivateKeyContent;
|
||||
|
||||
case FreeRDP_RdpKeyContent:
|
||||
return settings->RdpKeyContent;
|
||||
|
||||
case FreeRDP_WindowTitle:
|
||||
return settings->WindowTitle;
|
||||
|
||||
@ -2551,6 +2577,18 @@ int freerdp_set_param_string(rdpSettings* settings, int id, const char* param)
|
||||
tmp = &settings->PrivateKeyFile;
|
||||
break;
|
||||
|
||||
case FreeRDP_CertificateContent:
|
||||
tmp = &settings->CertificateContent;
|
||||
break;
|
||||
|
||||
case FreeRDP_PrivateKeyContent:
|
||||
tmp = &settings->PrivateKeyContent;
|
||||
break;
|
||||
|
||||
case FreeRDP_RdpKeyContent:
|
||||
tmp = &settings->RdpKeyContent;
|
||||
break;
|
||||
|
||||
case FreeRDP_RdpKeyFile:
|
||||
tmp = &settings->RdpKeyFile;
|
||||
break;
|
||||
|
||||
@ -364,9 +364,34 @@ BOOL rdp_server_accept_client_control_pdu(rdpRdp* rdp, wStream* s)
|
||||
|
||||
BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
rdpSettings *settings = rdp->settings;
|
||||
|
||||
if (!rdp_recv_client_font_list_pdu(s))
|
||||
return FALSE;
|
||||
|
||||
if (settings->SupportMonitorLayoutPdu && settings->MonitorCount)
|
||||
{
|
||||
/* client supports the monitorLayout PDU, let's send him the monitors if any */
|
||||
wStream *st;
|
||||
BOOL r;
|
||||
|
||||
st = rdp_data_pdu_init(rdp);
|
||||
if (!st)
|
||||
return FALSE;
|
||||
|
||||
if (!rdp_write_monitor_layout_pdu(st, settings->MonitorCount, settings->MonitorDefArray))
|
||||
{
|
||||
Stream_Free(st, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
r = rdp_send_data_pdu(rdp, st, DATA_PDU_TYPE_MONITOR_LAYOUT, 0);
|
||||
Stream_Free(st, TRUE);
|
||||
|
||||
if (!r)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!rdp_send_server_font_map_pdu(rdp))
|
||||
return FALSE;
|
||||
|
||||
|
||||
@ -21,6 +21,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <winpr/crypto.h>
|
||||
|
||||
#include "autodetect.h"
|
||||
|
||||
#define RDP_RTT_REQUEST_TYPE_CONTINUOUS 0x0001
|
||||
@ -173,7 +175,7 @@ BOOL autodetect_send_bandwidth_measure_payload(rdpContext* context, UINT16 paylo
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RAND_bytes(buffer, payloadLength);
|
||||
winpr_RAND(buffer, payloadLength);
|
||||
Stream_Write(s, buffer, payloadLength);
|
||||
|
||||
bResult = rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ);
|
||||
@ -225,7 +227,7 @@ static BOOL autodetect_send_bandwidth_measure_stop(rdpContext* context, UINT16 p
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RAND_bytes(buffer, payloadLength);
|
||||
winpr_RAND(buffer, payloadLength);
|
||||
Stream_Write(s, buffer, payloadLength);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -169,10 +169,10 @@
|
||||
|
||||
BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId);
|
||||
BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s);
|
||||
void rdp_write_demand_active(wStream* s, rdpSettings* settings);
|
||||
BOOL rdp_write_demand_active(wStream* s, rdpSettings* settings);
|
||||
BOOL rdp_send_demand_active(rdpRdp* rdp);
|
||||
BOOL rdp_recv_confirm_active(rdpRdp* rdp, wStream* s);
|
||||
void rdp_write_confirm_active(wStream* s, rdpSettings* settings);
|
||||
BOOL rdp_write_confirm_active(wStream* s, rdpSettings* settings);
|
||||
BOOL rdp_send_confirm_active(rdpRdp* rdp);
|
||||
|
||||
#endif /* __CAPABILITIES_H */
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/crypto.h>
|
||||
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
@ -398,18 +399,17 @@ static BOOL certificate_process_server_public_signature(rdpCertificate* certific
|
||||
const BYTE* sigdata, int sigdatalen, wStream* s, UINT32 siglen)
|
||||
{
|
||||
int i, sum;
|
||||
CryptoMd5 md5ctx;
|
||||
WINPR_MD5_CTX md5ctx;
|
||||
BYTE sig[TSSK_KEY_LENGTH];
|
||||
BYTE encsig[TSSK_KEY_LENGTH + 8];
|
||||
BYTE md5hash[CRYPTO_MD5_DIGEST_LENGTH];
|
||||
BYTE md5hash[WINPR_MD5_DIGEST_LENGTH];
|
||||
|
||||
md5ctx = crypto_md5_init();
|
||||
|
||||
if (!md5ctx)
|
||||
return FALSE;
|
||||
|
||||
crypto_md5_update(md5ctx, sigdata, sigdatalen);
|
||||
crypto_md5_final(md5ctx, md5hash);
|
||||
if (!winpr_MD5_Init(&md5ctx))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5ctx, sigdata, sigdatalen))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Final(&md5ctx, md5hash, sizeof(md5hash)))
|
||||
return FALSE;
|
||||
Stream_Read(s, encsig, siglen);
|
||||
|
||||
/* Last 8 bytes shall be all zero. */
|
||||
@ -662,54 +662,22 @@ BOOL certificate_read_server_certificate(rdpCertificate* certificate, BYTE* serv
|
||||
return ret;
|
||||
}
|
||||
|
||||
rdpRsaKey* key_new(const char* keyfile)
|
||||
rdpRsaKey* key_new_from_content(const char *keycontent, const char *keyfile)
|
||||
{
|
||||
BIO* bio = NULL;
|
||||
FILE* fp = NULL;
|
||||
RSA* rsa = NULL;
|
||||
int length;
|
||||
BYTE* buffer = NULL;
|
||||
rdpRsaKey* key = NULL;
|
||||
|
||||
key = (rdpRsaKey*) calloc(1, sizeof(rdpRsaKey));
|
||||
|
||||
if (!key)
|
||||
return NULL;
|
||||
|
||||
fp = fopen(keyfile, "r+b");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to open RSA key file %s: %s.", keyfile, strerror(errno));
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (fseek(fp, 0, SEEK_END) < 0)
|
||||
goto out_free;
|
||||
if ((length = ftell(fp)) < 0)
|
||||
goto out_free;
|
||||
if (fseek(fp, 0, SEEK_SET) < 0)
|
||||
goto out_free;
|
||||
|
||||
buffer = (BYTE*) malloc(length);
|
||||
|
||||
if (!buffer)
|
||||
goto out_free;
|
||||
|
||||
if (fread((void*) buffer, length, 1, fp) != 1)
|
||||
goto out_free;
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
|
||||
bio = BIO_new_mem_buf((void*) buffer, length);
|
||||
|
||||
bio = BIO_new_mem_buf((void *)keycontent, strlen(keycontent));
|
||||
if (!bio)
|
||||
goto out_free;
|
||||
|
||||
rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
|
||||
BIO_free(bio);
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
|
||||
if (!rsa)
|
||||
{
|
||||
@ -764,11 +732,50 @@ out_free_modulus:
|
||||
free(key->Modulus);
|
||||
out_free_rsa:
|
||||
RSA_free(rsa);
|
||||
out_free:
|
||||
free(key);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
rdpRsaKey* key_new(const char* keyfile)
|
||||
{
|
||||
FILE* fp = NULL;
|
||||
int length;
|
||||
char* buffer = NULL;
|
||||
rdpRsaKey* key = NULL;
|
||||
|
||||
fp = fopen(keyfile, "r+b");
|
||||
if (!fp)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to open RSA key file %s: %s.", keyfile, strerror(errno));
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (fseek(fp, 0, SEEK_END) < 0)
|
||||
goto out_free;
|
||||
if ((length = ftell(fp)) < 0)
|
||||
goto out_free;
|
||||
if (fseek(fp, 0, SEEK_SET) < 0)
|
||||
goto out_free;
|
||||
|
||||
buffer = (char *)malloc(length + 1);
|
||||
if (!buffer)
|
||||
goto out_free;
|
||||
|
||||
if (fread((void*) buffer, length, 1, fp) != 1)
|
||||
goto out_free;
|
||||
fclose(fp);
|
||||
buffer[length] = '\0';
|
||||
|
||||
key = key_new_from_content(buffer, keyfile);
|
||||
free(buffer);
|
||||
return key;
|
||||
|
||||
out_free:
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
free(buffer);
|
||||
free(key);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -59,6 +59,7 @@ rdpCertificate* certificate_new(void);
|
||||
void certificate_free(rdpCertificate* certificate);
|
||||
|
||||
rdpRsaKey* key_new(const char *keyfile);
|
||||
rdpRsaKey* key_new_from_content(const char *keycontent, const char *keyfile);
|
||||
void key_free(rdpRsaKey* key);
|
||||
|
||||
#define CERTIFICATE_TAG FREERDP_TAG("core.certificate")
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#include "transport.h"
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/crypto.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/error.h>
|
||||
@ -312,8 +313,6 @@ BOOL rdp_client_disconnect(rdpRdp* rdp)
|
||||
{
|
||||
BOOL status;
|
||||
|
||||
ResetEvent(rdp->context->abortEvent);
|
||||
|
||||
if (rdp->settingsCopy)
|
||||
{
|
||||
freerdp_settings_free(rdp->settingsCopy);
|
||||
@ -438,7 +437,7 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
||||
if (!settings->ClientRandom)
|
||||
return FALSE;
|
||||
|
||||
crypto_nonce(settings->ClientRandom, settings->ClientRandomLength);
|
||||
winpr_RAND(settings->ClientRandom, settings->ClientRandomLength);
|
||||
key_len = settings->RdpServerCertificate->cert_info.ModulusLength;
|
||||
mod = settings->RdpServerCertificate->cert_info.Modulus;
|
||||
exp = settings->RdpServerCertificate->cert_info.exponent;
|
||||
@ -491,20 +490,26 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
||||
|
||||
if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
|
||||
rdp->fips_encrypt = winpr_Cipher_New( WINPR_CIPHER_DES_EDE3_CBC,
|
||||
WINPR_ENCRYPT,
|
||||
rdp->fips_encrypt_key,
|
||||
fips_ivec);
|
||||
if (!rdp->fips_encrypt)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate des3 encrypt key");
|
||||
goto end;
|
||||
}
|
||||
rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);
|
||||
rdp->fips_decrypt = winpr_Cipher_New(WINPR_CIPHER_DES_EDE3_CBC,
|
||||
WINPR_DECRYPT,
|
||||
rdp->fips_decrypt_key,
|
||||
fips_ivec);
|
||||
if (!rdp->fips_decrypt)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate des3 decrypt key");
|
||||
goto end;
|
||||
}
|
||||
|
||||
rdp->fips_hmac = crypto_hmac_new();
|
||||
rdp->fips_hmac = calloc(1, sizeof(WINPR_HMAC_CTX));
|
||||
if (!rdp->fips_hmac)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate fips hmac");
|
||||
@ -514,22 +519,27 @@ static BOOL rdp_client_establish_keys(rdpRdp* rdp)
|
||||
goto end;
|
||||
}
|
||||
|
||||
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
|
||||
if (!rdp->rc4_decrypt_key)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate rc4 decrypt key");
|
||||
rdp->rc4_decrypt_key = winpr_RC4_New(rdp->decrypt_key, rdp->rc4_key_len);
|
||||
rdp->rc4_encrypt_key = winpr_RC4_New(rdp->encrypt_key, rdp->rc4_key_len);
|
||||
if (!rdp->rc4_decrypt_key || !rdp->rc4_encrypt_key)
|
||||
goto end;
|
||||
}
|
||||
|
||||
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
|
||||
if (!rdp->rc4_encrypt_key)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate rc4 encrypt key");
|
||||
goto end;
|
||||
}
|
||||
ret = TRUE;
|
||||
end:
|
||||
free(crypt_client_random);
|
||||
if (!ret)
|
||||
{
|
||||
winpr_Cipher_Free(rdp->fips_decrypt);
|
||||
winpr_Cipher_Free(rdp->fips_encrypt);
|
||||
winpr_RC4_Free(rdp->rc4_decrypt_key);
|
||||
winpr_RC4_Free(rdp->rc4_encrypt_key);
|
||||
|
||||
rdp->fips_decrypt = NULL;
|
||||
rdp->fips_encrypt = NULL;
|
||||
rdp->rc4_decrypt_key = NULL;
|
||||
rdp->rc4_encrypt_key = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -586,12 +596,12 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
|
||||
if (rand_len != key_len + 8)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid encrypted client random length");
|
||||
goto end2;
|
||||
goto end;
|
||||
}
|
||||
|
||||
crypt_client_random = calloc(1, rand_len);
|
||||
if (!crypt_client_random)
|
||||
goto end2;
|
||||
goto end;
|
||||
Stream_Read(s, crypt_client_random, rand_len);
|
||||
|
||||
mod = rdp->settings->RdpServerRsaKey->Modulus;
|
||||
@ -600,29 +610,33 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
|
||||
|
||||
/* now calculate encrypt / decrypt and update keys */
|
||||
if (!security_establish_keys(client_random, rdp))
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
rdp->do_crypt = TRUE;
|
||||
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
|
||||
rdp->fips_encrypt = winpr_Cipher_New(WINPR_CIPHER_DES_EDE3_CBC,
|
||||
WINPR_ENCRYPT,
|
||||
rdp->fips_encrypt_key,
|
||||
fips_ivec);
|
||||
if (!rdp->fips_encrypt)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate des3 encrypt key");
|
||||
goto end;
|
||||
}
|
||||
|
||||
rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);
|
||||
rdp->fips_decrypt = winpr_Cipher_New(WINPR_CIPHER_DES_EDE3_CBC,
|
||||
WINPR_DECRYPT,
|
||||
rdp->fips_decrypt_key,
|
||||
fips_ivec);
|
||||
if (!rdp->fips_decrypt)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate des3 decrypt key");
|
||||
goto end;
|
||||
}
|
||||
|
||||
rdp->fips_hmac = crypto_hmac_new();
|
||||
rdp->fips_hmac = calloc(1, sizeof(WINPR_HMAC_CTX));
|
||||
if (!rdp->fips_hmac)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate fips hmac");
|
||||
@ -632,25 +646,28 @@ BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
|
||||
goto end;
|
||||
}
|
||||
|
||||
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
|
||||
if (!rdp->rc4_decrypt_key)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate rc4 decrypt key");
|
||||
rdp->rc4_decrypt_key = winpr_RC4_New(rdp->decrypt_key, rdp->rc4_key_len);
|
||||
rdp->rc4_encrypt_key = winpr_RC4_New(rdp->encrypt_key, rdp->rc4_key_len);
|
||||
if (!rdp->rc4_decrypt_key || rdp->rc4_encrypt_key)
|
||||
goto end;
|
||||
}
|
||||
|
||||
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
|
||||
if (!rdp->rc4_encrypt_key)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate rc4 encrypt key");
|
||||
goto end;
|
||||
}
|
||||
ret = TRUE;
|
||||
end:
|
||||
free(crypt_client_random);
|
||||
end2:
|
||||
free(client_random);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
winpr_Cipher_Free(rdp->fips_encrypt);
|
||||
winpr_Cipher_Free(rdp->fips_decrypt);
|
||||
winpr_RC4_Free(rdp->rc4_encrypt_key);
|
||||
winpr_RC4_Free(rdp->rc4_decrypt_key);
|
||||
|
||||
rdp->fips_encrypt = NULL;
|
||||
rdp->fips_decrypt = NULL;
|
||||
rdp->rc4_encrypt_key = NULL;
|
||||
rdp->rc4_decrypt_key = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
"A configuration error prevented a connection to be established."
|
||||
|
||||
#define ERRCONNECT_CONNECT_UNDEFINED_STRING \
|
||||
"A undefined connection error occured."
|
||||
"A undefined connection error occurred."
|
||||
|
||||
#define ERRCONNECT_POST_CONNECT_FAILED_STRING \
|
||||
"The connection attempt was aborted due to post connect configuration errors."
|
||||
|
||||
@ -569,7 +569,7 @@ void rdp_print_errinfo(UINT32 code)
|
||||
{
|
||||
if (code == errInfo->code)
|
||||
{
|
||||
WLog_ERR(TAG, "%s (0x%08X):%s", errInfo->name, code, errInfo->info);
|
||||
WLog_INFO(TAG, "%s (0x%08X):%s", errInfo->name, code, errInfo->info);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
#include "transport.h"
|
||||
#include "connection.h"
|
||||
#include "message.h"
|
||||
#include "buildflags.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@ -71,6 +72,7 @@ BOOL freerdp_connect(freerdp* instance)
|
||||
connectErrorCode = 0;
|
||||
freerdp_set_last_error(instance->context, FREERDP_ERROR_SUCCESS);
|
||||
clearChannelError(instance->context);
|
||||
ResetEvent(instance->context->abortEvent);
|
||||
|
||||
rdp = instance->context->rdp;
|
||||
settings = instance->settings;
|
||||
@ -381,6 +383,7 @@ BOOL freerdp_reconnect(freerdp* instance)
|
||||
BOOL status;
|
||||
rdpRdp* rdp = instance->context->rdp;
|
||||
|
||||
ResetEvent(instance->context->abortEvent);
|
||||
status = rdp_client_reconnect(rdp);
|
||||
|
||||
return status;
|
||||
@ -395,7 +398,7 @@ BOOL freerdp_shall_disconnect(freerdp* instance)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
FREERDP_API BOOL freerdp_focus_required(freerdp* instance)
|
||||
BOOL freerdp_focus_required(freerdp* instance)
|
||||
{
|
||||
rdpRdp* rdp;
|
||||
BOOL bRetCode = FALSE;
|
||||
@ -438,13 +441,23 @@ const char* freerdp_get_version_string(void)
|
||||
|
||||
const char* freerdp_get_build_date(void)
|
||||
{
|
||||
static char build_date[64];
|
||||
|
||||
sprintf_s(build_date, sizeof(build_date), "%s %s", __DATE__, __TIME__);
|
||||
static char build_date[] = __DATE__ " " __TIME__;
|
||||
|
||||
return build_date;
|
||||
}
|
||||
|
||||
const char* freerdp_get_build_config(void)
|
||||
{
|
||||
static const char build_config[] =
|
||||
"Build configuration: " BUILD_CONFIG "\n"
|
||||
"Build type: " BUILD_TYPE "\n"
|
||||
"CFLAGS: " CFLAGS "\n"
|
||||
"Compiler: " COMPILER_ID ", " COMPILER_VERSION "\n"
|
||||
"Target architecture: " TARGET_ARCH "\n";
|
||||
|
||||
return build_config;
|
||||
}
|
||||
|
||||
const char* freerdp_get_build_revision(void)
|
||||
{
|
||||
return GIT_REVISION;
|
||||
@ -615,7 +628,7 @@ UINT32 freerdp_error_info(freerdp* instance)
|
||||
}
|
||||
|
||||
void freerdp_set_error_info(rdpRdp* rdp, UINT32 error) {
|
||||
rdp->errorInfo = error;
|
||||
rdp_set_error_info(rdp, error);
|
||||
}
|
||||
|
||||
UINT32 freerdp_get_last_error(rdpContext* context)
|
||||
@ -765,19 +778,19 @@ void freerdp_free(freerdp* instance)
|
||||
free(instance);
|
||||
}
|
||||
|
||||
FREERDP_API ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount) {
|
||||
ULONG freerdp_get_transport_sent(rdpContext* context, BOOL resetCount) {
|
||||
ULONG written = context->rdp->transport->written;
|
||||
if (resetCount)
|
||||
context->rdp->transport->written = 0;
|
||||
return written;
|
||||
}
|
||||
|
||||
FREERDP_API HANDLE getChannelErrorEventHandle(rdpContext* context)
|
||||
HANDLE getChannelErrorEventHandle(rdpContext* context)
|
||||
{
|
||||
return context->channelErrorEvent;
|
||||
}
|
||||
|
||||
FREERDP_API BOOL checkChannelErrorEvent(rdpContext* context)
|
||||
BOOL checkChannelErrorEvent(rdpContext* context)
|
||||
{
|
||||
if (WaitForSingleObject( context->channelErrorEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
@ -792,24 +805,24 @@ FREERDP_API BOOL checkChannelErrorEvent(rdpContext* context)
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
FREERDP_API UINT getChannelError(rdpContext* context)
|
||||
UINT getChannelError(rdpContext* context)
|
||||
{
|
||||
return context->channelErrorNum;
|
||||
}
|
||||
|
||||
FREERDP_API const char* getChannelErrorDescription(rdpContext* context)
|
||||
const char* getChannelErrorDescription(rdpContext* context)
|
||||
{
|
||||
return context->errorDescription;
|
||||
}
|
||||
|
||||
FREERDP_API void clearChannelError(rdpContext* context)
|
||||
void clearChannelError(rdpContext* context)
|
||||
{
|
||||
context->channelErrorNum = 0;
|
||||
memset(context->errorDescription, 0, 500);
|
||||
ResetEvent(context->channelErrorEvent);
|
||||
}
|
||||
|
||||
FREERDP_API void setChannelError(rdpContext* context, UINT errorNum, char* description)
|
||||
void setChannelError(rdpContext* context, UINT errorNum, char* description)
|
||||
{
|
||||
context->channelErrorNum = errorNum;
|
||||
strncpy(context->errorDescription, description, 499);
|
||||
|
||||
@ -29,8 +29,6 @@
|
||||
#include <winpr/dsparse.h>
|
||||
#include <winpr/winhttp.h>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#define TAG FREERDP_TAG("core.gateway.ntlm")
|
||||
|
||||
wStream* rpc_ntlm_http_request(rdpRpc* rpc, HttpContext* http, const char* method, int contentLength, SecBuffer* ntlmToken)
|
||||
|
||||
@ -28,7 +28,6 @@
|
||||
#include <winpr/dsparse.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "http.h"
|
||||
|
||||
|
||||
@ -198,14 +198,22 @@ BOOL rdg_send_tunnel_authorization(rdpRdg* rdg)
|
||||
int i;
|
||||
wStream* s;
|
||||
BOOL status;
|
||||
char* clientName = rdg->settings->ClientHostname;
|
||||
UINT16 clientNameLen = strlen(clientName) + 1;
|
||||
UINT32 packetSize = 12 + clientNameLen * 2;
|
||||
WCHAR* clientName = NULL;
|
||||
UINT16 clientNameLen;
|
||||
UINT32 packetSize;
|
||||
|
||||
clientNameLen = ConvertToUnicode(CP_UTF8, 0, rdg->settings->ClientHostname, -1, &clientName, 0);
|
||||
if (!clientName)
|
||||
return FALSE;
|
||||
|
||||
packetSize = 12 + clientNameLen * 2 + sizeof(WCHAR);
|
||||
s = Stream_New(NULL, packetSize);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
free(clientName);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Stream_Write_UINT16(s, PKT_TYPE_TUNNEL_AUTH); /* Type (2 bytes) */
|
||||
Stream_Write_UINT16(s, 0); /* Reserved (2 bytes) */
|
||||
@ -215,15 +223,16 @@ BOOL rdg_send_tunnel_authorization(rdpRdg* rdg)
|
||||
Stream_Write_UINT16(s, clientNameLen * 2); /* Client name string length */
|
||||
|
||||
for (i = 0; i < clientNameLen; i++)
|
||||
{
|
||||
Stream_Write_UINT16(s, clientName[i]);
|
||||
}
|
||||
|
||||
Stream_Write_UINT16(s, 0);
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = rdg_write_packet(rdg, s);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
free(clientName);
|
||||
|
||||
if (status)
|
||||
{
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
|
||||
#include <freerdp/log.h>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/bio.h>
|
||||
|
||||
#ifdef HAVE_VALGRIND_MEMCHECK_H
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/crypto.h>
|
||||
#include <winpr/winhttp.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
@ -422,7 +423,7 @@ int rts_ping_traffic_sent_notify_command_write(BYTE* buffer, UINT32 PingTrafficS
|
||||
|
||||
void rts_generate_cookie(BYTE* cookie)
|
||||
{
|
||||
RAND_pseudo_bytes(cookie, 16);
|
||||
winpr_RAND(cookie, 16);
|
||||
}
|
||||
|
||||
/* CONN/A Sequence */
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/crypto.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
|
||||
@ -591,9 +592,8 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength)
|
||||
/* clientName (32 bytes, null-terminated unicode, truncated to 15 characters) */
|
||||
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), 32 / 2, &str, 0, NULL, NULL);
|
||||
Stream_Seek(s, 32);
|
||||
sprintf_s(settings->ClientHostname, 31, "%s", str);
|
||||
settings->ClientHostname[31] = 0;
|
||||
free(str);
|
||||
free(settings->ClientHostname);
|
||||
settings->ClientHostname = str;
|
||||
str = NULL;
|
||||
|
||||
Stream_Read_UINT32(s, settings->KeyboardType); /* KeyboardType (4 bytes) */
|
||||
@ -649,8 +649,8 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength)
|
||||
|
||||
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), 64 / 2, &str, 0, NULL, NULL);
|
||||
Stream_Seek(s, 64); /* clientDigProductId (64 bytes) */
|
||||
sprintf_s(settings->ClientProductId, 32, "%s", str);
|
||||
free(str);
|
||||
free(settings->ClientProductId);
|
||||
settings->ClientProductId = str;
|
||||
blockLength -= 64;
|
||||
|
||||
if (blockLength < 1)
|
||||
@ -761,6 +761,9 @@ BOOL gcc_read_client_core_data(wStream* s, rdpMcs* mcs, UINT16 blockLength)
|
||||
if (settings->SupportDynamicTimeZone)
|
||||
settings->SupportDynamicTimeZone = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE) ? TRUE : FALSE;
|
||||
|
||||
if (settings->SupportMonitorLayoutPdu)
|
||||
settings->SupportMonitorLayoutPdu = (earlyCapabilityFlags & RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU) ? TRUE : FALSE;
|
||||
|
||||
if (!(earlyCapabilityFlags & RNS_UD_CS_VALID_CONNECTION_TYPE))
|
||||
connectionType = 0;
|
||||
|
||||
@ -866,6 +869,9 @@ void gcc_write_client_core_data(wStream* s, rdpMcs* mcs)
|
||||
if (settings->SupportDynamicTimeZone)
|
||||
earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE;
|
||||
|
||||
if (settings->SupportMonitorLayoutPdu)
|
||||
earlyCapabilityFlags |= RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU;
|
||||
|
||||
Stream_Write_UINT16(s, highColorDepth); /* highColorDepth */
|
||||
Stream_Write_UINT16(s, supportedColorDepths); /* supportedColorDepths */
|
||||
|
||||
@ -1173,7 +1179,7 @@ const BYTE tssk_exponent[] =
|
||||
|
||||
BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
WINPR_MD5_CTX md5;
|
||||
BYTE* sigData;
|
||||
int expLen, keyLen, sigDataLen;
|
||||
BYTE encryptedSignature[TSSK_KEY_LENGTH];
|
||||
@ -1343,7 +1349,7 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs)
|
||||
|
||||
settings->ServerRandomLength = serverRandomLen;
|
||||
settings->ServerRandom = (BYTE*) malloc(serverRandomLen);
|
||||
crypto_nonce(settings->ServerRandom, serverRandomLen);
|
||||
winpr_RAND(settings->ServerRandom, serverRandomLen);
|
||||
Stream_Write(s, settings->ServerRandom, serverRandomLen);
|
||||
|
||||
sigData = Stream_Pointer(s);
|
||||
@ -1370,15 +1376,12 @@ BOOL gcc_write_server_security_data(wStream* s, rdpMcs* mcs)
|
||||
|
||||
memcpy(signature, initial_signature, sizeof(initial_signature));
|
||||
|
||||
md5 = crypto_md5_init();
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
if (!winpr_MD5_Init(&md5))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, sigData, sigDataLen))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Final(&md5, signature, sizeof(signature)))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
crypto_md5_update(md5, sigData, sigDataLen);
|
||||
crypto_md5_final(md5, signature);
|
||||
|
||||
crypto_rsa_private_encrypt(signature, sizeof(signature), TSSK_KEY_LENGTH,
|
||||
tssk_modulus, tssk_privateExponent, encryptedSignature);
|
||||
@ -1594,6 +1597,12 @@ BOOL gcc_read_client_monitor_data(wStream* s, rdpMcs* mcs, UINT16 blockLength)
|
||||
Stream_Read_UINT32(s, flags); /* flags */
|
||||
Stream_Read_UINT32(s, monitorCount); /* monitorCount */
|
||||
|
||||
if (monitorCount > settings->MonitorDefArraySize)
|
||||
{
|
||||
WLog_ERR(TAG, "too many announced monitors(%d), clamping to %d", monitorCount, settings->MonitorDefArraySize);
|
||||
monitorCount = settings->MonitorDefArraySize;
|
||||
}
|
||||
|
||||
if (((blockLength - 8) / 20) < monitorCount)
|
||||
return FALSE;
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <freerdp/crypto/crypto.h>
|
||||
#include <freerdp/log.h>
|
||||
#include <freerdp/session.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "timezone.h"
|
||||
@ -44,7 +45,7 @@ static const char* const INFO_TYPE_LOGON_STRINGS[4] =
|
||||
|
||||
BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp)
|
||||
{
|
||||
CryptoHmac hmac;
|
||||
WINPR_HMAC_CTX hmac;
|
||||
BYTE ClientRandom[32];
|
||||
BYTE AutoReconnectRandom[32];
|
||||
ARC_SC_PRIVATE_PACKET* serverCookie;
|
||||
@ -67,18 +68,14 @@ BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp)
|
||||
if (settings->SelectedProtocol == PROTOCOL_RDP)
|
||||
CopyMemory(ClientRandom, settings->ClientRandom, settings->ClientRandomLength);
|
||||
|
||||
hmac = crypto_hmac_new();
|
||||
|
||||
if (!hmac)
|
||||
return FALSE;
|
||||
|
||||
/* SecurityVerifier = HMAC_MD5(AutoReconnectRandom, ClientRandom) */
|
||||
|
||||
if (!crypto_hmac_md5_init(hmac, AutoReconnectRandom, 16))
|
||||
if (!winpr_HMAC_Init(&hmac, WINPR_MD_MD5, AutoReconnectRandom, 16))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Update(&hmac, ClientRandom, 32))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Final(&hmac, clientCookie->securityVerifier, 16))
|
||||
return FALSE;
|
||||
crypto_hmac_update(hmac, ClientRandom, 32);
|
||||
crypto_hmac_final(hmac, clientCookie->securityVerifier, 16);
|
||||
crypto_hmac_free(hmac);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -90,7 +87,7 @@ BOOL rdp_compute_client_auto_reconnect_cookie(rdpRdp* rdp)
|
||||
* @param settings settings
|
||||
*/
|
||||
|
||||
BOOL rdp_read_server_auto_reconnect_cookie(rdpRdp* rdp, wStream* s)
|
||||
BOOL rdp_read_server_auto_reconnect_cookie(rdpRdp* rdp, wStream* s, logon_info_ex *info)
|
||||
{
|
||||
BYTE* p;
|
||||
ARC_SC_PRIVATE_PACKET* autoReconnectCookie;
|
||||
@ -102,16 +99,16 @@ BOOL rdp_read_server_auto_reconnect_cookie(rdpRdp* rdp, wStream* s)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */
|
||||
Stream_Read_UINT32(s, autoReconnectCookie->version); /* Version (4 bytes) */
|
||||
Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
|
||||
Stream_Read(s, autoReconnectCookie->arcRandomBits, 16); /* ArcRandomBits (16 bytes) */
|
||||
|
||||
if (autoReconnectCookie->cbLen != 28)
|
||||
{
|
||||
WLog_ERR(TAG, "ServerAutoReconnectCookie.cbLen != 28");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Stream_Read_UINT32(s, autoReconnectCookie->version); /* Version (4 bytes) */
|
||||
Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */
|
||||
Stream_Read(s, autoReconnectCookie->arcRandomBits, 16); /* ArcRandomBits (16 bytes) */
|
||||
|
||||
p = autoReconnectCookie->arcRandomBits;
|
||||
|
||||
WLog_DBG(TAG, "ServerAutoReconnectCookie: Version: %d LogonId: %d SecurityVerifier: "
|
||||
@ -120,6 +117,9 @@ BOOL rdp_read_server_auto_reconnect_cookie(rdpRdp* rdp, wStream* s)
|
||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],
|
||||
p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]);
|
||||
|
||||
info->LogonId = autoReconnectCookie->logonId;
|
||||
CopyMemory(info->ArcRandomBits, p, 16);
|
||||
|
||||
if ((settings->PrintReconnectCookie) && (autoReconnectCookie->cbLen > 0))
|
||||
{
|
||||
char* base64;
|
||||
@ -660,31 +660,46 @@ BOOL rdp_send_client_info(rdpRdp* rdp)
|
||||
return status;
|
||||
}
|
||||
|
||||
BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s)
|
||||
BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s, logon_info *info)
|
||||
{
|
||||
UINT32 cbDomain;
|
||||
UINT32 cbUserName;
|
||||
UINT32 SessionId;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 576)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */
|
||||
if (cbDomain > 52)
|
||||
return FALSE;
|
||||
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbDomain, &info->domain, 0, NULL, FALSE);
|
||||
if (!info->domain)
|
||||
return FALSE;
|
||||
Stream_Seek(s, 52); /* domain (52 bytes) */
|
||||
Stream_Read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */
|
||||
Stream_Seek(s, 512); /* userName (512 bytes) */
|
||||
Stream_Read_UINT32(s, SessionId); /* SessionId (4 bytes) */
|
||||
|
||||
WLog_DBG(TAG, "LogonInfoV1: SessionId: 0x%04X", SessionId);
|
||||
Stream_Read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */
|
||||
if (cbUserName > 512)
|
||||
goto error_username;
|
||||
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbUserName, &info->username, 0, NULL, FALSE);
|
||||
if (!info->username)
|
||||
goto error_username;
|
||||
Stream_Seek(s, 512); /* userName (512 bytes) */
|
||||
|
||||
Stream_Read_UINT32(s, info->sessionId); /* SessionId (4 bytes) */
|
||||
|
||||
WLog_DBG(TAG, "LogonInfoV1: SessionId: 0x%04X", info->sessionId);
|
||||
|
||||
return TRUE;
|
||||
|
||||
error_username:
|
||||
free(info->domain);
|
||||
info->domain = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s)
|
||||
BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s, logon_info *info)
|
||||
{
|
||||
UINT16 Version;
|
||||
UINT32 Size;
|
||||
UINT32 SessionId;
|
||||
UINT32 cbDomain;
|
||||
UINT32 cbUserName;
|
||||
|
||||
@ -693,7 +708,7 @@ BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s)
|
||||
|
||||
Stream_Read_UINT16(s, Version); /* Version (2 bytes) */
|
||||
Stream_Read_UINT32(s, Size); /* Size (4 bytes) */
|
||||
Stream_Read_UINT32(s, SessionId); /* SessionId (4 bytes) */
|
||||
Stream_Read_UINT32(s, info->sessionId); /* SessionId (4 bytes) */
|
||||
Stream_Read_UINT32(s, cbDomain); /* cbDomain (4 bytes) */
|
||||
Stream_Read_UINT32(s, cbUserName); /* cbUserName (4 bytes) */
|
||||
Stream_Seek(s, 558); /* pad (558 bytes) */
|
||||
@ -701,10 +716,21 @@ BOOL rdp_recv_logon_info_v2(rdpRdp* rdp, wStream* s)
|
||||
if (Stream_GetRemainingLength(s) < (cbDomain + cbUserName))
|
||||
return FALSE;
|
||||
|
||||
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbDomain, &info->domain, 0, NULL, FALSE);
|
||||
if (!info->domain)
|
||||
return FALSE;
|
||||
Stream_Seek(s, cbDomain); /* domain */
|
||||
|
||||
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) Stream_Pointer(s), cbUserName, &info->username, 0, NULL, FALSE);
|
||||
if (!info->username)
|
||||
{
|
||||
free(info->domain);
|
||||
info->domain = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
Stream_Seek(s, cbUserName); /* userName */
|
||||
|
||||
WLog_DBG(TAG, "LogonInfoV2: SessionId: 0x%04X", SessionId);
|
||||
WLog_DBG(TAG, "LogonInfoV2: SessionId: 0x%04X", info->sessionId);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -721,7 +747,7 @@ BOOL rdp_recv_logon_plain_notify(rdpRdp* rdp, wStream* s)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rdp_recv_logon_error_info(rdpRdp* rdp, wStream* s)
|
||||
BOOL rdp_recv_logon_error_info(rdpRdp* rdp, wStream* s, logon_info_ex *info)
|
||||
{
|
||||
UINT32 errorNotificationType;
|
||||
UINT32 errorNotificationData;
|
||||
@ -737,10 +763,12 @@ BOOL rdp_recv_logon_error_info(rdpRdp* rdp, wStream* s)
|
||||
|
||||
IFCALL(rdp->instance->LogonErrorInfo, rdp->instance, errorNotificationData, errorNotificationType);
|
||||
|
||||
info->ErrorNotificationType = errorNotificationType;
|
||||
info->ErrorNotificationData = errorNotificationData;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s)
|
||||
BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s, logon_info_ex *info)
|
||||
{
|
||||
UINT32 cbFieldData;
|
||||
UINT32 fieldsPresent;
|
||||
@ -752,7 +780,7 @@ BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s)
|
||||
Stream_Read_UINT16(s, Length); /* Length (2 bytes) */
|
||||
Stream_Read_UINT32(s, fieldsPresent); /* fieldsPresent (4 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) < (Length - 6))
|
||||
if ((Length < 6) || (Stream_GetRemainingLength(s) < (Length - 6)))
|
||||
return FALSE;
|
||||
|
||||
WLog_DBG(TAG, "LogonInfoExtended: fieldsPresent: 0x%04X", fieldsPresent);
|
||||
@ -764,20 +792,28 @@ BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s)
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
|
||||
info->haveCookie = TRUE;
|
||||
Stream_Read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */
|
||||
|
||||
if (!rdp_read_server_auto_reconnect_cookie(rdp, s))
|
||||
if (Stream_GetRemainingLength(s) < cbFieldData)
|
||||
return FALSE;
|
||||
|
||||
if (!rdp_read_server_auto_reconnect_cookie(rdp, s, info))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (fieldsPresent & LOGON_EX_LOGONERRORS)
|
||||
{
|
||||
info->haveErrorInfo = TRUE;
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, cbFieldData); /* cbFieldData (4 bytes) */
|
||||
|
||||
if (!rdp_recv_logon_error_info(rdp, s))
|
||||
if (Stream_GetRemainingLength(s) < cbFieldData)
|
||||
return FALSE;
|
||||
|
||||
if (!rdp_recv_logon_error_info(rdp, s, info))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -792,7 +828,11 @@ BOOL rdp_recv_logon_info_extended(rdpRdp* rdp, wStream* s)
|
||||
BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
UINT32 infoType;
|
||||
BOOL status = FALSE;
|
||||
BOOL status;
|
||||
logon_info logonInfo;
|
||||
logon_info_ex logonInfoEx;
|
||||
rdpContext *context = rdp->context;
|
||||
rdpUpdate *update = rdp->context->update;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
@ -802,22 +842,39 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s)
|
||||
switch (infoType)
|
||||
{
|
||||
case INFO_TYPE_LOGON:
|
||||
status = rdp_recv_logon_info_v1(rdp, s);
|
||||
ZeroMemory(&logonInfo, sizeof(logonInfo));
|
||||
status = rdp_recv_logon_info_v1(rdp, s, &logonInfo);
|
||||
if (status && update->SaveSessionInfo)
|
||||
status = update->SaveSessionInfo(context, infoType, &logonInfo);
|
||||
free(logonInfo.domain);
|
||||
free(logonInfo.username);
|
||||
break;
|
||||
|
||||
case INFO_TYPE_LOGON_LONG:
|
||||
status = rdp_recv_logon_info_v2(rdp, s);
|
||||
ZeroMemory(&logonInfo, sizeof(logonInfo));
|
||||
status = rdp_recv_logon_info_v2(rdp, s, &logonInfo);
|
||||
if (status && update->SaveSessionInfo)
|
||||
status = update->SaveSessionInfo(context, infoType, &logonInfo);
|
||||
free(logonInfo.domain);
|
||||
free(logonInfo.username);
|
||||
break;
|
||||
|
||||
case INFO_TYPE_LOGON_PLAIN_NOTIFY:
|
||||
status = rdp_recv_logon_plain_notify(rdp, s);
|
||||
if (status && update->SaveSessionInfo)
|
||||
status = update->SaveSessionInfo(context, infoType, NULL);
|
||||
break;
|
||||
|
||||
case INFO_TYPE_LOGON_EXTENDED_INF:
|
||||
status = rdp_recv_logon_info_extended(rdp, s);
|
||||
ZeroMemory(&logonInfoEx, sizeof(logonInfoEx));
|
||||
status = rdp_recv_logon_info_extended(rdp, s, &logonInfoEx);
|
||||
if (status && update->SaveSessionInfo)
|
||||
status = update->SaveSessionInfo(context, infoType, &logonInfoEx);
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "Unhandled saveSessionInfo type 0x%x", infoType);
|
||||
status = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -830,3 +887,174 @@ BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s)
|
||||
return status;
|
||||
}
|
||||
|
||||
static BOOL rdp_write_logon_info_v1(wStream *s, logon_info *info)
|
||||
{
|
||||
int sz = 4 + 52 + 4 + 512 + 4;
|
||||
int len;
|
||||
WCHAR *wString = NULL;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, sz))
|
||||
return FALSE;
|
||||
|
||||
/* domain */
|
||||
len = ConvertToUnicode(CP_UTF8, 0, info->domain, -1, &wString, 0);
|
||||
if (len < 0)
|
||||
return FALSE;
|
||||
len *= 2;
|
||||
if (len > 52)
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT32(s, len);
|
||||
Stream_Write(s, wString, len);
|
||||
Stream_Seek(s, 52 - len);
|
||||
free(wString);
|
||||
|
||||
/* username */
|
||||
len = ConvertToUnicode(CP_UTF8, 0, info->username, -1, &wString, 0);
|
||||
if (len < 0)
|
||||
return FALSE;
|
||||
|
||||
len *= 2;
|
||||
if (len > 512)
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT32(s, len);
|
||||
Stream_Write(s, wString, len);
|
||||
Stream_Seek(s, 512 - len);
|
||||
free(wString);
|
||||
|
||||
/* sessionId */
|
||||
Stream_Write_UINT32(s, info->sessionId);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL rdp_write_logon_info_v2(wStream *s, logon_info *info)
|
||||
{
|
||||
int Size = 2 + 4 + 4 + 4 + 4 + 558;
|
||||
int domainLen, usernameLen, len;
|
||||
WCHAR *wString;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, Size))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, SAVE_SESSION_PDU_VERSION_ONE);
|
||||
Stream_Write_UINT32(s, Size);
|
||||
Stream_Write_UINT32(s, info->sessionId);
|
||||
|
||||
domainLen = strlen(info->domain);
|
||||
Stream_Write_UINT32(s, (domainLen + 1) * 2);
|
||||
|
||||
usernameLen = strlen(info->username);
|
||||
Stream_Write_UINT32(s, (usernameLen + 1) * 2);
|
||||
|
||||
Stream_Seek(s, 558);
|
||||
|
||||
len = ConvertToUnicode(CP_UTF8, 0, info->domain, -1, &wString, 0);
|
||||
if (len < 0)
|
||||
return FALSE;
|
||||
|
||||
Stream_Write(s, wString, len * 2);
|
||||
free(wString);
|
||||
|
||||
len = ConvertToUnicode(CP_UTF8, 0, info->username, -1, &wString, 0);
|
||||
if (len < 0)
|
||||
return FALSE;
|
||||
|
||||
Stream_Write(s, wString, len * 2);
|
||||
free(wString);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL rdp_write_logon_info_plain(wStream *s)
|
||||
{
|
||||
if (!Stream_EnsureRemainingCapacity(s, 576))
|
||||
return FALSE;
|
||||
|
||||
Stream_Seek(s, 576);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL rdp_write_logon_info_ex(wStream *s, logon_info_ex *info)
|
||||
{
|
||||
UINT32 FieldsPresent = 0;
|
||||
UINT16 Size = 2 + 4 + 570;
|
||||
|
||||
if (info->haveCookie)
|
||||
{
|
||||
FieldsPresent |= LOGON_EX_AUTORECONNECTCOOKIE;
|
||||
Size += 28;
|
||||
}
|
||||
|
||||
if (info->haveErrorInfo)
|
||||
{
|
||||
FieldsPresent |= LOGON_EX_LOGONERRORS;
|
||||
Size += 8;
|
||||
}
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, Size))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT16(s, Size);
|
||||
Stream_Write_UINT32(s, FieldsPresent);
|
||||
|
||||
if (info->haveCookie)
|
||||
{
|
||||
Stream_Write_UINT32(s, 28); /* cbFieldData (4 bytes) */
|
||||
|
||||
Stream_Write_UINT32(s, 28); /* cbLen (4 bytes) */
|
||||
Stream_Write_UINT32(s, AUTO_RECONNECT_VERSION_1); /* Version (4 bytes) */
|
||||
Stream_Write_UINT32(s, info->LogonId); /* LogonId (4 bytes) */
|
||||
Stream_Write(s, info->ArcRandomBits, 16); /* ArcRandomBits (16 bytes) */
|
||||
}
|
||||
|
||||
if (info->haveErrorInfo)
|
||||
{
|
||||
Stream_Write_UINT32(s, 8); /* cbFieldData (4 bytes) */
|
||||
|
||||
Stream_Write_UINT32(s, info->ErrorNotificationType); /* ErrorNotificationType (4 bytes) */
|
||||
Stream_Write_UINT32(s, info->ErrorNotificationData); /* ErrorNotificationData (4 bytes) */
|
||||
}
|
||||
|
||||
Stream_Seek(s, 570);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL rdp_send_save_session_info(rdpContext *context, UINT32 type, void *data)
|
||||
{
|
||||
wStream *s;
|
||||
BOOL status;
|
||||
rdpRdp *rdp = context->rdp;
|
||||
|
||||
s = rdp_data_pdu_init(rdp);
|
||||
if (!s)
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT32(s, type);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INFO_TYPE_LOGON:
|
||||
status = rdp_write_logon_info_v1(s, (logon_info *)data);
|
||||
break;
|
||||
case INFO_TYPE_LOGON_LONG:
|
||||
status = rdp_write_logon_info_v2(s, (logon_info *)data);
|
||||
break;
|
||||
case INFO_TYPE_LOGON_PLAIN_NOTIFY:
|
||||
status = rdp_write_logon_info_plain(s);
|
||||
break;
|
||||
case INFO_TYPE_LOGON_EXTENDED_INF:
|
||||
status = rdp_write_logon_info_ex(s, (logon_info_ex *)data);
|
||||
break;
|
||||
default:
|
||||
WLog_ERR(TAG, "saveSessionInfo type 0x%x not handled", type);
|
||||
status = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status)
|
||||
status = rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SAVE_SESSION_INFO, rdp->mcs->userId);
|
||||
else
|
||||
Stream_Free(s, TRUE);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -26,11 +26,6 @@
|
||||
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#define INFO_TYPE_LOGON 0x00000000
|
||||
#define INFO_TYPE_LOGON_LONG 0x00000001
|
||||
#define INFO_TYPE_LOGON_PLAIN_NOTIFY 0x00000002
|
||||
#define INFO_TYPE_LOGON_EXTENDED_INF 0x00000003
|
||||
|
||||
/* Client Address Family */
|
||||
#define ADDRESS_FAMILY_INET 0x0002
|
||||
#define ADDRESS_FAMILY_INET6 0x0017
|
||||
@ -56,23 +51,13 @@
|
||||
#define INFO_VIDEO_DISABLE 0x00400000
|
||||
#define INFO_HIDEF_RAIL_SUPPORTED 0x02000000
|
||||
|
||||
/* Logon Information Types */
|
||||
#define INFO_TYPE_LOGON 0x00000000
|
||||
#define INFO_TYPE_LOGON_LONG 0x00000001
|
||||
#define INFO_TYPE_LOGON_PLAIN_NOTIFY 0x00000002
|
||||
#define INFO_TYPE_LOGON_EXTENDED_INF 0x00000003
|
||||
|
||||
/* Extended Logon Info */
|
||||
#define LOGON_EX_AUTORECONNECTCOOKIE 0x00000001
|
||||
#define LOGON_EX_LOGONERRORS 0x00000002
|
||||
|
||||
/* Logon Error Info */
|
||||
#define LOGON_FAILED_BAD_PASSWORD 0x00000000
|
||||
#define LOGON_FAILED_UPDATE_PASSWORD 0x00000001
|
||||
#define LOGON_FAILED_OTHER 0x00000002
|
||||
#define LOGON_WARNING 0x00000003
|
||||
#define SAVE_SESSION_PDU_VERSION_ONE 0x0001
|
||||
|
||||
|
||||
BOOL rdp_read_server_auto_reconnect_cookie(rdpRdp* rdp, wStream* s);
|
||||
BOOL rdp_read_client_auto_reconnect_cookie(rdpRdp* rdp, wStream* s);
|
||||
void rdp_write_client_auto_reconnect_cookie(rdpRdp* rdp, wStream* s);
|
||||
void rdp_write_auto_reconnect_cookie(rdpRdp* rdp, wStream* s);
|
||||
@ -83,5 +68,6 @@ void rdp_write_info_packet(rdpRdp* rdp, wStream* s);
|
||||
BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s);
|
||||
BOOL rdp_send_client_info(rdpRdp* rdp);
|
||||
BOOL rdp_recv_save_session_info(rdpRdp* rdp, wStream* s);
|
||||
BOOL rdp_send_save_session_info(rdpContext *context, UINT32 type, void *data);
|
||||
|
||||
#endif /* __INFO_H */
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#endif
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/crypto.h>
|
||||
#include <freerdp/log.h>
|
||||
|
||||
#include "redirection.h"
|
||||
@ -328,10 +329,10 @@ void license_generate_randoms(rdpLicense* license)
|
||||
ZeroMemory(license->ClientRandom, CLIENT_RANDOM_LENGTH); /* ClientRandom */
|
||||
ZeroMemory(license->PremasterSecret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */
|
||||
#ifndef LICENSE_NULL_CLIENT_RANDOM
|
||||
crypto_nonce(license->ClientRandom, CLIENT_RANDOM_LENGTH); /* ClientRandom */
|
||||
winpr_RAND(license->ClientRandom, CLIENT_RANDOM_LENGTH); /* ClientRandom */
|
||||
#endif
|
||||
#ifndef LICENSE_NULL_PREMASTER_SECRET
|
||||
crypto_nonce(license->PremasterSecret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */
|
||||
winpr_RAND(license->PremasterSecret, PREMASTER_SECRET_LENGTH); /* PremasterSecret */
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -384,22 +385,19 @@ BOOL license_generate_keys(rdpLicense* license)
|
||||
|
||||
BOOL license_generate_hwid(rdpLicense* license)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
WINPR_MD5_CTX md5;
|
||||
BYTE macAddress[6];
|
||||
|
||||
ZeroMemory(macAddress, sizeof(macAddress));
|
||||
ZeroMemory(license->HardwareId, HWID_LENGTH);
|
||||
|
||||
md5 = crypto_md5_init();
|
||||
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
if (!winpr_MD5_Init(&md5))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, macAddress, sizeof(macAddress)))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Final(&md5, &license->HardwareId[HWID_PLATFORM_ID_LENGTH], WINPR_MD5_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
crypto_md5_update(md5, macAddress, sizeof(macAddress));
|
||||
crypto_md5_final(md5, &license->HardwareId[HWID_PLATFORM_ID_LENGTH]);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -460,28 +458,23 @@ BOOL license_encrypt_premaster_secret(rdpLicense* license)
|
||||
|
||||
BOOL license_decrypt_platform_challenge(rdpLicense* license)
|
||||
{
|
||||
CryptoRc4 rc4;
|
||||
BOOL rc;
|
||||
WINPR_RC4_CTX* rc4;
|
||||
|
||||
license->PlatformChallenge->data = (BYTE *)malloc(license->EncryptedPlatformChallenge->length);
|
||||
if (!license->PlatformChallenge->data)
|
||||
return FALSE;
|
||||
license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;
|
||||
|
||||
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
|
||||
if (!rc4)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a rc4");
|
||||
free(license->PlatformChallenge->data);
|
||||
license->PlatformChallenge->data = NULL;
|
||||
if ((rc4 = winpr_RC4_New(license->LicensingEncryptionKey,
|
||||
LICENSING_ENCRYPTION_KEY_LENGTH)) == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
crypto_rc4(rc4, license->EncryptedPlatformChallenge->length,
|
||||
rc = winpr_RC4_Update(rc4, license->EncryptedPlatformChallenge->length,
|
||||
license->EncryptedPlatformChallenge->data,
|
||||
license->PlatformChallenge->data);
|
||||
|
||||
crypto_rc4_free(rc4);
|
||||
return TRUE;
|
||||
winpr_RC4_Free(rc4);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1025,7 +1018,7 @@ BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
|
||||
wStream* s;
|
||||
int length;
|
||||
BYTE* buffer;
|
||||
CryptoRc4 rc4;
|
||||
WINPR_RC4_CTX* rc4;
|
||||
BYTE mac_data[16];
|
||||
BOOL status;
|
||||
|
||||
@ -1046,19 +1039,23 @@ BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
|
||||
if (!status)
|
||||
return FALSE;
|
||||
|
||||
rc4 = crypto_rc4_init(license->LicensingEncryptionKey, LICENSING_ENCRYPTION_KEY_LENGTH);
|
||||
rc4 = winpr_RC4_New(license->LicensingEncryptionKey,
|
||||
LICENSING_ENCRYPTION_KEY_LENGTH);
|
||||
if (!rc4)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a rc4");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
buffer = (BYTE*) malloc(HWID_LENGTH);
|
||||
if (!buffer)
|
||||
return FALSE;
|
||||
|
||||
crypto_rc4(rc4, HWID_LENGTH, license->HardwareId, buffer);
|
||||
crypto_rc4_free(rc4);
|
||||
status = winpr_RC4_Update(rc4, HWID_LENGTH, license->HardwareId, buffer);
|
||||
winpr_RC4_Free(rc4);
|
||||
if (!status)
|
||||
{
|
||||
free(buffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
license->EncryptedHardwareId->type = BB_DATA_BLOB;
|
||||
license->EncryptedHardwareId->data = buffer;
|
||||
license->EncryptedHardwareId->length = HWID_LENGTH;
|
||||
|
||||
@ -1086,7 +1086,7 @@ BOOL nego_send_negotiation_response(rdpNego* nego)
|
||||
settings->EncryptionLevel = ENCRYPTION_LEVEL_NONE;
|
||||
}
|
||||
|
||||
if (!settings->RdpServerRsaKey && !settings->RdpKeyFile)
|
||||
if (!settings->RdpServerRsaKey && !settings->RdpKeyFile && !settings->RdpKeyContent)
|
||||
{
|
||||
WLog_ERR(TAG, "Missing server certificate");
|
||||
return FALSE;
|
||||
|
||||
@ -27,6 +27,7 @@ typedef struct rdp_nla rdpNla;
|
||||
|
||||
#include <winpr/sspi.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/crypto.h>
|
||||
|
||||
#include <freerdp/crypto/tls.h>
|
||||
#include <freerdp/crypto/ber.h>
|
||||
@ -75,7 +76,7 @@ struct rdp_nla
|
||||
SecBuffer authInfo;
|
||||
SecBuffer PublicKey;
|
||||
SecBuffer tsCredentials;
|
||||
CryptoRc4 rc4SealState;
|
||||
WINPR_RC4_CTX rc4SealState;
|
||||
LPTSTR ServicePrincipalName;
|
||||
SEC_WINNT_AUTH_IDENTITY* identity;
|
||||
PSecurityFunctionTable table;
|
||||
|
||||
@ -219,13 +219,21 @@ static BOOL freerdp_peer_initialize(freerdp_peer* client)
|
||||
if (settings->RdpKeyFile)
|
||||
{
|
||||
settings->RdpServerRsaKey = key_new(settings->RdpKeyFile);
|
||||
|
||||
if (!settings->RdpServerRsaKey)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid RDP key file %s", settings->RdpKeyFile);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (settings->RdpKeyContent)
|
||||
{
|
||||
settings->RdpServerRsaKey = key_new_from_content(settings->RdpKeyContent, NULL);
|
||||
if (!settings->RdpServerRsaKey)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid RDP key content");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -204,8 +204,7 @@ static int rdp_security_stream_init(rdpRdp* rdp, wStream* s, BOOL sec_header)
|
||||
int rdp_init_stream(rdpRdp* rdp, wStream* s)
|
||||
{
|
||||
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
|
||||
rdp_security_stream_init(rdp, s, FALSE);
|
||||
return 0;
|
||||
return rdp_security_stream_init(rdp, s, FALSE);
|
||||
}
|
||||
|
||||
wStream* rdp_send_stream_init(rdpRdp* rdp)
|
||||
@ -340,10 +339,7 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
|
||||
return FALSE;
|
||||
|
||||
if (!rdp->instance)
|
||||
{
|
||||
freerdp_abort_connect(rdp->instance);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
context = rdp->instance->context;
|
||||
|
||||
@ -363,7 +359,7 @@ BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length, UINT16* channelId)
|
||||
rdp_set_error_info(rdp, ERRINFO_RPC_INITIATED_DISCONNECT);
|
||||
}
|
||||
|
||||
WLog_ERR(TAG, "DisconnectProviderUltimatum: reason: %d", reason);
|
||||
WLog_DBG(TAG, "DisconnectProviderUltimatum: reason: %d", reason);
|
||||
freerdp_abort_connect(rdp->instance);
|
||||
|
||||
EventArgsInit(&e, "freerdp");
|
||||
@ -671,8 +667,7 @@ BOOL rdp_recv_set_error_info_data_pdu(rdpRdp* rdp, wStream* s)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, errorInfo); /* errorInfo (4 bytes) */
|
||||
rdp_set_error_info(rdp, errorInfo);
|
||||
return TRUE;
|
||||
return rdp_set_error_info(rdp, errorInfo);
|
||||
}
|
||||
|
||||
BOOL rdp_recv_server_auto_reconnect_status_pdu(rdpRdp* rdp, wStream* s)
|
||||
@ -706,13 +701,14 @@ BOOL rdp_recv_monitor_layout_pdu(rdpRdp* rdp, wStream* s)
|
||||
UINT32 monitorCount;
|
||||
MONITOR_DEF* monitor;
|
||||
MONITOR_DEF* monitorDefArray;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, monitorCount); /* monitorCount (4 bytes) */
|
||||
|
||||
if (Stream_GetRemainingLength(s) < (monitorCount * 20))
|
||||
if ((Stream_GetRemainingLength(s) / 20) < monitorCount)
|
||||
return FALSE;
|
||||
|
||||
monitorDefArray = (MONITOR_DEF*) calloc(monitorCount, sizeof(MONITOR_DEF));
|
||||
@ -720,9 +716,8 @@ BOOL rdp_recv_monitor_layout_pdu(rdpRdp* rdp, wStream* s)
|
||||
if (!monitorDefArray)
|
||||
return FALSE;
|
||||
|
||||
for (index = 0; index < monitorCount; index++)
|
||||
for (monitor = monitorDefArray, index = 0; index < monitorCount; index++, monitor++)
|
||||
{
|
||||
monitor = &(monitorDefArray[index]);
|
||||
Stream_Read_UINT32(s, monitor->left); /* left (4 bytes) */
|
||||
Stream_Read_UINT32(s, monitor->top); /* top (4 bytes) */
|
||||
Stream_Read_UINT32(s, monitor->right); /* right (4 bytes) */
|
||||
@ -730,27 +725,30 @@ BOOL rdp_recv_monitor_layout_pdu(rdpRdp* rdp, wStream* s)
|
||||
Stream_Read_UINT32(s, monitor->flags); /* flags (4 bytes) */
|
||||
}
|
||||
|
||||
IFCALLRET(rdp->update->RemoteMonitors, ret, rdp->context, monitorCount, monitorDefArray);
|
||||
|
||||
free(monitorDefArray);
|
||||
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL rdp_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, MONITOR_DEF* monitorDefArray)
|
||||
BOOL rdp_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, const rdpMonitor* monitorDefArray)
|
||||
{
|
||||
UINT32 index;
|
||||
MONITOR_DEF* monitor;
|
||||
const rdpMonitor* monitor;
|
||||
|
||||
if (!Stream_EnsureRemainingCapacity(s, 4 + (monitorCount * 20)))
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT32(s, monitorCount); /* monitorCount (4 bytes) */
|
||||
|
||||
for (index = 0; index < monitorCount; index++)
|
||||
for (index = 0, monitor = monitorDefArray; index < monitorCount; index++, monitor++)
|
||||
{
|
||||
monitor = &(monitorDefArray[index]);
|
||||
Stream_Write_UINT32(s, monitor->left); /* left (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->top); /* top (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->right); /* right (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->bottom); /* bottom (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->flags); /* flags (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->x); /* left (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->y); /* top (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->x + monitor->width - 1); /* right (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->y + monitor->height - 1); /* bottom (4 bytes) */
|
||||
Stream_Write_UINT32(s, monitor->is_primary ? 0x01 : 0x00); /* flags (4 bytes) */
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@ -1412,6 +1410,8 @@ BOOL rdp_send_error_info(rdpRdp* rdp)
|
||||
return TRUE;
|
||||
|
||||
s = rdp_data_pdu_init(rdp);
|
||||
if (!s)
|
||||
return FALSE;
|
||||
|
||||
Stream_Write_UINT32(s, rdp->errorInfo); /* error id (4 bytes) */
|
||||
|
||||
@ -1590,31 +1590,31 @@ void rdp_reset(rdpRdp* rdp)
|
||||
|
||||
if (rdp->rc4_decrypt_key)
|
||||
{
|
||||
crypto_rc4_free(rdp->rc4_decrypt_key);
|
||||
winpr_RC4_Free(rdp->rc4_decrypt_key);
|
||||
rdp->rc4_decrypt_key = NULL;
|
||||
}
|
||||
|
||||
if (rdp->rc4_encrypt_key)
|
||||
{
|
||||
crypto_rc4_free(rdp->rc4_encrypt_key);
|
||||
winpr_RC4_Free(rdp->rc4_encrypt_key);
|
||||
rdp->rc4_encrypt_key = NULL;
|
||||
}
|
||||
|
||||
if (rdp->fips_encrypt)
|
||||
{
|
||||
crypto_des3_free(rdp->fips_encrypt);
|
||||
winpr_Cipher_Free(rdp->fips_encrypt);
|
||||
rdp->fips_encrypt = NULL;
|
||||
}
|
||||
|
||||
if (rdp->fips_decrypt)
|
||||
{
|
||||
crypto_des3_free(rdp->fips_decrypt);
|
||||
winpr_Cipher_Free(rdp->fips_decrypt);
|
||||
rdp->fips_decrypt = NULL;
|
||||
}
|
||||
|
||||
if (rdp->fips_hmac)
|
||||
{
|
||||
crypto_hmac_free(rdp->fips_hmac);
|
||||
free(rdp->fips_hmac);
|
||||
rdp->fips_hmac = NULL;
|
||||
}
|
||||
|
||||
@ -1661,11 +1661,11 @@ void rdp_free(rdpRdp* rdp)
|
||||
{
|
||||
if (rdp)
|
||||
{
|
||||
crypto_rc4_free(rdp->rc4_decrypt_key);
|
||||
crypto_rc4_free(rdp->rc4_encrypt_key);
|
||||
crypto_des3_free(rdp->fips_encrypt);
|
||||
crypto_des3_free(rdp->fips_decrypt);
|
||||
crypto_hmac_free(rdp->fips_hmac);
|
||||
winpr_RC4_Free(rdp->rc4_decrypt_key);
|
||||
winpr_RC4_Free(rdp->rc4_encrypt_key);
|
||||
winpr_Cipher_Free(rdp->fips_encrypt);
|
||||
winpr_Cipher_Free(rdp->fips_decrypt);
|
||||
free(rdp->fips_hmac);
|
||||
freerdp_settings_free(rdp->settings);
|
||||
freerdp_settings_free(rdp->settingsCopy);
|
||||
transport_free(rdp->transport);
|
||||
|
||||
@ -51,6 +51,7 @@
|
||||
#include <freerdp/log.h>
|
||||
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/crypto.h>
|
||||
|
||||
/* Security Header Flags */
|
||||
#define SEC_EXCHANGE_PKT 0x0001
|
||||
@ -147,15 +148,15 @@ struct rdp_rdp
|
||||
rdpAutoDetect* autodetect;
|
||||
rdpHeartbeat* heartbeat;
|
||||
rdpMultitransport* multitransport;
|
||||
struct crypto_rc4_struct* rc4_decrypt_key;
|
||||
WINPR_RC4_CTX* rc4_decrypt_key;
|
||||
int decrypt_use_count;
|
||||
int decrypt_checksum_use_count;
|
||||
struct crypto_rc4_struct* rc4_encrypt_key;
|
||||
WINPR_RC4_CTX* rc4_encrypt_key;
|
||||
int encrypt_use_count;
|
||||
int encrypt_checksum_use_count;
|
||||
struct crypto_des3_struct* fips_encrypt;
|
||||
struct crypto_des3_struct* fips_decrypt;
|
||||
struct crypto_hmac_struct* fips_hmac;
|
||||
WINPR_CIPHER_CTX* fips_encrypt;
|
||||
WINPR_CIPHER_CTX* fips_decrypt;
|
||||
WINPR_HMAC_CTX* fips_hmac;
|
||||
UINT32 sec_flags;
|
||||
BOOL do_crypt;
|
||||
BOOL do_crypt_license;
|
||||
@ -214,6 +215,8 @@ int rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s);
|
||||
|
||||
void rdp_read_flow_control_pdu(wStream* s, UINT16* type);
|
||||
|
||||
BOOL rdp_write_monitor_layout_pdu(wStream* s, UINT32 monitorCount, const rdpMonitor* monitorDefArray);
|
||||
|
||||
int rdp_recv_callback(rdpTransport* transport, wStream* s, void* extra);
|
||||
|
||||
int rdp_check_fds(rdpRdp* rdp);
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "security.h"
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#include <winpr/crypto.h>
|
||||
|
||||
#define TAG FREERDP_TAG("core")
|
||||
|
||||
@ -126,35 +127,35 @@ fips_oddparity_table[256] =
|
||||
static BOOL security_salted_hash(const BYTE* salt, const BYTE* input, int length,
|
||||
const BYTE* salt1, const BYTE* salt2, BYTE* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
CryptoSha1 sha1;
|
||||
BYTE sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH];
|
||||
WINPR_MD5_CTX md5;
|
||||
WINPR_SHA1_CTX sha1;
|
||||
BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH];
|
||||
|
||||
/* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1(Input + Salt + Salt1 + Salt2)) */
|
||||
|
||||
/* SHA1_Digest = SHA1(Input + Salt + Salt1 + Salt2) */
|
||||
sha1 = crypto_sha1_init();
|
||||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
if (!winpr_SHA1_Init(&sha1))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, input, length)) /* Input */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, salt, 48)) /* Salt (48 bytes) */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, salt1, 32)) /* Salt1 (32 bytes) */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, salt2, 32)) /* Salt2 (32 bytes) */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest)))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, input, length); /* Input */
|
||||
crypto_sha1_update(sha1, salt, 48); /* Salt (48 bytes) */
|
||||
crypto_sha1_update(sha1, salt1, 32); /* Salt1 (32 bytes) */
|
||||
crypto_sha1_update(sha1, salt2, 32); /* Salt2 (32 bytes) */
|
||||
crypto_sha1_final(sha1, sha1_digest);
|
||||
|
||||
/* SaltedHash(Salt, Input, Salt1, Salt2) = MD5(S + SHA1_Digest) */
|
||||
md5 = crypto_md5_init();
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
if (!winpr_MD5_Init(&md5))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, salt, 48)) /* Salt (48 bytes) */
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Final(&md5, output, WINPR_MD5_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, salt, 48); /* Salt (48 bytes) */
|
||||
crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
|
||||
crypto_md5_final(md5, output);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -199,18 +200,18 @@ void security_mac_salt_key(const BYTE* session_key_blob, const BYTE* client_rand
|
||||
|
||||
BOOL security_md5_16_32_32(const BYTE* in0, const BYTE* in1, const BYTE* in2, BYTE* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
WINPR_MD5_CTX md5;
|
||||
|
||||
md5 = crypto_md5_init();
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
if (!winpr_MD5_Init(&md5))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, in0, 16))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, in1, 32))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, in2, 32))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Final(&md5, output, WINPR_MD5_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, in0, 16);
|
||||
crypto_md5_update(md5, in1, 32);
|
||||
crypto_md5_update(md5, in2, 32);
|
||||
crypto_md5_final(md5, output);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -232,76 +233,78 @@ void security_UINT32_le(BYTE* output, UINT32 value)
|
||||
BOOL security_mac_data(const BYTE* mac_salt_key, const BYTE* data, UINT32 length,
|
||||
BYTE* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
CryptoSha1 sha1;
|
||||
WINPR_MD5_CTX md5;
|
||||
WINPR_SHA1_CTX sha1;
|
||||
BYTE length_le[4];
|
||||
BYTE sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH];
|
||||
BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH];
|
||||
|
||||
/* MacData = MD5(MacSaltKey + pad2 + SHA1(MacSaltKey + pad1 + length + data)) */
|
||||
|
||||
security_UINT32_le(length_le, length); /* length must be little-endian */
|
||||
|
||||
/* SHA1_Digest = SHA1(MacSaltKey + pad1 + length + data) */
|
||||
sha1 = crypto_sha1_init();
|
||||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
if (!winpr_SHA1_Init(&sha1))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, mac_salt_key, 16)) /* MacSaltKey */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1))) /* pad1 */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, length_le, sizeof(length_le))) /* length */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, data, length)) /* data */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest)))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, mac_salt_key, 16); /* MacSaltKey */
|
||||
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
|
||||
crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */
|
||||
crypto_sha1_update(sha1, data, length); /* data */
|
||||
crypto_sha1_final(sha1, sha1_digest);
|
||||
|
||||
/* MacData = MD5(MacSaltKey + pad2 + SHA1_Digest) */
|
||||
md5 = crypto_md5_init();
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
if (!winpr_MD5_Init(&md5))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, mac_salt_key, 16)) /* MacSaltKey */
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2))) /* pad2 */
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Final(&md5, output, WINPR_MD5_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, mac_salt_key, 16); /* MacSaltKey */
|
||||
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
|
||||
crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
|
||||
crypto_md5_final(md5, output);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
CryptoSha1 sha1;
|
||||
WINPR_MD5_CTX md5;
|
||||
WINPR_SHA1_CTX sha1;
|
||||
BYTE length_le[4];
|
||||
BYTE md5_digest[CRYPTO_MD5_DIGEST_LENGTH];
|
||||
BYTE sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH];
|
||||
BYTE md5_digest[WINPR_MD5_DIGEST_LENGTH];
|
||||
BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH];
|
||||
|
||||
security_UINT32_le(length_le, length); /* length must be little-endian */
|
||||
|
||||
/* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */
|
||||
sha1 = crypto_sha1_init();
|
||||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
if (!winpr_SHA1_Init(&sha1))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1))) /* pad1 */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, length_le, sizeof(length_le))) /* length */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, data, length)) /* data */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest)))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
|
||||
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
|
||||
crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */
|
||||
crypto_sha1_update(sha1, data, length); /* data */
|
||||
crypto_sha1_final(sha1, sha1_digest);
|
||||
|
||||
/* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */
|
||||
md5 = crypto_md5_init();
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
if (!winpr_MD5_Init(&md5))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2))) /* pad2 */
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Final(&md5, md5_digest, sizeof(md5_digest)))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
|
||||
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
|
||||
crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
|
||||
crypto_md5_final(md5, md5_digest);
|
||||
|
||||
memcpy(output, md5_digest, 8);
|
||||
return TRUE;
|
||||
@ -310,12 +313,12 @@ BOOL security_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length, BYTE*
|
||||
BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
|
||||
BOOL encryption, BYTE* output)
|
||||
{
|
||||
CryptoMd5 md5;
|
||||
CryptoSha1 sha1;
|
||||
WINPR_MD5_CTX md5;
|
||||
WINPR_SHA1_CTX sha1;
|
||||
BYTE length_le[4];
|
||||
BYTE use_count_le[4];
|
||||
BYTE md5_digest[CRYPTO_MD5_DIGEST_LENGTH];
|
||||
BYTE sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH];
|
||||
BYTE md5_digest[WINPR_MD5_DIGEST_LENGTH];
|
||||
BYTE sha1_digest[WINPR_SHA1_DIGEST_LENGTH];
|
||||
|
||||
security_UINT32_le(length_le, length); /* length must be little-endian */
|
||||
|
||||
@ -333,30 +336,32 @@ BOOL security_salted_mac_signature(rdpRdp *rdp, const BYTE* data, UINT32 length,
|
||||
}
|
||||
|
||||
/* SHA1_Digest = SHA1(MACKeyN + pad1 + length + data) */
|
||||
sha1 = crypto_sha1_init();
|
||||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
if (!winpr_SHA1_Init(&sha1))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1))) /* pad1 */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, length_le, sizeof(length_le))) /* length */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, data, length)) /* data */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, use_count_le, sizeof(use_count_le))) /* encryptionCount */
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Final(&sha1, sha1_digest, sizeof(sha1_digest)))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
|
||||
crypto_sha1_update(sha1, pad1, sizeof(pad1)); /* pad1 */
|
||||
crypto_sha1_update(sha1, length_le, sizeof(length_le)); /* length */
|
||||
crypto_sha1_update(sha1, data, length); /* data */
|
||||
crypto_sha1_update(sha1, use_count_le, sizeof(use_count_le)); /* encryptionCount */
|
||||
crypto_sha1_final(sha1, sha1_digest);
|
||||
|
||||
/* MACSignature = First64Bits(MD5(MACKeyN + pad2 + SHA1_Digest)) */
|
||||
md5 = crypto_md5_init();
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
if (!winpr_MD5_Init(&md5))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, rdp->sign_key, rdp->rc4_key_len)) /* MacKeyN */
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2))) /* pad2 */
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, sha1_digest, sizeof(sha1_digest))) /* SHA1_Digest */
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Final(&md5, md5_digest, sizeof(md5_digest)))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, rdp->sign_key, rdp->rc4_key_len); /* MacKeyN */
|
||||
crypto_md5_update(md5, pad2, sizeof(pad2)); /* pad2 */
|
||||
crypto_md5_update(md5, sha1_digest, sizeof(sha1_digest)); /* SHA1_Digest */
|
||||
crypto_md5_final(md5, md5_digest);
|
||||
|
||||
memcpy(output, md5_digest, 8);
|
||||
return TRUE;
|
||||
@ -428,40 +433,38 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp)
|
||||
|
||||
if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
CryptoSha1 sha1;
|
||||
BYTE client_encrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1];
|
||||
BYTE client_decrypt_key_t[CRYPTO_SHA1_DIGEST_LENGTH + 1];
|
||||
sha1 = crypto_sha1_init();
|
||||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
WINPR_SHA1_CTX sha1;
|
||||
BYTE client_encrypt_key_t[WINPR_SHA1_DIGEST_LENGTH + 1];
|
||||
BYTE client_decrypt_key_t[WINPR_SHA1_DIGEST_LENGTH + 1];
|
||||
|
||||
if (!winpr_SHA1_Init(&sha1))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, client_random + 16, 16))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, server_random + 16, 16))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Final(&sha1, client_encrypt_key_t, sizeof(client_encrypt_key_t)))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, client_random + 16, 16);
|
||||
crypto_sha1_update(sha1, server_random + 16, 16);
|
||||
crypto_sha1_final(sha1, client_encrypt_key_t);
|
||||
client_encrypt_key_t[20] = client_encrypt_key_t[0];
|
||||
|
||||
sha1 = crypto_sha1_init();
|
||||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
if (!winpr_SHA1_Init(&sha1))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, client_random, 16))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, server_random, 16))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Final(&sha1, client_decrypt_key_t, sizeof(client_decrypt_key_t)))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, client_random, 16);
|
||||
crypto_sha1_update(sha1, server_random, 16);
|
||||
crypto_sha1_final(sha1, client_decrypt_key_t);
|
||||
client_decrypt_key_t[20] = client_decrypt_key_t[0];
|
||||
|
||||
sha1 = crypto_sha1_init();
|
||||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
if (!winpr_SHA1_Init(&sha1))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, client_decrypt_key_t, WINPR_SHA1_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, client_encrypt_key_t, WINPR_SHA1_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Final(&sha1, rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, client_decrypt_key_t, 20);
|
||||
crypto_sha1_update(sha1, client_encrypt_key_t, 20);
|
||||
crypto_sha1_final(sha1, rdp->fips_sign_key);
|
||||
|
||||
if (rdp->settings->ServerMode)
|
||||
{
|
||||
@ -532,42 +535,42 @@ BOOL security_establish_keys(const BYTE* client_random, rdpRdp* rdp)
|
||||
|
||||
BOOL security_key_update(BYTE* key, BYTE* update_key, int key_len, rdpRdp* rdp)
|
||||
{
|
||||
BYTE sha1h[CRYPTO_SHA1_DIGEST_LENGTH];
|
||||
CryptoMd5 md5;
|
||||
CryptoSha1 sha1;
|
||||
CryptoRc4 rc4;
|
||||
BYTE sha1h[WINPR_SHA1_DIGEST_LENGTH];
|
||||
WINPR_MD5_CTX md5;
|
||||
WINPR_SHA1_CTX sha1;
|
||||
WINPR_RC4_CTX* rc4;
|
||||
BOOL rc;
|
||||
BYTE salt[] = { 0xD1, 0x26, 0x9E }; /* 40 bits: 3 bytes, 56 bits: 1 byte */
|
||||
|
||||
sha1 = crypto_sha1_init();
|
||||
if (!sha1)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a sha1");
|
||||
if (!winpr_SHA1_Init(&sha1))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, update_key, key_len))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, pad1, sizeof(pad1)))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Update(&sha1, key, key_len))
|
||||
return FALSE;
|
||||
if (!winpr_SHA1_Final(&sha1, sha1h, sizeof(sha1h)))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_sha1_update(sha1, update_key, key_len);
|
||||
crypto_sha1_update(sha1, pad1, sizeof(pad1));
|
||||
crypto_sha1_update(sha1, key, key_len);
|
||||
crypto_sha1_final(sha1, sha1h);
|
||||
|
||||
md5 = crypto_md5_init();
|
||||
if (!md5)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a md5");
|
||||
if (!winpr_MD5_Init(&md5))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, update_key, key_len))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, pad2, sizeof(pad2)))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Update(&md5, sha1h, sizeof(sha1h)))
|
||||
return FALSE;
|
||||
if (!winpr_MD5_Final(&md5, key, WINPR_MD5_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
}
|
||||
crypto_md5_update(md5, update_key, key_len);
|
||||
crypto_md5_update(md5, pad2, sizeof(pad2));
|
||||
crypto_md5_update(md5, sha1h, sizeof(sha1h));
|
||||
crypto_md5_final(md5, key);
|
||||
|
||||
rc4 = crypto_rc4_init(key, key_len);
|
||||
if (!rc4)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate a rc4");
|
||||
if ((rc4 = winpr_RC4_New(key, key_len)) == NULL)
|
||||
return FALSE;
|
||||
rc = winpr_RC4_Update(rc4, key_len, key, key);
|
||||
winpr_RC4_Free(rc4);
|
||||
|
||||
if (!rc)
|
||||
return FALSE;
|
||||
}
|
||||
crypto_rc4(rc4, key_len, key, key);
|
||||
crypto_rc4_free(rc4);
|
||||
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_40BIT)
|
||||
memcpy(key, salt, 3);
|
||||
@ -584,17 +587,16 @@ BOOL security_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
if (!security_key_update(rdp->encrypt_key, rdp->encrypt_update_key, rdp->rc4_key_len, rdp))
|
||||
return FALSE;
|
||||
|
||||
crypto_rc4_free(rdp->rc4_encrypt_key);
|
||||
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
|
||||
winpr_RC4_Free(rdp->rc4_encrypt_key);
|
||||
rdp->rc4_encrypt_key = winpr_RC4_New(rdp->encrypt_key, rdp->rc4_key_len);
|
||||
if (!rdp->rc4_encrypt_key)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate rc4 encrypt key");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rdp->encrypt_use_count = 0;
|
||||
}
|
||||
|
||||
crypto_rc4(rdp->rc4_encrypt_key, length, data, data);
|
||||
if (!winpr_RC4_Update(rdp->rc4_encrypt_key, length, data, data))
|
||||
return FALSE;
|
||||
rdp->encrypt_use_count++;
|
||||
rdp->encrypt_checksum_use_count++;
|
||||
return TRUE;
|
||||
@ -609,17 +611,16 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
{
|
||||
if (!security_key_update(rdp->decrypt_key, rdp->decrypt_update_key, rdp->rc4_key_len, rdp))
|
||||
return FALSE;
|
||||
crypto_rc4_free(rdp->rc4_decrypt_key);
|
||||
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
|
||||
winpr_RC4_Free(rdp->rc4_decrypt_key);
|
||||
rdp->rc4_decrypt_key = winpr_RC4_New(rdp->decrypt_key,
|
||||
rdp->rc4_key_len);
|
||||
if (!rdp->rc4_decrypt_key)
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate rc4 decrypt key");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
rdp->decrypt_use_count = 0;
|
||||
}
|
||||
crypto_rc4(rdp->rc4_decrypt_key, length, data, data);
|
||||
if (!winpr_RC4_Update(rdp->rc4_decrypt_key, length, data, data))
|
||||
return FALSE;
|
||||
rdp->decrypt_use_count += 1;
|
||||
rdp->decrypt_checksum_use_count++;
|
||||
return TRUE;
|
||||
@ -627,17 +628,20 @@ BOOL security_decrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
|
||||
BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp* rdp)
|
||||
{
|
||||
BYTE buf[20];
|
||||
BYTE buf[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BYTE use_count_le[4];
|
||||
|
||||
security_UINT32_le(use_count_le, rdp->encrypt_use_count);
|
||||
|
||||
if (!crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20))
|
||||
if (!winpr_HMAC_Init(rdp->fips_hmac, WINPR_MD_SHA1,
|
||||
rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Update(rdp->fips_hmac, data, length))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Update(rdp->fips_hmac, use_count_le, 4))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Final(rdp->fips_hmac, buf, WINPR_SHA1_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
|
||||
crypto_hmac_update(rdp->fips_hmac, data, length);
|
||||
crypto_hmac_update(rdp->fips_hmac, use_count_le, 4);
|
||||
crypto_hmac_final(rdp->fips_hmac, buf, 20);
|
||||
|
||||
memmove(output, buf, 8);
|
||||
return TRUE;
|
||||
@ -645,7 +649,9 @@ BOOL security_hmac_signature(const BYTE* data, int length, BYTE* output, rdpRdp*
|
||||
|
||||
BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
{
|
||||
if (!crypto_des3_encrypt(rdp->fips_encrypt, length, data, data))
|
||||
size_t olen;
|
||||
|
||||
if (!winpr_Cipher_Update(rdp->fips_encrypt, data, length, data, &olen))
|
||||
return FALSE;
|
||||
rdp->encrypt_use_count++;
|
||||
return TRUE;
|
||||
@ -653,21 +659,29 @@ BOOL security_fips_encrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
|
||||
BOOL security_fips_decrypt(BYTE* data, int length, rdpRdp* rdp)
|
||||
{
|
||||
return crypto_des3_decrypt(rdp->fips_decrypt, length, data, data);
|
||||
size_t olen;
|
||||
|
||||
if (!winpr_Cipher_Update(rdp->fips_decrypt, data, length, data, &olen))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL security_fips_check_signature(const BYTE* data, int length, const BYTE* sig, rdpRdp* rdp)
|
||||
{
|
||||
BYTE buf[20];
|
||||
BYTE buf[WINPR_SHA1_DIGEST_LENGTH];
|
||||
BYTE use_count_le[4];
|
||||
|
||||
security_UINT32_le(use_count_le, rdp->decrypt_use_count);
|
||||
|
||||
if (!crypto_hmac_sha1_init(rdp->fips_hmac, rdp->fips_sign_key, 20))
|
||||
if (!winpr_HMAC_Init(rdp->fips_hmac, WINPR_MD_SHA1,
|
||||
rdp->fips_sign_key, WINPR_SHA1_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Update(rdp->fips_hmac, data, length))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Update(rdp->fips_hmac, use_count_le, 4))
|
||||
return FALSE;
|
||||
if (!winpr_HMAC_Final(rdp->fips_hmac, buf, WINPR_SHA1_DIGEST_LENGTH))
|
||||
return FALSE;
|
||||
crypto_hmac_update(rdp->fips_hmac, data, length);
|
||||
crypto_hmac_update(rdp->fips_hmac, use_count_le, 4);
|
||||
crypto_hmac_final(rdp->fips_hmac, buf, 20);
|
||||
|
||||
rdp->decrypt_use_count++;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user