using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Management.Automation; using System.Management.Automation.Provider; using System.Management.Automation.Runspaces; using System.Security.Principal; using System.DirectoryServices; using System.Security.Cryptography.X509Certificates; using Intel.Management.Wsman; using Intel.Management.Mei; using System.Security; using Common.Utils; ///AmtCrediental.cs has many Cmdlets that implement various types of credients ///Types of credendials include PSCredentials, Kerberos Credenitals, AD Objects, namespace Intel.Management.PSModule.Amt { [Cmdlet(VerbsCommon.Get, "AmtCredential", SupportsShouldProcess = true)] public class AmtCredential : PSCmdlet, IDisposable { [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Amt device user name")] public string UserName { get { return _userName; } set { _userName = value; } } [Parameter(Mandatory = false, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Amt device password")] public SecureString Password { get { return _password; } set { _password?.Dispose(); _password = value; } } [Parameter(Mandatory = false)] public SwitchParameter Force { get { return _force; } set { _force = value; } } protected override void ProcessRecord() { if (string.IsNullOrEmpty(_userName) && _password == null) { Intel.Management.Mei.MeDevice me = new Intel.Management.Mei.MeDevice(); _userName = me.LocalConnection.Username; _password = me.LocalConnection.Password; } if (string.IsNullOrEmpty(_userName)) _userName="admin"; if (_password == null) _password=UserName.ConvertToSecureString(); WriteObject(new PSCredential(_userName,_password.Copy())); } string _userName; SecureString _password; bool _force; #region IDisposable Implementation private bool _disposed = false; /// /// Implement IDisposable method /// /// protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { _password?.Dispose(); } _disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~AmtCredential() { Dispose(false); } #endregion } /// /// Converts a Digest realm and key to a password /// [Cmdlet(VerbsData.ConvertTo, "AmtPassword", SupportsShouldProcess = true) ] public class CovertToPasswordCmd : PSCmdlet { [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "A base64 encoded Master password" )] public System.Security.SecureString MasterPassword { get { return _secureKey; } set { _secureKey = value; } } [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Target Digest Realm")] public string DigestRealm { get { return _realm; } set { _realm = value; } } [Parameter(Mandatory = false, Position = 2, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Target Digest user")] public string Username { get { return _user; } set { _user = value; } } [Parameter(Mandatory = false, Position = 3, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Convert the password to plain text")] public SwitchParameter AsPlainText { get { return _asPlainText; } set { _asPlainText = value; } } [Parameter(Mandatory = false, Position = 4, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Force the password to be plain text")] public SwitchParameter Force { get { return _force; } set { _force = value; } } protected override void ProcessRecord() { base.ProcessRecord(); if (_user == null) _user = "admin"; byte[] key = null; if (_secureKey != null) { key = Convert.FromBase64String(CredentialManager.GetStringFromSecureString(_secureKey)); } //else if (_keyData != null) // key = _keyData; if (key != null) { System.Security.Cryptography.HMACSHA256 sha2 = new System.Security.Cryptography.HMACSHA256(key); key = sha2.ComputeHash(Encoding.ASCII.GetBytes(_realm + _user)); string password = Convert.ToBase64String(key); if (_asPlainText) { if (!_force) throw new PSInvalidOperationException("Plain text passwords require the use of the Force switch"); WriteObject(password); } else { WriteObject(CredentialManager.GetSecureString(password)); } } } System.Security.SecureString _secureKey; //byte[] _keyData; string _user; string _realm; bool _asPlainText; bool _force; } public enum UserDisplayFormat { Domain, Ldap, } [Cmdlet(VerbsData.ConvertTo, "Sid", SupportsShouldProcess = true)] public class ConvertToSid : PSCmdlet { [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "Domain User Name")] public string User { get { return _userName; } set { _userName = value; } } protected override void ProcessRecord() { if (_userName.ToUpper().StartsWith("LDAP://")) { DirectoryEntry entry = new DirectoryEntry(_userName); byte[] sidData = (byte[])entry.Properties["objectSid"].Value; SecurityIdentifier sec = new SecurityIdentifier(sidData.ToArray(), 0); WriteObject(sec); } else { NTAccount account = new NTAccount(_userName); SecurityIdentifier sec = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier)); WriteObject(sec); } } private string _userName; } [Cmdlet(VerbsData.ConvertFrom, "Sid", SupportsShouldProcess = true)] public class ConvertFromSid : PSCmdlet { public ConvertFromSid() { _format = UserDisplayFormat.Domain; } [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "Security Identifier in SDDL form")] public string Sid { get { return _sddl; } set { _sddl = value; } } [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, HelpMessage = "User Display Format")] public UserDisplayFormat Format { get { return _format; } set { _format = value; } } protected override void ProcessRecord() { SecurityIdentifier sec = new SecurityIdentifier(_sddl); switch (_format) { case UserDisplayFormat.Domain: NTAccount account = (NTAccount)sec.Translate(typeof(NTAccount)); WriteObject(account); break; case UserDisplayFormat.Ldap: DirectorySearcher s = new DirectorySearcher("(objectSid=" + sec.Value + ")"); SearchResult sc = s.FindOne(); WriteObject(sc.Path); break; default: throw new PSArgumentException(); } } private string _sddl;//Security descriptor definition form private UserDisplayFormat _format; } [Cmdlet(VerbsCommon.Get, "AmtDirectoryObject", SupportsShouldProcess = true)] public class GetDirectoryObjectCmd : PSCmdlet { [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "Service Principal Name")] public string ComputerName { get { return _host; } set { _host = value; } } protected override void ProcessRecord() { DirectorySearcher searcher = null; string spn= "HTTP/" + _host + ":16992"; searcher = new DirectorySearcher("(servicePrincipalName=" + spn + ")"); foreach (SearchResult result in searcher.FindAll()) { DirectoryEntry entry = new DirectoryEntry(result.Path); WriteObject(entry); } } string _host; } [Cmdlet(VerbsCommon.Remove, "AmtDirectoryObject", SupportsShouldProcess = true)] public class RemoveDirectoryObjectCmd : PSCmdlet { [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "Service Principal Name")] public System.DirectoryServices.DirectoryEntry Entery { get { return _entry; } set { _entry = value; } } protected override void ProcessRecord() { DirectoryEntry parentEntry = _entry.Parent; parentEntry.Children.Remove(_entry); parentEntry.CommitChanges(); } DirectoryEntry _entry; } [Cmdlet(VerbsCommon.New, "AmtDirectoryObject", SupportsShouldProcess = true)] public class NewDirectoryObjectCmd : PSCmdlet { [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, HelpMessage = "hostName")] public string ComputerName { get { return _host; } set { _host = value; } } [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, HelpMessage = "Directory Container")] public string Container { get { return _container; } set { _container = value; } } [Parameter(Mandatory = false, Position = 2, ValueFromPipeline = true, HelpMessage = "Password")] public string Password { get { return _password; } set { _password = value; } } protected override void ProcessRecord() { if (_container.IndexOf("=") < 0) _container = "OU=" + _container; if (!_container.ToUpper().StartsWith("LDAP://")) _container = "LDAP://" + _container; DirectoryEntry ouEntry = new DirectoryEntry(_container); char[] splits = { '.' }; string[] hosts = _host.Split(splits, StringSplitOptions.RemoveEmptyEntries); if (hosts.Length == 1) { int pos = ouEntry.Path.IndexOf(",DC="); if (pos >= 0) { string domain = ouEntry.Path.Substring(pos); domain = domain.Replace(",DC=", "."); _host = _host + domain; hosts = _host.Split(splits, StringSplitOptions.RemoveEmptyEntries); } } DirectoryEntry newEntry = ouEntry.Children.Add("CN=" + hosts[0], "Computer"); //makesure the object exsists ouEntry.CommitChanges(); newEntry.CommitChanges(); object[] param = new object[1]; newEntry.AuthenticationType = AuthenticationTypes.Secure; param[0] = _password; newEntry.Invoke("SetPassword", param); param[0] = 66172; //512 newEntry.InvokeSet("userAccountControl", param); param[0] = hosts[0] + "$iME"; newEntry.InvokeSet("samAccountName", param); object[] spns = new object[4]; spns[0] = "HTTP/" + _host + ":16992"; spns[1] = "HTTP/" + _host + ":16993"; spns[2] = "HTTP/" + _host + ":16994"; spns[3] = "HTTP/" + _host + ":16995"; param[0] = spns; newEntry.InvokeSet("servicePrincipalName", param); param[0] = false; newEntry.InvokeSet("AccountDisabled", param); newEntry.CommitChanges(); WriteObject(newEntry); } private string _container; private string _host; private string _password; }//End CreateObject [Cmdlet(VerbsCommon.Get, "CertificateChain", SupportsShouldProcess = true)] public class GetCertificateChainCmd : PSCmdlet { [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "PKI Leaf Certificate")] public X509Certificate2 Certificate { get { return _cert; } set { _cert = value; } } [Parameter(Mandatory = false, HelpMessage = "Return only the Root of the chain")] public SwitchParameter RootOnly { get { return _rootOnly; } set { _rootOnly = value; } } protected override void ProcessRecord() { X509Chain chain = new X509Chain(); chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.Build(_cert as X509Certificate2); for (int i = 0; i < chain.ChainElements.Count; i++) { bool doWrite = _rootOnly == false || (i == chain.ChainElements.Count - 1); if (doWrite) WriteObject(chain.ChainElements[i].Certificate); } chain.Reset(); } X509Certificate2 _cert; bool _rootOnly; }//end GetRootCertificate [Cmdlet(VerbsCommon.Get, "AmtSignature", SupportsShouldProcess = true)] public class GetSignatureCmd : PSCmdlet { [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Digital AMT Setup Certificate")] public X509Certificate2 Certificate { get { return _cert; } set { _cert = value; } } [Parameter(Mandatory = true, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Dicovered Hardware Nonce")] public string ConfigurationNonce { get { return _configNonce; } set { _configNonce = value; } } [Parameter(Mandatory = false, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Random Generate McNonce")] public string McNonce { get { return _mcNonce; } set { _mcNonce = value; } } protected override void ProcessRecord() { byte[] data = GetNonceData(); byte[] sig; string hashAlg = "SHA256"; System.Security.Cryptography.RSACryptoServiceProvider rsa = (System.Security.Cryptography.RSACryptoServiceProvider)_cert.PrivateKey; System.Security.Cryptography.RSAParameters rp = rsa.ExportParameters(true); rsa = new System.Security.Cryptography.RSACryptoServiceProvider(); rsa.ImportParameters(rp); sig = rsa.SignData(data, hashAlg); if (!rsa.VerifyData(data,hashAlg, sig)) { throw new InvalidOperationException("RSA Signature not valid"); } X509Chain chain = new X509Chain(); chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.Build(_cert as X509Certificate2); //verify from chain; rsa = (System.Security.Cryptography.RSACryptoServiceProvider)chain.ChainElements[0].Certificate.PublicKey.Key; if (!rsa.VerifyData(data, hashAlg, sig)) { throw new InvalidOperationException("RSA Signature not valid"); } DigitalSignatureInfo info = new DigitalSignatureInfo(Convert.ToBase64String(sig), _mcNonce, _configNonce, chain); WriteObject(info); } private byte[] GetNonceData() { if (_mcNonce == null) { byte[] rndData = new byte[20]; System.Security.Cryptography.RandomNumberGenerator rng = System.Security.Cryptography.RandomNumberGenerator.Create(); rng.GetBytes(rndData); _mcNonce = Convert.ToBase64String(rndData); } byte[] configData = Convert.FromBase64String(_configNonce); byte[] mcData = Convert.FromBase64String(_mcNonce); byte[] data = new byte[configData.Length + mcData.Length]; Array.Copy(configData, 0, data, 0, configData.Length); Array.Copy(mcData, 0, data, configData.Length, mcData.Length); return data; } X509Certificate2 _cert; string _configNonce; string _mcNonce; } [Cmdlet(VerbsCommon.Get, "AmtCredentialPath", SupportsShouldProcess = true)] public class GetCredentialPath : PSCmdlet { public GetCredentialPath() { _envType = Environment.SpecialFolder.LocalApplicationData; } [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Get Shared Credential Path")] public SwitchParameter Shared { get { return _envType == Environment.SpecialFolder.CommonApplicationData; } set { if (value) _envType = Environment.SpecialFolder.CommonApplicationData; else _envType = Environment.SpecialFolder.LocalApplicationData; } } protected override void ProcessRecord() { string path = System.Environment.GetFolderPath(_envType); path = System.IO.Path.Combine(path, "Intel"); path = System.IO.Path.Combine(path, "vProModule"); path = System.IO.Path.Combine(path, "shell.credentials.txt"); WriteObject(path); //System.Text.Encoding.ASCII.GetBytes() } Environment.SpecialFolder _envType; } [Cmdlet(VerbsCommon.Get, "AmtCertificate",DefaultParameterSetName="pfx", SupportsShouldProcess = true)] public class GetAmtCertificateCmd : PSCmdlet { public GetAmtCertificateCmd() { _storeName = "My"; } [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true,ValueFromPipelineByPropertyName=true, ParameterSetName="pfx", HelpMessage = "Path to a certificate file")] public string FilePath { get { return _filePath; } set { _filePath = value; } } [Parameter(Mandatory = false, Position = 1, ValueFromPipeline = true,ValueFromPipelineByPropertyName=true, ParameterSetName="pfx",HelpMessage = "Password protecting the private key")] public string Password { get { return _password; } set { _password = value; } } [Parameter(Mandatory = false,ParameterSetName="pfx")] public SwitchParameter Force { get { return _force; } set { _force = value; } } [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "store", HelpMessage = "The thumbprint of the certificate to load")] public string Thumbprint { get { return _thumbprint; } set { _thumbprint = value.Replace(" ",string.Empty).ToUpper(); } } [Parameter(Mandatory = false, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "store", HelpMessage = "The Certificate Store Name")] public string StoreName { get { return _storeName; } set { _storeName = value; } } [Parameter(Mandatory = false, Position = 1, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "store", HelpMessage = "The the machine store instead of the User store")] public SwitchParameter UseMachineStore { get { return _useMachine; } set { _useMachine = value; } } protected override void ProcessRecord() { if (_password != null && !_force) { throw new PSInvalidOperationException("plain text passwords require the use of the -Force switch"); } if (_thumbprint==null && _password == null) { this.Host.UI.Write("Enter pfx password: "); System.Security.SecureString secString = this.Host.UI.ReadLineAsSecureString(); _password = CredentialManager.GetStringFromSecureString(secString); } if (_thumbprint != null) { System.Security.Cryptography.X509Certificates.StoreName xStoreName = System.Security.Cryptography.X509Certificates.StoreName.My; StoreLocation location = StoreLocation.CurrentUser; if (_useMachine) location = StoreLocation.LocalMachine; X509Store store=null; switch (_storeName.ToLower()) { case "my": store = new X509Store(System.Security.Cryptography.X509Certificates.StoreName.My,location); break; case "ca": case "certificateauthority": store = new X509Store(System.Security.Cryptography.X509Certificates.StoreName.CertificateAuthority,location); break; case "authroot": store = new X509Store(System.Security.Cryptography.X509Certificates.StoreName.AuthRoot,location); break; case "root": store = new X509Store(System.Security.Cryptography.X509Certificates.StoreName.Root,location); break; case "trustedpeople": store = new X509Store(System.Security.Cryptography.X509Certificates.StoreName.TrustedPeople,location); break; case "trustedpublisher": store = new X509Store(System.Security.Cryptography.X509Certificates.StoreName.TrustedPublisher,location); break; default: store = new X509Store(xStoreName,location); break; } store.Open(OpenFlags.MaxAllowed); try { X509Certificate2 result = null; // X509Certificate2Collection col= store.Certificates.Find(X509FindType.FindByThumbprint,_thumbprint ,true); X509Certificate2Collection col = store.Certificates; foreach (X509Certificate2 cert in col) { if (string.Compare(cert.Thumbprint,_thumbprint,true)==0) result = cert; } if (result != null) WriteObject(result); } finally { store.Close(); } } else { X509Certificate2Collection certs = new X509Certificate2Collection(); certs.Import(_filePath, _password, X509KeyStorageFlags.Exportable); foreach (X509Certificate2 cert in certs) { if (cert.HasPrivateKey) { WriteObject(cert); } } } } string _filePath; string _password; string _thumbprint; string _storeName; bool _useMachine; bool _force; } [Cmdlet(VerbsCommon.New, "AmtPassword", SupportsShouldProcess = true)] public class NewPasswordCmd : PSCmdlet, IDisposable { public NewPasswordCmd() : base() { _length = 32; } [Parameter(Mandatory = false, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "Password Length")] public int Length { get { return _length; } set { _length = value; } } [Parameter(Mandatory = false, HelpMessage = "Convert the password to Base64 Encoded String")] public SwitchParameter AsBase64 { get { return _asBase64; } set { _asBase64 = value; } } protected override void ProcessRecord() { SecureString password = null; try { if (_asBase64) { System.Security.Cryptography.RandomNumberGenerator rng = System.Security.Cryptography.RandomNumberGenerator.Create(); byte[] data = new byte[_length]; rng.GetBytes(data); password = data.ConvertByteArrayToSecureString(); Array.Clear(data, 0, data.Length); } else { IMeDevice me = new MeDevice(); password = me.CreateRandomPassword(_length); } WriteObject(password); } finally { password?.Dispose(); } } int _length; bool _asBase64; #region IDisposable /// /// Implement IDisposable method /// /// protected virtual void Dispose(bool disposing) { if (disposing) { return; } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~NewPasswordCmd() { Dispose(false); } #endregion } /// /// Certificate Chain Status /// public enum HashAlgorithmType { Unknown = 0, Sha1 = 1, Sha256 = 2, Sha384 = 3, } /// /// Host Setup record /// public class SetupRecord { Intel.Management.Wsman.IManagedInstance _recordObj; /// /// Constructs a setup record /// /// Wsman Instance of the record public SetupRecord(IManagedInstance recordObj) { _recordObj = recordObj; } /// /// Get setup timestamp /// public DateTime Timestamp { get { return Intel.Management.Mei.MeDevice.FormatDate(_recordObj.GetProperty("CreationTimeStamp")); } } /// /// The name of the log /// public string LogName { get { return _recordObj.GetProperty("LogName").ToString(); } } /// /// Recored ID /// public string RecordID { get { return _recordObj.GetProperty("RecordID").ToString(); } } /// /// Gets a flag for Secure DNS /// public bool SecureDNS { get { if (_recordObj.GetProperty("SecureDNS").IsNull) return false; return bool.Parse(_recordObj.GetProperty("SecureDNS").ToString()); } } public string CertificateCN { get { if (_recordObj.GetProperty("CertificateCN").IsNull) return string.Empty; return _recordObj.GetProperty("CertificateCN").ToString(); } } public HashAlgorithmType HashAlgorithm { get { if (!_recordObj.GetProperty("HashAlgorithm").IsNull) { switch (int.Parse(_recordObj.GetProperty("HashAlgorithm").ToString())) { case 2: return HashAlgorithmType.Sha1; case 3: return HashAlgorithmType.Sha256; default: return HashAlgorithmType.Unknown; } } else if (!_recordObj.GetProperty("SelectedHashType").IsNull) { return (HashAlgorithmType)int.Parse(_recordObj.GetProperty("SelectedHashType").ToString()); } return HashAlgorithmType.Unknown; } } public string CertificateHash { get { string result = string.Empty; if (!_recordObj.GetProperty("ProvCertificateHash").IsNull) { result= _recordObj.GetProperty("ProvCertificateHash").ToString(); } else if (!_recordObj.GetProperty("SelectedHashData").IsNull) { result= _recordObj.GetProperty("SelectedHashData").ToString(); } if (!string.IsNullOrEmpty(result)) { byte[] hash = Convert.FromBase64String(result); result = BitConverter.ToString(hash); result = result.Replace("-", string.Empty); result=result.ToUpper(); } return result; } } public string[] CaCertificateSerials { get { List result = new List(); foreach (Intel.Management.Wsman.IWsmanItem item in _recordObj.GetProperty("CaCertificateSerials")) { result.Add(item.ToString()); } return result.ToArray(); } } public bool AdditionalCaSerialNums { get { if (_recordObj.GetProperty("AdditionalCaSerialNums").IsNull) return false; return bool.Parse(_recordObj.GetProperty("AdditionalCaSerialNums").ToString()); } } public bool HashIsOemDefault { get { if (_recordObj.GetProperty("HashIsOemDefault").IsNull) return false; return bool.Parse(_recordObj.GetProperty("HashIsOemDefault").ToString()); } } }//End SetupRecord public class DigitalSignatureInfo { string _signature; string _mcNonce; string _configNonce; X509Chain _chain; public DigitalSignatureInfo(string signature, string mcNonce, string configNonce, X509Chain chain) { _signature=signature; _mcNonce=mcNonce; _configNonce=configNonce; _chain=chain; } public string Signature { get { return _signature; } } public string McNonce { get { return _mcNonce; } } public string ConfigurationNonce { get { return _configNonce; } } public X509Chain CertificateChain { get { return _chain; } } public string SignatureType { get { return "SHA246"; } } public byte[] GetRawData() { byte[] mcData = Convert.FromBase64String(_mcNonce); byte[] configData = Convert.FromBase64String(_configNonce); byte[] result = new byte[mcData.Length + configData.Length]; Array.Copy(configData, 0, result, 0, configData.Length); Array.Copy(mcData, 0, result, configData.Length, mcData.Length); return result; } } public class AmtProxy { protected string _address; protected string _userName; protected string _password; public AmtProxy() { } public string Address { get { return _address;} set { _address = value; } } public string Username { get { return _userName; } set { _userName = value; } } public string Password { get { return _password; } set { _password = value; } } } class LConnectionManager { [ThreadStatic] private static WsmanConnection _conn; public static WsmanConnection Active { get { return _conn; } set { _conn = value; } } } public class ConnectionManager { [ThreadStatic] private static WsmanConnection _conn; [ThreadStatic] private static WsmanConnection _osAdminConn; [ThreadStatic] private static HECIClass _heci; /// /// Removes and Closes an Active connection /// /// public static void Remove(WsmanConnection conn) { if (_conn.Equals(conn)) { _conn = null; conn.Close(); } else if (_osAdminConn.Equals(conn)) { conn.Close(); _osAdminConn=null; _heci = null; } } /// /// Gets or sets the Active AMT session /// public static WsmanConnection ActiveSession { get { return _conn; } set { _conn = value; } } /// /// Gets a Heci connection /// public static HECIClass Heci { get { if (_heci==null) _heci=new HECIClass(); return _heci; } } /// /// Gets a local Os Admin Wsman Connection /// public static WsmanConnection LocalSession { get { if (_osAdminConn==null) { Heci.Init();//make sure we have a HECI object try { string username; SecureString password; if (_heci.GetLocalAdminCredentials(out username, out password)) { _osAdminConn = new WsmanConnection(); _osAdminConn.SetCredentials(username, password); } } finally { _heci.DeInit(); } } return _osAdminConn; } } } public class DeviceCertificate : X509Certificate2 { private string _instanceID; bool _isRoot; public DeviceCertificate(string base64Data,string instanceID,bool isTrustedRoot) : base(Convert.FromBase64String(base64Data)) { _instanceID = instanceID; _isRoot = isTrustedRoot; } public DeviceCertificate(X509Certificate2 cert, string instanceID, bool isTrustedRoot) : base(cert.RawData) { _instanceID = instanceID; _isRoot = isTrustedRoot; } public DeviceCertificate() : base() { _instanceID = string.Empty; _isRoot = false; } public string InstanceID { get { return _instanceID; } } public bool IsTrustedRootCertificate { get { return _isRoot; } } public override string ToString() { if (string.IsNullOrEmpty(_instanceID)) return string.Empty; return Thumbprint; } } /// public class CertificateItem { X509Certificate2 _item; public CertificateItem(DeviceCertificate item) { _item = item; } public string Name { get { return _item.Thumbprint; } } public X509Certificate2 Value { get { return _item; } } public string Type { get { return "DeviceCertificate"; } } } public class HashItem { string _name; string _value; public HashItem(string name, string value) { _name = name; _value = value; } public string Name { get { return _name; } } public string Value { get { return _value; } } } public enum AuthenticationProtocol : int { TLS=0, TTLS_MSCHAPv2=1, PEAP_MSCHAPv2=2, EAP_GTC=3, EAPFAST_MSCHAPv2=4, EAPFAST_GTC=5, EAPFAST_TLS=6, } public class WirelessProfile { string _instanceId; string _ssid; string _name; int _priority; string _authMethod; string _encMethod; WPASettings _wpa; IEEESettings _ieee; public WirelessProfile() { //_authMethod = ValueMap.Create("1", SupportedAuthenticationMethods); //_encMethod = ValueMap.Create("6", SupportedEncryptionMethods); _wpa = new WPASettings(); _ieee = new IEEESettings(); } public string Name { get { return _name; } set { _name = value; } } public string InstanceID { get { return _instanceId; } set { _instanceId = value; } } public string SSID { get { return _ssid; } set { _ssid = value; } } public BSSType BssType { get { return BSSType.Infrastructure; } //Infrastructure } public int Priority { get { return _priority; } set { _priority = value; } } public string EncryptionMethod { get { return _encMethod; } set { _encMethod = value; } } public string AuthenticationMethod { get { return _authMethod; } set { _authMethod = value; } } public static IDictionary SupportedEncryptionMethods { get { Dictionary result = new Dictionary(); result.Add("1", "Other"); result.Add("2", "WEP"); result.Add("3", "TKIP"); result.Add("4", "CCMP"); result.Add("5", "None"); return result; } } public static IDictionary SupportedAuthenticationMethods { get { Dictionary result = new Dictionary(); result.Add("1", "Other"); result.Add("2", "Open System"); result.Add("3", "Shared Key"); result.Add("4", "WPA PSK"); result.Add("5", "WPA IEEE 802.1x"); result.Add("6", "WPA2 PSK"); result.Add("7", "WPA2 IEEE 802.1x"); return result; } } public WPASettings WPA { get { return _wpa; } } public IEEESettings IEEE { get { return _ieee; } } public enum BSSType : int { Unknown =0, Independent=2, Infrastructure=3, } public override string ToString() { return "WirelessProfile"; } public class WEPSettings { byte[] _key; int _index; public byte[] Key { get { return _key; } set { _key = value; } } public int KeyIndex { get { return _index; } set { _index = value; } } public override string ToString() { return "WEPSettings"; } } public class WPASettings { byte[] _key; string _pass; public byte[] PSK { get { return _key; } set { _key = value; _pass = null; } } public string PassPhrase { get { return _pass; } set { _pass =value; _key = null; } } public override string ToString() { return "WPASettings"; } } public class IEEESettings { string _auth; string _serverCertificateCompareMethod; string _roamingIdentity; string _serverCertificateName; string _userName; string _password; string _domain; DeviceCertificate _clientCertificate; DeviceCertificate _caCertificate; byte[] _pac; string _PACPassword; byte[] _psk; public IEEESettings() { } public static IDictionary SupportedCertificateComparisonMethods { get { Dictionary result = new Dictionary(); result.Add("1", "Other"); result.Add("2", "FullName"); result.Add("3", "DomainSuffix"); return result; } } public static IDictionary SupportedAuthenticationProtocols { get { Dictionary result = new Dictionary(); result.Add("0", "EAP-TLS"); result.Add("1", "EAP-TTLS/MSCHAPv2"); result.Add("2", "PEAPv0/EAP-MSCHAPv2"); result.Add("3", "PEAPv1/EAP-GTC"); result.Add("4", "EAP-FAST/MSCHAPv2"); result.Add("5", "EAP-FAST/GTC"); result.Add("6", "EAP-MD5"); result.Add("7", "EAP-PSK"); result.Add("8", "EAP-SIM"); result.Add("9", "EAP-AKA"); result.Add("10", "EAP-FAST/TLS"); return result; } } public string AuthenticationProtocol { get { return _auth; } set { _auth = value; } } public string RoamingIdentity { get { return _roamingIdentity; } set { _roamingIdentity =value; } } public string ServerCertificateName { get { return _serverCertificateName; } set { _serverCertificateName =value; } } public string ServerCertificateNameComparison { get { return _serverCertificateCompareMethod;; } set { _serverCertificateCompareMethod =value; } } public string Username { get { return _userName; } set { _userName =value; } } public string Password { get { return _password; } set { _password =value; } } public string Domain { get { return _domain; } set { _domain =value; } } public byte[] ProtectedAccessCredential { get { return _pac; } set { _pac = value; } } public string PACPassword { get { return _PACPassword; } set { _PACPassword = value; } } public byte[] PSK { get { return _psk; } set { _psk = value; } } public DeviceCertificate ClientCredential { get { return _clientCertificate; } set { _clientCertificate = value; } } public DeviceCertificate CACredential { get { return _caCertificate; } set { _caCertificate = value; } } public override string ToString() { return "IEEESettings"; } } } /// /// Defines Credential Managment behavior /// public class CredentialManager { public static string GetAddress(string[] addressList) { return GetAddress(addressList, false); } public static string GetAddress(string[] addressList,bool useIPv6) { string result = string.Empty; if (addressList == null || addressList.Length == 0) throw new AmtException("No IP Address is avaible"); foreach (string address in addressList) { if (useIPv6) { if (address.IndexOf(":") > 0) result = address; } else { if (address.IndexOf(".") > 0) result = address; } } return result; } public static Uri GetServiceUri(string computerName,bool useTls) { Uri result = null; string port = ":16992"; if (computerName.EndsWith(":16993")) useTls=true; StringBuilder builder= new StringBuilder(); if (useTls) { builder.Append("https://"); port = ":16993"; } else { builder.Append("http://"); } builder.Append(computerName); result = new Uri(builder.ToString()); //only append the AMT port if no port was specified if (result.IsDefaultPort) { builder.Append(port); } builder.Append("/wsman"); result = new Uri(builder.ToString()); return result; } public static string GetStringFromSecureString(System.Security.SecureString secureString) { string result; if (secureString==null) throw new ArgumentNullException(); IntPtr ptr = Marshal.SecureStringToCoTaskMemUnicode((System.Security.SecureString)secureString); try { result = Marshal.PtrToStringUni(ptr); } finally { Marshal.ZeroFreeCoTaskMemUnicode(ptr); } return result; } public static System.Security.SecureString GetSecureString(string normalString) { char[] passChars = normalString.ToCharArray(); System.Security.SecureString secString = new System.Security.SecureString(); for (int i = 0; i < passChars.Length; i++) secString.AppendChar(passChars[i]); return secString; } public static void SetConnectionCredentials(WsmanConnection conn,PSCredential cred) { string user = string.Empty; SecureString pass = null; if (cred != null && cred.UserName != null) user = cred.UserName; if (cred != null && cred.Password != null) pass = cred.Password; conn.SetCredentials(user, pass); conn.Options.HidePassword = true; } public static string GetBase64PasswordHash(string user, string realm, string password) { System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); StringBuilder builder = new StringBuilder(); builder.Append(user); builder.Append(":"); builder.Append(realm); builder.Append(":"); builder.Append(password); byte[] hash = md5.ComputeHash(Encoding.ASCII.GetBytes(builder.ToString())); builder = new StringBuilder(Convert.ToBase64String(hash)); md5.Clear(); return builder.ToString(); } public static WsmanConnection GetConnection(string host,PSCredential cred,bool useTls, bool acceptSelfSignedCert, bool useMaster, AmtProxy proxy, X509Certificate clientCert) { WsmanConnection conn = new WsmanConnection(); string user = string.Empty; SecureString pass = null; if (string.IsNullOrEmpty(host)) host = "localhost"; if (clientCert != null) useTls = true; conn.Options.UseDigestMasterPassword = useMaster; conn.Address = CredentialManager.GetServiceUri(host, useTls).ToString(); if (cred != null && cred.UserName != null) user = cred.UserName; if (cred != null && cred.Password != null) pass = cred.Password; if (acceptSelfSignedCert) conn.Options.AcceptSelfSignedCertificate = true; conn.SetCredentials(user, pass); conn.Options.HidePassword = true; conn.Options.ClientCertificate = clientCert; return conn; } } public class MD4 { static uint PROV_RSA_FULL = 1; static uint CRYPT_VERIFYCONTEXT = 0xF0000000; static uint CALG_MD4 = 32770; enum HashParameters { HP_ALGID = 0x0001, HP_HASHVAL = 0x0002, HP_HASHSIZE = 0x0004, } public static byte[] ComputeHash(byte[] data) { IntPtr hProv = IntPtr.Zero; IntPtr hHash = IntPtr.Zero; byte[] result = new byte[16]; int lastError = 0; uint resultSize = (uint)result.Length; bool bOk = CryptAcquireContext(out hProv, null, null, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); if (bOk) bOk = CryptCreateHash(hProv, CALG_MD4, IntPtr.Zero, 0, out hHash); if (bOk) bOk = CryptHashData(hHash, data, (uint)data.Length, 0); if (bOk) bOk = CryptGetHashParam(hHash, HashParameters.HP_HASHVAL, result, ref resultSize, 0); if (!bOk) lastError = Marshal.GetLastWin32Error(); if (!hHash.Equals(IntPtr.Zero)) CryptDestroyHash(hHash); if (!hProv.Equals(IntPtr.Zero)) CryptReleaseContext(hProv, 0); if (!bOk) Marshal.ThrowExceptionForHR(lastError); return result; } //static uint CALG_MD5= 32771; [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CryptAcquireContext(out IntPtr phProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CryptCreateHash(IntPtr phProv, uint algId, IntPtr hKey, uint dwFlags, out IntPtr phHash); [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CryptHashData(IntPtr phHash, byte[] pbData, uint dataLen, uint flags); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CryptGetHashParam(IntPtr phHash, HashParameters dwParam, [Out] byte[] pbData, ref uint dataLen, uint flags); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CryptDestroyHash(IntPtr phHash); [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CryptReleaseContext(IntPtr phProv, uint flags); } }