//----------------------------------------------------------------------------
//
// 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 -
///
/// Return the enum description attribute
///
///
///
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) " ;
}
///
/// Display the help document
///
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);
}
///
/// Compares between two versions.
///
/// First version
/// Second version
///
/// 0 when equal.
/// greater than 0 when the first version is later.
/// less than 0 when the second version is later.
///
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 -
///
/// Determines wheter a character is valid for hostName char
///
/// char
/// true if valid char; otherwise false
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;
}
///
/// Determines whether an input address is in a valid FQDN format
///
/// MAC Address
/// true is valid FQDN format; otherwise false
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;
}
///
/// Determines whether an input address is in a valid host name format
///
///
/// true if input is in a valid hostName format; otherwise
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;
}
///
/// Determines whether an IP is in a valid IPV4 format
/// return true if valid format; otherwise returns false
///
/// MAC Address
/// true is valid IPV4 format; otherwise false
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;
}
///
/// Determines whether an IP is in a valid IPV4 format
/// return true if valid format; otherwise returns false
///
/// MAC Address
/// true is valid IPV4 format; otherwise false
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;
}
///
/// Returns Address format of input
///
/// Address
/// IPV4, IPV6, Host, Other
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;
}
///
/// Determines whether the macAddress input is in a valid mac format
/// return true if valid format; otherwise returns false
///
/// MAC Address
///
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;
}
///
/// Determines whether a password is in a strong password standard
///
///
///
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;
}
///
/// Determines whether a username is in valid format
///
///
///
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 -
///
/// Saves Connection Settings to app.config
///
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
}