Skip to content

Commit 4f1ac95

Browse files
authored
Merge pull request #358 from fluxcd/verify-artifact-checksum
Verify artifacts integrity
2 parents 9e51c3a + 59d3d88 commit 4f1ac95

File tree

4 files changed

+32
-8
lines changed

4 files changed

+32
-8
lines changed

config/default/kustomization.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1
22
kind: Kustomization
33
namespace: helm-system
44
resources:
5-
- https://github.com/fluxcd/source-controller/releases/download/v0.16.0/source-controller.crds.yaml
6-
- https://github.com/fluxcd/source-controller/releases/download/v0.16.0/source-controller.deployment.yaml
5+
- https://github.com/fluxcd/source-controller/releases/download/v0.18.0/source-controller.crds.yaml
6+
- https://github.com/fluxcd/source-controller/releases/download/v0.18.0/source-controller.deployment.yaml
77
- ../crd
88
- ../rbac
99
- ../manager

controllers/helmrelease_controller_chart.go

+27-3
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@ package controllers
1818

1919
import (
2020
"context"
21+
"crypto/sha1"
22+
"crypto/sha256"
2123
"fmt"
2224
"io"
23-
"io/ioutil"
2425
"net/http"
2526
"net/url"
2627
"os"
@@ -94,7 +95,7 @@ func (r *HelmReleaseReconciler) getHelmChart(ctx context.Context, hr *v2.HelmRel
9495
// loads it into a chart.Chart, and removes the downloaded artifact.
9596
// It returns the loaded chart.Chart on success, or an error.
9697
func (r *HelmReleaseReconciler) loadHelmChart(source *sourcev1.HelmChart) (*chart.Chart, error) {
97-
f, err := ioutil.TempFile("", fmt.Sprintf("%s-%s-*.tgz", source.GetNamespace(), source.GetName()))
98+
f, err := os.CreateTemp("", fmt.Sprintf("%s-%s-*.tgz", source.GetNamespace(), source.GetName()))
9899
if err != nil {
99100
return nil, err
100101
}
@@ -126,13 +127,36 @@ func (r *HelmReleaseReconciler) loadHelmChart(source *sourcev1.HelmChart) (*char
126127
return nil, fmt.Errorf("artifact '%s' download failed (status code: %s)", source.GetArtifact().URL, resp.Status)
127128
}
128129

129-
if _, err = io.Copy(f, resp.Body); err != nil {
130+
// verify checksum matches origin
131+
if err := r.copyAndVerifyArtifact(source.GetArtifact(), resp.Body, f); err != nil {
130132
return nil, err
131133
}
132134

133135
return loader.Load(f.Name())
134136
}
135137

138+
func (r *HelmReleaseReconciler) copyAndVerifyArtifact(artifact *sourcev1.Artifact, reader io.Reader, writer io.Writer) error {
139+
hasher := sha256.New()
140+
141+
// for backwards compatibility with source-controller v0.17.2 and older
142+
if len(artifact.Checksum) == 40 {
143+
hasher = sha1.New()
144+
}
145+
146+
// compute checksum
147+
mw := io.MultiWriter(hasher, writer)
148+
if _, err := io.Copy(mw, reader); err != nil {
149+
return err
150+
}
151+
152+
if checksum := fmt.Sprintf("%x", hasher.Sum(nil)); checksum != artifact.Checksum {
153+
return fmt.Errorf("failed to verify artifact: computed checksum '%s' doesn't match advertised '%s'",
154+
checksum, artifact.Checksum)
155+
}
156+
157+
return nil
158+
}
159+
136160
// deleteHelmChart deletes the v1beta1.HelmChart of the v2beta1.HelmRelease.
137161
func (r *HelmReleaseReconciler) deleteHelmChart(ctx context.Context, hr *v2.HelmRelease) error {
138162
if hr.Status.HelmChart == "" {

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/fluxcd/pkg/apis/kustomize v0.1.0
1010
github.com/fluxcd/pkg/apis/meta v0.10.0
1111
github.com/fluxcd/pkg/runtime v0.12.0
12-
github.com/fluxcd/source-controller/api v0.16.0
12+
github.com/fluxcd/source-controller/api v0.18.0
1313
github.com/go-logr/logr v0.4.0
1414
github.com/hashicorp/go-retryablehttp v0.6.8
1515
github.com/onsi/ginkgo v1.16.4

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,8 @@ github.com/fluxcd/pkg/apis/meta v0.10.0 h1:N7wVGHC1cyPdT87hrDC7UwCwRwnZdQM46PBSL
245245
github.com/fluxcd/pkg/apis/meta v0.10.0/go.mod h1:CW9X9ijMTpNe7BwnokiUOrLl/h13miwVr/3abEQLbKE=
246246
github.com/fluxcd/pkg/runtime v0.12.0 h1:BPZZ8bBkimpqGAPXqOf3LTaw+tcw6HgbWyCuzbbsJGs=
247247
github.com/fluxcd/pkg/runtime v0.12.0/go.mod h1:EyaTR2TOYcjL5U//C4yH3bt2tvTgIOSXpVRbWxUn/C4=
248-
github.com/fluxcd/source-controller/api v0.16.0 h1:xFz+K7lLg/82uOQp+a0g04GsgoWNfyzwXAoVQy4T/oI=
249-
github.com/fluxcd/source-controller/api v0.16.0/go.mod h1:guUCCapjzE2kocwFreQTM/IGvtAglIJc4L97mokairo=
248+
github.com/fluxcd/source-controller/api v0.18.0 h1:cK1uWHCujeEm9mjPPum5gogbMXOo0C6ieVZtTTxDNkY=
249+
github.com/fluxcd/source-controller/api v0.18.0/go.mod h1:guUCCapjzE2kocwFreQTM/IGvtAglIJc4L97mokairo=
250250
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
251251
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
252252
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=

0 commit comments

Comments
 (0)