Get-xHashiCorp_Vault_ClientToken.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<#
     .SYNOPSIS
        Retrieves HashiCorp Vaul Client token from OIDC Auth provider.
    .DESCRIPTION
        Retrieves HashiCorp Vaul Client token from OIDC Auth provider which allows to query HashiCorp Vault for secrets.
        Dependencies:
            * System which executes a script must have Microsoft Framework 4.6.1 and above installed.
            * SecureMFA_SupportTools.dll file must be present in script directory.
            * SecureMFA_SupportTools.json configuration file must be present in script directory.
                                     
            Below is Json config file sections which needs to be updated with your environment settings:
                {
                    "serialkey": "f01145697",
                    "hashicorp_auth_endpoint": "http://hscvault.adatum.labnet:8200/v1/auth/oidc/oidc/auth_url",
                    "hashicorp_token_endpoint": "http://hscvault.adatum.labnet:8200/v1/auth/oidc/oidc/callback",
                    "hashicorp_oidc_role": "kv-mgr9",
                    "hashicorp_oidc_uri": "uri:securemfa:testapp2:nativeapp:test",
                    "proxy_server": "http://proxy.adatum.labnet:8080",
                    "proxy_bypass_localaddresses": "false"
                }
 
    .PARAMETER ProxyFromConfig
        Decryption parameter is required for systems which use secret key encryption with AES256.
        ‘encryption_passphrase’ value must match setting which is defined in SecureMFA OTP provider configuration. Otherwise displayed OTP codes will not be valid.
 
    .NOTES
        Version: 1.0.0.3
        Author: SecureMfa.com
        Creation Date: 01/10/2019
        Purpose/Change: Incorporated into module
   
    .EXAMPLE
        C:\PS> Get-xHashiCorp_Vault_ClientToken
 
        This command will retrieve client token from HashiCorp Vault using OIDC auth configuration.
 
    .EXAMPLE
        C:\PS> Get-xHashiCorp_Vault_ClientToken -Proxy SystemDefaults
          
        This command will execute CLI commands using default systems proxy settings.
 
    .EXAMPLE
        C:\PS> Get-xHashiCorp_Vault_ClientToken -Proxy UseConfig
          
        This command will execute CLI commands using proxy settings from SecureMFA PS Module json config file.
     
    .EXAMPLE
        C:\PS> Get-xHashiCorp_Vault_ClientToken -Proxy none
          
        This command will execute CLI commands without proxy settings.
     
#>


#>

Function Get-xHashiCorp_Vault_ClientToken {
Param
(
    [Parameter(Mandatory=$false)]
    [ValidateSet('SystemDefaults','UseConfig','none')]
    [string]$Proxy='SystemDefaults'
)

DynamicParam
{
    # create a dictionary to return, and collection of parameters
    $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
    $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
 
    # create a new [string] parameter for all parameter sets, and decorate with a [ValidateSet]
    $dynParam = New-Object -Type System.Management.Automation.RuntimeDefinedParameter("Profile", [String], $attributeCollection)
    $attributes = New-Object System.Management.Automation.ParameterAttribute
    $fname = "Profiles.json"
    $paramOptions = New-Object System.Management.Automation.ValidateSetAttribute -ArgumentList (ConvertFrom-Json (Get-Content (join-path $PSScriptRoot $fname) -Raw))
 
    $attributeCollection.Add($attributes)
    $attributeCollection.Add($paramOptions)
    $paramDictionary.Add("Profile", $dynParam)
 
    return $paramDictionary
}

Process
{
    #Static Parameters
    $Event_Source = "SecureMFA_SupportTools"
    #Checking Dependencies
    #EventLog source dependency
    $ErrMsg = "ResetOTP EventLog source is missing. Please execute following PS command 'New-EventLog -Source SecureMFA_SupportTools -LogName Application' on the system before using the app."
    if (((Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Application).pschildname | where { $_ -eq $Event_Source} | measure).Count -eq 0) 
    {write-host $ErrMsg -ForegroundColor red; pause; break}
    #Config file dependency
    if ( $PSBoundParameters.Keys.Contains("Profile") )
    {
        $configfile = (Join-Path -Path $PSScriptRoot -ChildPath ($PSBoundParameters.Profile + '_SecureMFA_SupportTools.json'))
    }
    else {$configfile = (Join-Path -Path $PSScriptRoot -ChildPath SecureMFA_SupportTools.json)}
    #Test config file path.
    $ErrMsg = "$configfile file is missing. Please copy a file to script directory and try again."
    if (!(Test-Path $configfile)) { write-host $ErrMsg -ForegroundColor red; pause; break }
    #DLL file dependency
    $dllpath = (Join-Path -Path $PSScriptRoot -ChildPath SecureMFA_SupportTools.dll)
    $ErrMsg = "$configfile file is missing. Please copy a file to script directory and try again."
    if (!(Test-Path $dllpath)) { write-host $ErrMsg -ForegroundColor red; pause; break }

    #Read JSON file Configuration
    $json = Get-Content -Raw $configfile | ConvertFrom-Json
    $serialkey = $json.serialkey
    $hashicorp_auth_endpoint = $json.hashicorp_auth_endpoint
    $hashicorp_token_endpoint = $json.hashicorp_token_endpoint
    $hashicorp_oidc_role = $json.hashicorp_oidc_role
    $hashicorp_oidc_uri = $json.hashicorp_oidc_uri
    $webproxy = $json.proxy_server
    $bypassproxyonlocal; if($json.proxy_bypass_localaddresses -eq "true") {$bypassproxyonlocal = 1} else {$bypassproxyonlocal = 0}

    Try {

        [System.Reflection.Assembly]::LoadFile($dllpath) | Out-Null    
        [string]$access_token = $null

        #Set proxy settings for CLI
        if ($proxy -eq 'UseConfig') 
            {
            [system.net.webrequest]::defaultwebproxy = new-object system.net.webproxy($webproxy)
            [system.net.webrequest]::defaultwebproxy.credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
            [system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = $bypassproxyonlocal
            }
        elseif ($proxy -eq 'none') {netsh winhttp reset proxy | out-null ; [system.net.webrequest]::defaultwebproxy = $null}
        else {netsh winhttp import proxy source=ie | out-null}

        #Retreve client token using Hasicorp Vaul OIDC auth flow
        $atoken = [SecureMFA_SupportTools.IDPAUTH]::RetrieveHashicorpAccesToken($hashicorp_auth_endpoint, $hashicorp_oidc_role, $hashicorp_oidc_uri,$hashicorp_token_endpoint,$serialkey,[ref]$access_token) | Out-String

        try {$hashiauthtoken = ConvertFrom-Json $access_token -ErrorAction Stop;$validJson = $true;} catch {$validJson = $false;}
    
        #Validate client token
        $client_token = $access_token 
        $token = $null

        if ($validJson) {
            $client_token = $hashiauthtoken.auth.client_token
            write-host "Issued Hashicorp Vault client token: $client_token" -ForegroundColor Cyan
            #Return client token as auth header object for API
            $token = @{"X-Vault-Token" = "$client_token"}
        }  
    
        return $atoken,$token

        }

    #On error acction
    catch [System.Exception] { 
            $completed = get-date
            $line = $_.InvocationInfo.ScriptLineNumber
            $msg = $_.Exception.Message 

            Write-Host -ForegroundColor Red "Error: $msg"
            Write-EventLog –LogName Application –Source $Event_Source –EntryType Error –EventID 5559 –Message “$msg Executed by: $env:username Computer: $env:computername Line: $line”                 
            }    

    pause
    }
}