617 lines
17 KiB
C++
617 lines
17 KiB
C++
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 2003 Intel Corporation
|
|
//
|
|
// File: CimOpenWsmanClient.cpp
|
|
//
|
|
// Contents: An implementation of the ICimWsmanClient interface using openwsman
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include <cstring>
|
|
#include <math.h>
|
|
#include "CimException.h"
|
|
#include "CimOpenWsmanClient.h"
|
|
#include "OpenWsmanClient.h"
|
|
#include "WsmanEPR.h"
|
|
#include "WsmanFilter.h"
|
|
|
|
|
|
#pragma comment(lib, "legacy_stdio_definitions.lib")
|
|
|
|
using namespace std;
|
|
|
|
namespace Intel
|
|
{
|
|
namespace WSManagement
|
|
{
|
|
using WsmanExceptionNamespace::GeneralWsmanException;
|
|
using Intel::Manageability::Exceptions::WSManException;
|
|
using Intel::Manageability::Exceptions::HTTPException;
|
|
|
|
|
|
// Construct from params.
|
|
CimOpenWsmanClient::CimOpenWsmanClient(const string& host,
|
|
const int port,
|
|
bool secure,
|
|
AuthMethod auth_method,
|
|
const string& username,
|
|
const string& password,
|
|
// search for a client proxy address include proxy port
|
|
const string& proxy,
|
|
// search for a client proxy user name
|
|
const string& proxy_username,
|
|
// search for a client proxy password
|
|
const string proxy_password,
|
|
// determines which cert store to search
|
|
const bool local,
|
|
// search for a client cert with this name
|
|
const string& cert,
|
|
// search for a client cert with this oid
|
|
const string& oid,
|
|
// accept self-signed certificicate
|
|
const bool acceptSelfSignedCert
|
|
)
|
|
: cl(NULL)
|
|
{
|
|
try {
|
|
setHost(host);
|
|
setPortNum(port);
|
|
setSecure(secure);
|
|
setAuth(auth_method);
|
|
setUserName(username);
|
|
setPassword(password);
|
|
setClientCert(oid, cert, local);
|
|
setProxy(proxy, proxy_username, proxy_password);
|
|
}
|
|
catch (GeneralWsmanException& ex)
|
|
{
|
|
WSManException ex1(ex.what());
|
|
throw ex1;
|
|
}
|
|
|
|
OpenConnection(acceptSelfSignedCert);
|
|
}
|
|
|
|
|
|
CimOpenWsmanClient::CimOpenWsmanClient(const ConnectionInfo& Connection, const bool acceptSelfSignedCert)
|
|
: cl(NULL),
|
|
connection(Connection)
|
|
{
|
|
OpenConnection(acceptSelfSignedCert);
|
|
}
|
|
|
|
//set host
|
|
void CimOpenWsmanClient::setHost(const string& host) {
|
|
validateHost(host);
|
|
connection.host = host;
|
|
}
|
|
|
|
//set port number
|
|
void CimOpenWsmanClient::setPortNum(const int port) {
|
|
validatePortNum(port);
|
|
connection.port = port;
|
|
}
|
|
|
|
//set secure
|
|
void CimOpenWsmanClient::setSecure(const bool secure) {
|
|
connection.secure = secure;
|
|
}
|
|
|
|
//setAuth
|
|
void CimOpenWsmanClient::setAuth(AuthMethod auth_method) {
|
|
connection.authmethod = auth_method;
|
|
}
|
|
|
|
// set user name
|
|
void CimOpenWsmanClient::setUserName(const string& user_name) {
|
|
validateUserName(user_name);
|
|
connection.username = user_name;
|
|
}
|
|
|
|
//set password
|
|
void CimOpenWsmanClient::setPassword(const string& password) {
|
|
validatePassword(password);
|
|
connection.password = password;
|
|
}
|
|
|
|
//set proxy params
|
|
void CimOpenWsmanClient::setProxy(const string& proxy, const string& proxy_username, const string& proxy_password) {
|
|
validateProxy(proxy, proxy_username, proxy_password);
|
|
connection.proxy_host = proxy;
|
|
connection.proxy_user = proxy_username;
|
|
connection.proxy_password = proxy_password;
|
|
}
|
|
|
|
//set client certificate params
|
|
void CimOpenWsmanClient::setClientCert(const string& caOid, const string& caName, const bool localCert) {
|
|
validateClientCert(caName);
|
|
connection.local = localCert;
|
|
connection.certificate = caName;
|
|
connection.oid = caOid;
|
|
}
|
|
|
|
|
|
//Validate host
|
|
void CimOpenWsmanClient::validateHost(const string& host)
|
|
{
|
|
unsigned long addr = inet_addr(host.c_str());
|
|
if (INADDR_NONE != addr && INADDR_ANY != addr) {
|
|
//if it is valid dotted-decimal address
|
|
//convert back to string will prevent unwanted duplicates
|
|
struct in_addr inaddr;
|
|
inaddr.s_addr = addr;
|
|
char* client_ip = inet_ntoa(inaddr);
|
|
if (!client_ip) {
|
|
string error = "wsman_client_create failed:: invalid host name";
|
|
throw WsmanClientException(error.c_str(), WSMAN_GENERAL_ERROR);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Validate port
|
|
void CimOpenWsmanClient::validatePortNum(int port) {
|
|
//The largest possible source port number is 2^16 or 65535
|
|
if (port < 0 || port > pow(2.0, 16.0)) {
|
|
string error = "wsman_client_create failed:: invalid port number";
|
|
throw WsmanClientException(error.c_str(), WSMAN_GENERAL_ERROR);
|
|
}
|
|
}
|
|
|
|
//Validate username
|
|
void CimOpenWsmanClient::validateUserName(const string& user_name) {
|
|
//Accepting empty string for Kerberos connection
|
|
if (user_name.length() == 0 && connection.authmethod == KERBEROS)
|
|
return;
|
|
if (user_name.length() < 1 || user_name.length() > 32) {
|
|
string error = "wsman_client_create failed:: invalid username";
|
|
throw WsmanClientException(error.c_str(), WSMAN_GENERAL_ERROR);
|
|
}
|
|
}
|
|
|
|
//Validate password
|
|
void CimOpenWsmanClient::validatePassword(const string& password) {
|
|
//Accepting empty string for Kerberos connection
|
|
if (password.length() == 0 && connection.authmethod == KERBEROS)
|
|
return;
|
|
if (password.length() < 8 || password.length() > 32) {
|
|
string error = "wsman_client_create failed:: invalid password";
|
|
throw WsmanClientException(error.c_str(), WSMAN_GENERAL_ERROR);
|
|
}
|
|
}
|
|
|
|
//validate client certificate params
|
|
void CimOpenWsmanClient::validateClientCert(const string& caName) {
|
|
// In the common name field of the DN of a X509 certificate, , the limit is up to 64 characters
|
|
if (caName.length() > 64) {
|
|
string error = "wsman_client_create failed:: invalid certificate parameter";
|
|
throw WsmanClientException(error.c_str(), WSMAN_GENERAL_ERROR);
|
|
}
|
|
}
|
|
|
|
void CimOpenWsmanClient::validateProxyUsername(const string& user_name) {
|
|
if (user_name.length() < 1 || user_name.length() > 32) {
|
|
string error = "wsman_client_create failed:: invalid username";
|
|
throw WsmanClientException(error.c_str(), WSMAN_GENERAL_ERROR);
|
|
}
|
|
}
|
|
|
|
void CimOpenWsmanClient::validateProxyPassword(const string& password) {
|
|
if (password.length() < 8 || password.length() > 32) {
|
|
string error = "wsman_client_create failed:: invalid password";
|
|
throw WsmanClientException(error.c_str(), WSMAN_GENERAL_ERROR);
|
|
}
|
|
}
|
|
|
|
//validate proxy params
|
|
void CimOpenWsmanClient::validateProxy(const string& proxy, const string& proxy_username, const string& proxy_password) {
|
|
if(!proxy.empty())
|
|
validateHost(proxy);
|
|
if(!proxy_username.empty())
|
|
validateProxyUsername(proxy_username);
|
|
if(!proxy_password.empty())
|
|
validateProxyPassword(proxy_password);
|
|
}
|
|
|
|
void CimOpenWsmanClient::OpenConnection(bool acceptSelfSignedCert)
|
|
{
|
|
try
|
|
{
|
|
cl = new OpenWsmanClient(connection.host,
|
|
connection.port,
|
|
"/wsman",
|
|
connection.secure ? "https" : "http",
|
|
connection.authmethod == DIGEST ? "digest" : "gss",
|
|
connection.username,
|
|
connection.password,
|
|
connection.proxy_host,
|
|
connection.proxy_user,
|
|
connection.proxy_password
|
|
#ifdef WIN32
|
|
,
|
|
connection.local,
|
|
connection.certificate,
|
|
connection.oid
|
|
#endif // WIN32
|
|
);
|
|
}
|
|
catch (GeneralWsmanException& ex)
|
|
{
|
|
throw WSManException(ex.what());
|
|
}
|
|
if (acceptSelfSignedCert)
|
|
{
|
|
cl->AllowSelfSignedServerCert();
|
|
}
|
|
}
|
|
|
|
// Destructor.
|
|
CimOpenWsmanClient::~CimOpenWsmanClient()
|
|
{
|
|
if (cl != NULL)
|
|
{
|
|
delete cl;
|
|
}
|
|
}
|
|
|
|
// ConnectionInfo
|
|
ConnectionInfo CimOpenWsmanClient::Connection() const
|
|
{
|
|
return connection;
|
|
}
|
|
|
|
// Creates a new instance of a resource.
|
|
string CimOpenWsmanClient::Create(const string& resourceUri, const string& data) const
|
|
{
|
|
string ret;
|
|
try
|
|
{
|
|
ret = cl->Create(resourceUri, data);
|
|
}
|
|
catch (WsmanSoapFault& ex)
|
|
{
|
|
string exStirng = ex.GetFaultReason().empty() ? "" : ex.GetFaultReason();
|
|
exStirng += ex.GetFaultDetail().empty() ? "" : ("\n" + ex.GetFaultDetail());
|
|
WSManException ex1(exStirng);
|
|
throw ex1;
|
|
}
|
|
catch (WsmanClientException& ex)
|
|
{
|
|
HTTPException ex1(ex.what());
|
|
throw ex1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// Identify.
|
|
string CimOpenWsmanClient::Identify() const
|
|
{
|
|
return cl->Identify();
|
|
}
|
|
|
|
// Delete a resource.
|
|
void CimOpenWsmanClient::Delete(const string& resourceUri, const NameValuePairs* s) const
|
|
{
|
|
try
|
|
{
|
|
cl->Delete(resourceUri, s);
|
|
}
|
|
catch (WsmanSoapFault& ex)
|
|
{
|
|
string exStirng = ex.GetFaultReason().empty() ? "" : ex.GetFaultReason();
|
|
exStirng += ex.GetFaultDetail().empty() ? "" : ("\n" + ex.GetFaultDetail());
|
|
WSManException ex1(exStirng);
|
|
throw ex1;
|
|
}
|
|
catch (WsmanClientException& ex)
|
|
{
|
|
HTTPException ex1(ex.what());
|
|
throw ex1;
|
|
}
|
|
}
|
|
|
|
// Enumerate resource.
|
|
void CimOpenWsmanClient::Enumerate(const string& resourceUri, vector<string>& enumRes, const NameValuePairs* s) const
|
|
{
|
|
try
|
|
{
|
|
cl->Enumerate(resourceUri, enumRes, s);
|
|
}
|
|
catch (WsmanSoapFault& ex)
|
|
{
|
|
string exStirng = ex.GetFaultReason().empty() ? "" : ex.GetFaultReason();
|
|
exStirng += ex.GetFaultDetail().empty() ? "" : ("\n" + ex.GetFaultDetail());
|
|
WSManException ex1(exStirng);
|
|
throw ex1;
|
|
}
|
|
catch (WsmanClientException& ex)
|
|
{
|
|
HTTPException ex1(ex.what());
|
|
throw ex1;
|
|
}
|
|
}
|
|
|
|
// Retrieve a resource.
|
|
string CimOpenWsmanClient::Get(const string& resourceUri, const NameValuePairs* s) const
|
|
{
|
|
string ret;
|
|
try
|
|
{
|
|
ret = cl->Get(resourceUri, s);
|
|
}
|
|
catch (WsmanSoapFault& ex)
|
|
{
|
|
string exStirng = ex.GetFaultReason().empty() ? "" : ex.GetFaultReason();
|
|
exStirng += ex.GetFaultDetail().empty() ? "" : ("\n" + ex.GetFaultDetail());
|
|
WSManException ex1(exStirng);
|
|
throw ex1;
|
|
}
|
|
catch (WsmanClientException& ex)
|
|
{
|
|
HTTPException ex1(ex.what());
|
|
throw ex1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// Update a resource.
|
|
string CimOpenWsmanClient::Put(const string& resourceUri, const string& content, const NameValuePairs* s) const
|
|
{
|
|
string ret;
|
|
try
|
|
{
|
|
ret = cl->Put(resourceUri, content, s);
|
|
}
|
|
catch (WsmanSoapFault& ex)
|
|
{
|
|
string exStirng = ex.GetFaultReason().empty() ? "" : ex.GetFaultReason();
|
|
exStirng += ex.GetFaultDetail().empty() ? "" : ("\n" + ex.GetFaultDetail());
|
|
WSManException ex1(exStirng);
|
|
throw ex1;
|
|
}
|
|
catch (WsmanClientException& ex)
|
|
{
|
|
HTTPException ex1(ex.what());
|
|
throw ex1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
// Invokes a method and returns the results of the method call.
|
|
string CimOpenWsmanClient::Invoke(const string& resourceUri, const string& methodName, const string& content, const NameValuePairs* s) const
|
|
{
|
|
string ret;
|
|
try
|
|
{
|
|
ret = cl->Invoke(resourceUri, methodName, content, s);
|
|
}
|
|
catch (WsmanSoapFault& ex)
|
|
{
|
|
string exStirng = ex.GetFaultReason().empty() ? "" : ex.GetFaultReason();
|
|
exStirng += ex.GetFaultDetail().empty() ? "" : ("\n" + ex.GetFaultDetail());
|
|
WSManException ex1(exStirng);
|
|
throw ex1;
|
|
}
|
|
catch (WsmanClientException& ex)
|
|
{
|
|
HTTPException ex1(ex.what());
|
|
throw ex1;
|
|
}
|
|
return ret;
|
|
|
|
}
|
|
|
|
// Submit a subscription
|
|
string CimOpenWsmanClient::Subscribe(const string& resourceUri, const SubscribeInfo& info, string& identifier) const
|
|
{
|
|
WsmanClientNamespace::SubscribeInfo wsInfo;
|
|
wsInfo.filter = info.filter;
|
|
wsInfo.dialect = info.dialect;
|
|
wsInfo.delivery_uri = info.delivery_uri;
|
|
wsInfo.delivery_mode = (WsmanClientNamespace::NotificationDeliveryMode) info.delivery_mode;
|
|
wsInfo.selectorset = info.selectorset;
|
|
wsInfo.heartbeat_interval = info.heartbeat_interval;
|
|
wsInfo.expires = info.expires;
|
|
|
|
return cl->Subscribe(resourceUri, wsInfo, identifier);
|
|
}
|
|
|
|
// "Special" Enumerate
|
|
void CimOpenWsmanClient::Enumerate(vector<string>& enumRes, const EnumerateFilter& filter) const
|
|
{
|
|
string enumerateURI = "http://schemas.dmtf.org/wbem/wscim/1/*";
|
|
WsmanAssocType assocType;
|
|
string assocClass;
|
|
string resultClass;
|
|
string role;
|
|
string resultRole;
|
|
vector<string> resultProp;
|
|
|
|
CimReference tempReference = filter.reference;
|
|
WsmanEPR epr(tempReference.ResourceURI(), tempReference.Address());
|
|
WsManSelectors::const_iterator iter;
|
|
WsManSelectors tempSelectors = tempReference.Selectors();
|
|
NameValuePairs nvp;
|
|
for (iter = tempSelectors.begin(); iter != tempSelectors.end(); iter++)
|
|
{
|
|
epr.addTextSelector(iter->first, iter->second);
|
|
nvp.insert(pair<string, string>(iter->first, iter->second));
|
|
}
|
|
|
|
WsmanOptions opts(FLAG_NONE);
|
|
|
|
try
|
|
{
|
|
|
|
if (filter.assocType == Intel::WSManagement::EnumerateFilter::AllInstances)
|
|
{
|
|
cl->Enumerate(filter.reference.ResourceURI(), enumRes, &nvp);
|
|
}
|
|
else
|
|
{
|
|
// Enumerate associations
|
|
assocType = (filter.assocType == Intel::WSManagement::EnumerateFilter::AssociatedInstance ? WSMAN_ASSOCIATED : WSMAN_ASSOCIATOR);
|
|
assocClass = filter.associationClass;
|
|
resultClass = filter.resultClass;
|
|
role = filter.role;
|
|
resultRole = filter.resultRole;
|
|
resultProp = filter.resultProperties;
|
|
|
|
WsmanFilter wsman_filter(epr, assocType, assocClass, resultClass, role, resultRole, resultProp);
|
|
cl->Enumerate(enumerateURI, enumRes, opts, wsman_filter);
|
|
}
|
|
}
|
|
catch (WsmanSoapFault& ex)
|
|
{
|
|
WSManException ex1(ex.GetFaultReason());
|
|
throw ex1;
|
|
}
|
|
catch (WsmanClientException& ex)
|
|
{
|
|
HTTPException ex1(ex.what());
|
|
throw ex1;
|
|
}
|
|
}
|
|
|
|
// "Special" Enumerate of references
|
|
void CimOpenWsmanClient::EnumerateRef(vector<string>& enumRes, const EnumerateFilter& filter) const
|
|
{
|
|
string enumerateURI = "http://schemas.dmtf.org/wbem/wscim/1/*";
|
|
WsmanAssocType assocType;
|
|
string assocClass;
|
|
string resultClass;
|
|
string role;
|
|
string resultRole;
|
|
vector<string> resultProp;
|
|
|
|
CimReference tempReference = filter.reference;
|
|
WsmanEPR epr(tempReference.ResourceURI(), tempReference.Address());
|
|
WsManSelectors::const_iterator iter;
|
|
WsManSelectors tempSelectors = tempReference.Selectors();
|
|
NameValuePairs nvp;
|
|
for (iter = tempSelectors.begin(); iter != tempSelectors.end(); iter++)
|
|
{
|
|
epr.addTextSelector(iter->first, iter->second);
|
|
nvp.insert(pair<string, string>(iter->first, iter->second));
|
|
}
|
|
|
|
|
|
WsmanOptions opts(FLAG_ENUMERATION_ENUM_EPR);
|
|
|
|
try
|
|
{
|
|
if (filter.assocType == Intel::WSManagement::EnumerateFilter::AllInstances)
|
|
{
|
|
WsmanFilter empty_filter;
|
|
cl->Enumerate(filter.reference.ResourceURI(), enumRes, opts, empty_filter);
|
|
}
|
|
else
|
|
{
|
|
// Enumerate associations
|
|
assocType = (filter.assocType == Intel::WSManagement::EnumerateFilter::AssociatedInstance ? WSMAN_ASSOCIATED : WSMAN_ASSOCIATOR);
|
|
assocClass = filter.associationClass;
|
|
resultClass = filter.resultClass;
|
|
role = filter.role;
|
|
resultRole = filter.resultRole;
|
|
resultProp = filter.resultProperties;
|
|
|
|
|
|
WsmanFilter wsman_filter(epr, assocType, assocClass, resultClass, role, resultRole, resultProp);
|
|
cl->Enumerate(enumerateURI, enumRes, opts, wsman_filter);
|
|
}
|
|
}
|
|
catch (WsmanSoapFault& ex)
|
|
{
|
|
WSManException ex1(ex.GetFaultReason());
|
|
throw ex1;
|
|
}
|
|
catch (WsmanClientException& ex)
|
|
{
|
|
HTTPException ex1(ex.what());
|
|
throw ex1;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
// Renew a subscription
|
|
string CimOpenWsmanClient::Renew(const string& resourceUri, const string& identifier, float expire, const NameValuePairs* s) const
|
|
{
|
|
return cl->Renew(resourceUri, identifier, expire, s);
|
|
}
|
|
|
|
// Terminate a subscription
|
|
void CimOpenWsmanClient::Unsubscribe(const string& resourceUri, const string& identifier, const NameValuePairs* s) const
|
|
{
|
|
cl->Unsubscribe(resourceUri, identifier, s);
|
|
}
|
|
|
|
// Set auth method
|
|
void CimOpenWsmanClient::SetAuth(const char* auth_method)
|
|
{
|
|
connection.authmethod = (strcmp(auth_method, "digest") == 0) ? DIGEST : KERBEROS;
|
|
cl->SetAuth(auth_method);
|
|
}
|
|
|
|
|
|
// Set user name
|
|
void CimOpenWsmanClient::SetUserName(const char* user_name)
|
|
{
|
|
setUserName(user_name);
|
|
cl->SetUserName(user_name);
|
|
}
|
|
|
|
// Set passsword
|
|
void CimOpenWsmanClient::SetPassword(const char* password)
|
|
{
|
|
setPassword(password);
|
|
cl->SetPassword(password);
|
|
}
|
|
|
|
// Set encoding
|
|
void CimOpenWsmanClient::SetEncoding(const char* encoding)
|
|
{
|
|
cl->SetEncoding(encoding);
|
|
}
|
|
// Set CIM namespace
|
|
void CimOpenWsmanClient::SetNamespace(const char* ns)
|
|
{
|
|
cl->SetNamespace(ns);
|
|
}
|
|
|
|
#if defined (_WIN32) || defined (_WIN64)
|
|
// Set client certificate params
|
|
void CimOpenWsmanClient::SetClientCert(const char* caOid, const char* caName, const bool localCert)
|
|
{
|
|
setClientCert(caOid, caName, localCert);
|
|
cl->SetClientCert(caOid, caName, localCert);
|
|
}
|
|
void CimOpenWsmanClient::SetProxy(const char* proxy, const char* proxy_username, const char* proxy_password)
|
|
{
|
|
setProxy(proxy, proxy_username, proxy_password);
|
|
delete cl;
|
|
cl = NULL;
|
|
OpenConnection();
|
|
//cl->SetProxy(false,proxy, proxy_username, proxy_password);
|
|
}
|
|
|
|
#else
|
|
// Set server certificate params
|
|
void CimOpenWsmanClient::SetServerCert(const char* cainfo, const char* capath)
|
|
{
|
|
cl->SetServerCert(cainfo, capath);
|
|
}
|
|
|
|
// Set client certificates params
|
|
void CimOpenWsmanClient::SetClientCert(const char* cert, const char* key)
|
|
{
|
|
cl->SetClientCert(cert, key);
|
|
}
|
|
#endif
|
|
|
|
} // namespace WSManagement
|
|
} // namespace Intel
|
|
|