Merge tag 'upstream/2.0.0_gitb4b8239'

Upstream version 2.0.0~gitb4b8239
This commit is contained in:
Bernhard Miklautz 2016-02-29 16:49:29 +00:00
commit a12e58bec6
242 changed files with 12286 additions and 5372 deletions

View File

@ -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
View File

@ -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.

View File

@ -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
/**

View File

@ -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:

View File

@ -1,3 +0,0 @@
LIBRARY "cliprdr"
EXPORTS
VirtualChannelEntry @1

View File

@ -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
/**

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -1,3 +0,0 @@
LIBRARY "drive"
EXPORTS
DeviceServiceEntry @1

View File

@ -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 */

View File

@ -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
/**

View File

@ -394,6 +394,8 @@ static UINT parallel_free(DEVICE* device)
#ifdef STATIC_CHANNELS
#define DeviceServiceEntry parallel_DeviceServiceEntry
#else
#define DeviceServiceEntry FREERDP_API DeviceServiceEntry
#endif
/**

View File

@ -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;

View File

@ -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);

View File

@ -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
{

View File

@ -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;
}

View 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_ */

View File

@ -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)

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}
/**

View File

@ -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 */

View File

@ -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);

View File

@ -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
/**

View File

@ -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
/**

View File

@ -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);

View File

@ -813,6 +813,8 @@ static UINT serial_free(DEVICE* device)
#ifdef STATIC_CHANNELS
#define DeviceServiceEntry serial_DeviceServiceEntry
#else
#define DeviceServiceEntry FREERDP_API DeviceServiceEntry
#endif
/**

View File

@ -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);

View File

@ -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
/**

View File

@ -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:

View File

@ -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
/**

View File

@ -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")

View File

@ -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")

View File

@ -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)

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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

View File

@ -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)

View File

@ -1,3 +0,0 @@
LIBRARY "freerdp-client"
EXPORTS

View File

@ -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

View File

@ -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()

View File

@ -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")

View File

@ -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)

View File

@ -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@"

View 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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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
View 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__ */

View File

@ -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);

View File

@ -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 */

View File

@ -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)++;
}

View File

@ -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>

View File

@ -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>

View File

@ -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);
}

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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;
}

View File

@ -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")

View File

@ -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;
}

View File

@ -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."

View File

@ -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;
}

View File

@ -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);

View File

@ -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)

View File

@ -28,7 +28,6 @@
#include <winpr/dsparse.h>
#include <freerdp/log.h>
#include <openssl/rand.h>
#include "http.h"

View File

@ -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)
{

View File

@ -30,7 +30,6 @@
#include <freerdp/log.h>
#include <openssl/rand.h>
#include <openssl/bio.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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