rename and move syncml logic into a separate package

This commit is contained in:
Roberto Dip 2023-11-27 10:21:15 -03:00
parent f439432fae
commit d7c233d54c
13 changed files with 543 additions and 530 deletions

View file

@ -220,10 +220,10 @@ func (c *TestWindowsMDMClient) SendResponse() (map[string]fleet.ProtoCmdOperatio
}
var msg fleet.SyncML
msg.Xmlns = microsoft_mdm.SyncCmdNamespace
msg.Xmlns = syncml.SyncCmdNamespace
msg.SyncHdr = fleet.SyncHdr{
VerDTD: microsoft_mdm.SyncMLSupportedVersion,
VerProto: microsoft_mdm.SyncMLVerProto,
VerDTD: syncml.SyncMLSupportedVersion,
VerProto: syncml.SyncMLVerProto,
SessionID: sessionID,
MsgID: fmt.Sprint(messageIDInt + 1),
Source: &fleet.LocURI{LocURI: &c.DeviceID},
@ -498,11 +498,11 @@ func (c *TestWindowsMDMClient) getToken() (binarySecToken string, tokenValueType
return "", "", err
}
tokenValueType = microsoft_mdm.BinarySecurityAzureEnroll
tokenValueType = syncml.BinarySecurityAzureEnroll
binarySecToken = base64.URLEncoding.EncodeToString([]byte(tokenString))
case fleet.WindowsMDMProgrammaticEnrollmentType:
var err error
tokenValueType = microsoft_mdm.BinarySecurityDeviceEnroll
tokenValueType = syncml.BinarySecurityDeviceEnroll
binarySecToken, err = fleet.GetEncodedBinarySecurityToken(c.enrollmentType, c.tokenIdentifier)
if err != nil {
return "", "", fmt.Errorf("generating encoded security token: %w", err)

View file

@ -1730,15 +1730,15 @@ func (ds *Datastore) UpdateOrDeleteHostMDMAppleProfile(ctx context.Context, prof
return err
}
func (ds *Datastore) UpdateHostMDMProfilesVerification(ctx context.Context, hostUUID string, toVerify, toFail, toRetry []string) error {
func (ds *Datastore) UpdateHostMDMProfilesVerification(ctx context.Context, host *fleet.Host, toVerify, toFail, toRetry []string) error {
return ds.withRetryTxx(ctx, func(tx sqlx.ExtContext) error {
if err := setMDMProfilesVerifiedDB(ctx, tx, hostUUID, toVerify); err != nil {
if err := setMDMProfilesVerifiedDB(ctx, tx, host, toVerify); err != nil {
return err
}
if err := setMDMProfilesFailedDB(ctx, tx, hostUUID, toFail); err != nil {
if err := setMDMProfilesFailedDB(ctx, tx, host, toFail); err != nil {
return err
}
if err := setMDMProfilesRetryDB(ctx, tx, hostUUID, toRetry); err != nil {
if err := setMDMProfilesRetryDB(ctx, tx, host, toRetry); err != nil {
return err
}
return nil

View file

@ -10,6 +10,7 @@ import (
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm"
"github.com/go-kit/kit/log/level"
"github.com/google/uuid"
"github.com/jmoiron/sqlx"

View file

@ -12,8 +12,7 @@ import (
"strings"
"time"
mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
microsoft_mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/syncml"
)
//////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -62,11 +61,11 @@ func (req *SoapRequest) GetHeaderBinarySecurityToken() (*HeaderBinarySecurityTok
return nil, errors.New("binarySecurityToken is empty")
}
if req.Header.Security.Security.Encoding != mdm.EnrollEncode {
if req.Header.Security.Security.Encoding != syncml.EnrollEncode {
return nil, errors.New("binarySecurityToken encoding is invalid")
}
if req.Header.Security.Security.Value != mdm.BinarySecurityDeviceEnroll && req.Header.Security.Security.Value != mdm.BinarySecurityAzureEnroll {
if req.Header.Security.Security.Value != syncml.BinarySecurityDeviceEnroll && req.Header.Security.Security.Value != syncml.BinarySecurityAzureEnroll {
return nil, errors.New("binarySecurityToken type is invalid")
}
@ -149,15 +148,15 @@ func (req *SoapRequest) IsValidDiscoveryMsg() error {
}
// Ensure that only valid versions are supported
if req.Body.Discover.Request.RequestVersion != mdm.EnrollmentVersionV4 &&
req.Body.Discover.Request.RequestVersion != mdm.EnrollmentVersionV5 {
if req.Body.Discover.Request.RequestVersion != syncml.EnrollmentVersionV4 &&
req.Body.Discover.Request.RequestVersion != syncml.EnrollmentVersionV5 {
return errors.New("invalid discover message: Request.RequestVersion")
}
// Traverse the AuthPolicies slice and check for valid values
isInvalidAuth := true
for _, authPolicy := range req.Body.Discover.Request.AuthPolicies.AuthPolicy {
if authPolicy == mdm.AuthOnPremise {
if authPolicy == syncml.AuthOnPremise {
isInvalidAuth = false
break
}
@ -217,8 +216,8 @@ func (req *SoapRequest) IsValidRequestSecurityTokenMsg() error {
return errors.New("invalid requestsecuritytoken message: BinarySecurityToken.ValueType")
}
if req.Body.RequestSecurityToken.BinarySecurityToken.ValueType != mdm.EnrollReqTypePKCS10 &&
req.Body.RequestSecurityToken.BinarySecurityToken.ValueType != mdm.EnrollReqTypePKCS7 {
if req.Body.RequestSecurityToken.BinarySecurityToken.ValueType != syncml.EnrollReqTypePKCS10 &&
req.Body.RequestSecurityToken.BinarySecurityToken.ValueType != syncml.EnrollReqTypePKCS7 {
return errors.New("invalid requestsecuritytoken message: BinarySecurityToken.EncodingType not supported")
}
@ -230,29 +229,29 @@ func (req *SoapRequest) IsValidRequestSecurityTokenMsg() error {
return errors.New("invalid requestsecuritytoken message: AdditionalContext.ContextItems missing")
}
reqEnrollType, err := req.Body.RequestSecurityToken.GetContextItem(mdm.ReqSecTokenContextItemEnrollmentType)
if err != nil || (reqEnrollType != mdm.ReqSecTokenEnrollTypeDevice && reqEnrollType != mdm.ReqSecTokenEnrollTypeFull) {
return fmt.Errorf("invalid requestsecuritytoken message %s: %s - %v", mdm.ReqSecTokenContextItemEnrollmentType, reqEnrollType, err)
reqEnrollType, err := req.Body.RequestSecurityToken.GetContextItem(syncml.ReqSecTokenContextItemEnrollmentType)
if err != nil || (reqEnrollType != syncml.ReqSecTokenEnrollTypeDevice && reqEnrollType != syncml.ReqSecTokenEnrollTypeFull) {
return fmt.Errorf("invalid requestsecuritytoken message %s: %s - %v", syncml.ReqSecTokenContextItemEnrollmentType, reqEnrollType, err)
}
reqDeviceID, err := req.Body.RequestSecurityToken.GetContextItem(mdm.ReqSecTokenContextItemDeviceID)
reqDeviceID, err := req.Body.RequestSecurityToken.GetContextItem(syncml.ReqSecTokenContextItemDeviceID)
if err != nil || len(reqDeviceID) == 0 {
return fmt.Errorf("invalid requestsecuritytoken message %s: %s - %v", mdm.ReqSecTokenContextItemDeviceID, reqDeviceID, err)
return fmt.Errorf("invalid requestsecuritytoken message %s: %s - %v", syncml.ReqSecTokenContextItemDeviceID, reqDeviceID, err)
}
reqHwDeviceID, err := req.Body.RequestSecurityToken.GetContextItem(mdm.ReqSecTokenContextItemHWDevID)
reqHwDeviceID, err := req.Body.RequestSecurityToken.GetContextItem(syncml.ReqSecTokenContextItemHWDevID)
if err != nil || len(reqHwDeviceID) == 0 {
return fmt.Errorf("invalid requestsecuritytoken message %s: %s - %v", mdm.ReqSecTokenContextItemHWDevID, reqHwDeviceID, err)
return fmt.Errorf("invalid requestsecuritytoken message %s: %s - %v", syncml.ReqSecTokenContextItemHWDevID, reqHwDeviceID, err)
}
reqOSEdition, err := req.Body.RequestSecurityToken.GetContextItem(mdm.ReqSecTokenContextItemOSEdition)
reqOSEdition, err := req.Body.RequestSecurityToken.GetContextItem(syncml.ReqSecTokenContextItemOSEdition)
if err != nil || len(reqOSEdition) == 0 {
return fmt.Errorf("invalid requestsecuritytoken message %s: %s - %v", mdm.ReqSecTokenContextItemOSEdition, reqOSEdition, err)
return fmt.Errorf("invalid requestsecuritytoken message %s: %s - %v", syncml.ReqSecTokenContextItemOSEdition, reqOSEdition, err)
}
reqOSVersion, err := req.Body.RequestSecurityToken.GetContextItem(mdm.ReqSecTokenContextItemOSVersion)
reqOSVersion, err := req.Body.RequestSecurityToken.GetContextItem(syncml.ReqSecTokenContextItemOSVersion)
if err != nil || len(reqOSVersion) == 0 {
return fmt.Errorf("invalid requestsecuritytoken message %s: %s - %v", mdm.ReqSecTokenContextItemOSVersion, reqOSVersion, err)
return fmt.Errorf("invalid requestsecuritytoken message %s: %s - %v", syncml.ReqSecTokenContextItemOSVersion, reqOSVersion, err)
}
return nil
@ -360,7 +359,7 @@ func (token *HeaderBinarySecurityToken) IsValidToken() error {
return errors.New("binary security token is empty")
}
if token.Value != microsoft_mdm.BinarySecurityDeviceEnroll && token.Value != microsoft_mdm.BinarySecurityAzureEnroll {
if token.Value != syncml.BinarySecurityDeviceEnroll && token.Value != syncml.BinarySecurityAzureEnroll {
return errors.New("binary security token is invalid")
}
@ -373,7 +372,7 @@ func (token *HeaderBinarySecurityToken) IsAzureJWTToken() bool {
return false
}
if token.Value == microsoft_mdm.BinarySecurityAzureEnroll {
if token.Value == syncml.BinarySecurityAzureEnroll {
return true
}
@ -386,7 +385,7 @@ func (token *HeaderBinarySecurityToken) IsDeviceToken() bool {
return false
}
if token.Value == microsoft_mdm.BinarySecurityDeviceEnroll {
if token.Value == syncml.BinarySecurityDeviceEnroll {
return true
}
@ -503,8 +502,8 @@ func (msg RequestSecurityToken) GetBinarySecurityTokenData() (string, error) {
// Get Binary Security Token Type
func (msg RequestSecurityToken) GetBinarySecurityTokenType() (string, error) {
if msg.BinarySecurityToken.ValueType == mdm.EnrollReqTypePKCS10 ||
msg.BinarySecurityToken.ValueType == mdm.EnrollReqTypePKCS7 {
if msg.BinarySecurityToken.ValueType == syncml.EnrollReqTypePKCS10 ||
msg.BinarySecurityToken.ValueType == syncml.EnrollReqTypePKCS7 {
return msg.BinarySecurityToken.ValueType, nil
}
@ -1022,12 +1021,12 @@ func (msg *SyncML) IsValidHeader() error {
}
// SyncML DTD version check
if msg.SyncHdr.VerDTD != mdm.SyncMLSupportedVersion {
if msg.SyncHdr.VerDTD != syncml.SyncMLSupportedVersion {
return errors.New("unsupported DTD version")
}
// SyncML Proto version check
if msg.SyncHdr.VerProto != mdm.SyncMLVerProto {
if msg.SyncHdr.VerProto != syncml.SyncMLVerProto {
return errors.New("unsupported proto version")
}

View file

@ -4,7 +4,7 @@ import (
"encoding/xml"
"testing"
microsoft_mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/syncml"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/stretchr/testify/require"
)
@ -91,7 +91,7 @@ func TestBuildMDMWindowsProfilePayloadFromMDMResponse(t *testing.T) {
RawCommand: []byte(`<Atomic><Replace><</Atomic>`),
},
statuses: map[string]SyncMLCmd{
"foo": {CmdID: "foo", Data: ptr.String(microsoft_mdm.CmdStatusAtomicFailed)},
"foo": {CmdID: "foo", Data: ptr.String(syncml.CmdStatusAtomicFailed)},
},
hostUUID: "host-uuid",
expectedError: "XML syntax error",
@ -130,9 +130,9 @@ func TestBuildMDMWindowsProfilePayloadFromMDMResponse(t *testing.T) {
</Atomic>`),
},
statuses: map[string]SyncMLCmd{
"foo": {CmdID: "foo", Data: ptr.String(microsoft_mdm.CmdStatusAtomicFailed)},
"bar": {CmdID: "bar", Data: ptr.String(microsoft_mdm.CmdStatusOK)},
"baz": {CmdID: "baz", Data: ptr.String(microsoft_mdm.CmdStatusBadRequest)},
"foo": {CmdID: "foo", Data: ptr.String(syncml.CmdStatusAtomicFailed)},
"bar": {CmdID: "bar", Data: ptr.String(syncml.CmdStatusOK)},
"baz": {CmdID: "baz", Data: ptr.String(syncml.CmdStatusBadRequest)},
},
hostUUID: "host-uuid",
expectedPayload: &MDMWindowsProfilePayload{

View file

@ -9,7 +9,7 @@ import (
"github.com/beevik/etree"
"github.com/fleetdm/fleet/v4/server/mdm"
microsoft_mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/syncml"
)
// MDMWindowsBitLockerSummary reports the number of Windows hosts being managed by Fleet with
@ -81,8 +81,8 @@ func (m *MDMWindowsConfigProfile) ValidateUserProvided() error {
}
var fleetProvidedLocURIValidationMap = map[string][2]string{
microsoft_mdm.FleetBitLockerTargetLocURI: {"BitLocker", "mdm.enable_disk_encryption"},
microsoft_mdm.FleetOSUpdateTargetLocURI: {"Windows updates", "mdm.windows_updates"},
syncml.FleetBitLockerTargetLocURI: {"BitLocker", "mdm.enable_disk_encryption"},
syncml.FleetOSUpdateTargetLocURI: {"Windows updates", "mdm.windows_updates"},
}
func validateFleetProvidedLocURI(locURI string) error {

View file

@ -4,6 +4,7 @@ import (
"context"
"github.com/fleetdm/fleet/v4/server/fleet"
"github.com/fleetdm/fleet/v4/server/mdm"
)
// Profile verification is a set of related processes that run on the Fleet server to ensure that

View file

@ -55,57 +55,6 @@ const (
MSManageEntryPoint = "/ManagementServer/MDM.svc"
)
// XML Namespaces and type URLs used by the Microsoft Device Enrollment v2 protocol (MS-MDE2)
const (
DiscoverNS = "http://schemas.microsoft.com/windows/management/2012/01/enrollment"
PolicyNS = "http://schemas.microsoft.com/windows/pki/2009/01/enrollmentpolicy"
EnrollWSTrust = "http://docs.oasis-open.org/ws-sx/ws-trust/200512"
EnrollSecExt = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
EnrollTType = "http://schemas.microsoft.com/5.0.0.0/ConfigurationManager/Enrollment/DeviceEnrollmentToken"
EnrollPDoc = "http://schemas.microsoft.com/5.0.0.0/ConfigurationManager/Enrollment/DeviceEnrollmentProvisionDoc"
EnrollEncode = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#base64binary"
EnrollReq = "http://schemas.microsoft.com/windows/pki/2009/01/enrollment"
EnrollNSS = "http://www.w3.org/2003/05/soap-envelope"
EnrollNSA = "http://www.w3.org/2005/08/addressing"
EnrollXSI = "http://www.w3.org/2001/XMLSchema-instance"
EnrollXSD = "http://www.w3.org/2001/XMLSchema"
EnrollXSU = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
ActionNsDiag = "http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics"
ActionNsDiscovery = "http://schemas.microsoft.com/windows/management/2012/01/enrollment/IDiscoveryService/DiscoverResponse"
ActionNsPolicy = "http://schemas.microsoft.com/windows/pki/2009/01/enrollmentpolicy/IPolicy/GetPoliciesResponse"
ActionNsEnroll = EnrollReq + "/RSTRC/wstep"
EnrollReqTypePKCS10 = EnrollReq + "#PKCS10"
EnrollReqTypePKCS7 = EnrollReq + "#PKCS7"
BinarySecurityDeviceEnroll = "http://schemas.microsoft.com/5.0.0.0/ConfigurationManager/Enrollment/DeviceEnrollmentUserToken"
BinarySecurityAzureEnroll = "urn:ietf:params:oauth:token-type:jwt"
)
// Soap Error constants
// Details here: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-mde2/0a78f419-5fd7-4ddb-bc76-1c0f7e11da23
const (
// Message format is bad
SoapErrorMessageFormat = "s:messageformat"
// User not recognized
SoapErrorAuthentication = "s:authentication"
// User not allowed to enroll
SoapErrorAuthorization = "s:authorization"
// Failed to get certificate
SoapErrorCertificateRequest = "s:certificaterequest"
// Generic failure from management server, such as a database access error
SoapErrorEnrollmentServer = "s:enrollmentserver"
// The server hit an unexpected issue
SoapErrorInternalServiceFault = "s:internalservicefault"
// Cannot parse the security header
SoapErrorInvalidSecurity = "a:invalidsecurity"
)
// Device Enrolled States
const (
@ -120,286 +69,6 @@ const (
MDMDeviceStateManaged = "MDMDeviceEnrolledManaged"
)
// MS-MDE2 Message constants
const (
// Minimum supported version
EnrollmentVersionV4 = "4.0"
// Maximum supported version
EnrollmentVersionV5 = "5.0"
// xsi:nil indicates value is not present
DefaultStateXSI = "true"
// Supported authentication types
AuthOnPremise = "OnPremise"
// SOAP Fault codes
SoapFaultRecv = "s:receiver"
// SOAP Fault default error locale
SoapFaultLocale = "en-us"
// HTTP Content Type for SOAP responses
SoapContentType = "application/soap+xml; charset=utf-8"
// HTTP Content Type for SyncML MDM responses
SyncMLContentType = "application/vnd.syncml.dm+xml"
// HTTP Content Type for Webcontainer responses
WebContainerContentType = "text/html; charset=UTF-8"
// Minimal Key Length for SHA1WithRSA encryption
PolicyMinKeyLength = "2048"
// Certificate Validity Period in seconds (365 days)
PolicyCertValidityPeriodInSecs = "31536000"
// Certificate Renewal Period in seconds (180 days)
PolicyCertRenewalPeriodInSecs = "15552000"
// Supported Enroll types gathered from MS-MDE2 Spec Section 2.2.9.3
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-mde2/f7553554-b6e1-4a0d-abd6-6a2534503af7
// Supported Enroll Type Device
ReqSecTokenEnrollTypeDevice = "Device"
// Supported Enroll Type Full
ReqSecTokenEnrollTypeFull = "Full"
// Provisioning Doc Certificate Renewal Period (365 days)
WstepCertRenewalPeriodInDays = "365"
// Provisioning Doc Server supports ROBO auto certificate renewal
// TODO: Add renewal support
WstepROBOSupport = "true"
// Provisioning Doc Server retry interval
WstepRenewRetryInterval = "4"
// The PROVIDER-ID paramer specifies the server identifier for a management server used in the current management session
DocProvisioningAppProviderID = "Fleet"
// The NAME parameter is used in the APPLICATION characteristic to specify a user readable application identity
DocProvisioningAppName = DocProvisioningAppProviderID
// The CONNRETRYFREQ parameter is used in the APPLICATION characteristic to specify a user readable application identity
DocProvisioningAppConnRetryFreq = "6"
// The INITIALBACKOFFTIME parameter is used to specify the initial wait time in milliseconds when the DM client retries for the first time
DocProvisioningAppInitialBackoffTime = "30000"
// The MAXBACKOFFTIME parameter is used to specify the maximum number of milliseconds to sleep after package-sending failure
DocProvisioningAppMaxBackoffTime = "120000"
// The DocProvisioningVersion attributes defines the version of the provisioning document format
DocProvisioningVersion = "1.1"
// The number of times the DM client should retry to connect to the server when the client is initially configured or enrolled to communicate with the server.
DmClientCSPNumberOfFirstRetries = "8"
// The waiting time (in minutes) for the initial set of retries as specified by the number of retries in NumberOfFirstRetries
DmClientCSPIntervalForFirstSetOfRetries = "15"
// The number of times the DM client should retry a second round of connecting to the server when the client is initially configured/enrolled to communicate with the server
DmClientCSPNumberOfSecondRetries = "5"
// The waiting time (in minutes) for the second set of retries as specified by the number of retries in NumberOfSecondRetries
DmClientCSPIntervalForSecondSetOfRetries = "3"
// The number of times the DM client should retry connecting to the server when the client is initially configured/enrolled to communicate with the server
DmClientCSPNumberOfRemainingScheduledRetries = "0"
// The waiting time (in minutes) for the initial set of retries as specified by the number of retries in NumberOfRemainingScheduledRetries
DmClientCSPIntervalForRemainingScheduledRetries = "1560"
// It allows the IT admin to require the device to start a management session on any user login, regardless of if the user has preciously logged in
DmClientCSPPollOnLogin = "true"
// It specifies whether the DM client should send out a request pending alert in case the device response to a DM request is too slow.
DmClientCSPEnableOmaDmKeepAliveMessage = "true"
// CSR issuer should be verified during enrollment
EnrollVerifyIssue = true
// Int type used by the DM client configuration
DmClientIntType = "integer"
// Bool type used by the DM client configuration
DmClientBoolType = "boolean"
// Additional Context items present on the RequestSecurityToken token message
ReqSecTokenContextItemUXInitiated = "UXInitiated"
ReqSecTokenContextItemHWDevID = "HWDevID"
ReqSecTokenContextItemLocale = "Locale"
ReqSecTokenContextItemTargetedUserLoggedIn = "TargetedUserLoggedIn"
ReqSecTokenContextItemOSEdition = "OSEdition"
ReqSecTokenContextItemDeviceName = "DeviceName"
ReqSecTokenContextItemDeviceID = "DeviceID"
ReqSecTokenContextItemEnrollmentType = "EnrollmentType"
ReqSecTokenContextItemDeviceType = "DeviceType"
ReqSecTokenContextItemOSVersion = "OSVersion"
ReqSecTokenContextItemApplicationVersion = "ApplicationVersion"
ReqSecTokenContextItemNotInOobe = "NotInOobe"
ReqSecTokenContextItemRequestVersion = "RequestVersion"
// APPRU query param expected by STS Auth endpoint
STSAuthAppRu = "appru"
// Login related query param expected by STS Auth endpoint
STSLoginHint = "login_hint"
// redirect_uri query param expected by TOS endpoint
TOCRedirectURI = "redirect_uri"
// client-request-id query param expected by TOS endpoint
TOCReqID = "client-request-id"
// Alert payload user-driven unenrollment request
AlertUserUnenrollmentRequest = "com.microsoft:mdm.unenrollment.userrequest"
// FleetdWindowsInstallerGUID is the GUID used for fleetd on Windows
FleetdWindowsInstallerGUID = "./Device/Vendor/MSFT/EnterpriseDesktopAppManagement/MSI/%7BA427C0AA-E2D5-40DF-ACE8-0D726A6BE096%7D/DownloadInstall"
)
// MS-MDM Message constants
const (
// SyncML Message Content Type
SyncMLMsgContentType = "application/vnd.syncml.dm+xml"
// SyncML Message Meta Namespace
SyncMLMetaNamespace = "syncml:metinf"
// SyncML Cmd Namespace
SyncCmdNamespace = "SYNCML:SYNCML1.2"
// SyncML Message Header Name
SyncMLHdrName = "SyncHdr"
// Supported SyncML version
SyncMLSupportedVersion = "1.2"
// SyncML ver protocol version
SyncMLVerProto = "DM/" + SyncMLSupportedVersion
)
// MS-MDM Status Code constants
// Details here: https://learn.microsoft.com/en-us/windows/client-management/oma-dm-protocol-support
const (
// The SyncML command completed successfully
CmdStatusOK = "200"
// Accepted for processing
// This code denotes an asynchronous operation, such as a request to run a remote execution of an application
CmdStatusAcceptedForProcessing = "202"
// Authentication accepted
// Normally you'll only see this code in response to the SyncHdr element (used for authentication in the OMA-DM standard)
// You may see this code if you look at OMA DM logs, but CSPs don't typically generate this code.
CmdStatusAuthenticationAccepted = "212"
// Operation canceled
// The SyncML command completed successfully, but no more commands will be processed within the session.
CmdStatusOperationCancelled = "214"
// Not executed
// A command wasn't executed as a result of user interaction to cancel the command.
CmdStatusNotExecuted = "215"
// Atomic roll back OK
// A command was inside an Atomic element and Atomic failed, thhis command was rolled back successfully
CmdStatusAtomicRollbackAccepted = "216"
// Bad request. The requested command couldn't be performed because of malformed syntax.
// CSPs don't usually generate this error, however you might see it if your SyncML is malformed.
CmdStatusBadRequest = "400"
// Invalid credentials
// The requested command failed because the requestor must provide proper authentication. CSPs don't usually generate this error
CmdStatusInvalidCredentials = "401"
// Forbidden
// The requested command failed, but the recipient understood the requested command
CmdStatusForbidden = "403"
// Not found
// The requested target wasn't found. This code will be generated if you query a node that doesn't exist
CmdStatusNotFound = "404"
// Command not allowed
// This respond code will be generated if you try to write to a read-only node
CmdStatusNotAllowed = "405"
// Optional feature not supported
// This response code will be generated if you try to access a property that the CSP doesn't support
CmdStatusOptionalFeature = "406"
// Unsupported type or format
// This response code can result from XML parsing or formatting errors
CmdStatusUnsupportedType = "415"
// Already exists
// This response code occurs if you attempt to add a node that already exists
CmdStatusAlreadyExists = "418"
// Permission Denied
// The requested command failed because the sender doesn't have adequate access control permissions (ACL) on the recipient.
// An "Access denied" errors usually get translated to this response code.
CmdStatusPermissionDenied = "425"
// Command failed. Generic failure.
// The recipient encountered an unexpected condition, which prevented it from fulfilling the request
// This response code will occur when the SyncML DPU can't map the originating error code
CmdStatusCommandFailed = "500"
// Atomic failed
// One of the operations in an Atomic block failed
CmdStatusAtomicFailed = "507"
// Atomic roll back failed
// An Atomic operation failed and the command wasn't rolled back successfully.
CmdStatusAtomicRollbackFailed = "516"
)
// MS-MDM Supported Alerts
// Details on MS-MDM 2.2.7.2: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-mdm/72c6ea01-121c-48f9-85da-a26bb12aad51
const (
// SERVER-INITIATED MGMT
// Server-initiated device management session
CmdAlertServerInitiatedManagement = "1200"
// CLIENT-INITIATED MGMT
// Client-initiated device management session
CmdAlertClientInitiatedManagement = "1201"
// NEXT MESSAGE
// Request for the next message of a large object package
CmdAlertNextMessage = "1222"
// SESSION ABORT
// Informs recipient that the sender wishes to abort the DM session
CmdAlertSessionAbort = "1223"
// CLIENT EVENT
// Informs server that an event has occurred on the client
CmdAlertClientEvent = "1224"
// NO END OF DATA
// End of Data for chunked object not received.
CmdAlertNoEndOfData = "1225"
// GENERIC ALERT
// Generic client generated alert with or without a reference to a Management
CmdAlertGeneric = "1226"
)
const (
FleetBitLockerTargetLocURI = "/Vendor/MSFT/BitLocker"
FleetOSUpdateTargetLocURI = "/Vendor/MSFT/Policy/Config/Update"
)
func ResolveWindowsMDMDiscovery(serverURL string) (string, error) {
return commonmdm.ResolveURL(serverURL, MDE2DiscoveryPath, false)
}

View file

@ -0,0 +1,332 @@
package syncml
// XML Namespaces and type URLs used by the Microsoft Device Enrollment v2 protocol (MS-MDE2)
const (
DiscoverNS = "http://schemas.microsoft.com/windows/management/2012/01/enrollment"
PolicyNS = "http://schemas.microsoft.com/windows/pki/2009/01/enrollmentpolicy"
EnrollWSTrust = "http://docs.oasis-open.org/ws-sx/ws-trust/200512"
EnrollSecExt = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
EnrollTType = "http://schemas.microsoft.com/5.0.0.0/ConfigurationManager/Enrollment/DeviceEnrollmentToken"
EnrollPDoc = "http://schemas.microsoft.com/5.0.0.0/ConfigurationManager/Enrollment/DeviceEnrollmentProvisionDoc"
EnrollEncode = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#base64binary"
EnrollReq = "http://schemas.microsoft.com/windows/pki/2009/01/enrollment"
EnrollNSS = "http://www.w3.org/2003/05/soap-envelope"
EnrollNSA = "http://www.w3.org/2005/08/addressing"
EnrollXSI = "http://www.w3.org/2001/XMLSchema-instance"
EnrollXSD = "http://www.w3.org/2001/XMLSchema"
EnrollXSU = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
ActionNsDiag = "http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics"
ActionNsDiscovery = "http://schemas.microsoft.com/windows/management/2012/01/enrollment/IDiscoveryService/DiscoverResponse"
ActionNsPolicy = "http://schemas.microsoft.com/windows/pki/2009/01/enrollmentpolicy/IPolicy/GetPoliciesResponse"
ActionNsEnroll = EnrollReq + "/RSTRC/wstep"
EnrollReqTypePKCS10 = EnrollReq + "#PKCS10"
EnrollReqTypePKCS7 = EnrollReq + "#PKCS7"
BinarySecurityDeviceEnroll = "http://schemas.microsoft.com/5.0.0.0/ConfigurationManager/Enrollment/DeviceEnrollmentUserToken"
BinarySecurityAzureEnroll = "urn:ietf:params:oauth:token-type:jwt"
)
// Soap Error constants
// Details here: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-mde2/0a78f419-5fd7-4ddb-bc76-1c0f7e11da23
const (
// Message format is bad
SoapErrorMessageFormat = "s:messageformat"
// User not recognized
SoapErrorAuthentication = "s:authentication"
// User not allowed to enroll
SoapErrorAuthorization = "s:authorization"
// Failed to get certificate
SoapErrorCertificateRequest = "s:certificaterequest"
// Generic failure from management server, such as a database access error
SoapErrorEnrollmentServer = "s:enrollmentserver"
// The server hit an unexpected issue
SoapErrorInternalServiceFault = "s:internalservicefault"
// Cannot parse the security header
SoapErrorInvalidSecurity = "a:invalidsecurity"
)
// MS-MDM Status Code constants
// Details here: https://learn.microsoft.com/en-us/windows/client-management/oma-dm-protocol-support
const (
// The SyncML command completed successfully
CmdStatusOK = "200"
// Accepted for processing
// This code denotes an asynchronous operation, such as a request to run a remote execution of an application
CmdStatusAcceptedForProcessing = "202"
// Authentication accepted
// Normally you'll only see this code in response to the SyncHdr element (used for authentication in the OMA-DM standard)
// You may see this code if you look at OMA DM logs, but CSPs don't typically generate this code.
CmdStatusAuthenticationAccepted = "212"
// Operation canceled
// The SyncML command completed successfully, but no more commands will be processed within the session.
CmdStatusOperationCancelled = "214"
// Not executed
// A command wasn't executed as a result of user interaction to cancel the command.
CmdStatusNotExecuted = "215"
// Atomic roll back OK
// A command was inside an Atomic element and Atomic failed, thhis command was rolled back successfully
CmdStatusAtomicRollbackAccepted = "216"
// Bad request. The requested command couldn't be performed because of malformed syntax.
// CSPs don't usually generate this error, however you might see it if your SyncML is malformed.
CmdStatusBadRequest = "400"
// Invalid credentials
// The requested command failed because the requestor must provide proper authentication. CSPs don't usually generate this error
CmdStatusInvalidCredentials = "401"
// Forbidden
// The requested command failed, but the recipient understood the requested command
CmdStatusForbidden = "403"
// Not found
// The requested target wasn't found. This code will be generated if you query a node that doesn't exist
CmdStatusNotFound = "404"
// Command not allowed
// This respond code will be generated if you try to write to a read-only node
CmdStatusNotAllowed = "405"
// Optional feature not supported
// This response code will be generated if you try to access a property that the CSP doesn't support
CmdStatusOptionalFeature = "406"
// Unsupported type or format
// This response code can result from XML parsing or formatting errors
CmdStatusUnsupportedType = "415"
// Already exists
// This response code occurs if you attempt to add a node that already exists
CmdStatusAlreadyExists = "418"
// Permission Denied
// The requested command failed because the sender doesn't have adequate access control permissions (ACL) on the recipient.
// An "Access denied" errors usually get translated to this response code.
CmdStatusPermissionDenied = "425"
// Command failed. Generic failure.
// The recipient encountered an unexpected condition, which prevented it from fulfilling the request
// This response code will occur when the SyncML DPU can't map the originating error code
CmdStatusCommandFailed = "500"
// Atomic failed
// One of the operations in an Atomic block failed
CmdStatusAtomicFailed = "507"
// Atomic roll back failed
// An Atomic operation failed and the command wasn't rolled back successfully.
CmdStatusAtomicRollbackFailed = "516"
)
// MS-MDM Supported Alerts
// Details on MS-MDM 2.2.7.2: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-mdm/72c6ea01-121c-48f9-85da-a26bb12aad51
const (
// SERVER-INITIATED MGMT
// Server-initiated device management session
CmdAlertServerInitiatedManagement = "1200"
// CLIENT-INITIATED MGMT
// Client-initiated device management session
CmdAlertClientInitiatedManagement = "1201"
// NEXT MESSAGE
// Request for the next message of a large object package
CmdAlertNextMessage = "1222"
// SESSION ABORT
// Informs recipient that the sender wishes to abort the DM session
CmdAlertSessionAbort = "1223"
// CLIENT EVENT
// Informs server that an event has occurred on the client
CmdAlertClientEvent = "1224"
// NO END OF DATA
// End of Data for chunked object not received.
CmdAlertNoEndOfData = "1225"
// GENERIC ALERT
// Generic client generated alert with or without a reference to a Management
CmdAlertGeneric = "1226"
)
const (
FleetBitLockerTargetLocURI = "/Vendor/MSFT/BitLocker"
FleetOSUpdateTargetLocURI = "/Vendor/MSFT/Policy/Config/Update"
)
// MS-MDE2 Message constants
const (
// Minimum supported version
EnrollmentVersionV4 = "4.0"
// Maximum supported version
EnrollmentVersionV5 = "5.0"
// xsi:nil indicates value is not present
DefaultStateXSI = "true"
// Supported authentication types
AuthOnPremise = "OnPremise"
// SOAP Fault codes
SoapFaultRecv = "s:receiver"
// SOAP Fault default error locale
SoapFaultLocale = "en-us"
// HTTP Content Type for SOAP responses
SoapContentType = "application/soap+xml; charset=utf-8"
// HTTP Content Type for SyncML MDM responses
SyncMLContentType = "application/vnd.syncml.dm+xml"
// HTTP Content Type for Webcontainer responses
WebContainerContentType = "text/html; charset=UTF-8"
// Minimal Key Length for SHA1WithRSA encryption
PolicyMinKeyLength = "2048"
// Certificate Validity Period in seconds (365 days)
PolicyCertValidityPeriodInSecs = "31536000"
// Certificate Renewal Period in seconds (180 days)
PolicyCertRenewalPeriodInSecs = "15552000"
// Supported Enroll types gathered from MS-MDE2 Spec Section 2.2.9.3
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-mde2/f7553554-b6e1-4a0d-abd6-6a2534503af7
// Supported Enroll Type Device
ReqSecTokenEnrollTypeDevice = "Device"
// Supported Enroll Type Full
ReqSecTokenEnrollTypeFull = "Full"
// Provisioning Doc Certificate Renewal Period (365 days)
WstepCertRenewalPeriodInDays = "365"
// Provisioning Doc Server supports ROBO auto certificate renewal
// TODO: Add renewal support
WstepROBOSupport = "true"
// Provisioning Doc Server retry interval
WstepRenewRetryInterval = "4"
// The PROVIDER-ID paramer specifies the server identifier for a management server used in the current management session
DocProvisioningAppProviderID = "Fleet"
// The NAME parameter is used in the APPLICATION characteristic to specify a user readable application identity
DocProvisioningAppName = DocProvisioningAppProviderID
// The CONNRETRYFREQ parameter is used in the APPLICATION characteristic to specify a user readable application identity
DocProvisioningAppConnRetryFreq = "6"
// The INITIALBACKOFFTIME parameter is used to specify the initial wait time in milliseconds when the DM client retries for the first time
DocProvisioningAppInitialBackoffTime = "30000"
// The MAXBACKOFFTIME parameter is used to specify the maximum number of milliseconds to sleep after package-sending failure
DocProvisioningAppMaxBackoffTime = "120000"
// The DocProvisioningVersion attributes defines the version of the provisioning document format
DocProvisioningVersion = "1.1"
// The number of times the DM client should retry to connect to the server when the client is initially configured or enrolled to communicate with the server.
DmClientCSPNumberOfFirstRetries = "8"
// The waiting time (in minutes) for the initial set of retries as specified by the number of retries in NumberOfFirstRetries
DmClientCSPIntervalForFirstSetOfRetries = "15"
// The number of times the DM client should retry a second round of connecting to the server when the client is initially configured/enrolled to communicate with the server
DmClientCSPNumberOfSecondRetries = "5"
// The waiting time (in minutes) for the second set of retries as specified by the number of retries in NumberOfSecondRetries
DmClientCSPIntervalForSecondSetOfRetries = "3"
// The number of times the DM client should retry connecting to the server when the client is initially configured/enrolled to communicate with the server
DmClientCSPNumberOfRemainingScheduledRetries = "0"
// The waiting time (in minutes) for the initial set of retries as specified by the number of retries in NumberOfRemainingScheduledRetries
DmClientCSPIntervalForRemainingScheduledRetries = "1560"
// It allows the IT admin to require the device to start a management session on any user login, regardless of if the user has preciously logged in
DmClientCSPPollOnLogin = "true"
// It specifies whether the DM client should send out a request pending alert in case the device response to a DM request is too slow.
DmClientCSPEnableOmaDmKeepAliveMessage = "true"
// CSR issuer should be verified during enrollment
EnrollVerifyIssue = true
// Int type used by the DM client configuration
DmClientIntType = "integer"
// Bool type used by the DM client configuration
DmClientBoolType = "boolean"
// Additional Context items present on the RequestSecurityToken token message
ReqSecTokenContextItemUXInitiated = "UXInitiated"
ReqSecTokenContextItemHWDevID = "HWDevID"
ReqSecTokenContextItemLocale = "Locale"
ReqSecTokenContextItemTargetedUserLoggedIn = "TargetedUserLoggedIn"
ReqSecTokenContextItemOSEdition = "OSEdition"
ReqSecTokenContextItemDeviceName = "DeviceName"
ReqSecTokenContextItemDeviceID = "DeviceID"
ReqSecTokenContextItemEnrollmentType = "EnrollmentType"
ReqSecTokenContextItemDeviceType = "DeviceType"
ReqSecTokenContextItemOSVersion = "OSVersion"
ReqSecTokenContextItemApplicationVersion = "ApplicationVersion"
ReqSecTokenContextItemNotInOobe = "NotInOobe"
ReqSecTokenContextItemRequestVersion = "RequestVersion"
// APPRU query param expected by STS Auth endpoint
STSAuthAppRu = "appru"
// Login related query param expected by STS Auth endpoint
STSLoginHint = "login_hint"
// redirect_uri query param expected by TOS endpoint
TOCRedirectURI = "redirect_uri"
// client-request-id query param expected by TOS endpoint
TOCReqID = "client-request-id"
// Alert payload user-driven unenrollment request
AlertUserUnenrollmentRequest = "com.microsoft:mdm.unenrollment.userrequest"
// FleetdWindowsInstallerGUID is the GUID used for fleetd on Windows
FleetdWindowsInstallerGUID = "./Device/Vendor/MSFT/EnterpriseDesktopAppManagement/MSI/%7BA427C0AA-E2D5-40DF-ACE8-0D726A6BE096%7D/DownloadInstall"
)
// MS-MDM Message constants
const (
// SyncML Message Content Type
SyncMLMsgContentType = "application/vnd.syncml.dm+xml"
// SyncML Message Meta Namespace
SyncMLMetaNamespace = "syncml:metinf"
// SyncML Cmd Namespace
SyncCmdNamespace = "SYNCML:SYNCML1.2"
// SyncML Message Header Name
SyncMLHdrName = "SyncHdr"
// Supported SyncML version
SyncMLSupportedVersion = "1.2"
// SyncML ver protocol version
SyncMLVerProto = "DM/" + SyncMLSupportedVersion
)

View file

@ -18,6 +18,7 @@ import (
"time"
"github.com/fleetdm/fleet/v4/server"
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/syncml"
"github.com/golang-jwt/jwt/v4"
"github.com/micromdm/nanomdm/cryptoutil"
"go.mozilla.org/pkcs7"
@ -293,7 +294,7 @@ func GetAzureAuthTokenClaims(tokenStr string) (AzureData, error) {
}
func populateClientCert(sn *big.Int, subject string, issuerCert *x509.Certificate, csr *x509.CertificateRequest) (*x509.Certificate, error) {
certRenewalPeriodInSecsInt, err := strconv.Atoi(PolicyCertRenewalPeriodInSecs)
certRenewalPeriodInSecsInt, err := strconv.Atoi(syncml.PolicyCertRenewalPeriodInSecs)
if err != nil {
return nil, fmt.Errorf("invalid renewal time: %w", err)
}
@ -302,7 +303,7 @@ func populateClientCert(sn *big.Int, subject string, issuerCert *x509.Certificat
yearDuration := 365 * 24 * time.Hour
certSubject := pkix.Name{
OrganizationalUnit: []string{DocProvisioningAppProviderID},
OrganizationalUnit: []string{syncml.DocProvisioningAppProviderID},
CommonName: subject,
}
@ -335,7 +336,7 @@ func populateClientCert(sn *big.Int, subject string, issuerCert *x509.Certificat
// GetClientCSR returns the client certificate signing request from the BinarySecurityToken
func GetClientCSR(binSecTokenData string, tokenType string) (*x509.CertificateRequest, error) {
// Checking if this is a valid enroll security token (CSR)
if (tokenType != EnrollReqTypePKCS10) && (tokenType != EnrollReqTypePKCS7) {
if (tokenType != syncml.EnrollReqTypePKCS10) && (tokenType != syncml.EnrollReqTypePKCS7) {
return nil, fmt.Errorf("token type is not valid for MDM enrollment: %s", tokenType)
}
@ -347,7 +348,7 @@ func GetClientCSR(binSecTokenData string, tokenType string) (*x509.CertificateRe
// Sanity checks on binary signature token
// Sanity checks are done on PKCS10 for the moment
if tokenType == EnrollReqTypePKCS7 {
if tokenType == syncml.EnrollReqTypePKCS7 {
// Parse the CSR in PKCS7 Syntax Standard
pk7CSR, err := pkcs7.Parse(rawCSR)
if err != nil {

View file

@ -39,6 +39,7 @@ import (
apple_mdm "github.com/fleetdm/fleet/v4/server/mdm/apple"
"github.com/fleetdm/fleet/v4/server/mdm/apple/mobileconfig"
microsoft_mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/syncml"
"github.com/fleetdm/fleet/v4/server/ptr"
"github.com/fleetdm/fleet/v4/server/service/mock"
"github.com/fleetdm/fleet/v4/server/service/schedule"
@ -6864,7 +6865,7 @@ func (s *integrationMDMTestSuite) TestValidDiscoveryRequest() {
resBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.SoapContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.SoapContentType)
// Checking if SOAP response can be unmarshalled to an golang type
var xmlType interface{}
@ -6915,7 +6916,7 @@ func (s *integrationMDMTestSuite) TestInvalidDiscoveryRequest() {
resBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.SoapContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.SoapContentType)
// Checking if response can be unmarshalled to an golang type
var xmlType interface{}
@ -6967,7 +6968,7 @@ func (s *integrationMDMTestSuite) TestNoEmailDiscoveryRequest() {
resBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.SoapContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.SoapContentType)
// Checking if SOAP response can be unmarshalled to an golang type
var xmlType interface{}
@ -7002,7 +7003,7 @@ func (s *integrationMDMTestSuite) TestValidGetPoliciesRequestWithDeviceToken() {
resBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.SoapContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.SoapContentType)
// Checking if SOAP response can be unmarshalled to an golang type
var xmlType interface{}
@ -7032,7 +7033,7 @@ func (s *integrationMDMTestSuite) TestValidGetPoliciesRequestWithAzureToken() {
resBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.SoapContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.SoapContentType)
// Checking if SOAP response can be unmarshalled to an golang type
var xmlType interface{}
@ -7075,7 +7076,7 @@ func (s *integrationMDMTestSuite) TestGetPoliciesRequestWithInvalidUUID() {
resBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.SoapContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.SoapContentType)
// Checking if SOAP response can be unmarshalled to an golang type
var xmlType interface{}
@ -7108,7 +7109,7 @@ func (s *integrationMDMTestSuite) TestGetPoliciesRequestWithNotElegibleHost() {
resBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.SoapContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.SoapContentType)
// Checking if SOAP response can be unmarshalled to an golang type
var xmlType interface{}
@ -7142,7 +7143,7 @@ func (s *integrationMDMTestSuite) TestValidRequestSecurityTokenRequestWithDevice
resBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.SoapContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.SoapContentType)
// Checking if SOAP response can be unmarshalled to an golang type
var xmlType interface{}
@ -7193,7 +7194,7 @@ func (s *integrationMDMTestSuite) TestValidRequestSecurityTokenRequestWithAzureT
resBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.SoapContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.SoapContentType)
// Checking if SOAP response can be unmarshalled to an golang type
var xmlType interface{}
@ -7245,7 +7246,7 @@ func (s *integrationMDMTestSuite) TestInvalidRequestSecurityTokenRequestWithMiss
resBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.SoapContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.SoapContentType)
// Checking if SOAP response can be unmarshalled to an golang type
var xmlType interface{}
@ -7305,7 +7306,7 @@ func (s *integrationMDMTestSuite) TestValidGetTOC() {
resBytes, err := io.ReadAll(resp.Body)
require.NoError(t, err)
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.WebContainerContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.WebContainerContentType)
resTOCcontent := string(resBytes)
require.Contains(t, resTOCcontent, "Microsoft.AAD.BrokerPlugin")
@ -7547,8 +7548,8 @@ func (s *integrationMDMTestSuite) TestWindowsAutomaticEnrollmentCommands() {
fleetdExecCmd = c
}
}
require.Equal(t, microsoft_mdm.FleetdWindowsInstallerGUID, fleetdAddCmd.Cmd.GetTargetURI())
require.Equal(t, microsoft_mdm.FleetdWindowsInstallerGUID, fleetdExecCmd.Cmd.GetTargetURI())
require.Equal(t, syncml.FleetdWindowsInstallerGUID, fleetdAddCmd.Cmd.GetTargetURI())
require.Equal(t, syncml.FleetdWindowsInstallerGUID, fleetdExecCmd.Cmd.GetTargetURI())
}
func (s *integrationMDMTestSuite) TestValidManagementUnenrollRequest() {
@ -7590,7 +7591,7 @@ func (s *integrationMDMTestSuite) TestValidManagementUnenrollRequest() {
// Checking that Command error code was updated
// Checking response headers
require.Contains(t, resp.Header["Content-Type"], microsoft_mdm.SyncMLContentType)
require.Contains(t, resp.Header["Content-Type"], syncml.SyncMLContentType)
// Read response data
resBytes, err := io.ReadAll(resp.Body)
@ -8107,8 +8108,8 @@ func (s *integrationMDMTestSuite) TestMDMConfigProfileCRUD() {
assertAppleProfile("foo.txt", "foo", "foo-ident", 0, http.StatusBadRequest, "Couldn't upload. The file should be a .mobileconfig or .xml file.")
// Windows-reserved LocURI
assertWindowsProfile("bitlocker.xml", "bitlocker", microsoft_mdm.FleetBitLockerTargetLocURI, 0, http.StatusBadRequest, "Couldn't upload. Custom configuration profiles can't include BitLocker settings.")
assertWindowsProfile("updates.xml", "updates", microsoft_mdm.FleetOSUpdateTargetLocURI, testTeam.ID, http.StatusBadRequest, "Couldn't upload. Custom configuration profiles can't include Windows updates settings.")
assertWindowsProfile("bitlocker.xml", "bitlocker", syncml.FleetBitLockerTargetLocURI, 0, http.StatusBadRequest, "Couldn't upload. Custom configuration profiles can't include BitLocker settings.")
assertWindowsProfile("updates.xml", "updates", syncml.FleetOSUpdateTargetLocURI, testTeam.ID, http.StatusBadRequest, "Couldn't upload. Custom configuration profiles can't include Windows updates settings.")
// Windows invalid content
body, headers := generateNewProfileMultipartRequest(t, nil, "win.xml", []byte("\x00\x01\x02"), s.token)
@ -9178,9 +9179,9 @@ func (s *integrationMDMTestSuite) newGetPoliciesMsg(deviceToken bool, encodedBin
}
// JWT token by default
tokType := microsoft_mdm.BinarySecurityAzureEnroll
tokType := syncml.BinarySecurityAzureEnroll
if deviceToken {
tokType = microsoft_mdm.BinarySecurityDeviceEnroll
tokType = syncml.BinarySecurityDeviceEnroll
}
return []byte(`
@ -9222,9 +9223,9 @@ func (s *integrationMDMTestSuite) newSecurityTokenMsg(encodedBinToken string, de
}
// JWT token by default
tokType := microsoft_mdm.BinarySecurityAzureEnroll
tokType := syncml.BinarySecurityAzureEnroll
if deviceToken {
tokType = microsoft_mdm.BinarySecurityDeviceEnroll
tokType = syncml.BinarySecurityDeviceEnroll
}
// Preparing the RequestSecurityToken Request message
@ -9454,9 +9455,9 @@ func (s *integrationMDMTestSuite) TestWindowsProfileManagement() {
}
verifyProfiles := func(device *mdmtest.TestWindowsMDMClient, n int, fail bool) {
mdmResponseStatus := microsoft_mdm.CmdStatusOK
mdmResponseStatus := syncml.CmdStatusOK
if fail {
mdmResponseStatus = microsoft_mdm.CmdStatusAtomicFailed
mdmResponseStatus = syncml.CmdStatusAtomicFailed
}
s.awaitTriggerProfileSchedule(t)
cmds, err := device.StartManagementSession()
@ -9469,7 +9470,7 @@ func (s *integrationMDMTestSuite) TestWindowsProfileManagement() {
require.NoError(t, err)
for _, c := range cmds {
cmdID := c.Cmd.CmdID
status := microsoft_mdm.CmdStatusOK
status := syncml.CmdStatusOK
if c.Verb == "Atomic" {
atomicCmds = append(atomicCmds, c)
status = mdmResponseStatus
@ -9761,18 +9762,18 @@ func (s *integrationMDMTestSuite) TestBatchSetMDMProfiles() {
// profiles with reserved Windows location URIs
// bitlocker
res := s.Do("POST", "/api/v1/fleet/mdm/profiles/batch", batchSetMDMProfilesRequest{Profiles: map[string][]byte{
"N1": mobileconfigForTest("N1", "I1"),
microsoft_mdm.FleetBitLockerTargetLocURI: syncMLForTest(fmt.Sprintf("%s/Foo", microsoft_mdm.FleetBitLockerTargetLocURI)),
"N3": syncMLForTest("./Foo/Bar"),
"N1": mobileconfigForTest("N1", "I1"),
syncml.FleetBitLockerTargetLocURI: syncMLForTest(fmt.Sprintf("%s/Foo", syncml.FleetBitLockerTargetLocURI)),
"N3": syncMLForTest("./Foo/Bar"),
}}, http.StatusUnprocessableEntity, "team_id", strconv.Itoa(int(tm.ID)))
errMsg := extractServerErrorText(res.Body)
require.Contains(t, errMsg, "Custom configuration profiles can't include BitLocker settings. To control these settings, use the mdm.enable_disk_encryption option.")
// os updates
res = s.Do("POST", "/api/v1/fleet/mdm/profiles/batch", batchSetMDMProfilesRequest{Profiles: map[string][]byte{
"N1": mobileconfigForTest("N1", "I1"),
microsoft_mdm.FleetOSUpdateTargetLocURI: syncMLForTest(fmt.Sprintf("%s/Foo", microsoft_mdm.FleetOSUpdateTargetLocURI)),
"N3": syncMLForTest("./Foo/Bar"),
"N1": mobileconfigForTest("N1", "I1"),
syncml.FleetOSUpdateTargetLocURI: syncMLForTest(fmt.Sprintf("%s/Foo", syncml.FleetOSUpdateTargetLocURI)),
"N3": syncMLForTest("./Foo/Bar"),
}}, http.StatusUnprocessableEntity, "team_id", strconv.Itoa(int(tm.ID)))
errMsg = extractServerErrorText(res.Body)
require.Contains(t, errMsg, "Custom configuration profiles can't include Windows updates settings. To control these settings, use the mdm.windows_updates option.")

View file

@ -23,11 +23,12 @@ import (
"github.com/fleetdm/fleet/v4/server/contexts/ctxerr"
"github.com/fleetdm/fleet/v4/server/contexts/logging"
"github.com/fleetdm/fleet/v4/server/fleet"
microsoft_mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/syncml"
kitlog "github.com/go-kit/kit/log"
"github.com/go-kit/log/level"
mdm_types "github.com/fleetdm/fleet/v4/server/fleet"
mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
"github.com/google/uuid"
)
@ -80,7 +81,7 @@ func (r SoapResponseContainer) hijackRender(ctx context.Context, w http.Response
xmlRes = append(xmlRes, '\n')
w.Header().Set("Content-Type", mdm.SoapContentType)
w.Header().Set("Content-Type", syncml.SoapContentType)
w.Header().Set("Content-Length", strconv.Itoa(len(xmlRes)))
w.WriteHeader(http.StatusOK)
if n, err := w.Write(xmlRes); err != nil {
@ -141,7 +142,7 @@ func (r SyncMLResponseMsgContainer) hijackRender(ctx context.Context, w http.Res
xmlRes = append(xmlRes, '\n')
w.Header().Set("Content-Type", mdm.SyncMLContentType)
w.Header().Set("Content-Type", syncml.SyncMLContentType)
w.Header().Set("Content-Length", strconv.Itoa(len(xmlRes)))
w.WriteHeader(http.StatusOK)
if n, err := w.Write(xmlRes); err != nil {
@ -178,7 +179,7 @@ func (req MDMWebContainer) error() error { return req.Err }
func (req MDMWebContainer) hijackRender(ctx context.Context, w http.ResponseWriter) {
resData := []byte(*req.Data + "\n")
w.Header().Set("Content-Type", mdm.WebContainerContentType)
w.Header().Set("Content-Type", syncml.WebContainerContentType)
w.Header().Set("Content-Length", strconv.Itoa(len(resData)))
w.WriteHeader(http.StatusOK)
if n, err := w.Write(resData); err != nil {
@ -221,10 +222,10 @@ func NewDiscoverResponse(authPolicy string, policyUrl string, enrollmentUrl stri
}
return mdm_types.DiscoverResponse{
XMLNS: mdm.DiscoverNS,
XMLNS: syncml.DiscoverNS,
DiscoverResult: mdm_types.DiscoverResult{
AuthPolicy: authPolicy,
EnrollmentVersion: mdm.EnrollmentVersionV4,
EnrollmentVersion: syncml.EnrollmentVersionV4,
EnrollmentPolicyServiceUrl: policyUrl,
EnrollmentServiceUrl: enrollmentUrl,
},
@ -238,25 +239,25 @@ func NewGetPoliciesResponse(minimalKeyLength string, certificateValidityPeriodSe
}
return mdm_types.GetPoliciesResponse{
XMLNS: mdm.PolicyNS,
XMLNS: syncml.PolicyNS,
Response: mdm_types.Response{
PolicyFriendlyName: mdm_types.ContentAttr{
Xsi: mdm.DefaultStateXSI,
XMLNS: mdm.EnrollXSI,
Xsi: syncml.DefaultStateXSI,
XMLNS: syncml.EnrollXSI,
},
NextUpdateHours: mdm_types.ContentAttr{
Xsi: mdm.DefaultStateXSI,
XMLNS: mdm.EnrollXSI,
Xsi: syncml.DefaultStateXSI,
XMLNS: syncml.EnrollXSI,
},
PoliciesNotChanged: mdm_types.ContentAttr{
Xsi: mdm.DefaultStateXSI,
XMLNS: mdm.EnrollXSI,
Xsi: syncml.DefaultStateXSI,
XMLNS: syncml.EnrollXSI,
},
Policies: mdm_types.Policies{
Policy: mdm_types.GPPolicy{
PolicyOIDReference: "0",
CAs: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
Attributes: mdm_types.Attributes{
CommonName: "FleetDMAttributes",
@ -275,42 +276,42 @@ func NewGetPoliciesResponse(minimalKeyLength string, certificateValidityPeriodSe
AutoEnroll: "false",
},
SupersededPolicies: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
PrivateKeyFlags: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
SubjectNameFlags: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
EnrollmentFlags: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
GeneralFlags: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
RARequirements: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
KeyArchivalAttributes: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
Extensions: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
PrivateKeyAttributes: mdm_types.PrivateKeyAttributes{
MinimalKeyLength: minimalKeyLength,
KeySpec: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
KeyUsageProperty: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
Permissions: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
AlgorithmOIDReference: mdm_types.GenericAttr{
Xsi: mdm.DefaultStateXSI,
Xsi: syncml.DefaultStateXSI,
},
CryptoProviders: []mdm_types.ProviderAttr{
{Content: "Microsoft Platform Crypto Provider"},
@ -352,25 +353,25 @@ func NewRequestSecurityTokenResponseCollection(provisionedToken string) (mdm_typ
return mdm_types.RequestSecurityTokenResponseCollection{}, errors.New("invalid parameters")
}
enrollSecExtVal := mdm.EnrollSecExt
enrollSecExtVal := syncml.EnrollSecExt
return mdm_types.RequestSecurityTokenResponseCollection{
XMLNS: mdm.EnrollWSTrust,
XMLNS: syncml.EnrollWSTrust,
RequestSecurityTokenResponse: mdm_types.RequestSecurityTokenResponse{
TokenType: mdm.EnrollTType,
TokenType: syncml.EnrollTType,
DispositionMessage: mdm_types.SecAttr{
Content: "",
XMLNS: mdm.EnrollReq,
XMLNS: syncml.EnrollReq,
},
RequestID: mdm_types.SecAttr{
Content: "0",
XMLNS: mdm.EnrollReq,
XMLNS: syncml.EnrollReq,
},
RequestedSecurityToken: mdm_types.RequestedSecurityToken{
BinarySecurityToken: mdm_types.BinarySecurityToken{
Content: provisionedToken,
XMLNS: &enrollSecExtVal,
ValueType: mdm.EnrollPDoc,
EncodingType: mdm.EnrollEncode,
ValueType: syncml.EnrollPDoc,
EncodingType: syncml.EnrollEncode,
},
},
},
@ -382,7 +383,7 @@ func NewSoapFault(errorType string, origMessage int, errorMessage error) mdm_typ
return mdm_types.SoapFault{
OriginalMessageType: origMessage,
Code: mdm_types.Code{
Value: mdm.SoapFaultRecv,
Value: syncml.SoapFaultRecv,
Subcode: mdm_types.Subcode{
Value: errorType,
},
@ -390,7 +391,7 @@ func NewSoapFault(errorType string, origMessage int, errorMessage error) mdm_typ
Reason: mdm_types.Reason{
Text: mdm_types.ReasonText{
Content: errorMessage.Error(),
Lang: mdm.SoapFaultLocale,
Lang: syncml.SoapFaultLocale,
},
},
}
@ -427,16 +428,16 @@ func NewSoapResponse(payload interface{}, relatesTo string) (fleet.SoapResponse,
// Useful constants
// Some of these are string urls to be assigned to pointers - they need to have a type and cannot be const literals
var (
urlNSS = mdm.EnrollNSS
urlNSA = mdm.EnrollNSA
urlXSI = mdm.EnrollXSI
urlXSD = mdm.EnrollXSD
urlXSU = mdm.EnrollXSU
urlDiag = mdm.ActionNsDiag
urlDiscovery = mdm.ActionNsDiscovery
urlPolicy = mdm.ActionNsPolicy
urlEnroll = mdm.ActionNsEnroll
urlSecExt = mdm.EnrollSecExt
urlNSS = syncml.EnrollNSS
urlNSA = syncml.EnrollNSA
urlXSI = syncml.EnrollXSI
urlXSD = syncml.EnrollXSD
urlXSU = syncml.EnrollXSU
urlDiag = syncml.ActionNsDiag
urlDiscovery = syncml.ActionNsDiscovery
urlPolicy = syncml.ActionNsPolicy
urlEnroll = syncml.ActionNsEnroll
urlSecExt = syncml.EnrollSecExt
MUValue = "1"
timestampID = "_0"
secWindowStartTimeMin = -5
@ -600,9 +601,9 @@ func NewCertStoreProvisioningData(enrollmentType string, identityFingerprint str
}),
newCharacteristic("WSTEP", nil, []mdm_types.Characteristic{
newCharacteristic("Renew", []mdm_types.Param{
newParm("ROBOSupport", mdm.WstepROBOSupport, "boolean"),
newParm("RenewPeriod", mdm.WstepCertRenewalPeriodInDays, "integer"),
newParm("RetryInterval", mdm.WstepRenewRetryInterval, "integer"),
newParm("ROBOSupport", syncml.WstepROBOSupport, "boolean"),
newParm("RenewPeriod", syncml.WstepCertRenewalPeriodInDays, "integer"),
newParm("RetryInterval", syncml.WstepRenewRetryInterval, "integer"),
}, nil),
}),
})
@ -618,13 +619,13 @@ func NewCertStoreProvisioningData(enrollmentType string, identityFingerprint str
func NewApplicationProvisioningData(mdmEndpoint string) mdm_types.Characteristic {
provDoc := newCharacteristic("APPLICATION", []mdm_types.Param{
// The PROVIDER-ID parameter specifies the server identifier for a management server used in the current management session
newParm("PROVIDER-ID", mdm.DocProvisioningAppProviderID, ""),
newParm("PROVIDER-ID", syncml.DocProvisioningAppProviderID, ""),
// The APPID parameter is used to differentiate the types of available application services and protocols.
newParm("APPID", "w7", ""),
// The NAME parameter is used in the APPLICATION characteristic to specify a user readable application identity.
newParm("NAME", mdm.DocProvisioningAppName, ""),
newParm("NAME", syncml.DocProvisioningAppName, ""),
// The ADDR parameter is used in the APPADDR param to get or set the address of the OMA DM server.
newParm("ADDR", mdmEndpoint, ""),
@ -632,13 +633,13 @@ func NewApplicationProvisioningData(mdmEndpoint string) mdm_types.Characteristic
// The ROLE parameter is used in the APPLICATION characteristic to specify the security application chamber that the DM session should run with when communicating with the DM server.
// The BACKCOMPATRETRYFREQ parameter is used to specify how many retries the DM client performs when there are Connection Manager-level or WinInet-level errors
newParm("CONNRETRYFREQ", mdm.DocProvisioningAppConnRetryFreq, ""),
newParm("CONNRETRYFREQ", syncml.DocProvisioningAppConnRetryFreq, ""),
// The INITIALBACKOFFTIME parameter is used to specify the initial wait time in milliseconds when the DM client retries for the first time
newParm("INITIALBACKOFFTIME", mdm.DocProvisioningAppInitialBackoffTime, ""),
newParm("INITIALBACKOFFTIME", syncml.DocProvisioningAppInitialBackoffTime, ""),
// The MAXBACKOFFTIME parameter is used to specify the maximum number of milliseconds to sleep after package-sending failure
newParm("MAXBACKOFFTIME", mdm.DocProvisioningAppMaxBackoffTime, ""),
newParm("MAXBACKOFFTIME", syncml.DocProvisioningAppMaxBackoffTime, ""),
// The DEFAULTENCODING parameter is used to specify whether the DM client should use WBXML or XML for the DM package when communicating with the server.
newParm("DEFAULTENCODING", "application/vnd.syncml.dm+xml", ""),
@ -676,17 +677,17 @@ func NewApplicationProvisioningData(mdmEndpoint string) mdm_types.Characteristic
func NewDMClientProvisioningData() mdm_types.Characteristic {
dmClient := newCharacteristic("DMClient", nil, []mdm_types.Characteristic{
newCharacteristic("Provider", nil, []mdm_types.Characteristic{
newCharacteristic(mdm.DocProvisioningAppProviderID,
newCharacteristic(syncml.DocProvisioningAppProviderID,
[]mdm_types.Param{}, []mdm_types.Characteristic{
newCharacteristic("Poll", []mdm_types.Param{
newParm("NumberOfFirstRetries", mdm.DmClientCSPNumberOfFirstRetries, mdm.DmClientIntType),
newParm("IntervalForFirstSetOfRetries", mdm.DmClientCSPIntervalForFirstSetOfRetries, mdm.DmClientIntType),
newParm("NumberOfSecondRetries", mdm.DmClientCSPNumberOfSecondRetries, mdm.DmClientIntType),
newParm("IntervalForSecondSetOfRetries", mdm.DmClientCSPIntervalForSecondSetOfRetries, mdm.DmClientIntType),
newParm("NumberOfRemainingScheduledRetries", mdm.DmClientCSPNumberOfRemainingScheduledRetries, mdm.DmClientIntType),
newParm("IntervalForRemainingScheduledRetries", mdm.DmClientCSPIntervalForRemainingScheduledRetries, mdm.DmClientIntType),
newParm("PollOnLogin", mdm.DmClientCSPPollOnLogin, mdm.DmClientBoolType),
newParm("AllUsersPollOnFirstLogin", mdm.DmClientCSPPollOnLogin, mdm.DmClientBoolType),
newParm("NumberOfFirstRetries", syncml.DmClientCSPNumberOfFirstRetries, syncml.DmClientIntType),
newParm("IntervalForFirstSetOfRetries", syncml.DmClientCSPIntervalForFirstSetOfRetries, syncml.DmClientIntType),
newParm("NumberOfSecondRetries", syncml.DmClientCSPNumberOfSecondRetries, syncml.DmClientIntType),
newParm("IntervalForSecondSetOfRetries", syncml.DmClientCSPIntervalForSecondSetOfRetries, syncml.DmClientIntType),
newParm("NumberOfRemainingScheduledRetries", syncml.DmClientCSPNumberOfRemainingScheduledRetries, syncml.DmClientIntType),
newParm("IntervalForRemainingScheduledRetries", syncml.DmClientCSPIntervalForRemainingScheduledRetries, syncml.DmClientIntType),
newParm("PollOnLogin", syncml.DmClientCSPPollOnLogin, syncml.DmClientBoolType),
newParm("AllUsersPollOnFirstLogin", syncml.DmClientCSPPollOnLogin, syncml.DmClientBoolType),
}, nil),
}),
}),
@ -698,7 +699,7 @@ func NewDMClientProvisioningData() mdm_types.Characteristic {
// NewProvisioningDoc returns a new ProvisioningDoc container
func NewProvisioningDoc(certStoreData mdm_types.Characteristic, applicationData mdm_types.Characteristic, dmClientData mdm_types.Characteristic) mdm_types.WapProvisioningDoc {
return mdm_types.WapProvisioningDoc{
Version: mdm.DocProvisioningVersion,
Version: syncml.DocProvisioningVersion,
Characteristics: []mdm_types.Characteristic{
certStoreData,
applicationData,
@ -714,21 +715,21 @@ func mdmMicrosoftDiscoveryEndpoint(ctx context.Context, request interface{}, svc
// Checking first if Discovery message is valid and returning error if this is not the case
if err := req.IsValidDiscoveryMsg(); err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEDiscovery, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEDiscovery, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
// Getting the DiscoveryResponse message
discoveryResponseMsg, err := svc.GetMDMMicrosoftDiscoveryResponse(ctx, req.Body.Discover.Request.EmailAddress)
if err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEDiscovery, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEDiscovery, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
// Embedding the DiscoveryResponse message inside of a SoapResponse
response, err := NewSoapResponse(discoveryResponseMsg, req.GetMessageID())
if err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEDiscovery, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEDiscovery, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
@ -743,12 +744,12 @@ func mdmMicrosoftAuthEndpoint(ctx context.Context, request interface{}, svc flee
params := request.(*SoapRequestContainer).Params
// Sanity check on the expected query params
if !params.Has(mdm.STSAuthAppRu) || !params.Has(mdm.STSLoginHint) {
if !params.Has(syncml.STSAuthAppRu) || !params.Has(syncml.STSLoginHint) {
return getSTSAuthContent(""), errors.New("expected STS params are not present")
}
appru := params.Get(mdm.STSAuthAppRu)
loginHint := params.Get(mdm.STSLoginHint)
appru := params.Get(syncml.STSAuthAppRu)
loginHint := params.Get(syncml.STSLoginHint)
if (len(appru) == 0) || (len(loginHint) == 0) {
return getSTSAuthContent(""), errors.New("expected STS params are empty")
@ -770,28 +771,28 @@ func mdmMicrosoftPolicyEndpoint(ctx context.Context, request interface{}, svc fl
// Checking first if GetPolicies message is valid and returning error if this is not the case
if err := req.IsValidGetPolicyMsg(); err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEPolicy, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEPolicy, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
// Binary security token should be extracted to ensure this is a valid call
hdrSecToken, err := req.GetHeaderBinarySecurityToken()
if err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEPolicy, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEPolicy, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
// Getting the GetPoliciesResponse message
policyResponseMsg, err := svc.GetMDMWindowsPolicyResponse(ctx, hdrSecToken)
if err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEPolicy, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEPolicy, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
// Embedding the DiscoveryResponse message inside of a SoapResponse
response, err := NewSoapResponse(policyResponseMsg, req.GetMessageID())
if err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEPolicy, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEPolicy, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
@ -808,35 +809,35 @@ func mdmMicrosoftEnrollEndpoint(ctx context.Context, request interface{}, svc fl
// Checking first if RequestSecurityToken message is valid and returning error if this is not the case
if err := req.IsValidRequestSecurityTokenMsg(); err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
// Getting the RequestSecurityToken message from the SOAP request
reqSecurityTokenMsg, err := req.GetRequestSecurityTokenMessage()
if err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
// Binary security token should be extracted to ensure this is a valid call
hdrBinarySecToken, err := req.GetHeaderBinarySecurityToken()
if err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
// Getting the RequestSecurityTokenResponseCollection message
enrollResponseMsg, err := svc.GetMDMWindowsEnrollResponse(ctx, reqSecurityTokenMsg, hdrBinarySecToken)
if err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
// Embedding the DiscoveryResponse message inside of a SoapResponse
response, err := NewSoapResponse(enrollResponseMsg, req.GetMessageID())
if err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
return getSoapResponseFault(req.GetMessageID(), soapFault), nil
}
@ -857,14 +858,14 @@ func mdmMicrosoftManagementEndpoint(ctx context.Context, request interface{}, sv
// Checking first if incoming SyncML message is valid and returning error if this is not the case
if err := reqSyncML.IsValidMsg(); err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MSMDM, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MSMDM, err)
return getSoapResponseFault(reqSyncML.SyncHdr.MsgID, soapFault), nil
}
// Getting the MS-MDM response message
resSyncML, err := svc.GetMDMWindowsManagementResponse(ctx, reqSyncML, reqCerts)
if err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MSMDM, err)
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MSMDM, err)
return getSoapResponseFault(reqSyncML.SyncHdr.MsgID, soapFault), nil
}
@ -879,19 +880,19 @@ func mdmMicrosoftTOSEndpoint(ctx context.Context, request interface{}, svc fleet
params := request.(*MDMWebContainer).Params
// Sanity check on the expected query params
if !params.Has(mdm.TOCRedirectURI) || !params.Has(mdm.TOCReqID) {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEEnrollment, errors.New("invalid params"))
return getSoapResponseFault(mdm.SoapErrorInternalServiceFault, soapFault), nil
if !params.Has(syncml.TOCRedirectURI) || !params.Has(syncml.TOCReqID) {
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEEnrollment, errors.New("invalid params"))
return getSoapResponseFault(syncml.SoapErrorInternalServiceFault, soapFault), nil
}
redirectURI := params.Get(mdm.TOCRedirectURI)
reqID := params.Get(mdm.TOCReqID)
redirectURI := params.Get(syncml.TOCRedirectURI)
reqID := params.Get(syncml.TOCReqID)
// Getting the TOS content message
resTOCData, err := svc.GetMDMWindowsTOSContent(ctx, redirectURI, reqID)
if err != nil {
soapFault := svc.GetAuthorizedSoapFault(ctx, mdm.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
return getSoapResponseFault(mdm.SoapErrorInternalServiceFault, soapFault), nil
soapFault := svc.GetAuthorizedSoapFault(ctx, syncml.SoapErrorMessageFormat, mdm_types.MDEEnrollment, err)
return getSoapResponseFault(syncml.SoapErrorInternalServiceFault, soapFault), nil
}
return MDMWebContainer{
@ -961,7 +962,7 @@ func (svc *Service) authBinarySecurityToken(ctx context.Context, authToken *flee
if authToken.IsAzureJWTToken() {
// Validate the JWT Auth token by retreving its claims
tokenData, err := mdm.GetAzureAuthTokenClaims(authToken.Content)
tokenData, err := microsoft_mdm.GetAzureAuthTokenClaims(authToken.Content)
if err != nil {
return "", "", fmt.Errorf("binary security token claim failed: %v", err)
}
@ -985,17 +986,17 @@ func (svc *Service) GetMDMMicrosoftDiscoveryResponse(ctx context.Context, upnEma
}
// Getting the DiscoveryResponse message content
urlPolicyEndpoint, err := mdm.ResolveWindowsMDMPolicy(appCfg.ServerSettings.ServerURL)
urlPolicyEndpoint, err := microsoft_mdm.ResolveWindowsMDMPolicy(appCfg.ServerSettings.ServerURL)
if err != nil {
return nil, ctxerr.Wrap(ctx, err, "resolve policy endpoint")
}
urlEnrollEndpoint, err := mdm.ResolveWindowsMDMEnroll(appCfg.ServerSettings.ServerURL)
urlEnrollEndpoint, err := microsoft_mdm.ResolveWindowsMDMEnroll(appCfg.ServerSettings.ServerURL)
if err != nil {
return nil, ctxerr.Wrap(ctx, err, "resolve enroll endpoint")
}
discoveryMsg, err := NewDiscoverResponse(mdm.AuthOnPremise, urlPolicyEndpoint, urlEnrollEndpoint)
discoveryMsg, err := NewDiscoverResponse(syncml.AuthOnPremise, urlPolicyEndpoint, urlEnrollEndpoint)
if err != nil {
return nil, ctxerr.Wrap(ctx, err, "creation of DiscoverResponse message")
}
@ -1073,7 +1074,7 @@ func (svc *Service) GetMDMWindowsPolicyResponse(ctx context.Context, authToken *
svc.authz.SkipAuthorization(ctx)
// Getting the GetPoliciesResponse message content
policyMsg, err := NewGetPoliciesResponse(mdm.PolicyMinKeyLength, mdm.PolicyCertValidityPeriodInSecs, mdm.PolicyCertRenewalPeriodInSecs)
policyMsg, err := NewGetPoliciesResponse(syncml.PolicyMinKeyLength, syncml.PolicyCertValidityPeriodInSecs, syncml.PolicyCertRenewalPeriodInSecs)
if err != nil {
return nil, ctxerr.Wrap(ctx, err, "creation of GetPoliciesResponse message")
}
@ -1285,7 +1286,7 @@ func (svc *Service) enqueueInstallFleetdCommand(ctx context.Context, deviceID st
<CmdID>` + addCommandUUID + `</CmdID>
<Item>
<Target>
<LocURI>` + mdm.FleetdWindowsInstallerGUID + `</LocURI>
<LocURI>` + syncml.FleetdWindowsInstallerGUID + `</LocURI>
</Target>
</Item>
</Add>`)
@ -1298,7 +1299,7 @@ func (svc *Service) enqueueInstallFleetdCommand(ctx context.Context, deviceID st
<CmdID>` + execCommandUUID + `</CmdID>
<Item>
<Target>
<LocURI>` + mdm.FleetdWindowsInstallerGUID + `</LocURI>
<LocURI>` + syncml.FleetdWindowsInstallerGUID + `</LocURI>
</Target>
<Data>
<MsiInstallJob id="{A427C0AA-E2D5-40DF-ACE8-0D726A6BE096}">
@ -1332,7 +1333,7 @@ func (svc *Service) enqueueInstallFleetdCommand(ctx context.Context, deviceID st
addFleetdCmd := &fleet.MDMWindowsCommand{
CommandUUID: addCommandUUID,
RawCommand: rawAddCmd,
TargetLocURI: mdm.FleetdWindowsInstallerGUID,
TargetLocURI: syncml.FleetdWindowsInstallerGUID,
}
if err := svc.ds.MDMWindowsInsertCommandForHosts(ctx, []string{deviceID}, addFleetdCmd); err != nil {
return ctxerr.Wrap(ctx, err, "insert add command to install fleetd")
@ -1341,7 +1342,7 @@ func (svc *Service) enqueueInstallFleetdCommand(ctx context.Context, deviceID st
execFleetCmd := &fleet.MDMWindowsCommand{
CommandUUID: execCommandUUID,
RawCommand: rawExecCmd,
TargetLocURI: mdm.FleetdWindowsInstallerGUID,
TargetLocURI: syncml.FleetdWindowsInstallerGUID,
}
if err := svc.ds.MDMWindowsInsertCommandForHosts(ctx, []string{deviceID}, execFleetCmd); err != nil {
return ctxerr.Wrap(ctx, err, "insert exec command to install fleetd")
@ -1380,7 +1381,7 @@ func (svc *Service) processGenericAlert(ctx context.Context, messageID string, d
}
// Checking if user-initiated unenrollment request is present
if *item.Meta.Type.Content == mdm.AlertUserUnenrollmentRequest {
if *item.Meta.Type.Content == syncml.AlertUserUnenrollmentRequest {
// Deleting the device from the list of enrolled device
err := svc.ds.MDMWindowsDeleteEnrolledDeviceWithDeviceID(ctx, deviceID)
@ -1405,11 +1406,11 @@ func (svc *Service) processIncomingAlertsCommands(ctx context.Context, messageID
alertID := *cmd.Cmd.Data
switch alertID {
case mdm.CmdAlertClientInitiatedManagement:
case syncml.CmdAlertClientInitiatedManagement:
return svc.processNewSessionAlert(ctx, messageID, deviceID, cmd)
case mdm.CmdAlertServerInitiatedManagement:
case syncml.CmdAlertServerInitiatedManagement:
return svc.processNewSessionAlert(ctx, messageID, deviceID, cmd)
case mdm.CmdAlertGeneric:
case syncml.CmdAlertGeneric:
return svc.processGenericAlert(ctx, messageID, deviceID, cmd)
}
@ -1430,7 +1431,7 @@ func (svc *Service) processIncomingMDMCmds(ctx context.Context, deviceID string,
// Acknowledge the message header
// msgref is always 0 for the header
if err = reqMsg.IsValidHeader(); err == nil {
ackMsg := NewSyncMLCmdStatus(reqMessageID, "0", mdm.SyncMLHdrName, mdm.CmdStatusOK)
ackMsg := NewSyncMLCmdStatus(reqMessageID, "0", syncml.SyncMLHdrName, syncml.CmdStatusOK)
responseCmds = append(responseCmds, ackMsg)
}
@ -1453,7 +1454,7 @@ func (svc *Service) processIncomingMDMCmds(ctx context.Context, deviceID string,
}
// CmdStatusOK is returned for the rest of the operations
responseCmds = append(responseCmds, NewSyncMLCmdStatus(reqMessageID, protoCMD.Cmd.CmdID, protoCMD.Verb, mdm.CmdStatusOK))
responseCmds = append(responseCmds, NewSyncMLCmdStatus(reqMessageID, protoCMD.Cmd.CmdID, protoCMD.Verb, syncml.CmdStatusOK))
}
return responseCmds, nil
@ -1506,7 +1507,7 @@ func (svc *Service) createResponseSyncML(ctx context.Context, req *fleet.SyncML,
return nil, fmt.Errorf("appconfig was not available %w", err)
}
urlManagementEndpoint, err := mdm.ResolveWindowsMDMManagement(appConfig.ServerSettings.ServerURL)
urlManagementEndpoint, err := microsoft_mdm.ResolveWindowsMDMManagement(appConfig.ServerSettings.ServerURL)
if err != nil {
return nil, ctxerr.Wrap(ctx, err, "resolve management endpoint")
}
@ -1560,7 +1561,7 @@ func (svc *Service) getManagementResponse(ctx context.Context, reqMsg *fleet.Syn
// HW DeviceID is used to check the list of enrolled devices
func (svc *Service) removeWindowsDeviceIfAlreadyMDMEnrolled(ctx context.Context, secTokenMsg *fleet.RequestSecurityToken) error {
// Getting the HW DeviceID from the RequestSecurityToken msg
reqHWDeviceID, err := GetContextItem(secTokenMsg, mdm.ReqSecTokenContextItemHWDevID)
reqHWDeviceID, err := GetContextItem(secTokenMsg, syncml.ReqSecTokenContextItemHWDevID)
if err != nil {
return err
}
@ -1584,13 +1585,13 @@ func (svc *Service) removeWindowsDeviceIfAlreadyMDMEnrolled(ctx context.Context,
// https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-mde2/35e1aca6-1b8a-48ba-bbc0-23af5d46907a
func (svc *Service) getDeviceProvisioningInformation(ctx context.Context, secTokenMsg *fleet.RequestSecurityToken) (string, error) {
// Getting the HW DeviceID from the RequestSecurityToken msg
reqHWDeviceID, err := GetContextItem(secTokenMsg, mdm.ReqSecTokenContextItemHWDevID)
reqHWDeviceID, err := GetContextItem(secTokenMsg, syncml.ReqSecTokenContextItemHWDevID)
if err != nil {
return "", err
}
// Getting the EnrollmentType information from the RequestSecurityToken msg
reqEnrollType, err := GetContextItem(secTokenMsg, mdm.ReqSecTokenContextItemEnrollmentType)
reqEnrollType, err := GetContextItem(secTokenMsg, syncml.ReqSecTokenContextItemEnrollmentType)
if err != nil {
return "", err
}
@ -1608,7 +1609,7 @@ func (svc *Service) getDeviceProvisioningInformation(ctx context.Context, secTok
}
// Getting the client CSR request from the device
clientCSR, err := mdm.GetClientCSR(binSecurityTokenData, binSecurityTokenType)
clientCSR, err := microsoft_mdm.GetClientCSR(binSecurityTokenData, binSecurityTokenType)
if err != nil {
return "", err
}
@ -1634,7 +1635,7 @@ func (svc *Service) getDeviceProvisioningInformation(ctx context.Context, secTok
}
// Getting the MS-MDM management URL to provision the device
urlManagementEndpoint, err := mdm.ResolveWindowsMDMManagement(appCfg.ServerSettings.ServerURL)
urlManagementEndpoint, err := microsoft_mdm.ResolveWindowsMDMManagement(appCfg.ServerSettings.ServerURL)
if err != nil {
return "", err
}
@ -1662,43 +1663,43 @@ func (svc *Service) storeWindowsMDMEnrolledDevice(ctx context.Context, userID st
)
// Getting the DeviceID context information from the RequestSecurityToken msg
reqDeviceID, err := GetContextItem(secTokenMsg, mdm.ReqSecTokenContextItemDeviceID)
reqDeviceID, err := GetContextItem(secTokenMsg, syncml.ReqSecTokenContextItemDeviceID)
if err != nil {
return fmt.Errorf("%s %v", error_tag, err)
}
// Getting the HWDevID context information from the RequestSecurityToken msg
reqHWDevID, err := GetContextItem(secTokenMsg, mdm.ReqSecTokenContextItemHWDevID)
reqHWDevID, err := GetContextItem(secTokenMsg, syncml.ReqSecTokenContextItemHWDevID)
if err != nil {
return fmt.Errorf("%s %v", error_tag, err)
}
// Getting the Enroll DeviceType context information from the RequestSecurityToken msg
reqDeviceType, err := GetContextItem(secTokenMsg, mdm.ReqSecTokenContextItemDeviceType)
reqDeviceType, err := GetContextItem(secTokenMsg, syncml.ReqSecTokenContextItemDeviceType)
if err != nil {
return fmt.Errorf("%s %v", error_tag, err)
}
// Getting the Enroll DeviceName context information from the RequestSecurityToken msg
reqDeviceName, err := GetContextItem(secTokenMsg, mdm.ReqSecTokenContextItemDeviceName)
reqDeviceName, err := GetContextItem(secTokenMsg, syncml.ReqSecTokenContextItemDeviceName)
if err != nil {
return fmt.Errorf("%s %v", error_tag, err)
}
// Getting the Enroll RequestVersion context information from the RequestSecurityToken msg
reqEnrollVersion, err := GetContextItem(secTokenMsg, mdm.ReqSecTokenContextItemRequestVersion)
reqEnrollVersion, err := GetContextItem(secTokenMsg, syncml.ReqSecTokenContextItemRequestVersion)
if err != nil {
reqEnrollVersion = "request_version_not_present"
}
// Getting the RequestVersion context information from the RequestSecurityToken msg
reqAppVersion, err := GetContextItem(secTokenMsg, mdm.ReqSecTokenContextItemApplicationVersion)
reqAppVersion, err := GetContextItem(secTokenMsg, syncml.ReqSecTokenContextItemApplicationVersion)
if err != nil {
return fmt.Errorf("%s %v", error_tag, err)
}
// Getting the EnrollmentType information from the RequestSecurityToken msg
reqEnrollType, err := GetContextItem(secTokenMsg, mdm.ReqSecTokenContextItemEnrollmentType)
reqEnrollType, err := GetContextItem(secTokenMsg, syncml.ReqSecTokenContextItemEnrollmentType)
if err != nil {
return fmt.Errorf("%s %v", error_tag, err)
}
@ -1707,7 +1708,7 @@ func (svc *Service) storeWindowsMDMEnrolledDevice(ctx context.Context, userID st
enrolledDevice := &fleet.MDMWindowsEnrolledDevice{
MDMDeviceID: reqDeviceID,
MDMHardwareID: reqHWDevID,
MDMDeviceState: mdm.MDMDeviceStateEnrolled,
MDMDeviceState: microsoft_mdm.MDMDeviceStateEnrolled,
MDMDeviceType: reqDeviceType,
MDMDeviceName: reqDeviceName,
MDMEnrollType: reqEnrollType,
@ -1805,10 +1806,10 @@ func createSyncMLMessage(sessionID string, msgID string, deviceID string, source
// setting up things on the SyncML message
var msg mdm_types.SyncML
msg.Xmlns = mdm.SyncCmdNamespace
msg.Xmlns = syncml.SyncCmdNamespace
msg.SyncHdr = mdm_types.SyncHdr{
VerDTD: mdm.SyncMLSupportedVersion,
VerProto: mdm.SyncMLVerProto,
VerDTD: syncml.SyncMLSupportedVersion,
VerProto: syncml.SyncMLVerProto,
SessionID: sessionID,
MsgID: msgID,
Target: &mdm_types.LocURI{LocURI: &deviceID},
@ -2069,6 +2070,14 @@ func (svc *Service) GetMDMWindowsProfilesSummary(ctx context.Context, teamID *ui
}
func ReconcileWindowsProfiles(ctx context.Context, ds fleet.Datastore, logger kitlog.Logger) error {
appConfig, err := ds.AppConfig(ctx)
if err != nil {
return fmt.Errorf("reading app config: %w", err)
}
if !appConfig.MDM.WindowsEnabledAndConfigured {
return nil
}
// retrieve the profiles to install/remove.
toInstall, err := ds.ListMDMWindowsProfilesToInstall(ctx)
if err != nil {

View file

@ -9,8 +9,8 @@ import (
"github.com/fleetdm/fleet/v4/server/fleet"
mdm_types "github.com/fleetdm/fleet/v4/server/fleet"
mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
microsoft_mdm "github.com/fleetdm/fleet/v4/server/mdm/microsoft"
"github.com/fleetdm/fleet/v4/server/mdm/microsoft/syncml"
"github.com/stretchr/testify/require"
)
@ -34,7 +34,7 @@ func NewSoapRequest(request []byte) (fleet.SoapRequest, error) {
func TestValidSoapResponse(t *testing.T) {
relatesTo := "urn:uuid:0d5a1441-5891-453b-becf-a2e5f6ea3749"
soapFaultMsg := NewSoapFault(mdm.SoapErrorAuthentication, mdm_types.MDEDiscovery, errors.New("test"))
soapFaultMsg := NewSoapFault(syncml.SoapErrorAuthentication, mdm_types.MDEDiscovery, errors.New("test"))
sres, err := NewSoapResponse(&soapFaultMsg, relatesTo)
require.NoError(t, err)
outXML, err := xml.MarshalIndent(sres, "", " ")
@ -51,7 +51,7 @@ func TestInvalidSoapResponse(t *testing.T) {
func TestFaultMessageSoapResponse(t *testing.T) {
targetErrorString := "invalid input request"
soapFaultMsg := NewSoapFault(mdm.SoapErrorAuthentication, mdm_types.MDEDiscovery, errors.New(targetErrorString))
soapFaultMsg := NewSoapFault(syncml.SoapErrorAuthentication, mdm_types.MDEDiscovery, errors.New(targetErrorString))
sres, err := NewSoapResponse(&soapFaultMsg, "urn:uuid:0d5a1441-5891-453b-becf-a2e5f6ea3749")
require.NoError(t, err)
outXML, err := xml.MarshalIndent(sres, "", " ")