Update upstream source from tag 'upstream/2.2.0+dfsg1'

Update to upstream version '2.2.0+dfsg1'
with Debian dir e498d308dc
This commit is contained in:
Mike Gabriel 2020-08-25 09:16:29 +02:00
commit 34e4ef129f
33 changed files with 404 additions and 237 deletions

View File

@ -81,7 +81,7 @@ if ($ENV{BUILD_NUMBER})
endif()
set(WITH_LIBRARY_VERSIONING "ON")
set(RAW_VERSION_STRING "2.1.2")
set(RAW_VERSION_STRING "2.2.0")
if(EXISTS "${CMAKE_SOURCE_DIR}/.source_tag")
file(READ ${CMAKE_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
elseif(USE_VERSION_FROM_GIT_TAG)
@ -341,106 +341,99 @@ if(${CMAKE_C_COMPILER_ID} STREQUAL "Clang")
endif()
endif()
set(THREAD_PREFER_PTHREAD_FLAG TRUE)
if(NOT IOS)
find_package(Threads REQUIRED)
endif()
if(NOT WIN32)
CHECK_SYMBOL_EXISTS(pthread_mutex_timedlock pthread.h HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL)
if (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL)
CHECK_LIBRARY_EXISTS(pthread pthread_mutex_timedlock "" HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB)
endif (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL)
if (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB)
CHECK_LIBRARY_EXISTS(pthreads pthread_mutex_timedlock "" HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS)
endif (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB)
if (HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS)
set(HAVE_PTHREAD_MUTEX_TIMEDLOCK ON)
endif (HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS)
endif()
# Enable address sanitizer, where supported and when required
if(${CMAKE_C_COMPILER_ID} STREQUAL "Clang" OR CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_REQUIRED_FLAGS_SAVED ${CMAKE_REQUIRED_FLAGS})
CHECK_C_COMPILER_FLAG ("-fno-omit-frame-pointer" fno-omit-frame-pointer)
if (fno-omit-frame-pointer)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer")
endif()
set(CMAKE_REQUIRED_LINK_OPTIONS_SAVED ${CMAKE_REQUIRED_LINK_OPTIONS})
file(WRITE ${CMAKE_BINARY_DIR}/foo.txt "")
if(WITH_SANITIZE_ADDRESS)
set(CMAKE_REQUIRED_FLAGS "-fsanitize=address")
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS "-fsanitize=address")
CHECK_C_COMPILER_FLAG ("-fsanitize=address" fsanitize-address)
CHECK_C_COMPILER_FLAG ("-fsanitize-blacklist=${CMAKE_BINARY_DIR}/foo.txt" fsanitize-blacklist)
CHECK_C_COMPILER_FLAG ("-fsanitize-address-use-after-scope" fsanitize-address-use-after-scope)
unset(CMAKE_REQUIRED_FLAGS)
if(fsanitize-address)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
if(fsanitize-blacklist)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-blacklist=${CMAKE_SOURCE_DIR}/scripts/blacklist-address-sanitizer.txt")
endif(fsanitize-blacklist)
if(fsanitize-blacklist)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-blacklist=${CMAKE_SOURCE_DIR}/scripts/blacklist-address-sanitizer.txt")
endif(fsanitize-blacklist)
if(fsanitize-address-use-after-scope)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-address-use-after-scope")
endif(fsanitize-address-use-after-scope)
else(fsanitize-address)
message(WARNING "Missing support for address sanitizer!")
endif(fsanitize-address)
if(fno-omit-frame-pointer)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer")
endif()
if(fsanitize-address-use-after-scope)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-address-use-after-scope")
endif(fsanitize-address-use-after-scope)
elseif(WITH_SANITIZE_MEMORY)
set(CMAKE_REQUIRED_FLAGS "-fsanitize=memory")
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS "-fsanitize=memory")
CHECK_C_COMPILER_FLAG ("-fsanitize=memory" fsanitize-memory)
CHECK_C_COMPILER_FLAG ("-fsanitize-blacklist=${CMAKE_BINARY_DIR}/foo.txt" fsanitize-blacklist)
CHECK_C_COMPILER_FLAG ("-fsanitize-memory-use-after-dtor" fsanitize-memory-use-after-dtor)
CHECK_C_COMPILER_FLAG ("-fsanitize-memory-track-origins" fsanitize-memory-track-origins)
unset(CMAKE_REQUIRED_FLAGS)
if(fsanitize-memory)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=memory")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=memory")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=memory")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=memory")
if(fsanitize-blacklist)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-blacklist=${CMAKE_SOURCE_DIR}/scripts/blacklist-memory-sanitizer.txt")
endif(fsanitize-blacklist)
if(fsanitize-blacklist)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-blacklist=${CMAKE_SOURCE_DIR}/scripts/blacklist-memory-sanitizer.txt")
endif(fsanitize-blacklist)
if (fsanitize-memory-use-after-dtor)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-memory-use-after-dtor")
endif(fsanitize-memory-use-after-dtor)
if (fsanitize-memory-use-after-dtor)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-memory-use-after-dtor")
endif(fsanitize-memory-use-after-dtor)
if (fsanitize-memory-track-origins)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-memory-track-origins")
endif(fsanitize-memory-track-origins)
else(fsanitize-memory)
message(WARNING "Missing support for memory sanitizer!")
endif(fsanitize-memory)
if(fno-omit-frame-pointer)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer")
endif()
if (fsanitize-memory-track-origins)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-memory-track-origins")
endif(fsanitize-memory-track-origins)
elseif(WITH_SANITIZE_THREAD)
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS "-fsanitize=thread")
CHECK_C_COMPILER_FLAG ("-fsanitize=thread" fsanitize-thread)
CHECK_C_COMPILER_FLAG ("-fsanitize-blacklist=${CMAKE_BINARY_DIR}/foo.txt" fsanitize-blacklist)
unset(CMAKE_REQUIRED_FLAGS)
if(fsanitize-thread)
set(CMAKE_REQUIRED_FLAGS "-Werror -fsanitize=thread")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread")
if(fsanitize-blacklist)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-blacklist=${CMAKE_SOURCE_DIR}/scripts/blacklist-thread-sanitizer.txt")
endif(fsanitize-blacklist)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=thread")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
else(fsanitize-thread)
message(WARNING "Missing support for thread sanitizer!")
endif(fsanitize-thread)
if(fno-omit-frame-pointer)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread")
if(fsanitize-blacklist)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize-blacklist=${CMAKE_SOURCE_DIR}/scripts/blacklist-thread-sanitizer.txt")
endif(fsanitize-blacklist)
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=thread")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
endif()
file(REMOVE ${CMAKE_BINARY_DIR}/foo.txt)
set(CMAKE_REQUIRED_LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS_SAVED})
if (WITH_NO_UNDEFINED)
set(CMAKE_REQUIRED_FLAGS "-Wl,--no-undefined")
CHECK_C_COMPILER_FLAG (-Wl,--no-undefined no-undefined)
unset(CMAKE_REQUIRED_FLAGS)
if(no-undefined)
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined" )
SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined" )
endif()
endif()
set(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVED})
endif()
if(MSVC)
@ -626,26 +619,6 @@ if(ANDROID)
endif(WITH_GPROF)
endif()
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
if(NOT IOS)
find_package(Threads REQUIRED)
endif()
if(NOT WIN32)
CHECK_SYMBOL_EXISTS(pthread_mutex_timedlock pthread.h HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL)
if (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL)
CHECK_LIBRARY_EXISTS(pthread pthread_mutex_timedlock "" HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB)
endif (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL)
if (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB)
CHECK_LIBRARY_EXISTS(pthreads pthread_mutex_timedlock "" HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS)
endif (NOT HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB)
if (HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS)
set(HAVE_PTHREAD_MUTEX_TIMEDLOCK ON)
endif (HAVE_PTHREAD_MUTEX_TIMEDLOCK_SYMBOL OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIB OR HAVE_PTHREAD_MUTEX_TIMEDLOCK_LIBS)
endif()
if(WITH_VALGRIND_MEMCHECK)
check_include_files(valgrind/memcheck.h HAVE_VALGRIND_MEMCHECK_H)
else()
@ -671,6 +644,10 @@ if(UNIX OR CYGWIN)
list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES m)
set(X11_FEATURE_TYPE "RECOMMENDED")
set(WAYLAND_FEATURE_TYPE "RECOMMENDED")
include(CheckFunctionExists)
check_function_exists(getlogin_r HAVE_GETLOGIN_R)
else()
set(X11_FEATURE_TYPE "DISABLED")
set(WAYLAND_FEATURE_TYPE "DISABLED")

View File

@ -1,3 +1,31 @@
# 2020-07-20 Version 2.2.0
Important notes:
* CVE-2020-15103 - Integer overflow due to missing input sanitation in rdpegfx channel
Noteworty changes:
* fix: memory leak in nsc
* urbdrc
* some fixes and improvements
* build
* use cmake to detect getlogin_r
* improve asan checks/detection
* server/proxy
* new: support for heartbeats
* new: support for rail handshake ex flags
* fix: possible race condition with redirects
Fixed issues:
* #6263 Sound & mic - filter GSM codec for microphone redirection
* #6335: windows client title length
* #6370 - "Alternate Secondary Drawing Order UNKNOWN"
* #6298 - remoteapp with dialog is disconnecting when it loses focus
* #6299 - v2.1.2: Can't connect to Windows7
For a complete and detailed change log since the last release run:
git log 2.1.2..2.2.0
# 2020-06-22 Version 2.1.2
Important notes:

View File

@ -51,9 +51,13 @@ static const char* const RAIL_ORDER_TYPE_STRINGS[] = { "",
"",
"" };
const char* rail_get_order_type_string(BYTE orderType)
const char* rail_get_order_type_string(UINT16 orderType)
{
return RAIL_ORDER_TYPE_STRINGS[((orderType & 0xF0) >> 3) + (orderType & 0x0F)];
UINT32 index = ((orderType & 0xF0) >> 3) + (orderType & 0x0F);
if (index >= ARRAYSIZE(RAIL_ORDER_TYPE_STRINGS))
return "UNKNOWN";
return RAIL_ORDER_TYPE_STRINGS[index];
}
/**

View File

@ -26,8 +26,6 @@
#include <freerdp/rail.h>
const char* rail_get_order_type_string(BYTE orderType);
#define RAIL_PDU_HEADER_LENGTH 4
/* Fixed length of PDUs, excluding variable lengths */
@ -72,5 +70,6 @@ UINT rail_read_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam, BOOL ex
UINT rail_write_sysparam_order(wStream* s, const RAIL_SYSPARAM_ORDER* sysparam,
BOOL extendedSpiSupported);
BOOL rail_is_extended_spi_supported(UINT32 channelsFlags);
const char* rail_get_order_type_string(UINT16 orderType);
#endif /* FREERDP_CHANNEL_RAIL_COMMON_H */

View File

@ -60,7 +60,7 @@ static UINT rail_send(RailServerContext* context, wStream* s, ULONG length)
*
* @return 0 on success, otherwise a Win32 error code
*/
UINT rail_send_pdu(RailServerContext* context, wStream* s, UINT16 orderType)
static UINT rail_server_send_pdu(RailServerContext* context, wStream* s, UINT16 orderType)
{
UINT16 orderLength;
@ -278,7 +278,7 @@ static UINT rail_send_server_handshake(RailServerContext* context,
}
rail_write_handshake_order(s, handshake);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_HANDSHAKE);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_HANDSHAKE);
Stream_Free(s, TRUE);
return error;
}
@ -297,8 +297,6 @@ static UINT rail_send_server_handshake_ex(RailServerContext* context,
if (!context || !handshakeEx || !context->priv)
return ERROR_INVALID_PARAMETER;
/* Save channel flags to context */
context->priv->channelFlags = handshakeEx->railHandshakeFlags;
s = rail_pdu_init(RAIL_HANDSHAKE_EX_ORDER_LENGTH);
if (!s)
@ -307,8 +305,10 @@ static UINT rail_send_server_handshake_ex(RailServerContext* context,
return CHANNEL_RC_NO_MEMORY;
}
rail_server_set_handshake_ex_flags(context, handshakeEx->railHandshakeFlags);
rail_write_handshake_ex_order(s, handshakeEx);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_HANDSHAKE_EX);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_HANDSHAKE_EX);
Stream_Free(s, TRUE);
return error;
}
@ -344,7 +344,7 @@ static UINT rail_send_server_sysparam(RailServerContext* context,
}
rail_write_sysparam_order(s, sysparam, extendedSpiSupported);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_SYSPARAM);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_SYSPARAM);
Stream_Free(s, TRUE);
return error;
}
@ -372,7 +372,7 @@ static UINT rail_send_server_local_move_size(RailServerContext* context,
}
rail_write_local_move_size_order(s, localMoveSize);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_LOCALMOVESIZE);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_LOCALMOVESIZE);
Stream_Free(s, TRUE);
return error;
}
@ -400,7 +400,7 @@ static UINT rail_send_server_min_max_info(RailServerContext* context,
}
rail_write_min_max_info_order(s, minMaxInfo);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_MINMAXINFO);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_MINMAXINFO);
Stream_Free(s, TRUE);
return error;
}
@ -428,7 +428,7 @@ static UINT rail_send_server_taskbar_info(RailServerContext* context,
}
rail_write_taskbar_info_order(s, taskbarInfo);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_TASKBARINFO);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_TASKBARINFO);
Stream_Free(s, TRUE);
return error;
}
@ -456,7 +456,7 @@ static UINT rail_send_server_langbar_info(RailServerContext* context,
}
rail_write_langbar_info_order(s, langbarInfo);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_LANGBARINFO);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_LANGBARINFO);
Stream_Free(s, TRUE);
return error;
}
@ -484,7 +484,7 @@ static UINT rail_send_server_exec_result(RailServerContext* context,
}
rail_write_exec_result_order(s, execResult);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_EXEC_RESULT);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_EXEC_RESULT);
Stream_Free(s, TRUE);
return error;
}
@ -512,7 +512,7 @@ static UINT rail_send_server_z_order_sync(RailServerContext* context,
}
rail_write_z_order_sync_order(s, zOrderSync);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_ZORDER_SYNC);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_ZORDER_SYNC);
Stream_Free(s, TRUE);
return error;
}
@ -539,7 +539,7 @@ static UINT rail_send_server_cloak(RailServerContext* context, const RAIL_CLOAK*
}
rail_write_cloak_order(s, cloak);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_CLOAK);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_CLOAK);
Stream_Free(s, TRUE);
return error;
}
@ -568,7 +568,7 @@ rail_send_server_power_display_request(RailServerContext* context,
}
rail_write_power_display_request_order(s, powerDisplayRequest);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_POWER_DISPLAY_REQUEST);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_POWER_DISPLAY_REQUEST);
Stream_Free(s, TRUE);
return error;
}
@ -596,7 +596,7 @@ static UINT rail_send_server_get_app_id_resp(RailServerContext* context,
}
rail_write_get_app_id_resp_order(s, getAppidResp);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_GET_APPID_RESP);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_GET_APPID_RESP);
Stream_Free(s, TRUE);
return error;
}
@ -624,7 +624,7 @@ static UINT rail_send_server_get_appid_resp_ex(RailServerContext* context,
}
rail_write_get_appid_resp_ex_order(s, getAppidRespEx);
error = rail_send_pdu(context, s, TS_RAIL_ORDER_GET_APPID_RESP_EX);
error = rail_server_send_pdu(context, s, TS_RAIL_ORDER_GET_APPID_RESP_EX);
Stream_Free(s, TRUE);
return error;
}
@ -1522,6 +1522,17 @@ void rail_server_context_free(RailServerContext* context)
free(context);
}
void rail_server_set_handshake_ex_flags(RailServerContext* context, DWORD flags)
{
RailServerPrivate* priv;
if (!context || !context->priv)
return;
priv = context->priv;
priv->channelFlags = flags;
}
UINT rail_server_handle_messages(RailServerContext* context)
{
UINT status = CHANNEL_RC_OK;

View File

@ -600,7 +600,7 @@ static BOOL isAutomountLocation(const char* path)
uid_t uid = getuid();
char uname[MAX_PATH] = { 0 };
#ifndef getlogin_r
#ifndef HAVE_GETLOGIN_R
strncpy(uname, getlogin(), sizeof(uname));
#else
if (getlogin_r(uname, sizeof(uname)) != 0)

View File

@ -182,6 +182,10 @@ UINT rdpgfx_read_rect16(wStream* s, RECTANGLE_16* rect16)
Stream_Read_UINT16(s, rect16->top); /* top (2 bytes) */
Stream_Read_UINT16(s, rect16->right); /* right (2 bytes) */
Stream_Read_UINT16(s, rect16->bottom); /* bottom (2 bytes) */
if (rect16->left >= rect16->right)
return ERROR_INVALID_DATA;
if (rect16->top >= rect16->bottom)
return ERROR_INVALID_DATA;
return CHANNEL_RC_OK;
}

View File

@ -21,6 +21,8 @@ include_directories(common)
add_subdirectory(common)
if(WITH_CLIENT_CHANNELS)
option(WITH_DEBUG_URBDRC "Dump data send/received in URBDRC channel" OFF)
find_package(libusb-1.0 REQUIRED)
include_directories(${LIBUSB_1_INCLUDE_DIRS})

View File

@ -81,6 +81,22 @@ struct _ASYNC_TRANSFER_USER_DATA
#endif
};
static BOOL log_libusb_result(wLog* log, DWORD lvl, const char* fmt, int error, ...)
{
if (error < 0)
{
char buffer[8192] = { 0 };
va_list ap;
va_start(ap, error);
vsnprintf(buffer, sizeof(buffer), fmt, ap);
va_end(ap);
WLog_Print(log, lvl, "%s: error %s[%d]", buffer, libusb_error_name(error), error);
return TRUE;
}
return FALSE;
}
const char* usb_interface_class_to_string(uint8_t class)
{
switch (class)
@ -391,11 +407,8 @@ static int func_config_release_all_interface(URBDRC_PLUGIN* urbdrc,
{
int ret = libusb_release_interface(libusb_handle, i);
if (ret < 0)
{
WLog_Print(urbdrc->log, WLOG_ERROR, "config_release_all_interface: error num %d", ret);
if (log_libusb_result(urbdrc->log, WLOG_WARN, "libusb_release_interface", ret))
return -1;
}
}
return 0;
@ -410,11 +423,8 @@ static int func_claim_all_interface(URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE_HANDLE*
{
ret = libusb_claim_interface(libusb_handle, i);
if (ret < 0)
{
WLog_Print(urbdrc->log, WLOG_ERROR, "claim_all_interface: error num %d", ret);
if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_claim_interface", ret))
return -1;
}
}
return 0;
@ -447,14 +457,14 @@ static LIBUSB_DEVICE* udev_get_libusb_dev(libusb_context* context, uint8_t bus_n
static LIBUSB_DEVICE_DESCRIPTOR* udev_new_descript(URBDRC_PLUGIN* urbdrc, LIBUSB_DEVICE* libusb_dev)
{
int ret;
LIBUSB_DEVICE_DESCRIPTOR* descriptor;
descriptor = (LIBUSB_DEVICE_DESCRIPTOR*)malloc(sizeof(LIBUSB_DEVICE_DESCRIPTOR));
LIBUSB_DEVICE_DESCRIPTOR* descriptor =
(LIBUSB_DEVICE_DESCRIPTOR*)calloc(1, sizeof(LIBUSB_DEVICE_DESCRIPTOR));
if (!descriptor)
return NULL;
ret = libusb_get_device_descriptor(libusb_dev, descriptor);
if (ret < 0)
if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_get_device_descriptor", ret))
{
WLog_Print(urbdrc->log, WLOG_ERROR, "libusb_get_device_descriptor: error %s [%d]",
libusb_error_name(ret), ret);
free(descriptor);
return NULL;
}
@ -499,11 +509,7 @@ static int libusb_udev_select_interface(IUDEVICE* idev, BYTE InterfaceNumber, BY
error = libusb_set_interface_alt_setting(pdev->libusb_handle, InterfaceNumber,
AlternateSetting);
if (error < 0)
{
WLog_Print(urbdrc->log, WLOG_ERROR, "Set interface altsetting get error num %d",
error);
}
log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_set_interface_alt_setting", error);
}
}
@ -557,8 +563,7 @@ libusb_udev_complete_msconfig_setup(IUDEVICE* idev, MSUSB_CONFIG_DESCRIPTOR* MsC
for (pnum = 0; pnum < LibusbNumEndpoint; pnum++)
{
t_MsPipe = (MSUSB_PIPE_DESCRIPTOR*)malloc(sizeof(MSUSB_PIPE_DESCRIPTOR));
memset(t_MsPipe, 0, sizeof(MSUSB_PIPE_DESCRIPTOR));
t_MsPipe = (MSUSB_PIPE_DESCRIPTOR*)calloc(1, sizeof(MSUSB_PIPE_DESCRIPTOR));
if (pnum < MsInterface->NumberOfPipes && MsInterface->MsPipes)
{
@ -696,10 +701,8 @@ static int libusb_udev_select_configuration(IUDEVICE* idev, UINT32 bConfiguratio
else
ret = libusb_set_configuration(libusb_handle, bConfigurationValue);
if (ret < 0)
if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_set_configuration", ret))
{
WLog_Print(urbdrc->log, WLOG_ERROR, "libusb_set_configuration: error %s [%d]",
libusb_error_name(ret), ret);
func_claim_all_interface(urbdrc, libusb_handle, (*LibusbConfig)->bNumInterfaces);
return -1;
}
@ -707,10 +710,8 @@ static int libusb_udev_select_configuration(IUDEVICE* idev, UINT32 bConfiguratio
{
ret = libusb_get_active_config_descriptor(libusb_dev, LibusbConfig);
if (ret < 0)
if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_set_configuration", ret))
{
WLog_Print(urbdrc->log, WLOG_ERROR, "libusb_set_configuration: error %s [%d]",
libusb_error_name(ret), ret);
func_claim_all_interface(urbdrc, libusb_handle, (*LibusbConfig)->bNumInterfaces);
return -1;
}
@ -762,7 +763,7 @@ static UINT32 libusb_udev_control_query_device_text(IUDEVICE* idev, UINT32 TextT
{
UDEVICE* pdev = (UDEVICE*)idev;
LIBUSB_DEVICE_DESCRIPTOR* devDescriptor;
const char* strDesc = "Generic Usb String";
const char strDesc[] = "Generic Usb String";
char deviceLocation[25] = { 0 };
BYTE bus_number;
BYTE device_address;
@ -795,13 +796,16 @@ static UINT32 libusb_udev_control_query_device_text(IUDEVICE* idev, UINT32 TextT
slen = data[0];
locale = data[1];
if ((ret <= 0) || (ret < 4) || (slen < 4) || (locale != LIBUSB_DT_STRING) ||
if ((ret <= 0) || (ret <= 4) || (slen <= 4) || (locale != LIBUSB_DT_STRING) ||
(ret > UINT8_MAX))
{
char* msg = "SHORT_DESCRIPTOR";
if (ret < 0)
msg = libusb_error_name(ret);
WLog_Print(urbdrc->log, WLOG_DEBUG,
"libusb_get_string_descriptor: "
"ERROR num %d, iProduct: %" PRIu8 "!",
ret, devDescriptor->iProduct);
"%s [%d], iProduct: %" PRIu8 "!",
msg, ret, devDescriptor->iProduct);
len = MIN(sizeof(strDesc), inSize);
for (i = 0; i < len; i++)
@ -860,21 +864,20 @@ static int libusb_udev_os_feature_descriptor_request(IUDEVICE* idev, UINT32 Requ
BYTE* Buffer, int Timeout)
{
UDEVICE* pdev = (UDEVICE*)idev;
BYTE ms_string_desc[0x13];
BYTE ms_string_desc[0x13] = { 0 };
int error = 0;
/*
pdev->request_queue->register_request(pdev->request_queue, RequestId, NULL, 0);
*/
memset(ms_string_desc, 0, 0x13);
error = libusb_control_transfer(pdev->libusb_handle, LIBUSB_ENDPOINT_IN | Recipient,
LIBUSB_REQUEST_GET_DESCRIPTOR, 0x03ee, 0, ms_string_desc, 0x12,
Timeout);
// WLog_Print(urbdrc->log, WLOG_ERROR, "Get ms string: result number %d", error);
log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG, "libusb_control_transfer", error);
if (error > 0)
{
const BYTE bMS_Vendorcode = ms_string_desc[16];
// WLog_Print(urbdrc->log, WLOG_ERROR, "bMS_Vendorcode:0x%x", bMS_Vendorcode);
/** get os descriptor */
error = libusb_control_transfer(pdev->libusb_handle,
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | Recipient,
@ -962,14 +965,12 @@ static BOOL libusb_udev_detach_kernel_driver(IUDEVICE* idev)
for (i = 0; i < pdev->LibusbConfig->bNumInterfaces; i++)
{
err = libusb_kernel_driver_active(pdev->libusb_handle, i);
WLog_Print(urbdrc->log, WLOG_DEBUG, "libusb_kernel_driver_active = %s [%d]",
libusb_error_name(err), err);
log_libusb_result(urbdrc->log, WLOG_DEBUG, "libusb_kernel_driver_active", err);
if (err)
{
err = libusb_detach_kernel_driver(pdev->libusb_handle, i);
WLog_Print(urbdrc->log, WLOG_DEBUG, "libusb_detach_kernel_driver = %s [%d]",
libusb_error_name(err), err);
log_libusb_result(urbdrc->log, WLOG_DEBUG, "libusb_detach_kernel_driver", err);
}
}
@ -991,17 +992,13 @@ static BOOL libusb_udev_attach_kernel_driver(IUDEVICE* idev)
{
err = libusb_release_interface(pdev->libusb_handle, i);
if (err < 0)
{
WLog_Print(pdev->urbdrc->log, WLOG_DEBUG, "libusb_release_interface: error num %d = %d",
i, err);
}
log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG, "libusb_release_interface", err);
if (err != LIBUSB_ERROR_NO_DEVICE)
{
err = libusb_attach_kernel_driver(pdev->libusb_handle, i);
WLog_Print(pdev->urbdrc->log, WLOG_DEBUG, "libusb_attach_kernel_driver if%d = %d", i,
err);
log_libusb_result(pdev->urbdrc->log, WLOG_DEBUG, "libusb_attach_kernel_driver if=%d",
err, i);
}
}
@ -1094,7 +1091,6 @@ static int libusb_udev_query_device_port_status(IUDEVICE* idev, UINT32* UsbdStat
return -1;
urbdrc = pdev->urbdrc;
WLog_Print(urbdrc->log, WLOG_DEBUG, "...");
if (pdev->hub_handle != NULL)
{
@ -1103,11 +1099,8 @@ static int libusb_udev_query_device_port_status(IUDEVICE* idev, UINT32* UsbdStat
LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_OTHER,
LIBUSB_REQUEST_GET_STATUS, 0, pdev->port_number, UsbdStatus, BufferSize, Buffer, 1000);
if (ret < 0)
{
WLog_Print(urbdrc->log, WLOG_DEBUG, "libusb_control_transfer: error num %d", ret);
if (log_libusb_result(urbdrc->log, WLOG_DEBUG, "libusb_control_transfer", ret))
*BufferSize = 0;
}
else
{
WLog_Print(urbdrc->log, WLOG_DEBUG,
@ -1199,8 +1192,7 @@ static BOOL libusb_udev_control_transfer(IUDEVICE* idev, UINT32 RequestId, UINT3
if (status >= 0)
*BufferSize = (UINT32)status;
else
WLog_Print(pdev->urbdrc->log, WLOG_ERROR, "libusb_control_transfer %s [%d]",
libusb_error_name(status), status);
log_libusb_result(pdev->urbdrc->log, WLOG_ERROR, "libusb_control_transfer", status);
if (!func_set_usbd_status(pdev->urbdrc, pdev, UrbdStatus, status))
return FALSE;
@ -1303,11 +1295,8 @@ static int func_cancel_xact_request(URBDRC_PLUGIN* urbdrc, wHashTable* queue, ui
status = libusb_cancel_transfer(transfer);
if (status < 0)
if (log_libusb_result(urbdrc->log, WLOG_WARN, "libusb_cancel_transfer", status))
{
WLog_Print(urbdrc->log, WLOG_WARN, "libusb_cancel_transfer: error num %s [%d]",
libusb_error_name(status), status);
if (status == LIBUSB_ERROR_NOT_FOUND)
return -1;
}
@ -1409,11 +1398,7 @@ static void udev_free(IUDEVICE* idev)
{
rc = libusb_reset_device(udev->libusb_handle);
if (rc != LIBUSB_SUCCESS)
{
WLog_Print(urbdrc->log, WLOG_ERROR, "libusb_reset_device: error %s [%d]",
libusb_error_name(rc), rc);
}
log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_reset_device", rc);
}
/* release all interface and attach kernel driver */
@ -1490,12 +1475,8 @@ static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVI
error = libusb_open(libusb_list[i], &handle);
if (error < 0)
{
WLog_Print(urbdrc->log, WLOG_ERROR, "libusb_open error: %i - %s", error,
libusb_error_name(error));
if (log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_open", error))
break;
}
/* get port number */
error = libusb_get_port_numbers(libusb_list[i], port_numbers, sizeof(port_numbers));
@ -1504,8 +1485,7 @@ static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVI
if (error < 1)
{
/* Prevent open hub, treat as error. */
WLog_Print(urbdrc->log, WLOG_ERROR, "libusb_get_port_numbers error: %i - %s", error,
libusb_error_name(error));
log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_get_port_numbers", error);
break;
}
@ -1513,7 +1493,8 @@ static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVI
error = 0;
WLog_Print(urbdrc->log, WLOG_DEBUG, " Port: %d", pdev->port_number);
/* gen device path */
sprintf(pdev->path, "ugen%" PRIu16 ".%" PRIu16 "", bus_number, dev_number);
sprintf(pdev->path, "%" PRIu16 "-%" PRIu16 "", bus_number, pdev->port_number);
WLog_Print(urbdrc->log, WLOG_DEBUG, " DevPath: %s", pdev->path);
break;
}
@ -1535,10 +1516,7 @@ static int udev_get_hub_handle(URBDRC_PLUGIN* urbdrc, libusb_context* ctx, UDEVI
WLog_Print(urbdrc->log, WLOG_DEBUG, " Open hub: %" PRIu16 "", bus_number);
error = libusb_open(libusb_list[i], &handle);
if (error < 0)
WLog_Print(urbdrc->log, WLOG_ERROR, "libusb_open error: %i - %s", error,
libusb_error_name(error));
else
if (!log_libusb_result(urbdrc->log, WLOG_ERROR, "libusb_open", error))
pdev->hub_handle = handle;
break;
@ -1608,10 +1586,9 @@ static IUDEVICE* udev_init(URBDRC_PLUGIN* urbdrc, libusb_context* context, LIBUS
if (status != LIBUSB_SUCCESS)
{
WLog_Print(
urbdrc->log, WLOG_ERROR,
"libusb_open error: %i - %s [b=0x%02X,p=0x%02X,a=0x%02X,VID=0x%04X,PID=0x%04X]",
status, libusb_error_name(status), bus, port, addr, desc.idVendor, desc.idProduct);
log_libusb_result(urbdrc->log, WLOG_ERROR,
"libusb_open [b=0x%02X,p=0x%02X,a=0x%02X,VID=0x%04X,PID=0x%04X]",
status, bus, port, addr, desc.idVendor, desc.idProduct);
goto fail;
}
}
@ -1645,9 +1622,9 @@ static IUDEVICE* udev_init(URBDRC_PLUGIN* urbdrc, libusb_context* context, LIBUS
{
pdev->isCompositeDevice = 1;
}
else if ((devDescriptor->bDeviceClass == LIBUSB_CLASS_APPLICATION) &&
else if ((devDescriptor->bDeviceClass == 0xef) &&
(devDescriptor->bDeviceSubClass == LIBUSB_CLASS_COMM) &&
(devDescriptor->bDeviceProtocol == LIBUSB_CLASS_AUDIO))
(devDescriptor->bDeviceProtocol == 0x01))
{
pdev->isCompositeDevice = 1;
}

View File

@ -665,7 +665,7 @@ static BOOL urbdrc_udevman_register_devices(UDEVMAN* udevman, const char* device
}
else
{
idpair = malloc(sizeof(VID_PID_PAIR));
idpair = calloc(1, sizeof(VID_PID_PAIR));
if (!idpair)
return CHANNEL_RC_NO_MEMORY;
idpair->vid = id1;

View File

@ -86,7 +86,7 @@ static IWTSVirtualChannel* get_channel(IUDEVMAN* idevman)
static int func_container_id_generate(IUDEVICE* pdev, char* strContainerId)
{
char *p, *path;
UINT8 containerId[17];
UINT8 containerId[17] = { 0 };
UINT16 idVendor, idProduct;
idVendor = (UINT16)pdev->query_device_descriptor(pdev, ID_VENDOR);
idProduct = (UINT16)pdev->query_device_descriptor(pdev, ID_PRODUCT);
@ -97,7 +97,6 @@ static int func_container_id_generate(IUDEVICE* pdev, char* strContainerId)
else
p = path;
ZeroMemory(containerId, sizeof(containerId));
sprintf_s((char*)containerId, sizeof(containerId), "%04" PRIX16 "%04" PRIX16 "%s", idVendor,
idProduct, p);
/* format */
@ -114,7 +113,7 @@ static int func_container_id_generate(IUDEVICE* pdev, char* strContainerId)
static int func_instance_id_generate(IUDEVICE* pdev, char* strInstanceId, size_t len)
{
char instanceId[17];
char instanceId[17] = { 0 };
sprintf_s(instanceId, sizeof(instanceId), "\\%s", pdev->getPath(pdev));
/* format */
sprintf_s(strInstanceId, len,

View File

@ -17,8 +17,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "urbdrc_helpers.h"
#include "urbdrc_types.h"
#include <winpr/print.h>
const char* mask_to_string(UINT32 mask)
{
@ -405,4 +410,12 @@ void urbdrc_dump_message(wLog* log, BOOL client, BOOL write, wStream* s)
", FunctionId=%08" PRIx32 ", length=%" PRIdz,
type, call_to_string(client, InterfaceId, FunctionId), FunctionId, InterfaceId,
MessageId, FunctionId, length);
#if defined(WITH_DEBUG_URBDRC)
if (write)
WLog_Print(log, WLOG_TRACE, "-------------------------- URBDRC sent: ---");
else
WLog_Print(log, WLOG_TRACE, "-------------------------- URBDRC received:");
winpr_HexLogDump(log, WLOG_TRACE, Stream_Buffer(s), length);
WLog_Print(log, WLOG_TRACE, "-------------------------- URBDRC end -----");
#endif
}

View File

@ -1181,9 +1181,16 @@ static BOOL xf_pre_connect(freerdp* instance)
if (!settings->Username && !settings->CredentialsFromStdin && !settings->SmartcardLogon)
{
int rc;
char login_name[MAX_PATH] = { 0 };
if (getlogin_r(login_name, sizeof(login_name)) == 0)
#ifdef HAVE_GETLOGIN_R
rc = getlogin_r(login_name, sizeof(login_name));
#else
strncpy(login_name, getlogin(), sizeof(login_name));
rc = 0;
#endif
if (rc == 0)
{
settings->Username = _strdup(login_name);

View File

@ -24,6 +24,7 @@
#cmakedefine HAVE_PTHREAD_MUTEX_TIMEDLOCK
#cmakedefine HAVE_VALGRIND_MEMCHECK_H
#cmakedefine HAVE_EXECINFO_H
#cmakedefine HAVE_GETLOGIN_R
/* Features */
#cmakedefine SWRESAMPLE_FOUND
@ -159,6 +160,7 @@
#cmakedefine WITH_DEBUG_RDPEI
#cmakedefine WITH_DEBUG_TIMEZONE
#cmakedefine WITH_DEBUG_THREADS
#cmakedefine WITH_DEBUG_URBDRC
#cmakedefine WITH_DEBUG_MUTEX
#cmakedefine WITH_DEBUG_TRANSPORT
#cmakedefine WITH_DEBUG_WND

View File

@ -54,6 +54,7 @@ typedef RDP_CLIENT_ENTRY_POINTS_V1 RDP_CLIENT_ENTRY_POINTS;
#include <freerdp/update.h>
#include <freerdp/message.h>
#include <freerdp/autodetect.h>
#include <freerdp/heartbeat.h>
#ifdef __cplusplus
extern "C"
@ -309,7 +310,9 @@ extern "C"
ALIGN64 rdpAutoDetect* autodetect; /* (offset 19)
Auto-Detect handle for the connection.
Will be initialized by a call to freerdp_context_new() */
UINT64 paddingB[32 - 20]; /* 20 */
ALIGN64 rdpHeartbeat* heartbeat; /* (offset 21) */
UINT64 paddingB[32 - 21]; /* 21 */
ALIGN64 size_t
ContextSize; /* (offset 32)

View File

@ -0,0 +1,46 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* Heartbeat PDUs
*
* Copyright 2014 Dell Software <Mike.McDonald@software.dell.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_HEARTBEAT_H
#define FREERDP_HEARTBEAT_H
#include <freerdp/types.h>
typedef struct rdp_heartbeat rdpHeartbeat;
typedef BOOL (*pServerHeartbeat)(freerdp* instance, BYTE period, BYTE count1, BYTE count2);
struct rdp_heartbeat
{
pServerHeartbeat ServerHeartbeat;
};
#ifdef __cplusplus
extern "C"
{
#endif
FREERDP_API BOOL freerdp_heartbeat_send_heartbeat_pdu(freerdp_peer* peer, BYTE period,
BYTE count1, BYTE count2);
#ifdef __cplusplus
}
#endif
#endif /* FREERDP_HEARTBEAT_H */

View File

@ -141,6 +141,7 @@ extern "C"
FREERDP_API RailServerContext* rail_server_context_new(HANDLE vcm);
FREERDP_API void rail_server_context_free(RailServerContext* context);
FREERDP_API UINT rail_server_handle_messages(RailServerContext* context);
FREERDP_API void rail_server_set_handshake_ex_flags(RailServerContext* context, DWORD flags);
#ifdef __cplusplus
}

View File

@ -79,6 +79,7 @@ static BOOL ffmpeg_codec_is_filtered(enum AVCodecID id, BOOL encoder)
case AV_CODEC_ID_NONE:
return TRUE;
case AV_CODEC_ID_GSM_MS:
case AV_CODEC_ID_AAC:
case AV_CODEC_ID_AAC_LATM:
#if !defined(WITH_DSP_EXPERIMENTAL)

View File

@ -364,7 +364,7 @@ void nsc_context_free(NSC_CONTEXT* context)
if (context->priv)
{
for (i = 0; i < 4; i++)
for (i = 0; i < 5; i++)
free(context->priv->PlaneBuffers[i]);
nsc_profiler_print(context->priv);

View File

@ -672,6 +672,7 @@ BOOL freerdp_context_new(freerdp* instance)
instance->update = rdp->update;
instance->settings = rdp->settings;
instance->autodetect = rdp->autodetect;
instance->heartbeat = rdp->heartbeat;
context->graphics = graphics_new(context);
if (!context->graphics)

View File

@ -31,6 +31,7 @@ int rdp_recv_heartbeat_packet(rdpRdp* rdp, wStream* s)
BYTE period;
BYTE count1;
BYTE count2;
BOOL rc;
if (Stream_GetRemainingLength(s) < 4)
return -1;
@ -44,9 +45,39 @@ int rdp_recv_heartbeat_packet(rdpRdp* rdp, wStream* s)
"received Heartbeat PDU -> period=%" PRIu8 ", count1=%" PRIu8 ", count2=%" PRIu8 "",
period, count1, count2);
rc = IFCALLRESULT(TRUE, rdp->heartbeat->ServerHeartbeat, rdp->instance, period, count1, count2);
if (!rc)
{
WLog_ERR(HEARTBEAT_TAG, "heartbeat->ServerHeartbeat callback failed!");
return -1;
}
return 0;
}
BOOL freerdp_heartbeat_send_heartbeat_pdu(freerdp_peer* peer, BYTE period, BYTE count1, BYTE count2)
{
rdpRdp* rdp = peer->context->rdp;
wStream* s = rdp_message_channel_pdu_init(rdp);
if (!s)
return FALSE;
Stream_Seek_UINT8(s); /* reserved (1 byte) */
Stream_Write_UINT8(s, period); /* period (1 byte) */
Stream_Write_UINT8(s, count1); /* count1 (1 byte) */
Stream_Write_UINT8(s, count2); /* count2 (1 byte) */
WLog_DBG(HEARTBEAT_TAG,
"sending Heartbeat PDU -> period=%" PRIu8 ", count1=%" PRIu8 ", count2=%" PRIu8 "",
period, count1, count2);
if (!rdp_send_message_channel_pdu(rdp, s, SEC_HEARTBEAT))
return FALSE;
return TRUE;
}
rdpHeartbeat* heartbeat_new(void)
{
rdpHeartbeat* heartbeat = (rdpHeartbeat*)calloc(1, sizeof(rdpHeartbeat));

View File

@ -20,21 +20,15 @@
#ifndef FREERDP_LIB_CORE_HEARTBEET_H
#define FREERDP_LIB_CORE_HEARTBEET_H
typedef struct rdp_heartbeat rdpHeartbeat;
#include "rdp.h"
#include <freerdp/heartbeat.h>
#include <freerdp/freerdp.h>
#include <freerdp/log.h>
#include <freerdp/api.h>
#include <winpr/stream.h>
struct rdp_heartbeat
{
UINT32 placeholder;
};
int rdp_recv_heartbeat_packet(rdpRdp* rdp, wStream* s);
FREERDP_LOCAL rdpHeartbeat* heartbeat_new(void);

View File

@ -139,7 +139,8 @@ static BYTE get_bmf_bpp(UINT32 bmf, BOOL* pValid)
{
if (pValid)
*pValid = TRUE;
switch (bmf)
/* Mask out highest bit */
switch (bmf & (~CACHED_BRUSH))
{
case 1:
return 1;
@ -183,7 +184,7 @@ static BYTE get_bpp_bmf(UINT32 bpp, BOOL* pValid)
}
static BOOL check_order_activated(wLog* log, rdpSettings* settings, const char* orderName,
BOOL condition)
BOOL condition, const char* extendedMessage)
{
if (!condition)
{
@ -192,6 +193,8 @@ static BOOL check_order_activated(wLog* log, rdpSettings* settings, const char*
WLog_Print(log, WLOG_WARN,
"%s - SERVER BUG: The support for this feature was not announced!",
orderName);
if (extendedMessage)
WLog_Print(log, WLOG_WARN, "%s", extendedMessage);
return TRUE;
}
else
@ -200,6 +203,8 @@ static BOOL check_order_activated(wLog* log, rdpSettings* settings, const char*
"%s - SERVER BUG: The support for this feature was not announced! Use "
"/relax-order-checks to ignore",
orderName);
if (extendedMessage)
WLog_Print(log, WLOG_WARN, "%s", extendedMessage);
return FALSE;
}
}
@ -210,6 +215,7 @@ static BOOL check_order_activated(wLog* log, rdpSettings* settings, const char*
static BOOL check_alt_order_supported(wLog* log, rdpSettings* settings, BYTE orderType,
const char* orderName)
{
const char* extendedMessage = NULL;
BOOL condition = FALSE;
switch (orderType)
@ -217,6 +223,7 @@ static BOOL check_alt_order_supported(wLog* log, rdpSettings* settings, BYTE ord
case ORDER_TYPE_CREATE_OFFSCREEN_BITMAP:
case ORDER_TYPE_SWITCH_SURFACE:
condition = settings->OffscreenSupportLevel != 0;
extendedMessage = "Adding +offscreen-cache might mitigate";
break;
case ORDER_TYPE_CREATE_NINE_GRID_BITMAP:
@ -252,12 +259,13 @@ static BOOL check_alt_order_supported(wLog* log, rdpSettings* settings, BYTE ord
break;
}
return check_order_activated(log, settings, orderName, condition);
return check_order_activated(log, settings, orderName, condition, extendedMessage);
}
static BOOL check_secondary_order_supported(wLog* log, rdpSettings* settings, BYTE orderType,
const char* orderName)
{
const char* extendedMessage = NULL;
BOOL condition = FALSE;
switch (orderType)
@ -265,15 +273,18 @@ static BOOL check_secondary_order_supported(wLog* log, rdpSettings* settings, BY
case ORDER_TYPE_BITMAP_UNCOMPRESSED:
case ORDER_TYPE_CACHE_BITMAP_COMPRESSED:
condition = settings->BitmapCacheEnabled;
extendedMessage = "Adding +bitmap-cache might mitigate";
break;
case ORDER_TYPE_BITMAP_UNCOMPRESSED_V2:
case ORDER_TYPE_BITMAP_COMPRESSED_V2:
condition = settings->BitmapCacheEnabled;
extendedMessage = "Adding +bitmap-cache might mitigate";
break;
case ORDER_TYPE_BITMAP_COMPRESSED_V3:
condition = settings->BitmapCacheV3Enabled;
extendedMessage = "Adding +bitmap-cache might mitigate";
break;
case ORDER_TYPE_CACHE_COLOR_TABLE:
@ -308,12 +319,13 @@ static BOOL check_secondary_order_supported(wLog* log, rdpSettings* settings, BY
break;
}
return check_order_activated(log, settings, orderName, condition);
return check_order_activated(log, settings, orderName, condition, extendedMessage);
}
static BOOL check_primary_order_supported(wLog* log, rdpSettings* settings, UINT32 orderType,
const char* orderName)
{
const char* extendedMessage = NULL;
BOOL condition = FALSE;
switch (orderType)
@ -411,7 +423,7 @@ static BOOL check_primary_order_supported(wLog* log, rdpSettings* settings, UINT
break;
}
return check_order_activated(log, settings, orderName, condition);
return check_order_activated(log, settings, orderName, condition, extendedMessage);
}
static const char* primary_order_string(UINT32 orderType)
@ -2611,7 +2623,7 @@ static BOOL update_decompress_brush(wStream* s, BYTE* output, size_t outSize, BY
const BYTE* palette = Stream_Pointer(s) + 16;
const INT32 bytesPerPixel = ((bpp + 1) / 8);
if (!Stream_SafeSeek(s, 16ULL + 7ULL * bytesPerPixel)) // 64 / 4
if (Stream_GetRemainingLength(s) < 16 + bytesPerPixel * 4)
return FALSE;
for (y = 7; y >= 0; y--)
@ -3605,7 +3617,7 @@ static BOOL update_recv_primary_order(rdpUpdate* update, wStream* s, BYTE flags)
static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flags)
{
BOOL rc = FALSE;
size_t start, end, diff;
size_t start, end, pos, diff;
BYTE orderType;
UINT16 extraFlags;
UINT16 orderLength;
@ -3754,15 +3766,15 @@ static BOOL update_recv_secondary_order(rdpUpdate* update, wStream* s, BYTE flag
WLog_Print(update->log, WLOG_ERROR, "SECONDARY ORDER %s failed", name);
}
start += orderLength + 7;
end = Stream_GetPosition(s);
if (start > end)
end = start + orderLength + 7;
pos = Stream_GetPosition(s);
if (pos > end)
{
WLog_Print(update->log, WLOG_WARN, "SECONDARY_ORDER %s: read %" PRIuz "bytes too much",
name, end - start);
name, pos - end);
return FALSE;
}
diff = end - start;
diff = end - pos;
if (diff > 0)
{
WLog_Print(update->log, WLOG_DEBUG,

View File

@ -84,7 +84,7 @@ BOOL tpdu_read_header(wStream* s, BYTE* code, BYTE* li, UINT16 tpktlength)
if (*li + 4 > tpktlength)
{
WLog_ERR(TAG, "tpdu length %" PRIu16 " > tpkt header length %" PRIu16, li, tpktlength);
WLog_ERR(TAG, "tpdu length %" PRIu8 " > tpkt header length %" PRIu16, *li, tpktlength);
return FALSE;
}

View File

@ -31,6 +31,17 @@
#define TAG FREERDP_TAG("gdi")
static BOOL is_rect_valid(const RECTANGLE_16* rect, size_t width, size_t height)
{
if (!rect)
return FALSE;
if ((rect->left > rect->right) || (rect->right > width))
return FALSE;
if ((rect->top > rect->bottom) || (rect->bottom > height))
return FALSE;
return TRUE;
}
static DWORD gfx_align_scanline(DWORD widthInBytes, DWORD alignment)
{
const UINT32 align = alignment;
@ -1114,7 +1125,6 @@ static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context,
BOOL sameSurface;
UINT32 nWidth, nHeight;
const RECTANGLE_16* rectSrc;
RDPGFX_POINT16* destPt;
RECTANGLE_16 invalidRect;
gdiGfxSurface* surfaceSrc;
gdiGfxSurface* surfaceDst;
@ -1134,12 +1144,18 @@ static UINT gdi_SurfaceToSurface(RdpgfxClientContext* context,
if (!surfaceSrc || !surfaceDst)
goto fail;
if (!is_rect_valid(rectSrc, surfaceSrc->width, surfaceSrc->height))
goto fail;
nWidth = rectSrc->right - rectSrc->left;
nHeight = rectSrc->bottom - rectSrc->top;
for (index = 0; index < surfaceToSurface->destPtsCount; index++)
{
destPt = &surfaceToSurface->destPts[index];
const RDPGFX_POINT16* destPt = &surfaceToSurface->destPts[index];
const RECTANGLE_16 rect = { destPt->x, destPt->y, destPt->x + nWidth, destPt->y + nHeight };
if (!is_rect_valid(&rect, surfaceDst->width, surfaceDst->height))
goto fail;
if (!freerdp_image_copy(surfaceDst->data, surfaceDst->format, surfaceDst->scanline,
destPt->x, destPt->y, nWidth, nHeight, surfaceSrc->data,
@ -1192,6 +1208,9 @@ static UINT gdi_SurfaceToCache(RdpgfxClientContext* context,
if (!surface)
goto fail;
if (!is_rect_valid(rect, surface->width, surface->height))
goto fail;
cacheEntry = (gdiGfxCacheEntry*)calloc(1, sizeof(gdiGfxCacheEntry));
if (!cacheEntry)
@ -1234,7 +1253,6 @@ static UINT gdi_CacheToSurface(RdpgfxClientContext* context,
{
UINT status = ERROR_INTERNAL_ERROR;
UINT16 index;
RDPGFX_POINT16* destPt;
gdiGfxSurface* surface;
gdiGfxCacheEntry* cacheEntry;
RECTANGLE_16 invalidRect;
@ -1248,7 +1266,12 @@ static UINT gdi_CacheToSurface(RdpgfxClientContext* context,
for (index = 0; index < cacheToSurface->destPtsCount; index++)
{
destPt = &cacheToSurface->destPts[index];
const RDPGFX_POINT16* destPt = &cacheToSurface->destPts[index];
const RECTANGLE_16 rect = { destPt->x, destPt->y, destPt->x + cacheEntry->width,
destPt->y + cacheEntry->height };
if (!is_rect_valid(&rect, surface->width, surface->height))
goto fail;
if (!freerdp_image_copy(surface->data, surface->format, surface->scanline, destPt->x,
destPt->y, cacheEntry->width, cacheEntry->height, cacheEntry->data,

View File

@ -1,12 +1,11 @@
#!/bin/bash -e
function run {
echo "[RUN] $@"
"$@"
RES=$?
if [[ $RES -ne 0 ]];
then
echo "[ERROR] $@ retured $RES"
echo "[ERROR] $@ returned $RES" >&2
exit 1
fi
}
@ -38,7 +37,7 @@ run md5sum freerdp-${TAG}.tar.gz > freerdp-${TAG}.tar.gz.md5
run sha1sum freerdp-${TAG}.tar.gz > freerdp-${TAG}.tar.gz.sha1
run sha256sum freerdp-${TAG}.tar.gz > freerdp-${TAG}.tar.gz.sha256
run zip freerdp-${TAG}.zip freerdp-${TAG}
run zip -r freerdp-${TAG}.zip freerdp-${TAG}
run md5sum freerdp-${TAG}.zip > freerdp-${TAG}.zip.md5
run sha1sum freerdp-${TAG}.zip > freerdp-${TAG}.zip.sha1
run sha256sum freerdp-${TAG}.zip > freerdp-${TAG}.zip.sha256

View File

@ -35,6 +35,7 @@
#include "pf_update.h"
#include "pf_log.h"
#include "pf_modules.h"
#include "pf_input.h"
#include "pf_capture.h"
#define TAG PROXY_TAG("client")
@ -72,6 +73,19 @@ static void pf_client_on_error_info(void* ctx, ErrorInfoEventArgs* e)
freerdp_send_error_info(ps->context.rdp);
}
static void pf_client_on_activated(void* ctx, ActivatedEventArgs* e)
{
pClientContext* pc = (pClientContext*)ctx;
pServerContext* ps = pc->pdata->ps;
freerdp_peer* peer = ps->context.peer;
LOG_INFO(TAG, pc, "client activated, registering server input callbacks");
/* Register server input/update callbacks only after proxy client is fully activated */
pf_server_register_input_callbacks(peer->input);
pf_server_register_update_callbacks(peer->update);
}
static BOOL pf_client_load_rdpsnd(pClientContext* pc)
{
rdpContext* context = (rdpContext*)pc;
@ -156,12 +170,6 @@ static BOOL pf_client_use_peer_load_balance_info(pClientContext* pc)
return TRUE;
}
/**
* Called before a connection is established.
*
* TODO: Take client to proxy settings and use channel whitelist to filter out
* unwanted channels.
*/
static BOOL pf_client_pre_connect(freerdp* instance)
{
pClientContext* pc = (pClientContext*)instance->context;
@ -203,6 +211,7 @@ static BOOL pf_client_pre_connect(freerdp* instance)
PubSub_SubscribeChannelDisconnected(instance->context->pubSub,
pf_channels_on_client_channel_disconnect);
PubSub_SubscribeErrorInfo(instance->context->pubSub, pf_client_on_error_info);
PubSub_SubscribeActivated(instance->context->pubSub, pf_client_on_activated);
/**
* Load all required plugins / channels / libraries specified by current
* settings.
@ -273,6 +282,13 @@ static BOOL pf_client_receive_channel_data_hook(freerdp* instance, UINT16 channe
return client_receive_channel_data_original(instance, channelId, data, size, flags, totalSize);
}
static BOOL pf_client_on_server_heartbeat(freerdp* instance, BYTE period, BYTE count1, BYTE count2)
{
pClientContext* pc = (pClientContext*)instance->context;
pServerContext* ps = pc->pdata->ps;
return freerdp_heartbeat_send_heartbeat_pdu(ps->context.peer, period, count1, count2);
}
/**
* Called after a RDP connection was successfully established.
* Settings might have changed during negotiation of client / server feature
@ -348,6 +364,8 @@ static BOOL pf_client_post_connect(freerdp* instance)
}
}
instance->heartbeat->ServerHeartbeat = pf_client_on_server_heartbeat;
/*
* after the connection fully established and settings were negotiated with target server,
* send a reactivation sequence to the client with the negotiated settings. This way,

View File

@ -79,12 +79,21 @@ struct proxy_config
typedef struct proxy_config proxyConfig;
FREERDP_API BOOL pf_config_get_uint16(wIniFile* ini, const char* section, const char* key,
UINT16* result);
FREERDP_API BOOL pf_config_get_uint32(wIniFile* ini, const char* section, const char* key,
UINT32* result);
FREERDP_API BOOL pf_config_get_bool(wIniFile* ini, const char* section, const char* key);
FREERDP_API const char* pf_config_get_str(wIniFile* ini, const char* section, const char* key);
#ifdef __cplusplus
extern "C"
{
#endif
FREERDP_API BOOL pf_config_get_uint16(wIniFile* ini, const char* section, const char* key,
UINT16* result);
FREERDP_API BOOL pf_config_get_uint32(wIniFile* ini, const char* section, const char* key,
UINT32* result);
FREERDP_API BOOL pf_config_get_bool(wIniFile* ini, const char* section, const char* key);
FREERDP_API const char* pf_config_get_str(wIniFile* ini, const char* section, const char* key);
#ifdef __cplusplus
};
#endif
proxyConfig* pf_server_config_load(const char* path);
void pf_server_config_print(proxyConfig* config);

View File

@ -38,6 +38,15 @@ BOOL pf_rail_context_init(pServerContext* ps)
return FALSE;
}
/*
* when mstsc reconnects, it doesn't wait for a second handshake, so update all handshake flags
* to be SET, then set them again when the remote server sends his handshake.
*/
rail_server_set_handshake_ex_flags(rail,
TS_RAIL_ORDER_HANDSHAKEEX_FLAGS_HIDEF |
TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_EXTENDED_SPI_SUPPORTED |
TS_RAIL_ORDER_HANDSHAKE_EX_FLAGS_SNAP_ARRANGE_SUPPORTED);
rail->rdpcontext = (rdpContext*)ps;
return TRUE;
}

View File

@ -36,7 +36,6 @@
#include "pf_config.h"
#include "pf_client.h"
#include "pf_context.h"
#include "pf_input.h"
#include "pf_update.h"
#include "pf_rdpgfx.h"
#include "pf_disp.h"
@ -181,8 +180,6 @@ static BOOL pf_server_post_connect(freerdp_peer* peer)
return FALSE;
}
pf_server_register_input_callbacks(peer->input);
pf_server_register_update_callbacks(peer->update);
return pf_modules_run_hook(HOOK_TYPE_SERVER_POST_CONNECT, pdata);
}

View File

@ -51,7 +51,7 @@ if (NOT WIN32)
endif()
# Soname versioning
set(RAW_VERSION_STRING "2.1.2")
set(RAW_VERSION_STRING "2.2.0")
if(EXISTS "${CMAKE_SOURCE_DIR}/.source_tag")
file(READ ${CMAKE_SOURCE_DIR}/.source_tag RAW_VERSION_STRING)
elseif(USE_VERSION_FROM_GIT_TAG)

View File

@ -206,7 +206,7 @@ BOOL GetUserNameExA(EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG
switch (NameFormat)
{
case NameSamCompatible:
#ifndef getlogin_r
#ifndef HAVE_GETLOGIN_R
strncpy(login, getlogin(), sizeof(login));
#else
if (getlogin_r(login, sizeof(login)) != 0)

View File

@ -341,7 +341,7 @@ DWORD GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
time_t t;
struct tm tres;
struct tm* local_time;
TIME_ZONE_ENTRY* dtz;
TIME_ZONE_ENTRY* dtz = NULL;
LPTIME_ZONE_INFORMATION tz = lpTimeZoneInformation;
lpTimeZoneInformation->StandardBias = 0;
time(&t);