adfsmfa/Neos.IdentityServer 3.1/Neos.IdentityServer.MultiFactor.Cmdlets/Neos.IdentityServer.Multifactor.Cmdlets.DataContracts.cs
redhook 7a9d01545c 3.1.2112.0
3.1.2112.0
2021-11-29 18:23:45 +01:00

2279 lines
88 KiB
C#

//******************************************************************************************************************************************************************************************//
// Copyright (c) 2021 @redhook62 (adfsmfa@gmail.com) //
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), //
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, //
// and to permit persons to whom the Software is furnished to do so, subject to the following conditions: //
// //
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. //
// //
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, //
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. //
// //
// //
// https://github.com/neos-sdi/adfsmfa //
// //
//******************************************************************************************************************************************************************************************//
namespace MFA
{
using Neos.IdentityServer.MultiFactor;
using Neos.IdentityServer.MultiFactor.Administration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Text;
#region PSRegistration class
/// <summary>
/// PSRegistrationList class
/// <para type="synopsis">List of user entry in MFA System.</para>
/// <para type="description">List a user entry registered with MFA.</para>
/// </summary>
/// <example>
/// <para>$users = Get-MFAUsers</para>
/// </example>
public class PSRegistrationList : List<PSRegistration>
{
/// <summary>
/// explicit conversion to PSRegistrationList
/// </summary>
public static explicit operator PSRegistrationList(MFAUserList registrations)
{
if (registrations == null)
return null;
PSRegistrationList lst = new PSRegistrationList();
foreach (MFAUser reg in registrations)
{
lst.Add((PSRegistration)reg);
}
return lst;
}
/// <summary>
/// explicit conversion from PSRegistrationList
/// </summary>
public static explicit operator MFAUserList(PSRegistrationList registrations)
{
if (registrations == null)
return null;
MFAUserList lst = new MFAUserList();
foreach (PSRegistration reg in registrations)
{
lst.Add((MFAUser)reg);
}
return lst;
}
}
/// <summary>
/// PSRegistration class
/// <para type="synopsis">User entry in MFA System.</para>
/// <para type="description">Represent a user entry registered with MFA.</para>
/// <para type="description">You can access, update each user property.</para>
/// </summary>
/// <example>
/// <para>$u = Get-MFAUsers -Identity user@domain.com</para>
/// <para>$u.MailAddress = usermail@domain.com</para>
/// <para>$u.PhoneNumber = 0102030405</para>
/// <para>$u.PreferredMethod = Phone</para>
/// <para>Set-MFAUsers $u</para>
/// </example>
public class PSRegistration
{
/// <summary>
/// Properties
/// </summary>
public string ID { get; internal set; }
/// <summary>
/// <para type="description">User identity (upn).</para>
/// </summary>
public string UPN { get; set; }
/// <summary>
/// <para type="description">User mail address.</para>
/// </summary>
public string MailAddress { get; set; }
/// <summary>
/// <para type="description">User mobile phone number.</para>
/// </summary>
public string PhoneNumber { get; set; }
/// <summary>
/// <para type="description">User's PIN code. 0 if none.</para>
/// </summary>
public int PIN { get; set; }
/// <summary>
/// <para type="description">User status.</para>
/// </summary>
public bool Enabled { get; set; }
internal bool IsRegistered { get; set; }
/// <summary>
/// <para type="description">Preferred MFA method : Choose, Code, email, Phone, Face (for future use).</para>
/// </summary>
public PSPreferredMethod PreferredMethod { get; set; }
internal string OverrideMethod { get; set; }
internal bool IsApplied { get; set; }
/// <summary>
/// implicit conversion to PSRegistration
/// </summary>
public static explicit operator PSRegistration(MFAUser registration)
{
if (registration == null)
return null;
else
{
PSRegistration psnode = new PSRegistration
{
ID = registration.ID,
UPN = registration.UPN,
MailAddress = registration.MailAddress,
PhoneNumber = registration.PhoneNumber,
IsRegistered = registration.IsRegistered,
Enabled = registration.Enabled,
PreferredMethod = (PSPreferredMethod)registration.PreferredMethod,
OverrideMethod = registration.OverrideMethod,
PIN = registration.PIN,
IsApplied = registration.IsApplied
};
return psnode;
}
}
/// <summary>
/// implicit conversion from PSRegistration
/// </summary>
public static explicit operator MFAUser(PSRegistration psnode)
{
if (psnode == null)
return null;
else
{
MFAUser registration = new MFAUser
{
ID = psnode.ID,
UPN = psnode.UPN,
MailAddress = psnode.MailAddress,
PhoneNumber = psnode.PhoneNumber,
IsRegistered = psnode.IsRegistered,
Enabled = psnode.Enabled,
PreferredMethod = (PreferredMethod)psnode.PreferredMethod,
OverrideMethod = psnode.OverrideMethod,
PIN = psnode.PIN,
IsApplied = psnode.IsApplied
};
return registration;
}
}
}
#endregion
#region PSConfig
/// <summary>
/// PSGeneralConfiguration class
/// <para type="synopsis">Main configuration properties in MFA System.</para>
/// <para type="description">Represent Main configuration properties registered with MFA.</para>
/// <para type="description">You can access, update each config property.</para>
/// </summary>
/// <example>
/// <para>$cfg = Get-MFAConfig</para>
/// <para>$cfg.UseOfUserLanguages = $true</para>
/// <para>Set-MFAConfig $cfg</para>
/// </example>
public class PSConfig
{
/// <summary>
/// <para type="description">Administrators email, used in administrative emails sent to users.</para>
/// </summary>
public string AdminContact { get; set; }
/// <summary>
/// <para type="description">Issuer description (eg "my company").</para>
/// </summary>
public string Issuer { get; set; }
/// <summary>
/// <para type="description">Default contry code, used for SMS calls .</para>
/// </summary>
public string DefaultCountryCode { get; set; }
/// <summary>
/// <para type="description">Default provider when User method equals "Choose".</para>
/// </summary>
public PSPreferredMethod DefaultProviderMethod { get; set; }
/// <summary>
/// <para type="description">Policy attributes for users management and registration.</para>
/// </summary>
public PSUserFeaturesOptions UserFeatures { get; set; }
/// <summary>
/// <para type="description">Use or not our implementation for changing user password,if not we are using /ADFS/Portal/updatepasswor.</para>
/// </summary>
public bool CustomUpdatePassword { get; set; }
/// <summary>
/// <para type="description">Let user to change the default MFA provider for later use.</para>
/// </summary>
public bool KeepMySelectedOptionOn { get; set; }
/// <summary>
/// <para type="description">Send email notifications when a user update his configuration.</para>
/// </summary>
public bool ChangeNotificationsOn { get; set; }
/// <summary>
/// <para type="description">Use of User's browser laguages instead or standard localization features.</para>
/// </summary>
public bool UseOfUserLanguages { get; set; }
/// <summary>
/// <para type="description">Policy attributes for warnings to users.</para>
/// </summary>
public PSAdvertisingDays AdvertisingDays { get; set; }
/// <summary>
/// <para type="description">Kind of ADFS's User Interface version.</para>
/// </summary>
public PSUIKind UiKind { get; internal set; }
/// <summary>
/// <para type="description">Use ADFS 2019 paginated UI Styles.</para>
/// </summary>
public bool UseUIPaginated { get; internal set; }
/// <summary>
/// <para type="description">Options when using MFA as primary auth.</para>
/// </summary>
public PSPrimaryAuthOptions PrimaryAuhenticationOptions { get; set; } = PSPrimaryAuthOptions.None;
/// <summary>
/// <para type="description">Class Library for custom UI implementation (FullyQualifiedImplementation).</para>
/// </summary>
public string AdapterPresentationImplementation { get; set; }
/// <summary>
/// <para type="description">Force adfsmfa to no Use localization but a specified language.</para>
/// </summary>
public string ForcedLanguage { get; set; }
/// <summary>
/// implicit conversion to PSConfig
/// </summary>
public static explicit operator PSConfig(FlatConfig config)
{
if (config == null)
return null;
else
{
PSConfig psconfig = new PSConfig
{
AdminContact = config.AdminContact,
DefaultCountryCode = config.DefaultCountryCode,
Issuer = config.Issuer,
CustomUpdatePassword = config.CustomUpdatePassword,
KeepMySelectedOptionOn = config.KeepMySelectedOptionOn,
ChangeNotificationsOn = config.ChangeNotificationsOn,
UseOfUserLanguages = config.UseOfUserLanguages,
DefaultProviderMethod = (PSPreferredMethod)config.DefaultProviderMethod,
UserFeatures = (PSUserFeaturesOptions)config.UserFeatures,
AdvertisingDays = (PSAdvertisingDays)config.AdvertisingDays,
UseUIPaginated = config.UseUIPaginated,
UiKind = (PSUIKind)config.UiKind,
PrimaryAuhenticationOptions = (PSPrimaryAuthOptions)config.PrimaryAuhenticationOptions,
AdapterPresentationImplementation = config.AdapterPresentationImplementation,
ForcedLanguage = config.ForcedLanguage
};
return psconfig;
}
}
/// <summary>
/// implicit conversion from PSConfig
/// </summary>
public static explicit operator FlatConfig(PSConfig psconfig)
{
if (psconfig == null)
return null;
else
{
FlatConfig config = new FlatConfig
{
IsDirty = true,
AdminContact = psconfig.AdminContact,
CustomUpdatePassword = psconfig.CustomUpdatePassword,
DefaultCountryCode = psconfig.DefaultCountryCode,
Issuer = psconfig.Issuer,
KeepMySelectedOptionOn = psconfig.KeepMySelectedOptionOn,
ChangeNotificationsOn = psconfig.ChangeNotificationsOn,
UseOfUserLanguages = psconfig.UseOfUserLanguages,
DefaultProviderMethod = (PreferredMethod)psconfig.DefaultProviderMethod,
UserFeatures = (UserFeaturesOptions)psconfig.UserFeatures,
AdvertisingDays = (FlatAdvertising)psconfig.AdvertisingDays,
UseUIPaginated = psconfig.UseUIPaginated,
UiKind = (ADFSUserInterfaceKind)psconfig.UiKind,
PrimaryAuhenticationOptions = (PrimaryAuthOptions)psconfig.PrimaryAuhenticationOptions,
AdapterPresentationImplementation = psconfig.AdapterPresentationImplementation,
ForcedLanguage = psconfig.ForcedLanguage
};
return config;
}
}
}
#endregion
#region PSAdvertisingDays
/// <summary>
/// PSAdvertisingDays class
/// <para type="synopsis">Main configuration properties in MFA System.</para>
/// <para type="description">Range of days during which users are invited to register.</para>
/// </summary>
/// <example>
/// <para>$cfg = Get-MFAConfig</para>
/// <para>$cfg.AdvertisingDays.FirstDay = 12</para>
/// <para>$cfg.AdvertisingDays.FirstDay = 25</para>
/// <para>Set-MFAConfig $cfg</para>
/// </example>
public class PSAdvertisingDays
{
/// <summary>
/// <para type="description">First Day for advertising.</para>
/// </summary>
public uint FirstDay { get; set; }
/// <summary>
/// <para type="description">Last Day for advertising.</para>
/// </summary>
public uint LastDay { get; set; }
/// <summary>
/// <para type="description">OnFire.</para>
/// </summary>
public bool OnFire { get; set; }
/// <summary>
/// <para type="description">explicit operator.</para>
/// </summary>
public static explicit operator PSAdvertisingDays(FlatAdvertising adv)
{
if (adv == null)
return null;
PSAdvertisingDays cfg = new PSAdvertisingDays
{
FirstDay = adv.FirstDay,
LastDay = adv.LastDay,
OnFire = adv.OnFire
};
return cfg;
}
/// <summary>
/// <para type="description">explicit operator.</para>
/// </summary>
public static explicit operator FlatAdvertising(PSAdvertisingDays adv)
{
if (adv == null)
return null;
FlatAdvertising cfg = new FlatAdvertising
{
FirstDay = adv.FirstDay,
LastDay = adv.LastDay,
OnFire = adv.OnFire
};
return cfg;
}
/// <summary>
/// <para type="description">explicit operator.</para>
/// </summary>
public static implicit operator PSAdvertisingDays(string advstr)
{
if (string.IsNullOrEmpty(advstr))
return null;
string rec = advstr.Replace("{", "").Replace("}", "");
string[] data = rec.Split(';');
List<KeyValuePair<string, UInt32>> pp = new List<KeyValuePair<string, uint>>();
foreach (string xx in data)
{
string[] tp = xx.Split('=');
if (tp.Length == 2)
pp.Add(new KeyValuePair<string, UInt32>(tp[0].ToString().Trim(), Convert.ToUInt32(tp[1])));
}
if ((pp.Count == 0))
return null;
PSAdvertisingDays days = new PSAdvertisingDays();
foreach (KeyValuePair<string, UInt32> x in pp)
{
if (x.Key.ToLower().Equals("firstday"))
days.FirstDay = Convert.ToUInt32(x.Value);
if (x.Key.ToLower().Equals("lastday"))
days.LastDay = Convert.ToUInt32(x.Value);
}
days.OnFire = true;
return days;
}
/// <summary>
/// <para type="description">explicit operator.</para>
/// </summary>
public static implicit operator PSAdvertisingDays(ScriptBlock advstr)
{
if (advstr==null)
return null;
string rec = advstr.ToString().Replace("{", "").Replace("}", "");
string[] data = rec.Split(';');
List<KeyValuePair<string, UInt32>> pp = new List<KeyValuePair<string, uint>>();
foreach (string xx in data)
{
string[] tp = xx.Split('=');
if (tp.Length==2)
pp.Add(new KeyValuePair<string, UInt32>(tp[0].ToString().Trim(), Convert.ToUInt32(tp[1])));
}
if ((pp.Count ==0))
return null;
PSAdvertisingDays days = new PSAdvertisingDays();
foreach (KeyValuePair<string, UInt32> x in pp)
{
if (x.Key.ToLower().Equals("firstday"))
days.FirstDay = Convert.ToUInt32(x.Value);
if (x.Key.ToLower().Equals("lastday"))
days.LastDay = Convert.ToUInt32(x.Value);
}
days.OnFire = true;
return days;
}
/// <summary>
/// <para type="description">ToString() override.</para>
/// </summary>
public override string ToString()
{
return "{FirstDay : " + this.FirstDay.ToString() + "; LastDay : " + this.LastDay.ToString() + "; OnFire : " + this.OnFire.ToString()+"}";
}
}
#endregion
#region PSBaseStore
/// <summary>
/// <para type="synopsis">ADDS / SQL common class.</para>
/// <para type="description">ADDS / SQL base class.</para>
/// </summary>
/// <example>
/// <para>Get-MFAStore -Store ADDS</para>
/// </example>
public class PSBaseStore
{
/// <summary>
/// <para type="description">If true, users metadata are stored in ADDS attributes or in SQL Database. see : Get-MFAStore -Store ADDS or Get-MFAStore -Store SQL.</para>
/// </summary>
public bool Active { get; set; }
}
#endregion
#region PSADDSStore
/// <summary>
/// PSADDSStore class
/// <para type="synopsis">ADDS configuration properties in MFA System.</para>
/// <para type="description">ADDS configuration properties registered with MFA.You can access, update attributes properties.</para>
/// </summary>
/// <example>
/// <para>Get-MFAStore -Store ADDS</para>
/// </example>
public class PSADDSStore: PSBaseStore
{
/// <summary>
/// <para type="description">ADDS attribute name user to store user secret key (default msDS-cloudExtensionAttribute10).</para>
/// </summary>
public string KeyAttribute { get; set; }
/// <summary>
/// <para type="description">ADDS attribute name used to store user custom mail address (default msDS-cloudExtensionAttribute11).</para>
/// </summary>
public string MailAttribute { get; set; }
/// <summary>
/// <para type="description">ADDS attribute name used to store user phone number (default msDS-cloudExtensionAttribute12).</para>
/// </summary>
public string PhoneAttribute { get; set; }
/// <summary>
/// <para type="description">ADDS attribute name used to store user preferred method (Code, Phone, Mail) (default msDS-cloudExtensionAttribute13).</para>
/// </summary>
public string MethodAttribute { get; set; }
/// <summary>
/// <para type="description">ADDS attribute name used to store user preferred method (Code, Phone, Mail) (default msDS-cloudExtensionAttribute14).</para>
/// </summary>
public string OverrideMethodAttribute { get; set; }
/// <summary>
/// <para type="description">ADDS attribute name used to store user status with MFA (default msDS-cloudExtensionAttribute18).</para>
/// </summary>
public string EnabledAttribute { get; set; }
/// <summary>
/// <para type="description">ADDS attribute name used to store user pin code (default msDS-cloudExtensionAttribute15).</para>
/// </summary>
public string PinAttribute { get; set; }
/// <summary>
/// <para type="description">ADDS attribute name used to store multiple user Public Keys Credential (recommended msDS-KeyCredentialLink or othetMailbox).</para>
/// </summary>
public string PublicKeyCredentialAttribute { get; set; }
/// <summary>
/// <para type="description">ADDS attribute name used to store Client Certificate (default msDS-cloudExtensionAttribute16).</para>
/// </summary>
public string ClientCertificateAttribute { get; set; }
/// <summary>
/// <para type="description">ADDS attribute name used to store RSA Certificate (default msDS-cloudExtensionAttribute17).</para>
/// </summary>
public string RSACertificateAttribute { get; set; }
/// <summary>
/// <para type="description">Get or Set the max rows limit used to access MFA Active Directory.</para>
/// </summary>
public int MaxRows { get; set; }
/// <summary>
/// <para type="description">Get or Set value indicating if ldap or ldaps must be used to access MFA Active Directory.</para>
/// </summary>
public bool UseSSL { get; set; }
/// <summary>
/// implicit conversion
/// </summary>
public static explicit operator PSADDSStore(FlatADDSStore addsconfig)
{
if (addsconfig == null)
return null;
else
{
PSADDSStore psconfigadds = new PSADDSStore
{
Active = addsconfig.Active,
KeyAttribute = addsconfig.KeyAttribute,
MailAttribute = addsconfig.MailAttribute,
PhoneAttribute = addsconfig.PhoneAttribute,
MethodAttribute = addsconfig.MethodAttribute,
OverrideMethodAttribute = addsconfig.OverrideMethodAttribute,
PinAttribute = addsconfig.PinAttribute,
EnabledAttribute = addsconfig.EnabledAttribute,
PublicKeyCredentialAttribute = addsconfig.PublicKeyCredentialAttribute,
ClientCertificateAttribute = addsconfig.ClientCertificateAttribute,
RSACertificateAttribute = addsconfig.RSACertificateAttribute,
MaxRows = addsconfig.MaxRows,
UseSSL = addsconfig.UseSSL
};
return psconfigadds;
}
}
/// <summary>
/// implicit conversion
/// </summary>
public static explicit operator FlatADDSStore(PSADDSStore psconfig)
{
if (psconfig == null)
return null;
else
{
FlatADDSStore config = new FlatADDSStore
{
IsDirty = true,
Active = psconfig.Active,
KeyAttribute = psconfig.KeyAttribute,
MailAttribute = psconfig.MailAttribute,
PhoneAttribute = psconfig.PhoneAttribute,
MethodAttribute = psconfig.MethodAttribute,
OverrideMethodAttribute = psconfig.OverrideMethodAttribute,
PinAttribute = psconfig.PinAttribute,
EnabledAttribute = psconfig.EnabledAttribute,
PublicKeyCredentialAttribute = psconfig.PublicKeyCredentialAttribute,
ClientCertificateAttribute = psconfig.ClientCertificateAttribute,
RSACertificateAttribute = psconfig.RSACertificateAttribute,
MaxRows = psconfig.MaxRows,
UseSSL = psconfig.UseSSL
};
return config;
}
}
/// <summary>
/// SetADDSAttributesTemplate method implementation
/// </summary>
public static void SetADDSAttributesTemplate(PSADDSTemplateKind kind)
{
ManagementService.SetADDSAttributesTemplate((ADDSTemplateKind)kind, true);
}
}
#endregion
#region PSSQLStore
/// <summary>
/// PSSQLStore class
/// <para type="synopsis">SQL configuration properties in MFA System.</para>
/// <para type="description">SQL configuration properties registered with MFA. You can access, update connectionString property.</para>
/// </summary>
/// <example>
/// <para>Get-MFAStore -Store SQL</para>
/// </example>
public class PSSQLStore : PSBaseStore
{
/// <summary>
/// <para type="description">Get or Set the connection string used to access MFA SQL Database.</para>
/// </summary>
public string ConnectionString { get; set; }
/// <summary>
/// <para type="description">Get or Set the max rows limit used to access MFA SQL Database.</para>
/// </summary>
public int MaxRows { get; set; }
/// <summary>
/// <para type="description">Get or Set the SQLServer 2016 and up Always Encrypted feature. default = false.</para>
/// </summary>
public bool IsAlwaysEncrypted { get; set; }
/// <summary>
/// <para type="description">Get or Set the validity of the generated certificate (in years, 5 per default).</para>
/// </summary>
public int CertificateValidity { get; set; }
/// <summary>
/// <para type="description">Get or Set the SQLServer 2016 and up Always Encrypted feature Thumprint.</para>
/// </summary>
public string ThumbPrint { get; set; }
/// <summary>
/// <para type="description">Get or Set the indicating if we are reusing an existing certificate.</para>
/// </summary>
public bool CertReuse { get; set; }
/// <summary>
/// <para type="description">Get or Set the SQLServer 2016 crypting key name.</para>
/// </summary>
public string KeyName { get; set; }
/// <summary>
/// implicit conversion to PSConfig
/// </summary>
public static explicit operator PSSQLStore(FlatSQLStore sqlconfig)
{
if (sqlconfig == null)
return null;
else
{
PSSQLStore psconfigsql = new PSSQLStore
{
Active = sqlconfig.Active,
ConnectionString = sqlconfig.ConnectionString,
MaxRows = sqlconfig.MaxRows,
IsAlwaysEncrypted = sqlconfig.IsAlwaysEncrypted,
ThumbPrint = sqlconfig.ThumbPrint,
KeyName = sqlconfig.KeyName,
CertReuse = sqlconfig.CertReuse,
CertificateValidity = sqlconfig.CertificateValidity
};
return psconfigsql;
}
}
/// <summary>
/// implicit conversion from PSConfig
/// </summary>
public static explicit operator FlatSQLStore(PSSQLStore psconfig)
{
if (psconfig == null)
return null;
else
{
FlatSQLStore config = new FlatSQLStore
{
IsDirty = true,
Active = psconfig.Active,
ConnectionString = psconfig.ConnectionString,
MaxRows = psconfig.MaxRows,
IsAlwaysEncrypted = psconfig.IsAlwaysEncrypted,
ThumbPrint = psconfig.ThumbPrint,
KeyName = psconfig.KeyName,
CertReuse = psconfig.CertReuse,
CertificateValidity = psconfig.CertificateValidity
};
return config;
}
}
}
#endregion
#region PSCustomStore
/// <summary>
/// PSSQLStore class
/// <para type="synopsis">SQL configuration properties in MFA System.</para>
/// <para type="description">SQL configuration properties registered with MFA. You can access, update connectionString property.</para>
/// </summary>
/// <example>
/// <para>Get-MFAStore -Store SQL</para>
/// </example>
public class PSCustomStore : PSBaseStore
{
/// <summary>
/// <para type="description">Get or Set the connection string used to access MFA SQL Database.</para>
/// </summary>
public string ConnectionString { get; set; }
/// <summary>
/// <para type="description">Get or Set the max rows limit used to access MFA SQL Database.</para>
/// </summary>
public int MaxRows { get; set; }
/// <summary>
/// <para type="description">Full qualified implementation class for replacing default storage.</para>
/// </summary>
public string DataRepositoryFullyQualifiedImplementation { get; set; }
/// <summary>
/// <para type="description">Full qualified implementation class for replacing default storage for keys.</para>
/// </summary>
public string KeysRepositoryFullyQualifiedImplementation { get; set; }
/// <summary>
/// <para type="description">Full qualified implementation parameters for replacing default storage.</para>
/// </summary>
public string Parameters { get; set; }
/// <summary>
/// implicit conversion to PSConfig
/// </summary>
public static explicit operator PSCustomStore(FlatCustomStore sqlconfig)
{
if (sqlconfig == null)
return null;
else
{
PSCustomStore psconfigsql = new PSCustomStore
{
Active = sqlconfig.Active,
ConnectionString = sqlconfig.ConnectionString,
MaxRows = sqlconfig.MaxRows,
DataRepositoryFullyQualifiedImplementation = sqlconfig.DataRepositoryFullyQualifiedImplementation,
KeysRepositoryFullyQualifiedImplementation = sqlconfig.KeysRepositoryFullyQualifiedImplementation,
Parameters = sqlconfig.Parameters
};
return psconfigsql;
}
}
/// <summary>
/// implicit conversion from PSConfig
/// </summary>
public static explicit operator FlatCustomStore(PSCustomStore psconfig)
{
if (psconfig == null)
return null;
else
{
FlatCustomStore config = new FlatCustomStore
{
IsDirty = true,
Active = psconfig.Active,
ConnectionString = psconfig.ConnectionString,
MaxRows = psconfig.MaxRows,
DataRepositoryFullyQualifiedImplementation = psconfig.DataRepositoryFullyQualifiedImplementation,
KeysRepositoryFullyQualifiedImplementation = psconfig.KeysRepositoryFullyQualifiedImplementation,
Parameters = psconfig.Parameters
};
return config;
}
}
}
#endregion
#region PSBaseSecurity
/// <summary>
/// PSBaseSecurity class implementation
/// <para type="description">Base Security Class.</para>
/// </summary>
public abstract class PSBaseSecurity
{
}
#endregion
#region PSSecurity
/// <summary>
/// PSSecurity class
/// <para type="synopsis">MFA Security Management.</para>
/// <para type="description">MFA Security Management.</para>
/// </summary>
public class PSSecurity: PSBaseSecurity
{
/// <summary>
/// <para type="description">Max delay for the user to enter TOTP code (seconds 300 by default).</para>
/// </summary>
public int DeliveryWindow { get; set; }
/// <summary>
/// <para type="description">Number of allowed retry allowed (default 3)..</para>
/// </summary>
public int MaxRetries { get; set; }
/// <summary>
/// <para type="description">TOTP Replay Level feature.</para>
/// </summary>
public PSReplayLevel ReplayLevel { get; set; }
/// <summary>
/// <para type="description">Used to Change the version of the encryption Library. V1 is the initial implementation but is less secure, you must migrate to V2</para>
/// </summary>
public PSSecretKeyVersion LibVersion { get; set; }
/// <summary>
/// <para type="description">String used for XOR operations in V2 LibVersion</para>
/// </summary>
public string XORSecret { get; set; }
/// <summary>
/// <para type="description">Required PIN length wehen using aditionnal control with personal PIN.</para>
/// </summary>
public int PinLength { get; set; }
/// <summary>
/// <para type="description">Default value for user's PIN.</para>
/// </summary>
public int DefaultPin { get; set; }
/// <summary>
/// <para type="description">Use MFA Password Policy.</para>
/// </summary>
public bool UsePasswordPolicy { get; set; }
/// <summary>
/// <para type="description">Use Domain Password Policy or Domain Fine-Grained Password Policy.</para>
/// </summary>
public bool UsePSOPasswordPolicy { get; set; }
/// <summary>
/// <para type="description">Lock the user, if user password is expired.</para>
/// </summary>
public bool LockUserOnPasswordExpiration { get; set; }
/// <summary>
/// <para type="description">Max user password age.</para>
/// </summary>
public uint MaxPasswordAgeInDays { get; set; }
/// <summary>
/// <para type="description">Emit warning before user password expiration (in days).</para>
/// </summary>
public uint WarnPasswordExpirationBeforeInDays { get; set; }
/// <summary>
/// <para type="description">Domain name to access (read/write) Active Directory (if ADFS account has rights you leave it blank).</para>
/// </summary>
public string DomainAddress { get; set; }
/// <summary>
/// <para type="description">Account name to access (read/write) Active Directory (if ADFS account has rights you leave it blank).</para>
/// </summary>
public string Account { get; set; }
/// <summary>
/// <para type="description">Password used for account to access (read/write) Active Directory (if ADFS account has rights you leave it blank).</para>
/// </summary>
public string Password { get; set; }
/// <summary>
/// <para type="description">Account name used to access SQL Server Database (if ADFS account has rights you leave it blank).</para>
/// </summary>
public string SQLAccount { get; set; }
/// <summary>
/// <para type="description">Password used to access SQL Server Database (if ADFS account has rights you leave it blank).</para>
/// </summary>
public string SQLPassword { get; set; }
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator PSSecurity(FlatSecurity mgr)
{
if (mgr == null)
return null;
else
{
PSSecurity target = new PSSecurity
{
DeliveryWindow = mgr.DeliveryWindow,
MaxRetries = mgr.MaxRetries,
ReplayLevel = (PSReplayLevel)mgr.ReplayLevel,
LibVersion = (PSSecretKeyVersion)mgr.LibVersion,
XORSecret = mgr.XORSecret,
PinLength = mgr.PinLength,
DefaultPin = mgr.DefaultPin,
UsePasswordPolicy = mgr.UsePasswordPolicy,
UsePSOPasswordPolicy = mgr.UsePSOPasswordPolicy,
LockUserOnPasswordExpiration = mgr.LockUserOnPasswordExpiration,
MaxPasswordAgeInDays = mgr.MaxPasswordAgeInDays,
WarnPasswordExpirationBeforeInDays = mgr.WarnPasswordExpirationBeforeInDays,
DomainAddress = mgr.DomainAddress,
Account = mgr.Account,
Password = mgr.Password,
SQLAccount = mgr.SQLAccount,
SQLPassword = mgr.SQLPassword
};
return target;
}
}
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator FlatSecurity(PSSecurity mgr)
{
if (mgr == null)
return null;
else
{
FlatSecurity target = new FlatSecurity
{
IsDirty = true,
DeliveryWindow = mgr.DeliveryWindow,
MaxRetries = mgr.MaxRetries,
ReplayLevel = (ReplayLevel)mgr.ReplayLevel,
LibVersion = (SecretKeyVersion)mgr.LibVersion,
XORSecret = mgr.XORSecret,
PinLength = mgr.PinLength,
DefaultPin = mgr.DefaultPin,
UsePasswordPolicy = mgr.UsePasswordPolicy,
UsePSOPasswordPolicy = mgr.UsePSOPasswordPolicy,
LockUserOnPasswordExpiration = mgr.LockUserOnPasswordExpiration,
MaxPasswordAgeInDays = mgr.MaxPasswordAgeInDays,
WarnPasswordExpirationBeforeInDays = mgr.WarnPasswordExpirationBeforeInDays,
DomainAddress = mgr.DomainAddress,
Account = mgr.Account,
Password = mgr.Password,
SQLAccount = mgr.SQLAccount,
SQLPassword = mgr.SQLPassword
};
return target;
}
}
}
#endregion
#region PSRNGSecurity
/// <summary>
/// PSRNGSecurity class
/// <para type="synopsis">MFA Security Management for RNG Keys.</para>
/// <para type="description">MFA Security Management for RNG Keys.</para>
/// </summary>
public class PSRNGSecurity : PSBaseSecurity
{
/// <summary>
/// <para type="description">Used when RNG is selected, for choosing the size of the generated random number (128 to 512 bytes).</para>
/// </summary>
public PSKeyGeneratorMode KeyGenerator { get; set; }
/// <summary>
/// explicit operator from PSRNGSecurity
/// </summary>
public static explicit operator PSRNGSecurity(FlatRNGSecurity mgr)
{
if (mgr == null)
return null;
else
{
PSRNGSecurity target = new PSRNGSecurity
{
KeyGenerator = (PSKeyGeneratorMode)mgr.KeyGenerator
};
return target;
}
}
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator FlatRNGSecurity(PSRNGSecurity mgr)
{
if (mgr == null)
return null;
else
{
FlatRNGSecurity target = new FlatRNGSecurity
{
IsDirty = true,
KeyGenerator = (KeyGeneratorMode)mgr.KeyGenerator
};
return target;
}
}
}
#endregion
#region PSRNGSecurity
/// <summary>
/// PSCustomSecurity class
/// <para type="synopsis">MFA Security Management for Custom Keys.</para>
/// <para type="description">MFA Security Management for Custom Keys.</para>
/// </summary>
public class PSCustomSecurity : PSBaseSecurity
{
/// <summary>
/// <para type="description">Fully Qualified Type for custom security implementation.</para>
/// </summary>
public string CustomFullyQualifiedImplementation { get; set; }
/// <summary>
/// <para type="description">Custom parameters for custom security implementation.</para>
/// </summary>
public string CustomParameters { get; set; }
/// <summary>
/// explicit operator from PSRNGSecurity
/// </summary>
public static explicit operator PSCustomSecurity(FlatCustomSecurity mgr)
{
if (mgr == null)
return null;
else
{
PSCustomSecurity target = new PSCustomSecurity
{
CustomFullyQualifiedImplementation = mgr.CustomFullyQualifiedImplementation,
CustomParameters = mgr.CustomParameters
};
return target;
}
}
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator FlatCustomSecurity(PSCustomSecurity mgr)
{
if (mgr == null)
return null;
else
{
FlatCustomSecurity target = new FlatCustomSecurity
{
IsDirty = true,
CustomFullyQualifiedImplementation = mgr.CustomFullyQualifiedImplementation,
CustomParameters = mgr.CustomParameters
};
return target;
}
}
}
#endregion
#region PSAESSecurity
/// <summary>
/// PSAESSecurity class
/// <para type="synopsis">MFA Security Management for EAS Keys.</para>
/// <para type="description">MFA Security Management for EAS Keys.</para>
/// </summary>
public class PSAESSecurity : PSBaseSecurity
{
/// <summary>
/// <para type="description">Used when AES is selected, choosing between ECDH 256 Key ou custom 256 key (1024 bits).</para>
/// </summary>
public PSAESKeyGeneratorMode AESKeyGenerator { get; set; }
/// <summary>
/// explicit operator from PSAESSecurity
/// </summary>
public static explicit operator PSAESSecurity(FlatAESSecurity mgr)
{
if (mgr == null)
return null;
else
{
PSAESSecurity target = new PSAESSecurity
{
AESKeyGenerator = (PSAESKeyGeneratorMode)mgr.AESKeyGenerator
};
return target;
}
}
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator FlatAESSecurity(PSAESSecurity mgr)
{
if (mgr == null)
return null;
else
{
FlatAESSecurity target = new FlatAESSecurity
{
IsDirty = true,
AESKeyGenerator = (AESKeyGeneratorMode)mgr.AESKeyGenerator
};
return target;
}
}
}
#endregion
#region PSRSASecurity
/// <summary>
/// PSRSASecurity class
/// <para type="synopsis">MFA Security Management.</para>
/// <para type="description">MFA Security Management.</para>
/// </summary>
public class PSRSASecurity : PSBaseSecurity
{
/// <summary>
/// <para type="description">Certificate validity duration in Years (5 by default)</para>
/// </summary>
public int CertificateValidity { get; set; }
/// <summary>
/// <para type="description">Use a distinct certificate for each user when using KeyFormat==RSA. each certificate is deployed on ADDS or SQL Database</para>
/// </summary>
public bool CertificatePerUser { get; set; }
/// <summary>
/// <para type="description">Certificate Thumbprint when using KeyFormat==RSA. the certificate is deployed on all ADFS servers in Crypting Certificates store</para>
/// </summary>
public string CertificateThumbprint { get; set; }
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator PSRSASecurity(FlatRSASecurity mgr)
{
if (mgr == null)
return null;
else
{
PSRSASecurity target = new PSRSASecurity
{
CertificateValidity = mgr.CertificateValidity,
CertificatePerUser = mgr.CertificatePerUser,
CertificateThumbprint = mgr.CertificateThumbprint
};
return target;
}
}
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator FlatRSASecurity(PSRSASecurity mgr)
{
if (mgr == null)
return null;
else
{
FlatRSASecurity target = new FlatRSASecurity
{
IsDirty = true,
CertificateValidity = mgr.CertificateValidity,
CertificatePerUser = mgr.CertificatePerUser,
CertificateThumbprint = mgr.CertificateThumbprint
};
return target;
}
}
}
#endregion
#region PSBiometricSecurity
/// <summary>
/// PSBiometricSecurity class
/// <para type="synopsis">MFA Security Management.</para>
/// <para type="description">MFA Security Management.</para>
/// </summary>
public class PSBiometricSecurity : PSBaseSecurity
{
/// <summary>
/// <para type="description">Authenticator Attachment property (empty, Platform, Crossplatform).</para>
/// </summary>
public PSAuthenticatorAttachmentKind AuthenticatorAttachment { get; set; }
/// <summary>
/// <para type="description">Attestation Conveyance Preference property (None, Direct, Indirect).</para>
/// </summary>
public PSAttestationConveyancePreferenceKind AttestationConveyancePreference { get; set; }
/// <summary>
/// <para type="description">User Verification Requirement property (Preferred, Required, Discouraged).</para>
/// </summary>
public PSUserVerificationRequirementKind UserVerificationRequirement { get; set; }
/// <summary>
/// <para type="description">Extensions property (boolean) supports extensions ?.</para>
/// </summary>
public bool Extensions { get; set; }
/// <summary>
/// <para type="description">User Verification Method property (boolean).</para>
/// </summary>
public bool UserVerificationMethod { get; set; }
/// <summary>
/// <para type="description">Require Resident Key property (boolean).</para>
/// </summary>
public bool RequireResidentKey { get; set; }
/// <summary>
/// <para type="description">False = Use Default MDS3 MetadataRepository, True = Use Contrained MDS3 MetadataRepository, When your ADFS servers doesn't have an Internet access.</para>
/// <para type="description">True = Use Contrained MDS3 MetadataRepository, When your ADFS servers doesn't have an Internet access.</para>
/// <para type="description">You must download the latest MDS3 metadata at "https://mds.fidoalliance.org/".</para>
/// </summary>
public bool ConstrainedMetadataRepository { get; set; }
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator PSBiometricSecurity(FlatBiometricSecurity mgr)
{
if (mgr == null)
return null;
else
{
PSBiometricSecurity target = new PSBiometricSecurity
{
AuthenticatorAttachment = (PSAuthenticatorAttachmentKind)mgr.AuthenticatorAttachment,
AttestationConveyancePreference = (PSAttestationConveyancePreferenceKind)mgr.AttestationConveyancePreference,
UserVerificationRequirement = (PSUserVerificationRequirementKind)mgr.UserVerificationRequirement,
Extensions = mgr.Extensions,
UserVerificationMethod = mgr.UserVerificationMethod,
RequireResidentKey = mgr.RequireResidentKey,
ConstrainedMetadataRepository = mgr.ConstrainedMetadataRepository
};
return target;
}
}
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator FlatBiometricSecurity(PSBiometricSecurity mgr)
{
if (mgr == null)
return null;
else
{
FlatBiometricSecurity target = new FlatBiometricSecurity
{
IsDirty = true,
AuthenticatorAttachment = (FlatAuthenticatorAttachmentKind)mgr.AuthenticatorAttachment,
AttestationConveyancePreference = (FlatAttestationConveyancePreferenceKind)mgr.AttestationConveyancePreference,
UserVerificationRequirement = (FlatUserVerificationRequirementKind)mgr.UserVerificationRequirement,
Extensions = mgr.Extensions,
UserVerificationMethod = mgr.UserVerificationMethod,
RequireResidentKey = mgr.RequireResidentKey,
ConstrainedMetadataRepository = mgr.ConstrainedMetadataRepository
};
return target;
}
}
}
#endregion
#region PSBaseProvider
/// <summary>
/// <para type="synopsis">configuration properties in MFA System.</para>
/// <para type="description">base class for different configuration properties in MFA System.</para>
/// </summary>
public abstract class PSBaseProvider
{
/// <summary>
/// <para type="description">Provider Enabled property.</para>
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// <para type="description">Provider Enrollment Wizard Enabled property.</para>
/// </summary>
public bool EnrollWizard { get; set; }
/// <summary>
/// <para type="description">Provider Force Wizard if user dosen't complete during signing.</para>
/// </summary>
public PSForceWizardMode ForceWizard { get; set; }
/// <summary>
/// <para type="description">Set if additionnal verification with PIN (locally administered) must be done.</para>
/// </summary>
public bool PinRequired { get; set; }
/// <summary>
/// <para type="description">Force users to use this provider (mandatory for registration or not).</para>
/// </summary>
public bool IsRequired { get; set; }
/// <summary>
/// <para type="description">Full qualified implementation class for replacing default provider.</para>
/// </summary>
public string FullQualifiedImplementation { get; set; }
/// <summary>
/// <para type="description">Full qualified implementation parameters for replacing default provider.</para>
/// </summary>
public string Parameters { get; set; }
}
#endregion
#region PSTOTPProvider
/// <summary>
/// PSTOTPProvider class
/// <para type="synopsis">Parameters for TOTP Provider.</para>
/// <para type="description">provided for TOTP MFA.</para>
/// <para type="description">Typically this component is used with authenticator applications, Notification and more.</para>
/// </summary>
public class PSTOTPProvider: PSBaseProvider
{
/// <summary>
/// <para type="description">TOTP Provider Shadow codes. 2 by default</para>
/// </summary>
public int TOTPShadows { get; set; }
/// <summary>
/// <para type="description">TOTP Provider Hash algorithm. SHA1 by default</para>
/// </summary>
public PSHashMode Algorithm { get; set; }
/// <summary>
/// <para type="description">TOTP Provider Code len between 4 and 8. 6 by default</para>
/// </summary>
public int Digits { get; set; }
/// <summary>
/// <para type="description">TOTP Provider Code renew duration in seconds. 30s1 by default</para>
/// </summary>
public int Duration { get; set; }
/// <summary>
/// <para type="description">Set TOP Wizard Application list enabled/ disabled.</para>
/// </summary>
public PSOTPWizardOptions WizardOptions { get; set; }
/// <summary>
/// <para type="description">Type of generated Keys for users (RNG, RSA, CUSTOM RSA).</para>
/// <para type="description">Changing the key format, invalidate all the users secret keys previously used.</para>
/// <para type="description">RSA and RSA Custom are using Certificates. Custom RSA must Use Specific database to the keys and certs, one for each user, see New-MFASecretKeysDatabase cmdlet.</para>
/// </summary>
public PSSecretKeyFormat KeysFormat { get; set; }
/// <summary>
/// <para type="description">Used to trim the key at a fixed size, when you use RSA the key is very long, and QRCode is often too big for TOTP Application (1024 is a good size, even if RSA key is 2048 bytes long).</para>
/// </summary>
public PSKeySizeMode KeySize { get; set; }
/// <summary>
/// explicit operator from PSTOTPProvider
/// </summary>
public static explicit operator PSTOTPProvider(FlatTOTPProvider otp)
{
if (otp == null)
return null;
else
{
PSTOTPProvider target = new PSTOTPProvider
{
Enabled = otp.Enabled,
IsRequired = otp.IsRequired,
EnrollWizard = otp.EnrollWizard,
ForceWizard = (PSForceWizardMode)otp.ForceWizard,
TOTPShadows = otp.TOTPShadows,
Algorithm = (MFA.PSHashMode)otp.Algorithm,
Digits = otp.Digits,
Duration = otp.Duration,
PinRequired = otp.PinRequired,
WizardOptions = (PSOTPWizardOptions)otp.WizardOptions,
FullQualifiedImplementation = otp.FullyQualifiedImplementation,
KeySize = (PSKeySizeMode)otp.KeySize,
KeysFormat = (PSSecretKeyFormat)otp.KeysFormat,
Parameters = otp.Parameters
};
return target;
}
}
/// <summary>
/// explicit operator from FlatOTPProvider
/// </summary>
public static explicit operator FlatTOTPProvider(PSTOTPProvider otp)
{
if (otp == null)
return null;
else
{
FlatTOTPProvider target = new FlatTOTPProvider
{
IsDirty = true,
Enabled = otp.Enabled,
IsRequired = otp.IsRequired,
EnrollWizard = otp.EnrollWizard,
ForceWizard = (ForceWizardMode)otp.ForceWizard,
TOTPShadows = otp.TOTPShadows,
Algorithm = (HashMode)otp.Algorithm,
Digits = otp.Digits,
Duration = otp.Duration,
PinRequired = otp.PinRequired,
WizardOptions = (OTPWizardOptions)otp.WizardOptions,
KeySize = (KeySizeMode)otp.KeySize,
KeysFormat = (SecretKeyFormat)otp.KeysFormat,
FullyQualifiedImplementation = otp.FullQualifiedImplementation,
Parameters = otp.Parameters
};
return target;
}
}
}
#endregion
#region PSMailProvider
/// <summary>
/// PSMailProvider class
/// <para type="synopsis">SMTP configuration properties in MFA System.</para>
/// <para type="description">SMTP/POP configuration properties registered with MFA.</para>
/// <para type="description">You can access, update attributes properties.</para>
/// </summary>
/// <example>
/// <para>Get-MFAProvider -ProviderType Email</para>
/// </example>
public class PSMailProvider: PSBaseProvider
{
/// <summary>
/// <para type="description">Mail from property.</para>
/// </summary>
public string From { get; set; }
/// <summary>
/// <para type="description">Account Name used to access Mail platform.</para>
/// </summary>
public string UserName { get; set; }
/// <summary>
/// <para type="description">Password used with Username to access Mail platform.</para>
/// </summary>
public string Password { get; set; }
/// <summary>
/// <para type="description">Mail platform Host eg : smtp.office365.com.</para>
/// </summary>
public string Host { get; set; }
/// <summary>
/// <para type="description">Mail platform IP Port eg : 587.</para>
/// </summary>
public int Port { get; set; }
/// <summary>
/// <para type="description">Mail platform SSL option.</para>
/// </summary>
public bool UseSSL { get; set; }
/// <summary>
/// <para type="description">Your company description, tis is used in default mails contents.</para>
/// </summary>
public string Company { get; set; }
/// <summary>
/// <para type="description">indicate if connetion is Anonymous.</para>
/// </summary>
public bool Anonymous { get; set; }
/// <summary>
/// <para type="description">if your want Delivery Failures, Delayed delivery or nothing (default).</para>
/// </summary>
public bool DeliveryNotifications { get; set; }
/// <summary>
/// <para type="description">List of domains that are only allowed.</para>
/// </summary>
public PSMailAllowedDomains AllowedDomains { get; internal set; }
/// <summary>
/// <para type="description">List of domains that are not allowed.</para>
/// </summary>
public PSMailBlockedDomains BlockedDomains { get; internal set; }
/// <summary>
/// <para type="description">Custom mail templates.</para>
/// </summary>
public PSMailFileNames MailOTP { get; internal set; }
/// <summary>
/// <para type="description">Custom mail templates.</para>
/// </summary>
public PSMailFileNames MailInscription { get; internal set; }
/// <summary>
/// <para type="description">Custom mail templates.</para>
/// </summary>
public PSMailFileNames MailSecureKey { get; internal set; }
/// <summary>
/// <para type="description">Custom mail templates.</para>
/// </summary>
public PSMailFileNames MailNotifications { get; internal set; }
/// <summary>
/// Constructor
/// </summary>
public PSMailProvider()
{
this.BlockedDomains = new PSMailBlockedDomains();
this.AllowedDomains = new PSMailAllowedDomains();
this.MailOTP = new PSMailFileNames();
this.MailInscription = new PSMailFileNames();
this.MailSecureKey = new PSMailFileNames();
this.MailNotifications = new PSMailFileNames();
}
/// <summary>
/// explicit conversion to PSConfigMail
/// </summary>
public static explicit operator PSMailProvider(FlatMailProvider mails)
{
if (mails == null)
return null;
else
{
PSMailProvider psconfig = new PSMailProvider
{
Enabled = mails.Enabled,
IsRequired = mails.IsRequired,
EnrollWizard = mails.EnrollWizard,
ForceWizard = (PSForceWizardMode)mails.ForceWizard,
From = mails.From,
UserName = mails.UserName,
Password = mails.Password,
Host = mails.Host,
Port = mails.Port,
UseSSL = mails.UseSSL,
Company = mails.Company,
PinRequired = mails.PinRequired,
Anonymous = mails.Anonymous,
DeliveryNotifications = mails.DeliveryNotifications,
FullQualifiedImplementation = mails.FullyQualifiedImplementation,
Parameters = mails.Parameters
};
psconfig.AllowedDomains.Domains.Clear();
foreach (string itm in mails.AllowedDomains.Domains)
{
psconfig.AllowedDomains.AddDomain(itm);
}
psconfig.BlockedDomains.Domains.Clear();
foreach (string itm in mails.BlockedDomains.Domains)
{
psconfig.BlockedDomains.AddDomain(itm);
}
psconfig.MailOTP.Templates.Clear();
foreach (FlatMailFileName itm in mails.MailOTPContent)
{
psconfig.MailOTP.Templates.Add((PSMailFileName)itm);
}
psconfig.MailInscription.Templates.Clear();
foreach (FlatMailFileName itm in mails.MailAdminContent)
{
psconfig.MailInscription.Templates.Add((PSMailFileName)itm);
}
psconfig.MailSecureKey.Templates.Clear();
foreach (FlatMailFileName itm in mails.MailKeyContent)
{
psconfig.MailSecureKey.Templates.Add((PSMailFileName)itm);
}
psconfig.MailNotifications.Templates.Clear();
foreach (FlatMailFileName itm in mails.MailNotifications)
{
psconfig.MailNotifications.Templates.Add((PSMailFileName)itm);
}
return psconfig;
}
}
/// <summary>
/// explicit conversion from PSConfigMail
/// </summary>
public static explicit operator FlatMailProvider(PSMailProvider mails)
{
if (mails == null)
return null;
else
{
FlatMailProvider psconfig = new FlatMailProvider
{
IsDirty = true,
Enabled = mails.Enabled,
IsRequired = mails.IsRequired,
EnrollWizard = mails.EnrollWizard,
ForceWizard = (ForceWizardMode)mails.ForceWizard,
From = mails.From,
UserName = mails.UserName,
Password = mails.Password,
Host = mails.Host,
Port = mails.Port,
UseSSL = mails.UseSSL,
Company = mails.Company,
PinRequired = mails.PinRequired,
Anonymous = mails.Anonymous,
DeliveryNotifications = mails.DeliveryNotifications,
FullyQualifiedImplementation = mails.FullQualifiedImplementation,
Parameters = mails.Parameters
};
psconfig.AllowedDomains.Clear();
foreach (string itm in mails.AllowedDomains.Domains)
{
psconfig.AllowedDomains.AddDomain(itm);
}
psconfig.BlockedDomains.Clear();
foreach (string itm in mails.BlockedDomains.Domains)
{
psconfig.BlockedDomains.AddDomain(itm);
}
psconfig.MailOTPContent.Clear();
foreach (PSMailFileName itm in mails.MailOTP.Templates)
{
psconfig.MailOTPContent.Add((FlatMailFileName)itm);
}
psconfig.MailAdminContent.Clear();
foreach (PSMailFileName itm in mails.MailInscription.Templates)
{
psconfig.MailAdminContent.Add((FlatMailFileName)itm);
}
psconfig.MailKeyContent.Clear();
foreach (PSMailFileName itm in mails.MailSecureKey.Templates)
{
psconfig.MailKeyContent.Add((FlatMailFileName)itm);
}
psconfig.MailNotifications.Clear();
foreach (PSMailFileName itm in mails.MailNotifications.Templates)
{
psconfig.MailNotifications.Add((FlatMailFileName)itm);
}
return psconfig;
}
}
}
/// <summary>
/// PSConfigMailFileName class
/// <para type="synopsis">Mail custom templates used in MFA System.</para>
/// <para type="description">Mail custom templates registered with MFA.</para>
/// </summary>
public class PSMailFileName
{
/// <summary>
/// <para type="description">LCID (1033, 1034, 1036, 3082).</para>
/// </summary>
public int LCID { get; set; }
/// <summary>
/// <para type="description">File path to Html file user as custom template.</para>
/// </summary>
public string FileName { get; set; }
/// <summary>
/// <para type="description">Enabled status for custom template.</para>
/// </summary>
public bool Enabled { get; set; }
/// <summary>
/// Constructor
/// </summary>
public PSMailFileName(int lcid, string filename, bool enabled = true)
{
this.LCID = lcid;
this.FileName = filename;
this.Enabled = enabled;
}
/// <summary>
/// explicit operator
/// </summary>
public static explicit operator PSMailFileName(FlatMailFileName file)
{
if (file == null)
return null;
else
return new PSMailFileName(file.LCID, file.FileName, file.Enabled);
}
/// <summary>
/// explicit operator
/// </summary>
public static explicit operator FlatMailFileName(PSMailFileName file)
{
if (file == null)
return null;
else
return new FlatMailFileName(file.LCID, file.FileName, file.Enabled);
}
}
/// <summary>
/// PSMailFileName class
/// <para type="synopsis">Mail custom templates collection used in MFA System.</para>
/// <para type="description">Mail custom templates collection registered with MFA.</para>
/// </summary>
public class PSMailFileNames
{
private List<PSMailFileName> _list = new List<PSMailFileName>();
/// <summary>
/// <para type="description">Templates property.</para>
/// </summary>
public List<PSMailFileName> Templates
{
get
{
return _list;
}
}
/// <summary>
/// AddTemplate method implmentation
/// </summary>
public void AddTemplate(int lcid, string filename, bool enabled = true)
{
try
{
PSMailFileName item = (from it in _list where it.LCID == lcid select it).FirstOrDefault();
if (item!=null)
throw new Exception("Template already exists !");
_list.Add(new PSMailFileName(lcid, filename, enabled));
}
catch (Exception ex )
{
throw new Exception("Error Adding Template !", ex);
}
}
/// <summary>
/// SetTemplate method implmentation
/// </summary>
public void SetTemplate(int lcid, string filename, bool enabled = true)
{
try
{
PSMailFileName item = (from it in _list where it.LCID == lcid select it).First();
int i = _list.IndexOf(item);
item.FileName = filename;
item.Enabled = enabled;
_list[i] = item;
}
catch (Exception ex)
{
throw new Exception("Template dosen't exists !", ex);
}
}
/// <summary>
/// RemoveTemplate method implmentation
/// </summary>
public void RemoveTemplate(int lcid)
{
try
{
PSMailFileName item = (from it in _list where it.LCID == lcid select it).First();
int i = _list.IndexOf(item);
_list.RemoveAt(i);
}
catch (Exception ex)
{
throw new Exception("Template dosen't exists !", ex);
}
}
/// <summary>
/// ToString method override
/// </summary>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < _list.Count; i++)
{
PSMailFileName item = _list[i];
sb.Append(string.Format("{0} {1} File : {2}", item.Enabled, item.LCID, item.FileName));
if (i < _list.Count-1)
sb.AppendLine();
}
return sb.ToString();
}
}
/// <summary>
/// PSMailBlockedDomains class
/// <para type="synopsis">Mail blocked domains collection used in MFA System.</para>
/// <para type="description">Mail blocked domains collection registered with MFA.</para>
/// </summary>
public class PSMailBlockedDomains
{
private List<string> _list = new List<string>();
/// <summary>
/// <para type="description">BlockedDomains property.</para>
/// </summary>
public List<string> Domains
{
get
{
return _list;
}
}
/// <summary>
/// AddDomain method implmentation
/// </summary>
public void AddDomain(string domainname)
{
try
{
if (_list.Contains(domainname.ToLower()))
throw new Exception("Domain is already int blocked list !");
_list.Add(domainname.ToLower());
}
catch (Exception ex)
{
throw new Exception("Error Adding blocked domain !", ex);
}
}
/// <summary>
/// RemoveDomain method implmentation
/// </summary>
public void RemoveDomain(string domainname)
{
try
{
if (!_list.Contains(domainname.ToLower()))
throw new Exception("Domain not found int blocked list !");
int i = _list.IndexOf(domainname.ToLower());
_list.RemoveAt(i);
}
catch (Exception ex)
{
throw new Exception("Error removing blocked domain !", ex);
}
}
/// <summary>
/// ToString method override
/// </summary>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < _list.Count; i++)
{
string item = _list[i];
sb.Append(item);
if (i < _list.Count - 1)
sb.AppendLine();
}
return sb.ToString();
}
}
/// <summary>
/// PSMailAllowedDomains class
/// <para type="synopsis">Mail allowed domains only collection used in MFA System.</para>
/// <para type="description">Mail allowed domains only collection registered with MFA.</para>
/// </summary>
public class PSMailAllowedDomains
{
private List<string> _list = new List<string>();
/// <summary>
/// <para type="description">AllowedDomains property.</para>
/// </summary>
public List<string> Domains
{
get
{
return _list;
}
}
/// <summary>
/// AddDomain method implmentation
/// </summary>
public void AddDomain(string domainname)
{
try
{
if (_list.Contains(domainname.ToLower()))
throw new Exception("Domain is already int blocked list !");
_list.Add(domainname.ToLower());
}
catch (Exception ex)
{
throw new Exception("Error Adding blocked domain !", ex);
}
}
/// <summary>
/// RemoveDomain method implmentation
/// </summary>
public void RemoveDomain(string domainname)
{
try
{
if (!_list.Contains(domainname.ToLower()))
throw new Exception("Domain not found int blocked list !");
int i = _list.IndexOf(domainname.ToLower());
_list.RemoveAt(i);
}
catch (Exception ex)
{
throw new Exception("Error removing blocked domain !", ex);
}
}
/// <summary>
/// ToString method override
/// </summary>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < _list.Count; i++)
{
string item = _list[i];
sb.Append(item);
if (i < _list.Count - 1)
sb.AppendLine();
}
return sb.ToString();
}
}
#endregion
#region PSExternalProvider
/// <summary>
/// PSExternalProvider class
/// <para type="synopsis">Specify External OTP Provider, you must implement IExternalOTPProvider interface.</para>
/// <para type="description">Samples are provided for Azure and custom.</para>
/// <para type="description">Typically this component is used when sending SMS, you can use your own SMS gateway.</para>
/// </summary>
public class PSExternalProvider: PSBaseProvider
{
/// <summary>
/// <para type="description">your company name, can be used to format External message sent to user.</para>
/// </summary>
public string Company { get; set; }
/// <summary>
/// <para type="description">Optional Salt value, if your gateway support this feature.</para>
/// </summary>
public string Sha1Salt { get; set; }
/// <summary>
/// <para type="description">Pass parameter to your implemented provider, indicating if the mode is Request/Response</para>
/// </summary>
public bool IsTwoWay { get; set; }
/// <summary>
/// <para type="description">TimeOut Before cancelling operation</para>
/// </summary>
public int Timeout { get; set; }
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator PSExternalProvider(FlatExternalProvider otp)
{
if (otp == null)
return null;
else
{
PSExternalProvider target = new PSExternalProvider
{
Enabled = otp.Enabled,
IsRequired = otp.IsRequired,
EnrollWizard = otp.EnrollWizard,
ForceWizard = (MFA.PSForceWizardMode)otp.ForceWizard,
Company = otp.Company,
FullQualifiedImplementation = otp.FullyQualifiedImplementation,
IsTwoWay = otp.IsTwoWay,
Sha1Salt = otp.Sha1Salt,
Timeout = otp.Timeout,
PinRequired = otp.PinRequired,
Parameters = otp.Parameters
};
return target;
}
}
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator FlatExternalProvider(PSExternalProvider otp)
{
if (otp == null)
return null;
else
{
FlatExternalProvider target = new FlatExternalProvider
{
IsDirty = true,
Enabled = otp.Enabled,
IsRequired = otp.IsRequired,
EnrollWizard = otp.EnrollWizard,
ForceWizard = (ForceWizardMode)otp.ForceWizard,
Company = otp.Company,
FullyQualifiedImplementation = otp.FullQualifiedImplementation,
IsTwoWay = otp.IsTwoWay,
Sha1Salt = otp.Sha1Salt,
Timeout = otp.Timeout,
PinRequired = otp.PinRequired,
Parameters = otp.Parameters
};
return target;
}
}
}
#endregion
#region PSAzureProvider
/// <summary>
/// PSAzureProvider class
/// <para type="synopsis">Parameters for Azure MFA Provider.</para>
/// <para type="description">provided for Azure MFA.</para>
/// <para type="description">Typically this component is used when sending SMS, Notification and more.</para>
/// <para type="description">Note : everthing is managed by Microsoft MFA Remotely.</para>
/// </summary>
public class PSAzureProvider: PSBaseProvider
{
/// <summary>
/// <para type="description">your Azure/o365 tenantId / tenant name.</para>
/// </summary>
public string TenantId { get; set; }
/// <summary>
/// <para type="description">Thumbprint of the Azure cetificate (Done when configuring Azure MFA.</para>
/// </summary>
public string Thumbprint { get; set; }
/// <summary>
/// explicit operator from PSConfigAzureProvider
/// </summary>
public static explicit operator PSAzureProvider(FlatAzureProvider otp)
{
if (otp == null)
return null;
else
{
PSAzureProvider target = new PSAzureProvider
{
TenantId = otp.TenantId,
Thumbprint = otp.ThumbPrint,
Enabled = otp.Enabled,
IsRequired = otp.IsRequired,
EnrollWizard = false,
ForceWizard = MFA.PSForceWizardMode.Disabled,
PinRequired = otp.PinRequired,
FullQualifiedImplementation = otp.FullyQualifiedImplementation,
Parameters = otp.Parameters
};
return target;
}
}
/// <summary>
/// explicit operator from MMCKeysConfig
/// </summary>
public static explicit operator FlatAzureProvider(PSAzureProvider otp)
{
if (otp == null)
return null;
else
{
FlatAzureProvider target = new FlatAzureProvider
{
IsDirty = true,
TenantId = otp.TenantId,
ThumbPrint = otp.Thumbprint,
Enabled = otp.Enabled,
IsRequired = otp.IsRequired,
EnrollWizard = false,
ForceWizard = ForceWizardMode.Disabled,
PinRequired = otp.PinRequired,
FullyQualifiedImplementation = otp.FullQualifiedImplementation,
Parameters = otp.Parameters
};
return target;
}
}
}
#endregion
#region PSBiometricProvider
/// <summary>
/// PSBiometricProvider class
/// <para type="synopsis">Parameters for Biometric MFA Provider.</para>
/// <para type="description">provided Biometric MFA.</para>
/// <para type="description">Typically this component is used when using fingerprint or face recognition.</para>
/// </summary>
public class PSBiometricProvider : PSBaseProvider
{
/// <summary>
/// <para type="description">When Biometrics is default method, authentication directly called a first time</para> 3
/// </summary>
public bool DirectLogin { get; set; }
/// <summary>
/// <para type="description">Timeout property (in milliseconds).</para>
/// </summary>
public uint Timeout { get; set; }
/// <summary>
/// <para type="description">Timestamp Drift Tolerance property (in milliseconds).</para>
/// </summary>
public int TimestampDriftTolerance { get; set; }
/// <summary>
/// <para type="description">Challenge Size property (16, 32, 48, 64 bytes) (128, 256, 384, 512 bits).</para>
/// </summary>
public int ChallengeSize { get; set; }
/// <summary>
/// <para type="description">Server Domain property.</para>
/// </summary>
public string ServerDomain { get; set; }
/// <summary>
/// <para type="description">Server Name property.</para>
/// </summary>
public string ServerName { get; set; }
/// <summary>
/// <para type="description">Server Icon property (url).</para>
/// </summary>
public string ServerIcon { get; set; }
/// <summary>
/// <para type="description">Server Uri property (url).</para>
/// </summary>
public string Origin { get; set; }
/// <summary>
/// <para type="description">Pin requirements for unverified biometrics devices.</para>
/// </summary>
public WebAuthNPinRequirements PinRequirements { get; set; }
/// <summary>
/// <para type="description">Name biometric device at registration (NickName).</para>
/// </summary>
public bool UseNickNames { get; set; }
/// <summary>
/// <para type = "description" > Browsers can't use biometric authentication (eg: IE).</para>
/// </summary>
public string ForbiddenBrowsers { get; set; }
/// <summary>
/// <para type = "description" > Operating Systems that can use biometric authentication with user initiated action (eg: Safari for TouchID and FaceID).</para>
/// </summary>
public string InitiatedBrowsers { get; set; }
/// <summary>
/// <para type = "description" > Browsers that require that the counter is always 0 (eg: Safari for TouchID and FaceID).</para>
/// </summary>
public string NoCounterBrowsers { get; set; }
/// <summary>
/// explicit operator from PSConfigBiometricProvider
/// </summary>
public static explicit operator PSBiometricProvider(FlatBiometricProvider otp)
{
if (otp == null)
return null;
else
{
PSBiometricProvider target = new PSBiometricProvider
{
Enabled = otp.Enabled,
IsRequired = otp.IsRequired,
EnrollWizard = otp.EnrollWizard,
ForceWizard = (PSForceWizardMode)otp.ForceWizard,
PinRequired = otp.PinRequired,
PinRequirements = otp.PinRequirements,
DirectLogin = otp.DirectLogin,
UseNickNames = otp.UseNickNames,
FullQualifiedImplementation = otp.FullyQualifiedImplementation,
Parameters = otp.Parameters,
ForbiddenBrowsers = otp.ForbiddenBrowsers,
InitiatedBrowsers = otp.InitiatedBrowsers,
NoCounterBrowsers = otp.NoCounterBrowsers,
Timeout = otp.Timeout,
TimestampDriftTolerance = otp.TimestampDriftTolerance,
ChallengeSize = otp.ChallengeSize,
ServerDomain = otp.ServerDomain,
ServerName = otp.ServerName,
ServerIcon = otp.ServerIcon,
Origin = otp.Origin
};
return target;
}
}
/// <summary>
/// explicit operator for FlatBiometricProvider
/// </summary>
public static explicit operator FlatBiometricProvider(PSBiometricProvider otp)
{
if (otp == null)
return null;
else
{
FlatBiometricProvider target = new FlatBiometricProvider
{
IsDirty = true,
Enabled = otp.Enabled,
IsRequired = otp.IsRequired,
EnrollWizard = otp.EnrollWizard,
ForceWizard = (ForceWizardMode)otp.ForceWizard,
PinRequired = otp.PinRequired,
DirectLogin = otp.DirectLogin,
UseNickNames = otp.UseNickNames,
FullyQualifiedImplementation = otp.FullQualifiedImplementation,
Parameters = otp.Parameters,
ForbiddenBrowsers = otp.ForbiddenBrowsers,
InitiatedBrowsers = otp.InitiatedBrowsers,
NoCounterBrowsers = otp.NoCounterBrowsers,
Timeout = otp.Timeout,
TimestampDriftTolerance = otp.TimestampDriftTolerance,
ChallengeSize = otp.ChallengeSize,
ServerDomain = otp.ServerDomain,
ServerName = otp.ServerName,
ServerIcon = otp.ServerIcon,
Origin = otp.Origin
};
return target;
}
}
}
#endregion
}