From 30e6f048ab9b0253b9336404b7b810fff844e1db Mon Sep 17 00:00:00 2001 From: David Dworken Date: Sun, 2 Oct 2022 20:14:54 -0700 Subject: [PATCH] Add better handling for SLSA errors --- client/lib/lib.go | 12 ++++++++---- client/lib/slsa.go | 12 ++++++++++++ hishtory.go | 7 +++++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/client/lib/lib.go b/client/lib/lib.go index ae10a26..69df0e4 100644 --- a/client/lib/lib.go +++ b/client/lib/lib.go @@ -703,13 +703,17 @@ func Update(ctx *context.Context) error { } // Verify the SLSA attestation + var slsaError error if runtime.GOOS == "darwin" { - err = verifyBinaryMac(ctx, "/tmp/hishtory-client", downloadData) + slsaError = verifyBinaryMac(ctx, "/tmp/hishtory-client", downloadData) } else { - err = verifyBinary(ctx, "/tmp/hishtory-client", "/tmp/hishtory-client.intoto.jsonl", downloadData.Version) + slsaError = verifyBinary(ctx, "/tmp/hishtory-client", "/tmp/hishtory-client.intoto.jsonl", downloadData.Version) } - if err != nil { - return fmt.Errorf("failed to verify SLSA provenance of the updated binary, aborting update (to bypass, set `export HISHTORY_DISABLE_SLSA_ATTESTATION=true`): %v", err) + if slsaError != nil { + err = handleSlsaFailure(slsaError) + if err != nil { + return err + } } // Unlink the existing binary so we can overwrite it even though it is still running diff --git a/client/lib/slsa.go b/client/lib/slsa.go index 6fd4e18..8423481 100644 --- a/client/lib/slsa.go +++ b/client/lib/slsa.go @@ -1,6 +1,7 @@ package lib import ( + "bufio" "context" "crypto/sha256" "encoding/hex" @@ -77,3 +78,14 @@ func getFileHash(binaryPath string) (string, error) { hash := hex.EncodeToString(hasher.Sum(nil)) return hash, nil } + +func handleSlsaFailure(srcErr error) error { + fmt.Printf("\nFailed to verify SLSA provenance! This is likely due to a SLSA bug (SLSA is a brand new standard, and like all new things, has bugs). Ignoring this failure means falling back to the way most software does updates. Do you want to ignore this failure and update anyways? [y/N]") + reader := bufio.NewReader(os.Stdin) + resp, err := reader.ReadString('\n') + if err == nil && strings.TrimSpace(resp) == "y" { + fmt.Println("Proceeding with update...") + return nil + } + return fmt.Errorf("failed to verify SLSA provenance of the updated binary, aborting update (to bypass, set `export HISHTORY_DISABLE_SLSA_ATTESTATION=true`): %v", srcErr) +} diff --git a/hishtory.go b/hishtory.go index d36ea49..923cb9f 100644 --- a/hishtory.go +++ b/hishtory.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "fmt" + "log" "os" "strings" "time" @@ -105,8 +106,10 @@ func main() { } fmt.Printf("Commit Hash: %s\n", GitCommit) case "update": - // TODO: Add banner integration to update - lib.CheckFatalError(lib.Update(hctx.MakeContext())) + err := lib.Update(hctx.MakeContext()) + if err != nil { + log.Fatalf("Failed to update hishtory: %v", err) + } case "-h": fallthrough case "help":