2923 lines
71 KiB
C++

//----------------------------------------------------------------------------
//
// Copyright (C) 2006 Intel Corporation
//
// File: USBFile.cpp
//
// Contents: Sample Tool for creating and viewing Intel(R) AMT USB files.
//
//----------------------------------------------------------------------------
#include "SetupFileReaderWriter.h"
#include "ConfigFile.h"
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <msxml6.h>
#include <atlbase.h>
#include "SetupFileDefinitions.h"
#define FILE_EXISTS 1
#define XML_FILE_OK 0
#define TEXT_PID_SIZE 9
#define TEXT_PPS_SIZE 39
#define MAX_CERTS 3
#define NUMBER_STRING_LENGTH 6
#define TRUE_CONST "1"
#define FALSE_CONST "0"
#define MAX_RECORDS_NUMBER pow(2.0, 16.0)
// command line flags
#define CREATE_FLAG "-create"
#define VERSION_FLAG "-v"
#define AMT_FLAG "-amt"
#define RANDOM_PSK_FLAG "-rpsk"
#define PROV_FQDN_FLAG "-fqdn"
#define DNS_FLAG "-dns"
#define GUID_FLAG "-pp"
#define ZTC_FLAG "-ztc"
#define FWU_FLAG "-fwu"
#define FWUQ_FLAG "-fwuq"
#define NUM_OF_RECS_FLAG "-nrec"
#define GEN_FLAG "-gen"
#define XML_FILE_FLAG "-xml"
#define V1_FILE_FLAG "-v1file"
#define PID_FLAG "-pid"
#define PPS_FLAG "-pps"
#define CERT_HASH_FLAG "-hash"
#define CERT_HASH_STRING_FLAG "-hashStr"
#define VIEW_FLAG "-view"
#define SOLIDER_FLAG "-redir"
#define SUMMARY_FLAG "-summary"
#define HOSTNAME_FLAG "-hostname"
#define DOMAINAME_FLAG "-domname"
#define DHCP_FLAG "-dhcp"
#define SFWU_FLAG "-sfwu"
#define PROV_MODE_FLAG "-pm"
#define IDLE_TIME_OUT_FLAG "-ito"
#define PROVISION_SERVER_ADD_FLAG "-psadd"
#define PROVISION_SERVER_PORT_FLAG "-pspo"
#define VLAN_FLAG "-vlan"
#define PASSWORD_POLICY_FLAG "-passPolicyFlag"
#define STATIC_PV4_PARAMS_FLAG "-s4p"
#define CONSUMABLE_FLAG "-consume"
#define IPV6_FLAG "-ipv6"
#define SHARED_DEDICATED_FQDN_FLAG "-sdFqdn"
#define DYNAMIC_DNS_UPDATE_FLAG "-dDnsUpdate"
#define KVM_STATE_FLAG "-kvm"
#define USER_CONSENT_FLAG "-userConsentOption"
#define REMOTE_IT_CONSENT_FLAG "-userConsentPolicy"
#define ME_PROV_HALT_ACTIVATE_FLAG "-prov"
#define SETUP_CONFIGURATION_FLAG "-conf"
#define SUPPORT_CHANNEL_ID_FLAG "-scIden"
#define SUPPORT_CHANNEL_DESC_FLAG "-scDesc"
#define SERVICE_ACCOUNT_NO_FLAG "-sano"
#define ENROLLMENT_PAASCODE_FLAG "-enrPass"
#define SERVICE_TYPE_FLAG "-servType"
#define SERVICE_PROVIDER_ID_FLAG "-spIden"
#define SCRAMBLING_FLAG "-scramble"
#define OEM_CERTIFICATE_ENABLE "-oHash"
#define USER_CERTIFICATE_ENABLE "-uHash"
/*
* convert human readable PID to binary
* Arguments:
* textPID - [in] human readable PID
* status - [out] binary PID
*
* Return Value:
* true - on success
* false - on failure, due to a badly formatted textPID
*/
bool PIDFromString(const char *textPID,char binPID[PID_LENGTH])
{
unsigned int len = (unsigned int)strnlen_s((char*)textPID, TEXT_PID_SIZE +1);
if (len != TEXT_PID_SIZE) // buffer has a room for a terminating null
{
return false;
}
//sscanf will add a terminating null o the end of the variable,
//using a tmp variable to avoid memory overrun.
char tmpBinPid[TEXT_PID_SIZE];
int numFieldsRead =
sscanf(textPID, "%4s-%4s",
(tmpBinPid),
(tmpBinPid+4)
);
for (int i=0 ; i < PID_LENGTH ; binPID[i] = tmpBinPid[i] , i++);
return numFieldsRead == 2;
}
/*
* convert ASCII text to binary
* Arguments:
* textPPS - [in] human readable PPS
* status - [out] binary PPS
*
* Return Value:
* true - on success
* false - on failure, due to a badly formatted textPPS
*/
bool PPSFromString(const char *textPPS,char binPPS[PPS_LENGTH])
{
unsigned int len = (unsigned int)strnlen_s((char*)textPPS, TEXT_PPS_SIZE+1);
if (len != TEXT_PPS_SIZE) // buffer has a room for a terminating null
{
return false;
}
//sscanf will add a terminating null o the end of the variable,
//using a tmp variable to avoid memory overrun.
char tmpBinPPS[TEXT_PPS_SIZE];
int numFieldsRead =
sscanf(textPPS, "%4s-%4s-%4s-%4s-%4s-%4s-%4s-%4s",
(tmpBinPPS),
(tmpBinPPS+4),
(tmpBinPPS+4+4),
(tmpBinPPS+4+4+4),
(tmpBinPPS+4+4+4+4),
(tmpBinPPS+4+4+4+4+4),
(tmpBinPPS+4+4+4+4+4+4),
(tmpBinPPS+4+4+4+4+4+4+4)
);
for (int i=0 ; i < PPS_LENGTH ; binPPS[i] = tmpBinPPS[i] , i++);
return numFieldsRead == 8;
}
/*
* Try to parse the string given by the user into ipv4 address
* Arguments:
* ipv4Add - the input string e.g "123.22.233.23"
* ret - [out] a 4 byte array that will contain the ipv4 address
* Return Value:
* true - on success
* false - on failure, due to a badly formatted IPv4
*/
bool ParseIPv4Address(string ipv4Add, unsigned char ret[4])
{
size_t ip, dotPos;
string ch;
for (int i=0 ; i<4 ; i++)
{
dotPos = ipv4Add.find('.',0);
if ((string::npos == dotPos) && (i != 3))
{
return false;
}
ch = ipv4Add.substr(0,dotPos);
if (i != 3)
{
ipv4Add = ipv4Add.erase(0, dotPos+1);
}
stringstream ss(ch);
if (!ss)
{
return false;
}
ip = 257;
ss >> ip;
if (ip < 256)
{
ret[3-i]=(unsigned char)ip;
}
else
{
return false;
}
}
return true;
}
bool ParseIPv6StringWithNoDoubleColons(const string& ipv6PartInput, unsigned short& ipv6PartByteArrayIndex,
unsigned char* ipv6PartByteArray)
{
string ipv6Part = ipv6PartInput;
size_t oneColonPosition = ipv6Part.find_last_of(":");
for ( ; (ipv6PartByteArrayIndex < 16) && (oneColonPosition != string::npos) ; ipv6PartByteArrayIndex+=2)
{
string ipv6Byte = ipv6Part.substr(oneColonPosition+1/*":" length*/, ipv6Part.length());
char *endptr;
errno = 0;
unsigned int ipv6ByteNumber = strtol(ipv6Byte.c_str(), &endptr, 16);
if ((errno != 0) || (*endptr != '\0'))
{
return false;
}
if (ipv6ByteNumber<65536)
{
if (memcpy_s(ipv6PartByteArray + ipv6PartByteArrayIndex, 16 - ipv6PartByteArrayIndex, (unsigned char*)&ipv6ByteNumber, 2))
{
return false;
}
}
else
{
return false;
}
ipv6Part = ipv6Part.substr(0, oneColonPosition);
oneColonPosition = ipv6Part.find_last_of(":");
}
if (!ipv6Part.empty())
{
if (ipv6PartByteArrayIndex < 16)
{
char *endptr;
errno = 0;
unsigned int ipv6ByteNumber = strtol(ipv6Part.c_str(), &endptr, 16);
if ((errno != 0) || (*endptr != '\0'))
{
return false;
}
if (ipv6ByteNumber<65536)
{
if (memcpy_s(ipv6PartByteArray + ipv6PartByteArrayIndex, 16 - ipv6PartByteArrayIndex, (unsigned char*)&ipv6ByteNumber, 2))
{
return false;
}
}
else
{
return false;
}
ipv6PartByteArrayIndex+=2;
}
else
{
return false;
}
}
return true;
}
/*
* Try to parse the string given by the user into ipv6 address
* Arguments:
* ipv6Add - the input string e.g "fe80:0123:ddef::ab"
* ret - [out] a 16 byte array that will contain the ipv6 address
* Return Value:
* true - on success
* false - on failure, due to a badly formatted IPv6
*/
bool ParseIPv6Address(string ipv6Add, unsigned char ret[16])
{
string ipv6Left, ipv6Right;
bool shouldBeFull = false;
size_t twoColonsPosition = ipv6Add.find("::");
if (string::npos == twoColonsPosition)
{
ipv6Right = ipv6Add;
ipv6Left = "";
shouldBeFull = true;
}
else
{
ipv6Left = ipv6Add.substr(0, twoColonsPosition);
ipv6Right = ipv6Add.substr(twoColonsPosition+2/*"::" length*/, ipv6Add.length());
}
unsigned short numOfIPv6BytesWritten = 0;
if (false == ParseIPv6StringWithNoDoubleColons(ipv6Right, numOfIPv6BytesWritten, ret))
{
return false;
}
int rightEndedPosition = numOfIPv6BytesWritten;
if (false == ParseIPv6StringWithNoDoubleColons(ipv6Left, numOfIPv6BytesWritten, ret))
{
return false;
}
if (shouldBeFull)
{
if (numOfIPv6BytesWritten != 16)
{
return false;
}
}
unsigned char tmp[PROSERADDR_IPV6_SIZE];
if (memcpy_s(tmp, ARRAYSIZE(tmp), ret + rightEndedPosition, (numOfIPv6BytesWritten - rightEndedPosition)))
{
return false;
}
if (memcpy_s(ret + 16 - (numOfIPv6BytesWritten - rightEndedPosition),
ARRAYSIZE(tmp) - (16 - (numOfIPv6BytesWritten - rightEndedPosition)), tmp, (numOfIPv6BytesWritten - rightEndedPosition)))
{
return false;
}
memset(ret+rightEndedPosition, 0, 16-numOfIPv6BytesWritten);
return true;
}
/*
* parse the string given by the user into vlan number
* Arguments:
* vlan - the input string e.g "1-4000"
* ret - [out] a 3 byte array that will contain vlan number
* Return Value:
* true - on success
* false - on failure, due to a badly formatted vlan
*/
bool ParseVlan(string vlan ,unsigned char ret[3])
{
size_t dotPos =vlan.find('-',0);
string ch=vlan.substr(0,dotPos);
vlan=vlan.erase(0,dotPos+1);
if ((ch=="1")||(ch=="0"))
{
stringstream ss(ch);
short help;
if (!ss)
{
return false;
}
ss>>help;
ret[0]=(unsigned char)help;
}
else
{
return false;
}
int vlanTag = -1;
stringstream ss(vlan);
if (!ss)
{
return false;
}
ss >> vlanTag;
unsigned short shortVlanTag=(unsigned short)vlanTag;
if ((vlanTag>=1)&&(vlanTag<=4096))
{
if (memcpy_s(ret + 1, 2 * sizeof(*ret), &vlanTag, sizeof(shortVlanTag)))
{
return false;
}
}
else
{
return false;
}
return true;
}
/*
* check if the given file exists
* Arguments:
* fileName - the name of the file
* Return Value:
* true - file exists
* false - file does not exist
*/
bool fileExists(const char* fileName)
{
FILE *fp = fopen(fileName, "r");
if (fp)
{
fclose(fp);
return true;
}
return false;
}
/*
* Print a PID
* Arguments:
* fp - file pointer
* p - the pid
*/
void fwritePID(FILE* fp, const char* p)
{
for (int j=0; j<4; j++)
{
fprintf(fp, "%c", *p++);
}
fprintf(fp, "-");
for (int j=0; j<4; j++)
{
fprintf(fp, "%c", *p++);
}
}
/*
* Print a PPS
* Arguments:
* fp - file pointer
* p - the pps
*/
void fwritePPS(FILE* fp, const char* p)
{
for (int j=0; j<4; j++)
fprintf(fp, "%c", *p++);
for (int k=0; k<7; k++)
{
fprintf(fp, "-");
for (int j=0; j<4; j++)
{
fprintf(fp, "%c", *p++);
}
}
}
/*
* Write the provided PSK pairs to a file in XML format
* Arguments:
* fileName - the name of the xml file
* records - the psk pairs
* overwrite- overwrite the file if it exists
* Return Value:
* XML_FILE_OK upon success or a non-zero value upon failure
*/
int WriteXmlFile(const char* fileName, const vector<ConfigRecord>& records, bool overwrite)
{
if (!overwrite && fileExists(fileName))
{
return FILE_EXISTS;
}
FILE *fp = fopen(fileName, "w");
if (!fp)
{
fprintf(stderr, "could not open file \"%s\" for writing", fileName);
perror("");
return errno;
}
fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
fprintf(fp, "<pairs>\n");
for (unsigned int i=0; i<records.size(); i++)
{
const ConfigRecord r = records[i];
if (true == r.hasPskPair)
{
fprintf(fp, "\t<pair>\n");
fprintf(fp, "\t\t<pid>");
fwritePID(fp, r.Pid);
fprintf(fp, "</pid>\n");
fprintf(fp, "\t\t<pps>");
fwritePPS(fp, r.Pps);
fprintf(fp, "</pps>\n", r.Pps);
fprintf(fp, "\t</pair>\n");
}
}
fprintf(fp, "</pairs>\n");
fclose(fp);
return XML_FILE_OK;
}
/*
* create the bin file
* Arguments:
* settings - struct contains the flags the user chose
* fileName - file name to create
* xmlFile - the xml file in case -xml was chosen
* v1File - the corresponding version 1.0 file in case -v1file was chosen
*/
void createUSBFile(const RecordSettings& settings,
const string& fileName,
const string* xmlFile = NULL,
const string* v1File = NULL)
{
int retVal;
printf("Creating USB file %s with %d record%s\n", fileName.c_str(),
settings.numRecords,settings.multiple?"s.":".");
printf("USB file version: %d.%d\n", settings.majorVersion, settings.minorVersion);
vector<ConfigRecord> cfgRecords;
retVal = WriteConfigFile(settings, fileName, true, (xmlFile || v1File) ? &cfgRecords : NULL);
if (CONFIG_SUCCESS != retVal)
{
UINT32 ind1 = retVal - 1;
UINT32 ind2 = (retVal - FISRT_BIG_ERROR) + LAST_SMALL_ERROR + 1;
if (retVal <= LAST_SMALL_ERROR)
{
if (ind1 < ARRAYSIZE(S_ERROR_STRINGS))
printf("WriteConfigFile() returned with = %d (%s)\n", retVal, S_ERROR_STRINGS[ind1].c_str());
}
else if (ind2 < ARRAYSIZE(S_ERROR_STRINGS))
{
printf("WriteConfigFile() returned with = %d (%s)\n", retVal, S_ERROR_STRINGS[ind2].c_str());
}
exit(1);
}
if(xmlFile)
{
bool needToWrite = false;
for (unsigned int i=0; i<cfgRecords.size(); i++)
{
if (true == cfgRecords.at(i).hasPskPair)
{
needToWrite = true;
}
}
if (true == needToWrite)
{
retVal = WriteXmlFile(xmlFile->c_str(), cfgRecords, true);
if (XML_FILE_OK != retVal)
{
printf("WriteXmlFile() failed.\n");
exit(2);
}
}
else
{
printf("Warning: Cannot create XML file since no PSK data was given.\n");
}
}
if(v1File && (settings.majorVersion != SETUP_FILE_VERSION_1))
{
printf("Creating an additional USB version 1.0 file, %s, with the same record%s\n", v1File->c_str(),
settings.multiple?"s.":".");
retVal = WriteVersion1ConfigFile(*v1File, cfgRecords, true);
if (CONFIG_SUCCESS != retVal)
{
printf("Failed to create version 1 setup file.\n");
UINT32 ind1 = retVal - 1;
UINT32 ind2 = (retVal - FISRT_BIG_ERROR) + LAST_SMALL_ERROR + 1;
if (retVal <= LAST_SMALL_ERROR)
{
if (ind1 < ARRAYSIZE(S_ERROR_STRINGS))
printf("WriteVersion1ConfigFile() returned with = %d (%s)\n", retVal, S_ERROR_STRINGS[ind1].c_str());
}
else if (ind2 < ARRAYSIZE(S_ERROR_STRINGS))
{
printf("WriteVersion1ConfigFile() returned with = %d (%s)\n", retVal, S_ERROR_STRINGS[ind2].c_str());
}
exit(1);
}
}
}
/*
* Prints the usage instructions
*/
void syntax()
{
const char* executableName = "USBfile";
printf(
"syntax:\n");
printf("To create a USB file:\n");
printf(" %s %s <usb output file name> <current MEBx password>\n",
executableName, CREATE_FLAG);
printf(" <new MEBx password> [%s 1|2|2.1|3|4] [%s] [%s]\n",
VERSION_FLAG, AMT_FLAG, RANDOM_PSK_FLAG);
printf(" [%s <version 1 outfile>]\n", V1_FILE_FLAG);
printf(" [%s <DNS suffix>] [%s <prov server fqdn>]\n",
DNS_FLAG, PROV_FQDN_FLAG);
printf(" [%s 0|1]\n", CONSUMABLE_FLAG);
printf(" [%s 0|1]\n", ZTC_FLAG);
printf(" [%s 0|1]\n", DHCP_FLAG);
printf(" [%s 0|1]\n", SFWU_FLAG);
printf(" [%s 0|1|2]\n", FWU_FLAG);
printf(" [%s 0|1]\n", PROV_MODE_FLAG );
printf(" [%s 0|1|2]\n", FWUQ_FLAG);
printf(" [%s <16 byte GUID>]\n",GUID_FLAG);
printf(" [%s <port number>]\n",PROVISION_SERVER_PORT_FLAG);
printf(" [%s <ipv4|ipv6 addr>]\n",PROVISION_SERVER_ADD_FLAG);
printf(" [%s <4 byte of idle time out>]\n",IDLE_TIME_OUT_FLAG);
printf(" [%s <num of records>]\n", NUM_OF_RECS_FLAG);
printf(" [%s <num of records>]\n", GEN_FLAG);
printf(" [%s <xml file name>]\n", XML_FILE_FLAG);
printf(" [%s <pid> %s <pps>] \n", PID_FLAG, PPS_FLAG);
printf(" [%s 0|1|2]\n",USER_CERTIFICATE_ENABLE);
printf(" [%s 0|1]\n",OEM_CERTIFICATE_ENABLE);
printf(" [%s <cert file name> <friendly name><sha1|sha256|sha384>]\n",CERT_HASH_FLAG);
printf(" [%s <hash string in hex> <friendly name>]\n",CERT_HASH_STRING_FLAG);
printf(" [%s <n>]\n", SOLIDER_FLAG);
printf(" [%s <StaticIPv4Params>]\n",STATIC_PV4_PARAMS_FLAG);
printf(" [%s <hostname>]\n", HOSTNAME_FLAG);
printf(" [%s <domain name>]\n", DOMAINAME_FLAG);
printf(" [%s <0|1-VlanTag>]\n",VLAN_FLAG);
printf(" [%s <0|1|2>]\n",PASSWORD_POLICY_FLAG);
printf(" [%s <ipv6 xml file name>]\n",IPV6_FLAG);
printf(" [%s 0|1]\n",SHARED_DEDICATED_FQDN_FLAG);
printf(" [%s 0|1]\n",DYNAMIC_DNS_UPDATE_FLAG);
printf(" [%s 0|1]\n",KVM_STATE_FLAG);
printf(" [%s 0|1|255]\n",USER_CONSENT_FLAG);
printf(" [%s 0|1]\n",REMOTE_IT_CONSENT_FLAG);
printf(" [%s 0|1]\n",ME_PROV_HALT_ACTIVATE_FLAG);
printf(" [%s 0]\n",SETUP_CONFIGURATION_FLAG);
printf(" [%s <4 bytes of support channel identifier>]\n",SUPPORT_CHANNEL_ID_FLAG);
printf(" [%s <support channel description>]\n", SUPPORT_CHANNEL_DESC_FLAG);
printf(" [%s <service account number>]\n", SERVICE_ACCOUNT_NO_FLAG);
printf(" [%s <enrollment passcode>]\n", ENROLLMENT_PAASCODE_FLAG);
printf(" [%s 1|2|4]\n", SERVICE_TYPE_FLAG);
printf(" [%s <16 byte GUID>]\n", SERVICE_PROVIDER_ID_FLAG);
printf("\nTo view the valid records of a USB file:\n");
printf(" %s %s <usb file name>\n", executableName, VIEW_FLAG);
printf("\nTo view a summary of a USB file:\n");
printf(" %s %s <usb file name>\n\n", executableName, SUMMARY_FLAG);
printf("\t%s 1|2|2.1|3|4: the setup file version, 4 by default\n", VERSION_FLAG);
printf("\t%s <version 1 outfile>: creates a version 1 setup file\n", V1_FILE_FLAG);
printf("\t%s: this will set the manageability selection value to AMT\n",AMT_FLAG);
printf("\t%s: this will generate a random psk pair\n",RANDOM_PSK_FLAG);
printf("\t%s <DNS suffix>: sets the PKI dns suffix name (up to length 255)\n", DNS_FLAG);
printf("\t%s <prov server fqdn>: string up to length 255\n", PROV_FQDN_FLAG);
printf("\t%s 0|1: generate inconsumable record or consumable record(s),\n"
"\t 0 (inconsumable) by default\n", CONSUMABLE_FLAG);
printf("\t%s 0|1: disable/enable PKI Configuration\n", ZTC_FLAG);
printf("\t%s 0|1: disable/enable DHCP\n" , DHCP_FLAG);
printf("\t%s 0|1: disable/enable secure firmware update\n"
"\t (Supported in versions 2.1 - 3)\n", SFWU_FLAG);
printf("\t%s 0|1|2: disable/enable/enable password protected Firmware local\n"
"\t update (Password protected mode is supported starting from version 4)\n ", FWU_FLAG);
printf("\t%s 0|1: Enterprise/SMB provisining mode, 0 (Enterprise) by default\n"
"\t Note: this option is deprecated in version 3(+) file format\n", PROV_MODE_FLAG);
printf("\t%s 0|1|2: Always|Never|Restricted Firmware Update Qualifier\n"
"\t (Supported in versions 2.1 - 3)\n", FWUQ_FLAG);
printf("\t%s <GUID>: set the power packege ,GUID should be in network order\n",GUID_FLAG);
printf("\t%s <port number> provision server port number \n ",PROVISION_SERVER_PORT_FLAG);
printf("\t%s <ipv4|ipv6 addr> :ip address for provision server\n "
"\t ipv4 example: 123.222.222.121\n"
"\t ipv6 example: fe80:ffff:0012::212\n"
"\t Note: ipv6 address supported only in version 3(+) file format\n",PROVISION_SERVER_ADD_FLAG);
printf("\t%s <4 bytes of idle time out>: idle time out (valid values: %d-%d)\n",IDLE_TIME_OUT_FLAG, MIN_IDLE_TIMEOUT, MAX_IDLE_TIMEOUT);
printf("\t%s <n> : number of records to create\n",NUM_OF_RECS_FLAG);
printf("\t%s <n> : number of records with a random psk pair to create\n"
"\t Note: this option is deprecated, use %s and %s\n"
"\t options to generate multiple records with random psk pair\n"
,GEN_FLAG, NUM_OF_RECS_FLAG, RANDOM_PSK_FLAG);
printf("\t%s <xml file name> : configuration xml file \n", XML_FILE_FLAG);
printf("\t%s <pid> %s <pps>: a psk pair\n",PID_FLAG, PPS_FLAG);
printf("\t%s 0|1: disable/enable all preinstalled certs\n", OEM_CERTIFICATE_ENABLE);
printf("\t%s 0|1|2: disable/enable all user defined certs/delete all\n", USER_CERTIFICATE_ENABLE);
printf("\t%s <certificate file name> <friendly name><sha1|sha256|sha384>: to\n", CERT_HASH_FLAG);
printf("\t compute and add the hash of the given root certificate file according\n");
printf("\t to the given hash algorithm. Up to three certificates hashes may be\n"
"\t specified.\n"
"\t Notes: 1. The hash algorithm is optional, if no hash algorithm\n"
"\t is given, the tool uses as default sha1\n"
"\t 2. The sha256 and sha384 hash algorithms supported only in\n"
"\t version 3(+) file format\n"
"\t 3. In order to compute sha256 and sha384 hash algorithms the\n"
"\t tool uses the OpenSSL dll file: libcrypto.dll\n");
printf("\t%s <hash string in hex> <friendly name>\n", CERT_HASH_STRING_FLAG);
printf("\t\t Optional length hash string:\n");
printf("\t\t 20 bytes for sha1 (40 hex characters) \n");
printf("\t\t 32 bytes for sha256 (64 hex characters) \n");
printf("\t\t 48 bytes for sha384 (96 hex characters) \n");
printf("\t%s <n>:\n", SOLIDER_FLAG);
printf("\t\tThis is an integer that is calculated as follows:\n");
printf("\t\t bit 0 : 1 (Enable) or 0 (Disable) - SOL feature\n");
printf("\t\t bit 1 : 1 (Enable) or 0 (Disable) - IDER feature\n");
printf("\t\t bit 2 : 1 (Enable) or 0 (Disable) - Username/password\n"
"\t\t authentication type of the SOL/IDER in the ME FW\n");
printf("\t%s <localHost:SubnetMask:GatewayAddr:DNSaddr:SecondaryDNSaddr> \n",STATIC_PV4_PARAMS_FLAG);
printf(" :e.g 10.0.0.1:255.255.255.0:10.0.0.2:10.0.0.3:10.0.0.4\n ");
printf(" Notes: This option is not valid when generating an inconsumable record,");
printf(" DHCP flag must be disabled\n");
printf("\t%s <hostname> :ASCII reprasentation of host name max length 63\n"
"\t Note: This option is not valid when generating an inconsumable record\n", HOSTNAME_FLAG);
printf("\t%s <domain name> : max length of domain name is 255\n", DOMAINAME_FLAG);
printf("\t%s <0|1-VlanTag(1-4096)> : VlanStatus disable/enable e.g. 0-4011\n"
"\t Note: for a non supporting VLAN platforms,the MEBx ignores this setting", VLAN_FLAG);
printf("\t%s <0|1|2> : Default/block in post/always open\n",PASSWORD_POLICY_FLAG);
printf("\t%s <ipv6 xml file name>: an XML file which holds the IPv6\n"
"\t configuration data\n",IPV6_FLAG);
printf("\t%s 0|1: dedicated (0)/shared (1) FQDN\n"
"\t Note: This option is valid only if configuring the hostname as well\n",SHARED_DEDICATED_FQDN_FLAG);
printf("\t%s 0|1: disable/enable dynamic DNS update\n",DYNAMIC_DNS_UPDATE_FLAG);
printf("\t%s 0|1: disable/enable KVM\n",KVM_STATE_FLAG);
printf("\t%s 0|1|255: user consent disabled/enabled for kvm\n"
"\t only/enabled for all features ('255'-enabled for all features\n"
"\t option is supported starting from version 4)\n",USER_CONSENT_FLAG);
printf("\t%s 0|1: user consent policy configurable remotely\n",REMOTE_IT_CONSENT_FLAG);
printf("\t%s : specify this flag in order to scramble the setup file\n"
"\t records.\n",SCRAMBLING_FLAG);
printf("\t%s 0|1: stop/start configuration\n"
"\t Notes:\n"
"\t 1. Sending the ME provisioning Halt/Activate value of 0, stop,\n"
"\t configuration will cause a global reset after all the USB key\n"
"\t settings have been applied.\n"
"\t 2. To guaranty success of this command it is recommended to configure\n"
"\t either %s or %s, otherwise the success depends on the DHCP\n"
"\t state of the FW.\n",ME_PROV_HALT_ACTIVATE_FLAG, DNS_FLAG, PROV_FQDN_FLAG);
printf("\t%s 0: automated configuration\n"
"\t Automatic configuration will provision the system through\n"
"\t communication with the setup and configuration servers.\n", SETUP_CONFIGURATION_FLAG);
printf("\t%s <4 bytes of support channel id.>: support channel identifier\n"
"\t (valid values: %d-%d)\n",SUPPORT_CHANNEL_ID_FLAG, MIN_SUPPORT_CHANNEL_IDEN, MAX_SUPPORT_CHANNEL_IDEN);
printf("\t%s <support channel description>: friendly name used to describe\n"
"\t the party representedby the support channel identifier.\n"
"\t 60 character max.\n", SUPPORT_CHANNEL_DESC_FLAG);
printf("\t%s <service account number>: unique string identifier given to the\n"
"\t end user by the service provider. 32 character max\n", SERVICE_ACCOUNT_NO_FLAG);
printf("\t%s <enrollment passcode>: unique string that allows access to the\n"
"\t service to complete enrolment. 32 character max.\n", ENROLLMENT_PAASCODE_FLAG);
printf("\t%s 1|2|4: reactive/proactive/one time session\n", SERVICE_TYPE_FLAG);
printf("\t%s <GUID>: set the service provider identifier\n"
"\t GUID should be 32 hexadecimal chars in network order without spaces\n"
"\t For example: %s 0102030405060708090a0b0c0d0e0f00\n"
"\t represents the GUID: 04030201-0605-0807-090a-0b0c0d0e0f00\n", SERVICE_PROVIDER_ID_FLAG, SERVICE_PROVIDER_ID_FLAG);
printf("\t%s: specify this flag in order to scramble the setup file records\n", SCRAMBLING_FLAG);
printf("Examples:\n");
printf(" %s %s setup.bin admin Admin22@ %s %s 1 %s 10\n"
"\t %s setup.xml %s 1\n",
executableName, CREATE_FLAG, RANDOM_PSK_FLAG, VERSION_FLAG, NUM_OF_RECS_FLAG, XML_FILE_FLAG, CONSUMABLE_FLAG);
printf(" %s %s setup.bin admin Admin22@ %s AAAA-AAAN\n",
executableName, CREATE_FLAG, PID_FLAG);
printf(" %s AAAF-AAAF-AAAF-AAAF-AAAF-AAAF-AAAF-AAAF\n", PPS_FLAG);
printf(" %s %s setup.bin\n", executableName, VIEW_FLAG);
printf("\n");
printf("Notes:\n1. The BIOS requires a binary file with the name \"setup.bin\".\n");
printf("2. If a certificate hash is added, all default hashes will be disabled\n");
printf(" and all existing user defined hashes will be deleted.\n");
printf("3. If %s option was selected the %s option must come with it and vice versa.",PID_FLAG, PPS_FLAG);
printf("4. If %s or %s option was selected along with %s and %s options,\n"
" the psk pair that will be used is the one supplied using %s and %s.\n"
,RANDOM_PSK_FLAG,GEN_FLAG,PID_FLAG, PPS_FLAG,PID_FLAG, PPS_FLAG);
printf("5. If %s option was selected the %s option must come with it and vice\n"
" versa.\n", PROVISION_SERVER_PORT_FLAG,PROVISION_SERVER_ADD_FLAG);
}
/*
* Returns "Invalid value for <given field>."
* Arguments:
* field - field with invalid value
* Return Value:
* "Invalid value for <given field>."
*/
string ReturnInvalidValueString(char* field)
{
return "Invalid value for " + string(field) + ".\n\n";
}
/*
* Returns "Missing value for <given field>."
* Arguments:
* field - field with missing value
* Return Value:
* "Missing value for <given field>."
*/
string ReturnMissingValueString(char* field)
{
return "Missing value for " + string(field) + ".\n\n";
}
/*
* Parse the IPv6 XML file and stores the data into the RecordSettings object
* Arguments:
* fileName - the IPv6 XML file
* Return Value:
* 0 - succesfful parsing
* 1 - invalid xml file format
* 2 - invalid ipv6 addresses
*/
int ParseIPv6File(string fileName, unsigned char* ipv6Params ,unsigned char mjVersion)
{
IXMLDOMDocument *pXMLDom = NULL;
IXMLDOMNode *pXMLNode = NULL;
IXMLDOMNodeList *pXMLNodeList = NULL;
VARIANT var;
VARIANT_BOOL status;
BSTR bstr = NULL;
int successFlag = 0;
int majorVersion = (int)mjVersion;
do
{
CoInitialize(NULL);
HRESULT hr = CoCreateInstance(__uuidof(DOMDocument60),
NULL,
CLSCTX_INPROC_SERVER,
__uuidof(IXMLDOMDocument),
(void**)&pXMLDom);
if (FAILED(hr) || !pXMLDom)
{
successFlag = 1;
break;
}
hr = pXMLDom->put_validateOnParse(VARIANT_FALSE);
if (FAILED(hr))
{
successFlag = 1;
break;
}
try
{
VariantInit(&var);
auto oleFilename = std::unique_ptr<OLECHAR[]>(new OLECHAR[fileName.length() + 1]);
mbstowcs(oleFilename.get(), fileName.c_str(), fileName.length() + 1);
V_BSTR(&var) = SysAllocString(oleFilename.get());
V_VT(&var) = VT_BSTR;
hr = pXMLDom->load(var, &status);
if (FAILED(hr) || (status != VARIANT_TRUE))
{
successFlag = 1;
break;
}
hr = pXMLDom->get_xml(&bstr);
if (FAILED(hr))
{
successFlag = 1;
break;
}
hr = pXMLDom->get_firstChild(&pXMLNode);
if (FAILED(hr) || !pXMLNode)
{
successFlag = 1;
break;
}
hr = pXMLNode->get_nodeName(&bstr);
if (FAILED(hr))
{
successFlag = 1;
break;
}
string firstChild = ((bstr != NULL) ? CW2A(bstr) : "");
if (firstChild.compare("IPv6") != 0)
{
successFlag = 1;
break;
}
hr = pXMLNode->get_childNodes(&pXMLNodeList);
if (FAILED(hr))
{
successFlag = 1;
break;
}
long length = 0;
if (!pXMLNodeList)
{
successFlag = 1;
break;
}
hr = pXMLNodeList->get_length(&length);
if (FAILED(hr))
{
successFlag = 1;
break;
}
for (int i = 0; i < length; i++)
{
IXMLDOMNode *pXMLNode = NULL;
hr = pXMLNodeList->get_item(i, &pXMLNode);
if (!pXMLNode)
{
successFlag = 1;
break;
}
if (FAILED(hr))
{
successFlag = 1;
pXMLNode->Release();
break;
}
DOMNodeType type;
hr = pXMLNode->get_nodeType(&type);
if (FAILED(hr))
{
successFlag = 1;
pXMLNode->Release();
break;
}
if (type != NODE_ELEMENT)
{
pXMLNode->Release();
continue;
}
hr = pXMLNode->get_nodeName(&bstr);
if (FAILED(hr))
{
successFlag = 1;
pXMLNode->Release();
break;
}
string nodeName;
if (bstr)
nodeName = CW2A(bstr);
hr = pXMLNode->get_text(&bstr);
if (FAILED(hr))
{
successFlag = 1;
pXMLNode->Release();
break;
}
string nodeText;
if (bstr)
nodeText = CW2A(bstr);
if (0 == nodeName.compare("InterfaceIndex"))
{
if (0 == nodeText.compare("Wired"))
{
ipv6Params[IPV6_INTERFACE_INDEX_OFFSET] = 0;
}
else if (0 == nodeText.compare("Wired"))
{
ipv6Params[IPV6_INTERFACE_INDEX_OFFSET] = 1;
}
else
{
successFlag = 1;
pXMLNode->Release();
break;
}
}
else if (0 == nodeName.compare("IPv6Enabled"))
{
if (0 == nodeText.compare("False"))
{
ipv6Params[IPV6_ENABLED_OFFSET] = 0;
}
else if (0 == nodeText.compare("True"))
{
ipv6Params[IPV6_ENABLED_OFFSET] = 1;
}
else
{
successFlag = 1;
pXMLNode->Release();
break;
}
}
else if (0 == nodeName.compare("InterfaceIDType"))
{
if (0 == nodeText.compare("Random"))
{
ipv6Params[IPV6_INTERFACE_ID_TYPE_OFFSET] = 0;
}
else if (0 == nodeText.compare("Intel"))
{
ipv6Params[IPV6_INTERFACE_ID_TYPE_OFFSET] = 1;
}
else if (0 == nodeText.compare("Manual"))
{
ipv6Params[IPV6_INTERFACE_ID_TYPE_OFFSET] = 2;
}
else
{
successFlag = 1;
pXMLNode->Release();
break;
}
}
else if (0 == nodeName.compare("InterfaceID"))
{
if (nodeText.length() == IPV6_INTERFACE_ID_STRING_LENGTH)
{
for (int j = 0; j < IPV6_INTERFACE_ID_STRING_LENGTH; j++)
{
ipv6Params[IPV6_INTERFACE_ID_OFFSET + j] = nodeText.at(j);
}
}
else
{
successFlag = 1;
pXMLNode->Release();
break;
}
}
else if (0 == nodeName.compare("IPv6Address"))
{
unsigned char tmpIPv6Address[16];
memset(tmpIPv6Address, 0, 16);
if (!ParseIPv6Address(nodeText, tmpIPv6Address))
{
successFlag = 2;
pXMLNode->Release();
break;
}
else
{
if (majorVersion >= 4)
{
for (unsigned int j = 0; j < IPV6_INTERFACE_ID_STRING_LENGTH; j++)
{
ipv6Params[IPV6_ADDRESS_OFFSET + j] = tmpIPv6Address[j];
}
}
else
{
for (unsigned int j = 0; j < nodeText.length(); j++)
{
ipv6Params[IPV6_ADDRESS_OFFSET + j] = nodeText.at(j);
}
}
}
}
else if (0 == nodeName.compare("IPv6DefaultRouter"))
{
unsigned char tmpIPv6Address[16];
memset(tmpIPv6Address, 0, 16);
if (!ParseIPv6Address(nodeText, tmpIPv6Address))
{
successFlag = 2;
pXMLNode->Release();
break;
}
else
{
if (majorVersion >= 4)
{
for (unsigned int j = 0; j < IPV6_INTERFACE_ID_STRING_LENGTH; j++)
{
ipv6Params[IPV6_DEFAULT_ROUTER_OFFSET_NEW_FORMAT + j] = tmpIPv6Address[j];
}
}
else
{
for (unsigned int j = 0; j < nodeText.length(); j++)
{
ipv6Params[IPV6_DEFAULT_ROUTER_OFFSET + j] = nodeText.at(j);
}
}
}
}
else if (0 == nodeName.compare("DNSPrimaryIPv6Address"))
{
unsigned char tmpIPv6Address[16];
memset(tmpIPv6Address, 0, 16);
if (!ParseIPv6Address(nodeText, tmpIPv6Address))
{
successFlag = 2;
pXMLNode->Release();
break;
}
else
{
if (majorVersion >= 4)
{
for (unsigned int j = 0; j < IPV6_INTERFACE_ID_STRING_LENGTH; j++)
{
ipv6Params[IPV6_PRIMARY_DNS_ADD_OFFSET_NEW_FORMAT + j] = tmpIPv6Address[j];
}
}
else
{
for (unsigned int j = 0; j < nodeText.length(); j++)
{
ipv6Params[IPV6_PRIMARY_DNS_ADD_OFFSET + j] = nodeText.at(j);
}
}
}
}
else if (0 == nodeName.compare("DNSSecondaryIPv6Address"))
{
unsigned char tmpIPv6Address[16];
memset(tmpIPv6Address, 0, 16);
if (!ParseIPv6Address(nodeText, tmpIPv6Address))
{
successFlag = 2;
pXMLNode->Release();
break;
}
else
{
if (majorVersion >= 4)
{
for (unsigned int j = 0; j < IPV6_INTERFACE_ID_STRING_LENGTH; j++)
{
ipv6Params[IPV6_SECONDARY_DNS_ADD_OFFSET_NEW_FORMAT + j] = tmpIPv6Address[j];
}
}
else
{
for (unsigned int j = 0; j < nodeText.length(); j++)
{
ipv6Params[IPV6_SECONDARY_DNS_ADD_OFFSET + j] = nodeText.at(j);
}
}
}
}
pXMLNode->Release();
}
}
catch (std::bad_alloc&)
{
printf("ERROR: can't allocate memory");
successFlag = 1; //TODO: rewrite returned value
}
}
while(0);
if (bstr) SysFreeString(bstr);
if (&var) VariantClear(&var);
if (pXMLNode) pXMLNode->Release();
if (pXMLNodeList) pXMLNodeList->Release();
if (pXMLDom) pXMLDom->Release();
CoUninitialize();
return successFlag;
}
/*
* parse the command line
* Arguments:
* argc - number of arguments
* argv - the given command line's arguments
* RecordSettings [out]-struct with the given flags
* usbFile [out]-name of usb file
* xmlFile [out]- name of xml file
* xmlValid [out]- true if -xml was chosen
* v1File [out]- name of vresion 1 file name
* v1FileValid [out]- true if -v1file was chosen
* Return Value:
* true upon success or a false value upon failure
*/
bool parse(int argc, char* argv[], RecordSettings& input,
string& usbFile, string& xmlFile, bool& xmlValid,
string& v1File, bool& v1FileValid, string & errMessage)
{
bool status = true;
input.dnsSuffixValid = false;
input.serverFqdnValid = false;
input.pidValid = false;
input.ppsValid = false;
input.generateRandomPskPair = false;
input.soliderConfigValid = false;
// by default a single inconsumable record is created
input.multiple = false;
// by default, file version 4 is assumed
input.majorVersion = DEFAULT_MAJOR_VERSION;
input.minorVersion = DEFAULT_MINOR_VERSION;
input.enableRCFGValid = false;
input.enableRCFG = false;
input.fwLocalUpdatePresent = false;
input.fwUpdateQualifierPresent = false;
input.guidPresent = false;
input.hostNamePresent = false;
input.domainNamePresent = false;
input.dhcpPresent = false;
input.secureFWUpdatePresent = false;
input.provisionModePresent = false;
input.idleTimeOutPresent = false;
input.provisionServerAddPresent = false;
input.provisionServerAddSize = 0;
input.provisionServerPortPresent = false;
input.vlanPresent = false;
input.passPolicyFlagExist = false;
input.staticIPv4ParamsPresent = false;
input.setAmt = false;
input.consumable = false;
input.dhcp = false;//for the static Ipv4 parameter check
input.numRecords = 1;
input.sharedDedicatedFqdnPresent = false;
input.dynamicDnsUpdatePresent = false;
input.kvmStatePresent = false;
input.optInUserConsentPresent = false;
input.optInRemoteITPresent = false;
input.meProvisioningHaltActivatePresent = false;
input.manualSetupAndConfigurationPresent = false;
input.supportChannelIdentifierPresent = false;
input.supportChannelDescriptionPresent = false;
input.serviceAccountNumberPresent = false;
input.enrollmentPasscodePresent = false;
input.serviceTypePresent = false;
input.ipv6ParamsPresent = false;
input.ipv6Params = NULL;
input.serviceProviderIdentifierPresent = false;
//Setting default values for Service Provider Identifier - all 0's
memset(input.serviceProviderIdentifier, 0, GUID_LENGTH);
input.scrambleRecords = false;
input.oemCertificateFlagExist = false;
input.userCertificateFlagExist = false;
int i=2;
usbFile = argv[i++];
input.currentMEBxPwd = argv[i++];
input.newMEBxPwd = argv[i++];
errMessage = "";
//Parse major version - befor parse the another properties(the major version required to following flow)
int j = 5;
while(j < argc)
{
if(_stricmp(VERSION_FLAG, argv[j]) == 0)
{
if(j+1 < argc)
{
double tmp = atof(argv[j+1]);
int mjVersion=(int) tmp;// first digit
size_t mnVersion=(unsigned int)((tmp-mjVersion)*10);// second digit
if ((mjVersion==1 && mnVersion == 0) ||
(mjVersion==2 && (mnVersion == 0 || mnVersion == 1)) ||
(mjVersion==3 && mnVersion == 0) ||
(mjVersion==4 && mnVersion == 0))
{
input.majorVersion=mjVersion;
input.minorVersion=(unsigned char)mnVersion;
}
else
{
errMessage = ReturnInvalidValueString(argv[j]);
status = false;
break;
}
}
else
{
errMessage = ReturnInvalidValueString(argv[j]);
status = false;
break;
}
break;
}
j+=1;
}
while(i < argc)
{
if(_stricmp(VERSION_FLAG, argv[i]) == 0)
{
i+=2;
}
else if(_stricmp(AMT_FLAG, argv[i]) == 0)
{
i++;
input.setAmt = true;
}
else if(_stricmp(RANDOM_PSK_FLAG, argv[i]) == 0)
{
i++;
input.generateRandomPskPair = true;
}
else if(_stricmp(SOLIDER_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
int tmp = -1;
stringstream ss(argv[i+1]);
if (!ss)
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
ss >> tmp;
if(tmp < 0 || tmp > 7)
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
else
{
input.soliderConfigValid = true;
input.soliderConfig = tmp;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(DNS_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.dnsSuffixValid = true;
input.dnsSuffix = argv[i+1];
if((input.dnsSuffix.length() > CM_VARIABLE_IDENTIFIER_PKI_DNS_SUFFIX_MAXLEN) ||
(input.dnsSuffix.empty()))
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(GUID_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.guidPresent= true;
string help= argv[i+1];
string ch;
int byte;
if (help.length() == (GUID_LENGTH*2))
{
for (int j=0 ; j < GUID_LENGTH ; j++)
{
ch=help.substr(0,2);
sscanf(ch.c_str(),"%x",&byte);
help=help.erase(0,2);
input.guid[j]=byte;
}
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(PROV_FQDN_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.serverFqdnValid = true;
input.ServerFqdn = argv[i+1];
if((input.ServerFqdn.length() > CM_VARIABLE_IDENTIFIER_CONFIG_SERVER_FQDN_MAXLEN) ||
(input.ServerFqdn.empty()))
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(FWU_FLAG,argv[i])==0)
{
if(i+1 < argc)
{
input.fwLocalUpdatePresent = true;
if(strcmp(TRUE_CONST, argv[i+1]) == 0)
{
input.fwLocalUpdateEnable = LOCAL_FW_UPDATE_ENABLED;
}
else if(strcmp(FALSE_CONST, argv[i+1]) == 0)
{
input.fwLocalUpdateEnable = LOCAL_FW_UPDATE_DISABLED;
}
else if(strcmp("2", argv[i+1]) == 0)
{
input.fwLocalUpdateEnable = LOCAL_FW_UPDATE_PASSWORD_PROTECTED;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i=i+2;
}
else if(_stricmp(FWUQ_FLAG,argv[i])==0)
{
if(i+1 < argc)
{
input.fwUpdateQualifierPresent = true;
if(strcmp("0", argv[i+1]) == 0)
{
input.fwUpdateQualifier = 0;
}
else if(strcmp("1", argv[i+1]) == 0)
{
input.fwUpdateQualifier = 1;
}
else if(strcmp("2", argv[i+1]) == 0)
{
input.fwUpdateQualifier = 2;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(ZTC_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.enableRCFGValid = true;
if(strcmp(TRUE_CONST, argv[i+1]) == 0)
{
input.enableRCFG = true;
}
else if(strcmp(FALSE_CONST, argv[i+1]) == 0)
{
input.enableRCFG = false;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(XML_FILE_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
xmlFile = argv[i+1];
xmlValid = true;
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(V1_FILE_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
v1File = argv[i+1];
v1FileValid = true;
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if((_stricmp(NUM_OF_RECS_FLAG, argv[i]) == 0) || (_stricmp(GEN_FLAG, argv[i])==0))
{
if(i+1< argc)
{
stringstream ss(argv[i+1]);
ss>>input.numRecords;
if (!ss || input.numRecords<=0 || input.numRecords > MAX_RECORDS_NUMBER)// makes sure the user entered a valid nrec\gen value
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
if (input.numRecords>1)
{
input.multiple = true;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
if (_stricmp(GEN_FLAG, argv[i])==0)
{
input.generateRandomPskPair = true;
}
i+=2;
}
else if(_stricmp(PID_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.pidValid = true;
if(!PIDFromString(argv[i+1], input.pid))
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(PPS_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.ppsValid = true;
if(!PPSFromString(argv[i+1], input.pps))
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(CERT_HASH_FLAG, argv[i]) == 0)
{
bool hashAlgorithmFound = false;
if(i+2 < argc)
{
CertHashAlgorithm hashAlgorithm;
//Check for given hash algorithm
if (i+3 < argc)
{
if(_stricmp("sha1", argv[i+3]) == 0)
{
hashAlgorithm = USB_CERT_HASH_ALGORITHM_SHA1;
hashAlgorithmFound = true;
}
else if(_stricmp("sha256", argv[i+3]) == 0)
{
hashAlgorithm = USB_CERT_HASH_ALGORITHM_SHA256;
hashAlgorithmFound = true;
}
else if(_stricmp("sha384", argv[i+3]) == 0)
{
hashAlgorithm = USB_CERT_HASH_ALGORITHM_SHA384;
hashAlgorithmFound = true;
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
// up to 3 certs can be used
if (input.certHashes.size() == MAX_CERTS)
{
char tmp[NUMBER_STRING_LENGTH];
if (sprintf_s(tmp, ARRAYSIZE(tmp), "%d", MAX_CERTS) == -1)
{
return false;
}
errMessage = "No more than " + string(tmp) + " certificate hashes may be specified.\n\n";
status = false;
break;
}
else if(fileExists(argv[i+1]) && strnlen_s(argv[i+2], 33) <= 32)
{
CertHash temp = CertHash(argv[i+1], argv[i+2], hashAlgorithm);
if (temp._dllFailed)
{
string hashString = "";
if (USB_CERT_HASH_ALGORITHM_SHA256 == hashAlgorithm)
{
hashString = "SHA256";
}
else if (USB_CERT_HASH_ALGORITHM_SHA384 == hashAlgorithm)
{
hashString = "SHA384";
}
errMessage = "Failed to load libcrypto.dll - Can't compute hash algorithm " + hashString + " for file: " + string(argv[i+1]) + ".\n\n";
status = false;
break;
}
if (!temp._valid)
{
errMessage = "Invalid certificate file: " + string(argv[i+1]) + ".\n\n";
status = false;
break;
}
input.certHashes.push_back(temp);
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
if (hashAlgorithmFound)
{
i+=4;
}
else
{
i+=3;
}
}
else if(_stricmp(CERT_HASH_STRING_FLAG, argv[i]) == 0)
{
if(i+2 < argc)
{
// up to 3 certs can be used
if (input.certHashes.size() == MAX_CERTS)
{
char tmp[NUMBER_STRING_LENGTH];
if(sprintf_s(tmp, ARRAYSIZE(tmp), "%d", MAX_CERTS) == -1)
{
return false;
}
errMessage = "No more than " + string(tmp) + " certificate hashes may be specified.\n\n";
status = false;
break;
}
if (strnlen_s(argv[i+2], 33) > 32)
{
errMessage = "Invalid friendly name (more than 32 characters): " + string(argv[i+2]) + ".\n\n";
status = false;
break;
}
CertHash temp = CertHash(argv[i+1], argv[i+2]);
if (!temp._valid)
{
errMessage = "Invalid hash string: " + string(argv[i+1]) + ".\n\n";
status = false;
break;
}
input.certHashes.push_back(temp);
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=3;
}
// These flags was added in version 2.1 in AMT module
else if(_stricmp(HOSTNAME_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.hostNamePresent=true;
string hostName;
hostName=argv[i+1];
size_t hostNameLength = hostName.length();
if (hostNameLength <= HOSTNAME_MAX_LENGTH)
{
input.hostName = hostName;
}
else
{
char tmp[NUMBER_STRING_LENGTH];
if (sprintf_s(tmp, ARRAYSIZE(tmp), "%d", HOSTNAME_MAX_LENGTH) == -1)
{
return false;
}
errMessage = "Host name size cannot exceed " + string(tmp) + " bytes.\n\n";
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(DOMAINAME_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.domainNamePresent=true;
string DomainName;
DomainName=argv[i+1];
size_t DomainNameLength=DomainName.length();
if (DomainNameLength<=DOMAIN_NAME_MAX_LENGTH)
input.domainName=DomainName;
else
{
char tmp[NUMBER_STRING_LENGTH];
if (sprintf_s(tmp, ARRAYSIZE(tmp), "%d", DOMAIN_NAME_MAX_LENGTH) == -1)
{
return false;
}
errMessage = "Domain name size cannot exceed " + string(tmp) + " bytes.\n\n";
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(DHCP_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.dhcpPresent = true;
if(strcmp("1", argv[i+1]) == 0)
{
if (input.staticIPv4ParamsPresent)
{
errMessage = "Invalid value. Both DHCP and Static IP flags are turned on.\n\n";
status = false;
break;
}
input.dhcp = 2;
}
else if(strcmp("0", argv[i+1]) == 0)
{
input.dhcp = 1;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(SFWU_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.secureFWUpdatePresent = true;
if(strcmp("1", argv[i+1]) == 0)
{
input.secureFWUpdate = true;
}
else if(strcmp("0", argv[i+1]) == 0)
{
input.secureFWUpdate = false;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(PROV_MODE_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.provisionModePresent = true;
if(strcmp("1", argv[i+1]) == 0)
{
input.provisionMode = CM_VARIABLE_IDENTIFIER_PM_SMB;
}
else if(strcmp("0", argv[i+1]) == 0)
{
input.provisionMode = CM_VARIABLE_IDENTIFIER_PM_ENTERPRISE;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(IDLE_TIME_OUT_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.idleTimeOutPresent= true;
int ido = 0;
stringstream ss(argv[i+1]);
if (!ss)
{
std::stringstream tmpMin, tmpMax;
tmpMin << MIN_IDLE_TIMEOUT;
tmpMax << MAX_IDLE_TIMEOUT;
errMessage = "Idle time out invalid. (Valid values: " + tmpMin.str() + "-" + tmpMax.str() + ")\n\n";
status = false;
break;
}
ss >> ido;
if ((ido<=MAX_IDLE_TIMEOUT)&&(ido>=MIN_IDLE_TIMEOUT))
{
if (memcpy_s(input.idleTimeOut, ARRAYSIZE(input.idleTimeOut), (char *)&ido, IDLE_TIMEOUT_LENGTH))
{
return false;
}
}
else
{
std::stringstream tmpMin, tmpMax;
tmpMin << MIN_IDLE_TIMEOUT;
tmpMax << MAX_IDLE_TIMEOUT;
errMessage = "Idle time out invalid. (Valid values: " + tmpMin.str() + "-" + tmpMax.str() + ")\n\n";
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(PROVISION_SERVER_PORT_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.provisionServerPortPresent= true;
int intPort = -1;
stringstream ss(argv[i+1]);
if (!ss)
{
errMessage = "Invalid port number.\n\n";
status = false;
break;
}
ss >> intPort;
if (intPort<=65535 && intPort>=0)
{
unsigned short charHelp=(unsigned short) intPort;
if (memcpy_s(input.provisionServerPort, ARRAYSIZE(input.provisionServerPort), (char *)(&charHelp), sizeof(charHelp)))
{
return false;
}
}
else
{
errMessage = "Invalid port number.\n\n";
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(PROVISION_SERVER_ADD_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.provisionServerAddPresent= true;
string help= argv[i+1];
if (!ParseIPv4Address(help, input.provisionServerAdd))
{
if (!ParseIPv6Address(help, input.provisionServerAdd))
{
errMessage = "Invalid input for IP Address.\n\n";
status = false;
break;
}
else
{
input.provisionServerAddType = IPV6;
input.provisionServerAddSize = PROSERADDR_IPV6_SIZE;
}
}
else
{
input.provisionServerAddType = IPV4;
input.provisionServerAddSize = PROSERADDR_IPV4_SIZE;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(VLAN_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.vlanPresent= true;
string help= argv[i+1];
if (!ParseVlan(help,input.vlan))
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(PASSWORD_POLICY_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.passPolicyFlagExist = true;
int bits = -1;
stringstream ss(argv[i+1]);
if (!ss)
{
errMessage = "Invalid value for password policy flag " + string(argv[i]) + ".\n\n";
status = false;
break;
}
ss >> bits;
if ((bits>=0)&&(bits<=2))
{
input.passPolicyFlag=(CFG_MEBX_PWD_CHANGE_POLICY)bits;
}
else
{
errMessage = "Invalid value for password policy flag " + string(argv[i]) + ".\n\n";
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if (_stricmp(IPV6_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
if (fileExists(argv[i+1]))
{
size_t ipv6ParamSize = input.majorVersion < 4? IPV6_PARAMS_SIZE : IPV6_PARAMS_SIZE_NEW_FORMAT;
//according to version number
//Setting default values for IPv6 - all 0's
input.ipv6Params = new unsigned char[ipv6ParamSize];
memset(input.ipv6Params, 0, ipv6ParamSize);
int parsingResult = ParseIPv6File(argv[i+1], input.ipv6Params , input.majorVersion);
if (0 != parsingResult)
{
if (1 == parsingResult)
{
errMessage = "Invalid XML file given for " + string(argv[i]) + ".\n\n";
}
if (2 == parsingResult)
{
errMessage = "One or more of the IPv6 addresses in the given XML file for the " + string(argv[i]) + " are invalid.\n\n";
}
status = false;
break;
}
else
{
input.ipv6ParamsPresent = true;
}
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(SHARED_DEDICATED_FQDN_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.sharedDedicatedFqdnPresent = true;
if(strcmp("1", argv[i+1]) == 0)
{
input.sharedDedicatedFqdn = CM_VARIABLE_IDENTIFIER_SHARED_DEDICATED_FQDN_SHARED;
}
else if(strcmp("0", argv[i+1]) == 0)
{
input.sharedDedicatedFqdn = CM_VARIABLE_IDENTIFIER_SHARED_DEDICATED_FQDN_DEDICATED;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(DYNAMIC_DNS_UPDATE_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.dynamicDnsUpdatePresent = true;
if(strcmp("0", argv[i+1]) == 0)
{
input.dynamicDnsUpdate = CM_VARIABLE_IDENTIFIER_DYNAMIC_DNS_UPDATE_DISABLE;
}
else if(strcmp("1", argv[i+1]) == 0)
{
input.dynamicDnsUpdate = CM_VARIABLE_IDENTIFIER_DYNAMIC_DNS_UPDATE_ENABLE;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(KVM_STATE_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.kvmStatePresent = true;
if(strcmp("0", argv[i+1]) == 0)
{
input.kvmState = CM_VARIABLE_IDENTIFIER_KVM_STATE_DISABLE;
}
else if(strcmp("1", argv[i+1]) == 0)
{
input.kvmState = CM_VARIABLE_IDENTIFIER_KVM_STATE_ENABLE;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(USER_CONSENT_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.optInUserConsentPresent = true;
if(strcmp("0", argv[i+1]) == 0)
{
input.optInUserConsentOption = CM_VARIABLE_IDENTIFIER_OPT_IN_USER_CONSENT_DISABLE;
}
else if(strcmp("1", argv[i+1]) == 0)
{
input.optInUserConsentOption = CM_VARIABLE_IDENTIFIER_OPT_IN_USER_CONSENT_ENABLE_KVM;
}
else if(strcmp("255", argv[i+1]) == 0)
{
input.optInUserConsentOption = CM_VARIABLE_IDENTIFIER_OPT_IN_USER_CONSENT_ENABLE_ALL;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(REMOTE_IT_CONSENT_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.optInRemoteITPresent = true;
if(strcmp("0", argv[i+1]) == 0)
{
input.optInRemoteItPolicy = CM_VARIABLE_IDENTIFIER_OPT_IN_REMOTE_IT_CONSENT_DISABLE;
}
else if(strcmp("1", argv[i+1]) == 0)
{
input.optInRemoteItPolicy = CM_VARIABLE_IDENTIFIER_OPT_IN_REMOTE_IT_CONSENT_ENABLE;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(ME_PROV_HALT_ACTIVATE_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.meProvisioningHaltActivatePresent = true;
if(strcmp("0", argv[i+1]) == 0)
{
input.meProvisioningHaltActivate = CM_VARIABLE_IDENTIFIER_ME_PROVISION_HALT_ACTIVE_STOP;
}
else if(strcmp("1", argv[i+1]) == 0)
{
input.meProvisioningHaltActivate = CM_VARIABLE_IDENTIFIER_ME_PROVISION_HALT_ACTIVE_START;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(SETUP_CONFIGURATION_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.manualSetupAndConfigurationPresent = true;
if(strcmp("0", argv[i+1]) == 0)
{
input.manualSetupAndConfiguration = CM_VARIABLE_IDENTIFIER_MANUAL_SETUP_AND_CONFIGURATION_AUTOMATED;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(SUPPORT_CHANNEL_ID_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.supportChannelIdentifierPresent= true;
int ido = -1;
stringstream ss(argv[i+1]);
if (!ss)
{
std::stringstream tmpMin, tmpMax;
tmpMin << MIN_SUPPORT_CHANNEL_IDEN;
tmpMax << MAX_SUPPORT_CHANNEL_IDEN;
errMessage = "Support channel identifier invalid. (Valid values: " + tmpMin.str() + "-" + tmpMax.str() + ")\n\n";
status = false;
break;
}
ss >> ido;
if ((ido<=MAX_SUPPORT_CHANNEL_IDEN)&&(ido>=MIN_SUPPORT_CHANNEL_IDEN))
{
unsigned int idoInt=(unsigned int) ido;
memset(input.supportChannelIdentifier, 0, sizeof(idoInt));
if (memcpy_s(input.supportChannelIdentifier, ARRAYSIZE(input.supportChannelIdentifier), &idoInt, sizeof(idoInt)))
{
return false;
}
}
else
{
std::stringstream tmpMin, tmpMax;
tmpMin << MIN_SUPPORT_CHANNEL_IDEN;
tmpMax << MAX_SUPPORT_CHANNEL_IDEN;
errMessage = "Support channel identifier invalid. (Valid values: " + tmpMin.str() + "-" + tmpMax.str() + ")\n\n";
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(SUPPORT_CHANNEL_DESC_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.supportChannelDescriptionPresent = true;
string supportChannelDescription;
supportChannelDescription = argv[i+1];
size_t supportChannelDescriptionLength = supportChannelDescription.length();
if (supportChannelDescriptionLength <= SUPPORT_CHANNEL_DESC_MAX_LENGTH)
{
input.supportChannelDescription = supportChannelDescription;
}
else
{
char tmp[NUMBER_STRING_LENGTH];
if (sprintf_s(tmp, ARRAYSIZE(tmp), "%d", SUPPORT_CHANNEL_DESC_MAX_LENGTH) == -1)
{
return false;
}
errMessage = "Support Channel Description size cannot exceed " + string(tmp) + " bytes.\n\n";
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(SERVICE_ACCOUNT_NO_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.serviceAccountNumberPresent = true;
string serviceAccountNumber;
serviceAccountNumber = argv[i+1];
size_t serviceAccountNumberLength = serviceAccountNumber.length();
if (serviceAccountNumberLength <= SERVICE_ACCOUNT_NO_MAX_LENGTH)
{
input.serviceAccountNumber = serviceAccountNumber;
}
else
{
char tmp[NUMBER_STRING_LENGTH];
if (sprintf_s(tmp, ARRAYSIZE(tmp), "%d", SERVICE_ACCOUNT_NO_MAX_LENGTH) == -1)
{
return false;
}
errMessage = "SService Account Number size cannot exceed " + string(tmp) + " bytes.\n\n";
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(ENROLLMENT_PAASCODE_FLAG, argv[i]) == 0)
{
if(i+1< argc)
{
input.enrollmentPasscodePresent = true;
string enrollmentPasscode;
enrollmentPasscode = argv[i+1];
size_t enrollmentPasscodeLength = enrollmentPasscode.length();
if (enrollmentPasscodeLength <= SUPPORT_CHANNEL_DESC_MAX_LENGTH)
{
input.enrollmentPasscode = enrollmentPasscode;
}
else
{
char tmp[NUMBER_STRING_LENGTH];
if (sprintf_s(tmp,ARRAYSIZE(tmp) ,"%d", ENROLLMENT_PASSCODE_MAX_LENGTH) == -1)
{
return false;
}
errMessage = "Enrollment Passcode size cannot exceed " + string(tmp) + " bytes.\n\n";
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(SERVICE_TYPE_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.serviceTypePresent = true;
memset(input.serviceType, 0, SERVICE_TYPE_SIZE);
if(strcmp("1", argv[i+1]) == 0)
{
input.serviceType[0] = CM_VARIABLE_IDENTIFIER_SERVICE_TYPE_REACTIVE;
}
else if(strcmp("2", argv[i+1]) == 0)
{
input.serviceType[0] = CM_VARIABLE_IDENTIFIER_SERVICE_TYPE_PROACTIVE;
}
else if(strcmp("4", argv[i+1]) == 0)
{
input.serviceType[0] = CM_VARIABLE_IDENTIFIER_SERVICE_TYPE_ONE_TIME_SESSION;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if (_stricmp(SERVICE_PROVIDER_ID_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
input.serviceProviderIdentifierPresent= true;
string help= argv[i+1];
string ch;
int byte;
if (help.length() == (GUID_LENGTH*2))
{
for (int j=0 ; j < GUID_LENGTH ; j++)
{
ch=help.substr(0,2);
sscanf(ch.c_str(),"%x",&byte);
help=help.erase(0,2);
input.serviceProviderIdentifier[j]=byte;
}
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(OEM_CERTIFICATE_ENABLE, argv[i]) == 0)
{
input.oemCertificateFlagExist = true;
int bits = -1;
stringstream ss(argv[i+1]);
if (!ss)
{
errMessage = "Invalid value for pre installed certificate flag " + string(argv[i]) + ".\n\n";
status = false;
break;
}
ss >> bits;
if ((bits>=0)&&(bits<=2))
{
input.oemCertificateFlag = (OEM_CERTIFICATE_OPTION)bits;
}
else
{
errMessage = "Invalid value for pre installed certificate flag " + string(argv[i]) + ".\n\n";
status = false;
break;
}
i+=2;
}
else if(_stricmp(USER_CERTIFICATE_ENABLE, argv[i]) == 0)
{
input.userCertificateFlagExist = true;
int bits = -1;
stringstream ss(argv[i+1]);
if (!ss)
{
errMessage = "Invalid value for user defined certificate flag " + string(argv[i]) + ".\n\n";
status = false;
break;
}
ss >> bits;
if ((bits>=0)&&(bits<=2))
{
input.userCertificateFlag = (USER_CERTIFICATE_OPTION)bits;
}
else
{
errMessage = "Invalid value for user defined certificate flag " + string(argv[i]) + ".\n\n";
status = false;
break;
}
i+=2;
}
else if(_stricmp(STATIC_PV4_PARAMS_FLAG, argv[i]) == 0)
{
if (i+1 < argc)
{
if (input.dhcpPresent && (2 == input.dhcp))
{
errMessage = "Invalid value. Both DHCP and Static IP flags are turned on.\n\n";
status = false;
break;
}
input.staticIPv4ParamsPresent = true;
string addrs=argv[i+1];
unsigned char temp[4];
size_t dotPos;
bool sign=true;
string ch;
for (int j=0; j<5;j++)
{
dotPos= addrs.find(':',0);
if ((dotPos==-1)&&(j<4))
sign=false;
ch=addrs.substr(0,dotPos);
if (j<4) addrs=addrs.erase(0,dotPos+1);
if (!(sign)||(!ParseIPv4Address(ch,temp)))
{
errMessage = "Invalid value for IP address.\n\n";
status = false;
break;
}
if (memcpy_s(((input.staticIPv4Params) + j * 4), ARRAYSIZE(input.staticIPv4Params) - j * 4, temp, PROSERADDR_IPV4_SIZE))
{
return false;
}
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(CONSUMABLE_FLAG, argv[i]) == 0)
{
if(i+1 < argc)
{
if(strcmp(TRUE_CONST, argv[i+1]) == 0)
{
input.consumable = true;
}
else if(strcmp(FALSE_CONST, argv[i+1]) == 0)
{
input.consumable = false;
}
else
{
errMessage = ReturnInvalidValueString(argv[i]);
status = false;
break;
}
}
else
{
errMessage = ReturnMissingValueString(argv[i]);
status = false;
break;
}
i+=2;
}
else if(_stricmp(SCRAMBLING_FLAG, argv[i++]) == 0)
{
input.scrambleRecords = true;
}
else
{
errMessage = "Illegal command line flag.\n\n";
status = false;
break;
}
}
if(input.ipv6ParamsPresent == true && input.consumable == false)
{
errMessage = "You requested to define a static IP, but the -consume flag is not specified and therefore the needed parameters cannot be achieved.\n";
status = false;
}
if (1 == input.majorVersion)
{
input.consumable = true;
}
if ((!input.consumable)&&(input.multiple))
{
errMessage += "Unable to create more than one inconsumable record.\n\n";
status = false;
}
if ((!input.consumable)&&(input.staticIPv4ParamsPresent || input.hostNamePresent))
{
errMessage += "Unable to create an inconsumable record with static ip or host name.\n\n";
status = false;
}
if ((input.multiple)&&(input.staticIPv4ParamsPresent || input.hostNamePresent))
{
errMessage += "Unable to create more than one record with the same static ip or host name.\n\n";
status = false;
}
if ((input.dhcpPresent)&&(input.dhcp==1)&&(!input.staticIPv4ParamsPresent))
{
errMessage += "DHCP is disable and no static ip parameters were given.\n\n";
status = false;
}
if (((input.provisionServerAddPresent)&&(!input.provisionServerPortPresent))||((!input.provisionServerAddPresent)&&(input.provisionServerPortPresent)))
{
errMessage += "You have to provide both provision server Port and IP.\n\n";
status = false;
}
if (((input.pidValid)&&(!input.ppsValid))||((!input.pidValid)&&(input.ppsValid)))
{
errMessage += "You cannot update only one part of the PID:PPS pair.\n\n";
status = false;
}
if (( (!input.dhcpPresent) || ((input.dhcpPresent)&&(input.dhcp==2)) ) && (input.staticIPv4ParamsPresent))
{
errMessage += "DHCP is not disabled and static ip parameters were given.\n\n";
status = false;
}
if (!input.hostNamePresent && input.sharedDedicatedFqdnPresent)
{
errMessage += "Shared/Dedicated FQDN can be configured only if hostname is being configured as well.\n\n";
status = false;
}
if ( ((input.provisionModePresent)&&(CM_VARIABLE_IDENTIFIER_PM_SMB == input.provisionMode)) &&
((input.enableRCFGValid)|| (input.dnsSuffixValid) ||
(input.provisionServerAddPresent) || (input.provisionServerPortPresent) ||
(input.pidValid) ||(input.ppsValid) ||(input.generateRandomPskPair) ||
(!input.certHashes.empty())))
{
errMessage += "Invalid input for Provision mode SMB.\n\n";
status = false;
}
return status;
}
int main(int argc, char* argv[])
{
printf("\n*** Intel(R) AMT USB file writer and viewer sample v4.0***\n\n");
if (argc == 1)
{
syntax();
exit(0);
}
else if (0 == _stricmp(argv[1], CREATE_FLAG))
{
if (argc < 5)
{
syntax();
exit(0);
}
RecordSettings input;
string usbFile, xmlFile, v1File, errMessage;
bool xmlValid = false, v1FileValid = false;
if(!parse(argc, argv, input, usbFile, xmlFile, xmlValid, v1File, v1FileValid, errMessage))
{
printf ("%sFailed to process command line parameters.\n\n",errMessage.c_str());
syntax();
printf ("\n%sFailed to process command line parameters.\n",errMessage.c_str());
exit(0);
}
createUSBFile(input, usbFile, xmlValid ? &xmlFile : NULL,
v1FileValid ? &v1File : NULL);
if (NULL != input.ipv6Params)
{
delete[] input.ipv6Params;
input.ipv6Params = NULL;
}
}
else if (0 == _stricmp(argv[1], VIEW_FLAG))
{
if (argc != 3)
{
syntax();
exit(0);
}
int i=2;
const char* usbFileName = argv[i++];
int retVal = DumpUsbFile(usbFileName, cout, true);
if (CONFIG_SUCCESS != retVal)
{
UINT32 ind1 = retVal - 1;
UINT32 ind2 = (retVal - FISRT_BIG_ERROR) + LAST_SMALL_ERROR;
if (retVal <= LAST_SMALL_ERROR)
{
if (ind1 < ARRAYSIZE(S_ERROR_STRINGS))
fprintf(stderr, "Error reading USB file \"%s\" error code %d (%s)\n", usbFileName, retVal, S_ERROR_STRINGS[ind1].c_str());
}
else if (ind2 < ARRAYSIZE(S_ERROR_STRINGS))
{
fprintf(stderr, "Error reading USB file \"%s\" error code %d (%s)\n", usbFileName, retVal, S_ERROR_STRINGS[ind2].c_str());
}
exit(1);
}
}
else if (0 == _stricmp(argv[1], SUMMARY_FLAG))
{
if (argc != 3)
{
syntax();
exit(0);
}
int i=2;
const char* usbFileName = argv[i++];
int retVal = DumpUsbFile(usbFileName, cout, false);
if (CONFIG_SUCCESS != retVal)
{
UINT32 ind1 = retVal - 1;
UINT32 ind2 = (retVal - FISRT_BIG_ERROR) + LAST_SMALL_ERROR;
if (retVal <= LAST_SMALL_ERROR)
{
if (ind1 < ARRAYSIZE(S_ERROR_STRINGS))
fprintf(stderr, "Error reading USB file \"%s\" error code %d (%s)\n", usbFileName, retVal, S_ERROR_STRINGS[ind1].c_str());
}
else if (ind2 < ARRAYSIZE(S_ERROR_STRINGS))
{
fprintf(stderr, "Error reading USB file \"%s\" error code %d (%s)\n", usbFileName, retVal, S_ERROR_STRINGS[ind2].c_str());
}
exit(1);
}
}
else
{
syntax();
exit(0);
}
return 0;
}