client/common: add .msrcIncident type 1 file test
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Sun, 29 Jun 2014 16:36:28 +0000 (12:36 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Sun, 29 Jun 2014 16:36:28 +0000 (12:36 -0400)
client/common/assistance.c
client/common/test/TestClientAssistance.c
include/freerdp/client/assistance.h

index bfd6105..42509be 100644 (file)
@@ -22,6 +22,7 @@
 #endif
 
 #include <winpr/crt.h>
+#include <winpr/print.h>
 #include <winpr/windows.h>
 
 #include <openssl/ssl.h>
 #include <freerdp/client/assistance.h>
 
 /**
+ * Password encryption in establishing a remote assistance session of type 1:
+ * http://blogs.msdn.com/b/openspecification/archive/2011/10/31/password-encryption-in-establishing-a-remote-assistance-session-of-type-1.aspx
+ *
+ * Creation of PassStub for the Remote Assistance Ticket:
+ * http://social.msdn.microsoft.com/Forums/en-US/6316c3f4-ea09-4343-a4a1-9cca46d70d28/creation-of-passstub-for-the-remote-assistance-ticket?forum=os_windowsprotocols
+ */
+
+/**
  * CryptDeriveKey Function:
  * http://msdn.microsoft.com/en-us/library/windows/desktop/aa379916/
  *
@@ -102,29 +111,59 @@ int freerdp_client_assistance_decrypt1(rdpAssistanceFile* file, const char* pass
        int status;
        RC4_KEY rc4;
        MD5_CTX md5Ctx;
-       int PassStubLength;
+       int cbPasswordW;
+       int cbPassStubW;
        BYTE* PlainBlob = NULL;
        WCHAR* PasswordW = NULL;
+       WCHAR* PassStubW = NULL;
        BYTE EncryptionKey[AES_BLOCK_SIZE];
        BYTE PasswordHash[MD5_DIGEST_LENGTH];
 
+       /**
+        * PROV_RSA_FULL provider
+        * CALG_MD5 hashing
+        * CALG_RC4 encryption
+        * Key Length: 40 bits
+        * Salt Length: 88 bits
+        */
+
        status = ConvertToUnicode(CP_UTF8, 0, password, -1, &PasswordW, 0);
 
        if (status <= 0)
                return -1;
 
+       cbPasswordW = (status - 1) * 2;
+
+       printf("PasswordW (%d)\n", cbPasswordW);
+       winpr_HexDump(PasswordW, cbPasswordW);
+
        MD5_Init(&md5Ctx);
-       MD5_Update(&md5Ctx, PasswordW, status * 2);
+       MD5_Update(&md5Ctx, PasswordW, cbPasswordW);
        MD5_Final((void*) PasswordHash, &md5Ctx);
 
+       printf("PasswordHash (%s):\n", password);
+       winpr_HexDump(PasswordHash, sizeof(PasswordHash));
+
        status = freerdp_client_assistance_crypt_derive_key(PasswordHash, sizeof(PasswordHash),
                        EncryptionKey, sizeof(EncryptionKey));
 
        if (status < 0)
                return -1;
 
-       PassStubLength = strlen(file->PassStub);
-       file->EncryptedPassStubLength = PassStubLength + 4;
+       printf("DerivedKey (%d):\n", sizeof(EncryptionKey));
+       winpr_HexDump(EncryptionKey, sizeof(EncryptionKey));
+
+       status = ConvertToUnicode(CP_UTF8, 0, file->PassStub, -1, &PassStubW, 0);
+
+       if (status <= 0)
+               return -1;
+
+       cbPassStubW = (status - 1) * 2;
+
+       printf("PassStubW (%d)\n", cbPassStubW);
+       winpr_HexDump(PassStubW, cbPassStubW);
+
+       file->EncryptedPassStubLength = cbPassStubW + 4;
 
        PlainBlob = (BYTE*) calloc(1, file->EncryptedPassStubLength);
        file->EncryptedPassStub = (BYTE*) calloc(1, file->EncryptedPassStubLength);
@@ -135,12 +174,24 @@ int freerdp_client_assistance_decrypt1(rdpAssistanceFile* file, const char* pass
        if (!file->EncryptedPassStubLength)
                return -1;
 
-       *((UINT32*) PlainBlob) = PassStubLength;
-       CopyMemory(&PlainBlob[4], file->PassStub, PassStubLength);
+       *((UINT32*) PlainBlob) = cbPassStubW;
+       CopyMemory(&PlainBlob[4], PassStubW, cbPassStubW);
+
+       printf("PlainBlob (%d)\n", file->EncryptedPassStubLength);
+       winpr_HexDump(PlainBlob, file->EncryptedPassStubLength);
+
+#if 0
+       void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
+       void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
+                       unsigned char *outdata);
+#endif
 
        RC4_set_key(&rc4, sizeof(EncryptionKey), EncryptionKey);
        RC4(&rc4, file->EncryptedPassStubLength, PlainBlob, file->EncryptedPassStub);
 
+       printf("EncryptedPassStub (%d):\n", file->EncryptedPassStubLength);
+       winpr_HexDump(file->EncryptedPassStub, file->EncryptedPassStubLength);
+
        return 1;
 }
 
@@ -561,8 +612,13 @@ int freerdp_client_assistance_parse_file_buffer(rdpAssistanceFile* file, const c
                        file->LowSpeed = TRUE;
        }
 
-       file->EncryptedLHTicket = freerdp_client_assistance_parse_hex_string(file->LHTicket,
-                       &file->EncryptedLHTicketLength);
+       file->Type = (file->LHTicket) ? 2 : 1;
+
+       if (file->LHTicket)
+       {
+               file->EncryptedLHTicket = freerdp_client_assistance_parse_hex_string(file->LHTicket,
+                               &file->EncryptedLHTicketLength);
+       }
 
        status = freerdp_client_assistance_parse_connection_string1(file);
 
index 7aeef14..9fc92b4 100644 (file)
@@ -4,9 +4,25 @@
 
 #include <freerdp/client/assistance.h>
 
-const char* TEST_MSRC_INCIDENT_PASSWORD = "48BJQ853X3B4";
+const char* TEST_MSRC_INCIDENT_PASSWORD_TYPE1 = "Password1";
 
-static const char* TEST_MSRC_INCIDENT_FILE =
+static const char* TEST_MSRC_INCIDENT_FILE_TYPE1 =
+"<?xml version=\"1.0\" encoding=\"Unicode\" ?>"
+"<UPLOADINFO TYPE=\"Escalated\">"
+"<UPLOADDATA "
+"USERNAME=\"Administrator\" "
+"RCTICKET=\"65538,1,10.0.3.105:3389;winxpsp3.contoso3.com:3389,*,"
+"rb+v0oPmEISmi8N2zK/vuhgul/ABqlDt6wW0VxMyxK8=,*,*,IuaRySSbPDNna4+2mKcsKxsbJFI=\""
+"RCTICKETENCRYPTED=\"1\" "
+"DtStart=\"1314905741\" "
+"DtLength=\"180\" "
+"PassStub=\"RT=0PvIndan52*\" "
+"L=\"0\" />"
+"</UPLOADINFO>";
+
+const char* TEST_MSRC_INCIDENT_PASSWORD_TYPE2 = "48BJQ853X3B4";
+
+static const char* TEST_MSRC_INCIDENT_FILE_TYPE2 =
 "<?xml version=\"1.0\"?>"
 "<UPLOADINFO TYPE=\"Escalated\">"
 "<UPLOADDATA USERNAME=\"awake\" "
@@ -40,14 +56,56 @@ static const char* TEST_MSRC_INCIDENT_FILE =
 "L=\"0\"/>"
 "</UPLOADINFO>";
 
-int TestClientAssistance(int argc, char* argv[])
+int test_msrsc_incident_file_type1()
+{
+       int status;
+       rdpAssistanceFile* file;
+
+       file = freerdp_client_assistance_file_new();
+
+       status = freerdp_client_assistance_parse_file_buffer(file,
+                       TEST_MSRC_INCIDENT_FILE_TYPE1, sizeof(TEST_MSRC_INCIDENT_FILE_TYPE1));
+
+       printf("freerdp_client_assistance_parse_file_buffer: %d\n", status);
+
+       if (status < 0)
+               return -1;
+
+       printf("Username: %s\n", file->Username);
+       printf("LHTicket: %s\n", file->LHTicket);
+       printf("RCTicket: %s\n", file->RCTicket);
+       printf("RCTicketEncrypted: %d\n", file->RCTicketEncrypted);
+       printf("PassStub: %s\n", file->PassStub);
+       printf("DtStart: %d\n", file->DtStart);
+       printf("DtLength: %d\n", file->DtLength);
+       printf("LowSpeed: %d\n", file->LowSpeed);
+
+       printf("RASessionId: %s\n", file->RASessionId);
+       printf("RASpecificParams: %s\n", file->RASpecificParams);
+       printf("MachineAddress: %s\n", file->MachineAddress);
+       printf("MachinePort: %d\n", (int) file->MachinePort);
+
+       status = freerdp_client_assistance_decrypt(file, TEST_MSRC_INCIDENT_PASSWORD_TYPE1);
+
+       printf("freerdp_client_assistance_decrypt: %d\n", status);
+
+       if (status < 0)
+               return -1;
+
+       freerdp_client_assistance_file_free(file);
+
+       return 0;
+}
+
+int test_msrsc_incident_file_type2()
 {
        int status;
        rdpAssistanceFile* file;
 
        file = freerdp_client_assistance_file_new();
 
-       status = freerdp_client_assistance_parse_file_buffer(file, TEST_MSRC_INCIDENT_FILE, sizeof(TEST_MSRC_INCIDENT_FILE));
+       status = freerdp_client_assistance_parse_file_buffer(file,
+                       TEST_MSRC_INCIDENT_FILE_TYPE2, sizeof(TEST_MSRC_INCIDENT_FILE_TYPE2));
 
        printf("freerdp_client_assistance_parse_file_buffer: %d\n", status);
 
@@ -68,7 +126,7 @@ int TestClientAssistance(int argc, char* argv[])
        printf("MachineAddress: %s\n", file->MachineAddress);
        printf("MachinePort: %d\n", (int) file->MachinePort);
 
-       status = freerdp_client_assistance_decrypt(file, TEST_MSRC_INCIDENT_PASSWORD);
+       status = freerdp_client_assistance_decrypt(file, TEST_MSRC_INCIDENT_PASSWORD_TYPE2);
 
        printf("freerdp_client_assistance_decrypt: %d\n", status);
 
@@ -80,3 +138,12 @@ int TestClientAssistance(int argc, char* argv[])
        return 0;
 }
 
+int TestClientAssistance(int argc, char* argv[])
+{
+       test_msrsc_incident_file_type1();
+
+       //test_msrsc_incident_file_type2();
+
+       return 0;
+}
+
index 70e6008..6af76c6 100644 (file)
@@ -25,7 +25,8 @@
 
 struct rdp_assistance_file
 {
-       char* Type;
+       UINT32 Type;
+
        char* Username;
        char* LHTicket;
        char* RCTicket;