using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Management.Automation;
using Intel.Management.Wsman;
namespace Intel.Management.PSModule.Amt
{
///
/// Role Based Authorization service for "Users" folder
///
class RBAService : DriveContainer
{
public RBAService(DriveItem parent)
: base("ACL", parent)
{
_items = null;
}
public override void GetChildItems(ChildWriter writer)
{
writer.Add(new DigestUsers(this));
writer.Add(new KerberosUsers(this));
}
public override object GetReturnObject()
{
return new NameValuePairItem(Name, Value);
}
class UserAccount : DriveItem
{
protected IManagedReference _refToUser;
//protected IManagedReference _refToIdentity;
protected string _identity;
static string[] _properties = { "Privileges", "Enabled","IsAdmin" };
public UserAccount(string userName, IManagedReference refToUser, string identity, DriveItem parent)
: base(userName,new SecurityCredential(),parent)
{
_refToUser = refToUser;
_identity = identity;
}
public override string[] Properties
{
get
{
return _properties;
}
}
public virtual bool IsAdmin
{
get
{
return ((DigestUsers)_parent).IsAdmin(this);
}
}
public virtual bool Enabled
{
get
{
IManagedInstance userObj = _refToUser.Get();
string state = userObj.GetProperty("EnabledState").ToString();
return state.Equals("2") || state.Equals("6");
}
}
public virtual object[] Privileges
{
get
{
IWsmanConnection conn = _refToUser.Connection;
string privilegeName;
if (IsAdmin)
{
privilegeName = "Intel(r) AMT:Admin Privilege";
}
else
{
privilegeName = _identity + " Privilege";
}
IManagedReference refToPrivilege = conn.NewReference("CIM_Privilege");
refToPrivilege.AddSelector("InstanceID", privilegeName);
IManagedInstance privilegeObj = refToPrivilege.Get();
List realms = new List();
foreach (IWsmanItem item in privilegeObj.GetProperty("ActivityQualifiers"))
{
realms.Add(item.ToString());
}
return realms.ToArray();
}
set
{
IWsmanConnection conn = _refToUser.Connection;
string privilegeName;
if (IsAdmin)
{
privilegeName = "Intel(r) AMT:Admin Privilege";
}
else
{
privilegeName = _identity + " Privilege";
}
IManagedReference refToPrivilege = conn.NewReference("CIM_Privilege");
refToPrivilege.AddSelector("InstanceID", privilegeName);
IManagedInstance privilegeObj = refToPrivilege.Get();
privilegeObj.SetProperty("ActivityQualifiers", null);
privilegeObj.SetProperty("Activities", null);
privilegeObj.SetProperty("QualifierFormats", null);
foreach (string privilege in value)
{
privilegeObj.AddProperty("ActivityQualifiers", privilege);
privilegeObj.AddProperty("Activities","7");
privilegeObj.AddProperty("QualifierFormats", "16000");
}
refToPrivilege.Put(privilegeObj);
}
}
public override void RemoveItem(DriveProvider provider)
{
_refToUser.Delete();
_parent.RemoveChildItem(this);
}
public override void RenameItem(string newName)
{
IManagedInstance userObj = _refToUser.Get();
userObj.SetProperty("UserID", newName);
userObj=_refToUser.Put(userObj);
_name = userObj.GetProperty("UserID").ToString();
}
public override void SetItem(object values, DriveProvider provider)
{
IManagedInstance userObj = _refToUser.Connection.NewInstance(_refToUser.ResourceUri);
DigestUsers users = (DigestUsers)_parent;
string password = null;
if (values == null)
{
provider.Host.UI.Write("Enter password: ");
password = CredentialManager.GetStringFromSecureString(provider.Host.UI.ReadLineAsSecureString());
}
else if (values is System.Security.SecureString)
{
password = CredentialManager.GetStringFromSecureString(values as System.Security.SecureString);
}
else if (values is string)
{
password = values.ToString();
}
string hash = users.GetPasswordHash(_name, password);
userObj.SetProperty("RequestedState", "2");
userObj.SetProperty("EnabledState","2");
userObj.SetProperty("ElementName","Intel(r) AMT digest account");
userObj.SetProperty("SystemCreationClassName", "CIM_ComputerSystem");
userObj.SetProperty("SystemName", "ManagedSystem");
userObj.SetProperty("CreationClassName", "CIM_Account");
userObj.SetProperty("UserID", _name);
userObj.SetProperty("Name", _name);
userObj.SetProperty("UserPassword", hash);
userObj.SetProperty("UserPasswordEncryptionAlgorithm", "2");
userObj = _refToUser.Put(userObj);
}
public IManagedReference GetIdentity()
{
IManagedReference refToIdenity = _refToUser.Connection.NewReference("CIM_Identity");
refToIdenity.AddSelector("InstanceID", _identity);
return refToIdenity;
}
public override object GetReturnObject()
{
return new WideValueItem(Name, Value);
}
} // end user account class
public class UserParameters
{
public UserParameters()
{
_org="None";
}
[Parameter(Mandatory = false, Position = 0, HelpMessage = "Organization")]
public string Organization
{
get { return _org; }
set { _org = value; }
}
string _org;
}
class DigestUsers : DriveContainer
{
MD5 _md5;
string _realm;
UserAccount _adminAccount;
public DigestUsers( DriveItem parent)
: base ("Digest",parent)
{
}
public override void GetChildItems(ChildWriter writer)
{
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
IWsmanEnumeration colObj = conn.ExecQuery("SELECT * FROM CIM_Account");
foreach (IWsmanItem item in colObj)
{
IManagedInstance userObj = item.Object;
string identity = string.Format("Intel(r) AMT:{0}",
userObj.GetProperty("Name").ToString());
string userName = userObj.GetProperty("UserID").ToString();
IManagedReference refToUser = conn.NewReference(userObj.ResourceUri);
refToUser.AddSelector("Name", userObj.GetProperty("Name").ToString());
//IManagedReference refToIdentity = conn.NewReference("CIM_Identity");
//refToIdentity.AddSelector("InstanceID", identity);
// only show hidden $$ accounts if Force specified
if (writer.Force && userName.StartsWith("$$"))
writer.Add(new UserAccount(userName, refToUser, identity, this));
if (!userName.StartsWith("$$"))
writer.Add(new UserAccount(userName, refToUser, identity, this));
}
}
public override object GetReturnObject()
{
return new NameValuePairItem(Name, Value);
}
public bool IsAdmin(UserAccount account)
{
bool result=false;
if (_adminAccount == null)
{
IManagedReference refToIdentity = account.GetIdentity();
//call to get the role reference from the collection
IManagedReference _refToMember = refToIdentity.Connection.NewReference("CIM_MemberOfCollection");
_refToMember.AddSelector("Member", refToIdentity);
IManagedInstance memberObj = _refToMember.Get(); //
// get the role innstance
IManagedInstance roleObj = memberObj.GetProperty("Collection").Ref.Get();
if (roleObj.GetProperty("Name").ToString().Equals("Administrator"))
{
result = true;
_adminAccount = account;
}
}
else
{
result = _adminAccount.Name.Equals(account.Name);
}
return result;
}
public override object NewItemDynamicParameters(string itemTypeName, object newItemValue)
{
return new UserParameters();
}
public override DriveItem NewItem(string name, string type, object newItem, DriveProvider provider)
{
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
StringBuilder builder = new StringBuilder();
string password=null;
if (newItem ==null)
{
provider.Host.UI.Write("Enter password: ");
password = CredentialManager.GetStringFromSecureString(provider.Host.UI.ReadLineAsSecureString());
}
else if (newItem is System.Security.SecureString)
{
password= CredentialManager.GetStringFromSecureString(newItem as System.Security.SecureString);
}
else if (newItem is string)
{
password = newItem.ToString();
}
UserParameters userParms = provider.GetDynamicParameters() as UserParameters;
string hash = GetPasswordHash(name, password);
builder.Append("");
builder.Append("CIM_Account");
builder.Append("Intel(r) AMT digest account");
builder.Append("2");
builder.Append("");
builder.Append(name);
builder.Append("");
builder.Append("");
builder.Append(userParms.Organization);
builder.Append("");
builder.Append("2");
builder.Append("CIM_ComputerSystem");
builder.Append("ManagedSystem");
builder.Append("");
builder.Append(name);
builder.Append("");
builder.Append("");
builder.Append(hash);
builder.Append("");
builder.Append("2");
builder.Append("");
IManagedInstance templateObj = conn.NewInstance(builder.ToString());
string identity = string.Format("Intel(r) AMT:{0}", name);
IManagedReference refToSystem = conn.NewReference("CIM_ComputerSystem");
refToSystem.AddSelector("Name", "ManagedSystem");
IManagedReference refToService = conn.NewReference("CIM_AccountManagementService");
refToService.AddSelector("Name", "Intel(r) AMT Account Management Service");
IManagedInstance inputObj = refToService.CreateMethodInput("CreateAccount");
inputObj.SetProperty("System", refToSystem);
inputObj.SetProperty(null,templateObj);
IManagedInstance outObj = refToService.InvokeMethod(inputObj);
string returnValue = outObj.GetProperty("ReturnValue").ToString();
if (!returnValue.Equals("0"))
{
if (returnValue.Equals("1"))
AmtException.ThrowInvokeError(outObj, "Not Supported");
else if (returnValue.Equals("2"))
AmtException.ThrowInvokeError(outObj, "Failed");
else
AmtException.ThrowInvokeError(outObj);
}
UserAccount account= new UserAccount(name, outObj.GetProperty("Account").Ref,identity, this);
AddChildItem(account);
return account;
}
public string GetPasswordHash(string user, string password)
{
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
if (_realm == null)
{
IManagedInstance settingsObj = conn.NewInstance("SELECT * FROM AMT_GeneralSettings");
_realm = settingsObj.GetProperty("DigestRealm").ToString();
}
if (_md5 == null)
{
_md5 = new MD5CryptoServiceProvider();
_md5.Initialize();
}
StringBuilder builder = new StringBuilder();
builder.Append(user);
builder.Append(":");
builder.Append(_realm);
builder.Append(":");
builder.Append(password);
string hash = BitConverter.ToString(_md5.ComputeHash(Encoding.ASCII.GetBytes(builder.ToString())));
hash = hash.Replace("-", string.Empty);
return hash;
}
}// end DigestUsers
class KerberosUsers : DriveContainer
{
public KerberosUsers( DriveItem parent)
: base ("Kerberos",parent)
{
}
public override void GetChildItems(ChildWriter writer)
{
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
IWsmanEnumeration colObj = conn.ExecQuery("SELECT * FROM CIM_RemoteIdentity");
foreach (IWsmanItem item in colObj)
{
IManagedInstance userObj = item.Object;
string identity = userObj.GetProperty("InstanceID").ToString();
byte[] sidData = Convert.FromBase64String(userObj.GetProperty("Name").ToString());
SecurityIdentifier sec = new SecurityIdentifier(sidData.ToArray(), 0);
IManagedReference refToUser = conn.NewReference(userObj.ResourceUri);
refToUser.AddSelector("InstanceID", identity);
writer.Add(new KerberosAccount(sec.ToString(), refToUser, identity, this));
}
}
public override DriveItem NewItem(string name, string type, object newItem, DriveProvider provider)
{
IWsmanConnection conn = ((AmtRootService)GetRoot()).Connection;
SecurityIdentifier sec = new SecurityIdentifier(name);
byte[] sidData = new byte[sec.BinaryLength];
sec.GetBinaryForm(sidData, 0);
IManagedInstance inputObj= conn.NewInstance("CIM_RemoteIdentity");
inputObj.SetProperty("InstanceID", name);
inputObj.SetProperty("Name",Convert.ToBase64String(sidData));
inputObj.SetProperty("NameFormat","4");
IManagedReference refToUser = inputObj.Create();
IManagedInstance identityObj = refToUser.Get();
string identity = identityObj.GetProperty("InstanceID").ToString();
UserAccount account= new KerberosAccount(name, refToUser,identity, this);
AddChildItem(account);
return account;
}
public override object GetReturnObject()
{
return new NameValuePairItem(Name, Value);
}
}// end kerberos users
class KerberosAccount : UserAccount
{
public KerberosAccount(string user, IManagedReference refToIdentity, string identity, DriveItem parent) :
base(user, refToIdentity,identity, parent)
{
}
public override bool IsAdmin
{
get
{
return false;
}
}
public override bool Enabled
{
get
{
return true;
}
}
}
} //end RBAService class
} // end namespace