client/common: parse and use remote assistance file
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Sat, 28 Jun 2014 22:33:46 +0000 (18:33 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Sat, 28 Jun 2014 22:33:46 +0000 (18:33 -0400)
.gitignore
channels/remdesk/client/remdesk_main.c
client/common/assistance.c
client/common/client.c
client/common/cmdline.c
include/freerdp/client.h
include/freerdp/client/assistance.h
include/freerdp/settings.h
libfreerdp/common/settings.c
libfreerdp/core/info.c
libfreerdp/core/settings.c

index 415c544..a53e905 100755 (executable)
@@ -113,6 +113,7 @@ Release
 Win32
 build*/
 *.orig
+*.msrcIncident
 
 default.log
 *Amplifier XE*
index feeb7e4..546cdb9 100644 (file)
@@ -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;
index 45408bf..2067805 100644 (file)
@@ -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;
index 1fc565f..13b46b6 100644 (file)
@@ -27,6 +27,7 @@
 #include <freerdp/client/file.h>
 #include <freerdp/client/cmdline.h>
 #include <freerdp/client/channels.h>
+#include <freerdp/client/assistance.h>
 
 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;
+}
index 34bbd0b..71641ea 100644 (file)
@@ -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];
index 661f3ba..d4241f6 100644 (file)
@@ -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
index 00068a7..70e6008 100644 (file)
@@ -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);
 
index cb9e25c..2695a70 100644 (file)
@@ -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 */
index e04230f..12fe064 100644 (file)
@@ -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);
index 6e16968..f68dff1 100644 (file)
@@ -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->RemoteAssistanceMode)
+       {
+               cbUserName = ConvertToUnicode(CP_UTF8, 0, settings->Username, -1, &userNameW, 0) * 2;
+       }
+       else
+       {
+               /* user name provided by the expert for connecting to the novice computer */
+               cbUserName = ConvertToUnicode(CP_UTF8, 0, settings->Username, -1, &userNameW, 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 */
+               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
        {
-               cbPassword = ConvertToUnicode(CP_UTF8, 0, settings->Password, -1, &password, 0) * 2;
+               /* This field MUST be filled with "*" */
+               cbPassword = ConvertToUnicode(CP_UTF8, 0, "*", -1, &passwordW, 0) * 2;
        }
 
-       cbAlternateShell = ConvertToUnicode(CP_UTF8, 0, settings->AlternateShell, -1, &alternateShell, 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;
+       }
 
-       cbWorkingDir = ConvertToUnicode(CP_UTF8, 0, settings->ShellWorkingDirectory, -1, &workingDir, 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 */
index 6c0de1e..0843bbd 100644 (file)
@@ -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);