SHA checksums

This commit is contained in:
Hector Geraldino
2021-09-16 22:21:23 -04:00
committed by Marco Vermeulen
parent 8c889a5ee4
commit f7638f31c8
6 changed files with 115 additions and 5 deletions

2
.gitignore vendored
View File

@@ -7,6 +7,7 @@
.pid.lock
.project
.settings/
.vscode/
\#*
build/
classes
@@ -18,3 +19,4 @@ mongo.json
out/
sdkman-cli.iml
target/
bin/test

View File

@@ -38,7 +38,7 @@ function __sdk_help() {
__sdkman_echo_no_colour " offline [enable|disable]"
__sdkman_echo_no_colour " selfupdate [force]"
__sdkman_echo_no_colour " update"
__sdkman_echo_no_colour " flush [archives|tmp|broadcast|version]"
__sdkman_echo_no_colour " flush [archives|tmp|broadcast|metadata|version]"
__sdkman_echo_no_colour ""
__sdkman_echo_no_colour " candidate : the SDK to install: groovy, scala, grails, gradle, kotlin, etc."
__sdkman_echo_no_colour " use list command for comprehensive list of candidates"

View File

@@ -169,6 +169,7 @@ function __sdkman_download() {
echo ""
__sdkman_echo_no_colour "Found a previously downloaded ${candidate} ${version} archive. Not downloading it again..."
fi
__sdkman_checksum_zip "${archives_folder}/${candidate}-${version}.zip" "${headers}" || return 1
__sdkman_validate_zip "${archives_folder}/${candidate}-${version}.zip" || return 1
echo ""
}
@@ -185,3 +186,45 @@ function __sdkman_validate_zip() {
return 1
fi
}
function __sdkman_checksum_zip() {
local -r zip_archive="$1"
local -r headers_archive="$2"
local algorithm checksum cmd
local shasum_avail=false
local md5sum_avail=false
#Check for the appropriate checksum tools
if command -v shasum > /dev/null 2>&1; then
shasum_avail=true
fi
if command -v md5sum > /dev/null 2>&1; then
md5sum_avail=true
fi
while IFS= read -r line; do
algorithm=$(echo $line | sed -n 's/^X-Sdkman-Checksum-\(.*\):.*$/\1/p' | tr '[:lower:]' '[:upper:]')
checksum=$(echo $line | sed -n 's/^X-Sdkman-Checksum-.*:\(.*\)$/\1/p' | tr -cd '[:alnum:]')
if [[ -n ${algorithm} && -n ${checksum} ]]; then
if [[ "$algorithm" =~ 'SHA' && "$shasum_avail" == 'true' ]]; then
cmd="echo \"${checksum} *${zip_archive}\" | shasum --check --quiet"
elif [[ "$algorithm" =~ 'MD5' && "$md5sum_avail" == 'true' ]]; then
cmd="echo \"${checksum} ${zip_archive}\" | md5sum --check --quiet"
fi
if [[ -n $cmd ]]; then
__sdkman_echo_debug "Checksumming downloaded artifact ${zip_archive} (${algorithm})"
if ! eval "$cmd"; then
rm -f "$zip_archive"
echo ""
__sdkman_echo_red "Stop! An invalid checksum was detected and the archive removed! Please try re-installing."
return 1
fi
fi
fi
done < ${headers_archive}
}

View File

@@ -27,6 +27,14 @@ And(~'^the candidate "([^"]*)" version "([^"]*)" is available for download$') {
primeEndpointWithString("/hooks/post/${candidate}/${version}/${UnixUtils.inferPlatform()}", postInstallationHookSuccess())
}
And(~'^the candidate "([^"]*)" version "([^"]*)" is available for download with checksum "([^"]*)" using algorithm "([^"]*)"$') {
String candidate, String version, String checksum, String algorithm ->
primeEndpointWithString("/candidates/validate/${candidate}/${version}/${UnixUtils.inferPlatform()}", "valid")
primeDownloadFor(SERVICE_UP_URL, candidate, version, UnixUtils.inferPlatform(), ["X-Sdkman-Checksum-${algorithm}": "${checksum}"])
primeEndpointWithString("/hooks/pre/${candidate}/${version}/${UnixUtils.inferPlatform()}", preInstallationHookSuccess())
primeEndpointWithString("/hooks/post/${candidate}/${version}/${UnixUtils.inferPlatform()}", postInstallationHookSuccess())
}
And(~/^the appropriate universal hooks are available for "([^"]*)" version "([^"]*)" on "([^"]*)"$/) { String candidate, String version, String os ->
String lcPlatform = UnixUtils.inferPlatform(os)
primeUniversalHookFor("pre", candidate, version, lcPlatform)

View File

@@ -30,11 +30,18 @@ class WebServiceStub {
}
static primeDownloadFor(String host, String candidate, String version, String platform) {
primeDownloadFor(host, candidate, version, platform, [:])
}
static primeDownloadFor(String host, String candidate, String version, String platform, Map<String, String> headers) {
def binary = (candidate == "java") ? "jdk-${version}-${platform}.tar.gz" : "${candidate}-${version}.zip"
stubFor(get(urlEqualTo("/broker/download/${candidate}/${version}/${platform}")).willReturn(
aResponse()
.withHeader("Location", "${host}/${binary}")
.withStatus(302)))
def responseBuilder = aResponse()
.withHeader("Location", "${host}/${binary}")
.withStatus(302)
headers.each { responseBuilder.withHeader(it.key, it.value) }
stubFor(get(urlEqualTo("/broker/download/${candidate}/${version}/${platform}"))
.willReturn(responseBuilder))
stubFor(get(urlEqualTo("/$binary")).willReturn(
aResponse()

View File

@@ -0,0 +1,50 @@
Feature: Verify checksums
Background:
Given the internet is reachable
And an initialised environment
Scenario: Install a specific Candidate with a valid SHA-256 checksum
Given the system is bootstrapped
And the candidate "grails" version "1.3.9" is available for download with checksum "1f9234c8e622ec46d33883ea45b39ede768b92d478fe08f6952548247f7fbb65" using algorithm "SHA-256"
When I enter "sdk install grails 1.3.9"
Then I see "Done installing!"
And the candidate "grails" version "1.3.9" is installed
And the response headers file is created for candidate "grails" and version "1.3.9"
And the exit code is 0
Scenario: Install a specific Candidate with a valid SHA1 checksum
Given the system is bootstrapped
And the candidate "grails" version "1.3.9" is available for download with checksum "c68e386a6deec9fc4c1e18df21f92739ba2ab36e" using algorithm "SHA1"
When I enter "sdk install grails 1.3.9"
Then I see "Done installing!"
And the candidate "grails" version "1.3.9" is installed
And the response headers file is created for candidate "grails" and version "1.3.9"
And the exit code is 0
Scenario: Install a specific Candidate with a valid md5 checksum
Given the system is bootstrapped
And the candidate "grails" version "1.3.9" is available for download with checksum "1e87a7d982a2f41da96fdec289908552" using algorithm "MD5"
When I enter "sdk install grails 1.3.9"
Then I see "Done installing!"
And the candidate "grails" version "1.3.9" is installed
And the response headers file is created for candidate "grails" and version "1.3.9"
And the exit code is 0
Scenario: If an unknown algorithm is used it should not fail
Given the system is bootstrapped
And the candidate "grails" version "1.3.9" is available for download with checksum "abc-checksum-00000" using algorithm "ABC"
When I enter "sdk install grails 1.3.9"
Then I see "Done installing!"
And the candidate "grails" version "1.3.9" is installed
And the response headers file is created for candidate "grails" and version "1.3.9"
And the exit code is 0
Scenario: Abort installation on download of a corrupt Candidate with invalid SHA
Given the system is bootstrapped
And the candidate "grails" version "1.3.9" is available for download with checksum "c68e386a6deec9fc4c1e18df21f927000000000e" using algorithm "SHA-256"
When I enter "sdk install grails 1.3.9"
Then I see "Stop! An invalid checksum was detected and the archive removed! Please try re-installing."
And the candidate "grails" version "1.3.9" is not installed
And the archive for candidate "grails" version "1.3.9" is removed
And the exit code is 1