676 lines
23 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Provider;
using System.Xml;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using Intel.Management.Wsman;
namespace Intel.Management.PSModule.Amt
{
class AuditorService : SettingsContainer
{
public AuditorService(DriveItem parent)
: base("AccessMonitor", parent)
{
_value = new LogContent();
}
public override void GetChildItems(ChildWriter writer)
{
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
IWsmanEnumeration colObj = conn.ExecQuery("SELECT * FROM AMT_AuditLog");
foreach (IWsmanItem item in colObj)
{
if (item.Object.GetProperty("Name").ToString().Equals("Intel(r) AMT:Audit Log"))
{
//AuditState String[]
//EnabledState
_settingsObj=item.Object;
_refToSettings = conn.NewReference(item.Object.ResourceUri);
_refToSettings.AddSelector("Name",item.Object.GetProperty("Name").ToString());
writer.Add(new AuditState(this));
writer.Add(new UIntSetting("CurrentNumberOfRecords",this));
writer.Add(new UIntSetting("MaxAllowedAuditors",this));
writer.Add(new UIntSetting("MaxNumberOfRecords",this));
if (this.HasSetting("MinDaysToKeep"))
writer.Add(new UIntSetting("MinDaysToKeep",this));
if (this.HasSetting("OverwritePolicy"))
writer.Add(new ValueMapSetting("OverwritePolicy", ValueList.StoragePolicy, this));
writer.Add(new UIntSetting("PercentageFree",this));
//StoragePolicy
if (this.HasSetting("StoragePolicy"))
writer.Add(new ValueMapSetting("StoragePolicy", ValueList.StoragePolicy, this));
writer.Add(new DriveEntry("TimeOfLastRecord",
AmtDriveInfo.FormatDate(item.Object.GetProperty("TimeOfLastRecord")),this));
writer.Add(new Enabled(item.Object.GetProperty("EnabledState").ToString(), this));
writer.Add(new Signature(this));
writer.Add(new Events(this));
}
}
}
/*public IManagedReference GetReference()
{
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
return conn.NewReference("SELECT * FROM AMT_AuditLog WHERE Name='Intel(r) AMT:Audit Log'");
}*/
public override object GetReturnObject()
{
return new NameValuePairItem(Name, Value);
}
//static readonly int AUDIT_DISABLED = 1;
//static readonly int AUDIT_NO_SIGNATURE = 16;
enum AuditPolicyType
{
None=0,
Critical=1,
}
class AuditGroupValue
{
int _groupId;
public AuditGroupValue(int id)
{
_groupId = id;
}
public int GroupId
{
get { return _groupId; }
}
public override string ToString()
{
return "PolicyGroup";
}
}
class AuditPolicyValue
{
int _eventId;
bool _enabled;
AuditPolicyType _policyType;
int _appId;
public AuditPolicyValue(int eventId,int appId,bool enabled,AuditPolicyType policyType)
{
_eventId = eventId;
_appId = appId;
_enabled=enabled;
_policyType=policyType;
}
public AuditPolicyValue(AuditPolicyValue copy)
{
_eventId = copy._eventId;
_appId = copy._appId;
_enabled = copy._enabled;
_policyType = copy._policyType;
}
public int GroupId
{
get { return _appId; }
}
public int EventId
{
get { return _eventId; }
}
public bool Enabled
{
get { return _enabled; }
set { _enabled = value; }
}
public AuditPolicyType PolicyType
{
get { return _policyType; }
set { _policyType = value; }
}
public override string ToString()
{
string result = "Disabled";
if (_enabled && _policyType == AuditPolicyType.None)
result = "Enabled";
if (_enabled && _policyType == AuditPolicyType.Critical)
result = "Critical";
return result;
}
}
class AuditPolicy : DriveItem
{
public AuditPolicy(string name, int eventId, int appId,
bool enabled, AuditPolicyType policyType, DriveItem parent)
: base(name, new AuditPolicyValue(eventId,appId,enabled,policyType), parent)
{
}
public override void SetItem(object values, DriveProvider provider)
{
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
AuditPolicyValue policy = new AuditPolicyValue((AuditPolicyValue)_value);
IManagedReference refToPolicy = conn.NewReference("SELECT * FROM AMT_AuditPolicyRule");
IManagedInstance input = refToPolicy.CreateMethodInput("SetAuditPolicy");
if (string.Compare(values.ToString(), "Disable", true) == 0)
{
policy.Enabled = false;
policy.PolicyType = AuditPolicyType.None;
}
else if (string.Compare(values.ToString(), "Enabled", true) == 0)
{
policy.Enabled = true;
policy.PolicyType = AuditPolicyType.None;
}
else if (string.Compare(values.ToString(), "Critical", true) == 0)
{
policy.Enabled = true;
policy.PolicyType = AuditPolicyType.Critical;
}
else
{
throw new PSArgumentException();
}
input.SetProperty("Enable", policy.Enabled.ToString().ToLower());
input.SetProperty("AuditedAppID", policy.GroupId.ToString());
input.SetProperty("EventID", policy.EventId.ToString());
input.SetProperty("PolicyType", ((int)(policy.PolicyType)).ToString());
IManagedInstance outObj = refToPolicy.InvokeMethod(input);
switch (outObj.GetProperty("ReturnValue").ToString())
{
case "0":
_value = policy;
break;
case "1":
AmtException.ThrowInvokeError(outObj, "Internal Error");
break;
case "2":
AmtException.ThrowInvokeError(outObj, "Not Ready");
break;
case "16":
AmtException.ThrowInvokeError(outObj, "Not Permitted");
break;
case "36":
AmtException.ThrowInvokeError(outObj, "Invalid Parameter");
break;
case "38":
AmtException.ThrowInvokeError(outObj, "Flash write limit exceeded");
break;
case "2075":
AmtException.ThrowInvokeError(outObj, "Audit Fail");
break;
default:
AmtException.ThrowInvokeError(outObj);
break;
}
}
public override object GetReturnObject()
{
return new WideValueItem(Name, Value);
}
}
class AuditGroup : DriveContainer
{
int _groupId;
public AuditGroup(string name, int groupId, DriveItem parent)
: base(name , parent)
{
//_value = new AuditGroupValue(groupId);
_groupId = groupId;
}
private bool FindPolicyType(IManagedInstance ruleObj,int eventId, out AuditPolicyType policyType)
{
IWsmanItem eventItems = ruleObj.GetProperty("AuditApplicationEventID");
IWsmanItem ruleItems = ruleObj.GetProperty("PolicyType");
policyType = AuditPolicyType.None;
bool result = false;
for (int i = 0; i < eventItems.Count; i++)
{
string appevent = eventItems.Item(i).ToString();
// read policyNumer (appID + EventID)
uint policyNumber = uint.Parse(appevent);
// get policy Data
byte[] policyData = BitConverter.GetBytes(policyNumber);
//Array.Reverse(policyData);
//read event/App IDs
ushort eventNum = BitConverter.ToUInt16(policyData, 0);
ushort appId = BitConverter.ToUInt16(policyData, 2);
if ((int)eventNum == eventId && (int)appId == _groupId)
{
policyType = (AuditPolicyType)int.Parse(ruleItems.Item(i).ToString());
result = true;
break;
}
}
return result;
}
public override void GetChildItems(ChildWriter writer)
{
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
IManagedReference refToPolicy = conn.NewReference("SELECT * FROM AMT_AuditPolicyRule");
IManagedInstance ruleObj = refToPolicy.Get();
XmlDocument doc = new XmlDocument();
doc.LoadXml(Intel.Management.PSModule.Properties.Resources.AuditEventsXML);
XmlNode groupNode = doc.DocumentElement.SelectSingleNode(string.Format(
"Group[@AppId=\"{0}\"]", _groupId.ToString()));
XmlNodeList list = groupNode.ChildNodes;
foreach (XmlNode node in list)
{
if (node.LocalName.Equals("Event"))
{
string name = ((XmlElement)node).GetAttribute("Name");
int eventId = int.Parse(((XmlElement)node).GetAttribute("EventId"));
AuditPolicyType policyType;
bool enabled=FindPolicyType(ruleObj,eventId, out policyType);
writer.Add(new AuditPolicy(name, eventId,_groupId,enabled,policyType, this));
}
}
}
public static DriveContainer LoadEvents(DriveItem parent)
{
DriveContainer result = new DriveContainer("Events", parent);
XmlDocument doc = new XmlDocument();
doc.LoadXml(Intel.Management.PSModule.Properties.Resources.AuditEventsXML);
XmlNodeList list = doc.DocumentElement.ChildNodes;
foreach (XmlNode node in list)
{
if (node.LocalName.Equals("Group"))
{
string name = ((XmlElement)node).GetAttribute("Name");
int appId = int.Parse(((XmlElement)node).GetAttribute("AppId"));
result.AddChildItem(new AuditGroup(name, appId, result));
}
}
return result;
}
public override object GetReturnObject()
{
return new NameValuePairItem(Name, Value);
}
}
class Events : DriveContainer
{
public Events(DriveItem parent) :
base("Events", parent)
{
}
public override void GetChildItems(ChildWriter writer)
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(Intel.Management.PSModule.Properties.Resources.AuditEventsXML);
XmlNodeList list = doc.DocumentElement.ChildNodes;
foreach (XmlNode node in list)
{
if (node.LocalName.Equals("Group"))
{
string name = ((XmlElement)node).GetAttribute("Name");
int appId = int.Parse(((XmlElement)node).GetAttribute("AppId"));
writer.Add(new AuditGroup(name, appId, this));
}
}
}
}
class SignatureMaterial : X509Certificate2
{
public SignatureMaterial(byte[] rawData)
: base(rawData)
{
}
}
class AuditWriter : IContentWriter
{
IManagedReference _refToLog;
public AuditWriter(IManagedReference refToLog)
{
_refToLog = refToLog;
}
public void Dispose()
{
}
public void Close()
{
}
public void Seek(long offset, System.IO.SeekOrigin origin)
{
}
public System.Collections.IList Write(System.Collections.IList content)
{
byte[] keyData = null;
byte[] certData = null;
if (content.Count > 0)
{
X509Certificate2 cert2 = null;
if (content[0] is PSObject)
{
if (((PSObject)content[0]).BaseObject is X509Certificate2)
cert2 = (X509Certificate2)content[0];
else if (((PSObject)content[0]).BaseObject is X509CertificateCollection)
{
foreach (X509Certificate2 cert in (X509CertificateCollection)content[0])
{
if (cert.HasPrivateKey)
cert2 = cert;
}
}
}
else if ((content[0] is X509Certificate2))
cert2 = (X509Certificate2)content[0];
if (cert2 == null)
throw new FormatException();
if (cert2.HasPrivateKey)
{
if (cert2.PrivateKey is RSACryptoServiceProvider)
{
keyData=Intel.Management.Mei.KeyFormatter.EncodeKey(cert2.PrivateKey as RSACryptoServiceProvider, true);
certData = cert2.RawData;
}
}
if (keyData == null)
throw new PSArgumentException("Certificate does not contain private key");
IManagedInstance inputObj = _refToLog.CreateMethodInput("SetSigningKeyMaterial");
inputObj.SetProperty("SigningMechanismType", "0");
inputObj.SetProperty("SigningKey", Convert.ToBase64String(keyData));
inputObj.SetProperty("LengthOfCertificates", certData.Length.ToString());
inputObj.SetProperty("Certificates", Convert.ToBase64String(certData));
IManagedInstance outObj = _refToLog.InvokeMethod(inputObj);
if (!outObj.GetProperty("ReturnValue").ToString().Equals("0"))
{
ValueMap map = ValueMap.Create(outObj.GetProperty("ReturnValue").ToString(),ValueList.AuditSetKeyResult);
AmtException.ThrowInvokeError(outObj, map.ToString());
}
}
return content;
}
}
class AuditReader : IContentReader
{
IManagedReference _refToLog;
List<X509Certificate2> _list;
public AuditReader(IManagedReference refToLog)
{
_refToLog = refToLog;
}
public void Dispose()
{
}
public void Close()
{
}
public void Seek(long offset, System.IO.SeekOrigin origin)
{
}
public System.Collections.IList Read(long size)
{
System.Collections.IList content = new System.Collections.ArrayList();
if (_list == null)
{
_list = new List<X509Certificate2>();
IManagedInstance inputObj = _refToLog.CreateMethodInput("ExportAuditLogSignature");
inputObj.SetProperty("SigningMechanism", "0");
IManagedInstance outObj = _refToLog.InvokeMethod(inputObj);
string result = outObj.GetProperty("ReturnValue").ToString();
if (result.Equals("1"))
{
AmtException.ThrowInvokeError(outObj, "Internal Error");
}
else if (result.Equals("2"))
{
AmtException.ThrowInvokeError(outObj, "Not Ready");
}
else if (result.Equals("16"))
{
AmtException.ThrowInvokeError(outObj, "Not Permitted");
}
byte[] certData = Convert.FromBase64String(outObj.GetProperty("Certificates").ToString());
int offset = 0;
foreach (IWsmanItem item in outObj.GetProperty("LengthOfCertificates"))
{
int length = int.Parse(item.ToString());
byte[] rawData = new byte[length];
Array.Copy(certData, offset, rawData, 0, length);
X509Certificate2 cert = new X509Certificate2(rawData);
_list.Add(cert);
offset = offset + length;
}
}
if (_list != null)
{
for(long i=0;i<size && _list.Count>0;i++)
{
content.Add(_list[0]);
_list.RemoveAt(0);
}
}
return content;
}
}
class AuditState : SettingsItem
{
public AuditState(SettingsContainer parent)
: base("AuditState", parent)
{
List<string> list = new List<string>();
int state=int.Parse(parent.GetSetting("AuditState").ToString());
if ((state & 0x01) != 0)
list.Add("Disabled");
else
list.Add("Enabled");
if ((state & 0x02) !=0 )
list.Add("Locked");
if ((state & 0x04) !=0 )
list.Add("Almost Full - The storage area dedicated for the audit log reached 85% full");
if ((state & 0x08) != 0)
list.Add("Full - The storage area dedicated for the audit log is completely full; no events will be logged and critical events in policy will not be executed.");
if ((state & 0x10) !=0 )
list.Add("No Key - No key and certificate were set for the signing of the audit log. Feature cannot be enabled");
_value = list.ToArray();
}
}
class Enabled : SettingsItem
{
public Enabled(string state,SettingsContainer parent)
: base("Enabled", parent)
{
_value = state.Equals("2") || state.Equals("6");
}
public override void SetItem(object values, DriveProvider provider)
{
SettingsContainer settings = (SettingsContainer)_parent;
IManagedReference refToLog = settings.GetReference();
IManagedInstance inputObj = refToLog.CreateMethodInput("RequestStateChange");
IManagedInstance outObj=null;
bool changeTo = bool.Parse(values.ToString());
if (changeTo != (bool)_value && changeTo==true)
{
inputObj.SetProperty("RequestedState", "2");
outObj = refToLog.InvokeMethod(inputObj);
}
else if (changeTo != (bool)_value && changeTo==false)
{
inputObj.SetProperty("RequestedState", "3");
outObj = refToLog.InvokeMethod(inputObj);
}
switch (outObj.GetProperty("ReturnValue").ToString())
{
case "0":
//refresh the container
_value = changeTo;
break;
case "32770":
AmtException.ThrowInvokeError(outObj, "Not ready");
break;
case "32784":
AmtException.ThrowInvokeError(outObj, "Not Permitted");
break;
case "32806":
AmtException.ThrowInvokeError(outObj, "Invalid Parameter");
break;
case "2076":
AmtException.ThrowInvokeError(outObj, "Flash write limit exceeded");
break;
default:
AmtException.ThrowInvokeError(outObj);
break;
}
}
}
class Signature : SettingsItem
{
public Signature(SettingsContainer parent)
: base("Signature", parent)
{
_value = new Content();
}
public override IContentReader GetContentReader(DriveProvider provider)
{
return new AuditReader(((AuditorService)_parent).GetReference());
}
public override IContentWriter GetContentWriter(DriveProvider provider)
{
return new AuditWriter(((AuditorService)_parent).GetReference());
}
public override void ClearContent(DriveProvider provider)
{
}
}
} //End AuditorService
}//end namepsace