282 lines
8.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Management.Automation;
using System.Management.Automation.Provider;
using Intel.Management.Mei;
using Intel.Management.Wsman;
using Intel.Management.PSModule.Amt;
namespace Intel.Management.PSModule.Heci
{
class LocalService : DriveContainer
{
enum ControlModeType
{
NotProvisioned=0,
Client=1,
Admin=2,
}
enum CertChainStatus
{
NotStarted = 0,
InProgress = 1,
Complete = 2,
}
class HostSetup : DriveContainer
{
HECIClass _heci;
WsmanConnection _conn;
string _hash;
public HostSetup(HECIClass heci,DriveItem parent)
: base ("Setup",parent)
{
_heci = heci;
}
public override void GetChildItems(ChildWriter writer)
{
if (_conn == null)
{
_heci.Init();
try
{
string username, password;
if (_heci.GetLocalAdminCredentials(out username, out password))
{
_conn = new WsmanConnection();
_conn.SetCredentials(username, password);
}
}
finally
{
_heci.DeInit();
}
}
if (_conn == null)
throw new NotSupportedException();
IManagedReference refToService = _conn.NewReference("IPS_HostBasedSetupService");
IManagedInstance serviceObj = refToService.Get();
string currentMode = serviceObj.GetProperty("CurrentControlMode").ToString();
List<string> modes = new List<string>();
foreach (IWsmanItem item in serviceObj.GetProperty("AllowedControlModes"))
{
if (item.ToString().Equals("1"))
modes.Add("Client");
if (item.ToString().Equals("2"))
modes.Add("Admin");
}
if (!currentMode.Equals("0")) // the current mode
modes.Add("NotProvisioned");
writer.Add(new DriveItem("AllowedControlModes", modes.ToArray(), this));
if (!serviceObj.GetProperty("CertChainStatus").IsNull)
writer.Add(new DriveItem("CertChainStatus",
(CertChainStatus)int.Parse(serviceObj.GetProperty("CertChainStatus").ToString()), this));
if (!serviceObj.GetProperty("ConfigurationNonce").IsNull)
writer.Add( new DriveItem("ConfigurationNonce",serviceObj.GetProperty("ConfigurationNonce").ToString(), this));
writer.Add(new SetupMode(
(ControlModeType)int.Parse(currentMode),
this));
writer.Add(new SetupPassword(this));
}
public void SetAdminPassword(string password)
{
IManagedInstance settingsObj = _conn.NewInstance("SELECT * FROM AMT_GeneralSettings");
string realm = settingsObj.GetProperty("DigestRealm").ToString();
MD5 md5 = new MD5CryptoServiceProvider();
md5.Initialize();
StringBuilder builder = new StringBuilder();
builder.Append("admin");
builder.Append(":");
builder.Append(realm);
builder.Append(":");
builder.Append(password);
_hash = BitConverter.ToString(md5.ComputeHash(Encoding.ASCII.GetBytes(builder.ToString())));
_hash = _hash.Replace("-", string.Empty);
}
public void LocalSetup()
{
if (_hash == null)
throw new DriveException("NetAdminPassword not set");
IManagedReference refToService = _conn.NewReference("IPS_HostBasedSetupService");
IManagedInstance inputObj = refToService.CreateMethodInput("Setup");
inputObj.SetProperty("NetAdminPassEncryptionType", "2");
inputObj.SetProperty("NetworkAdminPassword", _hash);
// optional and signing certificate
IManagedInstance outObj = refToService.InvokeMethod(inputObj);
string result = outObj.GetProperty("ReturnValue").ToString();
switch (result)
{
case "0":
break;
case "1":
AmtException.ThrowInvokeError(outObj,"Internal Error");
break;
case "2":
AmtException.ThrowInvokeError(outObj, "Invalid State");
break;
case "3":
AmtException.ThrowInvokeError(outObj, "Invalid Parameter");
break;
case "4":
AmtException.ThrowInvokeError(outObj, "Method Disabled");
break;
case "5":
AmtException.ThrowInvokeError(outObj, "Authentication Faild");
break;
case "6":
AmtException.ThrowInvokeError(outObj, "Flash write limit exceeded");
break;
default:
AmtException.ThrowInvokeError(outObj);
break;
}
}
public void UnProvision()
{
_heci.Init();
try
{
if (!_heci.UnProvision())
throw new InvalidOperationException();
}
finally
{
_heci.DeInit();
}
}
public override void Clear()
{
_conn = null;
_hash = null;
base.Clear();
}
}
class SetupPassword : DriveItem
{
public SetupPassword(DriveItem parent)
: base("NetAdminPassword", string.Empty, parent)
{
}
public override void SetItem(object values, DriveProvider provider)
{
HostSetup service = (HostSetup)_parent;
service.SetAdminPassword(values.ToString());
}
}
class SetupMode : DriveItem
{
public SetupMode(ControlModeType mode, DriveItem parent)
: base("CurrentControlMode",mode, parent)
{
}
public override void SetItem(object values, DriveProvider provider)
{
HostSetup service = (HostSetup)_parent;
string value = values.ToString();
if (string.Compare(value, "NotProvisioned", true) == 0)
{
service.UnProvision();
_value = ControlModeType.NotProvisioned;
_parent.Clear();
}
else if (string.Compare(value, "Client", true) == 0)
{
service.LocalSetup();
_value = ControlModeType.Client;
}
else if (string.Compare(value, "Admin", true) == 0)
{
throw new NotImplementedException();
//_value = ControlModeType.Admin;
}
else
throw new FormatException();
}
}
HECIClass _heci;
public LocalService(DriveItem parent)
: base("Local",parent)
{
}
public override void GetChildItems(ChildWriter writer)
{
if (_heci == null)
{
_heci = new HECIClass();
}
writer.Add(new HostSetup(_heci, this));
/*_heci.Init();
try
{
HECIClass.ProvisioningState state;
if (_heci.GetProvisioningState(out state))
{
writer.Add(new ProvisioningState(_heci,state, this));
}
}
finally
{
_heci.DeInit();
}*/
}
}
}