import from CS git freerdp-2.11.7-1.el8
This commit is contained in:
parent
e86964ca0f
commit
1178f88fc5
@ -1 +1 @@
|
||||
84f51c81388c8b49346b9c5a7c4c982909017443 SOURCES/FreeRDP-2.2.0.tar.gz
|
||||
14a73f092e227a77f3d483658033d15d4501a753 SOURCES/FreeRDP-2.11.7.tar.gz
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
||||
SOURCES/FreeRDP-2.2.0.tar.gz
|
||||
SOURCES/FreeRDP-2.11.7.tar.gz
|
@ -1,315 +0,0 @@
|
||||
From 3ee4cabcfad3a9ccc3c59be21245b57c17e7ae75 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Thu, 21 Jan 2021 14:21:09 +0100
|
||||
Subject: [PATCH 1/3] client: Fix exit codes for /help and similar option
|
||||
|
||||
Currently, non-zero exit code is returned for /version, /buildconfig, /help,
|
||||
/monitor-list, /kbd-list and /kbd-lang-list command-line options for several
|
||||
clients. This is against conventions because 0 is usually returned in
|
||||
such cases. Also, there is potentially another problem that the returned
|
||||
codes overflow on UNIX systems (where the exit code is a number between 0
|
||||
and 255). Let's fix the clients to return 0 in the mentioned cases to honor
|
||||
conventions and 1 for the command-line parsing errors (or -1 for clients
|
||||
who already use that value).
|
||||
|
||||
Fixes: https://github.com/FreeRDP/FreeRDP/issues/6686
|
||||
---
|
||||
client/Sample/tf_freerdp.c | 9 +++++----
|
||||
client/Wayland/wlfreerdp.c | 13 +++++++------
|
||||
client/Windows/cli/wfreerdp.c | 4 ++++
|
||||
client/X11/cli/xfreerdp.c | 22 +++++++++++++---------
|
||||
winpr/include/winpr/cmdline.h | 1 +
|
||||
5 files changed, 30 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/client/Sample/tf_freerdp.c b/client/Sample/tf_freerdp.c
|
||||
index 3ba82c78338..49412cb417c 100644
|
||||
--- a/client/Sample/tf_freerdp.c
|
||||
+++ b/client/Sample/tf_freerdp.c
|
||||
@@ -338,12 +338,13 @@ int main(int argc, char* argv[])
|
||||
goto fail;
|
||||
|
||||
status = freerdp_client_settings_parse_command_line(context->settings, argc, argv, FALSE);
|
||||
- status =
|
||||
- freerdp_client_settings_command_line_status_print(context->settings, status, argc, argv);
|
||||
-
|
||||
if (status)
|
||||
{
|
||||
- rc = 0;
|
||||
+ freerdp_client_settings_command_line_status_print(context->settings, status, argc, argv);
|
||||
+
|
||||
+ if (status <= COMMAND_LINE_STATUS_PRINT && status >= COMMAND_LINE_STATUS_PRINT_LAST)
|
||||
+ rc = 0;
|
||||
+
|
||||
goto fail;
|
||||
}
|
||||
|
||||
diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c
|
||||
index 329d1200941..d77b47986ea 100644
|
||||
--- a/client/Wayland/wlfreerdp.c
|
||||
+++ b/client/Wayland/wlfreerdp.c
|
||||
@@ -628,18 +628,19 @@ int main(int argc, char* argv[])
|
||||
settings = context->settings;
|
||||
|
||||
status = freerdp_client_settings_parse_command_line(settings, argc, argv, FALSE);
|
||||
- status = freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
-
|
||||
if (status)
|
||||
{
|
||||
BOOL list = settings->ListMonitors;
|
||||
+
|
||||
+ freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
+
|
||||
if (list)
|
||||
wlf_list_monitors(wlc);
|
||||
|
||||
- freerdp_client_context_free(context);
|
||||
- if (list)
|
||||
- return 0;
|
||||
- return status;
|
||||
+ if (status <= COMMAND_LINE_STATUS_PRINT && status >= COMMAND_LINE_STATUS_PRINT_LAST)
|
||||
+ rc = 0;
|
||||
+
|
||||
+ goto fail;
|
||||
}
|
||||
|
||||
if (freerdp_client_start(context) != 0)
|
||||
diff --git a/client/Windows/cli/wfreerdp.c b/client/Windows/cli/wfreerdp.c
|
||||
index 7a76eeb9b59..b623067e98e 100644
|
||||
--- a/client/Windows/cli/wfreerdp.c
|
||||
+++ b/client/Windows/cli/wfreerdp.c
|
||||
@@ -108,6 +108,10 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
if (status)
|
||||
{
|
||||
freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
+
|
||||
+ if (status <= COMMAND_LINE_STATUS_PRINT && status >= COMMAND_LINE_STATUS_PRINT_LAST)
|
||||
+ rc = 0;
|
||||
+
|
||||
goto out;
|
||||
}
|
||||
|
||||
diff --git a/client/X11/cli/xfreerdp.c b/client/X11/cli/xfreerdp.c
|
||||
index c8a77f335f4..a3505b24d3c 100644
|
||||
--- a/client/X11/cli/xfreerdp.c
|
||||
+++ b/client/X11/cli/xfreerdp.c
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
+ int rc = 1;
|
||||
int status;
|
||||
HANDLE thread;
|
||||
xfContext* xfc;
|
||||
@@ -56,31 +57,34 @@ int main(int argc, char* argv[])
|
||||
xfc = (xfContext*)context;
|
||||
|
||||
status = freerdp_client_settings_parse_command_line(context->settings, argc, argv, FALSE);
|
||||
-
|
||||
- status = freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
-
|
||||
if (status)
|
||||
{
|
||||
BOOL list = settings->ListMonitors;
|
||||
+
|
||||
+ freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
+
|
||||
if (list)
|
||||
xf_list_monitors(xfc);
|
||||
|
||||
- freerdp_client_context_free(context);
|
||||
- if (list)
|
||||
- return 0;
|
||||
- return status;
|
||||
+ if (status <= COMMAND_LINE_STATUS_PRINT && status >= COMMAND_LINE_STATUS_PRINT_LAST)
|
||||
+ rc = 0;
|
||||
+
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
- freerdp_client_start(context);
|
||||
+ if (freerdp_client_start(context) != 0)
|
||||
+ goto out;
|
||||
|
||||
thread = freerdp_client_get_thread(context);
|
||||
|
||||
WaitForSingleObject(thread, INFINITE);
|
||||
GetExitCodeThread(thread, &dwExitCode);
|
||||
+ rc = xf_exit_code_from_disconnect_reason(dwExitCode);
|
||||
|
||||
freerdp_client_stop(context);
|
||||
|
||||
+out:
|
||||
freerdp_client_context_free(context);
|
||||
|
||||
- return xf_exit_code_from_disconnect_reason(dwExitCode);
|
||||
+ return rc;
|
||||
}
|
||||
diff --git a/winpr/include/winpr/cmdline.h b/winpr/include/winpr/cmdline.h
|
||||
index 865ee8f25c7..9276cda8eb1 100644
|
||||
--- a/winpr/include/winpr/cmdline.h
|
||||
+++ b/winpr/include/winpr/cmdline.h
|
||||
@@ -81,6 +81,7 @@
|
||||
#define COMMAND_LINE_STATUS_PRINT_HELP -2002
|
||||
#define COMMAND_LINE_STATUS_PRINT_VERSION -2003
|
||||
#define COMMAND_LINE_STATUS_PRINT_BUILDCONFIG -2004
|
||||
+#define COMMAND_LINE_STATUS_PRINT_LAST -2999
|
||||
|
||||
/* Command-Line Macros */
|
||||
|
||||
|
||||
From 531dd81836f2c97fcfcfeabdb9671fb76409ce8d Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Fri, 22 Jan 2021 08:40:03 +0100
|
||||
Subject: [PATCH 2/3] Refactored
|
||||
freerdp_client_settings_command_line_status_print_ex
|
||||
|
||||
Now returns 0 if help or version information was requested.
|
||||
---
|
||||
client/Sample/tf_freerdp.c | 7 ++-----
|
||||
client/Wayland/wlfreerdp.c | 5 +----
|
||||
client/Windows/cli/wfreerdp.c | 6 +-----
|
||||
client/X11/cli/xfreerdp.c | 5 +----
|
||||
client/common/cmdline.c | 14 +++++++++-----
|
||||
5 files changed, 14 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/client/Sample/tf_freerdp.c b/client/Sample/tf_freerdp.c
|
||||
index 49412cb417c..e9b9fe8397e 100644
|
||||
--- a/client/Sample/tf_freerdp.c
|
||||
+++ b/client/Sample/tf_freerdp.c
|
||||
@@ -340,11 +340,8 @@ int main(int argc, char* argv[])
|
||||
status = freerdp_client_settings_parse_command_line(context->settings, argc, argv, FALSE);
|
||||
if (status)
|
||||
{
|
||||
- freerdp_client_settings_command_line_status_print(context->settings, status, argc, argv);
|
||||
-
|
||||
- if (status <= COMMAND_LINE_STATUS_PRINT && status >= COMMAND_LINE_STATUS_PRINT_LAST)
|
||||
- rc = 0;
|
||||
-
|
||||
+ rc = freerdp_client_settings_command_line_status_print(context->settings, status, argc,
|
||||
+ argv);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c
|
||||
index d77b47986ea..4a583068968 100644
|
||||
--- a/client/Wayland/wlfreerdp.c
|
||||
+++ b/client/Wayland/wlfreerdp.c
|
||||
@@ -632,14 +632,11 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
BOOL list = settings->ListMonitors;
|
||||
|
||||
- freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
+ rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
|
||||
if (list)
|
||||
wlf_list_monitors(wlc);
|
||||
|
||||
- if (status <= COMMAND_LINE_STATUS_PRINT && status >= COMMAND_LINE_STATUS_PRINT_LAST)
|
||||
- rc = 0;
|
||||
-
|
||||
goto fail;
|
||||
}
|
||||
|
||||
diff --git a/client/Windows/cli/wfreerdp.c b/client/Windows/cli/wfreerdp.c
|
||||
index b623067e98e..e325f84771f 100644
|
||||
--- a/client/Windows/cli/wfreerdp.c
|
||||
+++ b/client/Windows/cli/wfreerdp.c
|
||||
@@ -107,11 +107,7 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
|
||||
if (status)
|
||||
{
|
||||
- freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
-
|
||||
- if (status <= COMMAND_LINE_STATUS_PRINT && status >= COMMAND_LINE_STATUS_PRINT_LAST)
|
||||
- rc = 0;
|
||||
-
|
||||
+ ret = freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
goto out;
|
||||
}
|
||||
|
||||
diff --git a/client/X11/cli/xfreerdp.c b/client/X11/cli/xfreerdp.c
|
||||
index a3505b24d3c..5b702194448 100644
|
||||
--- a/client/X11/cli/xfreerdp.c
|
||||
+++ b/client/X11/cli/xfreerdp.c
|
||||
@@ -61,14 +61,11 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
BOOL list = settings->ListMonitors;
|
||||
|
||||
- freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
+ rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
|
||||
if (list)
|
||||
xf_list_monitors(xfc);
|
||||
|
||||
- if (status <= COMMAND_LINE_STATUS_PRINT && status >= COMMAND_LINE_STATUS_PRINT_LAST)
|
||||
- rc = 0;
|
||||
-
|
||||
goto out;
|
||||
}
|
||||
|
||||
diff --git a/client/common/cmdline.c b/client/common/cmdline.c
|
||||
index ed467afb7d0..dc8367b7cd2 100644
|
||||
--- a/client/common/cmdline.c
|
||||
+++ b/client/common/cmdline.c
|
||||
@@ -1403,14 +1403,14 @@ int freerdp_client_settings_command_line_status_print_ex(rdpSettings* settings,
|
||||
if (status == COMMAND_LINE_STATUS_PRINT_VERSION)
|
||||
{
|
||||
freerdp_client_print_version();
|
||||
- return COMMAND_LINE_STATUS_PRINT_VERSION;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
if (status == COMMAND_LINE_STATUS_PRINT_BUILDCONFIG)
|
||||
{
|
||||
freerdp_client_print_version();
|
||||
freerdp_client_print_buildconfig();
|
||||
- return COMMAND_LINE_STATUS_PRINT_BUILDCONFIG;
|
||||
+ goto out;
|
||||
}
|
||||
else if (status == COMMAND_LINE_STATUS_PRINT)
|
||||
{
|
||||
@@ -1465,15 +1465,19 @@ int freerdp_client_settings_command_line_status_print_ex(rdpSettings* settings,
|
||||
settings->ListMonitors = TRUE;
|
||||
}
|
||||
|
||||
- return COMMAND_LINE_STATUS_PRINT;
|
||||
+ goto out;
|
||||
}
|
||||
else if (status < 0)
|
||||
{
|
||||
freerdp_client_print_command_line_help_ex(argc, argv, custom);
|
||||
- return COMMAND_LINE_STATUS_PRINT_HELP;
|
||||
+ status = COMMAND_LINE_STATUS_PRINT_HELP;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+out:
|
||||
+ if (status <= COMMAND_LINE_STATUS_PRINT && status >= COMMAND_LINE_STATUS_PRINT_LAST)
|
||||
+ return 0;
|
||||
+ return status;
|
||||
}
|
||||
|
||||
static BOOL ends_with(const char* str, const char* ext)
|
||||
|
||||
From 050a68fec901030c7428852f8f536ace055eb2f7 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Fri, 22 Jan 2021 09:32:51 +0100
|
||||
Subject: [PATCH 3/3] Do not eliminate original error status.
|
||||
|
||||
---
|
||||
client/common/cmdline.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/client/common/cmdline.c b/client/common/cmdline.c
|
||||
index dc8367b7cd2..66d3c4fffef 100644
|
||||
--- a/client/common/cmdline.c
|
||||
+++ b/client/common/cmdline.c
|
||||
@@ -1470,7 +1470,6 @@ int freerdp_client_settings_command_line_status_print_ex(rdpSettings* settings,
|
||||
else if (status < 0)
|
||||
{
|
||||
freerdp_client_print_command_line_help_ex(argc, argv, custom);
|
||||
- status = COMMAND_LINE_STATUS_PRINT_HELP;
|
||||
goto out;
|
||||
}
|
||||
|
@ -1,146 +0,0 @@
|
||||
From 4a4ecc32b160e93ee1e37e5617a0197e2d022643 Mon Sep 17 00:00:00 2001
|
||||
From: Armin Novak <armin.novak@thincast.com>
|
||||
Date: Thu, 4 Nov 2021 11:07:41 +0100
|
||||
Subject: [PATCH] Add checks for bitmap and glyph width/heigth values
|
||||
|
||||
CVE-2021-41160
|
||||
|
||||
https://github.com/FreeRDP/FreeRDP/pull/7349
|
||||
|
||||
Signed-off-by: Felipe Borges <felipeborges@gnome.org>
|
||||
---
|
||||
libfreerdp/core/orders.c | 14 ++++++++++++
|
||||
libfreerdp/core/surface.c | 45 +++++++++++++++++++++++++++++++++++++++
|
||||
libfreerdp/core/update.c | 7 ++++++
|
||||
3 files changed, 66 insertions(+)
|
||||
|
||||
diff --git a/libfreerdp/core/orders.c b/libfreerdp/core/orders.c
|
||||
index 74870fae6..44d23a61a 100644
|
||||
--- a/libfreerdp/core/orders.c
|
||||
+++ b/libfreerdp/core/orders.c
|
||||
@@ -1848,6 +1848,13 @@ static BOOL update_read_fast_glyph_order(wStream* s, const ORDER_INFO* orderInfo
|
||||
new_cb = ((glyph->cx + 7) / 8) * glyph->cy;
|
||||
new_cb += ((new_cb % 4) > 0) ? 4 - (new_cb % 4) : 0;
|
||||
|
||||
+ if ((glyph->cx == 0) || (glyph->cy == 0))
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "GLYPH_DATA_V2::cx=%" PRIu32 ", GLYPH_DATA_V2::cy=%" PRIu32,
|
||||
+ glyph->cx, glyph->cy);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if (fastGlyph->cbData < new_cb)
|
||||
return FALSE;
|
||||
|
||||
@@ -2825,6 +2832,13 @@ update_read_create_offscreen_bitmap_order(wStream* s,
|
||||
Stream_Read_UINT16(s, create_offscreen_bitmap->cy); /* cy (2 bytes) */
|
||||
deleteList = &(create_offscreen_bitmap->deleteList);
|
||||
|
||||
+ if ((create_offscreen_bitmap->cx == 0) || (create_offscreen_bitmap->cy == 0))
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "Invalid OFFSCREEN_DELETE_LIST: cx=%" PRIu16 ", cy=%" PRIu16,
|
||||
+ create_offscreen_bitmap->cx, create_offscreen_bitmap->cy);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if (deleteListPresent)
|
||||
{
|
||||
UINT32 i;
|
||||
diff --git a/libfreerdp/core/surface.c b/libfreerdp/core/surface.c
|
||||
index d5c709885..ca89d230c 100644
|
||||
--- a/libfreerdp/core/surface.c
|
||||
+++ b/libfreerdp/core/surface.c
|
||||
@@ -21,6 +21,8 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
+#include <assert.h>
|
||||
+
|
||||
#include <freerdp/utils/pcap.h>
|
||||
#include <freerdp/log.h>
|
||||
|
||||
@@ -62,6 +64,13 @@ static BOOL update_recv_surfcmd_bitmap_ex(wStream* s, TS_BITMAP_DATA_EX* bmp)
|
||||
Stream_Read_UINT16(s, bmp->height);
|
||||
Stream_Read_UINT32(s, bmp->bitmapDataLength);
|
||||
|
||||
+ if ((bmp->width == 0) || (bmp->height == 0))
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "invalid size value width=%" PRIu16 ", height=%" PRIu16, bmp->width,
|
||||
+ bmp->height);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if ((bmp->bpp < 1) || (bmp->bpp > 32))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid bpp value %" PRIu32 "", bmp->bpp);
|
||||
@@ -85,6 +94,39 @@ static BOOL update_recv_surfcmd_bitmap_ex(wStream* s, TS_BITMAP_DATA_EX* bmp)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+static BOOL update_recv_surfcmd_is_rect_valid(const rdpContext* context,
|
||||
+ const SURFACE_BITS_COMMAND* cmd)
|
||||
+{
|
||||
+ assert(context);
|
||||
+ assert(context->settings);
|
||||
+ assert(cmd);
|
||||
+
|
||||
+ /* We need a rectangle with left/top being smaller than right/bottom.
|
||||
+ * Also do not allow empty rectangles. */
|
||||
+ if ((cmd->destTop >= cmd->destBottom) || (cmd->destLeft >= cmd->destRight))
|
||||
+ {
|
||||
+ WLog_WARN(TAG,
|
||||
+ "Empty surface bits command rectangle: %" PRIu16 "x%" PRIu16 "-%" PRIu16
|
||||
+ "x%" PRIu16,
|
||||
+ cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ /* The rectangle needs to fit into our session size */
|
||||
+ if ((cmd->destRight > context->settings->DesktopWidth) ||
|
||||
+ (cmd->destBottom > context->settings->DesktopHeight))
|
||||
+ {
|
||||
+ WLog_WARN(TAG,
|
||||
+ "Invalid surface bits command rectangle: %" PRIu16 "x%" PRIu16 "-%" PRIu16
|
||||
+ "x%" PRIu16 " does not fit %" PRIu32 "x%" PRIu32,
|
||||
+ cmd->destLeft, cmd->destTop, cmd->destRight, cmd->destBottom,
|
||||
+ context->settings->DesktopWidth, context->settings->DesktopHeight);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT16 cmdType)
|
||||
{
|
||||
SURFACE_BITS_COMMAND cmd = { 0 };
|
||||
@@ -98,6 +140,9 @@ static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT
|
||||
Stream_Read_UINT16(s, cmd.destRight);
|
||||
Stream_Read_UINT16(s, cmd.destBottom);
|
||||
|
||||
+ if (!update_recv_surfcmd_is_rect_valid(update->context, &cmd))
|
||||
+ goto fail;
|
||||
+
|
||||
if (!update_recv_surfcmd_bitmap_ex(s, &cmd.bmp))
|
||||
goto fail;
|
||||
|
||||
diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c
|
||||
index ebb82fc2d..e137c3de8 100644
|
||||
--- a/libfreerdp/core/update.c
|
||||
+++ b/libfreerdp/core/update.c
|
||||
@@ -99,6 +99,13 @@ static BOOL update_read_bitmap_data(rdpUpdate* update, wStream* s, BITMAP_DATA*
|
||||
Stream_Read_UINT16(s, bitmapData->flags);
|
||||
Stream_Read_UINT16(s, bitmapData->bitmapLength);
|
||||
|
||||
+ if ((bitmapData->width == 0) || (bitmapData->height == 0))
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "Invalid BITMAP_DATA: width=%" PRIu16 ", height=%" PRIu16, bitmapData->width,
|
||||
+ bitmapData->height);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if (bitmapData->flags & BITMAP_COMPRESSION)
|
||||
{
|
||||
if (!(bitmapData->flags & NO_BITMAP_COMPRESSION_HDR))
|
||||
--
|
||||
2.32.0
|
||||
|
@ -1,62 +0,0 @@
|
||||
From e482b394efc371412ce659b731a9b1e1d73bdf0e Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Mon, 24 Oct 2022 10:42:56 +0200
|
||||
Subject: [PATCH] Added function _wcsncmp
|
||||
|
||||
* Compare WCHAR strings up to n characters
|
||||
|
||||
(cherry picked from commit 8178ed26a459356ece17414c6e871a7e0735a4ec)
|
||||
---
|
||||
winpr/include/winpr/string.h | 2 ++
|
||||
winpr/libwinpr/crt/string.c | 15 ++++++++++++++-
|
||||
2 files changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/winpr/include/winpr/string.h b/winpr/include/winpr/string.h
|
||||
index 8ce83bc1d..3b907c444 100644
|
||||
--- a/winpr/include/winpr/string.h
|
||||
+++ b/winpr/include/winpr/string.h
|
||||
@@ -57,6 +57,7 @@ extern "C"
|
||||
WINPR_API int _strnicmp(const char* string1, const char* string2, size_t count);
|
||||
|
||||
WINPR_API int _wcscmp(const WCHAR* string1, const WCHAR* string2);
|
||||
+ WINPR_API int _wcsncmp(const WCHAR* string1, const WCHAR* string2, size_t count);
|
||||
|
||||
WINPR_API size_t _wcslen(const WCHAR* str);
|
||||
WINPR_API size_t _wcsnlen(const WCHAR* str, size_t maxNumberOfElements);
|
||||
@@ -70,6 +71,7 @@ extern "C"
|
||||
#else
|
||||
|
||||
#define _wcscmp wcscmp
|
||||
+#define _wcsncmp wcsncmp
|
||||
#define _wcslen wcslen
|
||||
#define _wcsnlen wcsnlen
|
||||
#define _wcschr wcschr
|
||||
diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c
|
||||
index 37fcb4b25..c25ffa279 100644
|
||||
--- a/winpr/libwinpr/crt/string.c
|
||||
+++ b/winpr/libwinpr/crt/string.c
|
||||
@@ -90,7 +90,20 @@ int _wcscmp(const WCHAR* string1, const WCHAR* string2)
|
||||
|
||||
Data_Read_UINT16(string1, value1);
|
||||
Data_Read_UINT16(string2, value2);
|
||||
- return value1 - value2;
|
||||
+ return (int)value1 - value2;
|
||||
+}
|
||||
+
|
||||
+int _wcsncmp(const WCHAR* string1, const WCHAR* string2, size_t count)
|
||||
+{
|
||||
+ for (size_t x = 0; x < count; x++)
|
||||
+ {
|
||||
+ const WCHAR a = string1[x];
|
||||
+ const WCHAR b = string2[x];
|
||||
+
|
||||
+ if (a != b)
|
||||
+ return (int)a - b;
|
||||
+ }
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
/* _wcslen -> wcslen */
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,29 +0,0 @@
|
||||
From 8c513f127549433c830575202d1551b0e9dd182d Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 13 Oct 2022 09:00:48 +0200
|
||||
Subject: [PATCH] Added missing length check in urb_control_transfer
|
||||
|
||||
(cherry picked from commit ce838e2477cb8173ea5e98f35ad55ff41ea5117d)
|
||||
---
|
||||
channels/urbdrc/client/data_transfer.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c
|
||||
index 9a44e6e09..bb2784055 100644
|
||||
--- a/channels/urbdrc/client/data_transfer.c
|
||||
+++ b/channels/urbdrc/client/data_transfer.c
|
||||
@@ -673,7 +673,11 @@ static UINT urb_control_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callba
|
||||
buffer = Stream_Pointer(out);
|
||||
|
||||
if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
|
||||
+ {
|
||||
+ if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
|
||||
+ return ERROR_INVALID_DATA;
|
||||
Stream_Copy(s, out, OutputBufferSize);
|
||||
+ }
|
||||
|
||||
/** process TS_URB_CONTROL_TRANSFER */
|
||||
if (!pdev->control_transfer(pdev, RequestId, EndpointAddress, TransferFlags, bmRequestType,
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,51 +0,0 @@
|
||||
From babbd1e433d273634637f5199429986714864033 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 13 Oct 2022 09:09:28 +0200
|
||||
Subject: [PATCH] Added missing length checks in zgfx_decompress_segment
|
||||
|
||||
(cherry picked from commit 64716b335858109d14f27b51acc4c4d71a92a816)
|
||||
---
|
||||
libfreerdp/codec/zgfx.c | 11 +++++++----
|
||||
1 file changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/codec/zgfx.c b/libfreerdp/codec/zgfx.c
|
||||
index 1a2878bd9..04ddeadb2 100644
|
||||
--- a/libfreerdp/codec/zgfx.c
|
||||
+++ b/libfreerdp/codec/zgfx.c
|
||||
@@ -230,19 +230,19 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
|
||||
BYTE* pbSegment;
|
||||
size_t cbSegment;
|
||||
|
||||
- if (!zgfx || !stream)
|
||||
+ if (!zgfx || !stream || (segmentSize < 2))
|
||||
return FALSE;
|
||||
|
||||
cbSegment = segmentSize - 1;
|
||||
|
||||
- if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize < 1) ||
|
||||
- (segmentSize > UINT32_MAX))
|
||||
+ if ((Stream_GetRemainingLength(stream) < segmentSize) || (segmentSize > UINT32_MAX))
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT8(stream, flags); /* header (1 byte) */
|
||||
zgfx->OutputCount = 0;
|
||||
pbSegment = Stream_Pointer(stream);
|
||||
- Stream_Seek(stream, cbSegment);
|
||||
+ if (!Stream_SafeSeek(stream, cbSegment))
|
||||
+ return FALSE;
|
||||
|
||||
if (!(flags & PACKET_COMPRESSED))
|
||||
{
|
||||
@@ -346,6 +346,9 @@ static BOOL zgfx_decompress_segment(ZGFX_CONTEXT* zgfx, wStream* stream, size_t
|
||||
if (count > sizeof(zgfx->OutputBuffer) - zgfx->OutputCount)
|
||||
return FALSE;
|
||||
|
||||
+ if (count > zgfx->cBitsRemaining / 8)
|
||||
+ return FALSE;
|
||||
+
|
||||
CopyMemory(&(zgfx->OutputBuffer[zgfx->OutputCount]), zgfx->pbInputCurrent,
|
||||
count);
|
||||
zgfx_history_buffer_ring_write(zgfx, zgfx->pbInputCurrent, count);
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,32 +0,0 @@
|
||||
From b3a695e9f38a42f1ef0cade0d5e1fe60cf68864e Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 13 Oct 2022 08:36:26 +0200
|
||||
Subject: [PATCH] Ensure urb_create_iocompletion uses size_t for calculation
|
||||
|
||||
(cherry picked from commit de7e0f062ee53d00b4a966a43855a716e3478150)
|
||||
---
|
||||
channels/urbdrc/client/data_transfer.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c
|
||||
index 80e84af48..8642c8506 100644
|
||||
--- a/channels/urbdrc/client/data_transfer.c
|
||||
+++ b/channels/urbdrc/client/data_transfer.c
|
||||
@@ -97,7 +97,13 @@ static wStream* urb_create_iocompletion(UINT32 InterfaceField, UINT32 MessageId,
|
||||
UINT32 OutputBufferSize)
|
||||
{
|
||||
const UINT32 InterfaceId = (STREAM_ID_PROXY << 30) | (InterfaceField & 0x3FFFFFFF);
|
||||
- wStream* out = Stream_New(NULL, OutputBufferSize + 28);
|
||||
+
|
||||
+#if UINT32_MAX >= SIZE_MAX
|
||||
+ if (OutputBufferSize > UINT32_MAX - 28ull)
|
||||
+ return NULL;
|
||||
+#endif
|
||||
+
|
||||
+ wStream* out = Stream_New(NULL, OutputBufferSize + 28ull);
|
||||
|
||||
if (!out)
|
||||
return NULL;
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,37 +0,0 @@
|
||||
From 64544c7f4ed72b3023955ebe6ad3b118ebb8d6c7 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 6 Oct 2022 09:12:40 +0200
|
||||
Subject: [PATCH] Fix length checks in parallel driver
|
||||
|
||||
The length requested was not checked against the length read from
|
||||
the port.
|
||||
|
||||
(cherry picked from commit 094cc5a4596c299595b732effd59ee149181fd61)
|
||||
---
|
||||
channels/parallel/client/parallel_main.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/channels/parallel/client/parallel_main.c b/channels/parallel/client/parallel_main.c
|
||||
index af3e82703..993605a65 100644
|
||||
--- a/channels/parallel/client/parallel_main.c
|
||||
+++ b/channels/parallel/client/parallel_main.c
|
||||
@@ -159,7 +159,7 @@ static UINT parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp)
|
||||
return ERROR_INVALID_DATA;
|
||||
Stream_Read_UINT32(irp->input, Length);
|
||||
Stream_Read_UINT64(irp->input, Offset);
|
||||
- buffer = (BYTE*)malloc(Length);
|
||||
+ buffer = (BYTE*)calloc(Length, sizeof(BYTE));
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
@@ -178,6 +178,7 @@ static UINT parallel_process_irp_read(PARALLEL_DEVICE* parallel, IRP* irp)
|
||||
}
|
||||
else
|
||||
{
|
||||
+ Length = status;
|
||||
}
|
||||
|
||||
Stream_Write_UINT32(irp->output, Length);
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,49 +0,0 @@
|
||||
From bf9bce2c3e6c716cc708716484124c1fb47cb531 Mon Sep 17 00:00:00 2001
|
||||
From: Max Roncace <me@caseif.net>
|
||||
Date: Wed, 24 Feb 2021 17:44:28 -0500
|
||||
Subject: [PATCH] Fix /monitor-list flag being ignored on X11/Wayland
|
||||
|
||||
---
|
||||
client/Wayland/wlfreerdp.c | 4 +++-
|
||||
client/X11/cli/xfreerdp.c | 4 +++-
|
||||
2 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/client/Wayland/wlfreerdp.c b/client/Wayland/wlfreerdp.c
|
||||
index aca734211..26c5452a5 100644
|
||||
--- a/client/Wayland/wlfreerdp.c
|
||||
+++ b/client/Wayland/wlfreerdp.c
|
||||
@@ -651,10 +651,12 @@ int main(int argc, char* argv[])
|
||||
status = freerdp_client_settings_parse_command_line(settings, argc, argv, FALSE);
|
||||
if (status)
|
||||
{
|
||||
- BOOL list = settings->ListMonitors;
|
||||
+ BOOL list;
|
||||
|
||||
rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
|
||||
+ list = settings->ListMonitors;
|
||||
+
|
||||
if (list)
|
||||
wlf_list_monitors(wlc);
|
||||
|
||||
diff --git a/client/X11/cli/xfreerdp.c b/client/X11/cli/xfreerdp.c
|
||||
index 5b7021944..786a7eb5d 100644
|
||||
--- a/client/X11/cli/xfreerdp.c
|
||||
+++ b/client/X11/cli/xfreerdp.c
|
||||
@@ -59,10 +59,12 @@ int main(int argc, char* argv[])
|
||||
status = freerdp_client_settings_parse_command_line(context->settings, argc, argv, FALSE);
|
||||
if (status)
|
||||
{
|
||||
- BOOL list = settings->ListMonitors;
|
||||
+ BOOL list;
|
||||
|
||||
rc = freerdp_client_settings_command_line_status_print(settings, status, argc, argv);
|
||||
|
||||
+ list = settings->ListMonitors;
|
||||
+
|
||||
if (list)
|
||||
xf_list_monitors(xfc);
|
||||
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,39 +0,0 @@
|
||||
From b9c5e3668c4022b34734ac8ccb07dd044d4ff38c Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 13 Oct 2022 08:27:41 +0200
|
||||
Subject: [PATCH] Fixed division by zero in urbdrc
|
||||
|
||||
(cherry picked from commit 731f8419d04b481d7160de1f34062d630ed48765)
|
||||
---
|
||||
channels/urbdrc/client/libusb/libusb_udevice.c | 12 +++++++++---
|
||||
1 file changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/channels/urbdrc/client/libusb/libusb_udevice.c b/channels/urbdrc/client/libusb/libusb_udevice.c
|
||||
index aa69890ae..5784d9fe2 100644
|
||||
--- a/channels/urbdrc/client/libusb/libusb_udevice.c
|
||||
+++ b/channels/urbdrc/client/libusb/libusb_udevice.c
|
||||
@@ -1149,12 +1149,18 @@ static int libusb_udev_isoch_transfer(IUDEVICE* idev, URBDRC_CHANNEL_CALLBACK* c
|
||||
else
|
||||
Stream_Seek(user_data->data, (NumberOfPackets * 12));
|
||||
|
||||
- iso_packet_size = BufferSize / NumberOfPackets;
|
||||
- iso_transfer = libusb_alloc_transfer(NumberOfPackets);
|
||||
+ if (NumberOfPackets > 0)
|
||||
+ {
|
||||
+ iso_packet_size = BufferSize / NumberOfPackets;
|
||||
+ iso_transfer = libusb_alloc_transfer((int)NumberOfPackets);
|
||||
+ }
|
||||
|
||||
if (iso_transfer == NULL)
|
||||
{
|
||||
- WLog_Print(urbdrc->log, WLOG_ERROR, "Error: libusb_alloc_transfer.");
|
||||
+ WLog_Print(urbdrc->log, WLOG_ERROR,
|
||||
+ "Error: libusb_alloc_transfer [NumberOfPackets=%" PRIu32 ", BufferSize=%" PRIu32
|
||||
+ " ]",
|
||||
+ NumberOfPackets, BufferSize);
|
||||
async_transfer_user_data_free(user_data);
|
||||
return -1;
|
||||
}
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,122 +0,0 @@
|
||||
From 6ed2f7d1a379f69cca102e8166d20eb5ed38652b Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Fri, 22 Apr 2022 16:27:21 +0200
|
||||
Subject: [PATCH] Fixed format string for Stream_CheckAndLogRequiredLength
|
||||
|
||||
__LINE__ requires %d and not %PRIuz
|
||||
|
||||
(cherry picked from commit 74c1a006e940308b0653427d25a87ea5a24cb573)
|
||||
---
|
||||
winpr/include/winpr/stream.h | 14 ++++++++
|
||||
winpr/libwinpr/utils/stream.c | 65 +++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 79 insertions(+)
|
||||
|
||||
diff --git a/winpr/include/winpr/stream.h b/winpr/include/winpr/stream.h
|
||||
index f351eaa15..ed637f034 100644
|
||||
--- a/winpr/include/winpr/stream.h
|
||||
+++ b/winpr/include/winpr/stream.h
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/endian.h>
|
||||
#include <winpr/synch.h>
|
||||
+#include <winpr/wlog.h>
|
||||
+#include <winpr/debug.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
@@ -56,6 +57,19 @@ extern "C"
|
||||
WINPR_API void Stream_StaticInit(wStream* s, BYTE* buffer, size_t size);
|
||||
WINPR_API void Stream_Free(wStream* s, BOOL bFreeBuffer);
|
||||
|
||||
+#define Stream_CheckAndLogRequiredLength(tag, s, len) \
|
||||
+ Stream_CheckAndLogRequiredLengthEx(tag, WLOG_WARN, s, len, "%s(%s:%d)", __FUNCTION__, \
|
||||
+ __FILE__, __LINE__)
|
||||
+ WINPR_API BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s,
|
||||
+ UINT64 len, const char* fmt, ...);
|
||||
+ WINPR_API BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s,
|
||||
+ UINT64 len, const char* fmt, va_list args);
|
||||
+ WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s,
|
||||
+ UINT64 len, const char* fmt, ...);
|
||||
+ WINPR_API BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s,
|
||||
+ UINT64 len, const char* fmt,
|
||||
+ va_list args);
|
||||
+
|
||||
static INLINE void Stream_Seek(wStream* s, size_t _offset)
|
||||
{
|
||||
s->pointer += (_offset);
|
||||
diff --git a/winpr/libwinpr/utils/stream.c b/winpr/libwinpr/utils/stream.c
|
||||
index 1271981b7..cc119c771 100644
|
||||
--- a/winpr/libwinpr/utils/stream.c
|
||||
+++ b/winpr/libwinpr/utils/stream.c
|
||||
@@ -132,3 +132,68 @@ void Stream_Free(wStream* s, BOOL bFreeBuffer)
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
+
|
||||
+BOOL Stream_CheckAndLogRequiredLengthEx(const char* tag, DWORD level, wStream* s, UINT64 len,
|
||||
+ const char* fmt, ...)
|
||||
+{
|
||||
+ const size_t actual = Stream_GetRemainingLength(s);
|
||||
+
|
||||
+ if (actual < len)
|
||||
+ {
|
||||
+ va_list args;
|
||||
+
|
||||
+ va_start(args, fmt);
|
||||
+ Stream_CheckAndLogRequiredLengthExVa(tag, level, s, len, fmt, args);
|
||||
+ va_end(args);
|
||||
+
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+BOOL Stream_CheckAndLogRequiredLengthExVa(const char* tag, DWORD level, wStream* s, UINT64 len,
|
||||
+ const char* fmt, va_list args)
|
||||
+{
|
||||
+ const size_t actual = Stream_GetRemainingLength(s);
|
||||
+
|
||||
+ if (actual < len)
|
||||
+ return Stream_CheckAndLogRequiredLengthWLogExVa(WLog_Get(tag), level, s, len, fmt, args);
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+BOOL Stream_CheckAndLogRequiredLengthWLogEx(wLog* log, DWORD level, wStream* s, UINT64 len,
|
||||
+ const char* fmt, ...)
|
||||
+{
|
||||
+ const size_t actual = Stream_GetRemainingLength(s);
|
||||
+
|
||||
+ if (actual < len)
|
||||
+ {
|
||||
+ va_list args;
|
||||
+
|
||||
+ va_start(args, fmt);
|
||||
+ Stream_CheckAndLogRequiredLengthWLogExVa(log, level, s, len, fmt, args);
|
||||
+ va_end(args);
|
||||
+
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+BOOL Stream_CheckAndLogRequiredLengthWLogExVa(wLog* log, DWORD level, wStream* s, UINT64 len,
|
||||
+ const char* fmt, va_list args)
|
||||
+{
|
||||
+ const size_t actual = Stream_GetRemainingLength(s);
|
||||
+
|
||||
+ if (actual < len)
|
||||
+ {
|
||||
+ char prefix[1024] = { 0 };
|
||||
+
|
||||
+ vsnprintf(prefix, sizeof(prefix), fmt, args);
|
||||
+
|
||||
+ WLog_Print(log, level, "[%s] invalid length, got %" PRIuz ", require at least %" PRIu64,
|
||||
+ prefix, actual, len);
|
||||
+ winpr_log_backtrace_ex(log, level, 20);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
--
|
||||
2.38.1
|
||||
|
@ -1,58 +0,0 @@
|
||||
From ddf9b3f852c31311f8d726012131f657c9857276 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 13 Oct 2022 08:47:51 +0200
|
||||
Subject: [PATCH] Fixed missing input buffer length check in urbdrc
|
||||
|
||||
(cherry picked from commit 497df00f741dd4fc89292aaef2db7368aee45d0d)
|
||||
---
|
||||
channels/urbdrc/client/data_transfer.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/channels/urbdrc/client/data_transfer.c b/channels/urbdrc/client/data_transfer.c
|
||||
index bb2784055..80e84af48 100644
|
||||
--- a/channels/urbdrc/client/data_transfer.c
|
||||
+++ b/channels/urbdrc/client/data_transfer.c
|
||||
@@ -241,6 +241,10 @@ static UINT urbdrc_process_io_control(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* c
|
||||
|
||||
Stream_Read_UINT32(s, OutputBufferSize);
|
||||
Stream_Read_UINT32(s, RequestId);
|
||||
+
|
||||
+ if (OutputBufferSize > UINT32_MAX - 4)
|
||||
+ return ERROR_INVALID_DATA;
|
||||
+
|
||||
InterfaceId = ((STREAM_ID_PROXY << 30) | pdev->get_ReqCompletion(pdev));
|
||||
out = urb_create_iocompletion(InterfaceId, MessageId, RequestId, OutputBufferSize);
|
||||
|
||||
@@ -724,6 +728,15 @@ static UINT urb_bulk_or_interrupt_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBA
|
||||
Stream_Read_UINT32(s, TransferFlags); /** TransferFlags */
|
||||
Stream_Read_UINT32(s, OutputBufferSize);
|
||||
EndpointAddress = (PipeHandle & 0x000000ff);
|
||||
+
|
||||
+ if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
|
||||
+ {
|
||||
+ if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
|
||||
+ {
|
||||
+ return ERROR_INVALID_DATA;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/** process TS_URB_BULK_OR_INTERRUPT_TRANSFER */
|
||||
return pdev->bulk_or_interrupt_transfer(pdev, callback, MessageId, RequestId, EndpointAddress,
|
||||
TransferFlags, noAck, OutputBufferSize,
|
||||
@@ -808,6 +821,13 @@ static UINT urb_isoch_transfer(IUDEVICE* pdev, URBDRC_CHANNEL_CALLBACK* callback
|
||||
packetDescriptorData = Stream_Pointer(s);
|
||||
Stream_Seek(s, NumberOfPackets * 12);
|
||||
Stream_Read_UINT32(s, OutputBufferSize);
|
||||
+
|
||||
+ if (transferDir == USBD_TRANSFER_DIRECTION_OUT)
|
||||
+ {
|
||||
+ if (!Stream_CheckAndLogRequiredLength(TAG, s, OutputBufferSize))
|
||||
+ return ERROR_INVALID_DATA;
|
||||
+ }
|
||||
+
|
||||
return pdev->isoch_transfer(
|
||||
pdev, callback, MessageId, RequestId, EndpointAddress, TransferFlags, StartFrame,
|
||||
ErrorCount, noAck, packetDescriptorData, NumberOfPackets, OutputBufferSize,
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,29 +0,0 @@
|
||||
From bf28ea249de57acc6dfadbd778afef2093c1c283 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 6 Oct 2022 09:15:40 +0200
|
||||
Subject: [PATCH] Fixed missing length check in video channel
|
||||
|
||||
Data received in video redirection channel was not checked for
|
||||
proper length.
|
||||
|
||||
(cherry picked from commit eeffd1050e9284d1464b58e049b2b4d88726632b)
|
||||
---
|
||||
channels/video/client/video_main.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/channels/video/client/video_main.c b/channels/video/client/video_main.c
|
||||
index a21e7cdf2..a8031fc86 100644
|
||||
--- a/channels/video/client/video_main.c
|
||||
+++ b/channels/video/client/video_main.c
|
||||
@@ -930,6 +930,8 @@ static UINT video_data_on_data_received(IWTSVirtualChannelCallback* pChannelCall
|
||||
Stream_Read_UINT16(s, data.PacketsInSample);
|
||||
Stream_Read_UINT32(s, data.SampleNumber);
|
||||
Stream_Read_UINT32(s, data.cbSample);
|
||||
+ if (!Stream_CheckAndLogRequiredLength(TAG, s, data.cbSample))
|
||||
+ return ERROR_INVALID_DATA;
|
||||
data.pSample = Stream_Pointer(s);
|
||||
|
||||
/*
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,28 +0,0 @@
|
||||
From 80b2483373c00baec3a26b1d82027f16dfdd8859 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Mon, 24 Oct 2022 08:45:05 +0200
|
||||
Subject: [PATCH] Fixed missing stream length check in
|
||||
drive_file_query_directory
|
||||
|
||||
(cherry picked from commit 4e4bb79795d6ac85473fb7a83e53ccf63d204b93)
|
||||
---
|
||||
channels/drive/client/drive_main.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c
|
||||
index d3776381c..b6cf2ad32 100644
|
||||
--- a/channels/drive/client/drive_main.c
|
||||
+++ b/channels/drive/client/drive_main.c
|
||||
@@ -629,6 +629,9 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp)
|
||||
Stream_Read_UINT32(irp->input, PathLength);
|
||||
Stream_Seek(irp->input, 23); /* Padding */
|
||||
path = (WCHAR*)Stream_Pointer(irp->input);
|
||||
+ if (!Stream_CheckAndLogRequiredLength(TAG, irp->input, PathLength))
|
||||
+ return ERROR_INVALID_DATA;
|
||||
+
|
||||
file = drive_get_file_by_id(drive, irp->FileId);
|
||||
|
||||
if (file == NULL)
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,296 +0,0 @@
|
||||
From 865ba07a0fd4fbc7a8203482411aacca3bbfbb9f Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Mon, 24 Oct 2022 10:41:55 +0200
|
||||
Subject: [PATCH] Fixed path validation in drive channel
|
||||
|
||||
Check that canonical path is a subpath of the shared directory
|
||||
|
||||
(cherry picked from commit 844c94e6d0438fa7bd8ff8d5513c3f69c3018b85)
|
||||
---
|
||||
channels/drive/client/drive_file.c | 106 ++++++++++++++++++-----------
|
||||
channels/drive/client/drive_file.h | 8 +--
|
||||
channels/drive/client/drive_main.c | 8 +--
|
||||
3 files changed, 73 insertions(+), 49 deletions(-)
|
||||
|
||||
diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c
|
||||
index 305438593..1ea4ab9da 100644
|
||||
--- a/channels/drive/client/drive_file.c
|
||||
+++ b/channels/drive/client/drive_file.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
+#include <assert.h>
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
#include <winpr/crt.h>
|
||||
@@ -61,10 +62,14 @@
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
-static void drive_file_fix_path(WCHAR* path)
|
||||
+static BOOL drive_file_fix_path(WCHAR* path, size_t length)
|
||||
{
|
||||
size_t i;
|
||||
- size_t length = _wcslen(path);
|
||||
+
|
||||
+ if ((length == 0) || (length > UINT32_MAX))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ assert(path);
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
@@ -75,58 +79,82 @@ static void drive_file_fix_path(WCHAR* path)
|
||||
#ifdef WIN32
|
||||
|
||||
if ((length == 3) && (path[1] == L':') && (path[2] == L'/'))
|
||||
- return;
|
||||
+ return FALSE;
|
||||
|
||||
#else
|
||||
|
||||
if ((length == 1) && (path[0] == L'/'))
|
||||
- return;
|
||||
+ return FALSE;
|
||||
|
||||
#endif
|
||||
|
||||
if ((length > 0) && (path[length - 1] == L'/'))
|
||||
path[length - 1] = L'\0';
|
||||
+
|
||||
+ return TRUE;
|
||||
}
|
||||
|
||||
static WCHAR* drive_file_combine_fullpath(const WCHAR* base_path, const WCHAR* path,
|
||||
- size_t PathLength)
|
||||
+ size_t PathWCharLength)
|
||||
{
|
||||
- WCHAR* fullpath;
|
||||
- size_t base_path_length;
|
||||
+ BOOL ok = FALSE;
|
||||
+ WCHAR* fullpath = NULL;
|
||||
+ size_t length;
|
||||
|
||||
- if (!base_path || (!path && (PathLength > 0)))
|
||||
- return NULL;
|
||||
+ if (!base_path || (!path && (PathWCharLength > 0)))
|
||||
+ goto fail;
|
||||
|
||||
- base_path_length = _wcslen(base_path) * 2;
|
||||
- fullpath = (WCHAR*)calloc(1, base_path_length + PathLength + sizeof(WCHAR));
|
||||
+ const size_t base_path_length = _wcsnlen(base_path, MAX_PATH);
|
||||
+ length = base_path_length + PathWCharLength + 1;
|
||||
+ fullpath = (WCHAR*)calloc(length, sizeof(WCHAR));
|
||||
|
||||
if (!fullpath)
|
||||
+ goto fail;
|
||||
+
|
||||
+ CopyMemory(fullpath, base_path, base_path_length * sizeof(WCHAR));
|
||||
+ if (path)
|
||||
+ CopyMemory(&fullpath[base_path_length], path, PathWCharLength * sizeof(WCHAR));
|
||||
+
|
||||
+ if (!drive_file_fix_path(fullpath, length))
|
||||
+ goto fail;
|
||||
+
|
||||
+ /* Ensure the path does not contain sequences like '..' */
|
||||
+ const WCHAR dotdot[] = { '.', '.', '\0' };
|
||||
+ if (_wcsstr(&fullpath[base_path_length], dotdot))
|
||||
{
|
||||
- WLog_ERR(TAG, "malloc failed!");
|
||||
- return NULL;
|
||||
+ char abuffer[MAX_PATH] = { 0 };
|
||||
+ ConvertFromUnicode(CP_UTF8, 0, &fullpath[base_path_length], -1, (char**)&abuffer,
|
||||
+ ARRAYSIZE(abuffer) - 1, NULL, NULL);
|
||||
+
|
||||
+ WLog_WARN(TAG, "[rdpdr] received invalid file path '%s' from server, aborting!",
|
||||
+ &abuffer[base_path_length]);
|
||||
+ goto fail;
|
||||
}
|
||||
|
||||
- CopyMemory(fullpath, base_path, base_path_length);
|
||||
- if (path)
|
||||
- CopyMemory((char*)fullpath + base_path_length, path, PathLength);
|
||||
- drive_file_fix_path(fullpath);
|
||||
+ ok = TRUE;
|
||||
+fail:
|
||||
+ if (!ok)
|
||||
+ {
|
||||
+ free(fullpath);
|
||||
+ fullpath = NULL;
|
||||
+ }
|
||||
return fullpath;
|
||||
}
|
||||
|
||||
static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||
{
|
||||
- WIN32_FIND_DATAW findFileData;
|
||||
+ WIN32_FIND_DATAW findFileData = { 0 };
|
||||
BOOL ret = TRUE;
|
||||
- HANDLE dir;
|
||||
- WCHAR* fullpath;
|
||||
- WCHAR* path_slash;
|
||||
- size_t base_path_length;
|
||||
+ HANDLE dir = INVALID_HANDLE_VALUE;
|
||||
+ WCHAR* fullpath = NULL;
|
||||
+ WCHAR* path_slash = NULL;
|
||||
+ size_t base_path_length = 0;
|
||||
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
- base_path_length = _wcslen(path) * 2;
|
||||
- path_slash = (WCHAR*)calloc(1, base_path_length + sizeof(WCHAR) * 3);
|
||||
+ base_path_length = _wcslen(path);
|
||||
+ path_slash = (WCHAR*)calloc(base_path_length + 3, sizeof(WCHAR));
|
||||
|
||||
if (!path_slash)
|
||||
{
|
||||
@@ -134,12 +162,11 @@ static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- CopyMemory(path_slash, path, base_path_length);
|
||||
- path_slash[base_path_length / 2] = L'/';
|
||||
- path_slash[base_path_length / 2 + 1] = L'*';
|
||||
+ CopyMemory(path_slash, path, base_path_length * sizeof(WCHAR));
|
||||
+ path_slash[base_path_length] = L'/';
|
||||
+ path_slash[base_path_length + 1] = L'*';
|
||||
DEBUG_WSTR("Search in %s", path_slash);
|
||||
dir = FindFirstFileW(path_slash, &findFileData);
|
||||
- path_slash[base_path_length / 2 + 1] = 0;
|
||||
|
||||
if (dir == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@@ -149,7 +176,7 @@ static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||
|
||||
do
|
||||
{
|
||||
- size_t len = _wcslen(findFileData.cFileName);
|
||||
+ const size_t len = _wcsnlen(findFileData.cFileName, ARRAYSIZE(findFileData.cFileName));
|
||||
|
||||
if ((len == 1 && findFileData.cFileName[0] == L'.') ||
|
||||
(len == 2 && findFileData.cFileName[0] == L'.' && findFileData.cFileName[1] == L'.'))
|
||||
@@ -157,7 +184,7 @@ static BOOL drive_file_remove_dir(const WCHAR* path)
|
||||
continue;
|
||||
}
|
||||
|
||||
- fullpath = drive_file_combine_fullpath(path_slash, findFileData.cFileName, len * 2);
|
||||
+ fullpath = drive_file_combine_fullpath(path_slash, findFileData.cFileName, len);
|
||||
DEBUG_WSTR("Delete %s", fullpath);
|
||||
|
||||
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
@@ -333,13 +360,13 @@ static BOOL drive_file_init(DRIVE_FILE* file)
|
||||
return file->file_handle != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
-DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathLength, UINT32 id,
|
||||
- UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions,
|
||||
- UINT32 FileAttributes, UINT32 SharedAccess)
|
||||
+DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathWCharLength,
|
||||
+ UINT32 id, UINT32 DesiredAccess, UINT32 CreateDisposition,
|
||||
+ UINT32 CreateOptions, UINT32 FileAttributes, UINT32 SharedAccess)
|
||||
{
|
||||
DRIVE_FILE* file;
|
||||
|
||||
- if (!base_path || (!path && (PathLength > 0)))
|
||||
+ if (!base_path || (!path && (PathWCharLength > 0)))
|
||||
return NULL;
|
||||
|
||||
file = (DRIVE_FILE*)calloc(1, sizeof(DRIVE_FILE));
|
||||
@@ -359,7 +386,7 @@ DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 Pat
|
||||
file->CreateDisposition = CreateDisposition;
|
||||
file->CreateOptions = CreateOptions;
|
||||
file->SharedAccess = SharedAccess;
|
||||
- drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path, PathLength));
|
||||
+ drive_file_set_fullpath(file, drive_file_combine_fullpath(base_path, path, PathWCharLength));
|
||||
|
||||
if (!drive_file_init(file))
|
||||
{
|
||||
@@ -714,13 +741,10 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
||||
return FALSE;
|
||||
|
||||
fullpath = drive_file_combine_fullpath(file->basepath, (WCHAR*)Stream_Pointer(input),
|
||||
- FileNameLength);
|
||||
+ FileNameLength / sizeof(WCHAR));
|
||||
|
||||
if (!fullpath)
|
||||
- {
|
||||
- WLog_ERR(TAG, "drive_file_combine_fullpath failed!");
|
||||
return FALSE;
|
||||
- }
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@@ -759,7 +783,7 @@ BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UIN
|
||||
}
|
||||
|
||||
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
|
||||
- const WCHAR* path, UINT32 PathLength, wStream* output)
|
||||
+ const WCHAR* path, UINT32 PathWCharLength, wStream* output)
|
||||
{
|
||||
size_t length;
|
||||
WCHAR* ent_path;
|
||||
@@ -773,7 +797,7 @@ BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYT
|
||||
if (file->find_handle != INVALID_HANDLE_VALUE)
|
||||
FindClose(file->find_handle);
|
||||
|
||||
- ent_path = drive_file_combine_fullpath(file->basepath, path, PathLength);
|
||||
+ ent_path = drive_file_combine_fullpath(file->basepath, path, PathWCharLength);
|
||||
/* open new search handle and retrieve the first entry */
|
||||
file->find_handle = FindFirstFileW(ent_path, &file->find_data);
|
||||
free(ent_path);
|
||||
diff --git a/channels/drive/client/drive_file.h b/channels/drive/client/drive_file.h
|
||||
index ed789d6f0..6d3bd7045 100644
|
||||
--- a/channels/drive/client/drive_file.h
|
||||
+++ b/channels/drive/client/drive_file.h
|
||||
@@ -51,9 +51,9 @@ struct _DRIVE_FILE
|
||||
UINT32 CreateOptions;
|
||||
};
|
||||
|
||||
-DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathLength, UINT32 id,
|
||||
- UINT32 DesiredAccess, UINT32 CreateDisposition, UINT32 CreateOptions,
|
||||
- UINT32 FileAttributes, UINT32 SharedAccess);
|
||||
+DRIVE_FILE* drive_file_new(const WCHAR* base_path, const WCHAR* path, UINT32 PathWCharLength,
|
||||
+ UINT32 id, UINT32 DesiredAccess, UINT32 CreateDisposition,
|
||||
+ UINT32 CreateOptions, UINT32 FileAttributes, UINT32 SharedAccess);
|
||||
BOOL drive_file_free(DRIVE_FILE* file);
|
||||
|
||||
BOOL drive_file_open(DRIVE_FILE* file);
|
||||
@@ -64,6 +64,6 @@ BOOL drive_file_query_information(DRIVE_FILE* file, UINT32 FsInformationClass, w
|
||||
BOOL drive_file_set_information(DRIVE_FILE* file, UINT32 FsInformationClass, UINT32 Length,
|
||||
wStream* input);
|
||||
BOOL drive_file_query_directory(DRIVE_FILE* file, UINT32 FsInformationClass, BYTE InitialQuery,
|
||||
- const WCHAR* path, UINT32 PathLength, wStream* output);
|
||||
+ const WCHAR* path, UINT32 PathWCharLength, wStream* output);
|
||||
|
||||
#endif /* FREERDP_CHANNEL_DRIVE_FILE_H */
|
||||
diff --git a/channels/drive/client/drive_main.c b/channels/drive/client/drive_main.c
|
||||
index 1b5422522..d3776381c 100644
|
||||
--- a/channels/drive/client/drive_main.c
|
||||
+++ b/channels/drive/client/drive_main.c
|
||||
@@ -184,8 +184,8 @@ static UINT drive_process_irp_create(DRIVE_DEVICE* drive, IRP* irp)
|
||||
|
||||
path = (const WCHAR*)Stream_Pointer(irp->input);
|
||||
FileId = irp->devman->id_sequence++;
|
||||
- file = drive_file_new(drive->path, path, PathLength, FileId, DesiredAccess, CreateDisposition,
|
||||
- CreateOptions, FileAttributes, SharedAccess);
|
||||
+ file = drive_file_new(drive->path, path, PathLength / sizeof(WCHAR), FileId, DesiredAccess,
|
||||
+ CreateDisposition, CreateOptions, FileAttributes, SharedAccess);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
@@ -636,8 +636,8 @@ static UINT drive_process_irp_query_directory(DRIVE_DEVICE* drive, IRP* irp)
|
||||
irp->IoStatus = STATUS_UNSUCCESSFUL;
|
||||
Stream_Write_UINT32(irp->output, 0); /* Length */
|
||||
}
|
||||
- else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, path, PathLength,
|
||||
- irp->output))
|
||||
+ else if (!drive_file_query_directory(file, FsInformationClass, InitialQuery, path,
|
||||
+ PathLength / sizeof(WCHAR), irp->output))
|
||||
{
|
||||
irp->IoStatus = drive_map_windows_err(GetLastError());
|
||||
}
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,433 +0,0 @@
|
||||
From ea20ba13ec764b30d6642cd570929e71e97d00f1 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Tue, 12 Oct 2021 13:33:41 +0200
|
||||
Subject: [PATCH] Implemented missing TSG debug functions
|
||||
|
||||
(cherry picked from commit c06c4638061b0305a269dbb8f7c87009cf886f02)
|
||||
---
|
||||
libfreerdp/core/gateway/tsg.c | 330 ++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 313 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c
|
||||
index 1626b91..3376fb0 100644
|
||||
--- a/libfreerdp/core/gateway/tsg.c
|
||||
+++ b/libfreerdp/core/gateway/tsg.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
+#include <winpr/assert.h>
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/ndr.h>
|
||||
#include <winpr/error.h>
|
||||
@@ -39,13 +40,14 @@
|
||||
|
||||
#define TAG FREERDP_TAG("core.gateway.tsg")
|
||||
|
||||
+#define TSG_CAPABILITY_TYPE_NAP 0x00000001
|
||||
+
|
||||
#define TSG_PACKET_TYPE_HEADER 0x00004844
|
||||
#define TSG_PACKET_TYPE_VERSIONCAPS 0x00005643
|
||||
#define TSG_PACKET_TYPE_QUARCONFIGREQUEST 0x00005143
|
||||
#define TSG_PACKET_TYPE_QUARREQUEST 0x00005152
|
||||
#define TSG_PACKET_TYPE_RESPONSE 0x00005052
|
||||
#define TSG_PACKET_TYPE_QUARENC_RESPONSE 0x00004552
|
||||
-#define TSG_CAPABILITY_TYPE_NAP 0x00000001
|
||||
#define TSG_PACKET_TYPE_CAPS_RESPONSE 0x00004350
|
||||
#define TSG_PACKET_TYPE_MSGREQUEST_PACKET 0x00004752
|
||||
#define TSG_PACKET_TYPE_MESSAGE_PACKET 0x00004750
|
||||
@@ -308,16 +310,35 @@ static BOOL tsg_print(char** buffer, size_t* len, const char* fmt, ...)
|
||||
static BOOL tsg_packet_header_to_string(char** buffer, size_t* length,
|
||||
const TSG_PACKET_HEADER* header)
|
||||
{
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(header);
|
||||
+
|
||||
return tsg_print(buffer, length,
|
||||
"header { ComponentId=0x%04" PRIx16 ", PacketId=0x%04" PRIx16 " }",
|
||||
header->ComponentId, header->PacketId);
|
||||
}
|
||||
|
||||
+static BOOL tsg_type_capability_nap_to_string(char** buffer, size_t* length,
|
||||
+ const TSG_CAPABILITY_NAP* cur)
|
||||
+{
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(cur);
|
||||
+
|
||||
+ return tsg_print(buffer, length, "%s { capabilities=0x%08" PRIx32 " }",
|
||||
+ tsg_packet_id_to_string(TSG_CAPABILITY_TYPE_NAP), cur->capabilities);
|
||||
+}
|
||||
+
|
||||
static BOOL tsg_packet_capabilities_to_string(char** buffer, size_t* length,
|
||||
const TSG_PACKET_CAPABILITIES* caps, UINT32 numCaps)
|
||||
{
|
||||
UINT32 x;
|
||||
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(caps);
|
||||
+
|
||||
if (!tsg_print(buffer, length, "capabilities { "))
|
||||
return FALSE;
|
||||
|
||||
@@ -327,9 +348,7 @@ static BOOL tsg_packet_capabilities_to_string(char** buffer, size_t* length,
|
||||
switch (cur->capabilityType)
|
||||
{
|
||||
case TSG_CAPABILITY_TYPE_NAP:
|
||||
- if (!tsg_print(buffer, length, "%s { capabilities=0x%08" PRIx32 " }",
|
||||
- tsg_packet_id_to_string(cur->capabilityType),
|
||||
- cur->tsgPacket.tsgCapNap.capabilities))
|
||||
+ if (!tsg_type_capability_nap_to_string(buffer, length, &cur->tsgPacket.tsgCapNap))
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
@@ -344,6 +363,10 @@ static BOOL tsg_packet_capabilities_to_string(char** buffer, size_t* length,
|
||||
static BOOL tsg_packet_versioncaps_to_string(char** buffer, size_t* length,
|
||||
const TSG_PACKET_VERSIONCAPS* caps)
|
||||
{
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(caps);
|
||||
+
|
||||
if (!tsg_print(buffer, length, "versioncaps { "))
|
||||
return FALSE;
|
||||
if (!tsg_packet_header_to_string(buffer, length, &caps->tsgHeader))
|
||||
@@ -365,6 +388,277 @@ static BOOL tsg_packet_versioncaps_to_string(char** buffer, size_t* length,
|
||||
return tsg_print(buffer, length, " }");
|
||||
}
|
||||
|
||||
+static BOOL tsg_packet_quarconfigrequest_to_string(char** buffer, size_t* length,
|
||||
+ const TSG_PACKET_QUARCONFIGREQUEST* caps)
|
||||
+{
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(caps);
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, "quarconfigrequest { "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, " "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, " flags=0x%08" PRIx32, caps->flags))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return tsg_print(buffer, length, " }");
|
||||
+}
|
||||
+
|
||||
+static BOOL tsg_packet_quarrequest_to_string(char** buffer, size_t* length,
|
||||
+ const TSG_PACKET_QUARREQUEST* caps)
|
||||
+{
|
||||
+ BOOL rc = FALSE;
|
||||
+ char* name = NULL;
|
||||
+ char* strdata = NULL;
|
||||
+
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(caps);
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, "quarrequest { "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, " "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (caps->nameLength > 0)
|
||||
+ {
|
||||
+ if (ConvertFromUnicode(CP_UTF8, 0, caps->machineName, caps->nameLength, &name, 0, NULL,
|
||||
+ NULL) < 0)
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ strdata = winpr_BinToHexString(caps->data, caps->dataLen, TRUE);
|
||||
+ if (strdata || (caps->dataLen == 0))
|
||||
+ rc = tsg_print(buffer, length,
|
||||
+ " flags=0x%08" PRIx32 ", machineName=%s [%" PRIu32 "], data[%" PRIu32 "]=%s",
|
||||
+ caps->flags, name, caps->nameLength, caps->dataLen, strdata);
|
||||
+ free(name);
|
||||
+ free(strdata);
|
||||
+ if (!rc)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return tsg_print(buffer, length, " }");
|
||||
+}
|
||||
+
|
||||
+static const char* tsg_bool_to_string(BOOL val)
|
||||
+{
|
||||
+ if (val)
|
||||
+ return "true";
|
||||
+ return "false";
|
||||
+}
|
||||
+
|
||||
+static const char* tsg_redirection_flags_to_string(char* buffer, size_t size,
|
||||
+ const TSG_REDIRECTION_FLAGS* flags)
|
||||
+{
|
||||
+ WINPR_ASSERT(buffer || (size == 0));
|
||||
+ WINPR_ASSERT(flags);
|
||||
+
|
||||
+ _snprintf(buffer, size,
|
||||
+ "enableAllRedirections=%s, disableAllRedirections=%s, driveRedirectionDisabled=%s, "
|
||||
+ "printerRedirectionDisabled=%s, portRedirectionDisabled=%s, reserved=%s, "
|
||||
+ "clipboardRedirectionDisabled=%s, pnpRedirectionDisabled=%s",
|
||||
+ tsg_bool_to_string(flags->enableAllRedirections),
|
||||
+ tsg_bool_to_string(flags->disableAllRedirections),
|
||||
+ tsg_bool_to_string(flags->driveRedirectionDisabled),
|
||||
+ tsg_bool_to_string(flags->printerRedirectionDisabled),
|
||||
+ tsg_bool_to_string(flags->portRedirectionDisabled),
|
||||
+ tsg_bool_to_string(flags->reserved),
|
||||
+ tsg_bool_to_string(flags->clipboardRedirectionDisabled),
|
||||
+ tsg_bool_to_string(flags->pnpRedirectionDisabled));
|
||||
+ return buffer;
|
||||
+}
|
||||
+
|
||||
+static BOOL tsg_packet_response_to_string(char** buffer, size_t* length,
|
||||
+ const TSG_PACKET_RESPONSE* caps)
|
||||
+{
|
||||
+ BOOL rc = FALSE;
|
||||
+ char* strdata = NULL;
|
||||
+ char tbuffer[8192] = { 0 };
|
||||
+
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(caps);
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, "response { "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, " "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ strdata = winpr_BinToHexString(caps->responseData, caps->responseDataLen, TRUE);
|
||||
+ if (strdata || (caps->responseDataLen == 0))
|
||||
+ rc = tsg_print(
|
||||
+ buffer, length,
|
||||
+ " flags=0x%08" PRIx32 ", reserved=0x%08" PRIx32 ", responseData[%" PRIu32
|
||||
+ "]=%s, redirectionFlags={ %s }",
|
||||
+ caps->flags, caps->reserved, caps->responseDataLen, strdata,
|
||||
+ tsg_redirection_flags_to_string(tbuffer, ARRAYSIZE(tbuffer), &caps->redirectionFlags));
|
||||
+ free(strdata);
|
||||
+ if (!rc)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return tsg_print(buffer, length, " }");
|
||||
+}
|
||||
+
|
||||
+static BOOL tsg_packet_quarenc_response_to_string(char** buffer, size_t* length,
|
||||
+ const TSG_PACKET_QUARENC_RESPONSE* caps)
|
||||
+{
|
||||
+ BOOL rc = FALSE;
|
||||
+ char* strdata = NULL;
|
||||
+ RPC_CSTR uuid;
|
||||
+ char tbuffer[8192] = { 0 };
|
||||
+ size_t size = ARRAYSIZE(tbuffer);
|
||||
+ char* ptbuffer = tbuffer;
|
||||
+
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(caps);
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, "quarenc_response { "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, " "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (caps->certChainLen > 0)
|
||||
+ {
|
||||
+ if (ConvertFromUnicode(CP_UTF8, 0, caps->certChainData, caps->certChainLen, &strdata, 0,
|
||||
+ NULL, NULL) <= 0)
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ tsg_packet_versioncaps_to_string(&ptbuffer, &size, caps->versionCaps);
|
||||
+ UuidToStringA(&caps->nonce, &uuid);
|
||||
+ if (strdata || (caps->certChainLen == 0))
|
||||
+ rc =
|
||||
+ tsg_print(buffer, length,
|
||||
+ " flags=0x%08" PRIx32 ", certChain[%" PRIu32 "]=%s, nonce=%s, versionCaps=%s",
|
||||
+ caps->flags, caps->certChainLen, strdata, uuid, tbuffer);
|
||||
+ free(strdata);
|
||||
+ free(uuid);
|
||||
+ if (!rc)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return tsg_print(buffer, length, " }");
|
||||
+}
|
||||
+
|
||||
+static BOOL tsg_packet_message_response_to_string(char** buffer, size_t* length,
|
||||
+ const TSG_PACKET_MSG_RESPONSE* caps)
|
||||
+{
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(caps);
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, "msg_response { "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!tsg_print(buffer, length,
|
||||
+ " msgID=0x%08" PRIx32 ", msgType=0x%08" PRIx32 ", isMsgPresent=%" PRId32,
|
||||
+ caps->msgID, caps->msgType, caps->isMsgPresent))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return tsg_print(buffer, length, " }");
|
||||
+}
|
||||
+
|
||||
+static BOOL tsg_packet_caps_response_to_string(char** buffer, size_t* length,
|
||||
+ const TSG_PACKET_CAPS_RESPONSE* caps)
|
||||
+{
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(caps);
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, "caps_response { "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!tsg_packet_quarenc_response_to_string(buffer, length, &caps->pktQuarEncResponse))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!tsg_packet_message_response_to_string(buffer, length, &caps->pktConsentMessage))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return tsg_print(buffer, length, " }");
|
||||
+}
|
||||
+
|
||||
+static BOOL tsg_packet_message_request_to_string(char** buffer, size_t* length,
|
||||
+ const TSG_PACKET_MSG_REQUEST* caps)
|
||||
+{
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(caps);
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, "caps_message_request { "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, " maxMessagesPerBatch=%" PRIu32, caps->maxMessagesPerBatch))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return tsg_print(buffer, length, " }");
|
||||
+}
|
||||
+
|
||||
+static BOOL tsg_packet_auth_to_string(char** buffer, size_t* length, const TSG_PACKET_AUTH* caps)
|
||||
+{
|
||||
+ BOOL rc = FALSE;
|
||||
+ char* strdata = NULL;
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(caps);
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, "caps_message_request { "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!tsg_packet_versioncaps_to_string(buffer, length, &caps->tsgVersionCaps))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ strdata = winpr_BinToHexString(caps->cookie, caps->cookieLen, TRUE);
|
||||
+ if (strdata || (caps->cookieLen == 0))
|
||||
+ rc = tsg_print(buffer, length, " cookie[%" PRIu32 "]=%s", caps->cookieLen, strdata);
|
||||
+ free(strdata);
|
||||
+ if (!rc)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return tsg_print(buffer, length, " }");
|
||||
+}
|
||||
+
|
||||
+static BOOL tsg_packet_reauth_to_string(char** buffer, size_t* length,
|
||||
+ const TSG_PACKET_REAUTH* caps)
|
||||
+{
|
||||
+ BOOL rc = FALSE;
|
||||
+ WINPR_ASSERT(buffer);
|
||||
+ WINPR_ASSERT(length);
|
||||
+ WINPR_ASSERT(caps);
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, "caps_message_request { "))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ if (!tsg_print(buffer, length, " tunnelContext=0x%08" PRIx32 ", packetId=%s [0x%08" PRIx32 "]",
|
||||
+ caps->tunnelContext, tsg_packet_id_to_string(caps->packetId), caps->packetId))
|
||||
+ return FALSE;
|
||||
+
|
||||
+ switch (caps->packetId)
|
||||
+ {
|
||||
+ case TSG_PACKET_TYPE_VERSIONCAPS:
|
||||
+ rc = tsg_packet_versioncaps_to_string(buffer, length,
|
||||
+ caps->tsgInitialPacket.packetVersionCaps);
|
||||
+ break;
|
||||
+ case TSG_PACKET_TYPE_AUTH:
|
||||
+ rc = tsg_packet_auth_to_string(buffer, length, caps->tsgInitialPacket.packetAuth);
|
||||
+ break;
|
||||
+ default:
|
||||
+ rc = tsg_print(buffer, length, "TODO: Unhandled packet type %s [0x%08" PRIx32 "]",
|
||||
+ tsg_packet_id_to_string(caps->packetId), caps->packetId);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (!rc)
|
||||
+ return FALSE;
|
||||
+
|
||||
+ return tsg_print(buffer, length, " }");
|
||||
+}
|
||||
+
|
||||
static const char* tsg_packet_to_string(const TSG_PACKET* packet)
|
||||
{
|
||||
size_t len = 8192;
|
||||
@@ -387,43 +681,45 @@ static const char* tsg_packet_to_string(const TSG_PACKET* packet)
|
||||
goto fail;
|
||||
break;
|
||||
case TSG_PACKET_TYPE_QUARCONFIGREQUEST:
|
||||
- if (!tsg_print(&buffer, &len, "TODO"))
|
||||
+ if (!tsg_packet_quarconfigrequest_to_string(&buffer, &len,
|
||||
+ packet->tsgPacket.packetQuarConfigRequest))
|
||||
goto fail;
|
||||
break;
|
||||
case TSG_PACKET_TYPE_QUARREQUEST:
|
||||
- if (!tsg_print(&buffer, &len, "TODO"))
|
||||
+ if (!tsg_packet_quarrequest_to_string(&buffer, &len,
|
||||
+ packet->tsgPacket.packetQuarRequest))
|
||||
goto fail;
|
||||
break;
|
||||
case TSG_PACKET_TYPE_RESPONSE:
|
||||
- if (!tsg_print(&buffer, &len, "TODO"))
|
||||
+ if (!tsg_packet_response_to_string(&buffer, &len, packet->tsgPacket.packetResponse))
|
||||
goto fail;
|
||||
break;
|
||||
case TSG_PACKET_TYPE_QUARENC_RESPONSE:
|
||||
- if (!tsg_print(&buffer, &len, "TODO"))
|
||||
- goto fail;
|
||||
- break;
|
||||
- case TSG_CAPABILITY_TYPE_NAP:
|
||||
- if (!tsg_print(&buffer, &len, "TODO"))
|
||||
+ if (!tsg_packet_quarenc_response_to_string(&buffer, &len,
|
||||
+ packet->tsgPacket.packetQuarEncResponse))
|
||||
goto fail;
|
||||
break;
|
||||
case TSG_PACKET_TYPE_CAPS_RESPONSE:
|
||||
- if (!tsg_print(&buffer, &len, "TODO"))
|
||||
+ if (!tsg_packet_caps_response_to_string(&buffer, &len,
|
||||
+ packet->tsgPacket.packetCapsResponse))
|
||||
goto fail;
|
||||
break;
|
||||
case TSG_PACKET_TYPE_MSGREQUEST_PACKET:
|
||||
- if (!tsg_print(&buffer, &len, "TODO"))
|
||||
+ if (!tsg_packet_message_request_to_string(&buffer, &len,
|
||||
+ packet->tsgPacket.packetMsgRequest))
|
||||
goto fail;
|
||||
break;
|
||||
case TSG_PACKET_TYPE_MESSAGE_PACKET:
|
||||
- if (!tsg_print(&buffer, &len, "TODO"))
|
||||
+ if (!tsg_packet_message_response_to_string(&buffer, &len,
|
||||
+ packet->tsgPacket.packetMsgResponse))
|
||||
goto fail;
|
||||
break;
|
||||
case TSG_PACKET_TYPE_AUTH:
|
||||
- if (!tsg_print(&buffer, &len, "TODO"))
|
||||
+ if (!tsg_packet_auth_to_string(&buffer, &len, packet->tsgPacket.packetAuth))
|
||||
goto fail;
|
||||
break;
|
||||
case TSG_PACKET_TYPE_REAUTH:
|
||||
- if (!tsg_print(&buffer, &len, "TODO"))
|
||||
+ if (!tsg_packet_reauth_to_string(&buffer, &len, packet->tsgPacket.packetReauth))
|
||||
goto fail;
|
||||
break;
|
||||
default:
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,560 @@
|
||||
From a441e68fccc8ef137c9e8e667fed6adaab34ba37 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Holy <oholy@redhat.com>
|
||||
Date: Tue, 1 Oct 2024 15:43:07 +0200
|
||||
Subject: [PATCH] Revert "Moved clipboard utils to core library, fixes #6760
|
||||
(#7752)"
|
||||
|
||||
This reverts commit 26a83e6ccde272c1bbc2b2591325dc7a493811bc.
|
||||
---
|
||||
channels/cliprdr/client/cliprdr_format.c | 195 +++++++++++++++++++
|
||||
include/freerdp/channels/cliprdr.h | 12 +-
|
||||
include/freerdp/utils/cliprdr_utils.h | 48 -----
|
||||
libfreerdp/utils/CMakeLists.txt | 1 -
|
||||
libfreerdp/utils/cliprdr_utils.c | 235 -----------------------
|
||||
5 files changed, 206 insertions(+), 285 deletions(-)
|
||||
delete mode 100644 include/freerdp/utils/cliprdr_utils.h
|
||||
delete mode 100644 libfreerdp/utils/cliprdr_utils.c
|
||||
|
||||
diff --git a/channels/cliprdr/client/cliprdr_format.c b/channels/cliprdr/client/cliprdr_format.c
|
||||
index 0b6111b96..4c31a1b08 100644
|
||||
--- a/channels/cliprdr/client/cliprdr_format.c
|
||||
+++ b/channels/cliprdr/client/cliprdr_format.c
|
||||
@@ -173,3 +173,198 @@ UINT cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, wStream* s, UI
|
||||
|
||||
return error;
|
||||
}
|
||||
+
|
||||
+static UINT64 filetime_to_uint64(FILETIME value)
|
||||
+{
|
||||
+ UINT64 converted = 0;
|
||||
+ converted |= (UINT32)value.dwHighDateTime;
|
||||
+ converted <<= 32;
|
||||
+ converted |= (UINT32)value.dwLowDateTime;
|
||||
+ return converted;
|
||||
+}
|
||||
+
|
||||
+static FILETIME uint64_to_filetime(UINT64 value)
|
||||
+{
|
||||
+ FILETIME converted;
|
||||
+ converted.dwLowDateTime = (UINT32)(value >> 0);
|
||||
+ converted.dwHighDateTime = (UINT32)(value >> 32);
|
||||
+ return converted;
|
||||
+}
|
||||
+
|
||||
+#define CLIPRDR_FILEDESCRIPTOR_SIZE (4 + 32 + 4 + 16 + 8 + 8 + 520)
|
||||
+
|
||||
+/**
|
||||
+ * Parse a packed file list.
|
||||
+ *
|
||||
+ * The resulting array must be freed with the `free()` function.
|
||||
+ *
|
||||
+ * @param [in] format_data packed `CLIPRDR_FILELIST` to parse.
|
||||
+ * @param [in] format_data_length length of `format_data` in bytes.
|
||||
+ * @param [out] file_descriptor_array parsed array of `FILEDESCRIPTOR` structs.
|
||||
+ * @param [out] file_descriptor_count number of elements in `file_descriptor_array`.
|
||||
+ *
|
||||
+ * @returns 0 on success, otherwise a Win32 error code.
|
||||
+ */
|
||||
+UINT cliprdr_parse_file_list(const BYTE* format_data, UINT32 format_data_length,
|
||||
+ FILEDESCRIPTORW** file_descriptor_array, UINT32* file_descriptor_count)
|
||||
+{
|
||||
+ UINT result = NO_ERROR;
|
||||
+ UINT32 i;
|
||||
+ UINT32 count = 0;
|
||||
+ wStream* s = NULL;
|
||||
+
|
||||
+ if (!format_data || !file_descriptor_array || !file_descriptor_count)
|
||||
+ return ERROR_BAD_ARGUMENTS;
|
||||
+
|
||||
+ s = Stream_New((BYTE*)format_data, format_data_length);
|
||||
+ if (!s)
|
||||
+ return ERROR_NOT_ENOUGH_MEMORY;
|
||||
+
|
||||
+ if (Stream_GetRemainingLength(s) < 4)
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "invalid packed file list");
|
||||
+
|
||||
+ result = ERROR_INCORRECT_SIZE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ Stream_Read_UINT32(s, count); /* cItems (4 bytes) */
|
||||
+
|
||||
+ if (Stream_GetRemainingLength(s) / CLIPRDR_FILEDESCRIPTOR_SIZE < count)
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "packed file list is too short: expected %" PRIuz ", have %" PRIuz,
|
||||
+ ((size_t)count) * CLIPRDR_FILEDESCRIPTOR_SIZE, Stream_GetRemainingLength(s));
|
||||
+
|
||||
+ result = ERROR_INCORRECT_SIZE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ *file_descriptor_count = count;
|
||||
+ *file_descriptor_array = calloc(count, sizeof(FILEDESCRIPTORW));
|
||||
+ if (!*file_descriptor_array)
|
||||
+ {
|
||||
+ result = ERROR_NOT_ENOUGH_MEMORY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < count; i++)
|
||||
+ {
|
||||
+ int c;
|
||||
+ UINT64 lastWriteTime;
|
||||
+ FILEDESCRIPTORW* file = &((*file_descriptor_array)[i]);
|
||||
+
|
||||
+ Stream_Read_UINT32(s, file->dwFlags); /* flags (4 bytes) */
|
||||
+ Stream_Seek(s, 32); /* reserved1 (32 bytes) */
|
||||
+ Stream_Read_UINT32(s, file->dwFileAttributes); /* fileAttributes (4 bytes) */
|
||||
+ Stream_Seek(s, 16); /* reserved2 (16 bytes) */
|
||||
+ Stream_Read_UINT64(s, lastWriteTime); /* lastWriteTime (8 bytes) */
|
||||
+ file->ftLastWriteTime = uint64_to_filetime(lastWriteTime);
|
||||
+ Stream_Read_UINT32(s, file->nFileSizeHigh); /* fileSizeHigh (4 bytes) */
|
||||
+ Stream_Read_UINT32(s, file->nFileSizeLow); /* fileSizeLow (4 bytes) */
|
||||
+ for (c = 0; c < 260; c++) /* cFileName (520 bytes) */
|
||||
+ Stream_Read_UINT16(s, file->cFileName[c]);
|
||||
+ }
|
||||
+
|
||||
+ if (Stream_GetRemainingLength(s) > 0)
|
||||
+ WLog_WARN(TAG, "packed file list has %" PRIuz " excess bytes",
|
||||
+ Stream_GetRemainingLength(s));
|
||||
+out:
|
||||
+ Stream_Free(s, FALSE);
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+#define CLIPRDR_MAX_FILE_SIZE (2U * 1024 * 1024 * 1024)
|
||||
+
|
||||
+/**
|
||||
+ * Serialize a packed file list.
|
||||
+ *
|
||||
+ * The resulting format data must be freed with the `free()` function.
|
||||
+ *
|
||||
+ * @param [in] file_descriptor_array array of `FILEDESCRIPTOR` structs to serialize.
|
||||
+ * @param [in] file_descriptor_count number of elements in `file_descriptor_array`.
|
||||
+ * @param [out] format_data serialized CLIPRDR_FILELIST.
|
||||
+ * @param [out] format_data_length length of `format_data` in bytes.
|
||||
+ *
|
||||
+ * @returns 0 on success, otherwise a Win32 error code.
|
||||
+ */
|
||||
+UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
|
||||
+ UINT32 file_descriptor_count, BYTE** format_data,
|
||||
+ UINT32* format_data_length)
|
||||
+{
|
||||
+ return cliprdr_serialize_file_list_ex(CB_STREAM_FILECLIP_ENABLED, file_descriptor_array,
|
||||
+ file_descriptor_count, format_data, format_data_length);
|
||||
+}
|
||||
+
|
||||
+UINT cliprdr_serialize_file_list_ex(UINT32 flags, const FILEDESCRIPTORW* file_descriptor_array,
|
||||
+ UINT32 file_descriptor_count, BYTE** format_data,
|
||||
+ UINT32* format_data_length)
|
||||
+{
|
||||
+ UINT result = NO_ERROR;
|
||||
+ UINT32 i;
|
||||
+ wStream* s = NULL;
|
||||
+
|
||||
+ if (!file_descriptor_array || !format_data || !format_data_length)
|
||||
+ return ERROR_BAD_ARGUMENTS;
|
||||
+
|
||||
+ if ((flags & CB_STREAM_FILECLIP_ENABLED) == 0)
|
||||
+ {
|
||||
+ WLog_WARN(TAG, "No file clipboard support annouonced!");
|
||||
+ return ERROR_BAD_ARGUMENTS;
|
||||
+ }
|
||||
+
|
||||
+ s = Stream_New(NULL, 4 + file_descriptor_count * CLIPRDR_FILEDESCRIPTOR_SIZE);
|
||||
+ if (!s)
|
||||
+ return ERROR_NOT_ENOUGH_MEMORY;
|
||||
+
|
||||
+ Stream_Write_UINT32(s, file_descriptor_count); /* cItems (4 bytes) */
|
||||
+
|
||||
+ for (i = 0; i < file_descriptor_count; i++)
|
||||
+ {
|
||||
+ int c;
|
||||
+ UINT64 lastWriteTime;
|
||||
+ const FILEDESCRIPTORW* file = &file_descriptor_array[i];
|
||||
+
|
||||
+ /*
|
||||
+ * There is a known issue with Windows server getting stuck in
|
||||
+ * an infinite loop when downloading files that are larger than
|
||||
+ * 2 gigabytes. Do not allow clients to send such file lists.
|
||||
+ *
|
||||
+ * https://support.microsoft.com/en-us/help/2258090
|
||||
+ */
|
||||
+ if ((flags & CB_HUGE_FILE_SUPPORT_ENABLED) == 0)
|
||||
+ {
|
||||
+ if ((file->nFileSizeHigh > 0) || (file->nFileSizeLow >= CLIPRDR_MAX_FILE_SIZE))
|
||||
+ {
|
||||
+ WLog_ERR(TAG, "cliprdr does not support files over 2 GB");
|
||||
+ result = ERROR_FILE_TOO_LARGE;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ Stream_Write_UINT32(s, file->dwFlags); /* flags (4 bytes) */
|
||||
+ Stream_Zero(s, 32); /* reserved1 (32 bytes) */
|
||||
+ Stream_Write_UINT32(s, file->dwFileAttributes); /* fileAttributes (4 bytes) */
|
||||
+ Stream_Zero(s, 16); /* reserved2 (16 bytes) */
|
||||
+ lastWriteTime = filetime_to_uint64(file->ftLastWriteTime);
|
||||
+ Stream_Write_UINT64(s, lastWriteTime); /* lastWriteTime (8 bytes) */
|
||||
+ Stream_Write_UINT32(s, file->nFileSizeHigh); /* fileSizeHigh (4 bytes) */
|
||||
+ Stream_Write_UINT32(s, file->nFileSizeLow); /* fileSizeLow (4 bytes) */
|
||||
+ for (c = 0; c < 260; c++) /* cFileName (520 bytes) */
|
||||
+ Stream_Write_UINT16(s, file->cFileName[c]);
|
||||
+ }
|
||||
+
|
||||
+ Stream_SealLength(s);
|
||||
+
|
||||
+ Stream_GetBuffer(s, *format_data);
|
||||
+ Stream_GetLength(s, *format_data_length);
|
||||
+
|
||||
+ Stream_Free(s, FALSE);
|
||||
+
|
||||
+ return result;
|
||||
+
|
||||
+error:
|
||||
+ Stream_Free(s, TRUE);
|
||||
+
|
||||
+ return result;
|
||||
+}
|
||||
diff --git a/include/freerdp/channels/cliprdr.h b/include/freerdp/channels/cliprdr.h
|
||||
index fbf23f6e5..86fc65890 100644
|
||||
--- a/include/freerdp/channels/cliprdr.h
|
||||
+++ b/include/freerdp/channels/cliprdr.h
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <freerdp/api.h>
|
||||
#include <freerdp/types.h>
|
||||
-#include <freerdp/utils/cliprdr_utils.h>
|
||||
|
||||
#include <winpr/shell.h>
|
||||
|
||||
@@ -94,6 +93,17 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
+ FREERDP_API UINT cliprdr_parse_file_list(const BYTE* format_data, UINT32 format_data_length,
|
||||
+ FILEDESCRIPTORW** file_descriptor_array,
|
||||
+ UINT32* file_descriptor_count);
|
||||
+ FREERDP_API UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
|
||||
+ UINT32 file_descriptor_count, BYTE** format_data,
|
||||
+ UINT32* format_data_length);
|
||||
+ FREERDP_API UINT cliprdr_serialize_file_list_ex(UINT32 flags,
|
||||
+ const FILEDESCRIPTORW* file_descriptor_array,
|
||||
+ UINT32 file_descriptor_count,
|
||||
+ BYTE** format_data, UINT32* format_data_length);
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff --git a/include/freerdp/utils/cliprdr_utils.h b/include/freerdp/utils/cliprdr_utils.h
|
||||
deleted file mode 100644
|
||||
index 59ecf848f..000000000
|
||||
--- a/include/freerdp/utils/cliprdr_utils.h
|
||||
+++ /dev/null
|
||||
@@ -1,48 +0,0 @@
|
||||
-/**
|
||||
- * FreeRDP: A Remote Desktop Protocol Implementation
|
||||
- * RDPDR utility functions
|
||||
- *
|
||||
- * Copyright 2022 Armin Novak <armin.novak@thincast.com>
|
||||
- * Copyright 2022 Thincast Technologies GmbH
|
||||
- *
|
||||
- * 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_UTILS_CLIPRDR_H
|
||||
-#define FREERDP_UTILS_CLIPRDR_H
|
||||
-
|
||||
-#include <winpr/wtypes.h>
|
||||
-#include <winpr/shell.h>
|
||||
-#include <freerdp/api.h>
|
||||
-
|
||||
-#ifdef __cplusplus
|
||||
-extern "C"
|
||||
-{
|
||||
-#endif
|
||||
-
|
||||
- FREERDP_API UINT cliprdr_parse_file_list(const BYTE* format_data, UINT32 format_data_length,
|
||||
- FILEDESCRIPTORW** file_descriptor_array,
|
||||
- UINT32* file_descriptor_count);
|
||||
- FREERDP_API UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
|
||||
- UINT32 file_descriptor_count, BYTE** format_data,
|
||||
- UINT32* format_data_length);
|
||||
- FREERDP_API UINT cliprdr_serialize_file_list_ex(UINT32 flags,
|
||||
- const FILEDESCRIPTORW* file_descriptor_array,
|
||||
- UINT32 file_descriptor_count,
|
||||
- BYTE** format_data, UINT32* format_data_length);
|
||||
-
|
||||
-#ifdef __cplusplus
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
-#endif
|
||||
diff --git a/libfreerdp/utils/CMakeLists.txt b/libfreerdp/utils/CMakeLists.txt
|
||||
index 2ec561d33..7bff6736a 100644
|
||||
--- a/libfreerdp/utils/CMakeLists.txt
|
||||
+++ b/libfreerdp/utils/CMakeLists.txt
|
||||
@@ -20,7 +20,6 @@ set(MODULE_PREFIX "FREERDP_UTILS")
|
||||
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
passphrase.c
|
||||
- cliprdr_utils.c
|
||||
pcap.c
|
||||
profiler.c
|
||||
ringbuffer.c
|
||||
diff --git a/libfreerdp/utils/cliprdr_utils.c b/libfreerdp/utils/cliprdr_utils.c
|
||||
deleted file mode 100644
|
||||
index 7fb99d63a..000000000
|
||||
--- a/libfreerdp/utils/cliprdr_utils.c
|
||||
+++ /dev/null
|
||||
@@ -1,235 +0,0 @@
|
||||
-/**
|
||||
- * FreeRDP: A Remote Desktop Protocol Implementation
|
||||
- * Clipboard Virtual Channel Extension
|
||||
- *
|
||||
- * Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
- * Copyright 2022 Armin Novak <anovak@thincast.com
|
||||
- * Copyright 2022 Thincast Technologies GmbH
|
||||
- *
|
||||
- * 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 <winpr/stream.h>
|
||||
-#include <freerdp/utils/cliprdr_utils.h>
|
||||
-#include <freerdp/channels/cliprdr.h>
|
||||
-
|
||||
-#include <freerdp/log.h>
|
||||
-#define TAG FREERDP_TAG("utils." CLIPRDR_SVC_CHANNEL_NAME)
|
||||
-
|
||||
-#define CLIPRDR_FILEDESCRIPTOR_SIZE (4 + 32 + 4 + 16 + 8 + 8 + 520)
|
||||
-#define CLIPRDR_MAX_FILE_SIZE (2U * 1024 * 1024 * 1024)
|
||||
-
|
||||
-static UINT64 filetime_to_uint64(FILETIME value)
|
||||
-{
|
||||
- UINT64 converted = 0;
|
||||
- converted |= (UINT32)value.dwHighDateTime;
|
||||
- converted <<= 32;
|
||||
- converted |= (UINT32)value.dwLowDateTime;
|
||||
- return converted;
|
||||
-}
|
||||
-
|
||||
-static FILETIME uint64_to_filetime(UINT64 value)
|
||||
-{
|
||||
- FILETIME converted;
|
||||
- converted.dwLowDateTime = (UINT32)(value >> 0);
|
||||
- converted.dwHighDateTime = (UINT32)(value >> 32);
|
||||
- return converted;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * Parse a packed file list.
|
||||
- *
|
||||
- * The resulting array must be freed with the `free()` function.
|
||||
- *
|
||||
- * @param [in] format_data packed `CLIPRDR_FILELIST` to parse.
|
||||
- * @param [in] format_data_length length of `format_data` in bytes.
|
||||
- * @param [out] file_descriptor_array parsed array of `FILEDESCRIPTOR` structs.
|
||||
- * @param [out] file_descriptor_count number of elements in `file_descriptor_array`.
|
||||
- *
|
||||
- * @returns 0 on success, otherwise a Win32 error code.
|
||||
- */
|
||||
-UINT cliprdr_parse_file_list(const BYTE* format_data, UINT32 format_data_length,
|
||||
- FILEDESCRIPTORW** file_descriptor_array, UINT32* file_descriptor_count)
|
||||
-{
|
||||
- UINT result = NO_ERROR;
|
||||
- UINT32 i;
|
||||
- UINT32 count = 0;
|
||||
- wStream sbuffer;
|
||||
- wStream* s = &sbuffer;
|
||||
-
|
||||
- if (!format_data || !file_descriptor_array || !file_descriptor_count)
|
||||
- return ERROR_BAD_ARGUMENTS;
|
||||
-
|
||||
- Stream_StaticInit(&sbuffer, format_data, format_data_length);
|
||||
- if (!s)
|
||||
- return ERROR_NOT_ENOUGH_MEMORY;
|
||||
-
|
||||
- if (Stream_GetRemainingLength(s) < 4)
|
||||
- {
|
||||
- WLog_ERR(TAG, "invalid packed file list");
|
||||
-
|
||||
- result = ERROR_INCORRECT_SIZE;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- Stream_Read_UINT32(s, count); /* cItems (4 bytes) */
|
||||
-
|
||||
- if (Stream_GetRemainingLength(s) / CLIPRDR_FILEDESCRIPTOR_SIZE < count)
|
||||
- {
|
||||
- WLog_ERR(TAG, "packed file list is too short: expected %" PRIuz ", have %" PRIuz,
|
||||
- ((size_t)count) * CLIPRDR_FILEDESCRIPTOR_SIZE, Stream_GetRemainingLength(s));
|
||||
-
|
||||
- result = ERROR_INCORRECT_SIZE;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- *file_descriptor_count = count;
|
||||
- *file_descriptor_array = calloc(count, sizeof(FILEDESCRIPTORW));
|
||||
- if (!*file_descriptor_array)
|
||||
- {
|
||||
- result = ERROR_NOT_ENOUGH_MEMORY;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- for (i = 0; i < count; i++)
|
||||
- {
|
||||
- UINT64 tmp;
|
||||
- FILEDESCRIPTORW* file = &((*file_descriptor_array)[i]);
|
||||
-
|
||||
- Stream_Read_UINT32(s, file->dwFlags); /* flags (4 bytes) */
|
||||
- Stream_Read_UINT32(s, file->clsid.Data1);
|
||||
- Stream_Read_UINT16(s, file->clsid.Data2);
|
||||
- Stream_Read_UINT16(s, file->clsid.Data3);
|
||||
- Stream_Read(s, &file->clsid.Data4, sizeof(file->clsid.Data4));
|
||||
- Stream_Read_INT32(s, file->sizel.cx);
|
||||
- Stream_Read_INT32(s, file->sizel.cy);
|
||||
- Stream_Read_INT32(s, file->pointl.x);
|
||||
- Stream_Read_INT32(s, file->pointl.y);
|
||||
- Stream_Read_UINT32(s, file->dwFileAttributes); /* fileAttributes (4 bytes) */
|
||||
- Stream_Read_UINT64(s, tmp); /* ftCreationTime (8 bytes) */
|
||||
- file->ftCreationTime = uint64_to_filetime(tmp);
|
||||
- Stream_Read_UINT64(s, tmp); /* ftLastAccessTime (8 bytes) */
|
||||
- file->ftLastAccessTime = uint64_to_filetime(tmp);
|
||||
- Stream_Read_UINT64(s, tmp); /* lastWriteTime (8 bytes) */
|
||||
- file->ftLastWriteTime = uint64_to_filetime(tmp);
|
||||
- Stream_Read_UINT32(s, file->nFileSizeHigh); /* fileSizeHigh (4 bytes) */
|
||||
- Stream_Read_UINT32(s, file->nFileSizeLow); /* fileSizeLow (4 bytes) */
|
||||
- Stream_Read_UTF16_String(s, file->cFileName,
|
||||
- ARRAYSIZE(file->cFileName)); /* cFileName (520 bytes) */
|
||||
- }
|
||||
-
|
||||
- if (Stream_GetRemainingLength(s) > 0)
|
||||
- WLog_WARN(TAG, "packed file list has %" PRIuz " excess bytes",
|
||||
- Stream_GetRemainingLength(s));
|
||||
-out:
|
||||
-
|
||||
- return result;
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * Serialize a packed file list.
|
||||
- *
|
||||
- * The resulting format data must be freed with the `free()` function.
|
||||
- *
|
||||
- * @param [in] file_descriptor_array array of `FILEDESCRIPTOR` structs to serialize.
|
||||
- * @param [in] file_descriptor_count number of elements in `file_descriptor_array`.
|
||||
- * @param [out] format_data serialized CLIPRDR_FILELIST.
|
||||
- * @param [out] format_data_length length of `format_data` in bytes.
|
||||
- *
|
||||
- * @returns 0 on success, otherwise a Win32 error code.
|
||||
- */
|
||||
-UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
|
||||
- UINT32 file_descriptor_count, BYTE** format_data,
|
||||
- UINT32* format_data_length)
|
||||
-{
|
||||
- return cliprdr_serialize_file_list_ex(CB_STREAM_FILECLIP_ENABLED, file_descriptor_array,
|
||||
- file_descriptor_count, format_data, format_data_length);
|
||||
-}
|
||||
-
|
||||
-UINT cliprdr_serialize_file_list_ex(UINT32 flags, const FILEDESCRIPTORW* file_descriptor_array,
|
||||
- UINT32 file_descriptor_count, BYTE** format_data,
|
||||
- UINT32* format_data_length)
|
||||
-{
|
||||
- UINT result = NO_ERROR;
|
||||
- UINT32 i;
|
||||
- size_t len;
|
||||
- wStream* s = NULL;
|
||||
-
|
||||
- if (!file_descriptor_array || !format_data || !format_data_length)
|
||||
- return ERROR_BAD_ARGUMENTS;
|
||||
-
|
||||
- if ((flags & CB_STREAM_FILECLIP_ENABLED) == 0)
|
||||
- {
|
||||
- WLog_WARN(TAG, "No file clipboard support annouonced!");
|
||||
- return ERROR_BAD_ARGUMENTS;
|
||||
- }
|
||||
-
|
||||
- s = Stream_New(NULL, 4 + file_descriptor_count * CLIPRDR_FILEDESCRIPTOR_SIZE);
|
||||
- if (!s)
|
||||
- return ERROR_NOT_ENOUGH_MEMORY;
|
||||
-
|
||||
- Stream_Write_UINT32(s, file_descriptor_count); /* cItems (4 bytes) */
|
||||
-
|
||||
- for (i = 0; i < file_descriptor_count; i++)
|
||||
- {
|
||||
- int c;
|
||||
- UINT64 lastWriteTime;
|
||||
- const FILEDESCRIPTORW* file = &file_descriptor_array[i];
|
||||
-
|
||||
- /*
|
||||
- * There is a known issue with Windows server getting stuck in
|
||||
- * an infinite loop when downloading files that are larger than
|
||||
- * 2 gigabytes. Do not allow clients to send such file lists.
|
||||
- *
|
||||
- * https://support.microsoft.com/en-us/help/2258090
|
||||
- */
|
||||
- if ((flags & CB_HUGE_FILE_SUPPORT_ENABLED) == 0)
|
||||
- {
|
||||
- if ((file->nFileSizeHigh > 0) || (file->nFileSizeLow >= CLIPRDR_MAX_FILE_SIZE))
|
||||
- {
|
||||
- WLog_ERR(TAG, "cliprdr does not support files over 2 GB");
|
||||
- result = ERROR_FILE_TOO_LARGE;
|
||||
- goto error;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- Stream_Write_UINT32(s, file->dwFlags); /* flags (4 bytes) */
|
||||
- Stream_Zero(s, 32); /* reserved1 (32 bytes) */
|
||||
- Stream_Write_UINT32(s, file->dwFileAttributes); /* fileAttributes (4 bytes) */
|
||||
- Stream_Zero(s, 16); /* reserved2 (16 bytes) */
|
||||
- lastWriteTime = filetime_to_uint64(file->ftLastWriteTime);
|
||||
- Stream_Write_UINT64(s, lastWriteTime); /* lastWriteTime (8 bytes) */
|
||||
- Stream_Write_UINT32(s, file->nFileSizeHigh); /* fileSizeHigh (4 bytes) */
|
||||
- Stream_Write_UINT32(s, file->nFileSizeLow); /* fileSizeLow (4 bytes) */
|
||||
- for (c = 0; c < 260; c++) /* cFileName (520 bytes) */
|
||||
- Stream_Write_UINT16(s, file->cFileName[c]);
|
||||
- }
|
||||
-
|
||||
- Stream_SealLength(s);
|
||||
-
|
||||
- Stream_GetBuffer(s, *format_data);
|
||||
- Stream_GetLength(s, len);
|
||||
- if (len > UINT32_MAX)
|
||||
- goto error;
|
||||
-
|
||||
- *format_data_length = (UINT32)len;
|
||||
-
|
||||
- Stream_Free(s, FALSE);
|
||||
-
|
||||
- return result;
|
||||
-
|
||||
-error:
|
||||
- Stream_Free(s, TRUE);
|
||||
-
|
||||
- return result;
|
||||
-}
|
||||
--
|
||||
2.46.1
|
||||
|
@ -1,66 +0,0 @@
|
||||
From ddc6dacd06b41ed5001b1c884b5d5c9e0a70e275 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 10 Nov 2022 15:54:28 +0100
|
||||
Subject: [PATCH] [winpr, crt] Added wcsstr implementation
|
||||
|
||||
(cherry picked from commit 6c034ba6117a4efc9266e845fe9a9a92ed4ee61d)
|
||||
---
|
||||
winpr/include/winpr/string.h | 3 +++
|
||||
winpr/libwinpr/crt/string.c | 20 ++++++++++++++++++++
|
||||
2 files changed, 23 insertions(+)
|
||||
|
||||
diff --git a/winpr/include/winpr/string.h b/winpr/include/winpr/string.h
|
||||
index 3b907c444..2d7126210 100644
|
||||
--- a/winpr/include/winpr/string.h
|
||||
+++ b/winpr/include/winpr/string.h
|
||||
@@ -62,6 +62,8 @@ extern "C"
|
||||
WINPR_API size_t _wcslen(const WCHAR* str);
|
||||
WINPR_API size_t _wcsnlen(const WCHAR* str, size_t maxNumberOfElements);
|
||||
|
||||
+ WINPR_API WCHAR* _wcsstr(const WCHAR* str, const WCHAR* strSearch);
|
||||
+
|
||||
WINPR_API WCHAR* _wcschr(const WCHAR* str, WCHAR c);
|
||||
WINPR_API WCHAR* _wcsrchr(const WCHAR* str, WCHAR c);
|
||||
|
||||
@@ -74,6 +76,7 @@ extern "C"
|
||||
#define _wcsncmp wcsncmp
|
||||
#define _wcslen wcslen
|
||||
#define _wcsnlen wcsnlen
|
||||
+#define _wcsstr wcsstr
|
||||
#define _wcschr wcschr
|
||||
#define _wcsrchr wcsrchr
|
||||
|
||||
diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c
|
||||
index 5dcf4b3f1..efd7d166c 100644
|
||||
--- a/winpr/libwinpr/crt/string.c
|
||||
+++ b/winpr/libwinpr/crt/string.c
|
||||
@@ -147,6 +147,26 @@ size_t _wcsnlen(const WCHAR* str, size_t max)
|
||||
return x;
|
||||
}
|
||||
|
||||
+/* _wcsstr -> wcsstr */
|
||||
+
|
||||
+WCHAR* _wcsstr(const WCHAR* str, const WCHAR* strSearch)
|
||||
+{
|
||||
+ assert(str);
|
||||
+ assert(strSearch);
|
||||
+
|
||||
+ if (strSearch[0] == '\0')
|
||||
+ return str;
|
||||
+
|
||||
+ const size_t searchLen = _wcslen(strSearch);
|
||||
+ while (*str)
|
||||
+ {
|
||||
+ if (_wcsncmp(str, strSearch, searchLen) == 0)
|
||||
+ return str;
|
||||
+ str++;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
/* _wcschr -> wcschr */
|
||||
|
||||
WCHAR* _wcschr(const WCHAR* str, WCHAR c)
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,90 +0,0 @@
|
||||
From fb9d753af70b449dd7a17898d46fd57822a08dc1 Mon Sep 17 00:00:00 2001
|
||||
From: akallabeth <akallabeth@posteo.net>
|
||||
Date: Thu, 10 Nov 2022 14:21:22 +0100
|
||||
Subject: [PATCH] [winpr, crt] Fix wcs*cmp and wcs*len checks
|
||||
|
||||
(cherry picked from commit b60fac1a0470fe83e8d0b448f0fd7e9e6d6a0f96)
|
||||
---
|
||||
winpr/libwinpr/crt/string.c | 30 +++++++++++++++++++-----------
|
||||
1 file changed, 19 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/winpr/libwinpr/crt/string.c b/winpr/libwinpr/crt/string.c
|
||||
index c25ffa279..5dcf4b3f1 100644
|
||||
--- a/winpr/libwinpr/crt/string.c
|
||||
+++ b/winpr/libwinpr/crt/string.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <wctype.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
+#include <assert.h>
|
||||
#include <winpr/endian.h>
|
||||
|
||||
/* String Manipulation (CRT): http://msdn.microsoft.com/en-us/library/f0151s4x.aspx */
|
||||
@@ -80,21 +81,28 @@ int _strnicmp(const char* string1, const char* string2, size_t count)
|
||||
|
||||
int _wcscmp(const WCHAR* string1, const WCHAR* string2)
|
||||
{
|
||||
- WCHAR value1, value2;
|
||||
+ assert(string1);
|
||||
+ assert(string2);
|
||||
|
||||
- while (*string1 && (*string1 == *string2))
|
||||
+ while (TRUE)
|
||||
{
|
||||
- string1++;
|
||||
- string2++;
|
||||
+ const WCHAR w1 = *string1++;
|
||||
+ const WCHAR w2 = *string2++;
|
||||
+
|
||||
+ if (w1 != w2)
|
||||
+ return (int)w1 - w2;
|
||||
+ else if ((w1 == '\0') || (w2 == '\0'))
|
||||
+ return (int)w1 - w2;
|
||||
}
|
||||
|
||||
- Data_Read_UINT16(string1, value1);
|
||||
- Data_Read_UINT16(string2, value2);
|
||||
- return (int)value1 - value2;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
int _wcsncmp(const WCHAR* string1, const WCHAR* string2, size_t count)
|
||||
{
|
||||
+ assert(string1);
|
||||
+ assert(string2);
|
||||
+
|
||||
for (size_t x = 0; x < count; x++)
|
||||
{
|
||||
const WCHAR a = string1[x];
|
||||
@@ -102,6 +110,8 @@ int _wcsncmp(const WCHAR* string1, const WCHAR* string2, size_t count)
|
||||
|
||||
if (a != b)
|
||||
return (int)a - b;
|
||||
+ else if ((a == '\0') || (b == '\0'))
|
||||
+ return (int)a - b;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -112,8 +122,7 @@ size_t _wcslen(const WCHAR* str)
|
||||
{
|
||||
const WCHAR* p = (const WCHAR*)str;
|
||||
|
||||
- if (!p)
|
||||
- return 0;
|
||||
+ assert(p);
|
||||
|
||||
while (*p)
|
||||
p++;
|
||||
@@ -127,8 +136,7 @@ size_t _wcsnlen(const WCHAR* str, size_t max)
|
||||
{
|
||||
size_t x;
|
||||
|
||||
- if (!str)
|
||||
- return 0;
|
||||
+ assert(str);
|
||||
|
||||
for (x = 0; x < max; x++)
|
||||
{
|
||||
--
|
||||
2.37.1
|
||||
|
@ -1,18 +1,23 @@
|
||||
# Can be rebuilt with FFmpeg/H264 support enabled by passing "--with=ffmpeg",
|
||||
# "--with=x264" or "--with=openh264" to mock/rpmbuild; or by globally setting
|
||||
# these variables:
|
||||
|
||||
# Can be rebuilt with FFmpeg/OpenH264 support enabled by passing
|
||||
# "--with=ffmpeg", or "--with=openh264" to mock/rpmbuild; or by globally
|
||||
# setting these variables:
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2242028
|
||||
#global _with_ffmpeg 1
|
||||
#global _with_x264 1
|
||||
#global _with_openh264 1
|
||||
|
||||
# Can be rebuilt with OpenCL support enabled by passing # "--with=opencl"
|
||||
# or by globally setting:
|
||||
#global _opencl 1
|
||||
|
||||
# Momentarily disable GSS support
|
||||
# https://github.com/FreeRDP/FreeRDP/issues/4348
|
||||
#global _with_gss 1
|
||||
|
||||
# Disable server support in RHEL
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1639165
|
||||
%{!?rhel:%global _with_server 1}
|
||||
%if 0%{?fedora} || 0%{?rhel} >= 10
|
||||
%global _with_server 1
|
||||
%endif
|
||||
|
||||
# Disable support for missing codecs in RHEL
|
||||
%{!?rhel:%global _with_soxr 1}
|
||||
@ -21,8 +26,8 @@
|
||||
%endif
|
||||
|
||||
Name: freerdp
|
||||
Version: 2.2.0
|
||||
Release: 10%{?dist}
|
||||
Version: 2.11.7
|
||||
Release: 1%{?dist}
|
||||
Epoch: 2
|
||||
Summary: Free implementation of the Remote Desktop Protocol (RDP)
|
||||
License: ASL 2.0
|
||||
@ -30,37 +35,9 @@ URL: http://www.freerdp.com/
|
||||
|
||||
Source0: https://github.com/FreeRDP/FreeRDP/archive/%{version}/FreeRDP-%{version}.tar.gz
|
||||
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1910029
|
||||
Patch0: 6741.patch
|
||||
|
||||
# CVE-2021-41160 freerdp: improper region checks in all clients allow out of bound write to memory
|
||||
Patch1: Add-checks-for-bitmap-and-glyph-width-heigth-values.patch
|
||||
|
||||
# CVE-2021-41159 freerdp: improper client input validation for gateway connections allows to overwrite memory
|
||||
Patch2: Implement-missing-TSG-debug-functions.patch
|
||||
Patch3: Refactored-RPC-gateway-parser.patch
|
||||
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2108866
|
||||
Patch4: Fix-monitor-list-flag-being-ignored-on-X11-Wayland.patch
|
||||
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2136151
|
||||
Patch5: Fix-length-checks-in-parallel-driver.patch
|
||||
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2136153
|
||||
Patch6: Fixed-missing-length-check-in-video-channel.patch
|
||||
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2145139
|
||||
Patch7: Added-missing-length-checks-in-zgfx_decompress_segme.patch
|
||||
Patch8: Fixed-division-by-zero-in-urbdrc.patch
|
||||
Patch9: Added-missing-length-check-in-urb_control_transfer.patch
|
||||
Patch10: Fixed-missing-input-buffer-length-check-in-urbdrc.patch
|
||||
Patch11: Ensure-urb_create_iocompletion-uses-size_t-for-calcu.patch
|
||||
Patch12: Added-function-_wcsncmp.patch
|
||||
Patch13: winpr-crt-Fix-wcs-cmp-and-wcs-len-checks.patch
|
||||
Patch14: winpr-crt-Added-wcsstr-implementation.patch
|
||||
Patch15: Fixed-path-validation-in-drive-channel.patch
|
||||
Patch16: Fixed-missing-stream-length-check-in-drive_file_quer.patch
|
||||
Patch17: Fixed-format-string-for-Stream_CheckAndLogRequiredLe.patch
|
||||
# Revert changes that break API
|
||||
# https://issues.redhat.com/browse/RHEL-53081
|
||||
Patch0: Revert-Moved-clipboard-utils-to-core-library-fixes-6.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: gcc-c++
|
||||
@ -81,6 +58,8 @@ BuildRequires: libxkbfile-devel
|
||||
BuildRequires: libXrandr-devel
|
||||
%{?_with_server:BuildRequires: libXtst-devel}
|
||||
BuildRequires: libXv-devel
|
||||
%{?_with_opencl:BuildRequires: opencl-headers >= 3.0}
|
||||
%{?_with_opencl:BuildRequires: ocl-icd-devel}
|
||||
%{?_with_openh264:BuildRequires: openh264-devel}
|
||||
%{?_with_x264:BuildRequires: x264-devel}
|
||||
%{?_with_server:BuildRequires: pam-devel}
|
||||
@ -89,16 +68,6 @@ BuildRequires: zlib-devel
|
||||
BuildRequires: multilib-rpm-config
|
||||
|
||||
BuildRequires: pkgconfig(cairo)
|
||||
BuildRequires: pkgconfig(dbus-1)
|
||||
BuildRequires: pkgconfig(dbus-glib-1)
|
||||
BuildRequires: pkgconfig(glib-2.0)
|
||||
BuildRequires: pkgconfig(gstreamer-1.0)
|
||||
BuildRequires: pkgconfig(gstreamer-base-1.0)
|
||||
BuildRequires: pkgconfig(gstreamer-app-1.0)
|
||||
BuildRequires: pkgconfig(gstreamer-audio-1.0)
|
||||
BuildRequires: pkgconfig(gstreamer-fft-1.0)
|
||||
BuildRequires: pkgconfig(gstreamer-pbutils-1.0)
|
||||
BuildRequires: pkgconfig(gstreamer-video-1.0)
|
||||
%{?_with_gss:BuildRequires: pkgconfig(krb5) >= 1.13}
|
||||
BuildRequires: pkgconfig(libpcsclite)
|
||||
BuildRequires: pkgconfig(libpulse)
|
||||
@ -191,20 +160,21 @@ find . -name "*.c" -exec chmod 664 {} \;
|
||||
%cmake %{?_cmake_skip_rpath} \
|
||||
-DCMAKE_INSTALL_LIBDIR:PATH=%{_lib} \
|
||||
-DWITH_ALSA=ON \
|
||||
-DWITH_CAIRO=ON \
|
||||
-DWITH_CUPS=ON \
|
||||
-DWITH_CHANNELS=ON -DBUILTIN_CHANNELS=OFF \
|
||||
-DWITH_CLIENT=ON \
|
||||
-DWITH_DIRECTFB=OFF \
|
||||
-DWITH_DSP_FFMPEG=%{?_with_ffmpeg:ON}%{?!_with_ffmpeg:OFF} \
|
||||
-DWITH_FFMPEG=%{?_with_ffmpeg:ON}%{?!_with_ffmpeg:OFF} \
|
||||
-DWITH_GSM=ON \
|
||||
-DWITH_GSSAPI=%{?_with_gss:ON}%{?!_with_gss:OFF} \
|
||||
-DWITH_GSTREAMER_1_0=ON -DWITH_GSTREAMER_0_10=OFF \
|
||||
-DGSTREAMER_1_0_INCLUDE_DIRS=%{_includedir}/gstreamer-1.0 \
|
||||
-DWITH_ICU=ON \
|
||||
-DWITH_IPP=OFF \
|
||||
-DWITH_JPEG=ON \
|
||||
-DWITH_LAME=%{?_with_lame:ON}%{?!_with_lame:OFF} \
|
||||
-DWITH_MANPAGES=ON \
|
||||
-DWITH_OPENCL=%{?_with_opencl:ON}%{?!_with_opencl:OFF} \
|
||||
-DWITH_OPENH264=%{?_with_openh264:ON}%{?!_with_openh264:OFF} \
|
||||
-DWITH_OPENSSL=ON \
|
||||
-DWITH_PCSC=ON \
|
||||
@ -216,7 +186,6 @@ find . -name "*.c" -exec chmod 664 {} \;
|
||||
-DWITH_SOXR=%{?_with_soxr:ON}%{?!_with_soxr:OFF} \
|
||||
-DWITH_WAYLAND=ON \
|
||||
-DWITH_X11=ON \
|
||||
-DWITH_X264=%{?_with_x264:ON}%{?!_with_x264:OFF} \
|
||||
-DWITH_XCURSOR=ON \
|
||||
-DWITH_XEXT=ON \
|
||||
-DWITH_XKBFILE=ON \
|
||||
@ -244,17 +213,12 @@ find . -name "*.c" -exec chmod 664 {} \;
|
||||
-DARM_FP_ABI=soft \
|
||||
-DWITH_NEON=OFF \
|
||||
%endif
|
||||
.
|
||||
%{nil}
|
||||
|
||||
%make_build
|
||||
|
||||
pushd winpr/tools/makecert-cli
|
||||
%make_build
|
||||
popd
|
||||
%cmake_build
|
||||
|
||||
%install
|
||||
%make_install
|
||||
%make_install COMPONENT=tools
|
||||
%cmake_install
|
||||
|
||||
find %{buildroot} -name "*.a" -delete
|
||||
|
||||
@ -332,6 +296,9 @@ find %{buildroot} -name "*.a" -delete
|
||||
%{_libdir}/pkgconfig/winpr-tools2.pc
|
||||
|
||||
%changelog
|
||||
* Tue Oct 01 2024 Ondrej Holy <oholy@redhat.com> - 2:2.11.7-1
|
||||
- Update to 2.11.7 (RHEL-53081)
|
||||
|
||||
* Tue Dec 13 2022 Ondrej Holy <oholy@redhat.com> - 2:2.2.0-10
|
||||
- Fix "implicit declaration of function" errors (#2136153, #2145139)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user