Files
rpc/commands.cpp
2021-03-31 11:26:27 -07:00

489 lines
13 KiB
C++

/*********************************************************************
* Copyright (c) Intel Corporation 2019 - 2020
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/
#include "commands.h"
#include <string>
#include "port.h"
#include "utils.h"
#ifndef _WIN32
#include <string.h>
#endif
extern "C" {
#ifndef _WIN32
#include "HECILinux.h"
#endif
#include "PTHICommand.h"
#ifdef bool
#undef bool
#endif
}
#include "version.h"
bool cmd_is_admin()
{
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
return true;
}
bool cmd_get_version(std::string& version)
{
version = "14.0.0"; // FIXME: REMOVE WHEN HW AVAILABLE
return true; // FIXME: REMOVE WHEN HW AVAILABLE
version.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get code version
CODE_VERSIONS codeVersion;
AMT_STATUS status = pthi_GetCodeVersions(&codeVersion);
// additional versions
if (status == 0)
{
for (int i = 0; i < (int) codeVersion.VersionsCount; i++)
{
if (strcmp((char*)(codeVersion.Versions[i].Description.String), "AMT") == 0)
{
version = ((char*)codeVersion.Versions[i].Version.String);
return true;
}
}
}
return false;
}
bool cmd_get_build_number(std::string& version)
{
version.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get code version
CODE_VERSIONS codeVersion;
AMT_STATUS status = pthi_GetCodeVersions(&codeVersion);
// additional versions
if (status == 0)
{
for (int i = 0; i < (int) codeVersion.VersionsCount; i++)
{
if (strcmp((char*)(codeVersion.Versions[i].Description.String), "Build Number") == 0)
{
version = ((char*)codeVersion.Versions[i].Version.String);
return true;
}
}
}
return false;
}
bool cmd_get_sku(std::string& version)
{
version.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get code version
CODE_VERSIONS codeVersion;
AMT_STATUS status = pthi_GetCodeVersions(&codeVersion);
// additional versions
if (status == 0)
{
for (int i = 0; i < (int) codeVersion.VersionsCount; i++)
{
if (strcmp((char*)(codeVersion.Versions[i].Description.String), "Sku") == 0)
{
version = ((char*)codeVersion.Versions[i].Version.String);
return true;
}
}
}
return false;
}
bool cmd_get_uuid(std::vector<unsigned char>& uuid)
{
uuid.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get UUID
AMT_UUID amt_uuid;
AMT_STATUS amt_status = pthi_GetUUID(&amt_uuid);
if (amt_status == 0)
{
for (int i = 0; i < 16; i++)
{
uuid.push_back(amt_uuid[i]);
}
return true;
}
return false;
}
bool cmd_get_local_system_account(std::string& username, std::string& password)
{
username.clear();
password.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get Local System Account
LOCAL_SYSTEM_ACCOUNT local_system_account;
AMT_STATUS amt_status = pthi_GetLocalSystemAccount(&local_system_account);
if (amt_status == 0)
{
username = local_system_account.username;
password = local_system_account.password;
return true;
}
return false;
}
bool cmd_get_control_mode(int& mode)
{
mode = 0;
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get Control Mode
int controlMode;
AMT_STATUS amt_status = pthi_GetControlMode(&controlMode);
if (amt_status == 0)
{
mode = controlMode;
return true;
}
return false;
}
bool cmd_get_fqdn(fqdn_settings& fqdn_settings)
{
fqdn_settings.fqdn.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get fqdn
CFG_GET_FQDN_RESPONSE fqdn;
memset(&fqdn, 0, sizeof(CFG_GET_FQDN_RESPONSE));
AMT_STATUS amt_status = pthi_GetHostFQDN(&fqdn);
if (amt_status == 0)
{
fqdn_settings.ddns_ttl = fqdn.DDNSTTL;
fqdn_settings.ddns_update_enabled = fqdn.DDNSUpdateEnabled;
fqdn_settings.ddns_update_interval = fqdn.DDNSPeriodicUpdateInterval;
if (fqdn.FQDN.Length > 0)
{
fqdn_settings.fqdn = std::string(fqdn.FQDN.Buffer, fqdn.FQDN.Length);
free(fqdn.FQDN.Buffer);
}
return true;
}
return false;
}
bool cmd_get_dns_suffix(std::string& suffix)
{
suffix.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get DNS according to AMT
AMT_ANSI_STRING amt_dns_suffix;
AMT_STATUS amt_status = pthi_GetDnsSuffix(&amt_dns_suffix);
if (amt_status == 0)
{
if (amt_dns_suffix.Buffer != NULL)
{
std::string tmp(amt_dns_suffix.Buffer, amt_dns_suffix.Length);
suffix = tmp;
free(amt_dns_suffix.Buffer);
}
return true;
}
return false;
}
bool cmd_get_wired_mac_address(std::vector<unsigned char>& address)
{
address.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get wired interface
LAN_SETTINGS lan_settings;
UINT32 interface_settings = 0; // wired=0, wireless=1
AMT_STATUS amt_status = pthi_GetLanInterfaceSettings(interface_settings, &lan_settings);
if (amt_status == 0)
{
if (!lan_settings.Enabled)
{
return false;
}
for (int i = 0; i < 6; i++)
{
address.push_back(lan_settings.MacAddress[i]);
}
return true;
}
return false;
}
bool cmd_get_certificate_hashes(std::vector<cert_hash_entry>& hash_entries)
{
hash_entries.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get the hash handles
AMT_HASH_HANDLES amt_hash_handles;
CERTHASH_ENTRY certhash_entry;
memset(&amt_hash_handles, 0, sizeof(AMT_HASH_HANDLES));
if (pthi_EnumerateHashHandles(&amt_hash_handles) == 0)
{
for (int i = 0; i < (int) amt_hash_handles.Length; i++)
{
// get each entry
AMT_STATUS status = pthi_GetCertificateHashEntry(amt_hash_handles.Handles[i], &certhash_entry);
int hashSize;
cert_hash_entry tmp;
switch (certhash_entry.HashAlgorithm) {
case 0: // MD5
hashSize = 16;
tmp.algorithm = "MD5";
break;
case 1: // SHA1
hashSize = 20;
tmp.algorithm = "SHA1";
break;
case 2: // SHA256
hashSize = 32;
tmp.algorithm = "SHA256";
break;
case 3: // SHA512
hashSize = 64;
tmp.algorithm = "SHA512";
break;
default:
hashSize = 0;
tmp.algorithm = "UNKNOWN";
break;
}
if (certhash_entry.IsActive == 1)
{
std::string cert_name(certhash_entry.Name.Buffer, certhash_entry.Name.Length);
tmp.name = cert_name;
tmp.is_default = certhash_entry.IsDefault;
tmp.is_active = certhash_entry.IsActive;
std::string hashString;
for (int i = 0; i < hashSize; i++)
{
char hex[10];
snprintf(hex, 10, "%02x", certhash_entry.CertificateHash[i]);
hashString += hex;
}
tmp.hash = hashString;
hash_entries.push_back(tmp);
}
}
return true;
}
return false;
}
bool cmd_get_remote_access_connection_status(int& network_status, int& remote_status, int& remote_trigger, std::string& mps_hostname)
{
network_status = 0;
remote_status = 0;
remote_trigger = 0;
mps_hostname = "";
const int MPS_SERVER_MAXLENGTH = 256;
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get DNS according to AMT
REMOTE_ACCESS_STATUS remote_access_connection_status;
AMT_STATUS amt_status = pthi_GetRemoteAccessConnectionStatus(&remote_access_connection_status);
if (amt_status == 0)
{
network_status = remote_access_connection_status.AmtNetworkConnectionStatus;
remote_status = remote_access_connection_status.RemoteAccessConnectionStatus;
remote_trigger = remote_access_connection_status.RemoteAccessConnectionTrigger;
if (remote_access_connection_status.MpsHostname.Buffer != NULL)
{
if (remote_access_connection_status.MpsHostname.Length < MPS_SERVER_MAXLENGTH)
{
std::string tmp(remote_access_connection_status.MpsHostname.Buffer, remote_access_connection_status.MpsHostname.Length);
if (util_is_printable(tmp))
{
mps_hostname = tmp;
}
}
free(remote_access_connection_status.MpsHostname.Buffer);
}
return true;
}
return false;
}
bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settings)
{
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
// get wired interface
LAN_SETTINGS lan_settings;
UINT32 interface_settings = 0; // wired=0, wireless=1
AMT_STATUS amt_status = pthi_GetLanInterfaceSettings(interface_settings, &lan_settings);
if (amt_status == 0)
{
lan_interface_settings.is_enabled = lan_settings.Enabled;
lan_interface_settings.dhcp_mode = lan_settings.DhcpIpMode;
lan_interface_settings.dhcp_enabled = lan_settings.DhcpEnabled;
lan_interface_settings.link_status = lan_settings.LinkStatus;
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 24) & 0xff);
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 16) & 0xff);
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address >> 8) & 0xff);
lan_interface_settings.ip_address.push_back((lan_settings.Ipv4Address) & 0xff);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[0]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[1]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[2]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[3]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[4]);
lan_interface_settings.mac_address.push_back(lan_settings.MacAddress[5]);
return true;
}
return false;
}
bool cmd_start_config_host_based(config_host_based_settings& server_cert, config_host_based_settings& amt_cert)
{
amt_cert.algorithm = "MD5"; // FIXME: REMOVE WHEN HW AVAILABLE
amt_cert.hash = "000102030405060708090a0b0c0d0e0f"; // FIXME: REMOVE WHEN HW AVAILABLE
return true; // FIXME: REMOVE WHEN HW AVAILABLE
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
CFG_START_CONFIG_HBASED_REQUEST_INFO request;
CFG_START_CONFIG_HBASED_RESPONSE_INFO response;
memset(&request, 0, sizeof(CFG_START_CONFIG_HBASED_REQUEST_INFO));
memset(&response, 0, sizeof(CFG_START_CONFIG_HBASED_RESPONSE_INFO));
if (server_cert.algorithm == "MD5")
{
request.ServerHashAlgorithm = CERT_HASH_ALGORITHM_MD5;
}
else if (server_cert.algorithm == "SHA1")
{
request.ServerHashAlgorithm = CERT_HASH_ALGORITHM_SHA1;
}
else if (server_cert.algorithm == "SHA256")
{
request.ServerHashAlgorithm = CERT_HASH_ALGORITHM_SHA256;
}
else if (server_cert.algorithm == "SHA512")
{
request.ServerHashAlgorithm = CERT_HASH_ALGORITHM_SHA512;
}
else
{
return false;
}
std::vector<char> cert_bytes;
util_hex_string_to_bytes(server_cert.hash, cert_bytes);
std::copy(std::begin(cert_bytes), std::end(cert_bytes), request.ServerCertHash);
// start secure host based configuration
AMT_STATUS amt_status = pthi_StartConfigHBased(&request, &response);
if (amt_status == 0)
{
switch (response.HashAlgorithm)
{
case CERT_HASH_ALGORITHM_MD5:
amt_cert.algorithm = "MD5";
break;
case CERT_HASH_ALGORITHM_SHA1:
amt_cert.algorithm = "SHA1";
break;
case CERT_HASH_ALGORITHM_SHA256:
amt_cert.algorithm = "SHA256";
break;
case CERT_HASH_ALGORITHM_SHA512:
amt_cert.algorithm = "SHA512";
break;
default:
break;
}
std::vector<char> hash;
std::copy(std::begin(response.AMTCertHash), std::end(response.AMTCertHash), std::begin(hash));
util_bytes_to_hex_string(hash, amt_cert.hash);
return true;
}
return false;
}