Install-SecureMFA_WIN_OTP_AuthenticationProvider.ps1

#Requires -RunAsAdministrator

<#
     .SYNOPSIS
        Installs SecureMFA WIN Authentication Provider.
    .DESCRIPTION
        SecureMFA WIN Authentication Provider is a wrapping of OTP authentication on existing Microsoft provider which comes by default with Windows operating system. This allows to request MFA authentication during normal windows logon operations.
 
        Dependencies:
            * Supported Windows x64 platforms only.
            * Server OS minimal version must be Windows 2016.
            * Client OS minimal version must be Windows 10.
 
  
    .NOTES
        Version: 2.0.0.1
        Author: SecureMfa.com
        Creation Date: 28/09/2020
        Purpose/Change: New release.
   
    .EXAMPLE
        C:\PS> Install-SecureMFA_WIN_OTP_AuthenticationProvider -anchordnsname "adatum.labnet" -RDPonly $true -api_endpoint �https://awebapi.adatum.labnet/api/securemfaotp�
 
        Installs SecureMFA WIN OTP Provider on Windows for RDP sessions only (Console access is not affected) and points provider to API endpoint URL which is used for OTP codes validations.
        To lock down Windows OS with MFA for all sessions you must use -RDPonly $false parameter.
        Anchor parameter specifies OTP user�s suffix which is used in �SecureMfaOTP� database.
    
#>



#Check if windows events source for application log exist, if not create one.
if ([System.Diagnostics.EventLog]::SourceExists("SecureMFA WIN OTP") -eq $False) {New-EventLog -LogName "Application" -Source "SecureMFA WIN OTP" ; Write-Host "SecureMFA WIN OTP Log Source Created."}

Function Install-SecureMFA_WIN_OTP_AuthenticationProvider {
Param
(
    [Parameter(Mandatory=$false)][string]$anchordnsname = "adatum.labnet",
    [Parameter(Mandatory=$false)][string]$serialkey = "m000000",
    [Parameter(Mandatory=$false)][string]$subscriptionid = "1000000000000000000000001",
    [Parameter(Mandatory=$false)][string]$api_endpoint = "https://awebapi.adatum.labnet/api/securemfaotp",
    [Parameter(Mandatory=$false)][string]$sspr_url = "none",
    [Parameter(Mandatory=$false)][int]$api_timeout = 5000,
    [Parameter(Mandatory=$false)][bool]$RDPonly = $false, 
    [Parameter(Mandatory=$false)][int]$totp_offline_secret_valid_days = 0,
    [Parameter(Mandatory=$false)][int]$totp_offline_ui_login_failures = 0,
    [Parameter(Mandatory=$false)][int]$totp_offline_ui_lockout_minutes = 5,
    [Parameter(Mandatory=$false)][string]$data_encryption_passphrase = "d9GhT=7=Ox8-+LaZ",
    [Parameter(Mandatory=$false)][string]$api_headers_value = "P4WK6mUMgL6ztXtiJUurA3Fhn5Xjbejy1ZAhwokT",
    [Parameter(Mandatory=$false)][bool]$api_proxy_enable = $false,
    [Parameter(Mandatory=$false)][string]$api_proxy_server = "proxy.adatum.labnet",
    [Parameter(Mandatory=$false)][int]$api_proxy_port = 8080,
    [Parameter(Mandatory=$false)][bool]$verboselog = $false,
    [Parameter(Mandatory=$false)][Switch]$Force
)
    
     
    try
    {
        $Error.Clear()
        $provider_dll = (Join-Path -Path $PSScriptRoot -ChildPath sMFAWINAuthenticationProvider.dll) 
        $provider_dll_version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$provider_dll").FileVersion

        $provider_wintools_dll = (Join-Path -Path $PSScriptRoot -ChildPath SecureMFA_WinTools.dll)
        $provider_wintools_dll_version = [System.Diagnostics.FileVersionInfo]::GetVersionInfo("$provider_wintools_dll").FileVersion

        #Use default Change Password URL if none provided
        $ssprurl 
        if($sspr_url -eq "none") {$ssprurl = $api_endpoint.Split('/')[0] + '//' + $api_endpoint.Split('/')[2]} else {$ssprurl = $sspr_url}

        Write-Host "Provider File: $provider_dll"
        Write-Host "Provider Version: $provider_dll_version"
        Write-Host "Provider Windows Tools File: $provider_wintools_dll"
        Write-Host "Provider Windows Tools Version: $provider_wintools_dll_version"
        Write-Host "Provider Change Password link URL: $ssprurl" 

        write-host $provider_dll
        if (!(Test-Path $provider_dll -Type Leaf) ) { throw "$provider_dll does not exist." ; break}
        if (!(Test-Path $provider_wintools_dll -Type Leaf) ) { throw "$provider_wintools_dll does not exist." ; break}

        #Start deployment
        write-host "Creating SecureMFA WIN Authentication Provider registry entries" -ForegroundColor Yellow

        if((Test-Path -LiteralPath "HKLM:\SOFTWARE\SecureMFA") -ne $true) {  New-Item "HKLM:\SOFTWARE\SecureMFA" -force -ea SilentlyContinue };
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_anchordnsname' -Value $anchordnsname -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_serialkey' -Value $serialkey -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_subscriptionid' -Value $subscriptionid -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_api_endpoint' -Value $api_endpoint -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_ssprurl' -Value $ssprurl -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_api_timeout' -Value $api_timeout -PropertyType DWord -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_rdponly' -Value $RDPonly -PropertyType DWord -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_totp_offline_secret_valid_days' -Value $totp_offline_secret_valid_days -PropertyType DWord -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_totp_offline_ui_login_failures' -Value $totp_offline_ui_login_failures -PropertyType DWord -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_totp_offline_ui_lockout_minutes' -Value $totp_offline_ui_lockout_minutes -PropertyType DWord -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_data_encryption_passphrase' -Value $data_encryption_passphrase -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_api_headers_value' -Value $api_headers_value -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_api_proxy_enable' -Value $api_proxy_enable -PropertyType DWord -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_api_proxy_server' -Value $api_proxy_server -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_api_proxy_port' -Value $api_proxy_port -PropertyType DWord -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\SecureMFA' -Name 'win_verboselog' -Value $verboselog -PropertyType DWord -Force -ea SilentlyContinue;        
        
        #Load GAC Assembly
        Set-location $PSScriptRoot            
        [System.Reflection.Assembly]::Load("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") 
        $publish = New-Object System.EnterpriseServices.Internal.Publish

        #Remove SecureMFA Windows Tools DLL from GAC assembly
        $publish.GacRemove($provider_wintools_dll)       

        #Add SecureMFA Windows Tools DLL to GAC assembly
        Write-Host "GAC Install: $provider_wintools_dll" -ForegroundColor yellow;         
        $publish.GacInstall($provider_wintools_dll)  

        #Register SecureMFA Windows Tools
        New-Item "HKLM:\SOFTWARE\Classes\SecureMFA_WinTools.SecureMFAWINCOM_Class" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\SecureMFA_WinTools.SecureMFAWINCOM_Class\CLSID" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\InprocServer32" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\InprocServer32\$provider_wintools_dll_version" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\ProgId" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\SecureMFA_WinTools.OTP" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\SecureMFA_WinTools.OTP\CLSID" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\InprocServer32" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\InprocServer32\$provider_wintools_dll_version" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\ProgId" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}" -force -ea SilentlyContinue
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\SecureMFA_WinTools.SecureMFAWINCOM_Class" -Name "(default)" -Value "SecureMFA_WinTools.SecureMFAWINCOM_Class" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\SecureMFA_WinTools.SecureMFAWINCOM_Class\CLSID" -Name "(default)" -Value "{70A8A539-0204-4DB6-B52A-3B467A7F41A3}" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}" -Name "(default)" -Value "SecureMFA_WinTools.SecureMFAWINCOM_Class" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\InprocServer32" -Name "(default)" -Value "mscoree.dll" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\InprocServer32" -Name "ThreadingModel" -Value "Both" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\InprocServer32" -Name "Class" -Value "SecureMFA_WinTools.SecureMFAWINCOM_Class" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\InprocServer32" -Name "Assembly" -Value "SecureMFA_WinTools, Version=$provider_wintools_dll_version, Culture=neutral, PublicKeyToken=f1c44194ebb1b5d8" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\InprocServer32" -Name "RuntimeVersion" -Value "v4.0.30319" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\InprocServer32\$provider_wintools_dll_version" -Name "Class" -Value "SecureMFA_WinTools.SecureMFAWINCOM_Class" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\InprocServer32\$provider_wintools_dll_version" -Name "Assembly" -Value "SecureMFA_WinTools, Version=$provider_wintools_dll_version, Culture=neutral, PublicKeyToken=f1c44194ebb1b5d8" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\InprocServer32\$provider_wintools_dll_version" -Name "RuntimeVersion" -Value "v4.0.30319" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{70A8A539-0204-4DB6-B52A-3B467A7F41A3}\ProgId" -Name "(default)" -Value "SecureMFA_WinTools.SecureMFAWINCOM_Class" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\SecureMFA_WinTools.OTP" -Name "(default)" -Value "SecureMFA_WinTools.OTP" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\SecureMFA_WinTools.OTP\CLSID" -Name "(default)" -Value "{98E41317-0C68-3030-90A6-28EF09F61444}" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}" -Name "(default)" -Value "SecureMFA_WinTools.OTP" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\InprocServer32" -Name "(default)" -Value "mscoree.dll" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\InprocServer32" -Name "ThreadingModel" -Value "Both" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\InprocServer32" -Name "Class" -Value "SecureMFA_WinTools.OTP" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\InprocServer32" -Name "Assembly" -Value "SecureMFA_WinTools, Version=$provider_wintools_dll_version, Culture=neutral, PublicKeyToken=f1c44194ebb1b5d8" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\InprocServer32" -Name "RuntimeVersion" -Value "v4.0.30319" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\InprocServer32\$provider_wintools_dll_version" -Name "Class" -Value "SecureMFA_WinTools.OTP" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\InprocServer32\$provider_wintools_dll_version" -Name "Assembly" -Value "SecureMFA_WinTools, Version=$provider_wintools_dll_version, Culture=neutral, PublicKeyToken=f1c44194ebb1b5d8" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\InprocServer32\$provider_wintools_dll_version" -Name "RuntimeVersion" -Value "v4.0.30319" -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath "HKLM:\SOFTWARE\Classes\CLSID\{98E41317-0C68-3030-90A6-28EF09F61444}\ProgId" -Name "(default)" -Value "SecureMFA_WinTools.OTP" -PropertyType String -Force -ea SilentlyContinue;

        #Copy provider file into system directory
        Copy-Item $provider_dll -Destination ([Environment]::SystemDirectory + "\sMFAWINAuthenticationProvider.dll") -force

        #Register SecureMFA WIN Authentication Provider
        New-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{85A8E189-2C6F-44CF-AE85-4FD6220589DE}" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{85A8E189-2C6F-44CF-AE85-4FD6220589DE}" -force -ea SilentlyContinue 
        New-Item "HKLM:\SOFTWARE\Classes\CLSID\{85A8E189-2C6F-44CF-AE85-4FD6220589DE}\InprocServer32" -force -ea SilentlyContinue
        New-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filters\{85A8E189-2C6F-44CF-AE85-4FD6220589DE}" -force -ea SilentlyContinue
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers\{85A8E189-2C6F-44CF-AE85-4FD6220589DE}' -Name '(default)' -Value 'sMFAWINAuthenticationProvider' -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\Classes\CLSID\{85A8E189-2C6F-44CF-AE85-4FD6220589DE}' -Name '(default)' -Value 'sMFAWINAuthenticationProvider' -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\Classes\CLSID\{85A8E189-2C6F-44CF-AE85-4FD6220589DE}\InprocServer32' -Name '(default)' -Value 'sMFAWINAuthenticationProvider.dll' -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\Classes\CLSID\{85A8E189-2C6F-44CF-AE85-4FD6220589DE}\InprocServer32' -Name 'ThreadingModel' -Value 'Apartment' -PropertyType String -Force -ea SilentlyContinue;
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Provider Filters\{85A8E189-2C6F-44CF-AE85-4FD6220589DE}' -Name '(default)' -Value 'sMFAWINAuthenticationProvider' -PropertyType String -Force -ea SilentlyContinue;

         # Set windows fallback settings
        New-ItemProperty -LiteralPath 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\Credential Providers' -Name 'ProhibitFallbacks' -Value 1 -PropertyType DWord -Force -ea SilentlyContinue;

        Write-host "SecureMFA WIN Authentication Provider has been installed." -ForegroundColor Green
        Get-ItemProperty -Path 'HKLM:\SOFTWARE\SecureMFA' -Name win*
    }
    catch
    {
        Write-Host "$($MyInvocation.InvocationName): $_" -ForegroundColor red
    }    


}