400 lines
10 KiB
C++
400 lines
10 KiB
C++
//----------------------------------------------------------------------------
|
||
//
|
||
// Copyright (C) 2008 Intel Corporation
|
||
//
|
||
// File: ACLFlow.cpp
|
||
//
|
||
// Contents: Api code for Intel(R) Active Management Technology
|
||
// (Intel<65> AMT) ACL Sample.
|
||
//
|
||
// Notes: This file contains the ACLFlow methods implementation.
|
||
//
|
||
//----------------------------------------------------------------------------
|
||
|
||
#include "ACLFlow.h"
|
||
#include "CIM_Account.h"
|
||
#include "CIM_ComputerSystem.h"
|
||
#include "AMT_GeneralSettings.h"
|
||
#include "CIM_AccountManagementService.h"
|
||
#include "CimOpenWsmanClient.h" // Include from CIM Framework
|
||
#include "CommonDefinitions.h"
|
||
#include "CmdLineArguments.h"
|
||
#include "LogicException.h"
|
||
#include <iomanip>
|
||
#include "IO.h"
|
||
|
||
using namespace std;
|
||
using namespace ExceptionNamespace;
|
||
using namespace Intel::Manageability::Cim::Untyped;
|
||
using namespace Intel::Manageability::Cim::Typed;
|
||
|
||
#pragma region CONSTANT
|
||
|
||
static const string AMT_COPYRIGHTS_STRING = "ManagedSystem";
|
||
static const string DIGEST_REALM = "2";
|
||
static const string PASSWORD = "Admin!123";
|
||
static string USR = "acl";
|
||
|
||
#pragma endregion
|
||
|
||
#pragma region MEMBERS
|
||
|
||
string cimAccountName;
|
||
shared_ptr<CIM_Account> acl, new_acl;
|
||
unsigned int returnValue;
|
||
CmdLineArguments::Format format;
|
||
|
||
#pragma endregion
|
||
|
||
#pragma region HELP_METHODS
|
||
|
||
#pragma region PRINT_MESSAGE
|
||
|
||
// Print success message
|
||
void DisplaySuccess()
|
||
{
|
||
format.SetConsoleTextColor(HGREEN);
|
||
cout << "Success" << endl;
|
||
format.SetConsoleTextColor(LGRAY);
|
||
}
|
||
|
||
// Print fail message
|
||
void DisplayFailure()
|
||
{
|
||
format.SetConsoleTextColor(HRED);
|
||
cout << "Failed" << endl;
|
||
format.SetConsoleTextColor(LGRAY);
|
||
}
|
||
|
||
#pragma endregion
|
||
|
||
bool ComputeMD5(const char *username, const int user_len, const char *digestRealm, const int realm_len, const char *password,
|
||
const int pass_len, HASH_MD_5 md5hash)
|
||
{
|
||
char *colon = ":";
|
||
#ifdef _WIN32
|
||
HCRYPTPROV hCryptProv;
|
||
HCRYPTHASH hHash;
|
||
// Acquire a cryptographic provider context handle.
|
||
if (!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
// Create a hash object.
|
||
if (!CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash))
|
||
{
|
||
CryptReleaseContext(hCryptProv,0);
|
||
return false;
|
||
}
|
||
|
||
// Hash the data
|
||
if ( (!CryptHashData(hHash, (BYTE *)username , strnlen_s(username, user_len), 0)) ||
|
||
(!CryptHashData(hHash, (BYTE *)colon , strnlen_s(colon, 1), 0)) ||
|
||
(!CryptHashData(hHash, (BYTE *)digestRealm , strnlen_s(digestRealm, realm_len), 0)) ||
|
||
(!CryptHashData(hHash, (BYTE *)colon , strnlen_s(colon, 1), 0)) ||
|
||
(!CryptHashData(hHash, (BYTE *)password , strnlen_s(password, pass_len), 0)))
|
||
{
|
||
CryptDestroyHash(hHash);
|
||
CryptReleaseContext(hCryptProv,0);
|
||
return false;
|
||
}
|
||
|
||
DWORD dwRsult = sizeof(HASH_MD_5);
|
||
if (!CryptGetHashParam(hHash, HP_HASHVAL, md5hash, &dwRsult, 0))
|
||
{
|
||
CryptDestroyHash(hHash);
|
||
CryptReleaseContext(hCryptProv,0);
|
||
return false;
|
||
}
|
||
|
||
if(dwRsult != sizeof(HASH_MD_5))
|
||
{
|
||
printf("\n Unknown Error");
|
||
CryptDestroyHash(hHash);
|
||
CryptReleaseContext(hCryptProv,0);
|
||
return false;
|
||
}
|
||
|
||
// Clean up.
|
||
if(hHash)
|
||
{
|
||
if(!(CryptDestroyHash(hHash)))
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
if(hCryptProv)
|
||
{
|
||
if(!(CryptReleaseContext(hCryptProv,0)))
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
#else
|
||
MD5_CTX hash;
|
||
MD5_Init(&hash);
|
||
MD5_Update(&hash, username, strlen(username));
|
||
MD5_Update(&hash, colon, strlen(colon));
|
||
MD5_Update(&hash, digestRealm, strlen(digestRealm));
|
||
MD5_Update(&hash, colon, strlen(colon));
|
||
MD5_Update(&hash, password, strlen(password));
|
||
MD5_Final(md5hash, &hash);
|
||
return true;
|
||
#endif
|
||
}
|
||
|
||
#pragma endregion
|
||
|
||
#pragma region METHODS
|
||
|
||
/*
|
||
* Description: Enumerate acl accounts.
|
||
* Arguments:
|
||
* wsmanClient - The client to connect
|
||
* verbose - Indicates whether to print extended details about the operation
|
||
* numOfAccounts- The number of existing accounts
|
||
*/
|
||
void EnumerateACLAccounts(ICimWsmanClient *wsmanClient, int &numOfAccounts, bool verbose)
|
||
{
|
||
cout << endl << "Enumerate CIM_Account... ";
|
||
|
||
vector<tr1::shared_ptr<CIM_Account> > accountVector;
|
||
try
|
||
{
|
||
CIM_Account account;
|
||
accountVector = account.Enumerate(wsmanClient);
|
||
}
|
||
catch(WSManException e)
|
||
{
|
||
if (verbose)
|
||
cout << endl << "Error: " << e.what() << endl;
|
||
else
|
||
DisplayFailure();
|
||
|
||
cout << "Error: Error in Enumerate method." << endl;
|
||
return;
|
||
}
|
||
|
||
numOfAccounts = accountVector.size();
|
||
|
||
// Go over the array of accounts and print the UserName
|
||
vector<tr1::shared_ptr<CIM_Account> >::iterator itr;
|
||
int index_item =0;
|
||
for(itr = accountVector.begin(); itr != accountVector.end(); itr++)
|
||
{
|
||
// Save the first UserName for execute 'get' method
|
||
if(index_item ==0)
|
||
cimAccountName = ((*itr).get())->Name();
|
||
|
||
if (verbose)
|
||
cout << endl << "CIM_Account Name: " << ((*itr).get())->Name() << endl;
|
||
|
||
index_item++;
|
||
}
|
||
if (!verbose)
|
||
DisplaySuccess();
|
||
}
|
||
|
||
/*
|
||
* Description: Get specific account.
|
||
* Arguments:
|
||
* wsmanClient - The client to connect
|
||
* verbose - Indicates whether to print extended details about the operation
|
||
*/
|
||
void GetACLAccounts(ICimWsmanClient *wsmanClient, bool verbose)
|
||
{
|
||
cout << endl << "Get CIM_Account... ";
|
||
acl.reset(new CIM_Account(wsmanClient));
|
||
acl->Name(cimAccountName);
|
||
|
||
try
|
||
{
|
||
acl->Get(acl->Reference());
|
||
}
|
||
catch(WSManException e)
|
||
{
|
||
if (verbose)
|
||
cout << "failed with status " << e.what() << endl;
|
||
else
|
||
DisplayFailure();
|
||
|
||
cout << "Error: Error in Get method." << endl;
|
||
return;
|
||
}
|
||
if (verbose)
|
||
{
|
||
// Print the account data
|
||
if (acl->RequestedStateExists())
|
||
{
|
||
cout << endl << "CIM_Account Requested State: " << acl->RequestedState();
|
||
}
|
||
if (acl->UserIDExists())
|
||
{
|
||
cout << endl << "CIM_Account User ID: " << acl->UserID();
|
||
}
|
||
if(acl->OrganizationNameExists())
|
||
{
|
||
for (unsigned int i=0 ; i< acl->OrganizationName().size(); i++)
|
||
{
|
||
if(acl->OrganizationName().at(i) != "")
|
||
cout << endl << "CIM_Account Organization Name: " << acl->OrganizationName().at(i);
|
||
}
|
||
}
|
||
if (acl->ElementNameExists())
|
||
{
|
||
cout << endl << "CIM_Account Element Name: " << acl->ElementName();
|
||
}
|
||
if (acl->EnabledStateExists())
|
||
{
|
||
cout << endl << "CIM_Account Enabled State: " << acl->EnabledState();
|
||
}
|
||
if (acl->UserPasswordEncryptionAlgorithmExists())
|
||
{
|
||
cout << endl << "CIM_Account User Password Encryption Algorithm: " << acl->UserPasswordEncryptionAlgorithm();
|
||
}
|
||
cout << endl;
|
||
}
|
||
else
|
||
{
|
||
DisplaySuccess();
|
||
}
|
||
}
|
||
|
||
/*
|
||
* Description: Create new acl account.
|
||
* Arguments:
|
||
* wsmanClient - The client to connect
|
||
* verbose - Indicates whether to print extended details about the operation
|
||
*/
|
||
void CreateACLAccount(ICimWsmanClient *wsmanClient, bool verbose)
|
||
{
|
||
cout << endl << "Create CIM_Account... ";
|
||
|
||
CIM_ComputerSystem computerSystem(wsmanClient);
|
||
computerSystem.Name("ManagedSystem");
|
||
computerSystem.Get();
|
||
vector<tr1::shared_ptr<AMT_GeneralSettings> > vecSettings;
|
||
try
|
||
{
|
||
AMT_GeneralSettings generalSettings;
|
||
vecSettings = generalSettings.Enumerate(wsmanClient);
|
||
if(vecSettings.size() < 1)
|
||
throw LogicException("No instances");
|
||
}
|
||
catch(WSManException e)
|
||
{
|
||
cout << "Error: no instances in AMT_GeneralSettings class" << endl;
|
||
}
|
||
string dig = (vecSettings[0].get())->DigestRealm();
|
||
|
||
// Create a random name
|
||
char backupTemp[BACKUP_TEMP_LEN] = "_aclXXXXXX";
|
||
|
||
#pragma warning (disable:4996)
|
||
char* temp = _mktemp(backupTemp);
|
||
#pragma warning (default:4996)
|
||
|
||
USR=temp;
|
||
|
||
// Create the serivce which has the CreateAccount() method
|
||
CIM_AccountManagementService AccountManagementService(wsmanClient);
|
||
CIM_AccountManagementService::CreateAccount_INPUT input;
|
||
CIM_AccountManagementService::CreateAccount_OUTPUT output;
|
||
input.System(computerSystem.Reference());
|
||
|
||
// Initialize the new account
|
||
new_acl.reset(new CIM_Account(wsmanClient));
|
||
|
||
// Add the account properties
|
||
string sss(acl->CreationClassName());
|
||
new_acl->CreationClassName(acl->CreationClassName());
|
||
new_acl->ElementName(acl->ElementName());
|
||
new_acl->EnabledState(acl->EnabledState());
|
||
new_acl->Name(USR);
|
||
new_acl->RequestedState(acl->RequestedState());
|
||
new_acl->SystemCreationClassName(acl->SystemCreationClassName());
|
||
new_acl->SystemName(acl->SystemName());
|
||
new_acl->UserID(USR) ;
|
||
new_acl->UserPasswordEncryptionAlgorithm(acl->UserPasswordEncryptionAlgorithm());
|
||
|
||
HASH_MD_5 password;
|
||
if ( ComputeMD5(USR.c_str(), USR.length(), dig.c_str(), dig.length(), PASSWORD.c_str(), PASSWORD.length(), password) == false)
|
||
{
|
||
printf("\nError computing MD5Hash");
|
||
}
|
||
|
||
string ss1((const char*)password, sizeof(password));
|
||
stringstream ss2;
|
||
for(unsigned int i=0; i < ss1.length(); i++)
|
||
{
|
||
ss2 << hex << setw(2) << setfill('0') << (int)((unsigned char)ss1.at(i));
|
||
}
|
||
new_acl->UserPassword(ss2.str());
|
||
new_acl->OrganizationName(acl->OrganizationName());
|
||
try
|
||
{
|
||
CIM_AccountManagementService::CreateAccount_INPUT createAccountInput;
|
||
CIM_AccountManagementService::CreateAccount_OUTPUT createAccountOutput;
|
||
|
||
// Add the new account to the input parameters of the create account method
|
||
createAccountInput.System(computerSystem.Reference());
|
||
createAccountInput.AccountTemplate(*new_acl);
|
||
|
||
returnValue = AccountManagementService.CreateAccount(createAccountInput, createAccountOutput);
|
||
if(returnValue != PT_STATUS_SUCCESS)
|
||
{
|
||
if (verbose)
|
||
cout << "failed with status " << returnValue << endl;
|
||
else
|
||
DisplayFailure();
|
||
}
|
||
}
|
||
catch(WSManException e)
|
||
{
|
||
if (verbose)
|
||
cout << "failed with status " << e.what() << endl;
|
||
else
|
||
DisplayFailure();
|
||
|
||
cout << "Error: Error in Create method." << endl;
|
||
return;
|
||
}
|
||
if (verbose)
|
||
cout << endl << new_acl->Name() << " accout was created" << endl;
|
||
else
|
||
DisplaySuccess();
|
||
}
|
||
|
||
/*
|
||
* Description: Delete an account from the acl.
|
||
* Arguments:
|
||
* wsmanClient - The client to connect
|
||
* verbose - Indicates whether to print extended details about the operation
|
||
*/
|
||
void DeleteACLAccount(ICimWsmanClient *wsmanClient, bool verbose)
|
||
{
|
||
cout << endl << "Delete CIM_Account... ";
|
||
try
|
||
{
|
||
// Trying to delete the account which was created by the sample
|
||
new_acl->Delete();
|
||
}
|
||
catch(WSManException e)
|
||
{
|
||
if (verbose)
|
||
cout << "failed with status " << e.what() << endl;
|
||
else
|
||
DisplayFailure();
|
||
|
||
cout << "Error: Error in Delete method." << endl;
|
||
return;
|
||
}
|
||
if (verbose)
|
||
cout << endl << new_acl->Name() << " accout was deleted" << endl;
|
||
else
|
||
DisplaySuccess();
|
||
}
|
||
#pragma endregion
|