2025 lines
53 KiB
C++

//----------------------------------------------------------------------------
//
// Copyright (C) 2006 Intel Corporation
//
// File: ConfigFile.cpp
//
// Contents: Tool to create and view sample Intel(R) AMT USB format files
// used with the Configuration Server.
//
//----------------------------------------------------------------------------
#include "SetupFileReaderWriter.h"
#include "ConfigFile.h"
#include "SetupFileDefinitions.h"
#include <fstream>
#include <sstream>
using namespace std;
#include <iomanip>
// check if file exists
bool MyFileExists(const string& fileName)
{
ifstream in(fileName.c_str(), ios_base::binary);
if(in.is_open())
{
in.close();
return true;
}
in.clear(ios::failbit);
in.close();
return false;
}
bool IsPskAllZeroes(const char pid[PID_LENGTH], const char pps[PPS_LENGTH])
{
// check pid for all zeroes
for(int i = 0; i < PID_LENGTH; i++)
{
if (48 != pid[i])
{
return false;
}
}
// check pps for all zeroes
for(int i = 0; i < PPS_LENGTH; i++)
{
if (48 != pps[i])
{
return false;
}
}
return true;
}
bool IsPpsValid(const char pps[PPS_LENGTH])
{
// first validate char values
for(int i = 0; i < PPS_LENGTH; i++)
{
unsigned int tmp = (unsigned int)pps[i];
if(!((tmp > 47 && tmp < 58) || (tmp > 64 && tmp < 91)))
{
return false;
}
}
// validate CRC mechanism
for(int i = 0; i < 8; i++)
{
unsigned int crc = 0;
for(int j = 0; j < 3; j ++)
{
crc += pps[i*4 + j];
}
crc %= 36;
if(crc < 10)
{
crc = crc + 48;
}
else
{
crc = crc - 10 + 65;
}
if(crc != (unsigned int)pps[i*4 + 3])
{
return false;
}
}
return true;
}
bool IsPidValid(const char pid[PID_LENGTH])
{
// first validate char values
for(int i = 0; i < PID_LENGTH; i++)
{
unsigned int tmp = (unsigned int)pid[i];
if(!((tmp > 47 && tmp < 58) || (tmp > 64 && tmp < 91)))
{
return false;
}
}
// validate CRC mechanism
unsigned int crc = 0;
for(int i = 0; i < 7; i++)
{
crc += pid[i];
}
crc %= 36;
if(crc < 10)
{
crc = crc + 48;
}
else
{
crc = crc - 10 + 65;
}
if(crc != (unsigned int)pid[7])
{
return false;
}
return true;
}
bool IsPasswordValid(const string& pwd)
{
// validate length
int len = (int)pwd.length();
if(len < MIN_PWD_LEN || len > MAX_PWD_LEN)
{
return false;
}
// verify password strength
bool digit = false;
bool symbol = false;
bool upper = false;
bool lower = false;
for (int i = 0; i < len; i++)
{
// make sure that we have only acceptable characters
if ((pwd[i] == ':') ||
(pwd[i] == '"') ||
(pwd[i] == ',') ||
(pwd[i] < 0x20) ||
(pwd[i] > 0x7E))
{
//printf("\nError: The given password contains an invalid character.\n");
return false;
}
// lower case abc
if (pwd[i] >= 'a' && pwd[i] <= 'z')
{
lower = true;
}
// upper case ABC
else if (pwd[i] >= 'A' && pwd[i] <= 'Z')
{
upper = true;
}
// numeric
else if (pwd[i] >= '0' && pwd[i] <= '9')
{
digit = true;
}
// 7 bit ASCII non alpha numeric
else if (pwd[i] != '_' && pwd[i] != ' ')
{
symbol = true;
}
}
if(!(symbol && digit && upper && lower))
{
//printf("\nError: The given password is not strong.\n");
return false;
}
return true;
}
int IsRecordValid(const ConfigRecord record)
{
if (record.hasPskPair)
{
if (!IsPskAllZeroes((char*)(record.Pid), (char*)(record.Pps)))
{
if(!IsPidValid((char*)(record.Pid)))
{
return CONFIG_INVALID_PID;
}
if(!IsPpsValid((char*)(record.Pps)))
{
return CONFIG_INVALID_PPS;
}
}
}
if(!IsPasswordValid(record.NewMEBxPwd))
{
return CONFIG_INVALID_NEW_PWD;
}
if(record.CurrentMEBxPwd.length() > MAX_PWD_LEN ||
record.CurrentMEBxPwd.length() == 0)
{
return CONFIG_INVALID_CURR_PWD;
}
if(!record.valid)
{
return CONFIG_INVALID_RECORD;
}
return CONFIG_SUCCESS;
}
void RandomChar(char* randomChar, const string& validChars, const MyRand* myRand)
{
int length = (int)validChars.length();
int index = myRand->RandomNumber() % length;
if(randomChar)
{
*randomChar = validChars[index];
}
}
int RandomPassword(string* pwd, const unsigned int len, MyRand* myRand)
{
bool randIsNull = false;
int length = len;
string data;
data.resize(length);
const string CAPITALS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string LOWER_CASE = "abcdefghijklmnopqrstuvwxyz";
const string DIGITS = "0123456789";
const string SYMBOLS = "!#$%&'()*+-./;<=>?@{\\]^`{|}~";
const string all = CAPITALS + LOWER_CASE + DIGITS + SYMBOLS + " _";
if(length < MIN_PWD_LEN)
{
length = MIN_PWD_LEN;
}
if(length > MAX_PWD_LEN)
{
length = MAX_PWD_LEN;
}
if(myRand == NULL)
{
randIsNull = true;
try
{
myRand = new MyRand();
}
catch(RandomNumberError)
{
delete myRand;
return CONFIG_RNG_ERROR;
}
}
int retVal = CONFIG_SUCCESS;
try
{
// choose random index for capital, lowercase, symbol and digit
int indexes[MAX_PWD_LEN];
for(int i = 0; i < MAX_PWD_LEN; i++)
{
indexes[i] = i;
}
int r = myRand->RandomNumber() % length;
int capitalIndex = indexes[r];
indexes[r] = indexes[length - 1];
r = myRand->RandomNumber() % (length - 1);
int lowerIndex = indexes[r];
indexes[r] = indexes[length - 2];
r = myRand->RandomNumber() % (length - 2);
int symbolIndex = indexes[r];
indexes[r] = indexes[length - 3];
r = myRand->RandomNumber() % (length - 3);
int digitIndex = indexes[r];
char temp;
for(int i = 0; i < length; i++)
{
if(i == capitalIndex)
{
RandomChar(&temp, CAPITALS, myRand);
}
else if(i == lowerIndex)
{
RandomChar(&temp, LOWER_CASE, myRand);
}
else if(i == symbolIndex)
{
RandomChar(&temp, SYMBOLS, myRand);
}
else if(i == digitIndex)
{
RandomChar(&temp, DIGITS, myRand);
}
else
{
RandomChar(&temp, all, myRand);
}
data[i] = temp;
}
}
catch(RandomNumberError)
{
retVal = CONFIG_RNG_ERROR;
}
if(randIsNull)
{
delete myRand;
myRand = NULL;
}
if(retVal == CONFIG_SUCCESS)
{
if(pwd)
{
*pwd = data;
}
}
return retVal;
}
int RandomPid(char pid[PID_LENGTH], const MyRand* myRand)
{
bool randIsNull = false;
const string LEGAL = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if(myRand == NULL)
{
randIsNull = true;
try
{
myRand = new MyRand();
}
catch(RandomNumberError)
{
delete myRand;
return CONFIG_RNG_ERROR;
}
}
int retVal = CONFIG_SUCCESS;
char temp;
unsigned int crc = 0;
try
{
for(int i = 0; i < 7; i++)
{
RandomChar(&temp, LEGAL, myRand);
pid[i] = temp;
crc += (unsigned char)pid[i];
}
crc %= 36;
pid[7] = LEGAL[crc];
}
catch(RandomNumberError)
{
retVal = CONFIG_RNG_ERROR;
}
if(randIsNull)
{
delete myRand;
myRand = NULL;
}
return retVal;
}
int RandomPps(char pps[PPS_LENGTH], const MyRand* myRand)
{
bool randIsNull = false;
const string LEGAL = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if(myRand == NULL)
{
randIsNull = true;
try
{
myRand = new MyRand();
}
catch(RandomNumberError)
{
delete myRand;
return CONFIG_RNG_ERROR;
}
}
int retVal = CONFIG_SUCCESS;
char temp;
unsigned int crc = 0;
try
{
for(int i = 0; i < 8; i++)
{
crc = 0;
for(int j = 0; j < 3; j ++)
{
RandomChar(&temp, LEGAL, myRand);
pps[i*4 + j] = temp;
crc += (unsigned char)pps[i*4 + j];
}
crc %= 36;
pps[i*4 + 3] = LEGAL[crc];
}
}
catch(RandomNumberError)
{
retVal = CONFIG_RNG_ERROR;
}
if(randIsNull)
{
delete myRand;
myRand = NULL;
}
return retVal;
}
int WriteVersion1ConfigFile(const string& fileName,
const vector<ConfigRecord>& records,
const bool overwrite)
{
int retVal = CONFIG_SUCCESS;
unsigned int number = (unsigned int)records.size();
for(unsigned int i = 0; i < number; i++)
{
if((retVal = IsRecordValid(records[i])) != CONFIG_SUCCESS)
{
return retVal;
}
}
if(!overwrite && MyFileExists(fileName))
{
return CONFIG_FILE_WRITE_ERROR;
}
vector<DataRecord> dataRecords;
ConfigRecord temp;
for(unsigned int i = 0; i < number; i++)
{
temp = records[i];
DataRecord record; // default Ctr
record.AddRecordEntry(MODULE_IDENTIFIER_ME_KERNEL,
ME_VARIABLE_IDENTIFIER_CURRENT_MEBX_PWD,
(unsigned short)temp.CurrentMEBxPwd.length(),
(unsigned char*)temp.CurrentMEBxPwd.c_str());
record.AddRecordEntry(MODULE_IDENTIFIER_ME_KERNEL,
ME_VARIABLE_IDENTIFIER_NEW_MEBX_PWD,
(unsigned short)temp.NewMEBxPwd.length(),
(unsigned char*)temp.NewMEBxPwd.c_str());
if (temp.hasPskPair)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PID,
PID_LENGTH, (unsigned char*)temp.Pid);
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PPS,
PPS_LENGTH, (unsigned char*)temp.Pps);
}
dataRecords.push_back(record);
}
unsigned short headerChunkCount = SINGLE_CHUNK_COUNT;
unsigned short dataRecordChunkCount = SINGLE_CHUNK_COUNT;
unsigned int bufferLength = (unsigned int)CHUNK_SIZE *
(headerChunkCount + number * dataRecordChunkCount);
unsigned char* data = new unsigned char[bufferLength];
memset(data, 0, bufferLength);
SetupFileInfo fileInfo;
fileInfo.consumeRecords = false;
fileInfo.dataRecordChunkCount = dataRecordChunkCount;
fileInfo.headerChunkCount = headerChunkCount;
fileInfo.majorVersion = SETUP_FILE_VERSION_1;
fileInfo.minorVersion = 0;
fileInfo.recordCount = number;
fileInfo.recordsConsumed = 0;
retVal = RecordsToBuffer(dataRecords, fileInfo,
bufferLength, data);
if(retVal == CONFIG_SUCCESS)
{
ofstream setupFile(fileName.c_str(), ios_base::binary);
if(!setupFile.is_open())
{
retVal = CONFIG_FILE_WRITE_ERROR;
}
else
{
setupFile.write((char*)data,bufferLength);
setupFile.close();
}
}
delete[] data;
data = NULL;
return retVal;
}
int GetConfigRecord(const DataRecord record, ConfigRecord* config)
{
unsigned short varLen;
char pid[PID_LENGTH];
char pps[PPS_LENGTH];
char currPwdB[MAX_PWD_LEN + 1];
char newPwdB[MAX_PWD_LEN + 1];
if(!record.FindEntry(MODULE_IDENTIFIER_ME_KERNEL,
ME_VARIABLE_IDENTIFIER_CURRENT_MEBX_PWD,
&varLen, MAX_PWD_LEN, (unsigned char*)currPwdB))
{
return CONFIG_MISSING_CURR_PWD;
}
if(varLen == 0 || varLen > MAX_PWD_LEN)
{
return CONFIG_INVALID_CURR_PWD;
}
currPwdB[varLen] = 0;
if(!record.FindEntry(MODULE_IDENTIFIER_ME_KERNEL,
ME_VARIABLE_IDENTIFIER_NEW_MEBX_PWD,
&varLen, MAX_PWD_LEN, (unsigned char*)newPwdB))
{
return CONFIG_MISSING_NEW_PWD;
}
if(varLen < MIN_PWD_LEN || varLen > MAX_PWD_LEN)
{
return CONFIG_INVALID_NEW_PWD;
}
newPwdB[varLen] = 0;
if(!IsPasswordValid((char*)newPwdB))
{
return CONFIG_INVALID_NEW_PWD;
}
if(!record.FindEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PID,
&varLen, PID_LENGTH, (unsigned char*)pid))
{
return CONFIG_MISSING_PID;
}
if(varLen != PID_LENGTH)
{
return CONFIG_INVALID_PID;
}
if(!record.FindEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PPS,
&varLen, PPS_LENGTH, (unsigned char*)pps))
{
return CONFIG_MISSING_PPS;
}
if(varLen != PPS_LENGTH)
{
return CONFIG_INVALID_PPS;
}
if (!IsPskAllZeroes(pid, pps))
{
if (!IsPidValid(pid))
{
return CONFIG_INVALID_PID;
}
if (!IsPpsValid(pps))
{
return CONFIG_INVALID_PPS;
}
}
config->valid = true;
config->CurrentMEBxPwd = (char*)currPwdB;
config->NewMEBxPwd = (char*)newPwdB;
if (memcpy_s((char*)(config->Pid), PID_LENGTH, (char*)pid, PID_LENGTH))
{
return CONFIG_INVALID_PID;
}
if (memcpy_s((char*)(config->Pps), PPS_LENGTH, (char*)pps, PPS_LENGTH))
{
return CONFIG_INVALID_PPS;
}
return CONFIG_SUCCESS;
}
int ReadConfigFile(const string& fileName,
vector<ConfigRecord>& records)
{
ifstream ifs(fileName.c_str(), ifstream::binary);
if(!ifs.is_open())
{
return CONFIG_FILE_READ_ERROR;
}
ifs.seekg(0,ifstream::end);
unsigned int fileSize = ifs.tellg();
ifs.seekg(0);
unsigned char* data = new unsigned char[fileSize];
ifs.read((char*)data, fileSize);
ifs.close();
vector<DataRecord> dataRecords;
SetupFileInfo fileInfo;
int retVal = BufferToRecords(fileSize, data, &fileInfo, &dataRecords);
delete[] data;
data = NULL;
if(retVal != CONFIG_SUCCESS)
{
return retVal;
}
unsigned int numRecords = (unsigned int)dataRecords.size();
for(unsigned int i = 0; i < numRecords; i++)
{
ConfigRecord temp;
if(dataRecords[i].GetIsValid())
{
retVal = GetConfigRecord(dataRecords[i], &temp);
if(retVal != CONFIG_SUCCESS)
{
return retVal;
}
}
else
{
temp.valid = false;
}
records.push_back(temp);
}
return retVal;
}
int GetConfigFileRecord(const string& fileName,
const unsigned int index,
ConfigRecord* config)
{
ifstream ifs(fileName.c_str(), ifstream::binary);
if(!ifs.is_open())
{
return CONFIG_FILE_READ_ERROR;
}
ifs.seekg(0,ifstream::end);
unsigned int fileSize = ifs.tellg();
ifs.seekg(0);
unsigned char* data = new unsigned char[fileSize];
ifs.read((char*)data, fileSize);
ifs.close();
DataRecord record;
int retVal = GetRecordByIndex(fileSize, data, index, &record);
delete[] data;
data = NULL;
if(retVal != CONFIG_SUCCESS)
{
return retVal;
}
return GetConfigRecord(record, config);
}
int CreateDataRecord(const RecordSettings& settings, DataRecord& record)
{
/*********** Start of ME Kernel Variable Identifiers **********/
unsigned short currPwdLen = (unsigned short)settings.currentMEBxPwd.length();
if(currPwdLen == 0 || currPwdLen > MAX_PWD_LEN)
{
return CONFIG_INVALID_CURR_PWD;
}
if(!IsPasswordValid(settings.newMEBxPwd))
{
return CONFIG_INVALID_NEW_PWD;
}
// Current MEBx password (all versions)
record.AddRecordEntry(MODULE_IDENTIFIER_ME_KERNEL,
ME_VARIABLE_IDENTIFIER_CURRENT_MEBX_PWD,
currPwdLen,
(unsigned char*)settings.currentMEBxPwd.c_str());
// New MEBx password (all versions)
record.AddRecordEntry(MODULE_IDENTIFIER_ME_KERNEL,
ME_VARIABLE_IDENTIFIER_NEW_MEBX_PWD,
(unsigned short)settings.newMEBxPwd.length(),
(unsigned char*)settings.newMEBxPwd.c_str());
// Manageability Feature Selection (all versions)
if(settings.setAmt)
{
unsigned char man =
ME_VARIABLE_IDENTIFIER_MANAGEABILITY_FEATURE_AMT;
record.AddRecordEntry(MODULE_IDENTIFIER_ME_KERNEL,
ME_VARIABLE_IDENTIFIER_MANAGEABILITY_FEATURE_SELECTION,
ME_VARIABLE_IDENTIFIER_MANAGEABILITY_FEATURE_LEN, &man);
}
if(((2 == settings.majorVersion) && (1 == settings.minorVersion)) || (3 <= settings.majorVersion))
{
// Firmware Local Update (ver 2.1, 3 and 4)
if(settings.fwLocalUpdatePresent)
{
if((settings.fwLocalUpdateEnable == LOCAL_FW_UPDATE_PASSWORD_PROTECTED && 4 <= settings.majorVersion)
|| settings.fwLocalUpdateEnable == LOCAL_FW_UPDATE_DISABLED || settings.fwLocalUpdateEnable == LOCAL_FW_UPDATE_ENABLED)
{
unsigned char fwLocalUpdate = (unsigned char)settings.fwLocalUpdateEnable;
record.AddRecordEntry(MODULE_IDENTIFIER_ME_KERNEL,
ME_VARIABLE_IDENTIFIER_FW_LOCAL_UPDATE,
ME_VARIABLE_IDENTIFIER_FW_LOCAL_UPDATE_LEN, &fwLocalUpdate);
}
}
}
if(((2 == settings.majorVersion) && (1 == settings.minorVersion)) || (3 == settings.majorVersion))
{
// Firmware Update Qualifier (ver 2.1 and 3)
if (settings.fwUpdateQualifierPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_ME_KERNEL,
ME_VARIABLE_IDENTIFIER_FW_UPDATE_QUALIFIER,
ME_VARIABLE_IDENTIFIER_FW_UPDATE_QUALIFIER_LEN,
(const unsigned char *)&settings.fwUpdateQualifier);
}
}
if(((2 == settings.majorVersion) && (1 == settings.minorVersion)) || (3 <= settings.majorVersion))
{
// Power Packages (ver 2.1, 3 and 4)
if (settings.guidPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_ME_KERNEL,
ME_VARIABLE_IDENTIFIER_PP,
ME_VARIABLE_IDENTIFIER_PP_LEN,
(const unsigned char *)settings.guid);
}
}
/*********** End of ME Kernel Variable Identifiers **********/
/*********** Start of Intel(R) AMT CM Variable Identifiers **********/
// PID (all versions)
if(settings.pidValid)
{
if (!IsPskAllZeroes(settings.pid, settings.pps))
{
if(!IsPidValid(settings.pid))
{
return CONFIG_INVALID_PID;
}
}
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PID,
PID_LENGTH, (unsigned char*)&(settings.pid[0]));
}
// PPS (all versions)
if(settings.ppsValid)
{
if (!IsPskAllZeroes(settings.pid, settings.pps))
{
if(!IsPpsValid(settings.pps))
{
return CONFIG_INVALID_PPS;
}
}
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PPS,
PPS_LENGTH, (unsigned char*)&(settings.pps[0]));
}
if(settings.majorVersion >= 2)
{
// PKI DNS Suffix (ver 2, 2.1, 3 and 4)
if(settings.dnsSuffixValid)
{
if((settings.dnsSuffix.length() > CM_VARIABLE_IDENTIFIER_PKI_DNS_SUFFIX_MAXLEN) ||
(settings.dnsSuffix.empty()))
{
return CONFIG_INVALID_DNS_SUFFIX;
}
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PKI_DNS_SUFFIX,
(unsigned short)settings.dnsSuffix.length(),
(unsigned char*)settings.dnsSuffix.c_str());
}
// Config Server FQDN (ver 2, 2.1, 3 and 4)
if(settings.serverFqdnValid)
{
if((settings.ServerFqdn.length() > CM_VARIABLE_IDENTIFIER_CONFIG_SERVER_FQDN_MAXLEN) ||
(settings.ServerFqdn.empty()))
{
return CONFIG_INVALID_FQDN;
}
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_CONFIG_SERVER_FQDN,
(unsigned short)settings.ServerFqdn.length(),
(unsigned char*)settings.ServerFqdn.c_str());
}
// RCFG Enabled (ver 2, 2.1, 3 and 4)
if(settings.enableRCFGValid)
{
unsigned char rcfg = CM_VARIABLE_IDENTIFIER_RCFG_ENABLED_OFF;
if(settings.enableRCFG)
{
rcfg = CM_VARIABLE_IDENTIFIER_RCFG_ENABLED_ON;
}
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_RCFG_ENABLED,
CM_VARIABLE_IDENTIFIER_RCFG_ENABLED_LEN, &rcfg);
}
// Pre Installed (OEM) Cert Enable (ver 2, 2.1, 3 and 4)
if(settings.oemCertificateFlagExist)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PREINSTALLED_CERT_ENABLE,
CM_VARIABLE_IDENTIFIER_PREINSTALLED_CERT_ENABLE_LEN, (const unsigned char *)&settings.oemCertificateFlag);
}
// Pre Installed (OEM) Cert Enable (ver 2, 2.1, 3 and 4)
if(settings.userCertificateFlagExist)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_USER_DEFINED_CERTS_CONFIG,
CM_VARIABLE_IDENTIFIER_USER_DEFINED_CERTS_CONFIG_LEN, (const unsigned char *)&settings.userCertificateFlag);
}
if(!settings.certHashes.empty())
{
//// Pre Installed Cert Enable (ver 2, 2.1, 3 and 4)
//// Disable default
//unsigned char tmp = CM_VARIABLE_IDENTIFIER_PREINSTALLED_CERT_ENABLE_OFF;
//record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
// CM_VARIABLE_IDENTIFIER_PREINSTALLED_CERT_ENABLE,
// CM_VARIABLE_IDENTIFIER_PREINSTALLED_CERT_ENABLE_LEN, &tmp);
// User Defined Certs Config (ver 2, 2.1, 3 and 4)
// Delete existing user defined hashes
/*tmp = CM_VARIABLE_IDENTIFIER_USER_DEFINED_CERTS_CONFIG_DELETE;
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_USER_DEFINED_CERTS_CONFIG,
CM_VARIABLE_IDENTIFIER_USER_DEFINED_CERTS_CONFIG_LEN, &tmp);*/
// User Defined Cert Add (ver 2, 2.1, 3 and 4)
// Add new certs
unsigned char hash[CM_VARIABLE_IDENTIFIER_USER_DEFINED_CERT_ADD_MAXLEN];
for(unsigned int i = 0; i < settings.certHashes.size(); i++)
{
// SHA1 supported in ver 2, 2.1, 3 and 4 while SHA256 and SHA384 supported in ver 3 and 4 only;
// Therefore, add the cert to the file only if it stands in the described terms.
if ( (USB_CERT_HASH_ALGORITHM_SHA1 == settings.certHashes[i]._hashAlgorithm) ||
((USB_CERT_HASH_ALGORITHM_SHA256 == settings.certHashes[i]._hashAlgorithm ||
(USB_CERT_HASH_ALGORITHM_SHA384 == settings.certHashes[i]._hashAlgorithm))
&& (3 <= settings.majorVersion)))
{
hash[0] = settings.certHashes[i]._hashAlgorithm;
if(memcpy_s(hash + 1, ARRAYSIZE(hash) - 1, settings.certHashes[i]._hash, settings.certHashes[i]._hashLength))
{
return CONFIG_INVALID_CERT_SETTINGS;
}
memset(hash + 1 + settings.certHashes[i]._hashLength, 0,
CM_VARIABLE_IDENTIFIER_USER_DEFINED_CERT_ADD_MAXLEN - (1 + settings.certHashes[i]._hashLength));
// Friendly name length is assumed to be <= 32
*(hash + 1 + settings.certHashes[i]._hashLength) =
(unsigned char)settings.certHashes[i]._friendlyName.length();
if (memcpy_s(hash + 1 + settings.certHashes[i]._hashLength + 1,
ARRAYSIZE(hash) - settings.certHashes[i]._hashLength -2,
settings.certHashes[i]._friendlyName.c_str(),
settings.certHashes[i]._friendlyName.length()))
{
return CONFIG_INVALID_CERT_SETTINGS;
}
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_USER_DEFINED_CERT_ADD,
1 + settings.certHashes[i]._hashLength + 1 + (unsigned short)settings.certHashes[i]._friendlyName.length(),
hash);
}
}
}
// SOL IDER Config (ver 2, 2.1,3 and 4)
if(settings.soliderConfigValid)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_SOL_IDE_REDIRECTION_CONFIG,
CM_VARIABLE_IDENTIFIER_SOL_IDE_REDIRECTION_CONFIG_LEN,
&settings.soliderConfig);
}
}
if(((2 == settings.majorVersion) && (1 == settings.minorVersion)) || (3 <= settings.majorVersion))
{
// Host Name (ver 2.1, 3 and 4)
if (settings.hostNamePresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_HOST_NAME,
(unsigned short)settings.hostName.length(),
(const unsigned char *)settings.hostName.c_str());
}
// Domain Name (ver 2.1, 3 and 4)
if (settings.domainNamePresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_DOMAIN_NAME,
(unsigned short)settings.domainName.length(),
(const unsigned char *)settings.domainName.c_str());
}
// DHCP (ver 2.1, 3 and 4)
if (settings.dhcpPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_DHCP,
DHCP_LENGTH, (const unsigned char *)&settings.dhcp);
}
// Secure Firmware Update (ver 2.1 and 3)
if (3 >= settings.majorVersion && settings.secureFWUpdatePresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_SFWU,
SFWU_LENGTH, (const unsigned char *)&settings.secureFWUpdate);
}
// Idle timeout (ver 2.1, 3 and 4)
if (settings.idleTimeOutPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_ITO,
IDLE_TIMEOUT_LENGTH, (const unsigned char *)settings.idleTimeOut);
}
// Provisioning Mode (ver 2.1, deprecated from 3)
if (settings.provisionModePresent)
{
if (3 <= settings.majorVersion)
{
cout << endl
<< "Warning: Entering the 'Provisioning Mode' variable (configured using the '-pm' flag)"
<< endl << "\t to the file even though it is deprecated starting from version 3" << endl;
}
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PM,
PM_LENGTH, (const unsigned char *)&settings.provisionMode);
}
// Provisioning Server Address (ver 2.1, 3 and 4)
if (settings.provisionServerAddPresent)
{
// IPv4 supported in ver 2.1, 3 and 4 while IPv6 supported in ver 3 and 4 only;
// Therefore, add the provision server address to the file only if it stands in the described terms.
if ((IPV4 == settings.provisionServerAddType) ||
((IPV6 == settings.provisionServerAddType) && (3 <= settings.majorVersion)))
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PSADDR,
settings.provisionServerAddSize,
(const unsigned char *)settings.provisionServerAdd);
}
}
// Provisioning Server Port (ver 2.1, 3 and 4)
if (settings.provisionServerPortPresent)
{
// IPv4 supported in ver 2.1, 3 and 4 while IPv6 supported in ver 3 and 4 only;
// Therefore, add the provision server port to the file only if it stands in the described terms.
// (This check prevent from the user to add only the provision server port,
// in case ipv6 address was given in ver 2.1)
if ((IPV4 == settings.provisionServerAddType) ||
((IPV6 == settings.provisionServerAddType) && (3 <= settings.majorVersion)))
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PSPO,
PROSERPORT_SIZE, (const unsigned char *)settings.provisionServerPort);
}
}
// Static IPv4 Parameters (ver 2.1, 3 and 4)
if (settings.staticIPv4ParamsPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_STATIC_PV4_PARAMS,
STATIC_PV4_PARAMS_SIZE, (const unsigned char *)settings.staticIPv4Params);
}
// VLAN (ver 2.1, 3 and 4)
if (settings.vlanPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_VLAN,
VLAN_SIZE, (const unsigned char *)settings.vlan);
}
// MEBx Password Change Policy (ver 2.1, 3 and 4)
if(settings.passPolicyFlagExist)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PASS_POLICY_FLAG,
PASS_POLICY_FLAG_SIZE, (const unsigned char *)&settings.passPolicyFlag);
}
}
if(3 <= settings.majorVersion)
{
// IPV6 (from ver 3 only)
if (settings.ipv6ParamsPresent)
{
if(4 <= settings.majorVersion)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_IPV6,
CM_VARIABLE_IDENTIFIER_IPV6_LEN_NEW_FORMAT,
(const unsigned char *)settings.ipv6Params);
}
else
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_IPV6,
CM_VARIABLE_IDENTIFIER_IPV6_LEN,
(const unsigned char *)settings.ipv6Params);
}
}
// Shared/Dedicated FQDN (from ver 3 only)
if(settings.sharedDedicatedFqdnPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_SHARED_DEDICATED_FQDN,
CM_VARIABLE_IDENTIFIER_SHARED_DEDICATED_FQDN_LEN,
(const unsigned char *)&settings.sharedDedicatedFqdn);
}
// Dynamic DNS Update (from ver 3 only)
if(settings.dynamicDnsUpdatePresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_DYNAMIC_DNS_UPDATE,
CM_VARIABLE_IDENTIFIER_DYNAMIC_DNS_UPDATE_LEN,
(const unsigned char *)&settings.dynamicDnsUpdate);
}
// KVM State (from ver 3 only)
if(settings.kvmStatePresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_KVM_STATE,
CM_VARIABLE_IDENTIFIER_KVM_STATE_LEN,
(const unsigned char *)&settings.kvmState);
}
// Opt-In user consent option (from ver 3 only)
if(settings.optInUserConsentPresent)
{
//'all' (0xFF) option is supported starting from version 4 only
if (settings.optInUserConsentOption != CM_VARIABLE_IDENTIFIER_OPT_IN_USER_CONSENT_ENABLE_ALL
|| settings.majorVersion == 4)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_OPT_IN_USER_CONSENT_OPTION,
CM_VARIABLE_IDENTIFIER_OPT_IN_USER_CONSENT_OPTION_LEN,
(const unsigned char *)&settings.optInUserConsentOption);
}
}
// Opt-In remote IT consent policy (from ver 3 only)
if(settings.optInRemoteITPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_OPT_IN_REMOTE_IT_CONSENT_POLICY,
CM_VARIABLE_IDENTIFIER_OPT_IN_REMOTE_IT_CONSENT_POLICY_LEN,
(const unsigned char *)&settings.optInRemoteItPolicy);
}
// ME provisioning Halt/Activate (from ver 3 only)
if(settings.meProvisioningHaltActivatePresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_ME_PROVISION_HALT_ACTIVE,
CM_VARIABLE_IDENTIFIER_ME_PROVISION_HALT_ACTIVE_LEN,
(const unsigned char *)&settings.meProvisioningHaltActivate);
}
// Manual Setup and Configuration (from ver 3 only)
if(settings.manualSetupAndConfigurationPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_MANUAL_SETUP_AND_CONFIGURATION,
CM_VARIABLE_IDENTIFIER_MANUAL_SETUP_AND_CONFIGURATION_LEN,
(const unsigned char *)&settings.manualSetupAndConfiguration);
}
// Support Channel Identifier (from ver 3 only)
if (settings.supportChannelIdentifierPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_SUPPORT_CHANNEL_IDENTIFIER,
CM_VARIABLE_IDENTIFIER_SUPPORT_CHANNEL_IDENTIFIER_LEN,
(const unsigned char *)settings.supportChannelIdentifier);
}
// Support Channel Description (from ver 3 only)
if (settings.supportChannelDescriptionPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_SUPPORT_CHANNEL_DESCRIPTION,
(unsigned short)settings.supportChannelDescription.length(),
(const unsigned char *)settings.supportChannelDescription.c_str());
}
// Service Account Number (from ver 3 only)
if (settings.serviceAccountNumberPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_SERVICE_ACCOUNT_NUMBER,
(unsigned short)settings.serviceAccountNumber.length(),
(const unsigned char *)settings.serviceAccountNumber.c_str());
}
// Enrollment Passcode (from ver 3 only)
if (settings.enrollmentPasscodePresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_ENROLLMENT_PASSCODE,
(unsigned short)settings.enrollmentPasscode.length(),
(const unsigned char *)settings.enrollmentPasscode.c_str());
}
// Service Type (from ver 3 only)
if (settings.serviceTypePresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_SERVICE_TYPE,
CM_VARIABLE_IDENTIFIER_SERVICE_TYPE_LEN,
(const unsigned char *)settings.serviceType);
}
// Service Provider Identifier (from ver 3 only)
if (settings.serviceProviderIdentifierPresent)
{
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_SERVICE_PROVIDER_IDENTIFIER,
CM_VARIABLE_IDENTIFIER_SERVICE_PROVIDER_IDENTIFIER_LEN,
(const unsigned char *)settings.serviceProviderIdentifier);
}
}
if (4 == settings.majorVersion && settings.scrambleRecords)
{
record.SetScrambled(true);
}
/*********** End of Intel(R) AMT CM Variable Identifiers **********/
return CONFIG_SUCCESS;
}
int WriteConfigFile(const RecordSettings& settings,
const string& fileName,
bool overwrite,
vector<ConfigRecord>* cfgRecords)
{
if(!overwrite && MyFileExists(fileName))
{
return CONFIG_FILE_WRITE_ERROR;
}
vector<DataRecord> records;
int retVal;
DataRecord commonData; // default ctr
// create data record adds all of the common fields
retVal = CreateDataRecord(settings, commonData);
if(retVal != CONFIG_SUCCESS)
{
return retVal;
}
for(int i = 0; i < settings.numRecords; i++)
{
DataRecord record(commonData);
ConfigRecord cfgRecord;
cfgRecord.valid = true;
cfgRecord.hasPskPair = false;
cfgRecord.CurrentMEBxPwd = settings.currentMEBxPwd;
cfgRecord.NewMEBxPwd = settings.newMEBxPwd;
if (!((settings.provisionModePresent)&&(CM_VARIABLE_IDENTIFIER_PM_SMB == settings.provisionMode)))
{
// make sure settings does not have pid\pps before generating
if(settings.generateRandomPskPair && !settings.pidValid && !settings.ppsValid)
{
char pid[PID_LENGTH];
RandomPid(pid);
char pps[PPS_LENGTH];
RandomPps(pps);
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PID,
PID_LENGTH, (unsigned char*)pid);
record.AddRecordEntry(MODULE_IDENTIFIER_AMT_CM,
CM_VARIABLE_IDENTIFIER_PPS,
PPS_LENGTH, (unsigned char*)pps);
if (memcpy_s(&cfgRecord.Pid[0], ARRAYSIZE(cfgRecord.Pid), &pid[0], ARRAYSIZE(pid)))
{
return CONFIG_FILE_WRITE_ERROR;
}
if (memcpy_s(&cfgRecord.Pps[0], ARRAYSIZE(cfgRecord.Pps), &pps[0], ARRAYSIZE(pps)))
{
return CONFIG_FILE_WRITE_ERROR;
}
cfgRecord.hasPskPair = true;
}
else if (settings.pidValid && settings.ppsValid)
{
if (memcpy_s(&cfgRecord.Pid[0], ARRAYSIZE(cfgRecord.Pid), settings.pid, ARRAYSIZE(settings.pid)))
{
return CONFIG_FILE_WRITE_ERROR;
}
if (memcpy_s(&cfgRecord.Pps[0], ARRAYSIZE(cfgRecord.Pps), settings.pps, ARRAYSIZE(settings.pps)))
{
return CONFIG_FILE_WRITE_ERROR;
}
cfgRecord.hasPskPair = true;
}
}
if(cfgRecords)
{
cfgRecords->push_back(cfgRecord);
}
records.push_back(record);
}
SetupFileInfo fileInfo;
fileInfo.majorVersion = settings.majorVersion;
switch(settings.majorVersion)
{
case SETUP_FILE_VERSION_1:
fileInfo.minorVersion = 0;
if (false == settings.multiple)
{
fileInfo.consumeRecords = true;
}
break;
case SETUP_FILE_VERSION_2:
fileInfo.minorVersion = settings.minorVersion;
if (false == settings.multiple)
{
fileInfo.consumeRecords = settings.consumable;
}
break;
case SETUP_FILE_VERSION_3:
fileInfo.minorVersion = 0;
if (false == settings.multiple)
{
fileInfo.consumeRecords = settings.consumable;
}
break;
case SETUP_FILE_VERSION_4:
fileInfo.minorVersion = 0;
if (false == settings.multiple)
{
fileInfo.consumeRecords = settings.consumable;
}
break;
default:
return CONFIG_VERSION_UNSUPPORTED;
}
if (settings.multiple)
{
fileInfo.consumeRecords = true;
}
fileInfo.headerChunkCount = SINGLE_CHUNK_COUNT;
fileInfo.recordCount = settings.numRecords;
fileInfo.recordsConsumed = 0;
// all records require the same chunk count
fileInfo.dataRecordChunkCount = GetChunkCount(records[0]);
unsigned int bufferLength = (unsigned int)CHUNK_SIZE *
(fileInfo.headerChunkCount + records.size()*fileInfo.dataRecordChunkCount);
unsigned char* data = new unsigned char[bufferLength];
memset(data, 0, bufferLength);
retVal = RecordsToBuffer(records, fileInfo, bufferLength, data);
if(retVal == CONFIG_SUCCESS)
{
ofstream setupFile(fileName.c_str(), ios_base::binary);
if(!setupFile.is_open())
{
retVal = CONFIG_FILE_WRITE_ERROR;
}
else
{
setupFile.write((char*)data,bufferLength);
setupFile.close();
}
}
delete[] data;
data = NULL;
return retVal;
}
int ParseUsbFile(const string& fileName,
SetupFileInfo* fileInfo,
vector<DataRecord>* records)
{
ifstream ifs(fileName.c_str(), ifstream::binary);
if(!ifs.is_open())
{
return CONFIG_FILE_READ_ERROR;
}
ifs.seekg(0,ifstream::end);
unsigned int fileSize = ifs.tellg();
ifs.seekg(0);
unsigned char* data = new unsigned char[fileSize];
ifs.read((char*)data, fileSize);
ifs.close();
int retVal = BufferToRecords(fileSize, data, fileInfo, records);
delete[] data;
data = NULL;
return retVal;
}
int DumpUsbFile(const string& fileName, ostream& out, bool printRecords)
{
SetupFileInfo info;
info.majorVersion = 0;
info.minorVersion = 0;
info.consumeRecords = false;
info.recordCount = 0;
info.recordsConsumed = 0;
vector<DataRecord> records;
int retVal = CONFIG_SUCCESS;
if(CONFIG_SUCCESS != (retVal = ParseUsbFile(fileName, &info, &records)))
{
return retVal;
}
out << "USB file " << fileName.c_str() << " Contents:" << endl;
out << "Setup File version = " << (unsigned int)info.majorVersion
<< "." << (unsigned int)info.minorVersion << endl;
out << "Is Consumable = "
<< (info.consumeRecords ? "True" : "False") << endl;
out << "Total Records = " << info.recordCount << endl;
out << "Consumed Records = " << info.recordsConsumed << endl << endl;
if(printRecords)
{
out << "Valid Records:" << endl;
int recordValid;
for(unsigned int i = 0; i < (unsigned int)records.size(); i++)
{
out << "Record " << info.recordsConsumed + i + 1 << ":" << endl;
if(CONFIG_SUCCESS != (recordValid = PrintDataRecord(records[i], out, (unsigned int)info.majorVersion)))
{
out << "Illegal Record!!!" << endl;
out << "The following error code was received while printing "
"this record " << recordValid << endl;
retVal = CONFIG_INVALID_RECORD;
}
out << endl;
}
}
return retVal;
}
// print a pid
void PrintPid(const unsigned char* pid, ostream& out)
{
for (int j=0; j<4; j++)
{
out << pid[j];
}
out << "-";
for (int j=4; j<8; j++)
{
out << pid[j];
}
}
void PrintGuid(const unsigned char* guid, ostream& out)
{
out << hex;
for (int i=0;i<16;i++)
{
if ((4==i) || (6==i) || (8==i) || (10==i))
out << "-";
if (i<4)
out << setfill('0') << setw(2) <<(int)guid[3-i];
if ((i>=4)&&(i<=7))
{
if (i%2==0)
out << setfill('0') << setw(2) <<(int)guid[i+1];
else out << setfill('0') << setw(2) <<(int)guid[i-1];
}
if (i>7)
out << setfill('0') << setw(2) <<(int)guid[i];
}
out<<dec;
}
// print a pps
void PrintPps(const unsigned char* pps, ostream& out)
{
for (int j=0; j<4; j++)
out << pps[j];
for (int k=0; k<7; k++)
{
out << "-";
for (int j=0; j<4; j++)
{
out << pps[(k+1)*4 + j];
}
}
}
// print a cert hash
void PrintCertHash(const unsigned char* hash, unsigned char hashAlgorithm, ostream& out)
{
unsigned int hashSize = 0;
if (USB_CERT_HASH_ALGORITHM_SHA1 == hashAlgorithm)
{
hashSize = CERT_HASH_SHA1_LENGTH;
}
else if (USB_CERT_HASH_ALGORITHM_SHA256 == hashAlgorithm)
{
hashSize = CERT_HASH_SHA256_LENGTH;
}
else if (USB_CERT_HASH_ALGORITHM_SHA384 == hashAlgorithm)
{
hashSize = CERT_HASH_SHA384_LENGTH;
}
else
{
return;
}
for(unsigned int i = 0; i < hashSize; i++)
{
out << hex << setfill('0') << setw(2) << (unsigned int)hash[i];
if( i != hashSize - 1)
{
out << " ";
}
if (((i+1)%16 == 0) && (i+1<hashSize))
{
out << "\n\t\t\t\t ";
}
}
}
int PrintDataRecord(const DataRecord& record, ostream& out, unsigned int majorVersion)
{
string newValue;
int retVal = CONFIG_SUCCESS;
unsigned short length;
unsigned char* value;
unsigned short dhcpConfiguration;
unsigned short provisioningMode;
IPV6SettingsNewFormat ipv6SettingNewFormat;
if ( record.GetIsScrambled())
{
out << "--Scrambled record--" << endl;
}
vector<DataRecordEntry> entries = record.GetRecordEntries();
for(unsigned int i = 0; i < (unsigned int) entries.size(); i++)
{
length = entries[i].GetVariableLength();
value = new unsigned char[length + 1];
entries[i].GetVariableValue(length, value);
value[length] = 0;
switch(entries[i].GetModuleId())
{
case MODULE_IDENTIFIER_ME_KERNEL:
switch(entries[i].GetVariableId())
{
case ME_VARIABLE_IDENTIFIER_CURRENT_MEBX_PWD:
if(length == 0 || length > MAX_PWD_LEN)
{
retVal = CONFIG_INVALID_CURR_PWD;
break;
}
out << " Current MEBx password = "
<< value << endl;
break;
case ME_VARIABLE_IDENTIFIER_NEW_MEBX_PWD:
if(length < MIN_PWD_LEN || length > MAX_PWD_LEN)
{
retVal = CONFIG_INVALID_NEW_PWD;
break;
}
out << " New MEBx password = " << value << endl;
break;
case ME_VARIABLE_IDENTIFIER_MANAGEABILITY_FEATURE_SELECTION:
if(length != ME_VARIABLE_IDENTIFIER_MANAGEABILITY_FEATURE_LEN)
{
retVal = CONFIG_INVALID_MANAGEABILITY_FEATURE_SELECTION;
break;
}
out << " Manageability mode = "
<< (unsigned short) value[0] <<endl;
break;
case ME_VARIABLE_IDENTIFIER_FW_LOCAL_UPDATE:
if (length != ME_VARIABLE_IDENTIFIER_FW_LOCAL_UPDATE_LEN)
{
retVal =CONFIG_INVALID_INPUT;
break;
}
out << " Firmware local update = "
<< (unsigned short) value[0]<<endl;
break;
case ME_VARIABLE_IDENTIFIER_FW_UPDATE_QUALIFIER:
if (length != ME_VARIABLE_IDENTIFIER_FW_UPDATE_QUALIFIER_LEN)
{
retVal =CONFIG_INVALID_INPUT;
break;
}
out << " Firmware local update qualifier = "
<< (unsigned short) value[0]<<endl;
break;
case ME_VARIABLE_IDENTIFIER_PP:
if (length != ME_VARIABLE_IDENTIFIER_PP_LEN)
{
retVal = CONFIG_INVALID_INPUT;
break;
}
out << " Power packages = " ;
PrintGuid(value, out);
out<<endl;
break;
default:
// unrecognized
break;
}
break;
case MODULE_IDENTIFIER_AMT_CM:
switch(entries[i].GetVariableId())
{
case CM_VARIABLE_IDENTIFIER_HOST_NAME:
if (length>HOSTNAME_MAX_LENGTH)
{
retVal = CONFIG_INVALID_PID;
break;
}
cout << " Host Name = "
<< value << endl;
break;
case CM_VARIABLE_IDENTIFIER_DOMAIN_NAME:
if (length>DOMAIN_NAME_MAX_LENGTH)
{
retVal = CONFIG_INVALID_PID;
break;
}
cout << " Domain Name = "
<< value << endl;
break;
case CM_VARIABLE_IDENTIFIER_DHCP:
// The actual enumeration is 1 for disable and 2 for enable.
// The user input however is 0 for disable and 2 for enable
// and in the code it increased by 1 to match the SPEC.
// To view the file theres a need to substract one from the actual
// enumeration in order match the user input.
dhcpConfiguration = ((unsigned short)value[0])-1;
cout << " DHCP configuration = " << dhcpConfiguration;
if (0 == dhcpConfiguration)
{
cout << " (Disabled)";
}
else if (1 == dhcpConfiguration)
{
cout << " (Enabled)";
}
else
{
cout << " (Unknown)";
}
cout << endl;
break;
case CM_VARIABLE_IDENTIFIER_SFWU:
cout << " Secure Firmware update = "
<< (unsigned short)value[0] << endl;
break;
case CM_VARIABLE_IDENTIFIER_PM:
// The actual enumeration is 1 for Enterprise and 2 for Small Business.
// The user input however is 0 for Enterprise and 1 for Small Business
// and in the code it increased by 1 to match the SPEC.
// To view the file theres a need to substract one from the actual
// enumeration in order match the user input.
provisioningMode = ((unsigned short)value[0])-1;
cout << " Provisioning mode = " << provisioningMode;
if (0 == provisioningMode)
{
cout << " (Enterprise)";
}
else if (1 == provisioningMode)
{
cout << " (Small Business)";
}
else
{
cout << " (Unknown)";
}
cout << endl;
break;
case CM_VARIABLE_IDENTIFIER_ITO:
cout << " Idle Time Out is = "<< (unsigned short)*((unsigned short *)value) << endl;
break;
case CM_VARIABLE_IDENTIFIER_PSADDR:
if (PROSERADDR_IPV4_SIZE == entries[i].GetVariableLength())
{
printf (" Provision Server Address = %d.%d.%d.%d \n",value[3],value[2],value[1],value[0]);
}
else if (PROSERADDR_IPV6_SIZE == entries[i].GetVariableLength())
{
cout << " Provision Server Address = ";
for (int i=(PROSERADDR_IPV6_SIZE-1) ; i >= 0 ; i--)
{
if (((i+1)%2==0) && ((i+1)!=PROSERADDR_IPV6_SIZE))
{
cout << ":";
}
cout << hex << setfill('0') << setw(2) << (unsigned short)value[i];
}
cout << dec << endl;
}
break;
case CM_VARIABLE_IDENTIFIER_PSPO :
cout <<" Provision Server port number = "<<(unsigned short)*((unsigned short *)value)<<endl;
break;
case CM_VARIABLE_IDENTIFIER_VLAN :
cout <<" VlanStatus = "<<(unsigned int)*((unsigned char *)value)<<endl
<<" VlanTag = "<<(unsigned short)*((unsigned short *)(value+1))<<endl;
break;
case CM_VARIABLE_IDENTIFIER_PASS_POLICY_FLAG:
{
cout << " Password policy flag = " << (UINT32)*value << endl;
break;
}
case CM_VARIABLE_IDENTIFIER_STATIC_PV4_PARAMS:
printf (" Local Address = %d.%d.%d.%d \n",value[3],value[2],value[1],value[0]);
printf (" Subnet mask = %d.%d.%d.%d \n",value[7],value[6],value[5],value[4]);
printf (" Default Gateway Address = %d.%d.%d.%d \n",value[11],value[10],value[9],value[8]);
printf (" Primary DNS Address = %d.%d.%d.%d \n",value[15],value[14],value[13],value[12]);
printf (" Secondary DNS Address = %d.%d.%d.%d \n",value[19],value[18],value[17],value[16]);
break;
case CM_VARIABLE_IDENTIFIER_PID:
char tmpZeroedPps[PPS_LENGTH];
for (int i=0 ; i<PPS_LENGTH; tmpZeroedPps[i] = 0, i++);
if (IsPskAllZeroes((char*)value, tmpZeroedPps))
{
if(length != PID_LENGTH || !IsPidValid((char*)value))
{
retVal = CONFIG_INVALID_PID;
break;
}
}
cout << " PID = ";
PrintPid(value, out);
out << endl;
break;
case CM_VARIABLE_IDENTIFIER_PPS:
char tmpZeroedPid[PPS_LENGTH];
for (int i=0 ; i<PID_LENGTH; tmpZeroedPid[i] = 0, i++);
if (IsPskAllZeroes(tmpZeroedPid, (char*)value))
{
if(length != PPS_LENGTH || !IsPpsValid((char*)value))
{
retVal = CONFIG_INVALID_PPS;
break;
}
}
cout << " PPS = ";
PrintPps(value, out);
out << endl;
break;
case CM_VARIABLE_IDENTIFIER_PKI_DNS_SUFFIX:
if((length > CM_VARIABLE_IDENTIFIER_PKI_DNS_SUFFIX_MAXLEN) || (length == 0))
{
retVal = CONFIG_INVALID_DNS_SUFFIX;
break;
}
cout << " PKI DNS Suffix = "
<< value << endl;
break;
case CM_VARIABLE_IDENTIFIER_CONFIG_SERVER_FQDN:
if((length > CM_VARIABLE_IDENTIFIER_CONFIG_SERVER_FQDN_MAXLEN) || (length == 0))
{
retVal = CONFIG_INVALID_FQDN;
break;
}
cout << " Provisioing Server FQDN = "
<< value << endl;
break;
case CM_VARIABLE_IDENTIFIER_RCFG_ENABLED:
if(length != CM_VARIABLE_IDENTIFIER_RCFG_ENABLED_LEN)
{
retVal = CONFIG_INVALID_ZTC_ENABLED;
break;
}
out << " ZTC Enabled = "
<< (unsigned short)value[0] <<endl;
break;
case CM_VARIABLE_IDENTIFIER_PREINSTALLED_CERT_ENABLE:
if(length != CM_VARIABLE_IDENTIFIER_PREINSTALLED_CERT_ENABLE_LEN)
{
retVal = CONFIG_INVALID_CERT_SETTINGS;
break;
}
out << " Preinstalled Cert Hash Enable = "
<< (unsigned short)value[0] <<endl;
break;
case CM_VARIABLE_IDENTIFIER_USER_DEFINED_CERTS_CONFIG:
if(length != CM_VARIABLE_IDENTIFIER_PREINSTALLED_CERT_ENABLE_LEN)
{
retVal = CONFIG_INVALID_CERT_SETTINGS;
break;
}
out << " User Defined Hash Configuration = "
<< (unsigned short)value[0] <<endl;
break;
case CM_VARIABLE_IDENTIFIER_USER_DEFINED_CERT_ADD:
{
bool ok = true;
if(length > CM_VARIABLE_IDENTIFIER_USER_DEFINED_CERT_ADD_MAXLEN)
ok = false;
size_t friendlyNameLength = 0;
string hashAlgorithmName = "";
size_t friendlyNameIndex = 2;
if (USB_CERT_HASH_ALGORITHM_SHA1 == *(value))
{
friendlyNameLength = *(value + 1 + CERT_HASH_SHA1_LENGTH);
friendlyNameIndex += CERT_HASH_SHA1_LENGTH;
hashAlgorithmName = "SHA1";
}
else if (USB_CERT_HASH_ALGORITHM_SHA256 == *(value))
{
friendlyNameLength = *(value + 1 + CERT_HASH_SHA256_LENGTH);
friendlyNameIndex += CERT_HASH_SHA256_LENGTH;
hashAlgorithmName = "SHA256";
}
else if (USB_CERT_HASH_ALGORITHM_SHA384 == *(value))
{
friendlyNameLength = *(value + 1 + CERT_HASH_SHA384_LENGTH);
friendlyNameIndex += CERT_HASH_SHA384_LENGTH;
hashAlgorithmName = "SHA384";
}
else
{
ok = false;
}
if (friendlyNameLength > MAX_FRIENDLY_NAME_LENGTH)
{
ok = false;
}
if (!ok)
{
retVal = CONFIG_INVALID_CERT_SETTINGS;
break;
}
out << " User Defined Certificate Hash = ";
PrintCertHash(value + 1, *(value), out);
out << endl;
out << " Hash Algorithm = "
<< (unsigned short)(*value) << " (" << hashAlgorithmName << ")" << endl;
out << " Friendly Name = "
<< value + friendlyNameIndex << endl;
}
break;
case CM_VARIABLE_IDENTIFIER_SOL_IDE_REDIRECTION_CONFIG:
if(length != CM_VARIABLE_IDENTIFIER_SOL_IDE_REDIRECTION_CONFIG_LEN)
{
retVal = CONFIG_INVALID_SOLIDER_CONFIG;
break;
}
out << " SOL/IDE-R Config = "
<< (unsigned short)value[0] <<endl;
break;
case CM_VARIABLE_IDENTIFIER_IPV6:
cout << " Interface Index = "
<< ((unsigned short)value[IPV6_INTERFACE_INDEX_OFFSET]) << endl;
cout << " IPv6 Enabled = "
<< ((unsigned short)value[IPV6_ENABLED_OFFSET]) << endl;
cout << " Interface ID Type = "
<< ((unsigned short)value[IPV6_INTERFACE_ID_TYPE_OFFSET]) << endl;
cout << " Interface ID = " << value+IPV6_INTERFACE_ID_OFFSET << endl;
if(majorVersion >= 4)
{
ParseIPv6(value+IPV6_ADDRESS_OFFSET,ipv6SettingNewFormat.ipv6Address);
ParseIPv6(value+IPV6_DEFAULT_ROUTER_OFFSET_NEW_FORMAT,ipv6SettingNewFormat.defultRouter);
ParseIPv6(value+IPV6_PRIMARY_DNS_ADD_OFFSET_NEW_FORMAT,ipv6SettingNewFormat.primaryDNS);
ParseIPv6(value+IPV6_SECONDARY_DNS_ADD_OFFSET_NEW_FORMAT,ipv6SettingNewFormat.secondaryDNS);
cout << " IPv6 Address = " << ipv6SettingNewFormat.ipv6Address << endl;
cout << " IPv6 Default Router = " << ipv6SettingNewFormat.defultRouter<< endl;
cout << " DNS Primary IPv6 Address = " << ipv6SettingNewFormat.primaryDNS << endl;
cout << " DNS Secondary IPv6 Address = " << ipv6SettingNewFormat.secondaryDNS << endl;
}
else
{
cout << " IPv6 Address = " << value+IPV6_ADDRESS_OFFSET << endl;
cout << " IPv6 Default Router = " << value+IPV6_DEFAULT_ROUTER_OFFSET<< endl;
cout << " DNS Primary IPv6 Address = " << value+IPV6_PRIMARY_DNS_ADD_OFFSET << endl;
cout << " DNS Secondary IPv6 Address = " << value+IPV6_SECONDARY_DNS_ADD_OFFSET << endl;
}
break;
case CM_VARIABLE_IDENTIFIER_SHARED_DEDICATED_FQDN:
cout << " Shared/Dedicated FQDN = "
<< ((unsigned short)value[0]) << endl;
break;
case CM_VARIABLE_IDENTIFIER_DYNAMIC_DNS_UPDATE:
cout << " Dynamic DNS Update = "
<< ((unsigned short)value[0]) << endl;
break;
case CM_VARIABLE_IDENTIFIER_KVM_STATE:
cout << " KVM State = "
<< ((unsigned short)value[0]) << endl;
break;
case CM_VARIABLE_IDENTIFIER_OPT_IN_USER_CONSENT_OPTION:
cout << " Opt-In user consent option = "
<< ((unsigned short)value[0]) << endl;
break;
case CM_VARIABLE_IDENTIFIER_OPT_IN_REMOTE_IT_CONSENT_POLICY:
cout << " Opt-In remote IT consent policy = "
<< ((unsigned short)value[0]) << endl;
break;
case CM_VARIABLE_IDENTIFIER_ME_PROVISION_HALT_ACTIVE:
cout << " ME provisioning Halt/Activate = "
<< ((unsigned short)value[0]) << endl;
break;
case CM_VARIABLE_IDENTIFIER_MANUAL_SETUP_AND_CONFIGURATION:
cout << " Manual Setup and Configuration = "
<< ((unsigned short)value[0]) << endl;
break;
case CM_VARIABLE_IDENTIFIER_SUPPORT_CHANNEL_IDENTIFIER:
cout << " Support Channel Identifier is = "<< (unsigned int)*((unsigned int *)value) << endl;
break;
case CM_VARIABLE_IDENTIFIER_SUPPORT_CHANNEL_DESCRIPTION:
if (length > SUPPORT_CHANNEL_DESC_MAX_LENGTH)
{
retVal = CONFIG_INVALID_SUPPORT_CH_DESC;
break;
}
cout << " Support Channel Description = " << value << endl;
break;
case CM_VARIABLE_IDENTIFIER_SERVICE_ACCOUNT_NUMBER:
if (length > SERVICE_ACCOUNT_NO_MAX_LENGTH)
{
retVal = CONFIG_INVALID_SERVICE_ACC_NO;
break;
}
cout << " Service Account Number = " << value << endl;
break;
case CM_VARIABLE_IDENTIFIER_ENROLLMENT_PASSCODE:
if (length > ENROLLMENT_PASSCODE_MAX_LENGTH)
{
retVal = CONFIG_INVALID_ENROLLMENT_PASSCODE;
break;
}
cout << " Enrollment Passcode = " << value << endl;
break;
case CM_VARIABLE_IDENTIFIER_SERVICE_TYPE:
cout << " Service Type = "
<< ((unsigned short)value[0]) << endl;
break;
case CM_VARIABLE_IDENTIFIER_SERVICE_PROVIDER_IDENTIFIER:
if (length != CM_VARIABLE_IDENTIFIER_SERVICE_PROVIDER_IDENTIFIER_LEN)
{
retVal = CONFIG_INVALID_INPUT;
break;
}
out << " Service Provider Identifier = ";
PrintGuid(value,out);
out<<endl;
break;
default:
// unrecognized
break;
}
break;
default:
// module id not recognized
break;
}
delete[] value;
value = NULL;
if(retVal != CONFIG_SUCCESS)
{
break;
}
}
return retVal;
}
int ScrambleRecordData(unsigned char* recordData, const size_t recordDataSize)
{
for(unsigned int i = 0; i < recordDataSize; i ++)
{
recordData[i] = (recordData[i] + SCRAMBLE_SHIFTING_VALUE) % 256;
}
return CONFIG_SUCCESS;
}
int DescrambleRecordData(unsigned char* recordData, const size_t recordDataSize)
{
for(unsigned int i = 0; i < recordDataSize; i ++)
{
recordData[i] = (recordData[i] + (256 - SCRAMBLE_SHIFTING_VALUE)) % 256;
}
return CONFIG_SUCCESS;
}
bool ParseIPv6(unsigned char* ipv6PartByteArray, string & ipv6PartInput)
{
unsigned char* ipv6Part = ipv6PartByteArray;
byte ipv6Byte;
char buf[40];
int k = 0;
for (int ipv6PartByteArrayIndex = 15,i = 0 ; (ipv6PartByteArrayIndex >= 0) ; ipv6PartByteArrayIndex-- , i+=2)
{
if(k==2)
{
if (strcpy_s(buf + i, ARRAYSIZE(buf) - i, ":"))
{
return false;
}
k =0;
i++;
}
ipv6Byte = ipv6Part[ipv6PartByteArrayIndex];
if (sprintf_s(buf + i, ARRAYSIZE(buf) - i, "%02x", (int)ipv6Byte))
{
return false;
}
k++;
}
ipv6PartInput = buf;
return true;
}