From ad8890585cf77ff1a18d3de2d55d5e8fb0b36b7b Mon Sep 17 00:00:00 2001 From: Michael Wenders <1871010+we-mi@users.noreply.github.com> Date: Sun, 23 Jul 2023 22:37:15 +0200 Subject: [PATCH] (#1021) Adds support for authenticated downloads Download-relevant Chocolatey Helper functions are extended with a "Credentials" parameter to enable downloads over HTTP(S) that require authentication. The parameter is then attached to the Microsoft System.Net.HttpWebRequest object to perform the download. Before this change it was not possible to pass credentials for downloads --- .../helpers/functions/Get-ChocolateyWebFile.ps1 | 14 +++++++++----- .../helpers/functions/Get-WebFile.ps1 | 9 ++++++++- .../helpers/functions/Get-WebFileName.ps1 | 9 ++++++++- .../helpers/functions/Get-WebHeaders.ps1 | 9 ++++++++- .../functions/Install-ChocolateyPackage.ps1 | 5 +++++ .../Install-ChocolateyPowershellCommand.ps1 | 6 +++++- .../functions/Install-ChocolateyVsixPackage.ps1 | 6 +++++- .../functions/Install-ChocolateyZipPackage.ps1 | 6 +++++- 8 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/chocolatey.resources/helpers/functions/Get-ChocolateyWebFile.ps1 b/src/chocolatey.resources/helpers/functions/Get-ChocolateyWebFile.ps1 index 772761eae9..c0e21733b5 100644 --- a/src/chocolatey.resources/helpers/functions/Get-ChocolateyWebFile.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-ChocolateyWebFile.ps1 @@ -134,6 +134,9 @@ from the url resource. OPTIONAL switch to force download of file every time, even if the file already exists. +.PARAMETER Credentials +OPTIONAL A System.Net.ICredentials-Object that can be used for downloading files from a server which requires user authentication. + .PARAMETER IgnoredArguments Allows splatting with arguments that do not apply. Do not use directly. @@ -198,6 +201,7 @@ Get-FtpFile [parameter(Mandatory = $false)][hashtable] $options = @{Headers = @{} }, [parameter(Mandatory = $false)][switch] $getOriginalFileName, [parameter(Mandatory = $false)][switch] $forceDownload, + [parameter(Mandatory = $false)][System.Net.ICredentials] $credentials = $null, [parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments ) @@ -287,7 +291,7 @@ Get-FtpFile if ($url.StartsWith('http:')) { try { $httpsUrl = $url.Replace("http://", "https://") - Get-WebHeaders -Url $httpsUrl -ErrorAction "Stop" | Out-Null + Get-WebHeaders -Url $httpsUrl -Credentials $credentials -ErrorAction "Stop" | Out-Null $url = $httpsUrl Write-Warning "Url has SSL/TLS available, switching to HTTPS for download" } @@ -301,7 +305,7 @@ Get-FtpFile $fileFullPath = $fileFullPath -replace '\\chocolatey\\chocolatey\\', '\chocolatey\' $fileDirectory = [System.IO.Path]::GetDirectoryName($fileFullPath) $originalFileName = [System.IO.Path]::GetFileName($fileFullPath) - $fileFullPath = Get-WebFileName -Url $url -DefaultName $originalFileName + $fileFullPath = Get-WebFileName -Url $url -DefaultName $originalFileName -Credentials $credentials $fileFullPath = Join-Path $fileDirectory $fileFullPath $fileFullPath = [System.IO.Path]::GetFullPath($fileFullPath) } @@ -324,7 +328,7 @@ Get-FtpFile $headers = @{} if ($url.StartsWith('http')) { try { - $headers = Get-WebHeaders -Url $url -ErrorAction "Stop" + $headers = Get-WebHeaders -Url $url -Credentials $credentials -ErrorAction "Stop" } catch { if ($PSVersionTable.PSVersion -lt (New-Object 'Version' 3, 0)) { @@ -333,7 +337,7 @@ Get-FtpFile $originalProtocol = [System.Net.ServicePointManager]::SecurityProtocol [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Ssl3 try { - $headers = Get-WebHeaders -Url $url -ErrorAction "Stop" + $headers = Get-WebHeaders -Url $url -Credentials $credentials -ErrorAction "Stop" } catch { Write-Host "Attempt to get headers for $url failed.`n $($_.Exception.Message)" @@ -369,7 +373,7 @@ Get-FtpFile if ($needsDownload) { Write-Host "Downloading $packageName $bitPackage from `'$url`'" - Get-WebFile -Url $url -FileName $fileFullPath -Options $options + Get-WebFile -Url $url -FileName $fileFullPath -Options $options -Credentials $credentials } else { Write-Debug "$($packageName)'s requested file has already been downloaded. Using cached copy at diff --git a/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 b/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 index 774a2ede0f..399413e26a 100644 --- a/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-WebFile.ps1 @@ -66,6 +66,9 @@ Silences the progress output. .PARAMETER Options OPTIONAL - Specify custom headers. +.PARAMETER Credentials +OPTIONAL A System.Net.ICredentials-Object that can be used for downloading files from a server which requires user authentication. + .PARAMETER IgnoredArguments Allows splatting with arguments that do not apply. Do not use directly. @@ -88,6 +91,7 @@ Get-WebFileName [parameter(Mandatory = $false)][switch] $Passthru, [parameter(Mandatory = $false)][switch] $quiet, [parameter(Mandatory = $false)][hashtable] $options = @{Headers = @{} }, + [parameter(Mandatory = $false)][System.Net.ICredentials] $credentials = $null, [parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments ) @@ -110,7 +114,10 @@ Get-WebFileName $req = [System.Net.HttpWebRequest]::Create($url); $defaultCreds = [System.Net.CredentialCache]::DefaultCredentials - if ($defaultCreds -ne $null) { + if ($null -ne $credentials) { + $req.Credentials = $credentials + } + elseif ($defaultCreds -ne $null) { $req.Credentials = $defaultCreds } diff --git a/src/chocolatey.resources/helpers/functions/Get-WebFileName.ps1 b/src/chocolatey.resources/helpers/functions/Get-WebFileName.ps1 index e186e401dc..545904bd1f 100644 --- a/src/chocolatey.resources/helpers/functions/Get-WebFileName.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-WebFileName.ps1 @@ -53,6 +53,9 @@ from the url response. The user agent to use as part of the request. Defaults to 'chocolatey command line'. +.PARAMETER Credentials +OPTIONAL A System.Net.ICredentials-Object that can be used for downloading files from a server which requires user authentication. + .PARAMETER IgnoredArguments Allows splatting with arguments that do not apply. Do not use directly. @@ -69,6 +72,7 @@ Get-ChocolateyWebFile [parameter(Mandatory = $false, Position = 0)][string] $url = '', [parameter(Mandatory = $true, Position = 1)][string] $defaultName, [parameter(Mandatory = $false)][string] $userAgent = 'chocolatey command line', + [parameter(Mandatory = $false)][System.Net.ICredentials] $credentials = $null, [parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments ) @@ -107,7 +111,10 @@ Get-ChocolateyWebFile } $defaultCreds = [System.Net.CredentialCache]::DefaultCredentials - if ($defaultCreds -ne $null) { + if ($null -ne $credentials) { + $request.Credentials = $credentials + } + elseif ($defaultCreds -ne $null) { $request.Credentials = $defaultCreds } diff --git a/src/chocolatey.resources/helpers/functions/Get-WebHeaders.ps1 b/src/chocolatey.resources/helpers/functions/Get-WebHeaders.ps1 index 02cb01d730..edf737a7d8 100644 --- a/src/chocolatey.resources/helpers/functions/Get-WebHeaders.ps1 +++ b/src/chocolatey.resources/helpers/functions/Get-WebHeaders.ps1 @@ -37,6 +37,9 @@ This is the url to get a request/response from. The user agent to use as part of the request. Defaults to 'chocolatey command line'. +.PARAMETER Credentials +OPTIONAL A System.Net.ICredentials-Object that can be used for downloading files from a server which requires user authentication. + .PARAMETER IgnoredArguments Allows splatting with arguments that do not apply. Do not use directly. @@ -52,6 +55,7 @@ Get-WebFile param( [parameter(Mandatory = $false, Position = 0)][string] $url = '', [parameter(Mandatory = $false, Position = 1)][string] $userAgent = 'chocolatey command line', + [parameter(Mandatory = $false)][System.Net.ICredentials] $credentials = $null, [parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments ) @@ -63,7 +67,10 @@ Get-WebFile $request = [System.Net.HttpWebRequest]::Create($url); $defaultCreds = [System.Net.CredentialCache]::DefaultCredentials - if ($defaultCreds -ne $null) { + if ($null -ne $credentials) { + $request.Credentials = $credentials + } + elseif ($defaultCreds -ne $null) { $request.Credentials = $defaultCreds } diff --git a/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 b/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 index 5883432193..bb47f55459 100644 --- a/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 +++ b/src/chocolatey.resources/helpers/functions/Install-ChocolateyPackage.ps1 @@ -217,6 +217,9 @@ be used in place. NOTE: You can also use `Install-ChocolateyInstallPackage` for the same functionality (see links). +.PARAMETER Credentials +OPTIONAL A System.Net.ICredentials-Object that can be used for downloading files from a server which requires user authentication. + .PARAMETER IgnoredArguments Allows splatting with arguments that do not apply. Do not use directly. @@ -364,6 +367,7 @@ Install-ChocolateyZipPackage [alias("useOnlyPackageSilentArgs")][switch] $useOnlyPackageSilentArguments = $false, [parameter(Mandatory = $false)][switch]$useOriginalLocation, [parameter(Mandatory = $false)][scriptblock] $beforeInstall, + [parameter(Mandatory = $false)][System.Net.ICredentials] $credentials = $null, [parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments ) [string]$silentArgs = $silentArgs -join ' ' @@ -413,6 +417,7 @@ Install-ChocolateyZipPackage -Checksum64 $checksum64 ` -ChecksumType64 $checksumType64 ` -Options $options ` + -Credentials $credentials ` -GetOriginalFileName } diff --git a/src/chocolatey.resources/helpers/functions/Install-ChocolateyPowershellCommand.ps1 b/src/chocolatey.resources/helpers/functions/Install-ChocolateyPowershellCommand.ps1 index dba7607c0b..b2cde4363a 100644 --- a/src/chocolatey.resources/helpers/functions/Install-ChocolateyPowershellCommand.ps1 +++ b/src/chocolatey.resources/helpers/functions/Install-ChocolateyPowershellCommand.ps1 @@ -136,6 +136,9 @@ The recommendation is to use at least SHA256. .PARAMETER Options OPTIONAL - Specify custom headers. +.PARAMETER Credentials +OPTIONAL A System.Net.ICredentials-Object that can be used for downloading files from a server which requires user authentication. + .PARAMETER IgnoredArguments Allows splatting with arguments that do not apply. Do not use directly. @@ -187,13 +190,14 @@ Install-ChocolateyZipPackage [parameter(Mandatory = $false)][string] $checksum64 = '', [parameter(Mandatory = $false)][string] $checksumType64 = '', [parameter(Mandatory = $false)][hashtable] $options = @{Headers = @{} }, + [parameter(Mandatory = $false)][System.Net.ICredentials] $credentials = $null, [parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments ) Write-FunctionCallLogMessage -Invocation $MyInvocation -Parameters $PSBoundParameters if ($url -ne '') { - Get-ChocolateyWebFile $packageName $psFileFullPath $url $url64bit -checksum $checksum -checksumType $checksumType -checksum64 $checksum64 -checksumType64 $checksumType64 -Options $options + Get-ChocolateyWebFile $packageName $psFileFullPath $url $url64bit -checksum $checksum -checksumType $checksumType -checksum64 $checksum64 -checksumType64 $checksumType64 -Options $options -Credentials $credentials } if ($env:chocolateyPackageName -ne $null -and $env:chocolateyPackageName -eq $env:ChocolateyInstallDirectoryPackage) { diff --git a/src/chocolatey.resources/helpers/functions/Install-ChocolateyVsixPackage.ps1 b/src/chocolatey.resources/helpers/functions/Install-ChocolateyVsixPackage.ps1 index 1048c72b56..777d946425 100644 --- a/src/chocolatey.resources/helpers/functions/Install-ChocolateyVsixPackage.ps1 +++ b/src/chocolatey.resources/helpers/functions/Install-ChocolateyVsixPackage.ps1 @@ -107,6 +107,9 @@ Will be used for VsixUrl if VsixUrl is empty. This parameter provides compatibility, but should not be used directly and not with the community package repository until January 2018. +.PARAMETER Credentials +OPTIONAL A System.Net.ICredentials-Object that can be used for downloading files from a server which requires user authentication. + .PARAMETER IgnoredArguments Allows splatting with arguments that do not apply. Do not use directly. @@ -144,6 +147,7 @@ Install-ChocolateyZipPackage [parameter(Mandatory = $false)][string] $checksumType = '', [parameter(Mandatory = $false)][hashtable] $options = @{Headers = @{} }, [alias("fileFullPath")][parameter(Mandatory = $false)][string] $file = '', + [parameter(Mandatory = $false)][System.Net.ICredentials] $credentials = $null, [parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments ) @@ -193,7 +197,7 @@ Install-ChocolateyZipPackage if ($installer) { $download = "$env:TEMP\$($packageName.Replace(' ','')).vsix" try { - Get-ChocolateyWebFile $packageName $download $vsixUrl -checksum $checksum -checksumType $checksumType -Options $options + Get-ChocolateyWebFile $packageName $download $vsixUrl -checksum $checksum -checksumType $checksumType -Options $options -Credentials $credentials } catch { throw "There were errors attempting to retrieve the vsix from $vsixUrl. The error message was '$_'." diff --git a/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 b/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 index 1d956418dd..20c8044d25 100644 --- a/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 +++ b/src/chocolatey.resources/helpers/functions/Install-ChocolateyZipPackage.ps1 @@ -159,6 +159,9 @@ Usage of this parameter will prevent Uninstall-ChocolateyZipPackage from working, extracted files will have to be cleaned up with Remove-Item or a similar command instead. +.PARAMETER Credentials +OPTIONAL A System.Net.ICredentials-Object that can be used for downloading files from a server which requires user authentication. + .PARAMETER IgnoredArguments Allows splatting with arguments that do not apply. Do not use directly. @@ -200,6 +203,7 @@ Get-ChocolateyUnzip [alias("fileFullPath")][parameter(Mandatory = $false)][string] $file = '', [alias("fileFullPath64")][parameter(Mandatory = $false)][string] $file64 = '', [parameter(Mandatory = $false)][switch] $disableLogging, + [parameter(Mandatory = $false)][System.Net.ICredentials] $credentials = $null, [parameter(ValueFromRemainingArguments = $true)][Object[]] $ignoredArguments ) @@ -225,6 +229,6 @@ Get-ChocolateyUnzip $url64bit = $file64 } - $filePath = Get-ChocolateyWebFile $packageName $downloadFilePath $url $url64bit -checkSum $checkSum -checksumType $checksumType -checkSum64 $checkSum64 -checksumType64 $checksumType64 -options $options -getOriginalFileName + $filePath = Get-ChocolateyWebFile $packageName $downloadFilePath $url $url64bit -checkSum $checkSum -checksumType $checksumType -checkSum64 $checkSum64 -checksumType64 $checksumType64 -options $options -getOriginalFileName -Credentials $credentials Get-ChocolateyUnzip "$filePath" $unzipLocation $specificFolder $packageName -disableLogging:$disableLogging }