#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/
*
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);
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;
}
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);
#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\" "
"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);
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);
return 0;
}
+int TestClientAssistance(int argc, char* argv[])
+{
+ test_msrsc_incident_file_type1();
+
+ //test_msrsc_incident_file_type2();
+
+ return 0;
+}
+