backport openziti/ziti#4321 to release-v2.0.x compare process hashes … (#4345)

* backport openziti/ziti#4321 to release-v2.0.x compare process hashes and fingerprints case-insensitively

- normalizes configured hashes and signer fingerprints to lowercase unseparated hex in the
  PROCESS and PROCESS_MULTI stores, on load as well as on save, so values stored before this
  change read back normalized without a migration
- replaces the PROCESS store's lowercase-only pass, PROCESS_MULTI stored its values verbatim
- adds store tests for both types covering configured values and values written straight to bolt
- updates the process multi patch round-trip test, the management API now returns normalized
  values rather than the submitted strings
- removes the trailing newline from the signer fingerprint literal in the process and
  process-multi OIDC posture tests
This commit is contained in:
Andrew Martinez
2026-09-08 16:45:35 +01:00
committed by GitHub
parent 5188a018d1
commit d51acff74b
13 changed files with 396 additions and 27 deletions
+8 -1
View File
@@ -23,9 +23,16 @@ import (
var nonHex = regexp.MustCompile("[^a-f0-9]")
// CleanHexString normalizes a hex posture value to lowercase unseparated hex, the form posture
// check values are persisted in. Reported values must be normalized with it before they are
// compared against check values, whichever case and separator style the client sent them in.
func CleanHexString(hexString string) string {
return nonHex.ReplaceAllString(strings.ToLower(hexString), "")
}
// CleanMacAddress normalizes a MAC address to lowercase unseparated hex, the form MAC posture
// check values are persisted in. Reported addresses must be normalized with it before they are
// compared against check values, whichever separator style the client sent them in.
func CleanMacAddress(macAddress string) string {
return nonHex.ReplaceAllString(strings.ToLower(macAddress), "")
return CleanHexString(macAddress)
}
+8 -5
View File
@@ -17,8 +17,7 @@
package db
import (
"strings"
"github.com/openziti/ziti/v2/common/posture"
"github.com/openziti/ziti/v2/controller/storage/boltz"
)
@@ -53,15 +52,19 @@ func (entity *PostureCheckProcess) LoadValues(bucket *boltz.TypedBucket) {
entity.OperatingSystem = bucket.GetStringOrError(FieldPostureCheckProcessOs)
entity.Path = bucket.GetStringOrError(FieldPostureCheckProcessPath)
entity.Hashes = bucket.GetStringList(FieldPostureCheckProcessHashes)
entity.Fingerprint = bucket.GetStringOrError(FieldPostureCheckProcessFingerprint)
entity.Fingerprint = posture.CleanHexString(bucket.GetStringOrError(FieldPostureCheckProcessFingerprint))
for i, hash := range entity.Hashes {
entity.Hashes[i] = posture.CleanHexString(hash)
}
}
func (entity *PostureCheckProcess) SetValues(ctx *boltz.PersistContext, bucket *boltz.TypedBucket) {
entity.Fingerprint = strings.ToLower(entity.Fingerprint)
entity.Fingerprint = posture.CleanHexString(entity.Fingerprint)
for i, hash := range entity.Hashes {
entity.Hashes[i] = strings.ToLower(hash)
entity.Hashes[i] = posture.CleanHexString(hash)
}
bucket.SetString(FieldPostureCheckProcessOs, entity.OperatingSystem, ctx.FieldChecker)
@@ -18,6 +18,7 @@ package db
import (
"github.com/michaelquigley/pfxlog"
"github.com/openziti/ziti/v2/common/posture"
"github.com/openziti/ziti/v2/controller/storage/boltz"
)
@@ -52,6 +53,18 @@ func (entity *PostureCheckProcessMulti) GetTypeId() string {
return PostureCheckTypeProcessMulti
}
// cleanProcessMultiValues normalizes a process's hashes and signer fingerprints to lowercase
// unseparated hex, the form they are compared in.
func cleanProcessMultiValues(proc *ProcessMulti) {
for i, hash := range proc.Hashes {
proc.Hashes[i] = posture.CleanHexString(hash)
}
for i, fingerprint := range proc.SignerFingerprints {
proc.SignerFingerprints[i] = posture.CleanHexString(fingerprint)
}
}
func (entity *PostureCheckProcessMulti) LoadValues(bucket *boltz.TypedBucket) {
entity.Semantic = bucket.GetStringOrError(FieldSemantic)
@@ -68,6 +81,8 @@ func (entity *PostureCheckProcessMulti) LoadValues(bucket *boltz.TypedBucket) {
proc.SignerFingerprints = procBucket.GetStringList(FieldPostureCheckProcessMultiSignerFingerprints)
proc.Hashes = procBucket.GetStringList(FieldPostureCheckProcessMultiHashes)
cleanProcessMultiValues(proc)
entity.Processes = append(entity.Processes, proc)
}
}
@@ -79,6 +94,8 @@ func (entity *PostureCheckProcessMulti) SetValues(ctx *boltz.PersistContext, buc
seenKeys := map[string]struct{}{}
for _, proc := range entity.Processes {
cleanProcessMultiValues(proc)
key := proc.OsType + "-" + proc.Path
seenKeys[key] = struct{}{}
@@ -0,0 +1,166 @@
/*
Copyright NetFoundry Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package db
import (
"testing"
"github.com/openziti/ziti/v2/common/eid"
"github.com/openziti/ziti/v2/controller/storage/boltz"
"github.com/openziti/ziti/v2/controller/storage/boltztest"
)
const (
dirtyProcessHash = "3C:DA:EF:ED:01:38:A1:D0:1D:F9:AC:5C:8A:57:F0:2B:29:C2:4A:31:20:16:14:C5:1A:59:2E:EE:D2:E5:F7:F3"
cleanProcessHash = "3cdaefed0138a1d01df9ac5c8a57f02b29c24a31201614c51a592eeed2e5f7f3"
dirtyProcessFingerprint = "F1B2A6E9A37DFC918BD495E79B03DBBE6CB7477E3C6A0C29FF476C2B9A43AD0F\n"
cleanProcessFingerprint = "f1b2a6e9a37dfc918bd495e79b03dbbe6cb7477e3c6a0c29ff476c2b9a43ad0f"
testProcessOsType = "Windows"
testProcessPath = "C:\\example\\path\\1.exe"
)
// newProcessPostureCheck builds a PROCESS posture check carrying the given configured hashes and
// signer fingerprint.
func newProcessPostureCheck(hashes []string, fingerprint string) *PostureCheck {
return &PostureCheck{
BaseExtEntity: boltz.BaseExtEntity{Id: eid.New()},
Name: eid.New(),
TypeId: PostureCheckTypeProcess,
SubType: &PostureCheckProcess{
OperatingSystem: testProcessOsType,
Path: testProcessPath,
Hashes: hashes,
Fingerprint: fingerprint,
},
}
}
// newProcessMultiPostureCheck builds a PROCESS_MULTI posture check with a single process carrying
// the given configured hashes and signer fingerprints.
func newProcessMultiPostureCheck(hashes, fingerprints []string) *PostureCheck {
return &PostureCheck{
BaseExtEntity: boltz.BaseExtEntity{Id: eid.New()},
Name: eid.New(),
TypeId: PostureCheckTypeProcessMulti,
SubType: &PostureCheckProcessMulti{
Semantic: SemanticAllOf,
Processes: []*ProcessMulti{
{
OsType: testProcessOsType,
Path: testProcessPath,
Hashes: hashes,
SignerFingerprints: fingerprints,
},
},
},
}
}
// Test_PostureCheckProcessStore_NormalizesConfiguredValues locks in that a PROCESS check's
// configured hashes and signer fingerprint are stored as lowercase unseparated hex, whatever case
// and separator style they were configured in.
func Test_PostureCheckProcessStore_NormalizesConfiguredValues(t *testing.T) {
ctx := NewTestContext(t)
defer ctx.Cleanup()
check := newProcessPostureCheck([]string{dirtyProcessHash}, dirtyProcessFingerprint)
boltztest.RequireCreate(ctx, check)
boltztest.RequireReload(ctx, check)
stored := check.SubType.(*PostureCheckProcess)
ctx.Equal([]string{cleanProcessHash}, stored.Hashes)
ctx.Equal(cleanProcessFingerprint, stored.Fingerprint)
}
// Test_PostureCheckProcessMultiStore_NormalizesConfiguredValues locks in the same for a
// PROCESS_MULTI check, whose configured values are stored per process.
func Test_PostureCheckProcessMultiStore_NormalizesConfiguredValues(t *testing.T) {
ctx := NewTestContext(t)
defer ctx.Cleanup()
check := newProcessMultiPostureCheck([]string{dirtyProcessHash}, []string{dirtyProcessFingerprint})
boltztest.RequireCreate(ctx, check)
boltztest.RequireReload(ctx, check)
stored := check.SubType.(*PostureCheckProcessMulti)
ctx.Require().Len(stored.Processes, 1)
ctx.Equal([]string{cleanProcessHash}, stored.Processes[0].Hashes)
ctx.Equal([]string{cleanProcessFingerprint}, stored.Processes[0].SignerFingerprints)
}
// Test_PostureCheckProcessStore_NormalizesStoredValuesOnLoad locks in that a PROCESS check
// persisted before normalization reads back normalized, without waiting for the check to be saved
// again.
func Test_PostureCheckProcessStore_NormalizesStoredValuesOnLoad(t *testing.T) {
ctx := NewTestContext(t)
defer ctx.Cleanup()
check := newProcessPostureCheck([]string{cleanProcessHash}, cleanProcessFingerprint)
boltztest.RequireCreate(ctx, check)
err := ctx.GetDb().Update(nil, func(mc boltz.MutateContext) error {
bucket := ctx.stores.PostureCheck.GetEntityBucket(mc.Tx(), []byte(check.Id))
ctx.Require().NotNil(bucket)
typeBucket := bucket.GetOrCreateBucket(PostureCheckTypeProcess)
typeBucket.SetStringList(FieldPostureCheckProcessHashes, []string{dirtyProcessHash}, nil)
typeBucket.SetString(FieldPostureCheckProcessFingerprint, dirtyProcessFingerprint, nil)
return typeBucket.GetError()
})
ctx.Require().NoError(err)
boltztest.RequireReload(ctx, check)
stored := check.SubType.(*PostureCheckProcess)
ctx.Equal([]string{cleanProcessHash}, stored.Hashes)
ctx.Equal(cleanProcessFingerprint, stored.Fingerprint)
}
// Test_PostureCheckProcessMultiStore_NormalizesStoredValuesOnLoad locks in the same for a
// PROCESS_MULTI check.
func Test_PostureCheckProcessMultiStore_NormalizesStoredValuesOnLoad(t *testing.T) {
ctx := NewTestContext(t)
defer ctx.Cleanup()
check := newProcessMultiPostureCheck([]string{cleanProcessHash}, []string{cleanProcessFingerprint})
boltztest.RequireCreate(ctx, check)
err := ctx.GetDb().Update(nil, func(mc boltz.MutateContext) error {
bucket := ctx.stores.PostureCheck.GetEntityBucket(mc.Tx(), []byte(check.Id))
ctx.Require().NotNil(bucket)
typeBucket := bucket.GetOrCreateBucket(PostureCheckTypeProcessMulti)
processesBucket := typeBucket.GetOrCreateBucket(FieldPostureCheckProcessMultiProcesses)
procBucket := processesBucket.GetOrCreateBucket(testProcessOsType + "-" + testProcessPath)
procBucket.SetStringList(FieldPostureCheckProcessMultiHashes, []string{dirtyProcessHash}, nil)
procBucket.SetStringList(FieldPostureCheckProcessMultiSignerFingerprints, []string{dirtyProcessFingerprint}, nil)
return procBucket.GetError()
})
ctx.Require().NoError(err)
boltztest.RequireReload(ctx, check)
stored := check.SubType.(*PostureCheckProcessMulti)
ctx.Require().Len(stored.Processes, 1)
ctx.Equal([]string{cleanProcessHash}, stored.Processes[0].Hashes)
ctx.Equal([]string{cleanProcessFingerprint}, stored.Processes[0].SignerFingerprints)
}
@@ -18,8 +18,6 @@ package model
import (
"bytes"
"regexp"
"strings"
"sync/atomic"
"time"
@@ -464,9 +462,3 @@ func (pr *PostureResponse) Apply(postureData *PostureData) {
type PostureResponseSubType interface {
Apply(postureData *PostureData)
}
var macClean = regexp.MustCompile(`[^a-f\d]+`)
func CleanHexString(hexString string) string {
return macClean.ReplaceAllString(strings.ToLower(hexString), "")
}
@@ -18,6 +18,8 @@ package model
import (
"time"
"github.com/openziti/ziti/v2/common/posture"
)
type PostureResponseMac struct {
@@ -28,7 +30,7 @@ type PostureResponseMac struct {
func (pr *PostureResponseMac) Apply(postureData *PostureData) {
var cleanedAddresses []string
for _, address := range pr.Addresses {
cleanedAddresses = append(cleanedAddresses, CleanHexString(address))
cleanedAddresses = append(cleanedAddresses, posture.CleanHexString(address))
}
pr.Addresses = cleanedAddresses
@@ -19,6 +19,8 @@ package model
import (
"strings"
"time"
"github.com/openziti/ziti/v2/common/posture"
)
type PostureResponseProcess struct {
@@ -33,10 +35,10 @@ func (pr *PostureResponseProcess) Apply(postureData *PostureData) {
found := false
for i, fingerprint := range pr.SignerFingerprints {
pr.SignerFingerprints[i] = CleanHexString(fingerprint)
pr.SignerFingerprints[i] = posture.CleanHexString(fingerprint)
}
pr.BinaryHash = CleanHexString(pr.BinaryHash)
pr.BinaryHash = posture.CleanHexString(pr.BinaryHash)
for i, process := range postureData.Processes {
if process.PostureCheckId == pr.PostureCheckId {
+23 -1
View File
@@ -197,7 +197,7 @@ func (instance *Instance) Apply(response *edge_client_pb.PostureResponse, parser
instance.Woken = woken
updated = true
}
} else if processList := response.GetProcessList(); processList != nil {
} else if processList := normalizedProcessList(response.GetProcessList()); processList != nil {
if instance.mergeProcessList(processList) {
updated = true
}
@@ -270,6 +270,28 @@ func (instance *Instance) mergeProcessList(incoming *edge_client_pb.PostureRespo
return changed
}
// normalizedProcessList returns a copy of a reported process list with each binary hash and signer
// fingerprint normalized to the form the controller stores, so a process that passes a posture
// check at the controller passes the same check at the router. The caller's message is left
// untouched, and normalizing before the list is compared against the cached copy keeps a report
// differing only in formatting from reading as a posture change.
func normalizedProcessList(processList *edge_client_pb.PostureResponse_ProcessList) *edge_client_pb.PostureResponse_ProcessList {
if processList == nil {
return nil
}
normalized := proto.Clone(processList).(*edge_client_pb.PostureResponse_ProcessList)
for _, process := range normalized.Processes {
process.Hash = posture.CleanHexString(process.Hash)
for i, fingerprint := range process.SignerFingerprints {
process.SignerFingerprints[i] = posture.CleanHexString(fingerprint)
}
}
return normalized
}
func isOsDifferent(old *edge_client_pb.PostureResponse_Os, new *edge_client_pb.PostureResponse_OperatingSystem) bool {
if old == nil || old.Os == nil {
return true
+13 -5
View File
@@ -3,10 +3,10 @@ package posture
import (
"errors"
"fmt"
"slices"
"strings"
"github.com/michaelquigley/pfxlog"
"github.com/openziti/foundation/v2/stringz"
"github.com/openziti/sdk-golang/pb/edge_client_pb"
"github.com/openziti/ziti/v2/common/pb/edge_ctrl_pb"
"github.com/openziti/ziti/v2/controller/db"
@@ -169,12 +169,12 @@ func (p *ProcessCheck) compareProcesses(osType string, given *edge_client_pb.Pos
return result
}
if !strings.EqualFold(strings.ToLower(valid.OsType), strings.ToLower(osType)) {
if !strings.EqualFold(valid.OsType, osType) {
result.Reason = fmt.Errorf("os types do not match, given %s, expected: %s", osType, valid.OsType)
return result
}
if len(valid.Hashes) > 0 && !stringz.Contains(valid.Hashes, given.Hash) {
if len(valid.Hashes) > 0 && !containsFold(valid.Hashes, given.Hash) {
result.Reason = fmt.Errorf("hash is not valid, given %s, expected one of: %v", given.Hash, valid.Hashes)
return result
}
@@ -183,12 +183,12 @@ func (p *ProcessCheck) compareProcesses(osType string, given *edge_client_pb.Pos
validPrints := map[string]struct{}{}
for _, validPrint := range valid.Fingerprints {
validPrints[validPrint] = struct{}{}
validPrints[strings.ToLower(validPrint)] = struct{}{}
}
validPrintFound := false
for _, givenPrint := range given.SignerFingerprints {
if _, ok := validPrints[givenPrint]; ok {
if _, ok := validPrints[strings.ToLower(givenPrint)]; ok {
validPrintFound = true
break
}
@@ -202,3 +202,11 @@ func (p *ProcessCheck) compareProcesses(osType string, given *edge_client_pb.Pos
return nil
}
// containsFold reports whether values holds target, ignoring case. Configured hex values are
// stored as the administrator entered them, so they are compared case-insensitively.
func containsFold(values []string, target string) bool {
return slices.ContainsFunc(values, func(value string) bool {
return strings.EqualFold(value, target)
})
}
+139
View File
@@ -6,6 +6,7 @@ import (
"github.com/openziti/sdk-golang/pb/edge_client_pb"
"github.com/openziti/ziti/v2/common/pb/edge_ctrl_pb"
"github.com/openziti/ziti/v2/controller/db"
"github.com/stretchr/testify/require"
)
const testProcPath = "C:\\Windows\\System32\\notepad.exe"
@@ -88,3 +89,141 @@ func TestProcessCheck_NilInstanceData(t *testing.T) {
}
}
}
const (
lowerHash = "3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b"
upperHash = "3A7BD3E2360A3D29EEA436FCFB7E44C735D117C42D1C1835420B6B9942DD4F1B"
otherHash = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
lowerPrint = "a1b2c3d4e5f60718293a4b5c6d7e8f9012345678"
upperPrint = "A1B2C3D4E5F60718293A4B5C6D7E8F9012345678"
separatedPrint = "A1:B2:C3:D4:E5:F6:07:18:29:3A:4B:5C:6D:7E:8F:90:12:34:56:78"
otherPrint = "0011223344556677889900aabbccddeeff001122"
)
// newProcessCheckWith builds a single-process AllOf check carrying the configured hashes and
// signer fingerprints, as the router receives them from the controller's data state.
func newProcessCheckWith(hashes, fingerprints []string) *ProcessCheck {
check := newProcessCheck(db.SemanticAllOf)
check.Processes[0].Hashes = hashes
check.Processes[0].Fingerprints = fingerprints
return check
}
// reportedProcess builds posture state for a running process at the required path with the given
// reported hash and signer fingerprints.
func reportedProcess(hash string, fingerprints []string) *InstanceData {
return &InstanceData{
Os: &edge_client_pb.PostureResponse_Os{
Os: &edge_client_pb.PostureResponse_OperatingSystem{Type: "Windows"},
},
ProcessList: &edge_client_pb.PostureResponse_ProcessList{
Processes: []*edge_client_pb.PostureResponse_Process{
{
Path: testProcPath,
IsRunning: true,
Hash: hash,
SignerFingerprints: fingerprints,
},
},
},
}
}
// reportedProcessResponse builds a single-entry process list response for the required path with
// the given reported hash and signer fingerprints.
func reportedProcessResponse(hash string, fingerprints []string) *edge_client_pb.PostureResponse {
return processListResponse(&edge_client_pb.PostureResponse_Process{
Path: testProcPath,
IsRunning: true,
Hash: hash,
SignerFingerprints: fingerprints,
})
}
// Test_ProcessCheck_HashCaseIsIgnored locks in that hex hashes differing only in case are the same
// hash, as the controller treats them, in both directions.
func Test_ProcessCheck_HashCaseIsIgnored(t *testing.T) {
t.Run("configured uppercase, reported lowercase", func(t *testing.T) {
check := newProcessCheckWith([]string{upperHash}, nil)
require.Nil(t, check.Evaluate(reportedProcess(lowerHash, nil)))
})
t.Run("configured lowercase, reported uppercase", func(t *testing.T) {
check := newProcessCheckWith([]string{lowerHash}, nil)
require.Nil(t, check.Evaluate(reportedProcess(upperHash, nil)))
})
}
// Test_ProcessCheck_DifferentHashFails locks in that case insensitivity does not make a genuinely
// different hash pass.
func Test_ProcessCheck_DifferentHashFails(t *testing.T) {
check := newProcessCheckWith([]string{upperHash}, nil)
require.NotNil(t, check.Evaluate(reportedProcess(otherHash, nil)))
}
// Test_ProcessCheck_FingerprintCaseIsIgnored locks in the same for signer fingerprints, which the
// controller lowercases on both sides before comparing.
func Test_ProcessCheck_FingerprintCaseIsIgnored(t *testing.T) {
t.Run("configured uppercase, reported lowercase", func(t *testing.T) {
check := newProcessCheckWith(nil, []string{upperPrint})
require.Nil(t, check.Evaluate(reportedProcess(lowerHash, []string{lowerPrint})))
})
t.Run("configured lowercase, reported uppercase", func(t *testing.T) {
check := newProcessCheckWith(nil, []string{lowerPrint})
require.Nil(t, check.Evaluate(reportedProcess(lowerHash, []string{upperPrint})))
})
}
// Test_ProcessCheck_DifferentFingerprintFails locks in that case insensitivity does not make an
// unrelated signer pass.
func Test_ProcessCheck_DifferentFingerprintFails(t *testing.T) {
check := newProcessCheckWith(nil, []string{upperPrint})
require.NotNil(t, check.Evaluate(reportedProcess(lowerHash, []string{otherPrint})))
}
// Test_ProcessCheck_ReportedValuesNormalizedOnIngest locks in that reported hashes and signer
// fingerprints are stored in the normalized form the controller stores them in, whatever case and
// separator style the client sent.
func Test_ProcessCheck_ReportedValuesNormalizedOnIngest(t *testing.T) {
instance := newInstance()
updated := instance.Apply(reportedProcessResponse(upperHash, []string{separatedPrint}), nil)
data := snapshotData(instance)
require.True(t, updated)
require.Len(t, data.ProcessList.Processes, 1)
require.Equal(t, lowerHash, data.ProcessList.Processes[0].Hash)
require.Equal(t, []string{lowerPrint}, data.ProcessList.Processes[0].SignerFingerprints)
}
// Test_ProcessCheck_NormalizationDoesNotMutateResponse locks in that ingest normalization leaves
// the caller's protobuf message untouched.
func Test_ProcessCheck_NormalizationDoesNotMutateResponse(t *testing.T) {
instance := newInstance()
response := reportedProcessResponse(upperHash, []string{separatedPrint})
instance.Apply(response, nil)
require.Equal(t, upperHash, response.GetProcessList().Processes[0].Hash)
require.Equal(t, []string{separatedPrint}, response.GetProcessList().Processes[0].SignerFingerprints)
}
// Test_ProcessCheck_RepeatedResponseNotSeenAsChange locks in that re-reporting the same process in
// its uppercase form does not read as a posture change once the stored copy is normalized.
func Test_ProcessCheck_RepeatedResponseNotSeenAsChange(t *testing.T) {
instance := newInstance()
require.True(t, instance.Apply(reportedProcessResponse(upperHash, []string{separatedPrint}), nil))
updated := instance.Apply(reportedProcessResponse(upperHash, []string{separatedPrint}), nil)
require.False(t, updated)
}
+13 -2
View File
@@ -26,6 +26,7 @@ import (
"github.com/google/uuid"
"github.com/openziti/edge-api/rest_model"
"github.com/openziti/ziti/v2/common/eid"
"github.com/openziti/ziti/v2/common/posture"
)
func Test_PostureChecks_ProcessMulti(t *testing.T) {
@@ -781,12 +782,22 @@ func Test_PostureChecks_ProcessMulti(t *testing.T) {
ctx.testContextChanged(t)
for _, patchProcess := range patchProcesses {
var expectedHashes []string
for _, hash := range patchProcess.Hashes {
expectedHashes = append(expectedHashes, posture.CleanHexString(hash))
}
var expectedFingerprints []string
for _, fingerprint := range patchProcess.SignerFingerprints {
expectedFingerprints = append(expectedFingerprints, posture.CleanHexString(fingerprint))
}
isMatched := false
for _, getProcess := range getCheck.Processes {
if *getProcess.OsType == *patchProcess.OsType && *getProcess.Path == *patchProcess.Path {
isMatched = true
ctx.Req.ElementsMatch(patchProcess.Hashes, getProcess.Hashes)
ctx.Req.ElementsMatch(patchProcess.SignerFingerprints, getProcess.SignerFingerprints)
ctx.Req.ElementsMatch(expectedHashes, getProcess.Hashes)
ctx.Req.ElementsMatch(expectedFingerprints, getProcess.SignerFingerprints)
break
}
}
@@ -47,7 +47,7 @@ func Test_PostureCheck_SDK_Process_Multi_OIDC(t *testing.T) {
targetHash := "3cdaefed0138a1d01df9ac5c8a57f02b29c24a31201614c51a592eeed2e5f7f3"
targetPath := "C:\\example\\path\\1.exe"
targetSignerFingerprint := "f1b2a6e9a37dfc918bd495e79b03dbbe6cb7477e3c6a0c29ff476c2b9a43ad0f\n"
targetSignerFingerprint := "f1b2a6e9a37dfc918bd495e79b03dbbe6cb7477e3c6a0c29ff476c2b9a43ad0f"
targetProcess := &rest_model.ProcessMulti{
Hashes: []string{targetHash},
OsType: ToPtr(rest_model.OsTypeWindows),
+1 -1
View File
@@ -47,7 +47,7 @@ func Test_PostureCheck_SDK_Process_OIDC(t *testing.T) {
targetHash := "3cdaefed0138a1d01df9ac5c8a57f02b29c24a31201614c51a592eeed2e5f7f3"
targetPath := "C:\\example\\path\\1.exe"
targetSignerFingerprint := "f1b2a6e9a37dfc918bd495e79b03dbbe6cb7477e3c6a0c29ff476c2b9a43ad0f\n"
targetSignerFingerprint := "f1b2a6e9a37dfc918bd495e79b03dbbe6cb7477e3c6a0c29ff476c2b9a43ad0f"
targetProcess := &rest_model.Process{
Hashes: []string{targetHash},
OsType: ToPtr(rest_model.OsTypeWindows),