Milestone 5: deliver embedded RDP sessions and lifecycle hardening
This commit is contained in:
25
third_party/FreeRDP/channels/cliprdr/client/CMakeLists.txt
vendored
Normal file
25
third_party/FreeRDP/channels/cliprdr/client/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# FreeRDP: A Remote Desktop Protocol Implementation
|
||||
# FreeRDP cmake build script
|
||||
#
|
||||
# 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.
|
||||
|
||||
define_channel_client("cliprdr")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS cliprdr_format.c cliprdr_format.h cliprdr_main.c cliprdr_main.h ../cliprdr_common.h
|
||||
../cliprdr_common.c
|
||||
)
|
||||
|
||||
set(${MODULE_PREFIX}_LIBS winpr freerdp)
|
||||
add_channel_client_library(${MODULE_PREFIX} ${MODULE_NAME} ${CHANNEL_NAME} FALSE "VirtualChannelEntryEx")
|
||||
280
third_party/FreeRDP/channels/cliprdr/client/cliprdr_format.c
vendored
Normal file
280
third_party/FreeRDP/channels/cliprdr/client/cliprdr_format.c
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Clipboard Virtual Channel
|
||||
*
|
||||
* Copyright 2009-2011 Jay Sorg
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.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.
|
||||
*/
|
||||
|
||||
#include <freerdp/config.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
#include <winpr/clipboard.h>
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/settings.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <freerdp/client/cliprdr.h>
|
||||
|
||||
#include "cliprdr_main.h"
|
||||
#include "cliprdr_format.h"
|
||||
#include "../cliprdr_common.h"
|
||||
|
||||
CLIPRDR_FORMAT_LIST cliprdr_filter_format_list(const CLIPRDR_FORMAT_LIST* list, const UINT32 mask,
|
||||
const UINT32 checkMask)
|
||||
{
|
||||
const UINT32 maskData =
|
||||
checkMask & (CLIPRDR_FLAG_LOCAL_TO_REMOTE | CLIPRDR_FLAG_REMOTE_TO_LOCAL);
|
||||
const UINT32 maskFiles =
|
||||
checkMask & (CLIPRDR_FLAG_LOCAL_TO_REMOTE_FILES | CLIPRDR_FLAG_REMOTE_TO_LOCAL_FILES);
|
||||
WINPR_ASSERT(list);
|
||||
|
||||
CLIPRDR_FORMAT_LIST filtered = WINPR_C_ARRAY_INIT;
|
||||
filtered.common.msgType = CB_FORMAT_LIST;
|
||||
filtered.numFormats = list->numFormats;
|
||||
filtered.formats = calloc(filtered.numFormats, sizeof(CLIPRDR_FORMAT));
|
||||
|
||||
size_t wpos = 0;
|
||||
if ((mask & checkMask) == checkMask)
|
||||
{
|
||||
for (size_t x = 0; x < list->numFormats; x++)
|
||||
{
|
||||
const CLIPRDR_FORMAT* format = &list->formats[x];
|
||||
CLIPRDR_FORMAT* cur = &filtered.formats[x];
|
||||
cur->formatId = format->formatId;
|
||||
if (format->formatName)
|
||||
cur->formatName = _strdup(format->formatName);
|
||||
wpos++;
|
||||
}
|
||||
}
|
||||
else if ((mask & maskFiles) != 0)
|
||||
{
|
||||
for (size_t x = 0; x < list->numFormats; x++)
|
||||
{
|
||||
const CLIPRDR_FORMAT* format = &list->formats[x];
|
||||
CLIPRDR_FORMAT* cur = &filtered.formats[wpos];
|
||||
|
||||
if (!format->formatName)
|
||||
continue;
|
||||
if (strcmp(format->formatName, type_FileGroupDescriptorW) == 0 ||
|
||||
strcmp(format->formatName, type_FileContents) == 0)
|
||||
{
|
||||
cur->formatId = format->formatId;
|
||||
cur->formatName = _strdup(format->formatName);
|
||||
wpos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((mask & maskData) != 0)
|
||||
{
|
||||
for (size_t x = 0; x < list->numFormats; x++)
|
||||
{
|
||||
const CLIPRDR_FORMAT* format = &list->formats[x];
|
||||
CLIPRDR_FORMAT* cur = &filtered.formats[wpos];
|
||||
|
||||
if (!format->formatName ||
|
||||
(strcmp(format->formatName, type_FileGroupDescriptorW) != 0 &&
|
||||
strcmp(format->formatName, type_FileContents) != 0))
|
||||
{
|
||||
cur->formatId = format->formatId;
|
||||
if (format->formatName)
|
||||
cur->formatName = _strdup(format->formatName);
|
||||
wpos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
WINPR_ASSERT(wpos <= UINT32_MAX);
|
||||
filtered.numFormats = (UINT32)wpos;
|
||||
return filtered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen,
|
||||
UINT16 msgFlags)
|
||||
{
|
||||
CLIPRDR_FORMAT_LIST formatList = WINPR_C_ARRAY_INIT;
|
||||
CLIPRDR_FORMAT_LIST filteredFormatList = WINPR_C_ARRAY_INIT;
|
||||
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
formatList.common.msgType = CB_FORMAT_LIST;
|
||||
formatList.common.msgFlags = msgFlags;
|
||||
formatList.common.dataLen = dataLen;
|
||||
|
||||
if ((error =
|
||||
cliprdr_read_format_list(cliprdr->log, s, &formatList, cliprdr->useLongFormatNames)))
|
||||
goto error_out;
|
||||
|
||||
{
|
||||
const UINT32 mask = freerdp_settings_get_uint32(context->rdpcontext->settings,
|
||||
FreeRDP_ClipboardFeatureMask);
|
||||
filteredFormatList = cliprdr_filter_format_list(
|
||||
&formatList, mask, CLIPRDR_FLAG_REMOTE_TO_LOCAL | CLIPRDR_FLAG_REMOTE_TO_LOCAL_FILES);
|
||||
}
|
||||
|
||||
if (filteredFormatList.numFormats == 0)
|
||||
goto error_out;
|
||||
|
||||
{
|
||||
const DWORD level = WLOG_DEBUG;
|
||||
if (WLog_IsLevelActive(cliprdr->log, level))
|
||||
{
|
||||
WLog_Print(cliprdr->log, level, "ServerFormatList: numFormats: %" PRIu32 "",
|
||||
formatList.numFormats);
|
||||
for (size_t x = 0; x < formatList.numFormats; x++)
|
||||
{
|
||||
const CLIPRDR_FORMAT* format = &formatList.formats[x];
|
||||
WLog_Print(cliprdr->log, level, "[%" PRIuz "]: id=0x%08" PRIx32 " [%s|%s]", x,
|
||||
format->formatId, ClipboardGetFormatIdString(format->formatId),
|
||||
format->formatName);
|
||||
}
|
||||
|
||||
WLog_Print(cliprdr->log, level, "ServerFormatList [filtered]: numFormats: %" PRIu32 "",
|
||||
filteredFormatList.numFormats);
|
||||
for (size_t x = 0; x < filteredFormatList.numFormats; x++)
|
||||
{
|
||||
const CLIPRDR_FORMAT* format = &filteredFormatList.formats[x];
|
||||
WLog_Print(cliprdr->log, level, "[%" PRIuz "]: id=0x%08" PRIx32 " [%s|%s]", x,
|
||||
format->formatId, ClipboardGetFormatIdString(format->formatId),
|
||||
format->formatName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (context->ServerFormatList)
|
||||
{
|
||||
if ((error = context->ServerFormatList(context, &filteredFormatList)))
|
||||
WLog_Print(cliprdr->log, WLOG_ERROR, "ServerFormatList failed with error %" PRIu32 "",
|
||||
error);
|
||||
}
|
||||
|
||||
error_out:
|
||||
cliprdr_free_format_list(&filteredFormatList);
|
||||
cliprdr_free_format_list(&formatList);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, WINPR_ATTR_UNUSED wStream* s,
|
||||
UINT32 dataLen, UINT16 msgFlags)
|
||||
{
|
||||
CLIPRDR_FORMAT_LIST_RESPONSE formatListResponse = WINPR_C_ARRAY_INIT;
|
||||
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatListResponse");
|
||||
|
||||
formatListResponse.common.msgType = CB_FORMAT_LIST_RESPONSE;
|
||||
formatListResponse.common.msgFlags = msgFlags;
|
||||
formatListResponse.common.dataLen = dataLen;
|
||||
|
||||
IFCALLRET(context->ServerFormatListResponse, error, context, &formatListResponse);
|
||||
if (error)
|
||||
WLog_Print(cliprdr->log, WLOG_ERROR,
|
||||
"ServerFormatListResponse failed with error %" PRIu32 "!", error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen,
|
||||
UINT16 msgFlags)
|
||||
{
|
||||
CLIPRDR_FORMAT_DATA_REQUEST formatDataRequest = WINPR_C_ARRAY_INIT;
|
||||
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
formatDataRequest.common.msgType = CB_FORMAT_DATA_REQUEST;
|
||||
formatDataRequest.common.msgFlags = msgFlags;
|
||||
formatDataRequest.common.dataLen = dataLen;
|
||||
|
||||
if ((error = cliprdr_read_format_data_request(s, &formatDataRequest)))
|
||||
return error;
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG, "ServerFormatDataRequest (0x%08" PRIx32 " [%s])",
|
||||
formatDataRequest.requestedFormatId,
|
||||
ClipboardGetFormatIdString(formatDataRequest.requestedFormatId));
|
||||
|
||||
const UINT32 mask =
|
||||
freerdp_settings_get_uint32(context->rdpcontext->settings, FreeRDP_ClipboardFeatureMask);
|
||||
if ((mask & (CLIPRDR_FLAG_LOCAL_TO_REMOTE | CLIPRDR_FLAG_LOCAL_TO_REMOTE_FILES)) == 0)
|
||||
{
|
||||
return cliprdr_send_error_response(cliprdr, CB_FORMAT_DATA_RESPONSE);
|
||||
}
|
||||
|
||||
context->lastRequestedFormatId = formatDataRequest.requestedFormatId;
|
||||
IFCALLRET(context->ServerFormatDataRequest, error, context, &formatDataRequest);
|
||||
if (error)
|
||||
WLog_Print(cliprdr->log, WLOG_ERROR,
|
||||
"ServerFormatDataRequest failed with error %" PRIu32 "!", error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
* @return 0 on success, otherwise a Win32 error code
|
||||
*/
|
||||
UINT cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen,
|
||||
UINT16 msgFlags)
|
||||
{
|
||||
CLIPRDR_FORMAT_DATA_RESPONSE formatDataResponse = WINPR_C_ARRAY_INIT;
|
||||
CliprdrClientContext* context = cliprdr_get_client_interface(cliprdr);
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG,
|
||||
"ServerFormatDataResponse: msgFlags=0x%08" PRIx32 ", dataLen=%" PRIu32, msgFlags,
|
||||
dataLen);
|
||||
|
||||
formatDataResponse.common.msgType = CB_FORMAT_DATA_RESPONSE;
|
||||
formatDataResponse.common.msgFlags = msgFlags;
|
||||
formatDataResponse.common.dataLen = dataLen;
|
||||
|
||||
if ((error = cliprdr_read_format_data_response(s, &formatDataResponse)))
|
||||
return error;
|
||||
|
||||
const UINT32 mask =
|
||||
freerdp_settings_get_uint32(context->rdpcontext->settings, FreeRDP_ClipboardFeatureMask);
|
||||
if ((mask & (CLIPRDR_FLAG_REMOTE_TO_LOCAL | CLIPRDR_FLAG_REMOTE_TO_LOCAL_FILES)) == 0)
|
||||
{
|
||||
WLog_Print(cliprdr->log, WLOG_WARN,
|
||||
"Received ServerFormatDataResponse but remote -> local clipboard is disabled");
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
IFCALLRET(context->ServerFormatDataResponse, error, context, &formatDataResponse);
|
||||
if (error)
|
||||
WLog_Print(cliprdr->log, WLOG_ERROR,
|
||||
"ServerFormatDataResponse failed with error %" PRIu32 "!", error);
|
||||
|
||||
return error;
|
||||
}
|
||||
59
third_party/FreeRDP/channels/cliprdr/client/cliprdr_format.h
vendored
Normal file
59
third_party/FreeRDP/channels/cliprdr/client/cliprdr_format.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Clipboard Virtual Channel
|
||||
*
|
||||
* Copyright 2009-2011 Jay Sorg
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.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_CHANNEL_CLIPRDR_CLIENT_FORMAT_H
|
||||
#define FREERDP_CHANNEL_CLIPRDR_CLIENT_FORMAT_H
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/channels/cliprdr.h>
|
||||
|
||||
#include "cliprdr_main.h"
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL
|
||||
UINT cliprdr_process_format_list(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen,
|
||||
UINT16 msgFlags);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL
|
||||
UINT cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen,
|
||||
UINT16 msgFlags);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL
|
||||
UINT cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen,
|
||||
UINT16 msgFlags);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL
|
||||
UINT cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UINT32 dataLen,
|
||||
UINT16 msgFlags);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL
|
||||
CLIPRDR_FORMAT_LIST cliprdr_filter_format_list(const CLIPRDR_FORMAT_LIST* list, UINT32 mask,
|
||||
UINT32 checkMask);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_CLIPRDR_CLIENT_FORMAT_H */
|
||||
1209
third_party/FreeRDP/channels/cliprdr/client/cliprdr_main.c
vendored
Normal file
1209
third_party/FreeRDP/channels/cliprdr/client/cliprdr_main.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
63
third_party/FreeRDP/channels/cliprdr/client/cliprdr_main.h
vendored
Normal file
63
third_party/FreeRDP/channels/cliprdr/client/cliprdr_main.h
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Clipboard Virtual Channel
|
||||
*
|
||||
* Copyright 2009-2011 Jay Sorg
|
||||
* Copyright 2010-2011 Vic Lee
|
||||
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.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_CHANNEL_CLIPRDR_CLIENT_MAIN_H
|
||||
#define FREERDP_CHANNEL_CLIPRDR_CLIENT_MAIN_H
|
||||
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/svc.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/channels/log.h>
|
||||
#include <freerdp/client/cliprdr.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CHANNEL_DEF channelDef;
|
||||
CHANNEL_ENTRY_POINTS_FREERDP_EX channelEntryPoints;
|
||||
|
||||
CliprdrClientContext* context;
|
||||
|
||||
wLog* log;
|
||||
void* InitHandle;
|
||||
DWORD OpenHandle;
|
||||
void* MsgsHandle;
|
||||
|
||||
BOOL capabilitiesReceived;
|
||||
BOOL useLongFormatNames;
|
||||
BOOL streamFileClipEnabled;
|
||||
BOOL fileClipNoFilePaths;
|
||||
BOOL canLockClipData;
|
||||
BOOL hasHugeFileSupport;
|
||||
BOOL initialFormatListSent;
|
||||
} cliprdrPlugin;
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr);
|
||||
|
||||
WINPR_ATTR_NODISCARD
|
||||
FREERDP_LOCAL UINT cliprdr_send_error_response(cliprdrPlugin* cliprdr, UINT16 type);
|
||||
|
||||
FREERDP_LOCAL extern const char type_FileGroupDescriptorW[];
|
||||
|
||||
FREERDP_LOCAL extern const char type_FileContents[];
|
||||
|
||||
#endif /* FREERDP_CHANNEL_CLIPRDR_CLIENT_MAIN_H */
|
||||
Reference in New Issue
Block a user