Refactored licensing module

* Make the whole module opaque for easier testing
This commit is contained in:
akallabeth 2022-10-06 11:32:08 +02:00 committed by akallabeth
parent d171f4a1d5
commit 7d67adbc54
10 changed files with 1555 additions and 468 deletions

View File

@ -3,6 +3,8 @@
* Licensing API * Licensing API
* *
* Copyright 2018 David Fort <contact@hardening-consulting.com> * Copyright 2018 David Fort <contact@hardening-consulting.com>
* Copyright 2022 Armin Novak <armin.novak@thincast.com>
* Copyright 2022 Thincast Technologies GmbH
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,142 +23,39 @@
#define FREERDP_LICENSE_H #define FREERDP_LICENSE_H
#include <freerdp/api.h> #include <freerdp/api.h>
#include <freerdp/freerdp.h>
typedef struct rdp_license rdpLicense; #ifdef __cplusplus
/** @brief Licensing Packet Types */
enum
{
LICENSE_REQUEST = 0x01,
PLATFORM_CHALLENGE = 0x02,
NEW_LICENSE = 0x03,
UPGRADE_LICENSE = 0x04,
LICENSE_INFO = 0x12,
NEW_LICENSE_REQUEST = 0x13,
PLATFORM_CHALLENGE_RESPONSE = 0x15,
ERROR_ALERT = 0xFF
};
#define LICENSE_PKT_CS_MASK \
(LICENSE_INFO | NEW_LICENSE_REQUEST | PLATFORM_CHALLENGE_RESPONSE | ERROR_ALERT)
#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
/* Cryptographic Lengths */
#define CLIENT_RANDOM_LENGTH 32
#define SERVER_RANDOM_LENGTH 32
#define MASTER_SECRET_LENGTH 48
#define PREMASTER_SECRET_LENGTH 48
#define SESSION_KEY_BLOB_LENGTH 48
#define MAC_SALT_KEY_LENGTH 16
#define LICENSING_ENCRYPTION_KEY_LENGTH 16
#define HWID_PLATFORM_ID_LENGTH 4
#define HWID_UNIQUE_DATA_LENGTH 16
#define HWID_LENGTH 20
#define LICENSING_PADDING_SIZE 8
/* Preamble Flags */
#define PREAMBLE_VERSION_2_0 0x02
#define PREAMBLE_VERSION_3_0 0x03
#define LicenseProtocolVersionMask 0x0F
#define EXTENDED_ERROR_MSG_SUPPORTED 0x80
/** @brief binary Blob Types */
enum
{
BB_ANY_BLOB = 0x0000,
BB_DATA_BLOB = 0x0001,
BB_RANDOM_BLOB = 0x0002,
BB_CERTIFICATE_BLOB = 0x0003,
BB_ERROR_BLOB = 0x0004,
BB_ENCRYPTED_DATA_BLOB = 0x0009,
BB_KEY_EXCHG_ALG_BLOB = 0x000D,
BB_SCOPE_BLOB = 0x000E,
BB_CLIENT_USER_NAME_BLOB = 0x000F,
BB_CLIENT_MACHINE_NAME_BLOB = 0x0010
};
/* License Key Exchange Algorithms */
#define KEY_EXCHANGE_ALG_RSA 0x00000001
/** @brief license Error Codes */
enum
{
ERR_INVALID_SERVER_CERTIFICATE = 0x00000001,
ERR_NO_LICENSE = 0x00000002,
ERR_INVALID_MAC = 0x00000003,
ERR_INVALID_SCOPE = 0x00000004,
ERR_NO_LICENSE_SERVER = 0x00000006,
STATUS_VALID_CLIENT = 0x00000007,
ERR_INVALID_CLIENT = 0x00000008,
ERR_INVALID_PRODUCT_ID = 0x0000000B,
ERR_INVALID_MESSAGE_LENGTH = 0x0000000C
};
/** @brief state Transition Codes */
enum
{
ST_TOTAL_ABORT = 0x00000001,
ST_NO_TRANSITION = 0x00000002,
ST_RESET_PHASE_TO_START = 0x00000003,
ST_RESEND_LAST_MESSAGE = 0x00000004
};
/** @brief Platform Challenge Types */
enum
{
WIN32_PLATFORM_CHALLENGE_TYPE = 0x0100,
WIN16_PLATFORM_CHALLENGE_TYPE = 0x0200,
WINCE_PLATFORM_CHALLENGE_TYPE = 0x0300,
OTHER_PLATFORM_CHALLENGE_TYPE = 0xFF00
};
/** @brief License Detail Levels */
enum
{
LICENSE_DETAIL_SIMPLE = 0x0001,
LICENSE_DETAIL_MODERATE = 0x0002,
LICENSE_DETAIL_DETAIL = 0x0003
};
/*
* PlatformId:
*
* The most significant byte of the PlatformId field contains the operating system version of the
* client. The second most significant byte of the PlatformId field identifies the ISV that provided
* the client image. The remaining two bytes in the PlatformId field are used by the ISV to identify
* the build number of the operating system.
*
* 0x04010000:
*
* CLIENT_OS_ID_WINNT_POST_52 (0x04000000)
* CLIENT_IMAGE_ID_MICROSOFT (0x00010000)
*/
enum
{
CLIENT_OS_ID_WINNT_351 = 0x01000000,
CLIENT_OS_ID_WINNT_40 = 0x02000000,
CLIENT_OS_ID_WINNT_50 = 0x03000000,
CLIENT_OS_ID_WINNT_POST_52 = 0x04000000,
CLIENT_IMAGE_ID_MICROSOFT = 0x00010000,
CLIENT_IMAGE_ID_CITRIX = 0x00020000,
};
#ifdef __cpluscplus
extern "C" extern "C"
{ {
#endif #endif
FREERDP_API BOOL license_send_valid_client_error_packet(rdpRdp* rdp); typedef enum
{
LICENSE_STATE_INITIAL,
LICENSE_STATE_CONFIGURED,
LICENSE_STATE_REQUEST,
LICENSE_STATE_NEW_REQUEST,
LICENSE_STATE_PLATFORM_CHALLENGE,
LICENSE_STATE_PLATFORM_CHALLENGE_RESPONSE,
LICENSE_STATE_COMPLETED,
LICENSE_STATE_ABORTED
} LICENSE_STATE;
#ifdef __cpluscplus typedef enum
{
LICENSE_TYPE_INVALID = 0,
LICENSE_TYPE_NONE,
LICENSE_TYPE_ISSUED
} LICENSE_TYPE;
typedef struct rdp_license rdpLicense;
FREERDP_API rdpLicense* license_get(rdpContext* context);
FREERDP_API LICENSE_STATE license_get_state(const rdpLicense* license);
FREERDP_API LICENSE_TYPE license_get_type(const rdpLicense* license);
#ifdef __cplusplus
} }
#endif #endif

View File

@ -550,6 +550,12 @@ typedef struct
#define FreeRDP_ServerCertificateLength (199) #define FreeRDP_ServerCertificateLength (199)
#define FreeRDP_ClientRandom (200) #define FreeRDP_ClientRandom (200)
#define FreeRDP_ClientRandomLength (201) #define FreeRDP_ClientRandomLength (201)
#define FreeRDP_ServerLicenseRequired (202)
#define FreeRDP_ServerLicenseCompanyName (203)
#define FreeRDP_ServerLicenseProductVersion (204)
#define FreeRDP_ServerLicenseProductName (205)
#define FreeRDP_ServerLicenseProductIssuers (206)
#define FreeRDP_ServerLicenseProductIssuersCount (207)
#define FreeRDP_ChannelCount (256) #define FreeRDP_ChannelCount (256)
#define FreeRDP_ChannelDefArraySize (257) #define FreeRDP_ChannelDefArraySize (257)
#define FreeRDP_ChannelDefArray (258) #define FreeRDP_ChannelDefArray (258)
@ -1003,7 +1009,13 @@ struct rdp_settings
ALIGN64 UINT32 ServerCertificateLength; /* 199 */ ALIGN64 UINT32 ServerCertificateLength; /* 199 */
ALIGN64 BYTE* ClientRandom; /* 200 */ ALIGN64 BYTE* ClientRandom; /* 200 */
ALIGN64 UINT32 ClientRandomLength; /* 201 */ ALIGN64 UINT32 ClientRandomLength; /* 201 */
UINT64 padding0256[256 - 202]; /* 202 */ ALIGN64 BOOL ServerLicenseRequired; /* 202 */
ALIGN64 char* ServerLicenseCompanyName; /* 203 */
ALIGN64 UINT32 ServerLicenseProductVersion; /* 204 */
ALIGN64 char* ServerLicenseProductName; /* 205 */
ALIGN64 char** ServerLicenseProductIssuers; /* 206 */
ALIGN64 UINT32 ServerLicenseProductIssuersCount; /* 207 */
UINT64 padding0256[256 - 208]; /* 208 */
/* Client Network Data */ /* Client Network Data */
ALIGN64 UINT32 ChannelCount; /* 256 */ ALIGN64 UINT32 ChannelCount; /* 256 */
@ -1747,6 +1759,10 @@ extern "C"
FREERDP_API void freerdp_capability_buffer_free(rdpSettings* settings); FREERDP_API void freerdp_capability_buffer_free(rdpSettings* settings);
FREERDP_API BOOL freerdp_capability_buffer_copy(rdpSettings* settings, const rdpSettings* src); FREERDP_API BOOL freerdp_capability_buffer_copy(rdpSettings* settings, const rdpSettings* src);
FREERDP_API void freerdp_server_license_issuers_free(rdpSettings* settings);
FREERDP_API BOOL freerdp_server_license_issuers_copy(rdpSettings* settings, char** addresses,
UINT32 count);
FREERDP_API void freerdp_target_net_addresses_free(rdpSettings* settings); FREERDP_API void freerdp_target_net_addresses_free(rdpSettings* settings);
FREERDP_API BOOL freerdp_target_net_addresses_copy(rdpSettings* settings, char** addresses, FREERDP_API BOOL freerdp_target_net_addresses_copy(rdpSettings* settings, char** addresses,
UINT32 count); UINT32 count);

View File

@ -901,6 +901,43 @@ void freerdp_target_net_addresses_free(rdpSettings* settings)
settings->TargetNetPorts = NULL; settings->TargetNetPorts = NULL;
} }
void freerdp_server_license_issuers_free(rdpSettings* settings)
{
UINT32 x;
WINPR_ASSERT(settings);
if (settings->ServerLicenseProductIssuers)
{
for (x = 0; x < settings->ServerLicenseProductIssuersCount; x++)
free(settings->ServerLicenseProductIssuers[x]);
}
free(settings->ServerLicenseProductIssuers);
settings->ServerLicenseProductIssuers = NULL;
settings->ServerLicenseProductIssuersCount = 0;
}
BOOL freerdp_server_license_issuers_copy(rdpSettings* settings, char** issuers, UINT32 count)
{
UINT32 x;
WINPR_ASSERT(settings);
WINPR_ASSERT(issuers || (count == 0));
if (!freerdp_settings_set_pointer_len(settings, FreeRDP_ServerLicenseProductIssuers, NULL,
count))
return FALSE;
for (x = 0; x < count; x++)
{
char* issuer = _strdup(issuers[x]);
if (!issuer)
return FALSE;
settings->ServerLicenseProductIssuers[x] = issuer;
}
return TRUE;
}
void freerdp_performance_flags_make(rdpSettings* settings) void freerdp_performance_flags_make(rdpSettings* settings)
{ {
UINT32 PerformanceFlags = PERF_FLAG_NONE; UINT32 PerformanceFlags = PERF_FLAG_NONE;
@ -1309,6 +1346,12 @@ BOOL freerdp_settings_set_pointer_len(rdpSettings* settings, size_t id, const vo
return freerdp_settings_set_pointer_len_(settings, FreeRDP_TargetNetAddresses, return freerdp_settings_set_pointer_len_(settings, FreeRDP_TargetNetAddresses,
FreeRDP_TargetNetAddressCount, data, len, FreeRDP_TargetNetAddressCount, data, len,
sizeof(char*)); sizeof(char*));
case FreeRDP_ServerLicenseProductIssuers:
if (data == NULL)
freerdp_server_license_issuers_free(settings);
return freerdp_settings_set_pointer_len_(settings, FreeRDP_ServerLicenseProductIssuers,
FreeRDP_ServerLicenseProductIssuersCount, data,
len, sizeof(char*));
case FreeRDP_TargetNetPorts: case FreeRDP_TargetNetPorts:
if (data == NULL) if (data == NULL)
freerdp_target_net_addresses_free(settings); freerdp_target_net_addresses_free(settings);

View File

@ -435,6 +435,9 @@ BOOL freerdp_settings_get_bool(const rdpSettings* settings, size_t id)
case FreeRDP_SendPreconnectionPdu: case FreeRDP_SendPreconnectionPdu:
return settings->SendPreconnectionPdu; return settings->SendPreconnectionPdu;
case FreeRDP_ServerLicenseRequired:
return settings->ServerLicenseRequired;
case FreeRDP_ServerMode: case FreeRDP_ServerMode:
return settings->ServerMode; return settings->ServerMode;
@ -1111,6 +1114,10 @@ BOOL freerdp_settings_set_bool(rdpSettings* settings, size_t id, BOOL val)
settings->SendPreconnectionPdu = cnv.c; settings->SendPreconnectionPdu = cnv.c;
break; break;
case FreeRDP_ServerLicenseRequired:
settings->ServerLicenseRequired = cnv.c;
break;
case FreeRDP_ServerMode: case FreeRDP_ServerMode:
settings->ServerMode = cnv.c; settings->ServerMode = cnv.c;
break; break;
@ -1745,6 +1752,12 @@ UINT32 freerdp_settings_get_uint32(const rdpSettings* settings, size_t id)
case FreeRDP_ServerCertificateLength: case FreeRDP_ServerCertificateLength:
return settings->ServerCertificateLength; return settings->ServerCertificateLength;
case FreeRDP_ServerLicenseProductIssuersCount:
return settings->ServerLicenseProductIssuersCount;
case FreeRDP_ServerLicenseProductVersion:
return settings->ServerLicenseProductVersion;
case FreeRDP_ServerPort: case FreeRDP_ServerPort:
return settings->ServerPort; return settings->ServerPort;
@ -2223,6 +2236,14 @@ BOOL freerdp_settings_set_uint32(rdpSettings* settings, size_t id, UINT32 val)
settings->ServerCertificateLength = cnv.c; settings->ServerCertificateLength = cnv.c;
break; break;
case FreeRDP_ServerLicenseProductIssuersCount:
settings->ServerLicenseProductIssuersCount = cnv.c;
break;
case FreeRDP_ServerLicenseProductVersion:
settings->ServerLicenseProductVersion = cnv.c;
break;
case FreeRDP_ServerPort: case FreeRDP_ServerPort:
settings->ServerPort = cnv.c; settings->ServerPort = cnv.c;
break; break;
@ -2666,6 +2687,12 @@ const char* freerdp_settings_get_string(const rdpSettings* settings, size_t id)
case FreeRDP_ServerHostname: case FreeRDP_ServerHostname:
return settings->ServerHostname; return settings->ServerHostname;
case FreeRDP_ServerLicenseCompanyName:
return settings->ServerLicenseCompanyName;
case FreeRDP_ServerLicenseProductName:
return settings->ServerLicenseProductName;
case FreeRDP_ShellWorkingDirectory: case FreeRDP_ShellWorkingDirectory:
return settings->ShellWorkingDirectory; return settings->ShellWorkingDirectory;
@ -2941,6 +2968,12 @@ char* freerdp_settings_get_string_writable(rdpSettings* settings, size_t id)
case FreeRDP_ServerHostname: case FreeRDP_ServerHostname:
return settings->ServerHostname; return settings->ServerHostname;
case FreeRDP_ServerLicenseCompanyName:
return settings->ServerLicenseCompanyName;
case FreeRDP_ServerLicenseProductName:
return settings->ServerLicenseProductName;
case FreeRDP_ShellWorkingDirectory: case FreeRDP_ShellWorkingDirectory:
return settings->ShellWorkingDirectory; return settings->ShellWorkingDirectory;
@ -3226,6 +3259,12 @@ BOOL freerdp_settings_set_string_(rdpSettings* settings, size_t id, const char*
case FreeRDP_ServerHostname: case FreeRDP_ServerHostname:
return update_string(&settings->ServerHostname, cnv.cc, len, cleanup); return update_string(&settings->ServerHostname, cnv.cc, len, cleanup);
case FreeRDP_ServerLicenseCompanyName:
return update_string(&settings->ServerLicenseCompanyName, cnv.cc, len, cleanup);
case FreeRDP_ServerLicenseProductName:
return update_string(&settings->ServerLicenseProductName, cnv.cc, len, cleanup);
case FreeRDP_ShellWorkingDirectory: case FreeRDP_ShellWorkingDirectory:
return update_string(&settings->ShellWorkingDirectory, cnv.cc, len, cleanup); return update_string(&settings->ShellWorkingDirectory, cnv.cc, len, cleanup);
@ -3359,6 +3398,9 @@ void* freerdp_settings_get_pointer_writable(rdpSettings* settings, size_t id)
case FreeRDP_ServerCertificate: case FreeRDP_ServerCertificate:
return settings->ServerCertificate; return settings->ServerCertificate;
case FreeRDP_ServerLicenseProductIssuers:
return settings->ServerLicenseProductIssuers;
case FreeRDP_ServerRandom: case FreeRDP_ServerRandom:
return settings->ServerRandom; return settings->ServerRandom;
@ -3487,6 +3529,10 @@ BOOL freerdp_settings_set_pointer(rdpSettings* settings, size_t id, const void*
settings->ServerCertificate = cnv.v; settings->ServerCertificate = cnv.v;
break; break;
case FreeRDP_ServerLicenseProductIssuers:
settings->ServerLicenseProductIssuers = cnv.v;
break;
case FreeRDP_ServerRandom: case FreeRDP_ServerRandom:
settings->ServerRandom = cnv.v; settings->ServerRandom = cnv.v;
break; break;

View File

@ -191,6 +191,7 @@ static const struct settings_str_entry settings_map[] = {
"FreeRDP_RestrictedAdminModeRequired" }, "FreeRDP_RestrictedAdminModeRequired" },
{ FreeRDP_SaltedChecksum, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SaltedChecksum" }, { FreeRDP_SaltedChecksum, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SaltedChecksum" },
{ FreeRDP_SendPreconnectionPdu, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SendPreconnectionPdu" }, { FreeRDP_SendPreconnectionPdu, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SendPreconnectionPdu" },
{ FreeRDP_ServerLicenseRequired, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ServerLicenseRequired" },
{ FreeRDP_ServerMode, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ServerMode" }, { FreeRDP_ServerMode, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_ServerMode" },
{ FreeRDP_SmartSizing, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SmartSizing" }, { FreeRDP_SmartSizing, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SmartSizing" },
{ FreeRDP_SmartcardEmulation, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SmartcardEmulation" }, { FreeRDP_SmartcardEmulation, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_SmartcardEmulation" },
@ -383,6 +384,10 @@ static const struct settings_str_entry settings_map[] = {
{ FreeRDP_SelectedProtocol, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_SelectedProtocol" }, { FreeRDP_SelectedProtocol, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_SelectedProtocol" },
{ FreeRDP_ServerCertificateLength, FREERDP_SETTINGS_TYPE_UINT32, { FreeRDP_ServerCertificateLength, FREERDP_SETTINGS_TYPE_UINT32,
"FreeRDP_ServerCertificateLength" }, "FreeRDP_ServerCertificateLength" },
{ FreeRDP_ServerLicenseProductIssuersCount, FREERDP_SETTINGS_TYPE_UINT32,
"FreeRDP_ServerLicenseProductIssuersCount" },
{ FreeRDP_ServerLicenseProductVersion, FREERDP_SETTINGS_TYPE_UINT32,
"FreeRDP_ServerLicenseProductVersion" },
{ FreeRDP_ServerPort, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ServerPort" }, { FreeRDP_ServerPort, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ServerPort" },
{ FreeRDP_ServerRandomLength, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ServerRandomLength" }, { FreeRDP_ServerRandomLength, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ServerRandomLength" },
{ FreeRDP_ShareId, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ShareId" }, { FreeRDP_ShareId, FREERDP_SETTINGS_TYPE_UINT32, "FreeRDP_ShareId" },
@ -503,6 +508,10 @@ static const struct settings_str_entry settings_map[] = {
{ FreeRDP_RemoteAssistanceSessionId, FREERDP_SETTINGS_TYPE_STRING, { FreeRDP_RemoteAssistanceSessionId, FREERDP_SETTINGS_TYPE_STRING,
"FreeRDP_RemoteAssistanceSessionId" }, "FreeRDP_RemoteAssistanceSessionId" },
{ FreeRDP_ServerHostname, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ServerHostname" }, { FreeRDP_ServerHostname, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_ServerHostname" },
{ FreeRDP_ServerLicenseCompanyName, FREERDP_SETTINGS_TYPE_STRING,
"FreeRDP_ServerLicenseCompanyName" },
{ FreeRDP_ServerLicenseProductName, FREERDP_SETTINGS_TYPE_STRING,
"FreeRDP_ServerLicenseProductName" },
{ FreeRDP_ShellWorkingDirectory, FREERDP_SETTINGS_TYPE_STRING, { FreeRDP_ShellWorkingDirectory, FREERDP_SETTINGS_TYPE_STRING,
"FreeRDP_ShellWorkingDirectory" }, "FreeRDP_ShellWorkingDirectory" },
{ FreeRDP_SmartcardCertificate, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_SmartcardCertificate" }, { FreeRDP_SmartcardCertificate, FREERDP_SETTINGS_TYPE_STRING, "FreeRDP_SmartcardCertificate" },
@ -545,6 +554,8 @@ static const struct settings_str_entry settings_map[] = {
{ FreeRDP_ServerAutoReconnectCookie, FREERDP_SETTINGS_TYPE_POINTER, { FreeRDP_ServerAutoReconnectCookie, FREERDP_SETTINGS_TYPE_POINTER,
"FreeRDP_ServerAutoReconnectCookie" }, "FreeRDP_ServerAutoReconnectCookie" },
{ FreeRDP_ServerCertificate, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_ServerCertificate" }, { FreeRDP_ServerCertificate, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_ServerCertificate" },
{ FreeRDP_ServerLicenseProductIssuers, FREERDP_SETTINGS_TYPE_POINTER,
"FreeRDP_ServerLicenseProductIssuers" },
{ FreeRDP_ServerRandom, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_ServerRandom" }, { FreeRDP_ServerRandom, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_ServerRandom" },
{ FreeRDP_StaticChannelArray, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_StaticChannelArray" }, { FreeRDP_StaticChannelArray, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_StaticChannelArray" },
{ FreeRDP_TargetNetAddresses, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_TargetNetAddresses" }, { FreeRDP_TargetNetAddresses, FREERDP_SETTINGS_TYPE_POINTER, "FreeRDP_TargetNetAddresses" },

View File

@ -1053,23 +1053,40 @@ BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s)
int rdp_client_connect_license(rdpRdp* rdp, wStream* s) int rdp_client_connect_license(rdpRdp* rdp, wStream* s)
{ {
int status; int status;
LICENSE_STATE state;
UINT16 length, channelId, securityFlags;
if (!rdp_read_header(rdp, s, &length, &channelId))
return -1;
if (!rdp_read_security_header(s, &securityFlags, &length))
return -1;
if (securityFlags & SEC_ENCRYPT)
{
if (!rdp_decrypt(rdp, s, &length, securityFlags))
return -1;
}
if ((securityFlags & SEC_LICENSE_PKT) == 0)
return -1;
status = license_recv(rdp->license, s); status = license_recv(rdp->license, s);
if (status < 0) if (status < 0)
return status; return status;
if (rdp->license->state == LICENSE_STATE_ABORTED) state = license_get_state(rdp->license);
switch (state)
{ {
case LICENSE_STATE_ABORTED:
WLog_ERR(TAG, "license connection sequence aborted."); WLog_ERR(TAG, "license connection sequence aborted.");
return -1; return -1;
} case LICENSE_STATE_COMPLETED:
if (rdp->license->state == LICENSE_STATE_COMPLETED)
{
rdp_client_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE); rdp_client_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);
}
return 0; return 0;
default:
return 0;
}
} }
int rdp_client_connect_demand_active(rdpRdp* rdp, wStream* s) int rdp_client_connect_demand_active(rdpRdp* rdp, wStream* s)

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,8 @@
* RDP Licensing * RDP Licensing
* *
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2022 Armin Novak <armin.novak@thincast.com>
* Copyright 2022 Thincast Technologies GmbH
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,17 +24,16 @@
#include "rdp.h" #include "rdp.h"
#include <freerdp/license.h>
#include <freerdp/crypto/crypto.h> #include <freerdp/crypto/crypto.h>
#include <freerdp/crypto/certificate.h> #include <freerdp/crypto/certificate.h>
#include <freerdp/freerdp.h>
#include <freerdp/log.h> #include <freerdp/log.h>
#include <freerdp/api.h>
#include <freerdp/license.h> #include <freerdp/license.h>
#include <winpr/stream.h> #include <winpr/stream.h>
#define CLIENT_RANDOM_LENGTH 32
typedef struct typedef struct
{ {
UINT32 dwVersion; UINT32 dwVersion;
@ -52,56 +53,23 @@ typedef struct
typedef struct typedef struct
{ {
UINT32 count; UINT32 count;
LICENSE_BLOB* array; LICENSE_BLOB** array;
} SCOPE_LIST; } SCOPE_LIST;
typedef enum FREERDP_LOCAL BOOL license_send_valid_client_error_packet(rdpRdp* rdp);
{
LICENSE_STATE_AWAIT,
LICENSE_STATE_PROCESS,
LICENSE_STATE_ABORTED,
LICENSE_STATE_COMPLETED
} LICENSE_STATE;
struct rdp_license
{
LICENSE_STATE state;
rdpRdp* rdp;
rdpCertificate* certificate;
BYTE* Modulus;
UINT32 ModulusLength;
BYTE Exponent[4];
BYTE HardwareId[HWID_LENGTH];
BYTE ClientRandom[CLIENT_RANDOM_LENGTH];
BYTE ServerRandom[SERVER_RANDOM_LENGTH];
BYTE MasterSecret[MASTER_SECRET_LENGTH];
BYTE PremasterSecret[PREMASTER_SECRET_LENGTH];
BYTE SessionKeyBlob[SESSION_KEY_BLOB_LENGTH];
BYTE MacSaltKey[MAC_SALT_KEY_LENGTH];
BYTE LicensingEncryptionKey[LICENSING_ENCRYPTION_KEY_LENGTH];
LICENSE_PRODUCT_INFO* ProductInfo;
LICENSE_BLOB* ErrorInfo;
LICENSE_BLOB* KeyExchangeList;
LICENSE_BLOB* ServerCertificate;
LICENSE_BLOB* ClientUserName;
LICENSE_BLOB* ClientMachineName;
LICENSE_BLOB* PlatformChallenge;
LICENSE_BLOB* EncryptedPremasterSecret;
LICENSE_BLOB* EncryptedPlatformChallenge;
LICENSE_BLOB* EncryptedPlatformChallengeResponse;
LICENSE_BLOB* EncryptedHardwareId;
SCOPE_LIST* ScopeList;
UINT32 PacketHeaderLength;
};
FREERDP_LOCAL int license_recv(rdpLicense* license, wStream* s); FREERDP_LOCAL int license_recv(rdpLicense* license, wStream* s);
/* the configuration is applied from settings. Set FreeRDP_ServerLicense* settings */
FREERDP_LOCAL BOOL license_server_configure(rdpLicense* license);
FREERDP_LOCAL BOOL license_server_send_request(rdpLicense* license);
FREERDP_LOCAL rdpLicense* license_new(rdpRdp* rdp); FREERDP_LOCAL rdpLicense* license_new(rdpRdp* rdp);
FREERDP_LOCAL void license_free(rdpLicense* license); FREERDP_LOCAL void license_free(rdpLicense* license);
#define LICENSE_TAG FREERDP_TAG("core.license") #define LICENSE_TAG FREERDP_TAG("core.license")
#ifdef WITH_DEBUG_LICENSE #ifdef WITH_DEBUG_LICENSE
#define DEBUG_LICENSE(...) WLog_DBG(LICENSE_TAG, __VA_ARGS__) #define DEBUG_LICENSE(...) WLog_INFO(LICENSE_TAG, __VA_ARGS__)
#else #else
#define DEBUG_LICENSE(...) \ #define DEBUG_LICENSE(...) \
do \ do \

View File

@ -454,6 +454,7 @@ static BOOL check_key_helpers(size_t key, const char* stype)
FreeRDP_ServerCertificate, FreeRDP_ServerCertificate,
FreeRDP_TargetNetAddresses, FreeRDP_TargetNetAddresses,
FreeRDP_ReceivedCapabilities, FreeRDP_ReceivedCapabilities,
FreeRDP_ServerLicenseProductIssuers,
FreeRDP_TargetNetPorts, FreeRDP_TargetNetPorts,
FreeRDP_DeviceArray, FreeRDP_DeviceArray,
FreeRDP_ChannelDefArray, FreeRDP_ChannelDefArray,

View File

@ -137,6 +137,7 @@ static const size_t bool_list_indices[] = {
FreeRDP_RestrictedAdminModeRequired, FreeRDP_RestrictedAdminModeRequired,
FreeRDP_SaltedChecksum, FreeRDP_SaltedChecksum,
FreeRDP_SendPreconnectionPdu, FreeRDP_SendPreconnectionPdu,
FreeRDP_ServerLicenseRequired,
FreeRDP_ServerMode, FreeRDP_ServerMode,
FreeRDP_SmartSizing, FreeRDP_SmartSizing,
FreeRDP_SmartcardEmulation, FreeRDP_SmartcardEmulation,
@ -297,6 +298,8 @@ static const size_t uint32_list_indices[] = {
FreeRDP_RequestedProtocols, FreeRDP_RequestedProtocols,
FreeRDP_SelectedProtocol, FreeRDP_SelectedProtocol,
FreeRDP_ServerCertificateLength, FreeRDP_ServerCertificateLength,
FreeRDP_ServerLicenseProductIssuersCount,
FreeRDP_ServerLicenseProductVersion,
FreeRDP_ServerPort, FreeRDP_ServerPort,
FreeRDP_ServerRandomLength, FreeRDP_ServerRandomLength,
FreeRDP_ShareId, FreeRDP_ShareId,
@ -404,6 +407,8 @@ static const size_t string_list_indices[] = {
FreeRDP_RemoteAssistanceRCTicket, FreeRDP_RemoteAssistanceRCTicket,
FreeRDP_RemoteAssistanceSessionId, FreeRDP_RemoteAssistanceSessionId,
FreeRDP_ServerHostname, FreeRDP_ServerHostname,
FreeRDP_ServerLicenseCompanyName,
FreeRDP_ServerLicenseProductName,
FreeRDP_ShellWorkingDirectory, FreeRDP_ShellWorkingDirectory,
FreeRDP_SmartcardCertificate, FreeRDP_SmartcardCertificate,
FreeRDP_SmartcardPrivateKey, FreeRDP_SmartcardPrivateKey,
@ -443,6 +448,7 @@ static const size_t pointer_list_indices[] = {
FreeRDP_RedirectionTsvUrl, FreeRDP_RedirectionTsvUrl,
FreeRDP_ServerAutoReconnectCookie, FreeRDP_ServerAutoReconnectCookie,
FreeRDP_ServerCertificate, FreeRDP_ServerCertificate,
FreeRDP_ServerLicenseProductIssuers,
FreeRDP_ServerRandom, FreeRDP_ServerRandom,
FreeRDP_StaticChannelArray, FreeRDP_StaticChannelArray,
FreeRDP_TargetNetAddresses, FreeRDP_TargetNetAddresses,