Commit 95fb6dc8 authored by Vadim Shtayura's avatar Vadim Shtayura Committed by Commit Bot

[cipd] Check CIPD client hash during updates on Windows.

This is Windows counterpart to https://chromium-review.googlesource.com/1171957

Also cleanup code style in cipd.ps1 script. It appears the common convention
for global variables in PowerShell is $GlobalVar and for locals is $localVar.

R=nodir@chromium.org, iannucci@chromium.org
BUG=870166

Change-Id: Ib8ffbad85497db31f7f5d44fdca6ed843e56f220
Reviewed-on: https://chromium-review.googlesource.com/1175248
Commit-Queue: Vadim Shtayura <vadimsh@chromium.org>
Reviewed-by: 's avatarNodir Turakulov <nodir@chromium.org>
parent efb38bb3
...@@ -5,15 +5,16 @@ ...@@ -5,15 +5,16 @@
setlocal setlocal
set CIPD_CLIENT_SRV=https://chrome-infra-packages.appspot.com set CIPD_BACKEND=https://chrome-infra-packages.appspot.com
for /f %%i in (%~dp0cipd_client_version) do set CIPD_CLIENT_VER=%%i set VERSION_FILE="%~dp0cipd_client_version"
set CIPD_BINARY="%~dp0.cipd_client.exe"
if not exist "%~dp0.cipd_client.exe" ( if not exist %CIPD_BINARY% (
call :CLEAN_BOOTSTRAP call :CLEAN_BOOTSTRAP
goto :EXEC_CIPD goto :EXEC_CIPD
) )
call :SELF_UPDATE call :SELF_UPDATE >nul 2>&1
if %ERRORLEVEL% neq 0 ( if %ERRORLEVEL% neq 0 (
echo CIPD client self-update failed, trying to bootstrap it from scratch... 1>&2 echo CIPD client self-update failed, trying to bootstrap it from scratch... 1>&2
call :CLEAN_BOOTSTRAP call :CLEAN_BOOTSTRAP
...@@ -25,7 +26,7 @@ if %ERRORLEVEL% neq 0 ( ...@@ -25,7 +26,7 @@ if %ERRORLEVEL% neq 0 (
echo Failed to bootstrap or update CIPD client 1>&2 echo Failed to bootstrap or update CIPD client 1>&2
) )
if %ERRORLEVEL% equ 0 ( if %ERRORLEVEL% equ 0 (
"%~dp0.cipd_client.exe" %* "%CIPD_BINARY%" %*
) )
endlocal & ( endlocal & (
...@@ -46,7 +47,12 @@ exit /b %EXPORT_ERRORLEVEL% ...@@ -46,7 +47,12 @@ exit /b %EXPORT_ERRORLEVEL%
:: alternate data stream. This is equivalent to clicking the "Unblock" button :: alternate data stream. This is equivalent to clicking the "Unblock" button
:: in the file's properties dialog. :: in the file's properties dialog.
echo.>%~dp0cipd.ps1:Zone.Identifier echo.>%~dp0cipd.ps1:Zone.Identifier
powershell -NoProfile -ExecutionPolicy RemoteSigned -Command "%~dp0cipd.ps1" < nul powershell -NoProfile -ExecutionPolicy RemoteSigned ^
-Command "%~dp0cipd.ps1" ^
-CipdBinary "%CIPD_BINARY%" ^
-BackendURL "%CIPD_BACKEND%" ^
-VersionFile "%VERSION_FILE%" ^
<nul
if %ERRORLEVEL% equ 0 ( if %ERRORLEVEL% equ 0 (
:: Need to call SELF_UPDATE to setup .cipd_version file. :: Need to call SELF_UPDATE to setup .cipd_version file.
call :SELF_UPDATE call :SELF_UPDATE
...@@ -55,5 +61,7 @@ exit /B %ERRORLEVEL% ...@@ -55,5 +61,7 @@ exit /B %ERRORLEVEL%
:SELF_UPDATE :SELF_UPDATE
"%~dp0.cipd_client.exe" selfupdate -version "%CIPD_CLIENT_VER%" -service-url "%CIPD_CLIENT_SRV%" "%CIPD_BINARY%" selfupdate ^
-version-file "%VERSION_FILE%" ^
-service-url "%CIPD_BACKEND%"
exit /B %ERRORLEVEL% exit /B %ERRORLEVEL%
...@@ -2,72 +2,117 @@ ...@@ -2,72 +2,117 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
$myPath = Split-Path $MyInvocation.MyCommand.Path -Parent Param(
# Path to download the CIPD binary to.
[parameter(Mandatory=$true)][string]$CipdBinary,
# E.g. "https://chrome-infra-packages.appspot.com".
[parameter(Mandatory=$true)][string]$BackendURL,
# Path to the cipd_client_version file with the client version.
[parameter(Mandatory=$true)][string]$VersionFile
)
function GetEnvVar([string] $key, [scriptblock] $defaultFn) { $DepotToolsPath = Split-Path $MyInvocation.MyCommand.Path -Parent
if (Test-Path "Env:\$key") {
return (Get-ChildItem "Env:\$key").Value
}
return $defaultFn.Invoke()
}
$cipdClientVer = GetEnvVar "CIPD_CLIENT_VER" {
Get-Content (Join-Path $myPath -ChildPath 'cipd_client_version') -TotalCount 1
}
$cipdClientSrv = GetEnvVar "CIPD_CLIENT_SRV" {
"https://chrome-infra-packages.appspot.com"
}
$plat="windows" if ([System.IntPtr]::Size -eq 8) {
if ([environment]::Is64BitOperatingSystem) { $Platform = "windows-amd64"
$arch="amd64"
} else { } else {
$arch="386" $Platform = "windows-386"
} }
$url = "$cipdClientSrv/client?platform=$plat-$arch&version=$cipdClientVer" # Put depot_tool's git revision into the user agent string.
$client = Join-Path $myPath -ChildPath ".cipd_client.exe"
try { try {
$depot_tools_version = &git -C $myPath rev-parse HEAD 2>&1 $DepotToolsVersion = &git -C $DepotToolsPath rev-parse HEAD 2>&1
if ($LastExitCode -eq 0) { if ($LastExitCode -eq 0) {
$user_agent = "depot_tools/$depot_tools_version" $UserAgent = "depot_tools/$DepotToolsVersion"
} else { } else {
$user_agent = "depot_tools/???" $UserAgent = "depot_tools/???"
} }
} catch [System.Management.Automation.CommandNotFoundException] { } catch [System.Management.Automation.CommandNotFoundException] {
$user_agent = "depot_tools/no_git/???" $UserAgent = "depot_tools/no_git/???"
}
$Env:CIPD_HTTP_USER_AGENT_PREFIX = $UserAgent
# Tries to delete the file, ignoring errors. Used for best-effort cleanups.
function Delete-If-Possible($path) {
try {
[System.IO.File]::Delete($path)
} catch {
$err = $_.Exception.Message
echo "Warning: error when deleting $path - $err. Ignoring."
}
}
# Returns the expected SHA256 hex digest for the given platform reading it from
# *.digests file.
function Get-Expected-SHA256($platform) {
$digestsFile = $VersionFile+".digests"
foreach ($line in Get-Content $digestsFile) {
if ($line -match "^([0-9a-z\-]+)\s+sha256\s+([0-9a-f]+)$") {
if ($Matches[1] -eq $platform) {
return $Matches[2]
}
}
}
throw "No SHA256 digests for $platform in $digestsFile"
}
# Returns SHA256 hex digest of a binary file at the given path.
function Get-Actual-SHA256($path) {
# Note: we don't use Get-FileHash to be compatible with PowerShell v3.0
$file = [System.IO.File]::Open($path, [System.IO.FileMode]::Open)
try {
$algo = New-Object System.Security.Cryptography.SHA256Managed
$hash = $algo.ComputeHash($file)
} finally {
$file.Close()
}
$hex = ""
foreach ($byte in $hash) {
$hex += $byte.ToString("x2")
}
return $hex
} }
$Env:CIPD_HTTP_USER_AGENT_PREFIX = $user_agent
# Use a lock fle to prevent simultaneous processes from stepping on each other. $ExpectedSHA256 = Get-Expected-SHA256 $Platform
$cipd_lock = Join-Path $myPath -ChildPath '.cipd_client.lock' $Version = (Get-Content $VersionFile).Trim()
$URL = "$BackendURL/client?platform=$Platform&version=$Version"
# Use a lock file to prevent simultaneous processes from stepping on each other.
$CipdLockPath = Join-Path $DepotToolsPath -ChildPath ".cipd_client.lock"
$TmpPath = $CipdBinary + ".tmp"
while ($true) { while ($true) {
$cipd_lock_file = $false $CipdLockFile = $null
try { try {
$cipd_lock_file = [System.IO.File]::OpenWrite($cipd_lock) $CipdLockFile = [System.IO.File]::OpenWrite($CipdLockPath)
echo "Downloading CIPD client for $Platform from $URL..."
$wc = (New-Object System.Net.WebClient)
$wc.Headers.Add("User-Agent", $UserAgent)
$wc.DownloadFile($URL, $TmpPath)
echo "Bootstrapping cipd client for $plat-$arch from $url..." $ActualSHA256 = Get-Actual-SHA256 $TmpPath
$wc = (New-Object System.Net.WebClient) if ($ActualSHA256 -ne $ExpectedSHA256) {
$wc.Headers.add('User-Agent', $user_agent) throw "Invalid SHA256 digest: $ActualSHA256 != $ExpectedSHA256"
$wc.DownloadFile($url, $client) }
break
Move-Item -LiteralPath $TmpPath -Destination $CipdBinary -Force
break
} catch [System.IO.IOException] { } catch [System.IO.IOException] {
echo "CIPD bootstrap lock is held, trying again after delay..." echo "CIPD bootstrap lock is held, trying again after delay..."
Start-Sleep -s 1 Start-Sleep -s 1
} catch { } catch {
$err = $_.Exception.Message throw # for some reason this is needed to exit while(...) loop on errors
echo "CIPD bootstrap failed: $err"
throw $err
} finally { } finally {
if ($cipd_lock_file) { Delete-If-Possible $TmpPath
$cipd_lock_file.Close() if ($CipdLockFile) {
$cipd_lock_file = $false $CipdLockFile.Close()
try { Delete-If-Possible $CipdLockPath
[System.IO.File]::Delete($cipd_lock) }
} catch {}
}
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment