From 236d46ecc6c21af71245a597108d52637c30452e Mon Sep 17 00:00:00 2001 From: Claudio Costa Date: Thu, 2 Sep 2021 18:57:18 +0200 Subject: [PATCH] [MM-38321] Fix possible panics during license validation (#18333) * Fix possible panics during license validation * Return error if non 2xx code is returned by trial request server --- app/license.go | 7 ++++++ utils/license.go | 10 ++++---- utils/license_test.go | 55 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 61 insertions(+), 11 deletions(-) diff --git a/app/license.go b/app/license.go index 7907b1c0fe..4eaccb8be4 100644 --- a/app/license.go +++ b/app/license.go @@ -6,6 +6,7 @@ package app import ( "bytes" "encoding/json" + "fmt" "net/http" "os" "time" @@ -272,6 +273,12 @@ func (s *Server) RequestTrialLicense(trialRequest *model.TrialLicenseRequest) *m return model.NewAppError("RequestTrialLicense", "api.license.request_trial_license.app_error", nil, err.Error(), http.StatusBadRequest) } defer resp.Body.Close() + + if resp.StatusCode < 200 || resp.StatusCode >= 300 { + return model.NewAppError("RequestTrialLicense", "api.license.request_trial_license.app_error", nil, + fmt.Sprintf("Unexpected HTTP status code %q returned by server", resp.Status), http.StatusInternalServerError) + } + licenseResponse := model.MapFromJSON(resp.Body) if _, ok := licenseResponse["license"]; !ok { diff --git a/utils/license.go b/utils/license.go index cd449cd8fc..83d92375ea 100644 --- a/utils/license.go +++ b/utils/license.go @@ -71,16 +71,16 @@ func (l *LicenseValidatorImpl) ValidateLicense(signed []byte) (bool, string) { return false, "" } + // remove null terminator + for len(decoded) > 0 && decoded[len(decoded)-1] == byte(0) { + decoded = decoded[:len(decoded)-1] + } + if len(decoded) <= 256 { mlog.Error("Signed license not long enough") return false, "" } - // remove null terminator - for decoded[len(decoded)-1] == byte(0) { - decoded = decoded[:len(decoded)-1] - } - plaintext := decoded[:len(decoded)-256] signature := decoded[len(decoded)-256:] diff --git a/utils/license_test.go b/utils/license_test.go index 5fdb614988..c32faa044f 100644 --- a/utils/license_test.go +++ b/utils/license_test.go @@ -4,6 +4,8 @@ package utils import ( + "bytes" + "encoding/base64" "io/ioutil" "os" "testing" @@ -13,13 +15,54 @@ import ( ) func TestValidateLicense(t *testing.T) { - b1 := []byte("junk") - ok, _ := LicenseValidator.ValidateLicense(b1) - require.False(t, ok, "should have failed - bad license") + t.Run("should fail with junk data", func(t *testing.T) { + b1 := []byte("junk") + ok, _ := LicenseValidator.ValidateLicense(b1) + require.False(t, ok, "should have failed - bad license") - b2 := []byte("junkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunk") - ok, _ = LicenseValidator.ValidateLicense(b2) - require.False(t, ok, "should have failed - bad license") + b2 := []byte("junkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunkjunk") + ok, _ = LicenseValidator.ValidateLicense(b2) + require.False(t, ok, "should have failed - bad license") + }) + + t.Run("should not panic on shorted than expected input", func(t *testing.T) { + var licenseData bytes.Buffer + var inputData []byte + + for i := 0; i < 255; i++ { + inputData = append(inputData, 'A') + } + inputData = append(inputData, 0x00) + + encoder := base64.NewEncoder(base64.StdEncoding, &licenseData) + _, err := encoder.Write(inputData) + require.NoError(t, err) + err = encoder.Close() + require.NoError(t, err) + + ok, str := LicenseValidator.ValidateLicense(licenseData.Bytes()) + require.False(t, ok) + require.Empty(t, str) + }) + + t.Run("should not panic with input filled of null terminators", func(t *testing.T) { + var licenseData bytes.Buffer + var inputData []byte + + for i := 0; i < 256; i++ { + inputData = append(inputData, 0x00) + } + + encoder := base64.NewEncoder(base64.StdEncoding, &licenseData) + _, err := encoder.Write(inputData) + require.NoError(t, err) + err = encoder.Close() + require.NoError(t, err) + + ok, str := LicenseValidator.ValidateLicense(licenseData.Bytes()) + require.False(t, ok) + require.Empty(t, str) + }) } func TestGetLicenseFileLocation(t *testing.T) {