603 lines
20 KiB
C#
603 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Xml;
|
|
using System.Net;
|
|
using System.IO;
|
|
|
|
namespace Intel.Management.Wsman
|
|
{
|
|
class ManagedReference : IManagedReference
|
|
{
|
|
private WsmanConnection _conn;
|
|
private XmlDocument _document;
|
|
private XmlNamespaceManager _ns;
|
|
|
|
public ManagedReference(WsmanConnection conn, string resourceUri)
|
|
{
|
|
_conn = conn;
|
|
_document = new XmlDocument();
|
|
bool isExisting = false;
|
|
|
|
if (resourceUri.StartsWith("<"))
|
|
{
|
|
isExisting = true;
|
|
_document.LoadXml(resourceUri);
|
|
}
|
|
else if (resourceUri.ToLower().StartsWith("select * from "))
|
|
{
|
|
IManagedReference objRef = conn.GetReferenceFromSQL(resourceUri);
|
|
_document.LoadXml(objRef.Xml);
|
|
}
|
|
else if (resourceUri.IndexOf("/") > 0)
|
|
{
|
|
_document.LoadXml(string.Format(WsmanResources.EPR_XML, resourceUri));
|
|
}
|
|
else
|
|
{
|
|
string name = resourceUri;
|
|
int pos = name.IndexOf('_');
|
|
|
|
if (pos > 0)
|
|
name = _conn.ResolveNamespace(name.Substring(0, pos));
|
|
else if (name.Equals("*"))
|
|
name = _conn.ResolveNamespace("*");
|
|
|
|
|
|
if (name != null)
|
|
{
|
|
if (pos > 0)
|
|
name = name + resourceUri;
|
|
}
|
|
else
|
|
{
|
|
throw new
|
|
IndexOutOfRangeException(
|
|
string.Format(WsmanResources.NS_NOT_FOUND,
|
|
resourceUri));
|
|
}
|
|
|
|
|
|
_document.LoadXml(string.Format(WsmanResources.EPR_XML, name));
|
|
|
|
// assign the addreess
|
|
if (!isExisting)
|
|
{
|
|
LoadNamespaces();
|
|
if (_document.DocumentElement != null)
|
|
{
|
|
XmlNode node = _document.DocumentElement.SelectSingleNode("wsa:Address", _ns);
|
|
if (node != null)
|
|
node.InnerText = _conn.Address;
|
|
}
|
|
}
|
|
|
|
|
|
if (name.Equals(string.Empty))
|
|
{
|
|
LoadNamespaces();
|
|
//XmlNode node = _document.DocumentElement.SelectSingleNode("wsa:ReferenceParameters", _ns);
|
|
//XmlNode node = _document.DocumentElement.SelectSingleNode("wsa:ReferenceParameters/wsman:SelectorSet", _ns);
|
|
//node.ParentNode.RemoveChild(node);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public ManagedReference(WsmanConnection conn, XmlDocument document)
|
|
{
|
|
_conn = conn;
|
|
_document = document;
|
|
_ns = null;
|
|
}
|
|
|
|
public string Xml
|
|
{
|
|
get
|
|
{
|
|
return _document.InnerXml;
|
|
}
|
|
set
|
|
{
|
|
_document.LoadXml(value);
|
|
}
|
|
}
|
|
|
|
public string ResourceUri
|
|
{
|
|
get
|
|
{
|
|
LoadNamespaces();
|
|
if (_document.DocumentElement != null)
|
|
{
|
|
XmlNode node = _document.DocumentElement.SelectSingleNode("wsa:ReferenceParameters/wsman:ResourceURI", _ns);
|
|
if (node != null)
|
|
return node.InnerText;
|
|
}
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
public string SimpleName
|
|
{
|
|
get
|
|
{
|
|
string result = ResourceUri;
|
|
if(result != null)
|
|
{
|
|
int pos = result.LastIndexOf("/");
|
|
if (pos > 0)
|
|
result = result.Substring(pos+1);
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
|
|
public string Address
|
|
{
|
|
get
|
|
{
|
|
LoadNamespaces();
|
|
if (_document.DocumentElement != null)
|
|
{
|
|
XmlNode node = _document.DocumentElement.SelectSingleNode("wsa:Address", _ns);
|
|
if (node != null)
|
|
return node.InnerText;
|
|
}
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
public IWsmanConnection Connection
|
|
{
|
|
get
|
|
{
|
|
return _conn;
|
|
}
|
|
}
|
|
|
|
public void AddSelector(string name, object value)
|
|
{
|
|
LoadNamespaces();
|
|
|
|
XmlNode refNode = _document.DocumentElement.SelectSingleNode("wsa:ReferenceParameters", _ns);
|
|
XmlNode setNode = null;
|
|
XmlNode uriNode = null;
|
|
|
|
if (refNode!=null)
|
|
{
|
|
setNode = refNode.SelectSingleNode("wsman:SelectorSet",_ns);
|
|
uriNode = refNode.SelectSingleNode("wsman:ResourceURI", _ns);
|
|
|
|
|
|
}
|
|
if (setNode==null && refNode!=null && uriNode!=null)
|
|
{
|
|
setNode = _document.CreateElement(uriNode.Prefix,"SelectorSet",uriNode.NamespaceURI);
|
|
refNode.AppendChild(setNode);
|
|
|
|
}
|
|
|
|
if (setNode!=null)
|
|
{
|
|
XmlElement elt = _document.CreateElement(setNode.Prefix, "Selector", setNode.NamespaceURI);
|
|
setNode.AppendChild(elt);
|
|
|
|
elt.SetAttribute("Name", name);
|
|
if (value is IManagedReference)
|
|
elt.InnerXml = ((IManagedReference)value).Xml;
|
|
else if (value is string)
|
|
elt.InnerText = value.ToString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public IManagedInstance CreateMethodInput(string methodName)
|
|
{
|
|
return new ManagedInstance(_conn,
|
|
string.Format(WsmanResources.INPUT_INSTANCE,
|
|
methodName,ResourceUri));
|
|
}
|
|
|
|
public IManagedInstance Get()
|
|
{
|
|
IManagedInstance instance = null;
|
|
try
|
|
{
|
|
instance = (IManagedInstance)_conn.SubmitRequest(WsmanResources.GET_XML, this,null);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
// In AMT version latest then 5.0 if there is no instance- the machine throw an exception- so we catch it and return null.
|
|
if(e.Message.Contains("No route can be determined to reach the destination role defined by the WSAddressing To"))
|
|
instance = null;
|
|
else
|
|
throw;
|
|
}
|
|
|
|
return instance;
|
|
}
|
|
|
|
public IManagedInstance Put(object inputObj)
|
|
{
|
|
IManagedInstance input = (IManagedInstance)inputObj;
|
|
return (IManagedInstance)_conn.SubmitRequest(WsmanResources.PUT_XML, this,input);
|
|
}
|
|
|
|
public void Delete()
|
|
{
|
|
_conn.SubmitRequest(WsmanResources.DELETE_XML, this, null);
|
|
}
|
|
|
|
public IWsmanEnumeration Enumerate()
|
|
{
|
|
return Enumerate(string.Empty, string.Empty);
|
|
}
|
|
|
|
public IWsmanEnumeration Enumerate(object input, string mode)
|
|
{
|
|
StringBuilder builder = new StringBuilder();
|
|
if (input != null && input is ManagedInstance)
|
|
{
|
|
builder.Append("<w:Filter Dialect=\"");
|
|
|
|
if (((ManagedInstance)input).SimpleName.Equals("AssociatedInstances"))
|
|
{
|
|
builder.Append(WsmanResources.FILTER_DIALECT);
|
|
}
|
|
|
|
|
|
builder.Append("\">");
|
|
builder.Append(((ManagedInstance)input).Xml);
|
|
builder.Append("</w:Filter>");
|
|
}
|
|
|
|
|
|
else if (input != null && input is string && !input.Equals(string.Empty))
|
|
{
|
|
string filter = (string)input;
|
|
if (filter.ToLower().StartsWith("associators where "))
|
|
{
|
|
IManagedReference objRef = new ManagedReference(_conn, "http://schemas.dmtf.org/wbem/wscim/1/*");
|
|
BuildAssociation(filter, builder);
|
|
return objRef.Enumerate(builder, mode);
|
|
}
|
|
else if (filter.Equals("http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter"))
|
|
{
|
|
LoadNamespaces();
|
|
builder.Append("<w:Filter Dialect=\"http://schemas.dmtf.org/wbem/wsman/1/wsman/SelectorFilter\">");
|
|
|
|
XmlNode node = _document.DocumentElement.SelectSingleNode("wsa:ReferenceParameters/wsman:SelectorSet", _ns);
|
|
|
|
if (node!=null)
|
|
{
|
|
builder.Append(node.OuterXml);
|
|
}
|
|
|
|
|
|
builder.Append("</w:Filter>");
|
|
}
|
|
}
|
|
else if (input is StringBuilder stringBuilder)
|
|
{
|
|
builder = stringBuilder;
|
|
}
|
|
if (mode != null && !mode.Equals(string.Empty))
|
|
{
|
|
//Modes EnumerateObjectAndEPR
|
|
//EnumerateEPR
|
|
builder.Append("<w:EnumerationMode>");
|
|
builder.Append(mode);
|
|
builder.Append("</w:EnumerationMode>");
|
|
}
|
|
|
|
|
|
|
|
return (IWsmanEnumeration)_conn.SubmitRequest(
|
|
string.Format(WsmanResources.ENUM_XML,string.Empty,//_conn.Options.MaxElements.ToString(),
|
|
builder.ToString()),
|
|
this,null);
|
|
}
|
|
|
|
public IManagedInstance InvokeMethod(object inputObj)
|
|
{
|
|
IManagedInstance input = (IManagedInstance)inputObj;
|
|
return (IManagedInstance)_conn.SubmitRequest(
|
|
string.Format(WsmanResources.INVOKE_XML,
|
|
input.ResourceUri + "/" + input.MethodName),
|
|
this, input);
|
|
|
|
}
|
|
|
|
public IManagedReference Subscribe(string mode, string to)
|
|
{
|
|
StringBuilder builder = new StringBuilder();
|
|
StringBuilder secBuilder = new StringBuilder();
|
|
|
|
//<user>:<password>@<host>:<port>/<url-path>
|
|
|
|
|
|
|
|
if (to.Trim().TrimStart().StartsWith("<"))
|
|
{
|
|
XmlDocumentFragment frag = _document.CreateDocumentFragment();
|
|
frag.InnerXml = to;
|
|
|
|
XmlNode addrNode=frag.SelectSingleNode("Address");
|
|
XmlNode authNode = frag.SelectSingleNode("Auth");
|
|
XmlNode userNode = frag.SelectSingleNode("Username");
|
|
XmlNode passwordNode = frag.SelectSingleNode("Password");
|
|
XmlNode refNode = frag.SelectSingleNode("ReferenceParameters");
|
|
|
|
builder.Append("<wse:Delivery Mode=\"");
|
|
builder.Append(mode);
|
|
builder.Append("\" >");
|
|
builder.Append("<wse:NotifyTo>");
|
|
|
|
if(addrNode != null)
|
|
{
|
|
builder.Append("<a:Address>");
|
|
builder.Append(addrNode.InnerText);
|
|
builder.Append("</a:Address>");
|
|
}
|
|
|
|
if (authNode != null)
|
|
{
|
|
builder.Append("<wsman:Auth Profile=\"");
|
|
builder.Append(authNode.InnerText);
|
|
builder.Append("\"/>");
|
|
}
|
|
|
|
if (userNode != null && passwordNode != null)
|
|
{
|
|
_document.DocumentElement.SetAttribute("xmlns:wst",
|
|
"http://schemas.xmlsoap.org/ws/2005/02/trust");
|
|
_document.DocumentElement.SetAttribute("xmlns:wsse",
|
|
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
|
|
|
|
secBuilder.Append("<wst:IssuedTokens soap:mustUnderstand=\"true\">");
|
|
secBuilder.Append("<wst:RequestSecurityTokenResponse>");
|
|
secBuilder.Append("<wst:TokenType>");
|
|
secBuilder.Append("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken");
|
|
secBuilder.Append("</wst:TokenType>");
|
|
secBuilder.Append("<wst:RequestedSecurityToken>");
|
|
secBuilder.Append("<wsse:UsernameToken>");
|
|
secBuilder.Append("<wsse:Username>");
|
|
secBuilder.Append(userNode.InnerText);
|
|
secBuilder.Append("</wsse:Username>");
|
|
|
|
secBuilder.Append("<wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText\">");
|
|
secBuilder.Append(passwordNode.InnerText);
|
|
secBuilder.Append("</wsse:Password>");
|
|
|
|
secBuilder.Append("</wsse:UsernameToken>");
|
|
|
|
secBuilder.Append("</wst:RequestedSecurityToken>");
|
|
secBuilder.Append("</wst:RequestSecurityTokenResponse>");
|
|
secBuilder.Append("</wst:IssuedTokens>");
|
|
|
|
if (authNode == null)
|
|
{
|
|
builder.Append("<wsman:Auth Profile=\"http://schemas.xmlsoap.org/ws/2004/08/eventing/DeliveryModes/secprofile/http/digest\"/>");
|
|
}
|
|
}
|
|
|
|
if (refNode != null)
|
|
{
|
|
StringBuilder refParam = new StringBuilder("<a:ReferenceParameters>" + refNode.InnerXml + "</a:ReferenceParameters>");
|
|
ValidateRefParms(refNode.InnerXml);
|
|
builder.Append(refParam.ToString());
|
|
}
|
|
|
|
|
|
builder.Append("</wse:NotifyTo>");
|
|
builder.Append("</wse:Delivery>");
|
|
}
|
|
else
|
|
{
|
|
builder.Append("<wse:Delivery Mode=\"");
|
|
builder.Append(mode);
|
|
builder.Append("\" >");
|
|
builder.Append("<wse:NotifyTo>");
|
|
|
|
|
|
builder.Append("<a:Address>");
|
|
builder.Append(to);
|
|
builder.Append("</a:Address>");
|
|
builder.Append("</wse:NotifyTo>");
|
|
builder.Append("</wse:Delivery>");
|
|
}
|
|
|
|
|
|
return (IManagedReference)_conn.SubmitRequest(
|
|
string.Format(WsmanResources.SUBSCRIBE_XML, secBuilder.ToString(),
|
|
builder.ToString()),
|
|
this, null);
|
|
}
|
|
|
|
public void Unsubscribe()
|
|
{
|
|
_conn.SubmitRequest(WsmanResources.UNSUBSCRIBE_XML, this, null);
|
|
}
|
|
|
|
public string ToString(string format)
|
|
{
|
|
LoadNamespaces();
|
|
|
|
if (format.Equals("Selectors"))
|
|
{
|
|
XmlNode setNode = _document.DocumentElement.SelectSingleNode(
|
|
"wsa:ReferenceParameters/wsman:SelectorSet", _ns);
|
|
if(setNode != null)
|
|
return setNode.InnerXml;
|
|
}
|
|
else if (format.Equals("Address"))
|
|
{
|
|
return _document.DocumentElement.InnerXml;
|
|
|
|
}
|
|
|
|
throw new FormatException();
|
|
|
|
}
|
|
|
|
public static IManagedReference GetEmbeddedRef(WsmanConnection conn, XmlNode node, XmlNamespaceManager ns)
|
|
{
|
|
IManagedReference result = null;
|
|
XmlNode addrNode = null;
|
|
XmlNode refNode = null;
|
|
XmlNode uriNode = null;
|
|
|
|
if (node.HasChildNodes &&
|
|
node.ChildNodes.Count > 1)
|
|
addrNode = node.SelectSingleNode("wsa:Address", ns);
|
|
|
|
if (addrNode != null)
|
|
refNode = node.SelectSingleNode("wsa:ReferenceParameters", ns);
|
|
|
|
if (refNode != null)
|
|
uriNode = refNode.SelectSingleNode("wsman:ResourceURI", ns);
|
|
|
|
if (addrNode != null && refNode != null && uriNode!=null )
|
|
{
|
|
XmlDocument doc = new XmlDocument();
|
|
object[] parms = {addrNode.Prefix,addrNode.NamespaceURI,
|
|
uriNode.Prefix,uriNode.NamespaceURI};
|
|
|
|
doc.LoadXml(string.Format(WsmanResources.EPR_INSTANCE, parms));
|
|
doc.DocumentElement.InnerXml = addrNode.OuterXml + refNode.OuterXml;
|
|
|
|
result = new ManagedReference(conn,
|
|
doc);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private void LoadNamespaces()
|
|
{
|
|
|
|
if (_document !=null && _ns == null)
|
|
{
|
|
_ns = new XmlNamespaceManager(_document.NameTable);
|
|
_ns.AddNamespace("wsa", WsmanResources.ADDRESSING_NS);
|
|
_ns.AddNamespace("wsman", WsmanResources.WSMAN_NS);
|
|
}
|
|
}
|
|
|
|
private void BuildAssociation(string query, StringBuilder builder)
|
|
{
|
|
|
|
XmlDocument doc = new XmlDocument();
|
|
|
|
string assocClass=null;
|
|
string resultClass=null;
|
|
string resultRole=null;
|
|
string role = null;
|
|
|
|
string objectEpr = _document.DocumentElement.InnerXml;
|
|
// remove xmlnamespaces
|
|
|
|
|
|
//look for AssocClass
|
|
int pos = query.ToLower().IndexOf("assocclass=");
|
|
query = query.Substring(pos+"assocclass=".Length);
|
|
pos = query.IndexOf(" ");
|
|
if (pos > 0)
|
|
assocClass = query.Substring(0, pos);
|
|
else
|
|
assocClass = query;
|
|
|
|
//look for ResultClass
|
|
pos = query.ToLower().IndexOf("resultclass=");
|
|
query = query.Substring(pos + "resultclass=".Length);
|
|
pos = query.IndexOf(" ");
|
|
if (pos > 0)
|
|
resultClass = query.Substring(0, pos);
|
|
else
|
|
resultClass = query;
|
|
|
|
|
|
|
|
|
|
|
|
builder.Append("<w:Filter ");
|
|
builder.Append("Dialect=\"http://schemas.dmtf.org/wbem/wsman/1/cimbinding/associationFilter\">");
|
|
|
|
builder.Append("<p:AssociatedInstances ");
|
|
builder.Append("xmlns:p=\"http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd\">");
|
|
|
|
|
|
builder.Append("<p:Object>");
|
|
builder.Append(objectEpr);
|
|
builder.Append("</p:Object>");
|
|
|
|
if (assocClass!=null)
|
|
{
|
|
builder.Append("<p:AssociationClassName>");
|
|
builder.Append(assocClass);
|
|
builder.Append("</p:AssociationClassName>");
|
|
}
|
|
if (resultRole != null)
|
|
{
|
|
builder.Append("<p:Role>");
|
|
builder.Append(role);
|
|
builder.Append("</p:Role>");
|
|
}
|
|
|
|
if (resultClass != null)
|
|
{
|
|
builder.Append("<p:ResultClassName>");
|
|
builder.Append(resultClass);
|
|
builder.Append("</p:ResultClassName>");
|
|
}
|
|
if (resultRole != null)
|
|
{
|
|
builder.Append("<p:ResultRole>");
|
|
builder.Append(resultRole);
|
|
builder.Append("</p:ResultRole>");
|
|
}
|
|
builder.Append("</p:AssociatedInstances>");
|
|
builder.Append("</w:Filter>");
|
|
}
|
|
|
|
//Validate the reference paramters
|
|
//the reference parmeters are limited to 256 chars and supported from Intel AMT 5.1
|
|
private void ValidateRefParms(string ReferenceParameters)
|
|
{
|
|
|
|
if (ReferenceParameters.Length > 256)
|
|
throw new FormatException("The length of the reference parmeters is limited to 256 characters");
|
|
|
|
}
|
|
|
|
|
|
public override bool Equals(Object obj)
|
|
{
|
|
if (ReferenceEquals(null, obj)) return false;
|
|
if (ReferenceEquals(this, obj)) return true;
|
|
if (obj.GetType() != typeof (ManagedReference)) return false;
|
|
return Equals((ManagedReference) obj);
|
|
}
|
|
|
|
public bool Equals(ManagedReference other)
|
|
{
|
|
if (ReferenceEquals(null, other)) return false;
|
|
if (ReferenceEquals(this, other)) return true;
|
|
return Equals(other._conn, _conn) && Equals(other._document, _document);
|
|
}
|
|
|
|
public override int GetHashCode()
|
|
{
|
|
unchecked
|
|
{
|
|
int result = (_conn != null ? _conn.GetHashCode() : 0);
|
|
result = (result*397) ^ (_document != null ? _document.GetHashCode() : 0);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|