diff --git a/channels/rail/client/rail_main.c b/channels/rail/client/rail_main.c index 5766e34c3..ea772dd25 100644 --- a/channels/rail/client/rail_main.c +++ b/channels/rail/client/rail_main.c @@ -95,23 +95,6 @@ UINT rail_send_channel_data(railPlugin* rail, void* data, size_t length) return rail_send(rail, s); } -/** - * used by rail_client_execute() to free RAIL_EXEC_ORDER's - * internal malloced memory; - */ -static void rail_client_clean_exec_order(RAIL_EXEC_ORDER* exec) -{ - if (!exec) - return; - - free(exec->exeOrFile.string); - exec->exeOrFile.string = NULL; - free(exec->workingDir.string); - exec->workingDir.string = NULL; - free(exec->arguments.string); - exec->arguments.string = NULL; -} - /** * Callback Interface */ @@ -122,17 +105,22 @@ static void rail_client_clean_exec_order(RAIL_EXEC_ORDER* exec) * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_execute(RailClientContext* context, - RAIL_EXEC_ORDER* exec) + const RAIL_EXEC_ORDER* exec) { char* exeOrFile; UINT error; railPlugin* rail; + UINT16 flags; + RAIL_UNICODE_STRING ruExeOrFile = { 0 }; + RAIL_UNICODE_STRING ruWorkingDir = { 0 }; + RAIL_UNICODE_STRING ruArguments = { 0 }; if (!context || !exec) return ERROR_INVALID_PARAMETER; rail = (railPlugin*) context->handle; exeOrFile = exec->RemoteApplicationProgram; + flags = exec->flags; if (!exeOrFile) return ERROR_INVALID_PARAMETER; @@ -140,17 +128,22 @@ static UINT rail_client_execute(RailClientContext* context, if (strnlen(exeOrFile, MAX_PATH) >= 2) { if (strncmp(exeOrFile, "||", 2) != 0) - exec->flags |= RAIL_EXEC_FLAG_FILE; + flags |= RAIL_EXEC_FLAG_FILE; } - rail_string_to_unicode_string(exec->RemoteApplicationProgram, - &exec->exeOrFile); /* RemoteApplicationProgram */ - rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir, - &exec->workingDir); /* ShellWorkingDirectory */ - rail_string_to_unicode_string(exec->RemoteApplicationArguments, - &exec->arguments); /* RemoteApplicationCmdLine */ - error = rail_send_client_exec_order(rail, exec); - rail_client_clean_exec_order(exec); + if (!rail_string_to_unicode_string(exec->RemoteApplicationProgram, + &ruExeOrFile) || /* RemoteApplicationProgram */ + !rail_string_to_unicode_string(exec->RemoteApplicationWorkingDir, + &ruWorkingDir) || /* ShellWorkingDirectory */ + !rail_string_to_unicode_string(exec->RemoteApplicationArguments, + &ruArguments)) /* RemoteApplicationCmdLine */ + error = ERROR_INTERNAL_ERROR; + else + error = rail_send_client_exec_order(rail, flags, &ruExeOrFile, &ruWorkingDir, &ruArguments); + + free(ruExeOrFile.string); + free(ruWorkingDir.string); + free(ruArguments.string); return error; } @@ -160,7 +153,7 @@ static UINT rail_client_execute(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_activate(RailClientContext* context, - RAIL_ACTIVATE_ORDER* activate) + const RAIL_ACTIVATE_ORDER* activate) { railPlugin* rail; @@ -243,84 +236,87 @@ static UINT rail_send_client_sysparam(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_system_param(RailClientContext* context, - RAIL_SYSPARAM_ORDER* sysparam) + const RAIL_SYSPARAM_ORDER* sysInParam) { UINT error = CHANNEL_RC_OK; + RAIL_SYSPARAM_ORDER sysparam; - if (!context || !sysparam) + if (!context || !sysInParam) return ERROR_INVALID_PARAMETER; - if (sysparam->params & SPI_MASK_SET_HIGH_CONTRAST) - { - sysparam->param = SPI_SET_HIGH_CONTRAST; + sysparam = *sysInParam; - if ((error = rail_send_client_sysparam(context, sysparam))) + if (sysparam.params & SPI_MASK_SET_HIGH_CONTRAST) + { + sysparam.param = SPI_SET_HIGH_CONTRAST; + + if ((error = rail_send_client_sysparam(context, &sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %"PRIu32"!", error); return error; } } - if (sysparam->params & SPI_MASK_TASKBAR_POS) + if (sysparam.params & SPI_MASK_TASKBAR_POS) { - sysparam->param = SPI_TASKBAR_POS; + sysparam.param = SPI_TASKBAR_POS; - if ((error = rail_send_client_sysparam(context, sysparam))) + if ((error = rail_send_client_sysparam(context, &sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %"PRIu32"!", error); return error; } } - if (sysparam->params & SPI_MASK_SET_MOUSE_BUTTON_SWAP) + if (sysparam.params & SPI_MASK_SET_MOUSE_BUTTON_SWAP) { - sysparam->param = SPI_SET_MOUSE_BUTTON_SWAP; + sysparam.param = SPI_SET_MOUSE_BUTTON_SWAP; - if ((error = rail_send_client_sysparam(context, sysparam))) + if ((error = rail_send_client_sysparam(context, &sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %"PRIu32"!", error); return error; } } - if (sysparam->params & SPI_MASK_SET_KEYBOARD_PREF) + if (sysparam.params & SPI_MASK_SET_KEYBOARD_PREF) { - sysparam->param = SPI_SET_KEYBOARD_PREF; + sysparam.param = SPI_SET_KEYBOARD_PREF; - if ((error = rail_send_client_sysparam(context, sysparam))) + if ((error = rail_send_client_sysparam(context, &sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %"PRIu32"!", error); return error; } } - if (sysparam->params & SPI_MASK_SET_DRAG_FULL_WINDOWS) + if (sysparam.params & SPI_MASK_SET_DRAG_FULL_WINDOWS) { - sysparam->param = SPI_SET_DRAG_FULL_WINDOWS; + sysparam.param = SPI_SET_DRAG_FULL_WINDOWS; - if ((error = rail_send_client_sysparam(context, sysparam))) + if ((error = rail_send_client_sysparam(context, &sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %"PRIu32"!", error); return error; } } - if (sysparam->params & SPI_MASK_SET_KEYBOARD_CUES) + if (sysparam.params & SPI_MASK_SET_KEYBOARD_CUES) { - sysparam->param = SPI_SET_KEYBOARD_CUES; + sysparam.param = SPI_SET_KEYBOARD_CUES; - if ((error = rail_send_client_sysparam(context, sysparam))) + if ((error = rail_send_client_sysparam(context, &sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %"PRIu32"!", error); return error; } } - if (sysparam->params & SPI_MASK_SET_WORK_AREA) + if (sysparam.params & SPI_MASK_SET_WORK_AREA) { - sysparam->param = SPI_SET_WORK_AREA; + sysparam.param = SPI_SET_WORK_AREA; - if ((error = rail_send_client_sysparam(context, sysparam))) + if ((error = rail_send_client_sysparam(context, &sysparam))) { WLog_ERR(TAG, "rail_send_client_sysparam failed with error %"PRIu32"!", error); return error; @@ -336,7 +332,7 @@ static UINT rail_client_system_param(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_server_system_param(RailClientContext* context, - RAIL_SYSPARAM_ORDER* sysparam) + const RAIL_SYSPARAM_ORDER* sysparam) { if (!context || !sysparam) return ERROR_INVALID_PARAMETER; @@ -350,7 +346,7 @@ static UINT rail_server_system_param(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_system_command(RailClientContext* context, - RAIL_SYSCOMMAND_ORDER* syscommand) + const RAIL_SYSCOMMAND_ORDER* syscommand) { railPlugin* rail; @@ -367,7 +363,7 @@ static UINT rail_client_system_command(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_handshake(RailClientContext* context, - RAIL_HANDSHAKE_ORDER* handshake) + const RAIL_HANDSHAKE_ORDER* handshake) { railPlugin* rail; @@ -384,7 +380,7 @@ static UINT rail_client_handshake(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_server_handshake(RailClientContext* context, - RAIL_HANDSHAKE_ORDER* handshake) + const RAIL_HANDSHAKE_ORDER* handshake) { if (!context || !handshake) return ERROR_INVALID_PARAMETER; @@ -398,7 +394,7 @@ static UINT rail_server_handshake(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_handshake_ex(RailClientContext* context, - RAIL_HANDSHAKE_EX_ORDER* handshakeEx) + const RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { railPlugin* rail; @@ -415,7 +411,7 @@ static UINT rail_client_handshake_ex(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_server_handshake_ex(RailClientContext* context, - RAIL_HANDSHAKE_EX_ORDER* handshakeEx) + const RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { if (!context || !handshakeEx) return ERROR_INVALID_PARAMETER; @@ -429,7 +425,7 @@ static UINT rail_server_handshake_ex(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_notify_event(RailClientContext* context, - RAIL_NOTIFY_EVENT_ORDER* notifyEvent) + const RAIL_NOTIFY_EVENT_ORDER* notifyEvent) { railPlugin* rail; @@ -446,7 +442,7 @@ static UINT rail_client_notify_event(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_window_move(RailClientContext* context, - RAIL_WINDOW_MOVE_ORDER* windowMove) + const RAIL_WINDOW_MOVE_ORDER* windowMove) { railPlugin* rail; @@ -463,7 +459,7 @@ static UINT rail_client_window_move(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_server_local_move_size(RailClientContext* context, - RAIL_LOCALMOVESIZE_ORDER* localMoveSize) + const RAIL_LOCALMOVESIZE_ORDER* localMoveSize) { if (!context || !localMoveSize) return ERROR_INVALID_PARAMETER; @@ -477,7 +473,7 @@ static UINT rail_server_local_move_size(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_server_min_max_info(RailClientContext* context, - RAIL_MINMAXINFO_ORDER* minMaxInfo) + const RAIL_MINMAXINFO_ORDER* minMaxInfo) { if (!context || !minMaxInfo) return ERROR_INVALID_PARAMETER; @@ -491,7 +487,7 @@ static UINT rail_server_min_max_info(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_information(RailClientContext* context, - RAIL_CLIENT_STATUS_ORDER* clientStatus) + const RAIL_CLIENT_STATUS_ORDER* clientStatus) { railPlugin* rail; @@ -508,7 +504,7 @@ static UINT rail_client_information(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_system_menu(RailClientContext* context, - RAIL_SYSMENU_ORDER* sysmenu) + const RAIL_SYSMENU_ORDER* sysmenu) { railPlugin* rail; @@ -525,7 +521,7 @@ static UINT rail_client_system_menu(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_language_bar_info(RailClientContext* context, - RAIL_LANGBAR_INFO_ORDER* langBarInfo) + const RAIL_LANGBAR_INFO_ORDER* langBarInfo) { railPlugin* rail; @@ -542,7 +538,7 @@ static UINT rail_client_language_bar_info(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_server_language_bar_info(RailClientContext* context, - RAIL_LANGBAR_INFO_ORDER* langBarInfo) + const RAIL_LANGBAR_INFO_ORDER* langBarInfo) { if (!context || !langBarInfo) return ERROR_INVALID_PARAMETER; @@ -556,7 +552,7 @@ static UINT rail_server_language_bar_info(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_server_execute_result(RailClientContext* context, - RAIL_EXEC_RESULT_ORDER* execResult) + const RAIL_EXEC_RESULT_ORDER* execResult) { if (!context || !execResult) return ERROR_INVALID_PARAMETER; @@ -570,7 +566,7 @@ static UINT rail_server_execute_result(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_client_get_appid_request(RailClientContext* context, - RAIL_GET_APPID_REQ_ORDER* getAppIdReq) + const RAIL_GET_APPID_REQ_ORDER* getAppIdReq) { railPlugin* rail; @@ -587,7 +583,7 @@ static UINT rail_client_get_appid_request(RailClientContext* context, * @return 0 on success, otherwise a Win32 error code */ static UINT rail_server_get_appid_response(RailClientContext* context, - RAIL_GET_APPID_RESP_ORDER* getAppIdResp) + const RAIL_GET_APPID_RESP_ORDER* getAppIdResp) { if (!context || !getAppIdResp) return ERROR_INVALID_PARAMETER; diff --git a/channels/rail/client/rail_orders.c b/channels/rail/client/rail_orders.c index d10b8ee36..7e6cf4258 100644 --- a/channels/rail/client/rail_orders.c +++ b/channels/rail/client/rail_orders.c @@ -37,7 +37,7 @@ * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_write_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_string) +static UINT rail_write_unicode_string(wStream* s, const RAIL_UNICODE_STRING* unicode_string) { if (!s || !unicode_string) return ERROR_INVALID_PARAMETER; @@ -58,20 +58,24 @@ static UINT rail_write_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_s * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_write_unicode_string_value(wStream* s, RAIL_UNICODE_STRING* unicode_string) +static UINT rail_write_unicode_string_value(wStream* s, const RAIL_UNICODE_STRING* unicode_string) { + size_t length; + if (!s || !unicode_string) return ERROR_INVALID_PARAMETER; - if (unicode_string->length > 0) + length = unicode_string->length; + + if (length > 0) { - if (!Stream_EnsureRemainingCapacity(s, unicode_string->length)) + if (!Stream_EnsureRemainingCapacity(s, length)) { WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!"); return CHANNEL_RC_NO_MEMORY; } - Stream_Write(s, unicode_string->string, unicode_string->length); /* string */ + Stream_Write(s, unicode_string->string, length); /* string */ } return CHANNEL_RC_OK; @@ -103,14 +107,16 @@ UINT rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType) * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_write_high_contrast(wStream* s, RAIL_HIGH_CONTRAST* highContrast) +static UINT rail_write_high_contrast(wStream* s, const RAIL_HIGH_CONTRAST* highContrast) { + UINT32 colorSchemeLength; + if (!s || !highContrast) return ERROR_INVALID_PARAMETER; - highContrast->colorSchemeLength = highContrast->colorScheme.length + 2; + colorSchemeLength = highContrast->colorScheme.length + 2; Stream_Write_UINT32(s, highContrast->flags); /* flags (4 bytes) */ - Stream_Write_UINT32(s, highContrast->colorSchemeLength); /* colorSchemeLength (4 bytes) */ + Stream_Write_UINT32(s, colorSchemeLength); /* colorSchemeLength (4 bytes) */ return rail_write_unicode_string(s, &highContrast->colorScheme); /* colorScheme */ } @@ -275,7 +281,7 @@ static UINT rail_read_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* la return CHANNEL_RC_OK; } -static UINT rail_write_client_status_order(wStream* s, RAIL_CLIENT_STATUS_ORDER* clientStatus) +static UINT rail_write_client_status_order(wStream* s, const RAIL_CLIENT_STATUS_ORDER* clientStatus) { if (!s || !clientStatus) return ERROR_INVALID_PARAMETER; @@ -289,31 +295,44 @@ static UINT rail_write_client_status_order(wStream* s, RAIL_CLIENT_STATUS_ORDER* * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_write_client_exec_order(wStream* s, RAIL_EXEC_ORDER* exec) +static UINT rail_write_client_exec_order(wStream* s, UINT16 flags, + const RAIL_UNICODE_STRING* exeOrFile, const RAIL_UNICODE_STRING* workingDir, + const RAIL_UNICODE_STRING* arguments) { UINT error; - if (!s || !exec) + if (!s || !exeOrFile || !workingDir || !arguments) return ERROR_INVALID_PARAMETER; - Stream_Write_UINT16(s, exec->flags); /* flags (2 bytes) */ - Stream_Write_UINT16(s, exec->exeOrFile.length); /* exeOrFileLength (2 bytes) */ - Stream_Write_UINT16(s, exec->workingDir.length); /* workingDirLength (2 bytes) */ - Stream_Write_UINT16(s, exec->arguments.length); /* argumentsLength (2 bytes) */ + /* [MS-RDPERP] 2.2.2.3.1 Client Execute PDU (TS_RAIL_ORDER_EXEC) + * Check argument limits */ + if ((exeOrFile->length > 520) || (workingDir->length > 520) || + (arguments->length > 16000)) + { + WLog_ERR(TAG, + "TS_RAIL_ORDER_EXEC argument limits exceeded: ExeOrFile=%"PRIu16" [max=520], WorkingDir=%"PRIu16" [max=520], Arguments=%"PRIu16" [max=16000]", + exeOrFile->length, workingDir->length, arguments->length); + return ERROR_BAD_ARGUMENTS; + } - if ((error = rail_write_unicode_string_value(s, &exec->exeOrFile))) + Stream_Write_UINT16(s, flags); /* flags (2 bytes) */ + Stream_Write_UINT16(s, exeOrFile->length); /* exeOrFileLength (2 bytes) */ + Stream_Write_UINT16(s, workingDir->length); /* workingDirLength (2 bytes) */ + Stream_Write_UINT16(s, arguments->length); /* argumentsLength (2 bytes) */ + + if ((error = rail_write_unicode_string_value(s, exeOrFile))) { WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %"PRIu32"", error); return error; } - if ((error = rail_write_unicode_string_value(s, &exec->workingDir))) + if ((error = rail_write_unicode_string_value(s, workingDir))) { WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %"PRIu32"", error); return error; } - if ((error = rail_write_unicode_string_value(s, &exec->arguments))) + if ((error = rail_write_unicode_string_value(s, arguments))) { WLog_ERR(TAG, "rail_write_unicode_string_value failed with error %"PRIu32"", error); return error; @@ -327,7 +346,7 @@ static UINT rail_write_client_exec_order(wStream* s, RAIL_EXEC_ORDER* exec) * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_write_client_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam) +UINT rail_write_client_sysparam_order(wStream* s, const RAIL_SYSPARAM_ORDER* sysparam) { BYTE body; UINT error = CHANNEL_RC_OK; @@ -340,22 +359,22 @@ UINT rail_write_client_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam) switch (sysparam->param) { case SPI_SET_DRAG_FULL_WINDOWS: - body = sysparam->dragFullWindows; + body = sysparam->dragFullWindows ? 1 : 0; Stream_Write_UINT8(s, body); break; case SPI_SET_KEYBOARD_CUES: - body = sysparam->keyboardCues; + body = sysparam->keyboardCues ? 1 : 0; Stream_Write_UINT8(s, body); break; case SPI_SET_KEYBOARD_PREF: - body = sysparam->keyboardPref; + body = sysparam->keyboardPref ? 1 : 0; Stream_Write_UINT8(s, body); break; case SPI_SET_MOUSE_BUTTON_SWAP: - body = sysparam->mouseButtonSwap; + body = sysparam->mouseButtonSwap ? 1 : 0; Stream_Write_UINT8(s, body); break; @@ -388,7 +407,7 @@ UINT rail_write_client_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam) return error; } -static UINT rail_write_client_activate_order(wStream* s, RAIL_ACTIVATE_ORDER* activate) +static UINT rail_write_client_activate_order(wStream* s, const RAIL_ACTIVATE_ORDER* activate) { BYTE enabled; @@ -396,12 +415,12 @@ static UINT rail_write_client_activate_order(wStream* s, RAIL_ACTIVATE_ORDER* ac return ERROR_INVALID_PARAMETER; Stream_Write_UINT32(s, activate->windowId); /* windowId (4 bytes) */ - enabled = activate->enabled; + enabled = activate->enabled ? 1 : 0; Stream_Write_UINT8(s, enabled); /* enabled (1 byte) */ return ERROR_SUCCESS; } -static UINT rail_write_client_sysmenu_order(wStream* s, RAIL_SYSMENU_ORDER* sysmenu) +static UINT rail_write_client_sysmenu_order(wStream* s, const RAIL_SYSMENU_ORDER* sysmenu) { if (!s || !sysmenu) return ERROR_INVALID_PARAMETER; @@ -412,7 +431,7 @@ static UINT rail_write_client_sysmenu_order(wStream* s, RAIL_SYSMENU_ORDER* sysm return ERROR_SUCCESS; } -static UINT rail_write_client_syscommand_order(wStream* s, RAIL_SYSCOMMAND_ORDER* syscommand) +static UINT rail_write_client_syscommand_order(wStream* s, const RAIL_SYSCOMMAND_ORDER* syscommand) { if (!s || !syscommand) return ERROR_INVALID_PARAMETER; @@ -422,7 +441,8 @@ static UINT rail_write_client_syscommand_order(wStream* s, RAIL_SYSCOMMAND_ORDER return ERROR_SUCCESS; } -static UINT rail_write_client_notify_event_order(wStream* s, RAIL_NOTIFY_EVENT_ORDER* notifyEvent) +static UINT rail_write_client_notify_event_order(wStream* s, + const RAIL_NOTIFY_EVENT_ORDER* notifyEvent) { if (!s || !notifyEvent) return ERROR_INVALID_PARAMETER; @@ -433,7 +453,8 @@ static UINT rail_write_client_notify_event_order(wStream* s, RAIL_NOTIFY_EVENT_O return ERROR_SUCCESS; } -static UINT rail_write_client_window_move_order(wStream* s, RAIL_WINDOW_MOVE_ORDER* windowMove) +static UINT rail_write_client_window_move_order(wStream* s, + const RAIL_WINDOW_MOVE_ORDER* windowMove) { if (!s || !windowMove) return ERROR_INVALID_PARAMETER; @@ -446,7 +467,8 @@ static UINT rail_write_client_window_move_order(wStream* s, RAIL_WINDOW_MOVE_ORD return ERROR_SUCCESS; } -static UINT rail_write_client_get_appid_req_order(wStream* s, RAIL_GET_APPID_REQ_ORDER* getAppidReq) +static UINT rail_write_client_get_appid_req_order(wStream* s, + const RAIL_GET_APPID_REQ_ORDER* getAppidReq) { if (!s || !getAppidReq) return ERROR_INVALID_PARAMETER; @@ -455,7 +477,7 @@ static UINT rail_write_client_get_appid_req_order(wStream* s, RAIL_GET_APPID_REQ return ERROR_SUCCESS; } -static UINT rail_write_langbar_info_order(wStream* s, RAIL_LANGBAR_INFO_ORDER* langbarInfo) +static UINT rail_write_langbar_info_order(wStream* s, const RAIL_LANGBAR_INFO_ORDER* langbarInfo) { if (!s || !langbarInfo) return ERROR_INVALID_PARAMETER; @@ -802,7 +824,7 @@ UINT rail_order_recv(railPlugin* rail, wStream* s) * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake) +UINT rail_send_handshake_order(railPlugin* rail, const RAIL_HANDSHAKE_ORDER* handshake) { wStream* s; UINT error; @@ -829,7 +851,7 @@ UINT rail_send_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* handshakeEx) +UINT rail_send_handshake_ex_order(railPlugin* rail, const RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { wStream* s; UINT error; @@ -856,7 +878,7 @@ UINT rail_send_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* han * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_client_status_order(railPlugin* rail, RAIL_CLIENT_STATUS_ORDER* clientStatus) +UINT rail_send_client_status_order(railPlugin* rail, const RAIL_CLIENT_STATUS_ORDER* clientStatus) { wStream* s; UINT error; @@ -886,19 +908,21 @@ UINT rail_send_client_status_order(railPlugin* rail, RAIL_CLIENT_STATUS_ORDER* c * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_client_exec_order(railPlugin* rail, RAIL_EXEC_ORDER* exec) +UINT rail_send_client_exec_order(railPlugin* rail, UINT16 flags, + const RAIL_UNICODE_STRING* exeOrFile, const RAIL_UNICODE_STRING* workingDir, + const RAIL_UNICODE_STRING* arguments) { wStream* s; UINT error; size_t length; - if (!rail || !exec) + if (!rail || !exeOrFile || !workingDir || !arguments) return ERROR_INVALID_PARAMETER; length = RAIL_EXEC_ORDER_LENGTH + - exec->exeOrFile.length + - exec->workingDir.length + - exec->arguments.length; + exeOrFile->length + + workingDir->length + + arguments->length; s = rail_pdu_init(length); if (!s) @@ -907,7 +931,7 @@ UINT rail_send_client_exec_order(railPlugin* rail, RAIL_EXEC_ORDER* exec) return CHANNEL_RC_NO_MEMORY; } - if ((error = rail_write_client_exec_order(s, exec))) + if ((error = rail_write_client_exec_order(s, flags, exeOrFile, workingDir, arguments))) { WLog_ERR(TAG, "rail_write_client_exec_order failed with error %"PRIu32"!", error); goto out; @@ -929,7 +953,7 @@ out: * * @return 0 on success, otherwise a Win32 error code */ -static UINT rail_send_client_sysparam_order(railPlugin* rail, RAIL_SYSPARAM_ORDER* sysparam) +static UINT rail_send_client_sysparam_order(railPlugin* rail, const RAIL_SYSPARAM_ORDER* sysparam) { wStream* s; size_t length = RAIL_SYSPARAM_ORDER_LENGTH; @@ -1084,7 +1108,7 @@ static UINT rail_send_client_sysparams_order(railPlugin* rail, RAIL_SYSPARAM_ORD * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_client_activate_order(railPlugin* rail, RAIL_ACTIVATE_ORDER* activate) +UINT rail_send_client_activate_order(railPlugin* rail, const RAIL_ACTIVATE_ORDER* activate) { wStream* s; UINT error; @@ -1114,7 +1138,7 @@ UINT rail_send_client_activate_order(railPlugin* rail, RAIL_ACTIVATE_ORDER* acti * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_client_sysmenu_order(railPlugin* rail, RAIL_SYSMENU_ORDER* sysmenu) +UINT rail_send_client_sysmenu_order(railPlugin* rail, const RAIL_SYSMENU_ORDER* sysmenu) { wStream* s; UINT error; @@ -1144,7 +1168,7 @@ UINT rail_send_client_sysmenu_order(railPlugin* rail, RAIL_SYSMENU_ORDER* sysmen * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_client_syscommand_order(railPlugin* rail, RAIL_SYSCOMMAND_ORDER* syscommand) +UINT rail_send_client_syscommand_order(railPlugin* rail, const RAIL_SYSCOMMAND_ORDER* syscommand) { wStream* s; UINT error; @@ -1174,7 +1198,8 @@ UINT rail_send_client_syscommand_order(railPlugin* rail, RAIL_SYSCOMMAND_ORDER* * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_client_notify_event_order(railPlugin* rail, RAIL_NOTIFY_EVENT_ORDER* notifyEvent) +UINT rail_send_client_notify_event_order(railPlugin* rail, + const RAIL_NOTIFY_EVENT_ORDER* notifyEvent) { wStream* s; UINT error; @@ -1204,7 +1229,7 @@ UINT rail_send_client_notify_event_order(railPlugin* rail, RAIL_NOTIFY_EVENT_ORD * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_client_window_move_order(railPlugin* rail, RAIL_WINDOW_MOVE_ORDER* windowMove) +UINT rail_send_client_window_move_order(railPlugin* rail, const RAIL_WINDOW_MOVE_ORDER* windowMove) { wStream* s; UINT error; @@ -1234,7 +1259,8 @@ UINT rail_send_client_window_move_order(railPlugin* rail, RAIL_WINDOW_MOVE_ORDER * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_client_get_appid_req_order(railPlugin* rail, RAIL_GET_APPID_REQ_ORDER* getAppIdReq) +UINT rail_send_client_get_appid_req_order(railPlugin* rail, + const RAIL_GET_APPID_REQ_ORDER* getAppIdReq) { wStream* s; UINT error; @@ -1264,7 +1290,8 @@ UINT rail_send_client_get_appid_req_order(railPlugin* rail, RAIL_GET_APPID_REQ_O * * @return 0 on success, otherwise a Win32 error code */ -UINT rail_send_client_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* langBarInfo) +UINT rail_send_client_langbar_info_order(railPlugin* rail, + const RAIL_LANGBAR_INFO_ORDER* langBarInfo) { wStream* s; UINT error; diff --git a/channels/rail/client/rail_orders.h b/channels/rail/client/rail_orders.h index 028286aa1..0b4fd93fb 100644 --- a/channels/rail/client/rail_orders.h +++ b/channels/rail/client/rail_orders.h @@ -29,22 +29,27 @@ #define TAG CHANNELS_TAG("rail.client") -UINT rail_write_client_sysparam_order(wStream* s, RAIL_SYSPARAM_ORDER* sysparam); +UINT rail_write_client_sysparam_order(wStream* s, const RAIL_SYSPARAM_ORDER* sysparam); UINT rail_order_recv(railPlugin* rail, wStream* s); UINT rail_send_pdu(railPlugin* rail, wStream* s, UINT16 orderType); -UINT rail_send_handshake_order(railPlugin* rail, RAIL_HANDSHAKE_ORDER* handshake); -UINT rail_send_handshake_ex_order(railPlugin* rail, RAIL_HANDSHAKE_EX_ORDER* handshakeEx); -UINT rail_send_client_status_order(railPlugin* rail, RAIL_CLIENT_STATUS_ORDER* clientStatus); -UINT rail_send_client_exec_order(railPlugin* rail, RAIL_EXEC_ORDER* exec); -UINT rail_send_client_activate_order(railPlugin* rail, RAIL_ACTIVATE_ORDER* activate); -UINT rail_send_client_sysmenu_order(railPlugin* rail, RAIL_SYSMENU_ORDER* sysmenu); -UINT rail_send_client_syscommand_order(railPlugin* rail, RAIL_SYSCOMMAND_ORDER* syscommand); +UINT rail_send_handshake_order(railPlugin* rail, const RAIL_HANDSHAKE_ORDER* handshake); +UINT rail_send_handshake_ex_order(railPlugin* rail, const RAIL_HANDSHAKE_EX_ORDER* handshakeEx); +UINT rail_send_client_status_order(railPlugin* rail, const RAIL_CLIENT_STATUS_ORDER* clientStatus); +UINT rail_send_client_exec_order(railPlugin* rail, UINT16 flags, + const RAIL_UNICODE_STRING* exeOrFile, const RAIL_UNICODE_STRING* workingDir, + const RAIL_UNICODE_STRING* arguments); +UINT rail_send_client_activate_order(railPlugin* rail, const RAIL_ACTIVATE_ORDER* activate); +UINT rail_send_client_sysmenu_order(railPlugin* rail, const RAIL_SYSMENU_ORDER* sysmenu); +UINT rail_send_client_syscommand_order(railPlugin* rail, const RAIL_SYSCOMMAND_ORDER* syscommand); -UINT rail_send_client_notify_event_order(railPlugin* rail, RAIL_NOTIFY_EVENT_ORDER* notifyEvent); -UINT rail_send_client_window_move_order(railPlugin* rail, RAIL_WINDOW_MOVE_ORDER* windowMove); -UINT rail_send_client_get_appid_req_order(railPlugin* rail, RAIL_GET_APPID_REQ_ORDER* getAppIdReq); -UINT rail_send_client_langbar_info_order(railPlugin* rail, RAIL_LANGBAR_INFO_ORDER* langBarInfo); +UINT rail_send_client_notify_event_order(railPlugin* rail, + const RAIL_NOTIFY_EVENT_ORDER* notifyEvent); +UINT rail_send_client_window_move_order(railPlugin* rail, const RAIL_WINDOW_MOVE_ORDER* windowMove); +UINT rail_send_client_get_appid_req_order(railPlugin* rail, + const RAIL_GET_APPID_REQ_ORDER* getAppIdReq); +UINT rail_send_client_langbar_info_order(railPlugin* rail, + const RAIL_LANGBAR_INFO_ORDER* langBarInfo); #endif /* FREERDP_CHANNEL_RAIL_CLIENT_ORDERS_H */ diff --git a/channels/rail/rail_common.c b/channels/rail/rail_common.c index ea344c316..79d94cf82 100644 --- a/channels/rail/rail_common.c +++ b/channels/rail/rail_common.c @@ -51,7 +51,7 @@ const char* const RAIL_ORDER_TYPE_STRINGS[] = "" }; -void rail_string_to_unicode_string(char* string, RAIL_UNICODE_STRING* unicode_string) +BOOL rail_string_to_unicode_string(const char* string, RAIL_UNICODE_STRING* unicode_string) { WCHAR* buffer = NULL; int length = 0; @@ -60,11 +60,19 @@ void rail_string_to_unicode_string(char* string, RAIL_UNICODE_STRING* unicode_st unicode_string->length = 0; if (!string || strlen(string) < 1) - return; + return FALSE; length = ConvertToUnicode(CP_UTF8, 0, string, -1, &buffer, 0) * 2; + + if ((length < 0) || ((size_t)length * sizeof(WCHAR) > UINT16_MAX)) + { + free(buffer); + return FALSE; + } + unicode_string->string = (BYTE*) buffer; - unicode_string->length = (UINT16) length; + unicode_string->length = (UINT16) length * sizeof(WCHAR); + return TRUE; } /** @@ -117,7 +125,7 @@ UINT rail_read_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake) return CHANNEL_RC_OK; } -void rail_write_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake) +void rail_write_handshake_order(wStream* s, const RAIL_HANDSHAKE_ORDER* handshake) { Stream_Write_UINT32(s, handshake->buildNumber); /* buildNumber (4 bytes) */ } @@ -137,7 +145,7 @@ UINT rail_read_handshake_ex_order(wStream* s, RAIL_HANDSHAKE_EX_ORDER* handshake return CHANNEL_RC_OK; } -void rail_write_handshake_ex_order(wStream* s, RAIL_HANDSHAKE_EX_ORDER* handshakeEx) +void rail_write_handshake_ex_order(wStream* s, const RAIL_HANDSHAKE_EX_ORDER* handshakeEx) { Stream_Write_UINT32(s, handshakeEx->buildNumber); /* buildNumber (4 bytes) */ Stream_Write_UINT32(s, handshakeEx->railHandshakeFlags); /* railHandshakeFlags (4 bytes) */ diff --git a/channels/rail/rail_common.h b/channels/rail/rail_common.h index 15d65d4c7..fe1bc0290 100644 --- a/channels/rail/rail_common.h +++ b/channels/rail/rail_common.h @@ -44,11 +44,11 @@ extern const char* const RAIL_ORDER_TYPE_STRINGS[]; #define RAIL_GET_APPID_REQ_ORDER_LENGTH 4 /* fixed */ #define RAIL_LANGBAR_INFO_ORDER_LENGTH 4 /* fixed */ -void rail_string_to_unicode_string(char* string, RAIL_UNICODE_STRING* unicode_string); +BOOL rail_string_to_unicode_string(const char* string, RAIL_UNICODE_STRING* unicode_string); UINT rail_read_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake); -void rail_write_handshake_order(wStream* s, RAIL_HANDSHAKE_ORDER* handshake); +void rail_write_handshake_order(wStream* s, const RAIL_HANDSHAKE_ORDER* handshake); UINT rail_read_handshake_ex_order(wStream* s, RAIL_HANDSHAKE_EX_ORDER* handshakeEx); -void rail_write_handshake_ex_order(wStream* s, RAIL_HANDSHAKE_EX_ORDER* handshakeEx); +void rail_write_handshake_ex_order(wStream* s, const RAIL_HANDSHAKE_EX_ORDER* handshakeEx); wStream* rail_pdu_init(size_t length); UINT rail_read_pdu_header(wStream* s, UINT16* orderType, UINT16* orderLength); diff --git a/include/freerdp/client/rail.h b/include/freerdp/client/rail.h index 2284face0..69c8ba99b 100644 --- a/include/freerdp/client/rail.h +++ b/include/freerdp/client/rail.h @@ -35,26 +35,45 @@ typedef struct _rail_client_context RailClientContext; -typedef UINT (*pcRailClientExecute)(RailClientContext* context, RAIL_EXEC_ORDER* exec); -typedef UINT (*pcRailClientActivate)(RailClientContext* context, RAIL_ACTIVATE_ORDER* activate); -typedef UINT (*pcRailClientSystemParam)(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam); -typedef UINT (*pcRailServerSystemParam)(RailClientContext* context, RAIL_SYSPARAM_ORDER* sysparam); -typedef UINT (*pcRailClientSystemCommand)(RailClientContext* context, RAIL_SYSCOMMAND_ORDER* syscommand); -typedef UINT (*pcRailClientHandshake)(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake); -typedef UINT (*pcRailServerHandshake)(RailClientContext* context, RAIL_HANDSHAKE_ORDER* handshake); -typedef UINT (*pcRailClientHandshakeEx)(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx); -typedef UINT (*pcRailServerHandshakeEx)(RailClientContext* context, RAIL_HANDSHAKE_EX_ORDER* handshakeEx); -typedef UINT (*pcRailClientNotifyEvent)(RailClientContext* context, RAIL_NOTIFY_EVENT_ORDER* notifyEvent); -typedef UINT (*pcRailClientWindowMove)(RailClientContext* context, RAIL_WINDOW_MOVE_ORDER* windowMove); -typedef UINT (*pcRailServerLocalMoveSize)(RailClientContext* context, RAIL_LOCALMOVESIZE_ORDER* localMoveSize); -typedef UINT (*pcRailServerMinMaxInfo)(RailClientContext* context, RAIL_MINMAXINFO_ORDER* minMaxInfo); -typedef UINT (*pcRailClientInformation)(RailClientContext* context, RAIL_CLIENT_STATUS_ORDER* clientStatus); -typedef UINT (*pcRailClientSystemMenu)(RailClientContext* context, RAIL_SYSMENU_ORDER* sysmenu); -typedef UINT (*pcRailClientLanguageBarInfo)(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo); -typedef UINT (*pcRailServerLanguageBarInfo)(RailClientContext* context, RAIL_LANGBAR_INFO_ORDER* langBarInfo); -typedef UINT (*pcRailServerExecuteResult)(RailClientContext* context, RAIL_EXEC_RESULT_ORDER* execResult); -typedef UINT (*pcRailClientGetAppIdRequest)(RailClientContext* context, RAIL_GET_APPID_REQ_ORDER* getAppIdReq); -typedef UINT (*pcRailServerGetAppIdResponse)(RailClientContext* context, RAIL_GET_APPID_RESP_ORDER* getAppIdResp); +typedef UINT(*pcRailClientExecute)(RailClientContext* context, const RAIL_EXEC_ORDER* exec); +typedef UINT(*pcRailClientActivate)(RailClientContext* context, + const RAIL_ACTIVATE_ORDER* activate); +typedef UINT(*pcRailClientSystemParam)(RailClientContext* context, + const RAIL_SYSPARAM_ORDER* sysparam); +typedef UINT(*pcRailServerSystemParam)(RailClientContext* context, + const RAIL_SYSPARAM_ORDER* sysparam); +typedef UINT(*pcRailClientSystemCommand)(RailClientContext* context, + const RAIL_SYSCOMMAND_ORDER* syscommand); +typedef UINT(*pcRailClientHandshake)(RailClientContext* context, + const RAIL_HANDSHAKE_ORDER* handshake); +typedef UINT(*pcRailServerHandshake)(RailClientContext* context, + const RAIL_HANDSHAKE_ORDER* handshake); +typedef UINT(*pcRailClientHandshakeEx)(RailClientContext* context, + const RAIL_HANDSHAKE_EX_ORDER* handshakeEx); +typedef UINT(*pcRailServerHandshakeEx)(RailClientContext* context, + const RAIL_HANDSHAKE_EX_ORDER* handshakeEx); +typedef UINT(*pcRailClientNotifyEvent)(RailClientContext* context, + const RAIL_NOTIFY_EVENT_ORDER* notifyEvent); +typedef UINT(*pcRailClientWindowMove)(RailClientContext* context, + const RAIL_WINDOW_MOVE_ORDER* windowMove); +typedef UINT(*pcRailServerLocalMoveSize)(RailClientContext* context, + const RAIL_LOCALMOVESIZE_ORDER* localMoveSize); +typedef UINT(*pcRailServerMinMaxInfo)(RailClientContext* context, + const RAIL_MINMAXINFO_ORDER* minMaxInfo); +typedef UINT(*pcRailClientInformation)(RailClientContext* context, + const RAIL_CLIENT_STATUS_ORDER* clientStatus); +typedef UINT(*pcRailClientSystemMenu)(RailClientContext* context, + const RAIL_SYSMENU_ORDER* sysmenu); +typedef UINT(*pcRailClientLanguageBarInfo)(RailClientContext* context, + const RAIL_LANGBAR_INFO_ORDER* langBarInfo); +typedef UINT(*pcRailServerLanguageBarInfo)(RailClientContext* context, + const RAIL_LANGBAR_INFO_ORDER* langBarInfo); +typedef UINT(*pcRailServerExecuteResult)(RailClientContext* context, + const RAIL_EXEC_RESULT_ORDER* execResult); +typedef UINT(*pcRailClientGetAppIdRequest)(RailClientContext* context, + const RAIL_GET_APPID_REQ_ORDER* getAppIdReq); +typedef UINT(*pcRailServerGetAppIdResponse)(RailClientContext* context, + const RAIL_GET_APPID_RESP_ORDER* getAppIdResp); struct _rail_client_context { diff --git a/include/freerdp/rail.h b/include/freerdp/rail.h index c848382a0..57ed242ec 100644 --- a/include/freerdp/rail.h +++ b/include/freerdp/rail.h @@ -218,9 +218,6 @@ typedef struct _RAIL_CLIENT_STATUS_ORDER RAIL_CLIENT_STATUS_ORDER; struct _RAIL_EXEC_ORDER { UINT16 flags; - RAIL_UNICODE_STRING exeOrFile; - RAIL_UNICODE_STRING workingDir; - RAIL_UNICODE_STRING arguments; char* RemoteApplicationProgram; char* RemoteApplicationWorkingDir; char* RemoteApplicationArguments;