Update amtinfo, usage and admin check. General code cleanup and bug fixes.

This commit is contained in:
Mudit Vats
2020-10-30 09:51:18 -07:00
parent eb42f1e89d
commit 6d2e37e7fc
13 changed files with 434 additions and 148 deletions

View File

@@ -58,11 +58,14 @@ find_package(Boost COMPONENTS system REQUIRED)
# Find OpenSSL
find_package(OpenSSL)
# Find ZLIB
find_package(ZLIB)
# Download and build CppRestSDK, If GIT_TAG is changed then need to delete cpprestsdk-prefix because UPDATE_COMMAND is set to ""
include(ExternalProject)
ExternalProject_Add(cpprestsdk
GIT_REPOSITORY https://github.com/Microsoft/cpprestsdk.git
GIT_TAG v2.10.14
GIT_TAG v2.10.16
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=0 -DBUILD_SAMPLES=OFF -DBUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=<SOURCE_DIR>/../../install
TEST_COMMAND ""
UPDATE_COMMAND ""
@@ -72,7 +75,7 @@ set(CPPRESTSDK_LIBARIES ${SOURCE_DIR}/../../install/lib/)
set(CPPRESTSDK_INCLUDE_DIR ${SOURCE_DIR}/../../install/include/)
add_library(cpprest INTERFACE)
target_link_libraries(cpprest INTERFACE ${CPPRESTSDK_LIBARIES}/libcpprest.a OpenSSL::SSL OpenSSL::Crypto ${Boost_LIBRARIES} Threads::Threads)
target_link_libraries(cpprest INTERFACE ${CPPRESTSDK_LIBARIES}/libcpprest.a OpenSSL::SSL OpenSSL::Crypto ${Boost_LIBRARIES} Threads::Threads ZLIB::ZLIB)
target_include_directories(cpprest INTERFACE ${CPPRESTSDK_INCLUDE_DIR})
else (UNIX)

View File

@@ -898,7 +898,7 @@ AMT_STATUS pthi_GetRemoteAccessConnectionStatus(REMOTE_ACCESS_STATUS *remoteAcce
AMT_STATUS _verifyRemoteAccessConnectionStatus(const CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE *response)
{
ULONG ByteCount = response->Header.Header.Length;
if (ByteCount != (sizeof(CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE) - sizeof(PTHI_MESSAGE_HEADER) - sizeof(CHAR *) + response->MpsHostname.Length)) return PTSDK_STATUS_INTERNAL_ERROR;
if (ByteCount < (sizeof(CFG_GET_REMOTE_ACCESS_CONNECTION_STATUS_RESPONSE) - sizeof(PTHI_MESSAGE_HEADER) - sizeof(CHAR*))) return PTSDK_STATUS_INTERNAL_ERROR;
return AMT_STATUS_SUCCESS;
}
@@ -1347,7 +1347,7 @@ AMT_STATUS pthi_SetHostFQDN(char* str)
AMT_STATUS status;
UINT8 *readBuffer = NULL;
CFG_SET_HOST_FQDN_REQUEST command;
int len = (int)strnlen_s(str, _MAX_PATH);
int len = (int)strnlen_s(str, 256);
memset(&command, 0, sizeof(CFG_SET_HOST_FQDN_REQUEST)); // Fix the valgrind warning
command.Header = SET_HOST_FQDN_HEADER;

View File

@@ -2441,8 +2441,8 @@ ILibExportMethod void ILibStartChain(void *Chain)
//
// Free the pipe resources
//
fclose(((ILibBaseChain*)Chain)->TerminateReadPipe);
fclose(((ILibBaseChain*)Chain)->TerminateWritePipe);
if (((ILibBaseChain*)Chain)->TerminateReadPipe != NULL) {fclose(((ILibBaseChain*)Chain)->TerminateReadPipe);}
if (((ILibBaseChain*)Chain)->TerminateWritePipe != NULL) {fclose(((ILibBaseChain*)Chain)->TerminateWritePipe);}
((ILibBaseChain*)Chain)->TerminateReadPipe=0;
((ILibBaseChain*)Chain)->TerminateWritePipe=0;
#endif

View File

@@ -4,8 +4,6 @@ The Default ("master") branch is our release branch that is for production use.
RPC is an application which enables remote capabilities for AMT, such as as device activation. To accomplish this, RPC communicates with the RPS (Remote Provisioning Server).
As a prerequisite, a Local Management Service (LMS) must be installed and running on the operating system.
## Linux
Steps below are for Ubuntu 18.04.

View File

@@ -17,15 +17,15 @@
bool get_certificate_hashes(web::json::value& hashes)
{
std::vector<web::json::value> hashValues;
std::vector<std::string> certHashes;
std::vector<cert_hash_entry> certHashes;
if (!cmd_get_certificate_hashes(certHashes))
{
return false;
}
for (std::string hashString : certHashes)
for (cert_hash_entry hashString : certHashes)
{
hashValues.push_back(web::json::value::string(utility::conversions::convertstring(hashString)));
hashValues.push_back(web::json::value::string(utility::conversions::convertstring(hashString.hash)));
}
hashes = web::json::value::array(hashValues);
@@ -269,10 +269,6 @@ bool act_create_request(std::string commands, std::string dns_suffix, std::strin
utility::string_t payload = utility::conversions::to_string_t(encodedPayload);
msg[U("payload")] = web::json::value::string(payload);
#ifdef DEBUG
std::cout << "Activation info payload:" << serializedPayload << std::endl;
#endif
// serialize the entire message
request = utility::conversions::to_utf8string(msg.serialize());

View File

@@ -21,6 +21,19 @@ bool get_arg_exists(int argc, char* argv[], const char* long_opt, const char* sh
return false;
}
bool get_arg_exists(int argc, char* argv[], const char* opt)
{
for (int i = 1; i < argc; i++)
{
if ((strcasecmp(argv[i], opt) == 0))
{
return true;
}
}
return false;
}
bool get_arg_string(int argc, char* argv[], const char* long_opt, const char* short_opt, std::string& value)
{
value = "";
@@ -48,14 +61,41 @@ bool get_arg_string(int argc, char* argv[], const char* long_opt, const char* sh
return false;
}
bool get_arg_string(int argc, char* argv[], const char* opt, std::string& value)
{
value = "";
for (int i = 1; i < argc; i++)
{
if ((strcasecmp(argv[i], opt) == 0))
{
if (i + 1 < argc)
{
std::string tmp = argv[++i];
if (!util_is_printable(tmp))
{
return false;
}
value = tmp;
return true;
}
}
}
return false;
}
bool args_get_help(int argc, char* argv[])
{
return get_arg_exists(argc, argv, "--help", "-h");
return get_arg_exists(argc, argv, "--help");
}
bool args_get_version(int argc, char* argv[])
{
return get_arg_exists(argc, argv, "--version", "-v");
return get_arg_exists(argc, argv, "--version");
}
bool args_get_url(int argc, char* argv[], std::string& url)
@@ -65,7 +105,7 @@ bool args_get_url(int argc, char* argv[], std::string& url)
bool args_get_proxy(int argc, char* argv[], std::string& proxy)
{
return get_arg_string(argc, argv, "--proxy", "-x", proxy);
return get_arg_string(argc, argv, "--proxy", "-p", proxy);
}
bool args_get_cmd(int argc, char* argv[], std::string& cmd)
@@ -80,5 +120,10 @@ bool args_get_dns(int argc, char* argv[], std::string& dns)
bool args_get_info(int argc, char* argv[], std::string& info)
{
return get_arg_string(argc, argv, "--info", "-i", info);
return get_arg_string(argc, argv, "--amtinfo", info);
}
bool args_get_verbose(int argc, char* argv[])
{
return get_arg_exists(argc, argv, "--verbose", "-v");
}

1
args.h
View File

@@ -15,5 +15,6 @@ bool args_get_proxy(int argc, char* argv[], std::string& proxy);
bool args_get_cmd(int argc, char* argv[], std::string& cmd);
bool args_get_dns(int argc, char* argv[], std::string& dns);
bool args_get_info(int argc, char* argv[], std::string& info);
bool args_get_verbose(int argc, char* argv[]);
#endif

View File

@@ -6,6 +6,7 @@
#include "commands.h"
#include <string>
#include "port.h"
#include "utils.h"
#ifndef _WIN32
#include <string.h>
@@ -22,6 +23,13 @@ extern "C" {
}
#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.clear();
@@ -184,8 +192,12 @@ bool cmd_get_dns_suffix(std::string& suffix)
if (amt_status == 0)
{
std::string tmp(amt_dns_suffix.Buffer, amt_dns_suffix.Length);
suffix = tmp;
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;
}
@@ -222,9 +234,9 @@ bool cmd_get_wired_mac_address(std::vector<unsigned char>& address)
return false;
}
bool cmd_get_certificate_hashes(std::vector<std::string>& hashes)
bool cmd_get_certificate_hashes(std::vector<cert_hash_entry>& hash_entries)
{
hashes.clear();
hash_entries.clear();
// initialize HECI interface
if (heci_Init(NULL, PTHI_CLIENT) == 0) return false;
@@ -242,28 +254,38 @@ bool cmd_get_certificate_hashes(std::vector<std::string>& hashes)
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 = 64;
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;
hashString.clear();
for (int i = 0; i < hashSize; i++)
{
char hex[10];
@@ -271,7 +293,9 @@ bool cmd_get_certificate_hashes(std::vector<std::string>& hashes)
hashString += hex;
}
hashes.push_back(hashString);
tmp.hash = hashString;
hash_entries.push_back(tmp);
}
}
@@ -280,3 +304,77 @@ bool cmd_get_certificate_hashes(std::vector<std::string>& hashes)
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.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;
}

View File

@@ -9,6 +9,26 @@
#include <vector>
#include <string>
struct cert_hash_entry
{
std::string hash;
std::string name;
std::string algorithm;
bool is_active;
bool is_default;
};
struct lan_interface_settings
{
bool is_enabled;
bool link_status;
bool dhcp_enabled;
int dhcp_mode;
std::vector<unsigned char> ip_address;
std::vector<unsigned char> mac_address;
};
bool cmd_is_admin();
bool cmd_get_version(std::string& version);
bool cmd_get_build_number(std::string& version);
bool cmd_get_sku(std::string& version);
@@ -17,6 +37,8 @@ bool cmd_get_local_system_account(std::string& username, std::string& password);
bool cmd_get_control_mode(int& mode);
bool cmd_get_dns_suffix(std::string& suffix);
bool cmd_get_wired_mac_address(std::vector<unsigned char>& address);
bool cmd_get_certificate_hashes(std::vector<std::string>& hashes);
bool cmd_get_certificate_hashes(std::vector<cert_hash_entry>& hash_entries);
bool cmd_get_remote_access_connection_status(int& network_status, int& remote_status, int& remote_trigger, std::string& mps_hostname);
bool cmd_get_lan_interface_settings(lan_interface_settings& lan_interface_settings);
#endif

171
info.cpp
View File

@@ -10,13 +10,16 @@
#include "commands.h"
#include "utils.h"
void out_text(const std::string name, const std::vector<unsigned char> value, const unsigned char delimeter=' ')
const int PADDING = 25;
void out_text(const std::string name, const std::vector<unsigned char> value, const unsigned char delimeter = ' ', const bool hex = true)
{
std::cout << name << ": ";
std::cout << name << std::setfill(' ') << std::setw(PADDING - name.size()) << ": ";
int char_count = 1;
for (unsigned char tmp : value)
{
std::cout << std::setfill('0') << std::setw(2) << std::hex << (unsigned int) tmp;
(hex) ? std::cout << std::setfill('0') << std::setw(2) << std::hex << (unsigned int)tmp
: std::cout << (unsigned int)tmp;
if (char_count++ < value.size())
{
@@ -29,26 +32,23 @@ void out_text(const std::string name, const std::vector<unsigned char> value, co
void out_text(const std::string name, const std::string value)
{
std::cout << name << ": ";
std::cout << name << std::setfill(' ') << std::setw(PADDING - name.size()) << ": ";
std::cout << value;
std::cout << std::endl;
}
void out_text(const std::string name, const int value)
{
std::cout << name << ": ";
std::cout << name << std::setfill(' ') << std::setw(PADDING - name.size()) << ": ";
std::cout << value;
std::cout << std::endl;
}
void out_text(const std::string name, const std::vector<std::string> value)
{
int count = 1;
std::cout << name << std::endl;
std::cout << name << std::setfill(' ') << std::setw(PADDING - name.size()) << ": " << std::endl;
for (std::string tmp : value)
{
std::cout << std::setfill('0') << std::setw(2) << count++ << ":";
std::cout << tmp << std::endl;
}
}
@@ -70,7 +70,7 @@ bool info_get_build_number()
if (!cmd_get_build_number(tmp)) return false;
out_text("Build number", tmp);
out_text("Build Number", tmp);
return true;
}
@@ -111,7 +111,7 @@ bool info_get_control_mode()
else if (tmp == 1) control_mode = "activated in client control mode";
else if (tmp == 2) control_mode = "activated in admin control mode";
out_text("Control mode", control_mode);
out_text("Control Mode", control_mode);
return true;
}
@@ -122,29 +122,31 @@ bool info_get_dns_suffix()
if (!cmd_get_dns_suffix(tmp)) return false;
out_text("DNS suffix", tmp);
return true;
}
bool info_get_wired_mac_address()
{
std::vector<unsigned char> tmp;
if (!cmd_get_wired_mac_address(tmp)) return false;
out_text("Wired MAC address", tmp, '-');
out_text("DNS Suffix", tmp);
return true;
}
bool info_get_certificate_hashes()
{
std::vector<cert_hash_entry> hash_entries;
std::vector<std::string> tmp;
if (!cmd_get_certificate_hashes(tmp)) return false;
if (!cmd_get_certificate_hashes(hash_entries)) return false;
out_text("Certificate hashes", tmp);
for (cert_hash_entry entry : hash_entries)
{
std::string name = entry.name;
(entry.is_default) ? name += ", (Default, " : ", (Not Default, ";
(entry.is_active) ? name += "Active)" : "Not Active)";
tmp.push_back(name);
std::string algorithm = " " + entry.algorithm;
algorithm += ": " + entry.hash;
tmp.push_back(algorithm);
}
out_text("Certificate Hashes", tmp);
return true;
}
@@ -153,13 +155,99 @@ bool info_get_all()
{
std::vector<std::string> tmp;
if (info_get_version() && info_get_build_number() && info_get_sku() &&
info_get_uuid() && info_get_control_mode() && info_get_dns_suffix() &&
info_get_wired_mac_address() && info_get_certificate_hashes())
bool status_ver = info_get_version();
bool status_bld = info_get_build_number();
bool status_sku = info_get_sku();
bool status_uuid = info_get_uuid();
bool status_mode = info_get_control_mode();
bool status_dns = info_get_dns_suffix();
bool status_ras = info_get_remote_access_connection_status();
bool status_lan = info_get_lan_interface_settings();
bool status_cert = info_get_certificate_hashes();
if (status_ver && status_bld && status_sku && status_uuid && status_mode &&
status_dns && status_ras && status_lan && status_cert)
{
return true;
}
return false;
}
bool info_get_remote_access_connection_status()
{
int network_status;
int remote_status;
int remote_trigger;
std::string mps_hostname;
if (!cmd_get_remote_access_connection_status(network_status, remote_status, remote_trigger, mps_hostname)) return false;
std::string tmp;
switch (network_status)
{
case 0: tmp = "direct";
break;
case 1: tmp = "vpn";
break;
case 2: tmp = "outside enterprise";
break;
case 3:
default: tmp = "unknown";
break;
}
out_text("RAS Network", tmp);
switch (remote_status)
{
case 0: tmp = "not connected";
break;
case 1: tmp = "connecting";
break;
case 2: tmp = "connected";
break;
default: tmp = "unknown";
break;
}
out_text("RAS Remote Status", tmp);
switch (remote_trigger)
{
case 0: tmp = "user initiated";
break;
case 1: tmp = "alert";
break;
case 2: tmp = "periodic";
break;
case 3: tmp = "provisioning";
break;
default: tmp = "unknown";
break;
}
out_text("RAS Trigger", tmp);
out_text("RAS MPS Hostname", mps_hostname);
return true;
}
bool info_get_lan_interface_settings()
{
lan_interface_settings tmp;
if (!cmd_get_lan_interface_settings(tmp)) return false;
out_text("DHCP Enabled", (tmp.dhcp_enabled) ? "true" : "false");
out_text("DHCP Mode", (tmp.dhcp_mode == 1) ? "active" : "passive");
out_text("Link Status", (tmp.link_status) ? "up" : "down");
out_text("IP Address", tmp.ip_address, '.', false);
out_text("MAC Address", tmp.mac_address, ':');
return true;
}
@@ -169,7 +257,7 @@ bool info_get(const std::string info)
{
return info_get_version();
}
else if (info.compare("build") == 0)
else if (info.compare("bld") == 0)
{
return info_get_build_number();
}
@@ -189,14 +277,18 @@ bool info_get(const std::string info)
{
return info_get_dns_suffix();
}
else if (info.compare("mac") == 0)
{
return info_get_wired_mac_address();
}
else if (info.compare("cert") == 0)
{
return info_get_certificate_hashes();
}
else if (info.compare("ras") == 0)
{
return info_get_remote_access_connection_status();
}
else if (info.compare("lan") == 0)
{
return info_get_lan_interface_settings();
}
else if (info.compare("all") == 0)
{
return info_get_all();
@@ -204,3 +296,16 @@ bool info_get(const std::string info)
return false;
}
bool info_get_verify(const std::string info)
{
if ((info.compare("ver") == 0) || (info.compare("bld") == 0) || (info.compare("sku") == 0) ||
(info.compare("uuid") == 0) || (info.compare("mode") == 0) || (info.compare("dns") == 0) ||
(info.compare("cert") == 0) || (info.compare("ras") == 0) || (info.compare("lan") == 0) ||
(info.compare("all") == 0))
{
return true;
}
return false;
}

4
info.h
View File

@@ -9,13 +9,15 @@
#include <string>
bool info_get(const std::string info);
bool info_get_verify(const std::string info);
bool info_get_version();
bool info_get_build_number();
bool info_get_sku();
bool info_get_uuid();
bool info_get_control_mode();
bool info_get_dns_suffix();
bool info_get_wired_mac_address();
bool info_get_all();
bool info_get_remote_access_connection_status();
bool info_get_lan_interface_settings();
#endif

103
main.cpp
View File

@@ -59,10 +59,11 @@ int main(int argc, char* argv[])
std::string arg_cmd;
std::string arg_dns;
std::string arg_info;
bool arg_verbose = false;
if (argc == 1)
{
std::cout << "Use -h, --help for help." << std::endl;
std::cout << "Use --help for help." << std::endl;
return 0;
}
@@ -80,14 +81,24 @@ int main(int argc, char* argv[])
return 0;
}
// Check if running in elevated privileges
if (!cmd_is_admin())
{
std::cout << "Unable to launch application. Please ensure that Intel ME is present, the MEI driver is installed and that this application is run with administrator or root privileges." << std::endl;
return 0;
}
// check for info
if (args_get_info(argc, argv, arg_info))
{
if (!info_get(arg_info))
if (!info_get_verify(arg_info))
{
std::cout << "Incorrect or missing arguments." << std::endl;
std::cout << "Use -h, --help for help." << std::endl;
std::cout << "Use --help for help." << std::endl;
return 0;
}
info_get(arg_info);
return 0;
}
@@ -95,10 +106,16 @@ int main(int argc, char* argv[])
if (!args_get_url(argc, argv, arg_url) || !args_get_cmd(argc, argv, arg_cmd))
{
std::cout << "Incorrect or missing arguments." << std::endl;
std::cout << "Use -h, --help for help." << std::endl;
std::cout << "Use --help for help." << std::endl;
return 0;
}
// verbose output
if (args_get_verbose(argc, argv))
{
arg_verbose = true;
}
// Print version info
usage_show_version();
@@ -122,8 +139,8 @@ int main(int argc, char* argv[])
try
{
// check if LMS is available
SOCKET s = lms_connect();
closesocket(s);
SOCKET lms_socket = lms_connect();
closesocket(lms_socket);
}
catch (...)
{
@@ -137,10 +154,6 @@ int main(int argc, char* argv[])
}
}
#ifdef DEBUG
std::cout << "Activation info: " << std::endl << activation_info << std::endl;
#endif
// webSocket Interface
web::websockets::client::websocket_client_config client_config;
if (args_get_proxy(argc, argv, arg_proxy))
@@ -149,16 +162,17 @@ int main(int argc, char* argv[])
}
#ifdef DEBUG
// skip certificate verification if debug build
std::cout << "!!! SKIPPING CERTIFICATE VERIFICATION !!!" << std::endl;
std::cout << "Skipping certificate verification." << std::endl;
client_config.set_validate_certificates(false);
#endif
web::websockets::client::websocket_callback_client client(client_config);
std::condition_variable cv;
std::mutex mx;
SOCKET s;
SOCKET lms_socket;
memset(&lms_socket, 0, sizeof(SOCKET));
// set receive handler
client.set_message_handler([&client, &mx, &cv, &s](web::websockets::client::websocket_incoming_message ret_msg)
client.set_message_handler([&client, &mx, &cv, &lms_socket, arg_verbose](web::websockets::client::websocket_incoming_message ret_msg)
{
// kick the timer
std::chrono::time_point<std::chrono::system_clock> now = std::chrono::system_clock::now();
@@ -169,10 +183,6 @@ int main(int argc, char* argv[])
{
// handle message from server
std::string rcv_websocket_msg = ret_msg.extract_string().get();
#ifdef DEBUG
std::cout << std::endl << "<<<<< Received Message " << std::endl;
std::cout << rcv_websocket_msg << std::endl;
#endif
std::cout << "." << std::flush; // dot status output
// parse incoming JSON message
@@ -224,12 +234,6 @@ int main(int argc, char* argv[])
return;
}
#ifdef DEBUG
std::cout << msgMethod << ", " << msgStatus << ", " << msgMessage << std::endl;
std::cout << rcv_websocket_msg << std::endl;
#endif
// process any messages we can
// - if success, done
// - if error, get out
@@ -280,7 +284,7 @@ int main(int argc, char* argv[])
try
{
// conntect to lms
s = lms_connect();
lms_socket = lms_connect();
}
catch (...)
{
@@ -288,22 +292,23 @@ int main(int argc, char* argv[])
return;
}
#ifdef DEBUG
std::cout << std::endl << "vvvvv Sending Message " << std::endl;
std::cout << payloadDecoded << std::endl;
#endif
if (arg_verbose)
{
std::cout << std::endl << "vvv -- message to AMT -- vvv" << std::endl;
std::cout << payloadDecoded << std::endl;
}
// send message to LMS
if (send(s, payloadDecoded.c_str(), (int)payloadDecoded.length(), 0) < 0)
if (send(lms_socket, payloadDecoded.c_str(), (int)payloadDecoded.length(), 0) < 0)
{
throw std::runtime_error("error: socket send");
}
// handle response message from LMS
int fd = ((int) s) + 1;
int fd = ((int)lms_socket) + 1;
fd_set rset;
FD_ZERO(&rset);
FD_SET(s, &rset);
FD_SET(lms_socket, &rset);
timeval timeout;
memset(&timeout, 0, sizeof(timeval));
@@ -328,13 +333,9 @@ int main(int argc, char* argv[])
// read from LMS
char recv_buffer[4096];
memset(recv_buffer, 0, 4096);
res = recv(s, recv_buffer, 4096, 0);
res = recv(lms_socket, recv_buffer, 4096, 0);
if (res > 0)
{
#ifdef DEBUG
std::cout << std::endl << "^^^^^ Received Message" << std::endl;
std::cout << recv_buffer << std::endl;
#endif
superBuffer += recv_buffer;
}
else if (res < 0)
@@ -353,31 +354,32 @@ int main(int argc, char* argv[])
// if there is some data send it
if (superBuffer.length() > 0)
{
if (arg_verbose)
{
std::cout << std::endl << "^^^ -- message from AMT -- ^^^" << std::endl;
std::cout << superBuffer << std::endl;
}
std::string response;
if (!act_create_response(superBuffer.c_str(), response)) return;
web::websockets::client::websocket_outgoing_message send_websocket_msg;
std::string send_websocket_buffer(response);
send_websocket_msg.set_utf8_message(send_websocket_buffer);
#ifdef DEBUG
std::cout << std::endl << ">>>>> Sending Message" << std::endl;
std::cout << superBuffer << std::endl;
std::cout << send_websocket_buffer << std::endl;
#endif
client.send(send_websocket_msg).wait();
// done
closesocket(s);
closesocket(lms_socket);
return;
}
}
closesocket(s);
closesocket(lms_socket);
}
catch (...)
{
std::cerr << std::endl << "Communication error in receive handler." << std::endl;
closesocket(s);
closesocket(lms_socket);
}
});
@@ -403,12 +405,7 @@ int main(int argc, char* argv[])
{
// send activationParams to websocket
web::websockets::client::websocket_outgoing_message out_msg;
out_msg.set_utf8_message(activation_info);
#ifdef DEBUG
std::cout << std::endl << ">>>>> Sending Activiation Info" << std::endl;
std::cout << activation_info << std::endl;
#endif
out_msg.set_utf8_message(activation_info);
client.send(out_msg).wait();
}
catch (...)
@@ -433,10 +430,8 @@ int main(int argc, char* argv[])
client.close().wait();
// clean-up socket
if (s) {
shutdown(s, SD_BOTH);
closesocket(s);
}
shutdown(lms_socket, SD_BOTH);
closesocket(lms_socket);
exit(0);
}

View File

@@ -10,41 +10,62 @@
void usage_show_help()
{
std::cout << "Usage: " << PROJECT_NAME << " --help | --version | --info <item> | --url <url> --cmd <command> [--proxy <addr>] [--dns <dns>]" << std::endl;
std::cout << "Required:" << std::endl;
std::cout << " -u, --url <url> websocket server" << std::endl;
std::cout << " -c, --cmd <command> server command" << std::endl;
std::cout << "Optional:" << std::endl;
std::cout << " -x, --proxy <addr> proxy address and port" << std::endl;
std::cout << " -d, --dns <dns> dns suffix" << std::endl;
std::cout << "Informational:" << std::endl;
std::cout << " -h, --help this help text" << std::endl;
std::cout << " -v, --version version" << std::endl;
std::cout << " -i, --info <item> info on an <item>" << std::endl;
std::cout << std::endl;
std::cout << "Info <item>:" << std::endl;
std::cout << " all all items" << std::endl;
std::cout << " ver bios version" << std::endl;
std::cout << " build build number" << std::endl;
std::cout << " sku product sku" << std::endl;
std::cout << " uuid unique identifier" << std::endl;
std::cout << " mode current control mode {0=none, 1=client, 2=admin}" << std::endl;
std::cout << " dns domain name suffix" << std::endl;
std::cout << " mac wired MAC address" << std::endl;
std::cout << " cert certificate hashes" << std::endl;
std::cout << std::endl;
std::cout << "Examples:" << std::endl;
std::cout << " " << PROJECT_NAME << " --url wss://localhost:8080 --cmd \"-t activate --profile profile1\"" << std::endl;
std::cout << " " << PROJECT_NAME << " -u wss://localhost:8080 -c \"-t deactivate --password P@ssw0rd\" -x http://proxy.com:1000" << std::endl;
std::cout << " " << PROJECT_NAME << " -u wss://localhost:8080 -c \"-e [encrypted-command-text] -h [signature-hash]\"" << std::endl;
std::cout << std::endl;
std::cout << "Note:" << std::endl;
std::cout << " Since <command> can contain multiple options and arguments, the entire <command> must be in quotes as shown" << std::endl;
std::cout << " in the examples." << std::endl;
// 80 chars "01234567890123456789012345678901234567890123456789012345678901234567890123456789"
std::cout << "Usage: " << std::endl;
std::cout << " " << PROJECT_NAME << " <required> [optional]" << std::endl;
std::cout << " " << PROJECT_NAME << " <informational>" << std::endl;
std::cout << std::endl;
std::cout << "Required:" << std::endl;
std::cout << " -u, --url <url> websocket server" << std::endl;
std::cout << " -c, --cmd <command> server command" << std::endl;
std::cout << std::endl;
std::cout << " Since <command> can contain multiple options and arguments, the entire" << std::endl;
std::cout << " <command> must be in quotes. Please see examples below." << std::endl;
std::cout << std::endl;
std::cout << "Optional:" << std::endl;
std::cout << " -p, --proxy <addr> proxy address and port" << std::endl;
std::cout << " -d, --dns <dns> dns suffix override" << std::endl;
std::cout << " -v, --verbose verbose output" << std::endl;
std::cout << std::endl;
std::cout << "Informational:" << std::endl;
std::cout << " --help this help text" << std::endl;
std::cout << " --version version" << std::endl;
std::cout << " --amtinfo <item> AMT info on an <item>" << std::endl;
std::cout << std::endl;
std::cout << "Item:" << std::endl;
std::cout << " all all items" << std::endl;
std::cout << " ver BIOS version" << std::endl;
std::cout << " bld build number" << std::endl;
std::cout << " sku product SKU" << std::endl;
std::cout << " uuid unique identifier" << std::endl;
std::cout << " mode current control mode" << std::endl;
std::cout << " dns domain name suffix" << std::endl;
std::cout << " cert certificate hashes" << std::endl;
std::cout << " ras remote access status" << std::endl;
std::cout << " lan LAN settings" << std::endl;
std::cout << std::endl;
std::cout << "Examples:" << std::endl;
std::cout << " # Activate platform using profile1" << std::endl;
std::cout << " " << PROJECT_NAME << \
" --url wss://localhost:8080 --cmd \"-t activate --profile profile1\"" << std::endl;
std::cout << std::endl;
std::cout << " # Activate platform using profile1 and override DNS detection" << std::endl;
std::cout << " " << PROJECT_NAME << \
" --url wss://localhost:8080 --cmd \"-t activate --profile profile1\" --dns corp.com" << std::endl;
std::cout << std::endl;
std::cout << " # Deactivate platform and connect through a proxy" << std::endl;
std::cout << " " << PROJECT_NAME << \
" -u wss://localhost:8080 -c \"-t deactivate --password P@ssw0rd\" -p http://proxy.com:1000" << std::endl;
std::cout << std::endl;
std::cout << " # Show all informational items" << std::endl;
std::cout << " " << PROJECT_NAME << " --amtinfo all" << std::endl;
}
void usage_show_version()
{
std::cout << PROJECT_NAME << " " << PROJECT_VER << std::endl;
std::cout << "protocol " << PROTOCOL_VERSION << std::endl;
std::string project_name = PROJECT_NAME;
for (auto& c : project_name) c = toupper(c); // get upper case string
std::cout << project_name << " " << PROJECT_VER << "." << std::endl;
std::cout << "Protocol " << PROTOCOL_VERSION << "." << std::endl;
}