client/X11: Relieve CLIPRDR filename restriction when possible

Microsoft Windows imposes strict filename restrictions on its platform.
As RDP is developed by Microsoft and the RDS in MS Windows is typically
used as remote desktop server for the RDP protocol, these filename
restrictions are also enforced in WinPR, when copy-pasting files over
the clipboard.
However, in some connections no peer on MS Windows is involved and in
these situations, these filename restrictions are just an annoyance.

With a recent API addition in WinPR, it is now possible to override the
callback, where the filename is checked, whether it is valid.
So, use this new API to relieve the filename restriction, when the
connected remote desktop server is not on MS Windows.
This commit is contained in:
Pascal Nowack 2022-07-06 13:46:39 +02:00 committed by akallabeth
parent 43b609cd6c
commit 6492a00959
4 changed files with 44 additions and 23 deletions

View File

@ -1342,6 +1342,7 @@ static BOOL xf_post_connect(freerdp* instance)
rdpSettings* settings;
ResizeWindowEventArgs e;
xfContext* xfc;
BOOL serverIsWindowsPlatform;
WINPR_ASSERT(instance);
xfc = (xfContext*)instance->context;
@ -1422,7 +1423,9 @@ static BOOL xf_post_connect(freerdp* instance)
update->SetKeyboardIndicators = xf_keyboard_set_indicators;
update->SetKeyboardImeStatus = xf_keyboard_set_ime_status;
if (settings->RedirectClipboard && !(xfc->clipboard = xf_clipboard_new(xfc)))
serverIsWindowsPlatform = (settings->OsMajorType == OSMAJORTYPE_WINDOWS);
if (settings->RedirectClipboard &&
!(xfc->clipboard = xf_clipboard_new(xfc, !serverIsWindowsPlatform)))
return FALSE;
if (!(xfc->xfDisp = xf_disp_new(xfc)))

View File

@ -2569,6 +2569,26 @@ static UINT xf_cliprdr_clipboard_file_range_failure(wClipboardDelegate* delegate
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
}
static BOOL xf_cliprdr_clipboard_is_valid_unix_filename(LPCWSTR filename)
{
LPCWSTR c;
if (!filename)
return FALSE;
if (filename[0] == L'\0')
return FALSE;
/* Reserved characters */
for (c = filename; *c; ++c)
{
if (*c == L'/')
return FALSE;
}
return TRUE;
}
#ifdef WITH_FUSE
/* For better understanding the relationship between ino and index of arraylist*/
static inline xfCliprdrFuseInode* xf_cliprdr_fuse_util_get_inode(wArrayList* ino_list,
@ -3064,7 +3084,7 @@ static DWORD WINAPI xf_cliprdr_fuse_thread(LPVOID arg)
}
#endif
xfClipboard* xf_clipboard_new(xfContext* xfc)
xfClipboard* xf_clipboard_new(xfContext* xfc, BOOL relieveFilenameRestriction)
{
int i, n = 0;
rdpChannels* channels;
@ -3253,6 +3273,13 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
clipboard->delegate->ClipboardFileSizeFailure = xf_cliprdr_clipboard_file_size_failure;
clipboard->delegate->ClipboardFileRangeSuccess = xf_cliprdr_clipboard_file_range_success;
clipboard->delegate->ClipboardFileRangeFailure = xf_cliprdr_clipboard_file_range_failure;
if (relieveFilenameRestriction)
{
WLog_DBG(TAG, "Relieving CLIPRDR filename restriction");
clipboard->delegate->IsFileNameComponentValid = xf_cliprdr_clipboard_is_valid_unix_filename;
}
return clipboard;
#ifdef WITH_FUSE

View File

@ -25,7 +25,7 @@
#include <freerdp/client/cliprdr.h>
xfClipboard* xf_clipboard_new(xfContext* xfc);
xfClipboard* xf_clipboard_new(xfContext* xfc, BOOL relieveFilenameRestriction);
void xf_clipboard_free(xfClipboard* clipboard);
void xf_cliprdr_init(xfContext* xfc, CliprdrClientContext* cliprdr);

View File

@ -168,26 +168,17 @@ static BOOL rdp_read_general_capability_set(wStream* s, rdpSettings* settings)
if (!Stream_CheckAndLogRequiredLength(TAG, s, 20))
return FALSE;
if (settings->ServerMode)
{
Stream_Read_UINT16(s, settings->OsMajorType); /* osMajorType (2 bytes) */
Stream_Read_UINT16(s, settings->OsMinorType); /* osMinorType (2 bytes) */
}
else
{
Stream_Seek_UINT16(s); /* osMajorType (2 bytes) */
Stream_Seek_UINT16(s); /* osMinorType (2 bytes) */
}
Stream_Seek_UINT16(s); /* protocolVersion (2 bytes) */
Stream_Seek_UINT16(s); /* pad2OctetsA (2 bytes) */
Stream_Seek_UINT16(s); /* generalCompressionTypes (2 bytes) */
Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */
Stream_Seek_UINT16(s); /* updateCapabilityFlag (2 bytes) */
Stream_Seek_UINT16(s); /* remoteUnshareFlag (2 bytes) */
Stream_Seek_UINT16(s); /* generalCompressionLevel (2 bytes) */
Stream_Read_UINT8(s, refreshRectSupport); /* refreshRectSupport (1 byte) */
Stream_Read_UINT8(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */
Stream_Read_UINT16(s, settings->OsMajorType); /* osMajorType (2 bytes) */
Stream_Read_UINT16(s, settings->OsMinorType); /* osMinorType (2 bytes) */
Stream_Seek_UINT16(s); /* protocolVersion (2 bytes) */
Stream_Seek_UINT16(s); /* pad2OctetsA (2 bytes) */
Stream_Seek_UINT16(s); /* generalCompressionTypes (2 bytes) */
Stream_Read_UINT16(s, extraFlags); /* extraFlags (2 bytes) */
Stream_Seek_UINT16(s); /* updateCapabilityFlag (2 bytes) */
Stream_Seek_UINT16(s); /* remoteUnshareFlag (2 bytes) */
Stream_Seek_UINT16(s); /* generalCompressionLevel (2 bytes) */
Stream_Read_UINT8(s, refreshRectSupport); /* refreshRectSupport (1 byte) */
Stream_Read_UINT8(s, suppressOutputSupport); /* suppressOutputSupport (1 byte) */
settings->NoBitmapCompressionHeader = (extraFlags & NO_BITMAP_COMPRESSION_HDR) ? TRUE : FALSE;
settings->LongCredentialsSupported = (extraFlags & LONG_CREDENTIALS_SUPPORTED) ? TRUE : FALSE;