Skip to content

Commit

Permalink
Merge pull request #255 from FISHMANPET/p12_cert_password
Browse files Browse the repository at this point in the history
Improved P12 handling
  • Loading branch information
scrthq committed Feb 28, 2020
2 parents 166a23b + 63ee83f commit 988c685
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 11 deletions.
43 changes: 37 additions & 6 deletions PSGSuite/Public/Authentication/New-GoogleService.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,50 @@ function New-GoogleService {
$script:_PSGSuiteSessions[$sessionKey] | Select-Object -ExpandProperty Service
}
else {
if ($script:PSGSuite.P12KeyPath -or $script:PSGSuite.P12Key) {
if ($script:PSGSuite.JSONServiceAccountKey -or $script:PSGSuite.JSONServiceAccountKeyPath) {
Write-Verbose "Building ServiceAccountCredential from JSONServiceAccountKey as user '$User'"
try {
if (-not $script:PSGSuite.JSONServiceAccountKey) {
$script:PSGSuite.JSONServiceAccountKey = ([System.IO.File]::ReadAllBytes($script:PSGSuite.JSONServiceAccountKeyPath))
Set-PSGSuiteConfig -ConfigName $script:PSGSuite.ConfigName -JSONServiceAccountKey $script:PSGSuite.JSONServiceAccountKey -Verbose:$false
}
$stream = New-Object System.IO.MemoryStream $([System.Text.Encoding]::ASCII.GetBytes($script:PSGSuite.JSONServiceAccountKey)), $null
$credential = ([Google.Apis.Auth.OAuth2.GoogleCredential]::FromStream($stream)).CreateWithUser($User).CreateScoped($Scope).UnderlyingCredential
}
catch {
$PSCmdlet.ThrowTerminatingError($_)
}
finally {
if ($stream) {
$stream.Close()
}
}
}
elseif ($script:PSGSuite.P12KeyPath -or $script:PSGSuite.P12Key -or $script:PSGSuite.P12KeyObject) {
try {
Write-Verbose "Building ServiceAccountCredential from P12Key as user '$User'"
if (-not $script:PSGSuite.P12Key) {
$script:PSGSuite.P12Key = ([System.IO.File]::ReadAllBytes($script:PSGSuite.P12KeyPath))
Set-PSGSuiteConfig -ConfigName $script:PSGSuite.ConfigName -P12Key $script:PSGSuite.P12Key -Verbose:$false
if ($script:PSGSuite.P12KeyPath -or $script:PSGSuite.P12Key) {
if (-not $script:PSGSuite.P12Key) {
$script:PSGSuite.P12Key = ([System.IO.File]::ReadAllBytes($script:PSGSuite.P12KeyPath))
Set-PSGSuiteConfig -ConfigName $script:PSGSuite.ConfigName -P12Key $script:PSGSuite.P12Key -Verbose:$false
}
if ($script:PSGSuite.P12KeyPassword) {
$P12KeyPassword = $script:PSGSuite.P12KeyPassword
}
else {
$P12KeyPassword = "notasecret"
}
$certificate = New-Object 'System.Security.Cryptography.X509Certificates.X509Certificate2' -ArgumentList ([System.Byte[]]$script:PSGSuite.P12Key),$P12KeyPassword,([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
}
else {
$certificate = $script:PSGSuite.P12KeyObject
}
$certificate = New-Object 'System.Security.Cryptography.X509Certificates.X509Certificate2' -ArgumentList ([System.Byte[]]$script:PSGSuite.P12Key),"notasecret",([System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)
$credential = New-Object 'Google.Apis.Auth.OAuth2.ServiceAccountCredential' (New-Object 'Google.Apis.Auth.OAuth2.ServiceAccountCredential+Initializer' $script:PSGSuite.AppEmail -Property @{
User = $User
Scopes = [string[]]$Scope
}
).FromCertificate($certificate)

}
catch {
$PSCmdlet.ThrowTerminatingError($_)
Expand Down Expand Up @@ -116,7 +147,7 @@ function New-GoogleService {
}
}
else {
$PSCmdlet.ThrowTerminatingError((ThrowTerm "The current config '$($script:PSGSuite.ConfigName)' does not contain a P12KeyPath or a ClientSecretsPath! PSGSuite is unable to build a credential object for the service without a path to a credential file! Please update the configuration to include a path at least one of the two credential types."))
$PSCmdlet.ThrowTerminatingError((ThrowTerm "The current config '$($script:PSGSuite.ConfigName)' does not contain a JSONServiceAccountKeyPath, P12KeyPath, or ClientSecretsPath! PSGSuite is unable to build a credential object for the service without a path to a credential file! Please update the configuration to include a path at least one of the three credential types."))
}
$svc = New-Object "$ServiceType" (New-Object 'Google.Apis.Services.BaseClientService+Initializer' -Property @{
HttpClientInitializer = $credential
Expand Down
23 changes: 21 additions & 2 deletions PSGSuite/Public/Configuration/Get-PSGSuiteConfig.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ function Get-PSGSuiteConfig {
[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR(
$String))
}
elseif ($String -is [ScriptBlock]) {
$String.InvokeReturnAsIs()
}
else {
$String
}
Expand All @@ -65,14 +68,30 @@ function Get-PSGSuiteConfig {
@{l = 'ConfigName';e = {$choice}},
@{l = 'P12KeyPath';e = {Decrypt $_.P12KeyPath}},
'P12Key',
@{l = 'P12KeyPassword';e = {Decrypt $_.P12KeyPassword}},
@{l = 'P12KeyObject';e = {Decrypt $_.P12KeyObject}},
@{l = 'ClientSecretsPath';e = {Decrypt $_.ClientSecretsPath}},
@{l = 'ClientSecrets';e = {Decrypt $_.ClientSecrets}},
@{l = 'AppEmail';e = {Decrypt $_.AppEmail}},
@{l = 'AppEmail';e = {
if ($_.AppEmail) {
Decrypt $_.ServiceAccountClientID
}
elseif ($_.ClientSecrets) {
(Decrypt $_.ClientSecrets | ConvertFrom-Json).client_email
}
}},
@{l = 'AdminEmail';e = {Decrypt $_.AdminEmail}},
@{l = 'CustomerID';e = {Decrypt $_.CustomerID}},
@{l = 'Domain';e = {Decrypt $_.Domain}},
@{l = 'Preference';e = {Decrypt $_.Preference}},
@{l = 'ServiceAccountClientID';e = {Decrypt $_.ServiceAccountClientID}},
@{l = 'ServiceAccountClientID';e = {
if ($_.ServiceAccountClientID) {
Decrypt $_.ServiceAccountClientID
}
elseif ($_.ClientSecrets) {
(Decrypt $_.ClientSecrets | ConvertFrom-Json).client_id
}
}},
@{l = 'Chat';e = {
$dict = @{
Webhooks = @{}
Expand Down
18 changes: 15 additions & 3 deletions PSGSuite/Public/Configuration/Set-PSGSuiteConfig.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ function Set-PSGSuiteConfig {
.PARAMETER P12Key
The P12Key in byte array format. If the actual P12Key is present on the config, the P12KeyPath is not needed. The config will auto-update with this value after running any command, if P12KeyPath is filled and this value is not already present.
.PARAMETER P12KeyPassword
The password for the P12 Key file. If not specified the default of 'notasecret' will be used and this config value will not be set. This is only needed in the case where the P12 file has been manually rexported with a custom password
.PARAMETER ClientSecretsPath
The path to the Client Secrets JSON file downloaded from the Google Developer's Console. Using the ClientSecrets JSON will prompt the user to complete OAuth2 authentication in their browser on the first run and store the retrieved Refresh and Access tokens in the user's home directory. The config will auto-update with this value after running any command, if ClientSecretsPath is filled and this value is not already present. If P12KeyPath is also specified, ClientSecretsPath will be ignored.
The path to the Client Secrets JSON file downloaded from the Google Developer's Console. Using the ClientSecrets JSON will prompt the user to complete OAuth2 authentication in their browser on the first run and store the retrieved Refresh and Access tokens in the user's home directory. The config will auto-update with this value after running any command, if ClientSecretsPath is filled and this value is not already present. If JSONServiceAccountKeyPath or P12KeyPath is also specified, ClientSecretsPath will be ignored.
.PARAMETER ClientSecrets
The string contents of the Client Secrets JSON file downloaded from the Google Developer's Console. Using the ClientSecrets JSON will prompt the user to complete OAuth2 authentication in their browser on the first run and store the retrieved Refresh and Access tokens in the user's home directory. If P12KeyPath is also specified, ClientSecrets will be ignored.
The string contents of the Client Secrets JSON file downloaded from the Google Developer's Console. Using the ClientSecrets JSON will prompt the user to complete OAuth2 authentication in their browser on the first run and store the retrieved Refresh and Access tokens in the user's home directory. If JSONServiceAccountKeyPath or P12KeyPath is also specified, ClientSecrets will be ignored.
.PARAMETER AppEmail
The application email from the Google Developer's Console. This typically looks like the following:
Expand Down Expand Up @@ -95,6 +98,9 @@ function Set-PSGSuiteConfig {
[Byte[]]
$P12Key,
[parameter(Mandatory = $false,ValueFromPipelineByPropertyName = $true)]
[SecureString]
$P12KeyPassword,
[parameter(Mandatory = $false,ValueFromPipelineByPropertyName = $true)]
[string]
$ClientSecretsPath,
[parameter(Mandatory = $false,ValueFromPipelineByPropertyName = $true)]
Expand Down Expand Up @@ -145,6 +151,9 @@ function Set-PSGSuiteConfig {
elseif ($string -is [System.String] -and $String -notlike '') {
ConvertTo-SecureString -String $string -AsPlainText -Force
}
elseif ($string -is [System.Management.Automation.ScriptBlock]) {
$string
}
}
}
Process {
Expand All @@ -164,7 +173,7 @@ function Set-PSGSuiteConfig {
}
}
Write-Verbose "Setting config name '$ConfigName'"
$configParams = @('P12Key','P12KeyPath','ClientSecretsPath','ClientSecrets','AppEmail','AdminEmail','CustomerID','Domain','Preference','ServiceAccountClientID','Webhook','Space')
$configParams = @('P12Key','P12KeyPath','P12KeyPassword','ClientSecretsPath','ClientSecrets','AppEmail','AdminEmail','CustomerID','Domain','Preference','ServiceAccountClientID','Webhook','Space')
if ($SetAsDefaultConfig -or !$configHash["DefaultConfig"]) {
$configHash["DefaultConfig"] = $ConfigName
}
Expand All @@ -190,6 +199,9 @@ function Set-PSGSuiteConfig {
$configHash["$ConfigName"]['P12Key'] = ([System.IO.File]::ReadAllBytes($PSBoundParameters[$key]))
}
}
P12KeyPassword {
$configHash["$ConfigName"][$key] = $PSBoundParameters[$key]
}
ClientSecretsPath {
if (-not [System.String]::IsNullOrWhiteSpace($PSBoundParameters[$key].Trim())) {
$configHash["$ConfigName"][$key] = (Encrypt $PSBoundParameters[$key])
Expand Down

0 comments on commit 988c685

Please sign in to comment.