Skip to content

Commit

Permalink
WAB-9186: Support multiple RDS (using CAL Per Device).
Browse files Browse the repository at this point in the history
  • Loading branch information
XiaopengZHOU committed Mar 7, 2024
1 parent f8f9bed commit 9b08106
Show file tree
Hide file tree
Showing 11 changed files with 290 additions and 72 deletions.
103 changes: 79 additions & 24 deletions src/acl/file_system_license_store.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,61 @@ class FileSystemLicenseStore : public LicenseApi
{}

// The functions shall return empty bytes_view to indicate the error.
bytes_view get_license(char const* client_name, uint32_t version, char const* scope, char const* company_name, char const* product_id, writable_bytes_view out, bool enable_log) override
bytes_view get_license_v1(char const* client_name, char const* target_ip, uint32_t version, char const* scope, char const* company_name, char const* product_id, std::array<uint8_t, LIC::LICENSE_HWID_SIZE>& hwid, writable_bytes_view out, bool enable_log) override
{
char license_index[2048] = {};
::snprintf(license_index, sizeof(license_index) - 1, "%s_0x%08X_%s_%s_%s", target_ip, version, scope, company_name, product_id);
license_index[sizeof(license_index) - 1] = '\0';
std::replace(std::begin(license_index), std::end(license_index), ' ', '-');
LOG_IF(enable_log, LOG_INFO, "FileSystemLicenseStore::get_license_v1(): LicenseIndex=\"%s\"", license_index);

char filename[4096] = {};
::snprintf(filename, sizeof(filename) - 1, "%s/%s/%s",
license_path.c_str(), client_name, license_index);
filename[sizeof(filename) - 1] = '\0';

if (unique_fd ufd{::open(filename, O_RDONLY)}) {
size_t number_of_bytes_read = ::read(ufd.fd(), hwid.data(), hwid.size());
if (number_of_bytes_read != sizeof(hwid)) {
LOG(LOG_ERR, "FileSystemLicenseStore::get_license_v1: license file truncated (1) : expected %zu, got %zu", sizeof(hwid), number_of_bytes_read);
}
else {
uint32_t license_size = 0;
number_of_bytes_read = ::read(ufd.fd(), &license_size, sizeof(license_size));
if (number_of_bytes_read != sizeof(license_size)) {
LOG(LOG_ERR, "FileSystemLicenseStore::get_license_v1: license file truncated (2) : expected %zu, got %zu", sizeof(license_size), number_of_bytes_read);
}
else {
if (out.size() >= license_size)
{
number_of_bytes_read = ::read(ufd.fd(), out.data(), license_size);
if (number_of_bytes_read != license_size) {
LOG(LOG_ERR, "FileSystemLicenseStore::get_license_v1: license file truncated (3) : expected %u, got %zu", license_size, number_of_bytes_read);
}
else {
LOG(LOG_INFO, "FileSystemLicenseStore::get_license_v1: LicenseSize=%u", license_size);

return bytes_view { out.data(), license_size };
}
}
}
}
}
else {
LOG(LOG_WARNING, "FileSystemLicenseStore::get_license_v1: Failed to open license file! Path=\"%s\" errno=%s(%d)", filename, strerror(errno), errno);
}

return bytes_view { out.data(), 0 };
}

// The functions shall return empty bytes_view to indicate the error.
bytes_view get_license_v0(char const* client_name, uint32_t version, char const* scope, char const* company_name, char const* product_id, writable_bytes_view out, bool enable_log) override
{
char license_index[2048] = {};
::snprintf(license_index, sizeof(license_index) - 1, "0x%08X_%s_%s_%s", version, scope, company_name, product_id);
license_index[sizeof(license_index) - 1] = '\0';
std::replace(std::begin(license_index), std::end(license_index), ' ', '-');
LOG_IF(enable_log, LOG_INFO, "FileSystemLicenseStore::get_license(): LicenseIndex=\"%s\"", license_index);
LOG_IF(enable_log, LOG_INFO, "FileSystemLicenseStore::get_license_v0(): LicenseIndex=\"%s\"", license_index);

char filename[4096] = {};
::snprintf(filename, sizeof(filename) - 1, "%s/%s/%s",
Expand All @@ -56,34 +104,34 @@ class FileSystemLicenseStore : public LicenseApi
uint32_t license_size = 0;
size_t number_of_bytes_read = ::read(ufd.fd(), &license_size, sizeof(license_size));
if (number_of_bytes_read != sizeof(license_size)) {
LOG(LOG_ERR, "FileSystemLicenseStore::get_license: license file truncated (1) : expected %zu, got %zu", sizeof(license_size), number_of_bytes_read);
LOG(LOG_ERR, "FileSystemLicenseStore::get_license_v0: license file truncated (1) : expected %zu, got %zu", sizeof(license_size), number_of_bytes_read);
}
else {
if (out.size() >= license_size)
{
number_of_bytes_read = ::read(ufd.fd(), out.data(), license_size);
if (number_of_bytes_read != license_size) {
LOG(LOG_ERR, "FileSystemLicenseStore::get_license: license file truncated (2) : expected %u, got %zu", license_size, number_of_bytes_read);
LOG(LOG_ERR, "FileSystemLicenseStore::get_license_v0: license file truncated (2) : expected %u, got %zu", license_size, number_of_bytes_read);
}
else {
LOG(LOG_INFO, "FileSystemLicenseStore::get_license: LicenseSize=%u", license_size);
LOG(LOG_INFO, "FileSystemLicenseStore::get_license_v0: LicenseSize=%u", license_size);

return bytes_view { out.data(), license_size };
}
}
}
}
else {
LOG(LOG_WARNING, "FileSystemLicenseStore::get_license: Failed to open license file! Path=\"%s\" errno=%s(%d)", filename, strerror(errno), errno);
LOG(LOG_WARNING, "FileSystemLicenseStore::get_license_v0: Failed to open license file! Path=\"%s\" errno=%s(%d)", filename, strerror(errno), errno);
}

return bytes_view { out.data(), 0 };
}

bool put_license(char const* client_name, uint32_t version, char const* scope, char const* company_name, char const* product_id, bytes_view in, bool enable_log) override
bool put_license(char const* client_name, char const* target_ip, uint32_t version, char const* scope, char const* company_name, char const* product_id, std::array<uint8_t, LIC::LICENSE_HWID_SIZE> const& hwid, bytes_view in, bool enable_log) override
{
char license_index[2048] = {};
::snprintf(license_index, sizeof(license_index) - 1, "0x%08X_%s_%s_%s", version, scope, company_name, product_id);
::snprintf(license_index, sizeof(license_index) - 1, "%s_0x%08X_%s_%s_%s", target_ip, version, scope, company_name, product_id);
license_index[sizeof(license_index) - 1] = '\0';
std::replace_if(std::begin(license_index), std::end(license_index),
[](unsigned char c) { return (' ' == c); }, '-');
Expand Down Expand Up @@ -112,31 +160,38 @@ class FileSystemLicenseStore : public LicenseApi
if (fd != -1) {
unique_fd ufd{fd};
uint32_t const license_size = in.size();
if (sizeof(license_size) == ::write(ufd.fd(), &license_size, sizeof(license_size))) {
if (license_size == ::write(ufd.fd(), in.data(), in.size())) {
char filename[6145] = {};
::snprintf(filename, sizeof(filename) - 1, "%s/%s", license_dir_path, license_index);
filename[sizeof(filename) - 1] = '\0';

if (::rename(filename_temporary, filename) == 0) {
return true;
if (hwid.size() == ::write(ufd.fd(), hwid.data(), hwid.size())) {
if (sizeof(license_size) == ::write(ufd.fd(), &license_size, sizeof(license_size))) {
if (license_size == ::write(ufd.fd(), in.data(), in.size())) {
char filename[6145] = {};
::snprintf(filename, sizeof(filename) - 1, "%s/%s", license_dir_path, license_index);
filename[sizeof(filename) - 1] = '\0';

if (::rename(filename_temporary, filename) == 0) {
return true;
}

LOG( LOG_ERR
, "FileSystemLicenseStore::put_license: failed to rename the (temporary) license file! "
"temporary_filename=\"%s\" filename=\"%s\" errno=%s(%d)"
, filename_temporary, filename, strerror(errno), errno);
::unlink(filename_temporary);
}
else {
LOG( LOG_ERR
, "FileSystemLicenseStore::put_license: Failed to write (temporary) license file (1)! filename=\"%s\" errno=%s(%d)"
, filename_temporary, strerror(errno), errno);
}

LOG( LOG_ERR
, "FileSystemLicenseStore::put_license: failed to rename the (temporary) license file! "
"temporary_filename=\"%s\" filename=\"%s\" errno=%s(%d)"
, filename_temporary, filename, strerror(errno), errno);
::unlink(filename_temporary);
}
else {
LOG( LOG_ERR
, "FileSystemLicenseStore::put_license: Failed to write (temporary) license file (1)! filename=\"%s\" errno=%s(%d)"
, "FileSystemLicenseStore::put_license: Failed to write (temporary) license file (2)! filename=\"%s\" errno=%s(%d)"
, filename_temporary, strerror(errno), errno);
}
}
else {
LOG( LOG_ERR
, "FileSystemLicenseStore::put_license: Failed to write (temporary) license file (2)! filename=\"%s\" errno=%s(%d)"
, "FileSystemLicenseStore::put_license: Failed to write (temporary) license file (3)! filename=\"%s\" errno=%s(%d)"
, filename_temporary, strerror(errno), errno);
}
}
Expand Down
42 changes: 34 additions & 8 deletions src/acl/license_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#pragma once

#include "core/RDP/lic.hpp"
#include "utils/sugar/bytes_view.hpp"
#include "utils/sugar/noncopyable.hpp"

Expand All @@ -28,17 +29,40 @@ struct LicenseApi : noncopyable
virtual ~LicenseApi() = default;

// The functions shall return empty bytes_view to indicate the error.
virtual bytes_view get_license(char const* client_name, uint32_t version, char const* scope, char const* company_name,
char const* product_id, writable_bytes_view out, bool enable_log) = 0;
virtual bytes_view get_license_v1(char const* client_name, char const* target_ip, uint32_t version, char const* scope,
char const* company_name, char const* product_id, std::array<uint8_t, LIC::LICENSE_HWID_SIZE>& hwid, writable_bytes_view out,
bool enable_log) = 0;

virtual bool put_license(char const* client_name, uint32_t version, char const* scope, char const* company_name,
char const* product_id, bytes_view in, bool enable_log) = 0;
// The functions shall return empty bytes_view to indicate the error.
virtual bytes_view get_license_v0(char const* client_name, uint32_t version, char const* scope,
char const* company_name, char const* product_id, writable_bytes_view out,
bool enable_log) = 0;

virtual bool put_license(char const* client_name, char const* target_ip, uint32_t version, char const* scope, char const* company_name,
char const* product_id, std::array<uint8_t, LIC::LICENSE_HWID_SIZE> const& hwid, bytes_view in, bool enable_log) = 0;
};

struct NullLicenseStore : LicenseApi
{
bytes_view get_license(char const* client_name, uint32_t version, char const* scope, char const* company_name,
char const* product_id, writable_bytes_view out, bool enable_log) override
bytes_view get_license_v1(char const* client_name, char const* target_ip, uint32_t version, char const* scope,
char const* company_name, char const* product_id, std::array<uint8_t, LIC::LICENSE_HWID_SIZE>& hwid, writable_bytes_view out,
bool enable_log) override
{
(void)client_name;
(void)target_ip;
(void)version;
(void)scope;
(void)company_name;
(void)product_id;
(void)hwid;
(void)enable_log;

return bytes_view(out.data(), 0);
}

bytes_view get_license_v0(char const* client_name, uint32_t version, char const* scope,
char const* company_name, char const* product_id, writable_bytes_view out,
bool enable_log) override
{
(void)client_name;
(void)version;
Expand All @@ -50,14 +74,16 @@ struct NullLicenseStore : LicenseApi
return bytes_view(out.data(), 0);
}

bool put_license(char const* client_name, uint32_t version, char const* scope, char const* company_name,
char const* product_id, bytes_view in, bool enable_log) override
bool put_license(char const* client_name, char const* target_ip, uint32_t version, char const* scope, char const* company_name,
char const* product_id, std::array<uint8_t, LIC::LICENSE_HWID_SIZE> const& hwid, bytes_view in, bool enable_log) override
{
(void)client_name;
(void)target_ip;
(void)version;
(void)scope;
(void)company_name;
(void)product_id;
(void)hwid;
(void)in;
(void)enable_log;

Expand Down
1 change: 1 addition & 0 deletions src/acl/module_manager/create_module_rdp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ ModPack create_mod_rdp(
mod_rdp_params.replace_null_pointer_by_default_pointer = ini.get<cfg::mod_rdp::replace_null_pointer_by_default_pointer>();
mod_rdp_params.large_pointer_support = ini.get<cfg::globals::large_pointer_support>();
mod_rdp_params.load_balance_info = ini.get<cfg::mod_rdp::load_balance_info>().c_str();
mod_rdp_params.target_ip = ini.get<cfg::context::ip_target>().c_str();

// ======================= File System Params ===================
{
Expand Down
2 changes: 2 additions & 0 deletions src/core/RDP/lic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
#include "core/error.hpp"
#include "system/ssl_rc4.hpp"

#include <vector>


// Sent by server:
// 0x01 LICENSE_REQUEST Indicates a License Request PDU ([MS-RDPELE] section 2.2.2.1).
Expand Down
Loading

0 comments on commit 9b08106

Please sign in to comment.