From a884e5472ca97be64e7c49945af340e4420626e4 Mon Sep 17 00:00:00 2001 From: Jordan Montgomery Date: Wed, 29 Oct 2025 18:59:06 -0400 Subject: [PATCH] Add pkiclient.exe suffix support to SCEP proxy handler (#34709) **Related issue:** Resolves #34252 # Checklist for submitter If some of the following don't apply, delete the relevant line. - [x] Input data is properly validated, `SELECT *` is avoided, SQL injection is prevented (using placeholders for values in statements) - [x] If paths of existing endpoints are modified without backwards compatibility, checked the frontend/CLI for any necessary changes ## Testing - [x] Added/updated automated tests - [x] Where appropriate, [automated tests simulate multiple hosts and test for host isolation](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/reference/patterns-backend.md#unit-testing) (updates to one hosts's records do not affect another) - [x] QA'd all new/changed functionality manually --- server/mdm/scep/server/transport.go | 14 +++ server/service/integration_mdm_test.go | 129 +++++++++++++++---------- 2 files changed, 92 insertions(+), 51 deletions(-) diff --git a/server/mdm/scep/server/transport.go b/server/mdm/scep/server/transport.go index 648fe5333c..004722bab5 100644 --- a/server/mdm/scep/server/transport.go +++ b/server/mdm/scep/server/transport.go @@ -59,6 +59,20 @@ func MakeHTTPHandlerWithIdentifier(e *Endpoints, rootPath string, logger kitlog. encodeSCEPResponse, opts..., )) + // For Windows SCEP client which appends pkiclient.exe to the URL and seemingly cannot be configured + // to not do that + r.Path(rootPath + "{identifier}/pkiclient.exe").Methods("GET").Handler(kithttp.NewServer( + e.GetEndpoint, + decodeSCEPRequestWithIdentifier, + encodeSCEPResponse, + opts..., + )) + r.Path(rootPath + "{identifier}/pkiclient.exe").Methods("POST").Handler(kithttp.NewServer( + e.PostEndpoint, + decodeSCEPRequestWithIdentifier, + encodeSCEPResponse, + opts..., + )) return r } diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go index 5a7a44bba8..eb671206cc 100644 --- a/server/service/integration_mdm_test.go +++ b/server/service/integration_mdm_test.go @@ -696,6 +696,12 @@ func (s *integrationMDMTestSuite) TearDownTest() { return err }) + // Delete any CAs + mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { + _, err := q.ExecContext(ctx, "DELETE FROM certificate_authorities") + return err + }) + // clear any pending worker job mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { _, err := q.ExecContext(ctx, "DELETE FROM jobs") @@ -14100,6 +14106,17 @@ func (s *integrationMDMTestSuite) TestAppleMDMActionsOnPersonalHost() { } func (s *integrationMDMTestSuite) TestSCEPProxy() { + s.runSCEPProxyTestWithOptionalSuffix("") +} + +func (s *integrationMDMTestSuite) TestSCEPProxyWithMicrosoftSuffix() { + // Windows SCEP client appends pkiclient.exe to the URL for all requests + s.runSCEPProxyTestWithOptionalSuffix("/pkiclient.exe") +} + +// suffix is optional but will be tested with all endpoints. The idea of this is to ensure +// we get the exact same behavior whether it is used or not. +func (s *integrationMDMTestSuite) runSCEPProxyTestWithOptionalSuffix(suffix string) { t := s.T() ctx := context.Background() @@ -14179,28 +14196,28 @@ func (s *integrationMDMTestSuite) TestSCEPProxy() { message := base64.StdEncoding.EncodeToString(data) // NDES not configured - res := s.DoRawNoAuth("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest) + res := s.DoRawNoAuth("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest) errBody, err := io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "missing operation") // Provide SCEP operation (GetCACaps) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest, nil, "operation", "GetCACaps") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest, nil, "operation", "GetCACaps") errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), eeservice.MessageSCEPProxyNotConfigured) // Provide SCEP operation (GetCACerts) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest, nil, "operation", "GetCACert") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest, nil, "operation", "GetCACert") errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), eeservice.MessageSCEPProxyNotConfigured) // Provide SCEP operation (PKIOperation) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), eeservice.MessageSCEPProxyNotConfigured) // Provide SCEP operation (GetNextCACert) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest, nil, "operation", "GetNextCACert") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest, nil, "operation", "GetNextCACert") errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "not implemented") @@ -14223,15 +14240,15 @@ func (s *integrationMDMTestSuite) TestSCEPProxy() { }) require.NoError(t, err) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusInternalServerError, nil, "operation", "GetCACaps") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusInternalServerError, nil, "operation", "GetCACaps") errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "Could not GetCACaps from SCEP server") - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusInternalServerError, nil, "operation", "GetCACert") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusInternalServerError, nil, "operation", "GetCACert") errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "Could not GetCACert from SCEP server") - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusInternalServerError, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusInternalServerError, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -14261,11 +14278,11 @@ func (s *integrationMDMTestSuite) TestSCEPProxy() { require.NoError(t, err) // GetCACaps - _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusRequestTimeout, nil, "operation", "GetCACaps") + _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusRequestTimeout, nil, "operation", "GetCACaps") // GetCACert - _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusRequestTimeout, nil, "operation", "GetCACert") + _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusRequestTimeout, nil, "operation", "GetCACert") // PKIOperation - _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusRequestTimeout, nil, "operation", + _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusRequestTimeout, nil, "operation", "PKIOperation", "message", message) *s.scepConfig.Timeout = 10 * time.Second @@ -14283,13 +14300,13 @@ func (s *integrationMDMTestSuite) TestSCEPProxy() { require.NoError(t, err) // GetCACaps - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusOK, nil, "operation", "GetCACaps") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusOK, nil, "operation", "GetCACaps") body, err := io.ReadAll(res.Body) require.NoError(t, err) assert.Equal(t, scepserver.DefaultCACaps, string(body)) // GetCACert - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusOK, nil, "operation", "GetCACert") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusOK, nil, "operation", "GetCACert") body, err = io.ReadAll(res.Body) require.NoError(t, err) certs, err := x509.ParseCertificates(body) @@ -14298,25 +14315,25 @@ func (s *integrationMDMTestSuite) TestSCEPProxy() { // PKIOperation // Invalid identifier format - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozo", nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozo"+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "invalid identifier") // Non-Apple config profile (missing leading 'a') - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozoHost%2CwbozoProfile", nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozoHost%2CwbozoProfile"+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "invalid profile UUID") // Unknown host/profile - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozoHost%2CabozoProfile", nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozoHost%2CabozoProfile"+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "unknown identifier") // Profile which is not pending - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+badIdentifier, nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+badIdentifier+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -14325,7 +14342,7 @@ func (s *integrationMDMTestSuite) TestSCEPProxy() { // "Good" request without one-time challenge. // Note, a cert is not returned here because the message is not a fully valid SCEP request. However, building a valid SCEP request is a bit involved, // and this request is sufficient for testing our proxy functionality. - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusOK, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusOK, nil, "operation", "PKIOperation", "message", message) body, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -14344,7 +14361,7 @@ func (s *integrationMDMTestSuite) TestSCEPProxy() { }, }) require.NoError(t, err) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -14363,7 +14380,7 @@ func (s *integrationMDMTestSuite) TestSCEPProxy() { require.NoError(t, err) // Profile status is not yet "pending" (should be null) until profile sync - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+badIdentifier, nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+badIdentifier+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -14372,7 +14389,7 @@ func (s *integrationMDMTestSuite) TestSCEPProxy() { // trigger a profile sync s.awaitTriggerProfileSchedule(t) // Good request with non-expired challenge - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusOK, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusOK, nil, "operation", "PKIOperation", "message", message) body, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -14382,8 +14399,18 @@ func (s *integrationMDMTestSuite) TestSCEPProxy() { } func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { + s.runSmallstepSCEPProxyTestWithOptionalSuffix("") +} + +func (s *integrationMDMTestSuite) TestSmallstepSCEPProxyWithMicrosoftSuffix() { + // Windows SCEP client appends pkiclient.exe to the URL for all requests + s.runSmallstepSCEPProxyTestWithOptionalSuffix("/pkiclient.exe") +} + +func (s *integrationMDMTestSuite) runSmallstepSCEPProxyTestWithOptionalSuffix(suffix string) { t := s.T() ctx := context.Background() + caName := "Smallstep" + strings.ReplaceAll(strings.ReplaceAll(suffix, "/", ""), ".", "") // Add an MDM profile globalProfiles := [][]byte{ @@ -14442,47 +14469,47 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { HostUUID: host.UUID, ProfileUUID: profileUUID, Type: fleet.CAConfigSmallstep, - CAName: "Smallstep", + CAName: caName, }, { HostUUID: host.UUID, ProfileUUID: badProfile.ProfileUUID, Type: fleet.CAConfigSmallstep, - CAName: "Smallstep", + CAName: caName, }, }) require.NoError(t, err) - identifier := url.PathEscape(host.UUID + "," + profileUUID + "," + "Smallstep") - badIdentifier := url.PathEscape(host.UUID + "," + badProfile.ProfileUUID + "," + "Smallstep") + identifier := url.PathEscape(host.UUID + "," + profileUUID + "," + caName) + badIdentifier := url.PathEscape(host.UUID + "," + badProfile.ProfileUUID + "," + caName) data, err := os.ReadFile("./testdata/PKCSReq.der") require.NoError(t, err) message := base64.StdEncoding.EncodeToString(data) // NDES not configured - res := s.DoRawNoAuth("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest) + res := s.DoRawNoAuth("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest) errBody, err := io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "missing operation") // Provide SCEP operation (GetCACaps) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest, nil, "operation", "GetCACaps") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest, nil, "operation", "GetCACaps") errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), eeservice.MessageSCEPProxyNotConfigured) // Provide SCEP operation (GetCACerts) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest, nil, "operation", "GetCACert") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest, nil, "operation", "GetCACert") errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), eeservice.MessageSCEPProxyNotConfigured) // Provide SCEP operation (PKIOperation) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), eeservice.MessageSCEPProxyNotConfigured) // Provide SCEP operation (GetNextCACert) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest, nil, "operation", "GetNextCACert") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest, nil, "operation", "GetNextCACert") errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "not implemented") @@ -14497,7 +14524,7 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { password := "pass" ca, err := s.ds.NewCertificateAuthority(ctx, &fleet.CertificateAuthority{ Type: string(fleet.CATypeSmallstep), - Name: ptr.String("Smallstep"), + Name: ptr.String(caName), URL: &testServer.URL, ChallengeURL: &challengeUrl, Username: &username, @@ -14505,15 +14532,15 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { }) require.NoError(t, err) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusInternalServerError, nil, "operation", "GetCACaps") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusInternalServerError, nil, "operation", "GetCACaps") errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "Could not GetCACaps from SCEP server") - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusInternalServerError, nil, "operation", "GetCACert") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusInternalServerError, nil, "operation", "GetCACert") errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "Could not GetCACert from SCEP server") - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusInternalServerError, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusInternalServerError, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -14534,7 +14561,7 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { s.DoRaw("DELETE", fmt.Sprintf("/api/latest/fleet/certificate_authorities/%d", ca.ID), nil, http.StatusNoContent) ca, err = s.ds.NewCertificateAuthority(ctx, &fleet.CertificateAuthority{ Type: string(fleet.CATypeSmallstep), - Name: ptr.String("Smallstep"), + Name: ptr.String(caName), URL: &ndesTimeoutServer.URL, ChallengeURL: &challengeUrl, Username: &username, @@ -14543,11 +14570,11 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { require.NoError(t, err) // GetCACaps - _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusRequestTimeout, nil, "operation", "GetCACaps") + _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusRequestTimeout, nil, "operation", "GetCACaps") // GetCACert - _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusRequestTimeout, nil, "operation", "GetCACert") + _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusRequestTimeout, nil, "operation", "GetCACert") // PKIOperation - _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusRequestTimeout, nil, "operation", + _ = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusRequestTimeout, nil, "operation", "PKIOperation", "message", message) *s.scepConfig.Timeout = 10 * time.Second @@ -14556,7 +14583,7 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { s.DoRaw("DELETE", fmt.Sprintf("/api/latest/fleet/certificate_authorities/%d", ca.ID), nil, http.StatusNoContent) _, err = s.ds.NewCertificateAuthority(ctx, &fleet.CertificateAuthority{ Type: string(fleet.CATypeSmallstep), - Name: ptr.String("Smallstep"), + Name: ptr.String(caName), URL: ptr.String(scepServer.URL + "/scep"), ChallengeURL: &challengeUrl, Username: &username, @@ -14565,13 +14592,13 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { require.NoError(t, err) // GetCACaps - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusOK, nil, "operation", "GetCACaps") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusOK, nil, "operation", "GetCACaps") body, err := io.ReadAll(res.Body) require.NoError(t, err) assert.Equal(t, scepserver.DefaultCACaps, string(body)) // GetCACert - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusOK, nil, "operation", "GetCACert") + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusOK, nil, "operation", "GetCACert") body, err = io.ReadAll(res.Body) require.NoError(t, err) certs, err := x509.ParseCertificates(body) @@ -14580,25 +14607,25 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { // PKIOperation // Invalid identifier format - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozo", nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozo"+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "invalid identifier") // Non-Apple config profile (missing leading 'a') - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozoHost%2CwbozoProfile", nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozoHost%2CwbozoProfile"+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "invalid profile UUID") // Unknown host/profile - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozoHost%2CabozoProfile", nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+"bozoHost%2CabozoProfile"+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) assert.Contains(t, string(errBody), "unknown identifier") // Profile which is not pending - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+badIdentifier, nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+badIdentifier+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -14607,7 +14634,7 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { // "Good" request without one-time challenge. // Note, a cert is not returned here because the message is not a fully valid SCEP request. However, building a valid SCEP request is a bit involved, // and this request is sufficient for testing our proxy functionality. - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusOK, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusOK, nil, "operation", "PKIOperation", "message", message) body, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -14622,11 +14649,11 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { ProfileUUID: profileUUID, ChallengeRetrievedAt: ptr.Time(time.Now().Add(-eeservice.NDESChallengeInvalidAfter)), Type: fleet.CAConfigSmallstep, - CAName: "Smallstep", + CAName: caName, }, }) require.NoError(t, err) - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -14639,13 +14666,13 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { ProfileUUID: profileUUID, ChallengeRetrievedAt: ptr.Time(time.Now().Add(-eeservice.NDESChallengeInvalidAfter + time.Minute)), Type: fleet.CAConfigSmallstep, - CAName: "Smallstep", + CAName: caName, }, }) require.NoError(t, err) // Profile status is not yet "pending" (should be null) until profile sync - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+badIdentifier, nil, http.StatusBadRequest, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+badIdentifier+suffix, nil, http.StatusBadRequest, nil, "operation", "PKIOperation", "message", message) errBody, err = io.ReadAll(res.Body) require.NoError(t, err) @@ -14654,7 +14681,7 @@ func (s *integrationMDMTestSuite) TestSmallstepSCEPProxy() { // trigger a profile sync s.awaitTriggerProfileSchedule(t) // Good request with non-expired challenge - res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier, nil, http.StatusOK, nil, "operation", + res = s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+suffix, nil, http.StatusOK, nil, "operation", "PKIOperation", "message", message) body, err = io.ReadAll(res.Body) require.NoError(t, err)