Re: [ rdesktop-Bugs-2817779 ] Can't connect to WinServ 2008 SP2: "internal license error"
Thomas Uhle <[email protected]> Tue, 20 Sep 2011 23:25:37 +0200 (CEST)
| Newsgroups | gmane.network.rdesktop.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Peter, I have done some more investigations on RDP licensing and believe that I understand now how it works. Indeed, the terminal server replies with a license error message with the error code STATUS_VALID_CLIENT after checking the presented CAL when rdesktop is running the second and third time. This behaviour corresponds to case 1 in [MS-RDPELE] section 3.2.5.3 "Processing Client License Information" at http://msdn.microsoft.com/en-us/library/cc241955%28v=prot.10%29.aspx , ending the licensing protocol. Yet I wanted to know whether rdesktop behaves correctly, so I inserted some additional debug messages to licence.c (patch is attached to this e-mail) and realised that the licensing protocol is complete only the first time that rdesktop is called. The second time, a disconnect PDU is received right after the licensing PDU with the CAL was sent. I recognised that licence_process() in licence.c has no implementation for the cases LICENCE_TAG_RESULT (that is if the PDU contains a license error message) and LICENCE_TAG_REISSUE (that is if the PDU contains an upgraded permanent license). But that was not really a problem this time. Then I checked the License Information packet built in licence_present() according to [MS-RDPELE] section 2.2.2.3 "Client License Information" at http://msdn.microsoft.com/en-us/library/cc241919%28v=prot.10%29.aspx , which has been almost correct except for the calculation of the packet length (which really was a hard job to find out) and the type id for the BLOB with the encrypted master secret. After applying these fixes, rdesktop again works like a charm (no more "work-arounds" needed). I have prepared a unidiff file providing all these patches, which is attached to this e-mail. Please feel free to commit these changes to the rdesktop repository for being able to close the pending bug #2817779. Apart from that, I am not sure whether it makes sense to implement the missing function for the case LICENCE_TAG_RESULT in licence_process(). The information needed to parse a license error message packet can be found at http://msdn.microsoft.com/en-us/library/cc240482%28v=prot.10%29.aspx . Best regards, Thomas Uhle ------------------------------------------------------------------------------ All the data continuously generated in your IT infrastructure contains a definitive record of customers, application performance, security threats, fraudulent activity and more. Splunk takes this data and makes sense of it. Business sense. IT sense. Common sense. http://p.sf.net/sfu/splunk-d2dcopy1 _______________________________________________ rdesktop-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/rdesktop-devel
rdesktop-licence-patch.diff
(text/x-patch, 2.9 KB)
--- licence.c~ 2011-04-18 13:21:57 +0200
+++ licence.c 2011-09-20 20:51:03 +0200
@@ -2,6 +2,7 @@
rdesktop: A Remote Desktop Protocol client.
RDP licensing negotiation
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
+ Copyright (C) Thomas Uhle <[email protected]> 2011
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -60,11 +61,11 @@
{
uint32 sec_flags = SEC_LICENCE_NEG;
uint16 length =
- 16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
+ 24 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
STREAM s;
- s = sec_init(sec_flags, length + 4);
+ s = sec_init(sec_flags, length + 2);
out_uint8(s, LICENCE_TAG_PRESENT);
out_uint8(s, 2); /* version */
@@ -75,7 +76,7 @@
out_uint16_le(s, 0x0201);
out_uint8p(s, client_random, SEC_RANDOM_SIZE);
- out_uint16(s, 0);
+ out_uint16_le(s, 2);
out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
out_uint8s(s, SEC_PADDING_SIZE);
@@ -115,7 +116,7 @@
out_uint16_le(s, 0xff01);
out_uint8p(s, client_random, SEC_RANDOM_SIZE);
- out_uint16(s, 0);
+ out_uint16_le(s, 2);
out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
out_uint8s(s, SEC_PADDING_SIZE);
@@ -163,11 +164,18 @@
ssl_rc4_set_key(&crypt_key, g_licence_key, 16);
ssl_rc4_crypt(&crypt_key, hwid, hwid, sizeof(hwid));
+#if WITH_DEBUG
+ DEBUG(("Sending licensing PDU (message type 0x%02x)\n", LICENCE_TAG_PRESENT));
+#endif
licence_present(null_data, null_data, licence_data, licence_size, hwid, signature);
+
xfree(licence_data);
return;
}
+#if WITH_DEBUG
+ DEBUG(("Sending licensing PDU (message type 0x%02x)\n", LICENCE_TAG_REQUEST));
+#endif
licence_send_request(null_data, null_data, g_username, g_hostname);
}
@@ -249,6 +257,9 @@
ssl_rc4_set_key(&crypt_key, g_licence_key, 16);
ssl_rc4_crypt(&crypt_key, hwid, crypt_hwid, LICENCE_HWID_SIZE);
+#if WITH_DEBUG
+ DEBUG(("Sending licensing PDU (message type 0x%02x)\n", LICENCE_TAG_AUTHRESP));
+#endif
licence_send_authresp(out_token, crypt_hwid, out_sig);
}
@@ -300,6 +311,10 @@
in_uint8(s, tag);
in_uint8s(s, 3); /* version, length */
+#if WITH_DEBUG
+ DEBUG(("Received licensing PDU (message type 0x%02x)\n", tag));
+#endif
+
switch (tag)
{
case LICENCE_TAG_DEMAND:
@@ -311,14 +326,14 @@
break;
case LICENCE_TAG_ISSUE:
+ case LICENCE_TAG_REISSUE:
licence_process_issue(s);
break;
- case LICENCE_TAG_REISSUE:
case LICENCE_TAG_RESULT:
break;
default:
- unimpl("licence tag 0x%x\n", tag);
+ unimpl("licence tag 0x%02x\n", tag);
}
}