444 lines
16 KiB
C#
444 lines
16 KiB
C#
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright © 2009-2014, Intel Corporation. All rights reserved.
|
|
//
|
|
// File: Utilities.cs
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
using System;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Reflection;
|
|
using System.ComponentModel;
|
|
using System.Collections.Generic;
|
|
using System.Text.RegularExpressions;
|
|
using UCT.Forms;
|
|
using System.IO;
|
|
using System.Windows.Forms;
|
|
using Microsoft.Win32;
|
|
using Intel.Management.Wsman;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace UCT.Utils
|
|
{
|
|
#region - Delegates -
|
|
|
|
public delegate void ProgressDelegate(BackgroundWorker worker, DoWorkEventArgs e, object[] obj);
|
|
public delegate void UpdateOptInStateLabel(OptInState state);
|
|
public delegate void UpdatePowerStateDelegate(PowerState pstate);
|
|
public delegate void UpdateWirelessStateLabel(LinkControl linkControl, LinkControl linkPref);
|
|
public delegate void AdvancePanelDelegate(bool connected);
|
|
public delegate void ChangeConnectionIcon_D(bool connected);
|
|
public delegate void OperationPanel_D(bool enablePanel);
|
|
public delegate void CodeMonitorPanel_D(bool send);
|
|
public delegate void StatisticsPanel_D(bool known);
|
|
public delegate void Timer_D(TimerStatus status);
|
|
public delegate void DisplayStatusBarDelegate(string msg);
|
|
public delegate void ClearStatusBarDelegate();
|
|
public delegate void MoveFocusToCodeFrameDelagate();
|
|
public delegate void TimerSession_D();
|
|
public delegate void UpdateGUIParams_D(bool connected);
|
|
public delegate void Operation_D();
|
|
public delegate void ChangeTimerNoteDelegate(string txt);
|
|
public delegate void StateChanged_D();
|
|
public delegate void WirelessLinkChanged_D();
|
|
public delegate void PowerStateChanged_D();
|
|
public delegate void Connection_panel_D(ConnectionState state);
|
|
public delegate void Connection_D();
|
|
public delegate void WriteLog_D(String line, LogInteraction interaction);
|
|
|
|
#endregion
|
|
|
|
public enum Address : byte
|
|
{
|
|
other = 1,
|
|
Host,
|
|
IPV4,
|
|
IPV6
|
|
};
|
|
|
|
class Utilities
|
|
{
|
|
#region - Members -
|
|
|
|
private const string SPECIAL_CHARS = "! @ # $ % ^ & * ( ) - _ + = [ ] { } \\ | ; ' ` ~ < > . / ?";
|
|
private const string INVALID_USERNAME_CHARS = ": , < > &";
|
|
private const string HELP_FILE_NAME = "UserConsentTool.chm";
|
|
|
|
private const string OID_LOCAL = "2.16.840.1.113741.1.2.2";
|
|
private const string OID_REMOTE = "2.16.840.1.113741.1.2.1";
|
|
|
|
#endregion
|
|
|
|
#region - Methods -
|
|
|
|
/// <summary>
|
|
/// Return the enum description attribute
|
|
/// </summary>
|
|
/// <param name="eValue"></param>
|
|
/// <returns></returns>
|
|
internal static string GetEnumDescription(Enum eValue)
|
|
{
|
|
FieldInfo finfo = eValue.GetType().GetField(eValue.ToString());
|
|
if (finfo != null)
|
|
{
|
|
DescriptionAttribute[] attr = (DescriptionAttribute[])finfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
|
if (attr.Length != 0)
|
|
{
|
|
return attr[0].Description;
|
|
}
|
|
else
|
|
{
|
|
return eValue.ToString();
|
|
}
|
|
}
|
|
else
|
|
return eValue.ToString()+" (Unknown) " ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Display the help document
|
|
/// </summary>
|
|
internal static void DisplayHelpDocument(Control parent)
|
|
{
|
|
if (!File.Exists(HELP_FILE_NAME))
|
|
{
|
|
AMT_SW_GUI.MessageManager.ShowErrorMessage("User Consent Tool help file does not exist.", "Help File Not Found");
|
|
}
|
|
Help.ShowHelp(parent, HELP_FILE_NAME);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Compares between two versions.
|
|
/// </summary>
|
|
/// <param name="amtversion">First version</param>
|
|
/// <param name="version">Second version</param>
|
|
/// <returns>
|
|
/// 0 when equal.
|
|
/// greater than 0 when the first version is later.
|
|
/// less than 0 when the second version is later.
|
|
/// </returns>
|
|
public static int CompareVersions(string amtversion, string version)
|
|
{
|
|
try
|
|
{
|
|
Version amtVersion = new Version(amtversion);
|
|
Version versionToCopmare = new Version(version);
|
|
return amtVersion.CompareTo(versionToCopmare);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
throw new Exception("Failed to compare versions. Check if the versions are in a correct format.");
|
|
}
|
|
}
|
|
|
|
//return a specific certificate from the cert store.
|
|
internal static X509CertificateCollection getCertFromStore(String clientCert)
|
|
{
|
|
|
|
X509CertificateCollection certificatesCollection = new X509CertificateCollection();
|
|
|
|
// Open CurrentUser cert store
|
|
using (X509Store currentUserStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
|
|
{
|
|
currentUserStore.Open(OpenFlags.ReadOnly);
|
|
|
|
foreach (X509Certificate2 certificate in currentUserStore.Certificates)
|
|
{
|
|
if (certificate.Subject.Contains(clientCert))
|
|
{
|
|
// Checking that the Enhanced Key Usage in the certificate is the one for AMT
|
|
foreach (X509Extension extension in certificate.Extensions)
|
|
{
|
|
if (extension is X509EnhancedKeyUsageExtension)
|
|
{
|
|
X509EnhancedKeyUsageExtension ex = (X509EnhancedKeyUsageExtension)extension;
|
|
foreach (Oid OID in ex.EnhancedKeyUsages)
|
|
{
|
|
if (OID.Value == OID_REMOTE || OID.Value == OID_LOCAL)
|
|
certificatesCollection.Add(certificate);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Open LocalMachine cert store
|
|
using (X509Store localMachineStore = new X509Store(StoreName.My, StoreLocation.LocalMachine))
|
|
{
|
|
localMachineStore.Open(OpenFlags.ReadOnly);
|
|
|
|
foreach (X509Certificate2 certificate in localMachineStore.Certificates)
|
|
{
|
|
if (certificate.Subject.Contains(clientCert))
|
|
{
|
|
// Checking that the Enhanced Key Usage in the certificate is the one for AMT
|
|
foreach (X509Extension extension in certificate.Extensions)
|
|
{
|
|
if (extension is X509EnhancedKeyUsageExtension)
|
|
{
|
|
X509EnhancedKeyUsageExtension ex = (X509EnhancedKeyUsageExtension)extension;
|
|
foreach (Oid OID in ex.EnhancedKeyUsages)
|
|
{
|
|
if (OID.Value == OID_REMOTE || OID.Value == OID_LOCAL)
|
|
certificatesCollection.Add(certificate);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//if (certificatesCollection.Count < 1)
|
|
// throw new ManageabilityException("Can not find appropriate certificate in certificate store");
|
|
|
|
return certificatesCollection;
|
|
}
|
|
#region - Input Validation -
|
|
|
|
/// <summary>
|
|
/// Determines wheter a character is valid for hostName char
|
|
/// </summary>
|
|
/// <param name="c">char</param>
|
|
/// <returns>true if valid char; otherwise false</returns>
|
|
internal static bool LegalHostnameChar(char c)
|
|
{
|
|
if ((c >= 'a' && c <= 'z') || ((c >= 'A' && c <= 'Z')) || ((c >= '0' && c <= '9')))
|
|
{
|
|
return true;
|
|
}
|
|
if ((c == '-') || (c == '_') || (c == '/') || (c == '#'))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether an input address is in a valid FQDN format
|
|
/// </summary>
|
|
/// <param name="macAddr">MAC Address</param>
|
|
/// <returns>true is valid FQDN format; otherwise false</returns>
|
|
internal static bool IsValidFQDN(string fqdn)
|
|
{
|
|
if (fqdn != "")
|
|
{
|
|
//check for a '.'
|
|
bool dotExists = false;
|
|
for (int i = 0; i < fqdn.Length; i++)
|
|
{
|
|
char c = fqdn[i];
|
|
if ((c == '.'))
|
|
{
|
|
dotExists = true;
|
|
continue;
|
|
}
|
|
if (!(LegalHostnameChar(c)))
|
|
return false;
|
|
if((i-1) == fqdn.LastIndexOf('.'))
|
|
if ((c >= '0') && (c <= '9'))
|
|
return false;
|
|
|
|
if (i == (fqdn.Length - 1))
|
|
if ((c == '.'))
|
|
return false;
|
|
}
|
|
if (!dotExists)
|
|
return false;
|
|
Regex reg = new Regex(@"(?=^.{1,254}$)(^(?:(?!\d+\.|-)[a-zA-Z0-9_\-]{1,63}(?!-)\.?)+(?:[a-zA-Z\d]{1,})$)");
|
|
bool ret = reg.IsMatch(fqdn);
|
|
return ret;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether an input address is in a valid host name format
|
|
/// </summary>
|
|
/// <param name="hostname"></param>
|
|
/// <returns>true if input is in a valid hostName format; otherwise</returns>
|
|
public static bool ValidateHostname(string hostname)
|
|
{
|
|
if (hostname.Length > 63 || hostname.Length < 1)
|
|
return false;
|
|
for (int i = 0; i < hostname.Length; i++)
|
|
{
|
|
|
|
if (!LegalHostnameChar(hostname[i]))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether an IP is in a valid IPV4 format
|
|
/// return true if valid format; otherwise returns false
|
|
/// </summary>
|
|
/// <param name="macAddr">MAC Address</param>
|
|
/// <returns>true is valid IPV4 format; otherwise false</returns>
|
|
internal static bool IsValidIPV6(string ip)
|
|
{
|
|
IPAddress IPV6;
|
|
if (IPAddress.TryParse(ip, out IPV6))
|
|
{
|
|
if (IPV6.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether an IP is in a valid IPV4 format
|
|
/// return true if valid format; otherwise returns false
|
|
/// </summary>
|
|
/// <param name="macAddr">MAC Address</param>
|
|
/// <returns>true is valid IPV4 format; otherwise false</returns>
|
|
internal static bool IsValidIPV4(string ip)
|
|
{
|
|
IPAddress IPV4;
|
|
if (IPAddress.TryParse(ip, out IPV4))
|
|
if (IPV4.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns Address format of input
|
|
/// </summary>
|
|
/// <param name="inAddress">Address</param>
|
|
/// <returns>IPV4, IPV6, Host, Other</returns>
|
|
internal static Address CheckAddressFormat(string inAddress)
|
|
{
|
|
IPAddress address;
|
|
if (IPAddress.TryParse(inAddress, out address))
|
|
{
|
|
switch (address.AddressFamily)
|
|
{
|
|
case System.Net.Sockets.AddressFamily.InterNetwork:
|
|
return Address.IPV4;
|
|
case System.Net.Sockets.AddressFamily.InterNetworkV6:
|
|
return Address.IPV6;
|
|
}
|
|
}
|
|
|
|
if (ValidateHostname(inAddress))
|
|
return Address.Host;
|
|
return Address.other;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether the macAddress input is in a valid mac format
|
|
/// return true if valid format; otherwise returns false
|
|
/// </summary>
|
|
/// <param name="macAddr">MAC Address</param>
|
|
/// <returns></returns>
|
|
internal static bool IsValidMACAddr(string macAddr)
|
|
{
|
|
if (string.IsNullOrEmpty(macAddr))
|
|
return false;
|
|
bool ret = Regex.IsMatch(macAddr, "/^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$");
|
|
return ret;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether a password is in a strong password standard
|
|
/// </summary>
|
|
/// <param name="password"></param>
|
|
/// <returns></returns>
|
|
internal static bool IsStrongPassword(string password)
|
|
{
|
|
// check length
|
|
if (password.Length < 8)
|
|
return false;
|
|
bool lower, upper, digit, special;
|
|
lower = upper = digit = special = false;
|
|
foreach (Char c in password)
|
|
{
|
|
if (Char.IsDigit(c))
|
|
digit = true;
|
|
else if (Char.IsLower(c))
|
|
lower = true;
|
|
else if (Char.IsUpper(c))
|
|
upper = true;
|
|
else if (SPECIAL_CHARS.Contains(Char.ToString(c)))
|
|
special = true;
|
|
else return false;
|
|
}
|
|
return digit && lower && upper && special;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines whether a username is in valid format
|
|
/// </summary>
|
|
/// <param name="password"></param>
|
|
/// <returns></returns>
|
|
internal static bool IsValidUserName(string username)
|
|
{
|
|
// Check if the user name is "Admin" or start with "$$" - invalid usernames
|
|
if (username.CompareTo("Admin") == 0 || username.StartsWith("$$") == true)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool isValid = false;
|
|
foreach (Char c in username)
|
|
{
|
|
if (Char.IsLetterOrDigit(c))
|
|
isValid = true;
|
|
else if (INVALID_USERNAME_CHARS.Contains(Char.ToString(c)) || c.CompareTo('"') == 0)
|
|
return false;
|
|
}
|
|
return isValid;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region - Config file settings -
|
|
|
|
/// <summary>
|
|
/// Saves Connection Settings to app.config
|
|
/// </summary>
|
|
public static void SaveConfigFile(Connection connection)
|
|
{
|
|
Properties.Settings.Default.HOST_NAME = connection.HostName;
|
|
Properties.Settings.Default.USER_NAME = connection.UserName;
|
|
Properties.Settings.Default.KRB_ENABLE = connection.KerberosEnable;
|
|
Properties.Settings.Default.TLS_ENABLE = connection.TLSEnable;
|
|
Properties.Settings.Default.MTLS_ENABLE = connection.MTLSEnable;
|
|
Properties.Settings.Default.CLIENT_CERTIFICATE = connection.ClientCertificate;
|
|
Properties.Settings.Default.USE_CIRA = connection.CiraEnable;
|
|
Properties.Settings.Default.PROXY_HOSTNAME = connection.ProxyHost;
|
|
Properties.Settings.Default.PROXY_PORT = connection.ProxyPort.ToString();
|
|
Properties.Settings.Default.PROXY_USERNAME = connection.ProxyUserName;
|
|
|
|
Properties.Settings.Default.Save();
|
|
}
|
|
//public static void SaveConfigFile(WsmanConnection connection)
|
|
//{
|
|
// Properties.Settings.Default.HOST_NAME = connection.Address;
|
|
// Properties.Settings.Default.USER_NAME = connection.Username;
|
|
// Properties.Settings.Default.Save();
|
|
//}
|
|
|
|
#endregion APP_CONFIG
|
|
|
|
#endregion
|
|
}
|
|
|
|
#region - UCTException class -
|
|
|
|
public class UCTException : Exception
|
|
{
|
|
public UCTException() : base() { }
|
|
|
|
public UCTException(string msg) : base(msg) { }
|
|
}
|
|
|
|
#endregion
|
|
}
|