292 lines
11 KiB
C#
292 lines
11 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Management;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using Newtonsoft.Json;
|
|
using Xylem.Common.CommonCore.Consts;
|
|
|
|
|
|
namespace Xylem.Common.Cryptology.Security
|
|
{
|
|
/// <summary>
|
|
/// Cryptology information container
|
|
/// </summary>
|
|
public static class CryptInformation
|
|
{
|
|
/// <summary>
|
|
/// Separator for PC name from hardware information
|
|
/// </summary>
|
|
public const String SeparatorPcFromHwId = @"\";
|
|
|
|
/// <summary>
|
|
/// Get domain from local machine
|
|
/// </summary>
|
|
/// <returns> domain </returns>
|
|
/// <remarks date="2021-Jan-30" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
public static String GetSysDomain()
|
|
{
|
|
// Collect key information from HW and user
|
|
var userInformation = GetDomainAndUserLoginName();
|
|
var userInformationFields = userInformation.Split(Convert.ToChar("\\"));
|
|
return userInformationFields[0];
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get user login name from local machine
|
|
/// </summary>
|
|
/// <returns> user login name </returns>
|
|
/// <remarks date="2021-Jan-30" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
/// <remarks date="2021-Jun-01" author="Thomas Wiedebusch">
|
|
/// - Convert to upper to get rid of the case sensitive user login name.
|
|
/// </remarks>
|
|
public static String GetSysUserLoginName()
|
|
{
|
|
// Collect key information from HW and user
|
|
var userInformation = GetDomainAndUserLoginName();
|
|
var userInformationFields = userInformation.Split(Convert.ToChar("\\"));
|
|
return userInformationFields[1].ToUpper();
|
|
}
|
|
|
|
/// <summary>
|
|
/// User login name including the domain e.g. "SPXMLU\bauer_marc"
|
|
/// </summary>
|
|
/// <remarks date="2021-Jan-21" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
/// <remarks date="2021-Jun-01" author="Thomas Wiedebusch">
|
|
/// - Private function as user name is case sensitive.
|
|
/// </remarks>
|
|
private static String GetDomainAndUserLoginName()
|
|
{
|
|
return System.Security.Principal.WindowsIdentity.GetCurrent().Name;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Getting local PC name which is useful for inter-program communication for operators to
|
|
/// select the right PC for update operation.
|
|
/// </summary>
|
|
/// <remarks date="2021-Apr-08" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
public static String GetSysPcName()
|
|
{
|
|
return Environment.MachineName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Getting the PC name out of the system information string which is useful for inter-program
|
|
/// communication for operators to select the right PC for update operation.
|
|
/// </summary>
|
|
/// <remarks date="2021-Apr-08" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
public static String GetPcNameFromHwId(String hardwareId)
|
|
{
|
|
if (!hardwareId.Contains(SeparatorPcFromHwId)) return Constants.StrUnknown;
|
|
var hwIdFields = hardwareId.Split(Convert.ToChar(SeparatorPcFromHwId));
|
|
return hwIdFields[0];
|
|
}
|
|
|
|
/// <summary>
|
|
/// User password hash replaced by random code if user is not registered or valid date is expired
|
|
/// </summary>
|
|
/// <remarks date="2021-Mar-19" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
/// <remarks date="2021-Mar-22" author="Thomas Wiedebusch">
|
|
/// - Replace "-" with blank in random code.
|
|
/// </remarks>
|
|
public static String GetSysUserPasswordHash(UserInformation sysUser)
|
|
{
|
|
var randomCode = BitConverter.ToString(Cryptology.BuildRandomValue(32)).Replace("-", "");
|
|
// Take the validation date for to decide for new random code.
|
|
if (sysUser == null || string.IsNullOrEmpty(sysUser.PasswordHash) ||
|
|
DateTimeOffset.Compare(sysUser.ValidDate, DateTimeOffset.Now) < 1) return randomCode;
|
|
// if the registration valid date is not outdated, the sys user password shall remain as is
|
|
return sysUser.PasswordHash;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check user input for "full name".
|
|
/// </summary>
|
|
/// <param name="name">full user name for check</param>
|
|
/// <returns>true if user name matches the:
|
|
/// - Start with capital letter,
|
|
/// - one or more lowercase letters,
|
|
/// - white space and at least
|
|
/// - one trailing word,
|
|
/// - double names separated with - or ' are allowed as well as special characters
|
|
/// like umlaut in German or Spain...
|
|
/// </returns>
|
|
/// <remarks date="2021-Feb-08" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
/// <remarks date="2021-Apr-13" author="Thomas Wiedebusch">
|
|
/// - Check name for null or empty.
|
|
/// </remarks>
|
|
public static Boolean CheckUserFullNameFormat(String name)
|
|
{
|
|
return !string.IsNullOrEmpty(name) && Regex.Match(name, @"\b\p{Lu}[-'\w]+(\s[-'\w]+)+$").Success;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check if the decoding is possible by comparison of the reg user with the sys user.
|
|
/// All information needs to be checked including the proper assigned FullName and the pwd hash.
|
|
/// </summary>
|
|
/// <param name="regUser"></param>
|
|
/// <returns>true if all information is set for decoding</returns>
|
|
/// <remarks date="2021-Mar-15" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
/// <remarks date="2021-Mar-20" author="Thomas Wiedebusch">
|
|
/// - GetSysUserPasswordHash.
|
|
/// </remarks>
|
|
public static Boolean IsDecodingPossible(UserInformation regUser)
|
|
{
|
|
if (regUser == null || string.IsNullOrEmpty(regUser.FullName)) return false;
|
|
|
|
return regUser.Domain == GetSysDomain() &&
|
|
regUser.LogInName == GetSysUserLoginName() &&
|
|
regUser.HardwareId == GetSysHardwareId() &&
|
|
regUser.PasswordHash == GetSysUserPasswordHash(regUser);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read the sys user from Win10 system.
|
|
/// </summary>
|
|
/// <param name="sysUser"></param>
|
|
/// <remarks date="2021-Mar-15" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
/// <remarks date="2021-Mar-19" author="Thomas Wiedebusch">
|
|
/// - Take the sys user as input.
|
|
/// </remarks>
|
|
public static void GetSysUser(UserInformation sysUser)
|
|
{
|
|
sysUser.Domain = GetSysDomain();
|
|
sysUser.LogInName = GetSysUserLoginName();
|
|
sysUser.HardwareId = GetSysHardwareId();
|
|
sysUser.PasswordHash = GetSysUserPasswordHash(sysUser);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Write the user registration from the registration file on the local HDD.
|
|
/// </summary>
|
|
/// <param name="pathFile"></param>
|
|
/// <param name="dbFullRegUser"></param>
|
|
/// <returns>true if file exists and user has at least the FullName being set</returns>
|
|
/// <remarks date="2021-Mar-15" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
public static Boolean WriteUserRegistration(String pathFile, UserInformation dbFullRegUser)
|
|
{
|
|
// Register user to local HDD if the DB user is not identical
|
|
if (string.IsNullOrEmpty(pathFile)) return false;
|
|
try
|
|
{
|
|
// Store user registration from ..[User]/AppData/Roaming/Genesis.
|
|
var serializedData = JsonConvert.SerializeObject(dbFullRegUser);
|
|
var asciiStream = Encoding.UTF8.GetBytes(serializedData);
|
|
File.WriteAllBytes(pathFile, asciiStream);
|
|
return true;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Read the user registration from the registration file on the local HDD.
|
|
/// </summary>
|
|
/// <param name="pathFile"></param>
|
|
/// <param name="regUser"></param>
|
|
/// <returns>true if file exists and user has at least the FullName being set</returns>
|
|
/// <remarks date="2021-Mar-15" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
/// <remarks date="2021-Jun-01" author="Thomas Wiedebusch">
|
|
/// - Convert to upper to get rid of the case sensitive user login name.
|
|
/// </remarks>
|
|
public static Boolean ReadUserRegistration(String pathFile, out UserInformation regUser)
|
|
{
|
|
regUser = null;
|
|
try
|
|
{
|
|
if (!File.Exists(pathFile)) return false;
|
|
|
|
regUser = new UserInformation();
|
|
// load user registration from ..[User]/AppData/Roaming/Genesis
|
|
var asciiStream = File.ReadAllBytes(pathFile);
|
|
var serializedData = Encoding.UTF8.GetString(asciiStream, 0, asciiStream.Length);
|
|
|
|
regUser = JsonConvert.DeserializeObject<UserInformation>(serializedData);
|
|
regUser.LogInName = regUser.LogInName.ToUpper();
|
|
return true;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Bios version of user PC
|
|
/// </summary>
|
|
/// <remarks date="2021-Jan-20" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
public static String GetBiosVersion()
|
|
{
|
|
var bios = new ManagementObjectSearcher("SELECT Version FROM Win32_BIOS");
|
|
var biosCollection = bios.Get();
|
|
var strBios = new StringBuilder();
|
|
foreach (var obj in biosCollection)
|
|
{
|
|
strBios.Append(obj["Version"]);
|
|
}
|
|
|
|
return strBios.ToString();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Hardware identification of user PC based on UUID and processor ID
|
|
/// </summary>
|
|
/// <remarks date="2021-Jan-20" author="Thomas Wiedebusch">
|
|
/// - Initial.
|
|
/// </remarks>
|
|
/// <remarks date="2021-Apr-08" author="Thomas Wiedebusch">
|
|
/// - Add PC-Name to the HW Id to inform the FwUpdateBuilder operator about the PC.
|
|
/// </remarks>
|
|
public static String GetSysHardwareId()
|
|
{
|
|
var strHwId = new StringBuilder();
|
|
var pcName = GetSysPcName();
|
|
strHwId.Append(pcName);
|
|
strHwId.Append(SeparatorPcFromHwId);
|
|
var computerSystem = new ManagementObjectSearcher("SELECT UUID FROM Win32_ComputerSystemProduct");
|
|
var computerSystemCollection = computerSystem.Get();
|
|
foreach (var obj in computerSystemCollection)
|
|
{
|
|
strHwId.Append(obj["UUID"]);
|
|
}
|
|
|
|
strHwId.Append("-");
|
|
|
|
var processorInfo = new ManagementObjectSearcher("SELECT ProcessorID From Win32_processor");
|
|
var processorInfoCollection = processorInfo.Get();
|
|
foreach (var obj in processorInfoCollection)
|
|
{
|
|
strHwId.Append(obj["ProcessorID"]);
|
|
}
|
|
|
|
return strHwId.ToString();
|
|
}
|
|
}
|
|
}
|