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