plugin/discovery: improve providery discovery verification errors

This commit is contained in:
findkim 2019-03-21 14:38:51 -05:00
parent 2726282307
commit 161fe47b34
3 changed files with 49 additions and 19 deletions

View File

@ -532,6 +532,11 @@ func (c *InitCommand) getProviders(earlyConfig *earlyconfig.Config, state *state
case err == discovery.ErrorNoVersionCompatible: case err == discovery.ErrorNoVersionCompatible:
// Generic version incompatible msg // Generic version incompatible msg
c.Ui.Error(fmt.Sprintf(errProviderIncompatible, provider, constraint)) c.Ui.Error(fmt.Sprintf(errProviderIncompatible, provider, constraint))
case err == discovery.ErrorSignatureVerification:
c.Ui.Error(fmt.Sprintf(errSignatureVerification, provider))
case err == discovery.ErrorChecksumVerification,
err == discovery.ErrorMissingChecksumVerification:
c.Ui.Error(fmt.Sprintf(errChecksumVerification, provider))
default: default:
c.Ui.Error(fmt.Sprintf(errProviderInstallError, provider, err.Error(), DefaultPluginVendorDir)) c.Ui.Error(fmt.Sprintf(errProviderInstallError, provider, err.Error(), DefaultPluginVendorDir))
} }
@ -928,7 +933,7 @@ const errProviderInstallError = `
Terraform analyses the configuration and state and automatically downloads Terraform analyses the configuration and state and automatically downloads
plugins for the providers used. However, when attempting to download this plugins for the providers used. However, when attempting to download this
plugin an unexpected error occured. plugin an unexpected error occurred.
This may be caused if for some reason Terraform is unable to reach the This may be caused if for some reason Terraform is unable to reach the
plugin repository. The repository may be unreachable if access is blocked plugin repository. The repository may be unreachable if access is blocked
@ -959,3 +964,18 @@ by -plugin-dir on the command line, or in the following directory if custom
plugin directories are not set: plugin directories are not set:
%[2]s %[2]s
` `
const errChecksumVerification = `
[reset][bold][red]Error verifying checksum for provider %[1]q[reset][red]
The checksum for provider distribution from the Terraform Registry
did not match the source. This may mean that the distributed files
were changed after this version was released to the Registry.
`
const errSignatureVerification = `
[reset][bold][red]Error verifying GPG signature for provider %[1]q[reset][red]
Terraform was unable to verify the GPG signature of the downloaded provider
files using the keys downloaded from the Terraform Registry. This may mean that
the publisher of the provider removed the key it was signed with, or that the
distributed files were changed after this version was released.
`

View File

@ -35,6 +35,22 @@ const ErrorNoSuchProvider = Error("no provider exists with the given name")
// requested platform // requested platform
const ErrorNoVersionCompatibleWithPlatform = Error("no available version is compatible for the requested platform") const ErrorNoVersionCompatibleWithPlatform = Error("no available version is compatible for the requested platform")
// ErrorMissingChecksumVerification indicates that either the provider
// distribution is missing the SHA256SUMS file or the checksum file does
// not contain a checksum for the binary plugin
const ErrorMissingChecksumVerification = Error("unable to verify checksum")
// ErrorChecksumVerification indicates that the current checksum of the
// provider plugin has changed since the initial release and is not trusted
// to download
const ErrorChecksumVerification = Error("unexpected plugin checksum")
// ErrorSignatureVerification indicates that the digital signature for a
// provider distribution could not be verified for one of the following
// reasons: missing signature file, missing public key, or the signature
// was not signed by any known key for the publisher
const ErrorSignatureVerification = Error("unable to verify signature")
func (err Error) Error() string { func (err Error) Error() string {
return string(err) return string(err)
} }

View File

@ -30,18 +30,6 @@ import (
const protocolVersionHeader = "x-terraform-protocol-version" const protocolVersionHeader = "x-terraform-protocol-version"
const gpgVerificationError = `GPG signature verification error:
Terraform was unable to verify the GPG signature of the downloaded provider
files using the keys downloaded from the Terraform Registry. This may mean that
the publisher of the provider removed the key it was signed with, or that the
distributed files were changed after this version was released.`
const checksumVerificationError = `Checksum verification error:
The checksum for provider distribution %q from the Terraform Registry
did not match the source (%s).
This may mean that the distributed files were changed after this version
was released.`
var httpClient *http.Client var httpClient *http.Client
var errVersionNotFound = errors.New("version not found") var errVersionNotFound = errors.New("version not found")
@ -411,13 +399,15 @@ func (i *ProviderInstaller) getProviderChecksum(resp *response.TerraformProvider
// Get SHA256SUMS file. // Get SHA256SUMS file.
shasums, err := getFile(resp.ShasumsURL) shasums, err := getFile(resp.ShasumsURL)
if err != nil { if err != nil {
return "", fmt.Errorf("error fetching checksums: %s", err) log.Printf("[ERROR] error fetching checksums from %q: %s", resp.ShasumsURL, err)
return "", ErrorMissingChecksumVerification
} }
// Get SHA256SUMS.sig file. // Get SHA256SUMS.sig file.
signature, err := getFile(resp.ShasumsSignatureURL) signature, err := getFile(resp.ShasumsSignatureURL)
if err != nil { if err != nil {
return "", fmt.Errorf("error fetching checksums signature: %s", err) log.Printf("[ERROR] error fetching checksums signature from %q: %s", resp.ShasumsSignatureURL, err)
return "", ErrorSignatureVerification
} }
// Verify the GPG signature returned from the Registry. // Verify the GPG signature returned from the Registry.
@ -425,7 +415,7 @@ func (i *ProviderInstaller) getProviderChecksum(resp *response.TerraformProvider
signer, err := verifySig(shasums, signature, asciiArmor) signer, err := verifySig(shasums, signature, asciiArmor)
if err != nil { if err != nil {
log.Printf("[ERROR] error verifying signature: %s", err) log.Printf("[ERROR] error verifying signature: %s", err)
return "", fmt.Errorf(gpgVerificationError) return "", ErrorSignatureVerification
} }
// Also verify the GPG signature against the HashiCorp public key. This is // Also verify the GPG signature against the HashiCorp public key. This is
@ -434,7 +424,7 @@ func (i *ProviderInstaller) getProviderChecksum(resp *response.TerraformProvider
_, err = verifySig(shasums, signature, HashicorpPublicKey) _, err = verifySig(shasums, signature, HashicorpPublicKey)
if err != nil { if err != nil {
log.Printf("[ERROR] error verifying signature against HashiCorp public key: %s", err) log.Printf("[ERROR] error verifying signature against HashiCorp public key: %s", err)
return "", fmt.Errorf(gpgVerificationError) return "", ErrorSignatureVerification
} }
// Display identity for GPG key which succeeded verifying the signature. // Display identity for GPG key which succeeded verifying the signature.
@ -448,8 +438,12 @@ func (i *ProviderInstaller) getProviderChecksum(resp *response.TerraformProvider
// Extract checksum for this os/arch platform binary and verify against Registry // Extract checksum for this os/arch platform binary and verify against Registry
checksum := checksumForFile(shasums, resp.Filename) checksum := checksumForFile(shasums, resp.Filename)
if checksum == "" || checksum != resp.Shasum { if checksum == "" {
return "", fmt.Errorf(checksumVerificationError, resp.Filename, resp.ShasumsURL) log.Printf("[ERROR] missing checksum for %s from source %s", resp.Filename, resp.ShasumsURL)
return "", ErrorMissingChecksumVerification
} else if checksum != resp.Shasum {
log.Printf("[ERROR] unexpected checksum for %s from source %q", resp.Filename, resp.ShasumsURL)
return "", ErrorChecksumVerification
} }
return checksum, nil return checksum, nil