libfreerdp-core: encoding and sending of licensing packets

This commit is contained in:
Marc-André Moreau 2011-07-12 01:16:59 -04:00
parent d797e7ce92
commit 4da5b77cbe
7 changed files with 351 additions and 40 deletions

View File

@ -71,5 +71,7 @@ void rdp_client_connect(rdpRdp* rdp)
rdp_send_client_info(rdp);
rdp_recv(rdp);
rdp_recv(rdp);
}

View File

@ -20,14 +20,88 @@
#include "license.h"
/**
* Receive an RDP licensing packet.\n
* @msdn{cc240479}
* @param rdp RDP module
* Read a licensing preamble.\n
* @msdn{cc240480}
* @param s stream
* @param sec_flags security flags
* @param bMsgType license message type
* @param flags message flags
* @param wMsgSize message size
*/
void license_recv(rdpLicense* license, STREAM* s, uint16 sec_flags)
void license_read_preamble(STREAM* s, uint8* bMsgType, uint8* flags, uint16* wMsgSize)
{
/* preamble (4 bytes) */
stream_read_uint8(s, *bMsgType); /* bMsgType (1 byte) */
stream_read_uint8(s, *flags); /* flags (1 byte) */
stream_read_uint16(s, *wMsgSize); /* wMsgSize (2 bytes) */
}
/**
* Write a licensing preamble.\n
* @msdn{cc240480}
* @param s stream
* @param bMsgType license message type
* @param flags message flags
* @param wMsgSize message size
*/
void license_write_preamble(STREAM* s, uint8 bMsgType, uint8 flags, uint16 wMsgSize)
{
/* preamble (4 bytes) */
stream_write_uint8(s, bMsgType); /* bMsgType (1 byte) */
stream_write_uint8(s, flags); /* flags (1 byte) */
stream_write_uint16(s, wMsgSize); /* wMsgSize (2 bytes) */
}
/**
* Initialize a license packet stream.\n
* @param license license module
* @return stream
*/
STREAM* license_send_stream_init(rdpLicense* license)
{
STREAM* s;
s = transport_send_stream_init(license->rdp->transport, 4096);
stream_seek(s, LICENSE_PACKET_HEADER_LENGTH);
return s;
}
/**
* Send an RDP licensing packet.\n
* @msdn{cc240479}
* @param license license module
* @param s stream
*/
void license_send(rdpLicense* license, STREAM* s, uint8 type)
{
int length;
uint16 wMsgSize;
uint16 sec_flags;
length = stream_get_length(s);
stream_set_pos(s, 0);
sec_flags = SEC_LICENSE_PKT;
wMsgSize = length - LICENSE_PACKET_HEADER_LENGTH;
rdp_write_header(license->rdp, s, length);
rdp_write_security_header(s, sec_flags);
license_write_preamble(s, type, PREAMBLE_VERSION_2_0, wMsgSize);
stream_set_pos(s, length);
transport_write(license->rdp->transport, s);
}
/**
* Receive an RDP licensing packet.\n
* @msdn{cc240479}
* @param license license module
* @param s stream
*/
void license_recv(rdpLicense* license, STREAM* s)
{
uint8 flags;
uint8 bMsgType;
@ -35,10 +109,7 @@ void license_recv(rdpLicense* license, STREAM* s, uint16 sec_flags)
printf("SEC_LICENSE_PKT\n");
/* preamble (4 bytes) */
stream_read_uint8(s, bMsgType); /* bMsgType (1 byte) */
stream_read_uint8(s, flags); /* flags (1 byte) */
stream_read_uint16(s, wMsgSize); /* wMsgSize (2 bytes) */
license_read_preamble(s, &bMsgType, &flags, &wMsgSize); /* preamble (4 bytes) */
printf("bMsgType:%X, flags:%X, wMsgSize:%02x\n", bMsgType, flags, wMsgSize);
@ -46,6 +117,7 @@ void license_recv(rdpLicense* license, STREAM* s, uint16 sec_flags)
{
case LICENSE_REQUEST:
license_read_license_request_packet(license, s);
license_send_new_license_request_packet(license);
break;
case PLATFORM_CHALLENGE:
@ -71,7 +143,8 @@ void license_recv(rdpLicense* license, STREAM* s, uint16 sec_flags)
}
/**
* Read PRODUCT_INFO.\n
* Read Product Information (PRODUCT_INFO).\n
* @msdn{cc241915}
* @param s stream
* @param productInfo product information
*/
@ -91,13 +164,58 @@ void license_read_product_info(STREAM* s, PRODUCT_INFO* productInfo)
stream_read(s, productInfo->pbProductId, productInfo->cbProductId);
}
/**
* Allocate New Product Information (PRODUCT_INFO).\n
* @msdn{cc241915}
* @return new product information
*/
PRODUCT_INFO* license_new_product_info()
{
PRODUCT_INFO* productInfo;
productInfo = (PRODUCT_INFO*) xmalloc(sizeof(PRODUCT_INFO));
productInfo->dwVersion = 0;
productInfo->cbCompanyName = 0;
productInfo->pbCompanyName = NULL;
productInfo->cbProductId = 0;
productInfo->pbProductId = NULL;
return productInfo;
}
/**
* Free Product Information (PRODUCT_INFO).\n
* @msdn{cc241915}
* @param productInfo product information
*/
void license_free_product_info(PRODUCT_INFO* productInfo)
{
if (productInfo->pbCompanyName != NULL)
xfree(productInfo->pbCompanyName);
if (productInfo->pbProductId != NULL)
xfree(productInfo->pbProductId);
xfree(productInfo);
}
/**
* Read License Binary Blob (LICENSE_BINARY_BLOB).\n
* @msdn{cc240481}
* @param s stream
* @param blob license binary blob
*/
void license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob)
{
uint16 wBlobType;
stream_read_uint16(s, wBlobType); /* wBlobType (2 bytes) */
if (blob->type != wBlobType && blob->type != 0)
if (blob->type != wBlobType && blob->type != BB_ANY_BLOB)
{
printf("license binary blob type does not match expected type.\n");
return;
@ -112,6 +230,61 @@ void license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob)
stream_read(s, blob->data, blob->length); /* blobData */
}
/**
* Write License Binary Blob (LICENSE_BINARY_BLOB).\n
* @msdn{cc240481}
* @param s stream
* @param blob license binary blob
*/
void license_write_binary_blob(STREAM* s, LICENSE_BLOB* blob)
{
stream_write_uint16(s, blob->type); /* wBlobType (2 bytes) */
stream_write_uint16(s, blob->length); /* wBlobLen (2 bytes) */
if (blob->length > 0)
stream_write(s, blob->data, blob->length); /* blobData */
}
/**
* Allocate New License Binary Blob (LICENSE_BINARY_BLOB).\n
* @msdn{cc240481}
* @return new license binary blob
*/
LICENSE_BLOB* license_new_binary_blob(uint16 type)
{
LICENSE_BLOB* blob;
blob = (LICENSE_BLOB*) xmalloc(sizeof(LICENSE_BLOB));
blob->type = type;
blob->length = 0;
blob->data = NULL;
return blob;
}
/**
* Free License Binary Blob (LICENSE_BINARY_BLOB).\n
* @msdn{cc240481}
* @param blob license binary blob
*/
void license_free_binary_blob(LICENSE_BLOB* blob)
{
if (blob->data != NULL)
xfree(blob->data);
xfree(blob);
}
/**
* Read License Scope List (SCOPE_LIST).\n
* @msdn{cc241916}
* @param s stream
* @param scopeList scope list
*/
void license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList)
{
int i;
@ -130,10 +303,45 @@ void license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList)
}
}
/**
* Allocate New License Scope List (SCOPE_LIST).\n
* @msdn{cc241916}
* @return new scope list
*/
SCOPE_LIST* license_new_scope_list()
{
SCOPE_LIST* scopeList;
scopeList = (SCOPE_LIST*) xmalloc(sizeof(SCOPE_LIST));
scopeList->count = 0;
scopeList->array = NULL;
return scopeList;
}
/**
* Free License Scope List (SCOPE_LIST).\n
* @msdn{cc241916}
* @param scopeList scope list
*/
void license_free_scope_list(SCOPE_LIST* scopeList)
{
int i;
for (i = 0; i < scopeList->count; i++)
{
license_free_binary_blob(&scopeList->array[i]);
}
xfree(scopeList);
}
/**
* Read a LICENSE_REQUEST packet.\n
* @msdn{cc241914}
* @param rdp RDP module
* @param license license module
* @param s stream
*/
@ -145,22 +353,22 @@ void license_read_license_request_packet(rdpLicense* license, STREAM* s)
stream_read(s, license->server_random, 32);
/* ProductInfo */
license_read_product_info(s, &(license->product_info));
license_read_product_info(s, license->product_info);
/* KeyExchangeList */
license_read_binary_blob(s, &(license->key_exchange_list));
license_read_binary_blob(s, license->key_exchange_list);
/* ServerCertificate */
license_read_binary_blob(s, &(license->server_certificate));
license_read_binary_blob(s, license->server_certificate);
/* ScopeList */
license_read_scope_list(s, &(license->scope_list));
license_read_scope_list(s, license->scope_list);
}
/**
* Read a PLATFORM_CHALLENGE packet.\n
* @msdn{cc241921}
* @param rdp RDP module
* @param license license module
* @param s stream
*/
@ -172,7 +380,7 @@ void license_read_platform_challenge_packet(rdpLicense* license, STREAM* s)
/**
* Read a NEW_LICENSE packet.\n
* @msdn{cc241926}
* @param rdp RDP module
* @param license license module
* @param s stream
*/
@ -184,7 +392,7 @@ void license_read_new_license_packet(rdpLicense* license, STREAM* s)
/**
* Read an UPGRADE_LICENSE packet.\n
* @msdn{cc241924}
* @param rdp RDP module
* @param license license module
* @param s stream
*/
@ -196,7 +404,7 @@ void license_read_upgrade_license_packet(rdpLicense* license, STREAM* s)
/**
* Read an ERROR_ALERT packet.\n
* @msdn{cc240482}
* @param rdp RDP module
* @param license license module
* @param s stream
*/
@ -205,12 +413,62 @@ void license_read_error_alert_packet(rdpLicense* license, STREAM* s)
}
/**
* Write Platform ID.\n
* @msdn{cc241918}
* @param license license module
* @param s stream
*/
void license_write_platform_id(rdpLicense* license, STREAM* s)
{
stream_write_uint8(s, 0); /* Client Operating System Version */
stream_write_uint8(s, 0); /* Independent Software Vendor (ISV) */
stream_write_uint16(s, 0x0201); /* Client Software Build */
}
/**
* Write a NEW_LICENSE_REQUEST packet.\n
* @msdn{cc241918}
* @param license license module
* @param s stream
*/
void license_write_new_license_request_packet(rdpLicense* license, STREAM* s)
{
stream_write_uint32(s, KEY_EXCHANGE_ALG_RSA); /* PreferredKeyExchangeAlg (4 bytes) */
license_write_platform_id(license, s); /* PlatformId (4 bytes) */
stream_write(s, license->client_random, 32); /* ClientRandom (32 bytes) */
license_write_binary_blob(s, license->encrypted_pre_master_secret); /* EncryptedPreMasterSecret */
license_write_binary_blob(s, license->client_user_name); /* ClientUserName */
license_write_binary_blob(s, license->client_machine_name); /* ClientMachineName */
}
/**
* Send a NEW_LICENSE_REQUEST packet.\n
* @msdn{cc241918}
* @param license license module
*/
void license_send_new_license_request_packet(rdpLicense* license)
{
STREAM* s;
s = license_send_stream_init(license);
/* TODO: generate keys */
license_write_new_license_request_packet(license, s);
license_send(license, s, NEW_LICENSE_REQUEST);
}
/**
* Instantiate new license module.
* @return new license module
*/
rdpLicense* license_new()
rdpLicense* license_new(rdpRdp* rdp)
{
rdpLicense* license;
@ -218,8 +476,14 @@ rdpLicense* license_new()
if (license != NULL)
{
license->key_exchange_list.type = BB_KEY_EXCHG_ALG_BLOB;
license->server_certificate.type = BB_CERTIFICATE_BLOB;
license->rdp = rdp;
license->product_info = license_new_product_info();
license->key_exchange_list = license_new_binary_blob(BB_KEY_EXCHG_ALG_BLOB);
license->server_certificate = license_new_binary_blob(BB_CERTIFICATE_BLOB);
license->encrypted_pre_master_secret = license_new_binary_blob(BB_RANDOM_BLOB);
license->client_user_name = license_new_binary_blob(BB_CLIENT_USER_NAME_BLOB);
license->client_machine_name = license_new_binary_blob(BB_CLIENT_MACHINE_NAME_BLOB);
license->scope_list = license_new_scope_list();
}
return license;
@ -234,6 +498,13 @@ void license_free(rdpLicense* license)
{
if (license != NULL)
{
license_free_product_info(license->product_info);
license_free_binary_blob(license->key_exchange_list);
license_free_binary_blob(license->server_certificate);
license_free_binary_blob(license->encrypted_pre_master_secret);
license_free_binary_blob(license->client_user_name);
license_free_binary_blob(license->client_machine_name);
license_free_scope_list(license->scope_list);
xfree(license);
}
}

View File

@ -41,6 +41,9 @@ typedef struct rdp_license rdpLicense;
#define LICENSE_PKT_SC_MASK (LICENSE_REQUEST | PLATFORM_CHALLENGE | NEW_LICENSE | UPGRADE_LICENSE | ERROR_ALERT)
#define LICENSE_PKT_MASK (LICENSE_PKT_CS_MASK | LICENSE_PKT_SC_MASK)
#define LICENSE_PREAMBLE_LENGTH 4
#define LICENSE_PACKET_HEADER_LENGTH (RDP_PACKET_HEADER_LENGTH + RDP_SECURITY_HEADER_LENGTH + LICENSE_PREAMBLE_LENGTH)
/* Licensing Preamble Flags */
#define PREAMBLE_VERSION_2_0 0x02
#define PREAMBLE_VERSION_3_0 0x03
@ -48,6 +51,7 @@ typedef struct rdp_license rdpLicense;
#define EXTENDED_ERROR_MSG_SUPPORTED 0x80
/* Licensing Binary Blob Types */
#define BB_ANY_BLOB 0x0000
#define BB_DATA_BLOB 0x0001
#define BB_RANDOM_BLOB 0x0002
#define BB_CERTIFICATE_BLOB 0x0003
@ -58,6 +62,7 @@ typedef struct rdp_license rdpLicense;
#define BB_CLIENT_USER_NAME_BLOB 0x000F
#define BB_CLIENT_MACHINE_NAME_BLOB 0x0010
/* Key Exchange Algorithms */
#define KEY_EXCHANGE_ALG_RSA 0x00000001
typedef struct
@ -84,17 +89,34 @@ typedef struct
struct rdp_license
{
struct rdp_rdp* rdp;
uint8 client_random[32];
uint8 server_random[32];
PRODUCT_INFO product_info;
LICENSE_BLOB key_exchange_list;
LICENSE_BLOB server_certificate;
SCOPE_LIST scope_list;
PRODUCT_INFO* product_info;
LICENSE_BLOB* key_exchange_list;
LICENSE_BLOB* server_certificate;
LICENSE_BLOB* client_user_name;
LICENSE_BLOB* client_machine_name;
LICENSE_BLOB* encrypted_pre_master_secret;
SCOPE_LIST* scope_list;
};
void license_recv(rdpLicense* license, STREAM* s, uint16 sec_flags);
void license_send(rdpLicense* license, STREAM* s, uint8 type);
void license_recv(rdpLicense* license, STREAM* s);
STREAM* license_send_stream_init(rdpLicense* license);
PRODUCT_INFO* license_new_product_info();
void license_free_product_info(PRODUCT_INFO* productInfo);
void license_read_product_info(STREAM* s, PRODUCT_INFO* productInfo);
LICENSE_BLOB* license_new_binary_blob(uint16 type);
void license_free_binary_blob(LICENSE_BLOB* blob);
void license_read_binary_blob(STREAM* s, LICENSE_BLOB* blob);
void license_write_binary_blob(STREAM* s, LICENSE_BLOB* blob);
SCOPE_LIST* license_new_scope_list();
void license_free_scope_list(SCOPE_LIST* scopeList);
void license_read_scope_list(STREAM* s, SCOPE_LIST* scopeList);
void license_read_license_request_packet(rdpLicense* license, STREAM* s);
void license_read_platform_challenge_packet(rdpLicense* license, STREAM* s);
@ -102,7 +124,10 @@ void license_read_new_license_packet(rdpLicense* license, STREAM* s);
void license_read_upgrade_license_packet(rdpLicense* license, STREAM* s);
void license_read_error_alert_packet(rdpLicense* license, STREAM* s);
rdpLicense* license_new();
void license_write_new_license_request_packet(rdpLicense* license, STREAM* s);
void license_send_new_license_request_packet(rdpLicense* license);
rdpLicense* license_new(rdpRdp* rdp);
void license_free(rdpLicense* license);
#endif /* __LICENSE_H */

View File

@ -61,6 +61,22 @@ STREAM* rdp_send_stream_init(rdpRdp* rdp)
return s;
}
/**
* Write an RDP packet header.\n
* @param rdp rdp module
* @param s stream
* @param length RDP packet length
*/
void rdp_write_header(rdpRdp* rdp, STREAM* s, int length)
{
mcs_write_domain_mcspdu_header(s, DomainMCSPDU_SendDataRequest, length);
per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */
per_write_integer16(s, MCS_GLOBAL_CHANNEL_ID, 0); /* channelId */
stream_write_uint8(s, 0x70); /* dataPriority + segmentation */
per_write_length(s, length - RDP_PACKET_HEADER_LENGTH); /* userData (OCTET_STRING) */
}
/**
* Send an RDP packet.\n
* @param rdp RDP module
@ -74,12 +90,7 @@ void rdp_send(rdpRdp* rdp, STREAM* s)
length = stream_get_length(s);
stream_set_pos(s, 0);
mcs_write_domain_mcspdu_header(s, DomainMCSPDU_SendDataRequest, length);
per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID); /* initiator */
per_write_integer16(s, MCS_GLOBAL_CHANNEL_ID, 0); /* channelId */
stream_write_uint8(s, 0x70); /* dataPriority + segmentation */
per_write_length(s, length - RDP_PACKET_HEADER_LENGTH); /* userData (OCTET_STRING) */
rdp_write_header(rdp, s, length);
stream_set_pos(s, length);
transport_write(rdp->transport, s);
@ -118,11 +129,11 @@ void rdp_recv(rdpRdp* rdp)
switch (sec_flags & SEC_PKT_MASK)
{
case SEC_LICENSE_PKT:
license_recv(rdp->license, s, sec_flags);
license_recv(rdp->license, s);
break;
case SEC_REDIRECTION_PKT:
rdp_read_redirection_packet(rdp, s, sec_flags);
rdp_read_redirection_packet(rdp, s);
break;
default:
@ -147,7 +158,7 @@ rdpRdp* rdp_new()
{
rdp->settings = settings_new();
rdp->transport = transport_new(rdp->settings);
rdp->license = license_new(rdp->license);
rdp->license = license_new(rdp);
rdp->nego = nego_new(rdp->transport);
rdp->mcs = mcs_new(rdp->transport);
}

View File

@ -51,6 +51,7 @@ typedef struct rdp_rdp rdpRdp;
#define SEC_PKT_SC_MASK (SEC_LICENSE_PKT | SEC_REDIRECTION_PKT)
#define SEC_PKT_MASK (SEC_PKT_CS_MASK | SEC_PKT_SC_MASK)
#define RDP_SECURITY_HEADER_LENGTH 4
#define RDP_PACKET_HEADER_LENGTH (TPDU_DATA_LENGTH + MCS_SEND_DATA_HEADER_LENGTH)
struct rdp_rdp
@ -66,6 +67,7 @@ void rdp_read_security_header(STREAM* s, uint16* flags);
void rdp_write_security_header(STREAM* s, uint16 flags);
STREAM* rdp_send_stream_init(rdpRdp* rdp);
void rdp_write_header(rdpRdp* rdp, STREAM* s, int length);
void rdp_send(rdpRdp* rdp, STREAM* s);
void rdp_recv(rdpRdp* rdp);

View File

@ -27,7 +27,7 @@
* @param sec_flags security flags
*/
void rdp_read_redirection_packet(rdpRdp* rdp, STREAM* s, uint16 sec_flags)
void rdp_read_redirection_packet(rdpRdp* rdp, STREAM* s)
{
printf("SEC_REDIRECTION_PKT\n");
}

View File

@ -25,6 +25,6 @@
#include <freerdp/freerdp.h>
#include <freerdp/utils/stream.h>
void rdp_read_redirection_packet(rdpRdp* rdp, STREAM* s, uint16 sec_flags);
void rdp_read_redirection_packet(rdpRdp* rdp, STREAM* s);
#endif /* __REDIRECTION_H */