mirror of https://github.com/neutrinolabs/xrdp
Initial cut at a unit test for xrdp_sec_process_mcs_data_monitors
This commit is contained in:
parent
a266d67fdf
commit
0a2562d33d
|
@ -493,6 +493,7 @@ AC_CONFIG_FILES([
|
||||||
sesman/tools/Makefile
|
sesman/tools/Makefile
|
||||||
tests/Makefile
|
tests/Makefile
|
||||||
tests/common/Makefile
|
tests/common/Makefile
|
||||||
|
tests/libxrdp/Makefile
|
||||||
tests/memtest/Makefile
|
tests/memtest/Makefile
|
||||||
tests/xrdp/Makefile
|
tests/xrdp/Makefile
|
||||||
tools/Makefile
|
tools/Makefile
|
||||||
|
|
|
@ -2330,7 +2330,7 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Process a [MS-RDPBCGR] TS_UD_CS_MONITOR message.
|
/* Process a [MS-RDPBCGR] TS_UD_CS_MONITOR message.
|
||||||
reads the client monitors data */
|
reads the client monitors data */
|
||||||
static int
|
int
|
||||||
xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
|
xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
|
@ -2374,7 +2374,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
|
||||||
LOG(LOG_LEVEL_ERROR,
|
LOG(LOG_LEVEL_ERROR,
|
||||||
"[MS-RDPBCGR] Protocol error: TS_UD_CS_MONITOR monitorCount "
|
"[MS-RDPBCGR] Protocol error: TS_UD_CS_MONITOR monitorCount "
|
||||||
"MUST be less than 16, received: %d", monitorCount);
|
"MUST be less than 16, received: %d", monitorCount);
|
||||||
return 1;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
client_info->monitorCount = monitorCount;
|
client_info->monitorCount = monitorCount;
|
||||||
|
@ -2468,7 +2468,7 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
|
||||||
"Allowed height range: min %d, max %d. Height received: %d",
|
"Allowed height range: min %d, max %d. Height received: %d",
|
||||||
0xC8, 0x7FFE, client_info->width,
|
0xC8, 0x7FFE, client_info->width,
|
||||||
0xC8, 0x7FFE, client_info->height);
|
0xC8, 0x7FFE, client_info->height);
|
||||||
return 1; /* error */
|
return 3; /* error */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keep a copy of non negative monitor info values for xrdp_wm usage */
|
/* keep a copy of non negative monitor info values for xrdp_wm usage */
|
||||||
|
|
|
@ -4,5 +4,6 @@ EXTRA_DIST = \
|
||||||
|
|
||||||
SUBDIRS = \
|
SUBDIRS = \
|
||||||
common \
|
common \
|
||||||
|
libxrdp \
|
||||||
memtest \
|
memtest \
|
||||||
xrdp
|
xrdp
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
AM_CPPFLAGS = \
|
||||||
|
-I$(top_builddir) \
|
||||||
|
-I$(top_srcdir)/libxrdp \
|
||||||
|
-I$(top_srcdir)/common
|
||||||
|
|
||||||
|
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
|
||||||
|
$(top_srcdir)/tap-driver.sh
|
||||||
|
|
||||||
|
TESTS = test_libxrdp
|
||||||
|
check_PROGRAMS = test_libxrdp
|
||||||
|
|
||||||
|
test_libxrdp_SOURCES = \
|
||||||
|
test_libxrdp.h \
|
||||||
|
test_libxrdp_main.c \
|
||||||
|
test_monitor_processing.c
|
||||||
|
|
||||||
|
test_libxrdp_CFLAGS = \
|
||||||
|
@CHECK_CFLAGS@
|
||||||
|
|
||||||
|
test_libxrdp_LDADD = \
|
||||||
|
$(top_builddir)/common/libcommon.la \
|
||||||
|
$(top_builddir)/libxrdp/libxrdp.la \
|
||||||
|
@CHECK_LIBS@
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef TEST_LIBXRDP_H
|
||||||
|
#define TEST_LIBXRDP_H
|
||||||
|
|
||||||
|
#include <check.h>
|
||||||
|
|
||||||
|
Suite *make_suite_test_monitor_processing(void);
|
||||||
|
|
||||||
|
#endif /* TEST_LIBXRDP_H */
|
|
@ -0,0 +1,22 @@
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
#include "config_ac.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <check.h>
|
||||||
|
#include "test_libxrdp.h"
|
||||||
|
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
int number_failed;
|
||||||
|
SRunner *sr;
|
||||||
|
|
||||||
|
sr = srunner_create (make_suite_test_monitor_processing());
|
||||||
|
// srunner_add_suite(sr, make_list_suite());
|
||||||
|
|
||||||
|
srunner_set_tap(sr, "-");
|
||||||
|
srunner_run_all (sr, CK_ENV);
|
||||||
|
number_failed = srunner_ntests_failed(sr);
|
||||||
|
srunner_free(sr);
|
||||||
|
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||||
|
}
|
|
@ -0,0 +1,305 @@
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
#include "config_ac.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "test_libxrdp.h"
|
||||||
|
#include "libxrdp.h"
|
||||||
|
#include "os_calls.h"
|
||||||
|
|
||||||
|
struct xrdp_sec *sec_layer;
|
||||||
|
struct xrdp_rdp *rdp_layer;
|
||||||
|
struct xrdp_session *session;
|
||||||
|
|
||||||
|
int
|
||||||
|
xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s);
|
||||||
|
|
||||||
|
void setup(void)
|
||||||
|
{
|
||||||
|
rdp_layer = (struct xrdp_rdp *)g_malloc(sizeof(struct xrdp_rdp), 1);
|
||||||
|
session = (struct xrdp_session *)g_malloc(sizeof(struct xrdp_session), 1);
|
||||||
|
session->rdp = rdp_layer;
|
||||||
|
session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info);
|
||||||
|
session->client_info->multimon = 1;
|
||||||
|
sec_layer = (struct xrdp_sec *) g_malloc(sizeof(struct xrdp_sec), 1);
|
||||||
|
sec_layer->rdp_layer = rdp_layer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void teardown(void)
|
||||||
|
{
|
||||||
|
g_free(sec_layer);
|
||||||
|
g_free(session);
|
||||||
|
g_free(rdp_layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(test_process_monitors__when_flags_is_not_zero__fail)
|
||||||
|
{
|
||||||
|
struct stream *s = (struct stream *)NULL;
|
||||||
|
make_stream(s);
|
||||||
|
init_stream(s, 8);
|
||||||
|
|
||||||
|
out_uint32_le(s, 1);
|
||||||
|
out_uint32_le(s, 0);
|
||||||
|
s_mark_end(s);
|
||||||
|
//Reset the read counter of the stream so the processing function handles it properly.
|
||||||
|
s->p = s->data;
|
||||||
|
|
||||||
|
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||||
|
ck_assert_int_eq(error, 1);
|
||||||
|
|
||||||
|
free_stream(s);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_process_monitors__when_mounter_count_is_greater_than_sixteen__fail)
|
||||||
|
{
|
||||||
|
struct stream *s = (struct stream *)NULL;
|
||||||
|
make_stream(s);
|
||||||
|
init_stream(s, 8);
|
||||||
|
|
||||||
|
out_uint32_le(s, 0);
|
||||||
|
out_uint32_le(s, 17);
|
||||||
|
s_mark_end(s);
|
||||||
|
//Reset the read counter of the stream so the processing function handles it properly.
|
||||||
|
s->p = s->data;
|
||||||
|
|
||||||
|
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||||
|
ck_assert_int_eq(error, 2);
|
||||||
|
|
||||||
|
free_stream(s);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_process_monitors__with_single_monitor_happy_path)
|
||||||
|
{
|
||||||
|
struct xrdp_client_info *client_info = &(rdp_layer->client_info);
|
||||||
|
struct stream *s = (struct stream *)NULL;
|
||||||
|
make_stream(s);
|
||||||
|
init_stream(s, 28);
|
||||||
|
|
||||||
|
out_uint32_le(s, 0); //flags
|
||||||
|
out_uint32_le(s, 1); //monitorCount
|
||||||
|
|
||||||
|
// Pretend we have a 4k monitor
|
||||||
|
out_uint32_le(s, 0); //monitor left
|
||||||
|
out_uint32_le(s, 0); //monitor top
|
||||||
|
out_uint32_le(s, 3840); //monitor right
|
||||||
|
out_uint32_le(s, 2160); //monitor bottom
|
||||||
|
out_uint32_le(s, 1); //is primary
|
||||||
|
|
||||||
|
s_mark_end(s);
|
||||||
|
//Reset the read counter of the stream so the processing function handles it properly.
|
||||||
|
s->p = s->data;
|
||||||
|
|
||||||
|
//Verify function call passed.
|
||||||
|
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||||
|
ck_assert_int_eq(error, 0);
|
||||||
|
|
||||||
|
ck_assert_int_eq(client_info->monitorCount, 1);
|
||||||
|
|
||||||
|
// Verify normal monitor
|
||||||
|
ck_assert_int_eq(client_info->minfo[0].left, 0);
|
||||||
|
ck_assert_int_eq(client_info->minfo[0].top, 0);
|
||||||
|
ck_assert_int_eq(client_info->minfo[0].right, 3840);
|
||||||
|
ck_assert_int_eq(client_info->minfo[0].bottom, 2160);
|
||||||
|
ck_assert_int_eq(client_info->minfo[0].is_primary, 1);
|
||||||
|
|
||||||
|
// Verify normalized monitor
|
||||||
|
ck_assert_int_eq(client_info->minfo_wm[0].left, 0);
|
||||||
|
ck_assert_int_eq(client_info->minfo_wm[0].top, 0);
|
||||||
|
ck_assert_int_eq(client_info->minfo_wm[0].right, 3840);
|
||||||
|
ck_assert_int_eq(client_info->minfo_wm[0].bottom, 2160);
|
||||||
|
ck_assert_int_eq(client_info->minfo_wm[0].is_primary, 1);
|
||||||
|
|
||||||
|
// Verify geometry (+1 greater than )
|
||||||
|
ck_assert_int_eq(client_info->width, 3841);
|
||||||
|
ck_assert_int_eq(client_info->height, 2161);
|
||||||
|
|
||||||
|
free_stream(s);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_process_monitors__when_no_primary_monitor_is_specified_one_is_selected)
|
||||||
|
{
|
||||||
|
struct xrdp_client_info *client_info = &(rdp_layer->client_info);
|
||||||
|
struct stream *s = (struct stream *)NULL;
|
||||||
|
make_stream(s);
|
||||||
|
init_stream(s, 28);
|
||||||
|
|
||||||
|
out_uint32_le(s, 0); //flags
|
||||||
|
out_uint32_le(s, 1); //monitorCount
|
||||||
|
|
||||||
|
// Pretend we have a 4k monitor
|
||||||
|
out_uint32_le(s, 0); //monitor left
|
||||||
|
out_uint32_le(s, 0); //monitor top
|
||||||
|
out_uint32_le(s, 3840); //monitor right
|
||||||
|
out_uint32_le(s, 2160); //monitor bottom
|
||||||
|
out_uint32_le(s, 0); //is primary
|
||||||
|
|
||||||
|
s_mark_end(s);
|
||||||
|
//Reset the read counter of the stream so the processing function handles it properly.
|
||||||
|
s->p = s->data;
|
||||||
|
|
||||||
|
//Verify function call passed.
|
||||||
|
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||||
|
ck_assert_int_eq(error, 0);
|
||||||
|
|
||||||
|
ck_assert_int_eq(client_info->monitorCount, 1);
|
||||||
|
|
||||||
|
// Verify normal monitor
|
||||||
|
ck_assert_int_eq(client_info->minfo[0].left, 0);
|
||||||
|
ck_assert_int_eq(client_info->minfo[0].top, 0);
|
||||||
|
ck_assert_int_eq(client_info->minfo[0].right, 3840);
|
||||||
|
ck_assert_int_eq(client_info->minfo[0].bottom, 2160);
|
||||||
|
ck_assert_int_eq(client_info->minfo[0].is_primary, 1);
|
||||||
|
|
||||||
|
// Verify normalized monitor
|
||||||
|
ck_assert_int_eq(client_info->minfo_wm[0].left, 0);
|
||||||
|
ck_assert_int_eq(client_info->minfo_wm[0].top, 0);
|
||||||
|
ck_assert_int_eq(client_info->minfo_wm[0].right, 3840);
|
||||||
|
ck_assert_int_eq(client_info->minfo_wm[0].bottom, 2160);
|
||||||
|
ck_assert_int_eq(client_info->minfo_wm[0].is_primary, 1);
|
||||||
|
|
||||||
|
// Verify geometry (+1 greater than )
|
||||||
|
ck_assert_int_eq(client_info->width, 3841);
|
||||||
|
ck_assert_int_eq(client_info->height, 2161);
|
||||||
|
|
||||||
|
free_stream(s);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_process_monitors__when_virtual_desktop_width_is_too_large)
|
||||||
|
{
|
||||||
|
struct stream *s = (struct stream *)NULL;
|
||||||
|
make_stream(s);
|
||||||
|
init_stream(s, 28);
|
||||||
|
|
||||||
|
out_uint32_le(s, 0); //flags
|
||||||
|
out_uint32_le(s, 1); //monitorCount
|
||||||
|
|
||||||
|
// Pretend we have a 4k monitor
|
||||||
|
out_uint32_le(s, 0); //monitor left
|
||||||
|
out_uint32_le(s, 0); //monitor top
|
||||||
|
out_uint32_le(s, 33000); //monitor right
|
||||||
|
out_uint32_le(s, 2160); //monitor bottom
|
||||||
|
out_uint32_le(s, 1); //is primary
|
||||||
|
|
||||||
|
s_mark_end(s);
|
||||||
|
//Reset the read counter of the stream so the processing function handles it properly.
|
||||||
|
s->p = s->data;
|
||||||
|
|
||||||
|
//Verify function call passed.
|
||||||
|
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||||
|
ck_assert_int_eq(error, 3);
|
||||||
|
|
||||||
|
free_stream(s);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_process_monitors__when_virtual_desktop_width_is_too_small)
|
||||||
|
{
|
||||||
|
struct stream *s = (struct stream *)NULL;
|
||||||
|
make_stream(s);
|
||||||
|
init_stream(s, 28);
|
||||||
|
|
||||||
|
out_uint32_le(s, 0); //flags
|
||||||
|
out_uint32_le(s, 1); //monitorCount
|
||||||
|
|
||||||
|
// Pretend we have a 4k monitor
|
||||||
|
out_uint32_le(s, 0); //monitor left
|
||||||
|
out_uint32_le(s, 0); //monitor top
|
||||||
|
out_uint32_le(s, 100); //monitor right
|
||||||
|
out_uint32_le(s, 2160); //monitor bottom
|
||||||
|
out_uint32_le(s, 1); //is primary
|
||||||
|
|
||||||
|
s_mark_end(s);
|
||||||
|
//Reset the read counter of the stream so the processing function handles it properly.
|
||||||
|
s->p = s->data;
|
||||||
|
|
||||||
|
//Verify function call passed.
|
||||||
|
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||||
|
ck_assert_int_eq(error, 3);
|
||||||
|
|
||||||
|
free_stream(s);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_process_monitors__when_virtual_desktop_height_is_too_large)
|
||||||
|
{
|
||||||
|
struct stream *s = (struct stream *)NULL;
|
||||||
|
make_stream(s);
|
||||||
|
init_stream(s, 28);
|
||||||
|
|
||||||
|
out_uint32_le(s, 0); //flags
|
||||||
|
out_uint32_le(s, 1); //monitorCount
|
||||||
|
|
||||||
|
// Pretend we have a 4k monitor
|
||||||
|
out_uint32_le(s, 0); //monitor left
|
||||||
|
out_uint32_le(s, 0); //monitor top
|
||||||
|
out_uint32_le(s, 3840); //monitor right
|
||||||
|
out_uint32_le(s, 33000); //monitor bottom
|
||||||
|
out_uint32_le(s, 1); //is primary
|
||||||
|
|
||||||
|
s_mark_end(s);
|
||||||
|
//Reset the read counter of the stream so the processing function handles it properly.
|
||||||
|
s->p = s->data;
|
||||||
|
|
||||||
|
//Verify function call passed.
|
||||||
|
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||||
|
ck_assert_int_eq(error, 3);
|
||||||
|
|
||||||
|
free_stream(s);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
START_TEST(test_process_monitors__when_virtual_desktop_height_is_too_small)
|
||||||
|
{
|
||||||
|
struct stream *s = (struct stream *)NULL;
|
||||||
|
make_stream(s);
|
||||||
|
init_stream(s, 28);
|
||||||
|
|
||||||
|
out_uint32_le(s, 0); //flags
|
||||||
|
out_uint32_le(s, 1); //monitorCount
|
||||||
|
|
||||||
|
// Pretend we have a 4k monitor
|
||||||
|
out_uint32_le(s, 0); //monitor left
|
||||||
|
out_uint32_le(s, 0); //monitor top
|
||||||
|
out_uint32_le(s, 3840); //monitor right
|
||||||
|
out_uint32_le(s, 100); //monitor bottom
|
||||||
|
out_uint32_le(s, 1); //is primary
|
||||||
|
|
||||||
|
s_mark_end(s);
|
||||||
|
//Reset the read counter of the stream so the processing function handles it properly.
|
||||||
|
s->p = s->data;
|
||||||
|
|
||||||
|
//Verify function call passed.
|
||||||
|
int error = xrdp_sec_process_mcs_data_monitors(sec_layer, s);
|
||||||
|
ck_assert_int_eq(error, 3);
|
||||||
|
|
||||||
|
free_stream(s);
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
Suite *
|
||||||
|
make_suite_test_monitor_processing(void)
|
||||||
|
{
|
||||||
|
Suite *s;
|
||||||
|
TCase *tc_process_monitors;
|
||||||
|
|
||||||
|
s = suite_create("Monitor_Processing");
|
||||||
|
|
||||||
|
tc_process_monitors = tcase_create("xrdp_sec_process_mcs_data_monitors");
|
||||||
|
tcase_add_checked_fixture(tc_process_monitors, setup, teardown);
|
||||||
|
tcase_add_test(tc_process_monitors, test_process_monitors__when_flags_is_not_zero__fail);
|
||||||
|
tcase_add_test(tc_process_monitors, test_process_monitors__when_mounter_count_is_greater_than_sixteen__fail);
|
||||||
|
tcase_add_test(tc_process_monitors, test_process_monitors__with_single_monitor_happy_path);
|
||||||
|
tcase_add_test(tc_process_monitors, test_process_monitors__when_no_primary_monitor_is_specified_one_is_selected);
|
||||||
|
tcase_add_test(tc_process_monitors, test_process_monitors__when_virtual_desktop_width_is_too_large);
|
||||||
|
tcase_add_test(tc_process_monitors, test_process_monitors__when_virtual_desktop_width_is_too_small);
|
||||||
|
tcase_add_test(tc_process_monitors, test_process_monitors__when_virtual_desktop_height_is_too_large);
|
||||||
|
tcase_add_test(tc_process_monitors, test_process_monitors__when_virtual_desktop_height_is_too_small);
|
||||||
|
|
||||||
|
suite_add_tcase(s, tc_process_monitors);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
Loading…
Reference in New Issue