diff --git a/.gitignore b/.gitignore index 415c5441b..a53e90543 100755 --- a/.gitignore +++ b/.gitignore @@ -113,6 +113,7 @@ Release Win32 build*/ *.orig +*.msrcIncident default.log *Amplifier XE* diff --git a/channels/remdesk/client/remdesk_main.c b/channels/remdesk/client/remdesk_main.c index feeb7e4db..546cdb9e4 100644 --- a/channels/remdesk/client/remdesk_main.c +++ b/channels/remdesk/client/remdesk_main.c @@ -39,8 +39,8 @@ static int remdesk_process_receive(remdeskPlugin* remdesk, wStream* s) { int status = 1; - printf("RemDeskReceive: %d\n", Stream_Length(s)); - winpr_HexDump(Stream_Buffer(s), Stream_Length(s)); + printf("RemdeskReceive: %d\n", Stream_GetRemainingLength(s)); + winpr_HexDump(Stream_Pointer(s), Stream_GetRemainingLength(s)); return status; } @@ -303,8 +303,6 @@ BOOL VCAPITYPE VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL; - printf("remdesk_VirtualChannelEntry\n"); - strcpy(remdesk->channelDef.name, "remdesk"); pEntryPointsEx = (CHANNEL_ENTRY_POINTS_FREERDP*) pEntryPoints; diff --git a/client/common/assistance.c b/client/common/assistance.c index 45408bfc6..206780547 100644 --- a/client/common/assistance.c +++ b/client/common/assistance.c @@ -575,6 +575,68 @@ int freerdp_client_assistance_parse_file_buffer(rdpAssistanceFile* file, const c return 1; } +int freerdp_client_assistance_parse_file(rdpAssistanceFile* file, const char* name) +{ + int status; + BYTE* buffer; + FILE* fp = NULL; + size_t readSize; + long int fileSize; + + fp = fopen(name, "r"); + + if (!fp) + return -1; + + fseek(fp, 0, SEEK_END); + fileSize = ftell(fp); + fseek(fp, 0, SEEK_SET); + + if (fileSize < 1) + { + fclose(fp); + return -1; + } + + buffer = (BYTE*) malloc(fileSize + 2); + readSize = fread(buffer, fileSize, 1, fp); + + if (!readSize) + { + if (!ferror(fp)) + readSize = fileSize; + } + fclose(fp); + + if (readSize < 1) + { + free(buffer); + buffer = NULL; + return -1; + } + + buffer[fileSize] = '\0'; + buffer[fileSize + 1] = '\0'; + + status = freerdp_client_assistance_parse_file_buffer(file, (char*) buffer, fileSize); + + free(buffer); + + return status; +} + +int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* file, rdpSettings* settings) +{ + freerdp_set_param_bool(settings, FreeRDP_RemoteAssistanceMode, TRUE); + + if (!file->RASessionId) + return -1; + + freerdp_set_param_string(settings, FreeRDP_RemoteAssistanceSessionId, file->RASessionId); + + return 1; +} + rdpAssistanceFile* freerdp_client_assistance_file_new() { rdpAssistanceFile* file; diff --git a/client/common/client.c b/client/common/client.c index 1fc565f9a..13b46b6bf 100644 --- a/client/common/client.c +++ b/client/common/client.c @@ -27,6 +27,7 @@ #include #include #include +#include int freerdp_client_common_new(freerdp* instance, rdpContext* context) { @@ -118,6 +119,11 @@ int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, status = freerdp_client_settings_parse_connection_file(settings, settings->ConnectionFile); } + if (settings->AssistanceFile) + { + status = freerdp_client_settings_parse_assistance_file(settings, settings->AssistanceFile); + } + return status; } @@ -167,3 +173,28 @@ int freerdp_client_settings_write_connection_file(const rdpSettings* settings, c return 0; } + +int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, const char* filename) +{ + int status; + rdpAssistanceFile* file; + + file = freerdp_client_assistance_file_new(); + + if (!file) + return -1; + + status = freerdp_client_assistance_parse_file(file, filename); + + if (status < 0) + return -1; + + status = freerdp_client_populate_settings_from_assistance_file(file, settings); + + if (status < 0) + return -1; + + freerdp_client_assistance_file_free(file); + + return 0; +} diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 34bbd0b6b..71641ea6b 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -156,6 +156,7 @@ COMMAND_LINE_ARGUMENT_A args[] = { "print-reconnect-cookie", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Print base64 reconnect cookie after connecting" }, { "heartbeat", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Support heartbeat PDUs" }, { "multitransport", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Support multitransport protocol" }, + { "assistance", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueFalse, NULL, -1, NULL, "Remote assistance mode" }, { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } }; @@ -284,6 +285,17 @@ int freerdp_client_command_line_pre_filter(void* context, int index, int argc, L return 1; } } + + if (length > 13) + { + if (_stricmp(&(argv[index])[length - 13], ".msrcIncident") == 0) + { + settings = (rdpSettings*) context; + settings->AssistanceFile = _strdup(argv[index]); + + return 1; + } + } } return 0; @@ -1845,6 +1857,10 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, { settings->PrintReconnectCookie = arg->Value ? TRUE : FALSE; } + CommandLineSwitchCase(arg, "assistance") + { + settings->RemoteAssistanceMode = arg->Value ? TRUE : FALSE; + } CommandLineSwitchDefault(arg) { } @@ -2023,6 +2039,27 @@ int freerdp_client_load_addins(rdpChannels* channels, rdpSettings* settings) } } + if (settings->RemoteAssistanceMode) + { + if (!freerdp_static_channel_collection_find(settings, "encomsp")) + { + char* params[1]; + + params[0] = "encomsp"; + + freerdp_client_add_static_channel(settings, 1, (char**) params); + } + + if (!freerdp_static_channel_collection_find(settings, "remdesk")) + { + char* params[1]; + + params[0] = "remdesk"; + + freerdp_client_add_static_channel(settings, 1, (char**) params); + } + } + for (index = 0; index < settings->StaticChannelCount; index++) { args = settings->StaticChannelArray[index]; diff --git a/include/freerdp/client.h b/include/freerdp/client.h index 661f3bac4..d4241f6a1 100644 --- a/include/freerdp/client.h +++ b/include/freerdp/client.h @@ -86,10 +86,13 @@ FREERDP_API freerdp* freerdp_client_get_instance(rdpContext* context); FREERDP_API HANDLE freerdp_client_get_thread(rdpContext* context); FREERDP_API int freerdp_client_settings_parse_command_line(rdpSettings* settings, int argc, char** argv); + FREERDP_API int freerdp_client_settings_parse_connection_file(rdpSettings* settings, const char* filename); FREERDP_API int freerdp_client_settings_parse_connection_file_buffer(rdpSettings* settings, const BYTE* buffer, size_t size); FREERDP_API int freerdp_client_settings_write_connection_file(const rdpSettings* settings, const char* filename, BOOL unicode); +FREERDP_API int freerdp_client_settings_parse_assistance_file(rdpSettings* settings, const char* filename); + #ifdef __cplusplus } #endif diff --git a/include/freerdp/client/assistance.h b/include/freerdp/client/assistance.h index 00068a73e..70e600884 100644 --- a/include/freerdp/client/assistance.h +++ b/include/freerdp/client/assistance.h @@ -56,8 +56,11 @@ extern "C" { #endif FREERDP_API int freerdp_client_assistance_parse_file_buffer(rdpAssistanceFile* file, const char* buffer, size_t size); +FREERDP_API int freerdp_client_assistance_parse_file(rdpAssistanceFile* file, const char* name); FREERDP_API int freerdp_client_assistance_decrypt(rdpAssistanceFile* file, const char* password); +FREERDP_API int freerdp_client_populate_settings_from_assistance_file(rdpAssistanceFile* file, rdpSettings* settings); + FREERDP_API rdpAssistanceFile* freerdp_client_assistance_file_new(); FREERDP_API void freerdp_client_assistance_file_free(rdpAssistanceFile* file); diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index cb9e25cb7..2695a70cc 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -585,6 +585,8 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_DisableCursorShadow 966 #define FreeRDP_DisableCursorBlinking 967 #define FreeRDP_AllowDesktopComposition 968 +#define FreeRDP_RemoteAssistanceMode 1024 +#define FreeRDP_RemoteAssistanceSessionId 1025 #define FreeRDP_TlsSecurity 1088 #define FreeRDP_NlaSecurity 1089 #define FreeRDP_RdpSecurity 1090 @@ -654,6 +656,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define FreeRDP_CredentialsFromStdin 1604 #define FreeRDP_ComputerName 1664 #define FreeRDP_ConnectionFile 1728 +#define FreeRDP_AssistanceFile 1729 #define FreeRDP_HomePath 1792 #define FreeRDP_ConfigPath 1793 #define FreeRDP_CurrentPath 1794 @@ -935,7 +938,11 @@ struct rdp_settings ALIGN64 BOOL DisableCursorBlinking; /* 967 */ ALIGN64 BOOL AllowDesktopComposition; /* 968 */ UINT64 padding1024[1024 - 969]; /* 969 */ - UINT64 padding1088[1088 - 1024]; /* 1024 */ + + /* Remote Assistance */ + ALIGN64 BOOL RemoteAssistanceMode; /* 1024 */ + ALIGN64 char* RemoteAssistanceSessionId; /* 1025 */ + UINT64 padding1088[1088 - 1026]; /* 1026 */ /** * X.224 Connection Request/Confirm @@ -1047,7 +1054,8 @@ struct rdp_settings /* Files */ ALIGN64 char* ConnectionFile; /* 1728 */ - UINT64 padding1792[1792 - 1729]; /* 1729 */ + ALIGN64 char* AssistanceFile; /* 1729 */ + UINT64 padding1792[1792 - 1730]; /* 1730 */ /* Paths */ ALIGN64 char* HomePath; /* 1792 */ diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index e04230f37..12fe064a6 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -809,6 +809,10 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id) return settings->AllowDesktopComposition; break; + case FreeRDP_RemoteAssistanceMode: + return settings->RemoteAssistanceMode; + break; + case FreeRDP_TlsSecurity: return settings->TlsSecurity; break; @@ -1294,6 +1298,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param) settings->AllowDesktopComposition = param; break; + case FreeRDP_RemoteAssistanceMode: + settings->RemoteAssistanceMode = param; + break; + case FreeRDP_TlsSecurity: settings->TlsSecurity = param; break; @@ -2368,6 +2376,10 @@ char* freerdp_get_param_string(rdpSettings* settings, int id) return settings->DynamicDSTTimeZoneKeyName; break; + case FreeRDP_RemoteAssistanceSessionId: + return settings->RemoteAssistanceSessionId; + break; + case FreeRDP_AuthenticationServiceClass: return settings->AuthenticationServiceClass; break; @@ -2412,6 +2424,10 @@ char* freerdp_get_param_string(rdpSettings* settings, int id) return settings->ConnectionFile; break; + case FreeRDP_AssistanceFile: + return settings->AssistanceFile; + break; + case FreeRDP_HomePath: return settings->HomePath; break; @@ -2553,6 +2569,11 @@ int freerdp_set_param_string(rdpSettings* settings, int id, const char* param) settings->DynamicDSTTimeZoneKeyName = _strdup(param); break; + case FreeRDP_RemoteAssistanceSessionId: + free(settings->RemoteAssistanceSessionId); + settings->RemoteAssistanceSessionId = _strdup(param); + break; + case FreeRDP_AuthenticationServiceClass: free(settings->AuthenticationServiceClass); settings->AuthenticationServiceClass = _strdup(param); @@ -2608,6 +2629,11 @@ int freerdp_set_param_string(rdpSettings* settings, int id, const char* param) settings->ConnectionFile = _strdup(param); break; + case FreeRDP_AssistanceFile: + free(settings->AssistanceFile); + settings->AssistanceFile = _strdup(param); + break; + case FreeRDP_HomePath: free(settings->HomePath); settings->HomePath = _strdup(param); diff --git a/libfreerdp/core/info.c b/libfreerdp/core/info.c index 6e1696833..f68dff17b 100644 --- a/libfreerdp/core/info.c +++ b/libfreerdp/core/info.c @@ -393,15 +393,15 @@ BOOL rdp_read_info_packet(wStream* s, rdpSettings* settings) void rdp_write_info_packet(wStream* s, rdpSettings* settings) { UINT32 flags; - WCHAR* domain = NULL; + WCHAR* domainW = NULL; int cbDomain = 0; - WCHAR* userName = NULL; + WCHAR* userNameW = NULL; int cbUserName = 0; - WCHAR* password = NULL; + WCHAR* passwordW = NULL; int cbPassword = 0; - WCHAR* alternateShell = NULL; + WCHAR* alternateShellW = NULL; int cbAlternateShell = 0; - WCHAR* workingDir = NULL; + WCHAR* workingDirW = NULL; int cbWorkingDir = 0; BOOL usedPasswordCookie = FALSE; @@ -439,30 +439,62 @@ void rdp_write_info_packet(wStream* s, rdpSettings* settings) if (settings->Domain) { - cbDomain = ConvertToUnicode(CP_UTF8, 0, settings->Domain, -1, &domain, 0) * 2; + cbDomain = ConvertToUnicode(CP_UTF8, 0, settings->Domain, -1, &domainW, 0) * 2; } else { - domain = NULL; + domainW = NULL; cbDomain = 0; } - cbUserName = ConvertToUnicode(CP_UTF8, 0, settings->Username, -1, &userName, 0) * 2; - - if (settings->RedirectionPassword && settings->RedirectionPasswordLength > 0) + if (!settings->RemoteAssistanceMode) { - usedPasswordCookie = TRUE; - password = (WCHAR*) settings->RedirectionPassword; - cbPassword = settings->RedirectionPasswordLength - 2; /* Strip double zero termination */ + cbUserName = ConvertToUnicode(CP_UTF8, 0, settings->Username, -1, &userNameW, 0) * 2; } else { - cbPassword = ConvertToUnicode(CP_UTF8, 0, settings->Password, -1, &password, 0) * 2; + /* user name provided by the expert for connecting to the novice computer */ + cbUserName = ConvertToUnicode(CP_UTF8, 0, settings->Username, -1, &userNameW, 0) * 2; } - cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, settings->AlternateShell, -1, &alternateShell, 0) * 2; + if (!settings->RemoteAssistanceMode) + { + if (settings->RedirectionPassword && settings->RedirectionPasswordLength > 0) + { + usedPasswordCookie = TRUE; + passwordW = (WCHAR*) settings->RedirectionPassword; + cbPassword = settings->RedirectionPasswordLength - 2; /* Strip double zero termination */ + } + else + { + cbPassword = ConvertToUnicode(CP_UTF8, 0, settings->Password, -1, &passwordW, 0) * 2; + } + } + else + { + /* This field MUST be filled with "*" */ + cbPassword = ConvertToUnicode(CP_UTF8, 0, "*", -1, &passwordW, 0) * 2; + } - cbWorkingDir = ConvertToUnicode(CP_UTF8, 0, settings->ShellWorkingDirectory, -1, &workingDir, 0) * 2; + if (!settings->RemoteAssistanceMode) + { + cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, settings->AlternateShell, -1, &alternateShellW, 0) * 2; + } + else + { + /* This field MUST be filled with "*" */ + cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, "*", -1, &alternateShellW, 0) * 2; + } + + if (!settings->RemoteAssistanceMode) + { + cbWorkingDir = ConvertToUnicode(CP_UTF8, 0, settings->ShellWorkingDirectory, -1, &workingDirW, 0) * 2; + } + else + { + /* Remote Assistance Session Id */ + cbWorkingDir = ConvertToUnicode(CP_UTF8, 0, settings->RemoteAssistanceSessionId, -1, &workingDirW, 0) * 2; + } Stream_Write_UINT32(s, 0); /* CodePage */ Stream_Write_UINT32(s, flags); /* flags */ @@ -474,32 +506,32 @@ void rdp_write_info_packet(wStream* s, rdpSettings* settings) Stream_Write_UINT16(s, cbWorkingDir); /* cbWorkingDir */ if (cbDomain > 0) - Stream_Write(s, domain, cbDomain); + Stream_Write(s, domainW, cbDomain); Stream_Write_UINT16(s, 0); if (cbUserName > 0) - Stream_Write(s, userName, cbUserName); + Stream_Write(s, userNameW, cbUserName); Stream_Write_UINT16(s, 0); if (cbPassword > 0) - Stream_Write(s, password, cbPassword); + Stream_Write(s, passwordW, cbPassword); Stream_Write_UINT16(s, 0); if (cbAlternateShell > 0) - Stream_Write(s, alternateShell, cbAlternateShell); + Stream_Write(s, alternateShellW, cbAlternateShell); Stream_Write_UINT16(s, 0); if (cbWorkingDir > 0) - Stream_Write(s, workingDir, cbWorkingDir); + Stream_Write(s, workingDirW, cbWorkingDir); Stream_Write_UINT16(s, 0); - free(domain); - free(userName); - free(alternateShell); - free(workingDir); + free(domainW); + free(userNameW); + free(alternateShellW); + free(workingDirW); if (!usedPasswordCookie) - free(password); + free(passwordW); if (settings->RdpVersion >= 5) rdp_write_extended_info_packet(s, settings); /* extraInfo */ diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 6c0de1e7f..0843bbdd6 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -464,6 +464,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings) _settings->ClientAddress = _strdup(settings->ClientAddress); /* 769 */ _settings->ClientDir = _strdup(settings->ClientDir); /* 770 */ _settings->DynamicDSTTimeZoneKeyName = _strdup(settings->DynamicDSTTimeZoneKeyName); /* 897 */ + _settings->RemoteAssistanceSessionId = _strdup(settings->RemoteAssistanceSessionId); /* 1025 */ _settings->AuthenticationServiceClass = _strdup(settings->AuthenticationServiceClass); /* 1098 */ _settings->PreconnectionBlob = _strdup(settings->PreconnectionBlob); /* 1155 */ _settings->KerberosKdc = _strdup(settings->KerberosKdc); /* 1344 */ @@ -476,6 +477,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings) _settings->WmClass = _strdup(settings->WmClass); /* 1549 */ _settings->ComputerName = _strdup(settings->ComputerName); /* 1664 */ _settings->ConnectionFile = _strdup(settings->ConnectionFile); /* 1728 */ + _settings->AssistanceFile = _strdup(settings->AssistanceFile); /* 1729 */ _settings->HomePath = _strdup(settings->HomePath); /* 1792 */ _settings->ConfigPath = _strdup(settings->ConfigPath); /* 1793 */ _settings->CurrentPath = _strdup(settings->CurrentPath); /* 1794 */ @@ -624,6 +626,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings) _settings->DisableCursorShadow = settings->DisableCursorShadow; /* 966 */ _settings->DisableCursorBlinking = settings->DisableCursorBlinking; /* 967 */ _settings->AllowDesktopComposition = settings->AllowDesktopComposition; /* 968 */ + _settings->RemoteAssistanceMode = settings->RemoteAssistanceMode; /* 1024 */ _settings->TlsSecurity = settings->TlsSecurity; /* 1088 */ _settings->NlaSecurity = settings->NlaSecurity; /* 1089 */ _settings->RdpSecurity = settings->RdpSecurity; /* 1090 */ @@ -810,6 +813,8 @@ void freerdp_settings_free(rdpSettings* settings) free(settings->ClientDir); free(settings->CertificateFile); free(settings->PrivateKeyFile); + free(settings->ConnectionFile); + free(settings->AssistanceFile); free(settings->ReceivedCapabilities); free(settings->OrderSupport); free(settings->ClientHostname); @@ -837,6 +842,7 @@ void freerdp_settings_free(rdpSettings* settings) free(settings->RedirectionDomain); free(settings->RedirectionPassword); free(settings->RedirectionTsvUrl); + free(settings->RemoteAssistanceSessionId); free(settings->AuthenticationServiceClass); freerdp_target_net_addresses_free(settings); freerdp_device_collection_free(settings);