400 lines
10 KiB
C++
Raw Blame History

//----------------------------------------------------------------------------
//
// 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