//---------------------------------------------------------------------------- // // Copyright (C) 2008 Intel Corporation // // File: ACLFlow.cpp // // Contents: Api code for Intel(R) Active Management Technology // (Intel� 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 #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 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 > 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 >::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 > 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