diff --git a/changes/34243-deploy-user-scoped-scep-profiles-for-windows b/changes/34243-deploy-user-scoped-scep-profiles-for-windows new file mode 100644 index 0000000000..0173949ecf --- /dev/null +++ b/changes/34243-deploy-user-scoped-scep-profiles-for-windows @@ -0,0 +1 @@ +* Add ability to deploy user-scoped SCEP profiles for Windows hosts \ No newline at end of file diff --git a/server/fleet/windows_mdm.go b/server/fleet/windows_mdm.go index 1a28ed1f57..aef433e361 100644 --- a/server/fleet/windows_mdm.go +++ b/server/fleet/windows_mdm.go @@ -204,7 +204,7 @@ func validateFleetProvidedLocURI(locURI string, enableCustomOSUpdates bool) erro // and then based on it being marked Optional, or Required in the description. // A list containg all valid SCEP Profile LocURIs, a combination of optional and required to validate for non-SCEP LocURIs. -var validSCEPProfileLocURIs = slices.Concat([]string{ +var validDeviceSCEPProfileLocURIs = slices.Concat([]string{ fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/AADKeyIdentifierList", FleetVarSCEPWindowsCertificateID.WithPrefix()), fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/ContainerName", FleetVarSCEPWindowsCertificateID.WithPrefix()), fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/CustomTextToShowInPrompt", FleetVarSCEPWindowsCertificateID.WithPrefix()), @@ -215,9 +215,22 @@ var validSCEPProfileLocURIs = slices.Concat([]string{ fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/TemplateName", FleetVarSCEPWindowsCertificateID.WithPrefix()), fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/ValidPeriod", FleetVarSCEPWindowsCertificateID.WithPrefix()), fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/ValidPeriodUnits", FleetVarSCEPWindowsCertificateID.WithPrefix()), -}, requiredSCEPProfileLocURIs) +}, requiredDeviceSCEPProfileLocURIs) -var requiredSCEPProfileLocURIs = []string{ +var validUserSCEPProfileLocURIs = slices.Concat([]string{ + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/AADKeyIdentifierList", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/ContainerName", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/CustomTextToShowInPrompt", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/KeyProtection", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/RetryCount", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/RetryDelay", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/SubjectAlternativeNames", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/TemplateName", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/ValidPeriod", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/ValidPeriodUnits", FleetVarSCEPWindowsCertificateID.WithPrefix()), +}, requiredUserSCEPProfileLocURIs) + +var requiredDeviceSCEPProfileLocURIs = []string{ fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s", FleetVarSCEPWindowsCertificateID.WithPrefix()), fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/CAThumbprint", FleetVarSCEPWindowsCertificateID.WithPrefix()), fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/Challenge", FleetVarSCEPWindowsCertificateID.WithPrefix()), @@ -229,15 +242,34 @@ var requiredSCEPProfileLocURIs = []string{ fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/SubjectName", FleetVarSCEPWindowsCertificateID.WithPrefix()), } -var validExecSCEPProfileLocURIs = []string{ +var requiredUserSCEPProfileLocURIs = []string{ + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/CAThumbprint", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/Challenge", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/EKUMapping", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/HashAlgorithm", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/KeyLength", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/KeyUsage", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/ServerURL", FleetVarSCEPWindowsCertificateID.WithPrefix()), + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/SubjectName", FleetVarSCEPWindowsCertificateID.WithPrefix()), +} + +var validDeviceExecSCEPProfileLocURIs = []string{ fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/Enroll", FleetVarSCEPWindowsCertificateID.WithPrefix()), } +var validUserExecSCEPProfileLocURIs = []string{ + fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s/Install/Enroll", FleetVarSCEPWindowsCertificateID.WithPrefix()), +} + type windowsSCEPProfileValidator struct { - totalLocURIs int - totalExecLocURIs int - foundLocURIs map[string]bool - foundExecLocURIs map[string]bool + totalLocURIs int + totalExecLocURIs int + foundLocURIs map[string]bool + foundExecLocURIs map[string]bool + requiredSCEPProfileLocURIs *[]string + validSCEPProfileLocURIs *[]string + validExecSCEPProfileLocURIs *[]string } func newWindowsSCEPProfileValidator() *windowsSCEPProfileValidator { @@ -254,12 +286,16 @@ func (v *windowsSCEPProfileValidator) isSCEPProfile() bool { func (v *windowsSCEPProfileValidator) validateLocURI(locURI string) error { sanitizedLocURI := strings.TrimSpace(locURI) - // If we see a LocURI with SCEP prefix, but no Fleet Var we fail early. - if v.isSCEPLocURIWithoutFleetVar(sanitizedLocURI) { - return fmt.Errorf("You must use %q after \"./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/\".", FleetVarSCEPWindowsCertificateID.WithPrefix()) + if err := v.setLocURIArrays(sanitizedLocURI); err != nil { + return err } - if slices.Contains(validSCEPProfileLocURIs, sanitizedLocURI) { + // If we see a LocURI with SCEP prefix, but no Fleet Var we fail early. + if v.isSCEPLocURIWithoutFleetVar(sanitizedLocURI) { + return fmt.Errorf("You must use %q after \"ClientCertificateInstall/SCEP/\".", FleetVarSCEPWindowsCertificateID.WithPrefix()) + } + + if slices.Contains(*v.validSCEPProfileLocURIs, sanitizedLocURI) { v.foundLocURIs[sanitizedLocURI] = true } @@ -270,12 +306,16 @@ func (v *windowsSCEPProfileValidator) validateLocURI(locURI string) error { func (v *windowsSCEPProfileValidator) validateExecLocURI(locURI string) error { sanitizedLocURI := strings.TrimSpace(locURI) - // If we see a LocURI with SCEP prefix, but no Fleet Var we fail early. - if v.isSCEPLocURIWithoutFleetVar(sanitizedLocURI) { - return fmt.Errorf("You must use %q after \"./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/\".", FleetVarSCEPWindowsCertificateID.WithPrefix()) + if err := v.setLocURIArrays(sanitizedLocURI); err != nil { + return err } - if slices.Contains(validExecSCEPProfileLocURIs, sanitizedLocURI) { + // If we see a LocURI with SCEP prefix, but no Fleet Var we fail early. + if v.isSCEPLocURIWithoutFleetVar(sanitizedLocURI) { + return fmt.Errorf("You must use %q after \"ClientCertificateInstall/SCEP/\".", FleetVarSCEPWindowsCertificateID.WithPrefix()) + } + + if slices.Contains(*v.validExecSCEPProfileLocURIs, sanitizedLocURI) { v.foundExecLocURIs[sanitizedLocURI] = true } @@ -283,17 +323,53 @@ func (v *windowsSCEPProfileValidator) validateExecLocURI(locURI string) error { return nil } +func (v *windowsSCEPProfileValidator) setLocURIArrays(locURI string) error { + switch { + case IsWindowsSCEPLocURI(locURI) && v.validExecSCEPProfileLocURIs == nil: + if strings.HasPrefix(locURI, "./User") { + v.requiredSCEPProfileLocURIs = &requiredUserSCEPProfileLocURIs + v.validSCEPProfileLocURIs = &validUserSCEPProfileLocURIs + v.validExecSCEPProfileLocURIs = &validUserExecSCEPProfileLocURIs + } else { + v.requiredSCEPProfileLocURIs = &requiredDeviceSCEPProfileLocURIs + v.validSCEPProfileLocURIs = &validDeviceSCEPProfileLocURIs + v.validExecSCEPProfileLocURIs = &validDeviceExecSCEPProfileLocURIs + } + case !IsWindowsSCEPLocURI(locURI) && v.validExecSCEPProfileLocURIs == nil: + // Not a SCEP profile, set empty arrays to avoid nil pointer dereference later. + emptyArray := []string{} + v.requiredSCEPProfileLocURIs = &emptyArray + v.validSCEPProfileLocURIs = &emptyArray + v.validExecSCEPProfileLocURIs = &emptyArray + case IsWindowsSCEPLocURI(locURI) && v.validExecSCEPProfileLocURIs != nil: + // Check against mixing Device and User SCEP LocURIs. + firstValidLocURI := (*v.validSCEPProfileLocURIs)[0] + if strings.HasPrefix(firstValidLocURI, "./Device") && strings.HasPrefix(locURI, "./User") || + strings.HasPrefix(firstValidLocURI, "./User") && strings.HasPrefix(locURI, "./Device") { + return errors.New("All elements in the SCEP profile must start either with \"./Device\" or \"./User\".") + } + } + + return nil +} + // isSCEPLocURIWithoutFleetVar checks that the provided locURI starts with the SCEP prefix // and that it includes the required Fleet Var for SCEP Windows Certificate ID. // Skips any locURI that does not start with the SCEP prefix. func (v windowsSCEPProfileValidator) isSCEPLocURIWithoutFleetVar(locURI string) bool { - if strings.HasPrefix(locURI, "./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/") && - !strings.HasPrefix(locURI, fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s", FleetVarSCEPWindowsCertificateID.WithPrefix())) { + if (strings.HasPrefix(locURI, "./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/") && + !strings.HasPrefix(locURI, fmt.Sprintf("./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/%s", FleetVarSCEPWindowsCertificateID.WithPrefix()))) || (strings.HasPrefix(locURI, "./User/Vendor/MSFT/ClientCertificateInstall/SCEP/") && + !strings.HasPrefix(locURI, fmt.Sprintf("./User/Vendor/MSFT/ClientCertificateInstall/SCEP/%s", FleetVarSCEPWindowsCertificateID.WithPrefix()))) { return true } return false } +func IsWindowsSCEPLocURI(locURI string) bool { + return strings.HasPrefix(locURI, "./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/") || + strings.HasPrefix(locURI, "./User/Vendor/MSFT/ClientCertificateInstall/SCEP/") +} + func (v *windowsSCEPProfileValidator) finalizeValidation() error { if !v.isSCEPProfile() { // Cheeky validation here, to only allow Exec elements in SCEP profiles. @@ -303,20 +379,30 @@ func (v *windowsSCEPProfileValidator) finalizeValidation() error { return nil // Not a SCEP profile, nothing to validate here. } + // If we reach here with empty arrays something has gone wrong. + if len(*v.validExecSCEPProfileLocURIs) == 0 || len(*v.validSCEPProfileLocURIs) == 0 || len(*v.requiredSCEPProfileLocURIs) == 0 { + return errors.New("Internal error validating SCEP profile LocURIs.") + } + + // ADD CODE HERE + // Verify that we do not have any non-scep loc URIs present if v.totalLocURIs != len(v.foundLocURIs) { - return errors.New("Only options that have starting with \"./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/\" can be added to SCEP profile.") + return errors.New("Only options that have starting with \"ClientCertificateInstall/SCEP/\" can be added to SCEP profile.") } // Check that at least one Exec LocURI is present and it matches the only one we have in the array. - if len(v.foundExecLocURIs) != 1 && !v.foundExecLocURIs[validExecSCEPProfileLocURIs[0]] { - return errors.New("Couldn't add. \"./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/Enroll\" must be included within . Please add and try again.") + validExecLocURIs := *v.validExecSCEPProfileLocURIs + if len(v.foundExecLocURIs) != 1 && !v.foundExecLocURIs[validExecLocURIs[0]] { + return errors.New("Couldn't add. \"ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/Enroll\" must be included within . Please add and try again.") } // Check that all required LocURIs are present - for _, requiredLocURI := range requiredSCEPProfileLocURIs { + for _, requiredLocURI := range *v.requiredSCEPProfileLocURIs { if !v.foundLocURIs[requiredLocURI] { - return fmt.Errorf("%q is missing. Please add and try again", requiredLocURI) + trimmedPrefix := strings.TrimPrefix(requiredLocURI, "./Device/Vendor/MSFT/") + trimmedPrefix = strings.TrimPrefix(trimmedPrefix, "./User/Vendor/MSFT/") + return fmt.Errorf("%q is missing. Please add and try again.", trimmedPrefix) } } diff --git a/server/fleet/windows_mdm_test.go b/server/fleet/windows_mdm_test.go index 7c45c5ceb1..b40fde809f 100644 --- a/server/fleet/windows_mdm_test.go +++ b/server/fleet/windows_mdm_test.go @@ -613,7 +613,7 @@ func TestValidateUserProvided(t *testing.T) { `), }, - wantErr: "Only options that have starting with \"./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/\" can be added to SCEP profile.", + wantErr: "Only options that have starting with \"ClientCertificateInstall/SCEP/\" can be added to SCEP profile.", }, { name: "SCEP profile without Exec block", @@ -626,7 +626,7 @@ func TestValidateUserProvided(t *testing.T) { `), }, - wantErr: "\"./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/Enroll\" must be included within . Please add and try again.", + wantErr: "\"ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/Enroll\" must be included within . Please add and try again.", }, { name: "SCEP profile with Exec block, but worng LocURI ", @@ -646,7 +646,7 @@ func TestValidateUserProvided(t *testing.T) { `), }, - wantErr: "Couldn't add. \"./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/Enroll\" must be included within . Please add and try again.", + wantErr: "Couldn't add. \"ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/Enroll\" must be included within . Please add and try again.", }, { name: fmt.Sprintf("SCEP profile with missing $FLEET_VAR_%s after SCEP LocURI", FleetVarSCEPWindowsCertificateID), @@ -666,7 +666,7 @@ func TestValidateUserProvided(t *testing.T) { `), }, - wantErr: fmt.Sprintf("You must use \"$FLEET_VAR_%s\" after \"./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/\".", FleetVarSCEPWindowsCertificateID), + wantErr: fmt.Sprintf("You must use \"$FLEET_VAR_%s\" after \"ClientCertificateInstall/SCEP/\".", FleetVarSCEPWindowsCertificateID), }, { name: "SCEP Profile with missing required LocURI", @@ -688,7 +688,7 @@ func TestValidateUserProvided(t *testing.T) { `), }, - wantErr: fmt.Sprintf("\"./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_%s/Install/CAThumbprint\" is missing.", FleetVarSCEPWindowsCertificateID), + wantErr: fmt.Sprintf("\"ClientCertificateInstall/SCEP/$FLEET_VAR_%s/Install/CAThumbprint\" is missing. Please add and try again.", FleetVarSCEPWindowsCertificateID), }, { name: "Only SCEP profiles can have Exec elements", @@ -705,6 +705,28 @@ func TestValidateUserProvided(t *testing.T) { }, wantErr: "Only SCEP profiles can include elements.", }, + { + name: "Either device or user SCEP profiles, not both", + profile: MDMWindowsConfigProfile{ + SyncML: []byte(` + + + + ./Device/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID + + + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/Enroll + + + + `), + }, + wantErr: "All elements in the SCEP profile must start either with \"./Device\" or \"./User\".", + }, } for _, tt := range tests { diff --git a/server/mdm/microsoft/profile_verifier.go b/server/mdm/microsoft/profile_verifier.go index f1452b7c4b..30686585d1 100644 --- a/server/mdm/microsoft/profile_verifier.go +++ b/server/mdm/microsoft/profile_verifier.go @@ -170,7 +170,7 @@ func compareResultsToExpectedProfiles(ctx context.Context, logger kitlog.Logger, } err = LoopOverExpectedHostProfiles(ctx, logger, ds, host, func(profile *fleet.ExpectedMDMProfile, ref, locURI, wantData string) { - if strings.HasPrefix(strings.TrimSpace(locURI), "./Device/Vendor/MSFT/ClientCertificateInstall/SCEP") { + if strings.Contains(strings.TrimSpace(locURI), "/Vendor/MSFT/ClientCertificateInstall/SCEP") { verified[profile.Name] = struct{}{} // We delete here if by some accident it was marked as missing before delete(missing, profile.Name) diff --git a/server/mdm/microsoft/profile_verifier_test.go b/server/mdm/microsoft/profile_verifier_test.go index c5238b08dc..770a91fa35 100644 --- a/server/mdm/microsoft/profile_verifier_test.go +++ b/server/mdm/microsoft/profile_verifier_test.go @@ -605,6 +605,14 @@ func TestVerifyHostMDMProfilesHappyPaths(t *testing.T) { Data: "non related data", }, }), 0}, + {"N2", syncml.ForTestWithData([]syncml.TestCommand{ + { + Verb: "Replace", + LocURI: ` + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/bogus-key-value`, + Data: "non related data", + }, + }), 0}, }, existingProfiles: []fleet.HostMDMWindowsProfile{ { @@ -612,8 +620,13 @@ func TestVerifyHostMDMProfilesHappyPaths(t *testing.T) { Name: "N1", Status: &fleet.MDMDeliveryPending, }, + { + ProfileUUID: "uuid-N2", + Name: "N2", + Status: &fleet.MDMDeliveryPending, + }, }, - toVerify: []string{"N1"}, + toVerify: []string{"N1", "N2"}, }, } diff --git a/server/service/integration_mdm_profiles_test.go b/server/service/integration_mdm_profiles_test.go index c746c0459d..f0419f4c88 100644 --- a/server/service/integration_mdm_profiles_test.go +++ b/server/service/integration_mdm_profiles_test.go @@ -7909,10 +7909,21 @@ func (s *integrationMDMTestSuite) TestWindowsProfilesFleetVariableSubstitution() "Profile should be verified in host details API for no-vars host") } -//go:embed testdata/profiles/windows-scep.xml -var windowsSCEPProfileBytes []byte +//go:embed testdata/profiles/windows-device-scep.xml +var windowsDeviceSCEPProfileBytes []byte -func (s *integrationMDMTestSuite) TestWindowsSCEPProfile() { +func (s *integrationMDMTestSuite) TestWindowsDeviceSCEPProfile() { + testWindowsSCEPProfile(s, windowsDeviceSCEPProfileBytes) +} + +//go:embed testdata/profiles/windows-user-scep.xml +var windowsUserSCEPProfileBytes []byte + +func (s *integrationMDMTestSuite) TestWindowsUserSCEPProfile() { + testWindowsSCEPProfile(s, windowsUserSCEPProfileBytes) +} + +func testWindowsSCEPProfile(s *integrationMDMTestSuite, windowsScepProfile []byte) { t := s.T() ctx := context.Background() scepServer := scep_server.StartTestSCEPServer(t) @@ -7953,7 +7964,7 @@ func (s *integrationMDMTestSuite) TestWindowsSCEPProfile() { // Upload SCEP profile with missing CA resp := s.Do("POST", "/api/v1/fleet/mdm/profiles/batch", batchSetMDMProfilesRequest{Profiles: []fleet.MDMProfileBatchPayload{ - {Name: "WindowsSCEPProfile", Contents: windowsSCEPProfileBytes}, + {Name: "WindowsSCEPProfile", Contents: windowsScepProfile}, }}, http.StatusBadRequest) errMsg := extractServerErrorText(resp.Body) @@ -7972,7 +7983,7 @@ func (s *integrationMDMTestSuite) TestWindowsSCEPProfile() { s.Do("POST", "/api/v1/fleet/mdm/profiles/batch", batchSetMDMProfilesRequest{Profiles: []fleet.MDMProfileBatchPayload{ - {Name: "WindowsSCEPProfile", Contents: windowsSCEPProfileBytes}, + {Name: "WindowsSCEPProfile", Contents: windowsScepProfile}, }}, http.StatusNoContent) @@ -8022,17 +8033,11 @@ func (s *integrationMDMTestSuite) TestWindowsSCEPProfile() { foundProfile = true profileUUID = p.ProfileUUID require.NotNil(t, p.Status) - assert.Equal(t, fleet.MDMDeliveryVerified, *p.Status) + require.Equal(t, fleet.MDMDeliveryVerified, *p.Status) } } require.True(t, foundProfile, "WindowsSCEPProfile not found for host") - mysql.ExecAdhocSQL(t, s.ds, func(q sqlx.ExtContext) error { - mysql.DumpTable(t, q, "host_mdm_windows_profiles") - mysql.DumpTable(t, q, "host_mdm_managed_certificates") - return nil - }) - // Attempt simple SCEP call with GetCACaps operation to verify SCEP server is reachable identifier := host.UUID + "," + profileUUID + "," + "INTEGRATION" scepRes := s.DoRawWithHeaders("GET", apple_mdm.SCEPProxyPath+identifier+"/pkiclient.exe", nil, http.StatusOK, nil, "operation", "GetCACaps") diff --git a/server/service/testdata/profiles/windows-scep.xml b/server/service/testdata/profiles/windows-device-scep.xml similarity index 100% rename from server/service/testdata/profiles/windows-scep.xml rename to server/service/testdata/profiles/windows-device-scep.xml diff --git a/server/service/testdata/profiles/windows-user-scep.xml b/server/service/testdata/profiles/windows-user-scep.xml new file mode 100644 index 0000000000..8aa9fcbff5 --- /dev/null +++ b/server/service/testdata/profiles/windows-user-scep.xml @@ -0,0 +1,140 @@ + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID + + + node + + + + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/RetryCount + + + int + + 3 + + + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/RetryDelay + + + int + + 10 + + + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/KeyUsage + + + int + + 160 + + + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/KeyLength + + + int + + 1024 + + + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/HashAlgorithm + + + chr + + SHA-1 + + + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/SubjectName + + + chr + + CN=$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID + + + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/EKUMapping + + + chr + + 1.3.6.1.5.5.7.3.2 + + + + 10 + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/ServerURL + + + chr + + $FLEET_VAR_CUSTOM_SCEP_PROXY_URL_INTEGRATION + + + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/Challenge + + + chr + + $FLEET_VAR_CUSTOM_SCEP_CHALLENGE_INTEGRATION + + + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/CAThumbprint + + + chr + + 2133EC6A3CFB8418837BB395188D1A62CA2B96A6 + + + + + + + ./User/Vendor/MSFT/ClientCertificateInstall/SCEP/$FLEET_VAR_SCEP_WINDOWS_CERTIFICATE_ID/Install/Enroll + + + \ No newline at end of file