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;
}
}
}
}