mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 08:55:24 +00:00
2d4c1b079a
for #16416
515 lines
18 KiB
Go
515 lines
18 KiB
Go
package mdmtest
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/tls"
|
|
"encoding/base64"
|
|
"encoding/xml"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strconv"
|
|
|
|
"github.com/fleetdm/fleet/v4/pkg/fleethttp"
|
|
"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"
|
|
"github.com/fleetdm/fleet/v4/server/ptr"
|
|
"github.com/golang-jwt/jwt/v4"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type TestWindowsMDMClient struct {
|
|
// DeviceID identifies a MDM enrollment, sent and managed by the device.
|
|
DeviceID string
|
|
// hardwareID identifies a device.
|
|
hardwareID string
|
|
// fleetServerURL is the URL of the Fleet server, used to ping the MDM endpoints.
|
|
fleetServerURL string
|
|
// debug enables debug logging of request/responses.
|
|
debug bool
|
|
// enrollmentType is used to simulate different Windows enrollment
|
|
// types (programatic, automatic.)
|
|
enrollmentType fleet.WindowsMDMEnrollmentType
|
|
// tokenIdentifier is used for authentication during the programmatic enrollment.
|
|
tokenIdentifier string
|
|
// lastManagementResp tracks the last response we received from the server.
|
|
lastManagementResp *fleet.SyncML
|
|
// queuedCommandResponses tracks the commands that will be sent next
|
|
// time the device responds to the server.
|
|
queuedCommandResponses map[string]fleet.SyncMLCmd
|
|
}
|
|
|
|
// TestWindowsMDMClientOption allows configuring a
|
|
// TestWindowsMDMClient.
|
|
type TestWindowsMDMClientOption func(*TestWindowsMDMClient)
|
|
|
|
// TestWindowsMDMClientDebug configures the TestWindowsMDMClient to
|
|
// run in debug mode.
|
|
func TestWindowsMDMClientDebug() TestWindowsMDMClientOption {
|
|
return func(c *TestWindowsMDMClient) {
|
|
c.debug = true
|
|
}
|
|
}
|
|
|
|
func NewTestMDMClientWindowsProgramatic(serverURL string, orbitNodeKey string, opts ...TestWindowsMDMClientOption) *TestWindowsMDMClient {
|
|
c := TestWindowsMDMClient{
|
|
fleetServerURL: serverURL,
|
|
DeviceID: uuid.NewString(),
|
|
enrollmentType: fleet.WindowsMDMProgrammaticEnrollmentType,
|
|
tokenIdentifier: orbitNodeKey,
|
|
hardwareID: uuid.NewString(),
|
|
}
|
|
for _, fn := range opts {
|
|
fn(&c)
|
|
}
|
|
return &c
|
|
}
|
|
|
|
func NewTestMDMClientWindowsAutomatic(serverURL string, email string, opts ...TestWindowsMDMClientOption) *TestWindowsMDMClient {
|
|
c := TestWindowsMDMClient{
|
|
fleetServerURL: serverURL,
|
|
DeviceID: uuid.NewString(),
|
|
enrollmentType: fleet.WindowsMDMAutomaticEnrollmentType,
|
|
tokenIdentifier: email,
|
|
hardwareID: uuid.NewString(),
|
|
}
|
|
for _, fn := range opts {
|
|
fn(&c)
|
|
}
|
|
return &c
|
|
}
|
|
|
|
func (c *TestWindowsMDMClient) StartManagementSession() (map[string]fleet.ProtoCmdOperation, error) {
|
|
// Get SessionID
|
|
sessionIDInt := 0
|
|
if c.lastManagementResp != nil {
|
|
sessionID, err := c.lastManagementResp.GetSessionID()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("session ID processing error %w", err)
|
|
}
|
|
sessionIDInt, err = strconv.Atoi(sessionID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("converting session ID to int: %w", err)
|
|
}
|
|
}
|
|
managementReq := []byte(`
|
|
<SyncML xmlns="SYNCML:SYNCML1.2">
|
|
<SyncHdr>
|
|
<VerDTD>1.2</VerDTD>
|
|
<VerProto>DM/1.2</VerProto>
|
|
<SessionID>` + fmt.Sprint(sessionIDInt+1) + `</SessionID>
|
|
<MsgID>1</MsgID>
|
|
<Target>
|
|
<LocURI>` + c.fleetServerURL + microsoft_mdm.MDE2ManagementPath + `</LocURI>
|
|
</Target>
|
|
<Source>
|
|
<LocURI>` + c.DeviceID + `</LocURI>
|
|
</Source>
|
|
</SyncHdr>
|
|
<SyncBody>
|
|
<Alert>
|
|
<CmdID>2</CmdID>
|
|
<Data>1201</Data>
|
|
</Alert>
|
|
<Alert>
|
|
<CmdID>3</CmdID>
|
|
<Data>1224</Data>
|
|
<Item>
|
|
<Meta>
|
|
<Type xmlns="syncml:metinf">com.microsoft/MDM/LoginStatus</Type>
|
|
</Meta>
|
|
<Data>user</Data>
|
|
</Item>
|
|
</Alert>
|
|
<Replace>
|
|
<CmdID>4</CmdID>
|
|
<Item>
|
|
<Source>
|
|
<LocURI>./DevInfo/DevId</LocURI>
|
|
</Source>
|
|
<Data>` + c.DeviceID + `</Data>
|
|
</Item>
|
|
<Item>
|
|
<Source>
|
|
<LocURI>./DevInfo/Man</LocURI>
|
|
</Source>
|
|
<Data>VMware, Inc.</Data>
|
|
</Item>
|
|
<Item>
|
|
<Source>
|
|
<LocURI>./DevInfo/Mod</LocURI>
|
|
</Source>
|
|
<Data>VMware7,1</Data>
|
|
</Item>
|
|
<Item>
|
|
<Source>
|
|
<LocURI>./DevInfo/DmV</LocURI>
|
|
</Source>
|
|
<Data>1.3</Data>
|
|
</Item>
|
|
<Item>
|
|
<Source>
|
|
<LocURI>./DevInfo/Lang</LocURI>
|
|
</Source>
|
|
<Data>en-US</Data>
|
|
</Item>
|
|
</Replace>
|
|
<Final/>
|
|
</SyncBody>
|
|
</SyncML>
|
|
`)
|
|
|
|
return c.doManagementReq(managementReq)
|
|
}
|
|
|
|
func (c *TestWindowsMDMClient) doManagementReq(rawXMLReq []byte) (map[string]fleet.ProtoCmdOperation, error) {
|
|
if c.debug {
|
|
fmt.Println("=============== management request ================")
|
|
fmt.Println(string(rawXMLReq))
|
|
}
|
|
|
|
// TODO: this request works because we're allowing devices without
|
|
// certificates to communicate with the server. We will need to include the
|
|
// certificate we generated during enrollment when we fix that.
|
|
managementResp, err := c.request(microsoft_mdm.MDE2ManagementPath, rawXMLReq)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rawXMLResp, err := io.ReadAll(managementResp.Body)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("reading response body: %w", err)
|
|
}
|
|
|
|
if c.debug {
|
|
fmt.Println("=============== management response ================")
|
|
fmt.Println(string(rawXMLResp))
|
|
}
|
|
|
|
var syncML fleet.SyncML
|
|
if err := xml.Unmarshal(rawXMLResp, &syncML); err != nil {
|
|
return nil, fmt.Errorf("unmarshalling response body: %w", err)
|
|
}
|
|
c.lastManagementResp = &syncML
|
|
|
|
cmds := make(map[string]fleet.ProtoCmdOperation)
|
|
for _, p := range c.lastManagementResp.GetOrderedCmds() {
|
|
cmds[p.Cmd.CmdID.Value] = p
|
|
}
|
|
|
|
// before returning, clean up any lingering responses
|
|
c.queuedCommandResponses = make(map[string]fleet.SyncMLCmd)
|
|
return cmds, nil
|
|
}
|
|
|
|
func (c *TestWindowsMDMClient) SendResponse() (map[string]fleet.ProtoCmdOperation, error) {
|
|
// Get SessionID
|
|
sessionID, err := c.lastManagementResp.GetSessionID()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("session ID processing error %w", err)
|
|
}
|
|
|
|
// Get MessageID
|
|
messageID, err := c.lastManagementResp.GetMessageID()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("message ID processing error %w", err)
|
|
}
|
|
messageIDInt, err := strconv.Atoi(messageID)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("converting message ID to int: %w", err)
|
|
}
|
|
|
|
var msg fleet.SyncML
|
|
msg.Xmlns = syncml.SyncCmdNamespace
|
|
msg.SyncHdr = fleet.SyncHdr{
|
|
VerDTD: syncml.SyncMLSupportedVersion,
|
|
VerProto: syncml.SyncMLVerProto,
|
|
SessionID: sessionID,
|
|
MsgID: fmt.Sprint(messageIDInt + 1),
|
|
Source: &fleet.LocURI{LocURI: &c.DeviceID},
|
|
Target: &fleet.LocURI{
|
|
LocURI: ptr.String(c.fleetServerURL + microsoft_mdm.MDE2ManagementPath),
|
|
},
|
|
}
|
|
|
|
// iterate over mocked responses and append them to the SyncML message
|
|
for _, protoCmd := range c.queuedCommandResponses {
|
|
msg.AppendCommand(fleet.MDMRaw, protoCmd)
|
|
}
|
|
|
|
xmlReq, err := xml.MarshalIndent(msg, "", "\t")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("serializing XML req: %w", err)
|
|
}
|
|
|
|
return c.doManagementReq(xmlReq)
|
|
}
|
|
|
|
// AppendResponse sets a response for a specific command UUID.
|
|
func (c *TestWindowsMDMClient) AppendResponse(op fleet.SyncMLCmd) {
|
|
c.queuedCommandResponses[op.CmdID.Value] = op
|
|
}
|
|
|
|
func (c *TestWindowsMDMClient) GetCurrentMsgID() (string, error) {
|
|
msgID, err := c.lastManagementResp.GetMessageID()
|
|
if err != nil {
|
|
return "", fmt.Errorf("getting management response msg id: %w", err)
|
|
}
|
|
return msgID, nil
|
|
}
|
|
|
|
func (c *TestWindowsMDMClient) Enroll() error {
|
|
if err := c.Discovery(); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := c.Policy(); err != nil {
|
|
return err
|
|
}
|
|
|
|
binarySecToken, tokenValueType, err := c.getToken()
|
|
if err != nil {
|
|
return fmt.Errorf("getting binary token: %w", err)
|
|
}
|
|
|
|
enrollReq := []byte(`
|
|
<s:Envelope
|
|
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
|
xmlns:a="http://www.w3.org/2005/08/addressing"
|
|
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
|
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
|
xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512"
|
|
xmlns:ac="http://schemas.xmlsoap.org/ws/2006/12/authorization">
|
|
<s:Header>
|
|
<a:Action s:mustUnderstand="1">http://schemas.microsoft.com/windows/pki/2009/01/enrollment/RST/wstep</a:Action>
|
|
<a:MessageID>urn:uuid:0d5a1441-5891-453b-becf-a2e5f6ea3749</a:MessageID>
|
|
<a:ReplyTo>
|
|
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
|
|
</a:ReplyTo>
|
|
<a:To s:mustUnderstand="1">` + c.fleetServerURL + microsoft_mdm.MDE2EnrollPath + `</a:To>
|
|
<wsse:Security s:mustUnderstand="1">
|
|
<wsse:BinarySecurityToken ValueType="` + tokenValueType + `" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#base64binary">` + binarySecToken + `</wsse:BinarySecurityToken>
|
|
</wsse:Security>
|
|
</s:Header>
|
|
<s:Body>
|
|
<wst:RequestSecurityToken>
|
|
<wst:TokenType>http://schemas.microsoft.com/5.0.0.0/ConfigurationManager/Enrollment/DeviceEnrollmentToken</wst:TokenType>
|
|
<wst:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</wst:RequestType>
|
|
<wsse:BinarySecurityToken ValueType="http://schemas.microsoft.com/windows/pki/2009/01/enrollment#PKCS10" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#base64binary">MIIC5jCCAc4CAQAwSjFIMEYGA1UEAww/MEYzQjhFNkMtQTI3MS00NTU2LTlCNzIt
|
|
QTI2Q0JEITgwOTBDOEI0ODRBMEUyNEVCNUM1NkU4MDZDQjRFRTVCMIIBIjANBgkq
|
|
hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoLj7gBWVMPiVsbrB13jW86bB/Rz+bAOj
|
|
J9MxMwuwOtbPicESpReZ7QgjNhv5tTubLCHRlIRhcawxPOhpZCZTRolT/3q2xhYT
|
|
3WnW8uLiPLTyQpmoI66yfMAUlNfKboeFpgMB6GCM3FColmQBHzWrPulY5zUSwBFs
|
|
YwogoSKVH9ekAv5FQZpqW8zj9tTU1t7U1qMwyb03u1+7JGJ0lBBjCDkoMCB0sSVO
|
|
Fybg//zsHqdYs876jnh8qH6GG8XUVrCk4PYX/b1Fak9D4DcedCQ/sDlsxB1i4TjY
|
|
apbduFo9/wc/OL9KVBk2LWPXvwV0/EWggx4QFZpaabeJy5J0CbdpvQIDAQABoFcw
|
|
VQYJKoZIhvcNAQkOMUgwRjATBgNVHSUEDDAKBggrBgEFBQcDAjAvBgorBgEEAYI3
|
|
QgEABCE4MDkwQzhCNDg0QTBFMjRFQjVDNTZFODA2Q0I0RUU1QgAwDQYJKoZIhvcN
|
|
AQELBQADggEBAFwiNxM90FippSvLgoqMw9TpyoSTD2hftPW+bpGA1OxxBmSwCwI9
|
|
oE7/6bMLX9k9iBt6QaQomWp6Gh+Rpuz0uzHp32TLbuV87//awydG8meyU6GMVZ6R
|
|
xfIAH4rmdhJ9ccpnugSLMYr3+UKLWSOjeTB2ZKcVx7LTsHzqaDg3ghJDSNx12wSY
|
|
LmEKCHDR1FNPcXB6hfs3CfJOnJhcOX+Gg2GrqjAEA2ty2rEJ9LVZo0Q3A7pfEezs
|
|
YioVozr1IWYySwWVzMf/SUwKZkKJCAJmSVcixE+4kxPkyPGyauIrN3wWC0zb+mjF
|
|
3aJBpJrK45UhKb1LOBHOtV7BsoEkOUNmCdQ=
|
|
</wsse:BinarySecurityToken>
|
|
<ac:AdditionalContext
|
|
xmlns="http://schemas.xmlsoap.org/ws/2006/12/authorization">
|
|
<ac:ContextItem Name="UXInitiated">
|
|
<ac:Value>false</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="HWDevID">
|
|
<ac:Value>` + c.hardwareID + `</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="Locale">
|
|
<ac:Value>en-US</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="TargetedUserLoggedIn">
|
|
<ac:Value>true</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="OSEdition">
|
|
<ac:Value>48</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="DeviceName">
|
|
<ac:Value>DESKTOP-H1T20J1</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="MAC">
|
|
<ac:Value>A2-19-7D-41-B3-9C</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="DeviceID">
|
|
<ac:Value>` + c.DeviceID + `</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="EnrollmentType">
|
|
<ac:Value>Full</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="DeviceType">
|
|
<ac:Value>CIMClient_Windows</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="OSVersion">
|
|
<ac:Value>10.0.22598.1</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="ApplicationVersion">
|
|
<ac:Value>10.0.22598.1</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="NotInOobe">
|
|
<ac:Value>false</ac:Value>
|
|
</ac:ContextItem>
|
|
<ac:ContextItem Name="RequestVersion">
|
|
<ac:Value>5.0</ac:Value>
|
|
</ac:ContextItem>
|
|
</ac:AdditionalContext>
|
|
</wst:RequestSecurityToken>
|
|
</s:Body>
|
|
</s:Envelope>
|
|
`)
|
|
|
|
if _, err := c.request(microsoft_mdm.MDE2EnrollPath, enrollReq); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *TestWindowsMDMClient) Discovery() error {
|
|
discoveryReq := []byte(`
|
|
<s:Envelope
|
|
xmlns:a="http://www.w3.org/2005/08/addressing"
|
|
xmlns:s="http://www.w3.org/2003/05/soap-envelope">
|
|
<s:Header>
|
|
<a:Action s:mustUnderstand="1">http://schemas.microsoft.com/windows/management/2012/01/enrollment/IDiscoveryService/Discover</a:Action>
|
|
<a:MessageID>urn:uuid:748132ec-a575-4329-b01b-6171a9cf8478</a:MessageID>
|
|
<a:ReplyTo>
|
|
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
|
|
</a:ReplyTo>
|
|
<a:To s:mustUnderstand="1">` + c.fleetServerURL + microsoft_mdm.MDE2DiscoveryPath + `</a:To>
|
|
</s:Header>
|
|
<s:Body>
|
|
<Discover
|
|
xmlns="http://schemas.microsoft.com/windows/management/2012/01/enrollment">
|
|
<request
|
|
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
|
|
<EmailAddress></EmailAddress>
|
|
<RequestVersion>5.0</RequestVersion>
|
|
<DeviceType>CIMClient_Windows</DeviceType>
|
|
<ApplicationVersion>6.2.9200.1</ApplicationVersion>
|
|
<OSEdition>48</OSEdition>
|
|
<AuthPolicies>
|
|
<AuthPolicy>OnPremise</AuthPolicy>
|
|
<AuthPolicy>Federated</AuthPolicy>
|
|
</AuthPolicies>
|
|
</request>
|
|
</Discover>
|
|
</s:Body>
|
|
</s:Envelope>
|
|
`)
|
|
|
|
// TODO: parse the response and store the policy and enroll endpoints instead
|
|
// of hardcoding them to truly test that the server is behaving as expected.
|
|
if _, err := c.request(microsoft_mdm.MDE2DiscoveryPath, discoveryReq); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *TestWindowsMDMClient) Policy() error {
|
|
binarySecToken, tokenValueType, err := c.getToken()
|
|
if err != nil {
|
|
return fmt.Errorf("getting binary token: %w", err)
|
|
}
|
|
|
|
policyReq := []byte(`
|
|
<s:Envelope
|
|
xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
|
xmlns:a="http://www.w3.org/2005/08/addressing"
|
|
xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
|
|
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
|
xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512"
|
|
xmlns:ac="http://schemas.xmlsoap.org/ws/2006/12/authorization">
|
|
<s:Header>
|
|
<a:Action s:mustUnderstand="1">http://schemas.microsoft.com/windows/pki/2009/01/enrollmentpolicy/IPolicy/GetPolicies</a:Action>
|
|
<a:MessageID>urn:uuid:72048B64-0F19-448F-8C2E-B4C661860AA0</a:MessageID>
|
|
<a:ReplyTo>
|
|
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
|
|
</a:ReplyTo>
|
|
<a:To s:mustUnderstand="1">` + c.fleetServerURL + microsoft_mdm.MDE2PolicyPath + `</a:To>
|
|
<wsse:Security s:mustUnderstand="1">
|
|
<wsse:BinarySecurityToken ValueType="` + tokenValueType + `" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#base64binary">` + binarySecToken + `</wsse:BinarySecurityToken>
|
|
</wsse:Security>
|
|
</s:Header>
|
|
<s:Body
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
|
<GetPolicies
|
|
xmlns="http://schemas.microsoft.com/windows/pki/2009/01/enrollmentpolicy">
|
|
<client>
|
|
<lastUpdate xsi:nil="true"/>
|
|
<preferredLanguage xsi:nil="true"/>
|
|
<TPMManufacturer>IBM</TPMManufacturer>
|
|
<TPMFirmwareVersion>8217.4131.22.13878</TPMFirmwareVersion>
|
|
</client>
|
|
<requestFilter xsi:nil="true"/>
|
|
</GetPolicies>
|
|
</s:Body>
|
|
</s:Envelope>
|
|
`)
|
|
|
|
// TODO: store the policy requirements to generate a certificate and generate
|
|
// one on the fly using them instead of using hardcoded values.
|
|
if _, err := c.request(microsoft_mdm.MDE2PolicyPath, policyReq); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *TestWindowsMDMClient) request(path string, reqBody []byte) (*http.Response, error) {
|
|
request, err := http.NewRequest("POST", c.fleetServerURL+path, bytes.NewReader(reqBody))
|
|
if err != nil {
|
|
return nil, fmt.Errorf("create request: %w", err)
|
|
}
|
|
cc := fleethttp.NewClient(fleethttp.WithTLSClientConfig(&tls.Config{
|
|
// Ignoring "G402: TLS InsecureSkipVerify set true", this is only used for automated testing.
|
|
InsecureSkipVerify: true, //nolint:gosec
|
|
}))
|
|
response, err := cc.Do(request)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("send request: %w", err)
|
|
}
|
|
if response.StatusCode != http.StatusOK {
|
|
return nil, fmt.Errorf("request error: %d, %s", response.StatusCode, response.Status)
|
|
}
|
|
|
|
return response, nil
|
|
}
|
|
|
|
func (c *TestWindowsMDMClient) getToken() (binarySecToken string, tokenValueType string, err error) {
|
|
switch c.enrollmentType {
|
|
case fleet.WindowsMDMAutomaticEnrollmentType:
|
|
claims := &jwt.MapClaims{
|
|
"upn": c.tokenIdentifier,
|
|
"tid": "tenant_id",
|
|
"unique_name": "foo_bar",
|
|
"scp": "mdm_delegation",
|
|
}
|
|
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
|
tokenString, err := token.SignedString([]byte("foo"))
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
tokenValueType = syncml.BinarySecurityAzureEnroll
|
|
binarySecToken = base64.URLEncoding.EncodeToString([]byte(tokenString))
|
|
case fleet.WindowsMDMProgrammaticEnrollmentType:
|
|
var err error
|
|
tokenValueType = syncml.BinarySecurityDeviceEnroll
|
|
binarySecToken, err = fleet.GetEncodedBinarySecurityToken(c.enrollmentType, c.tokenIdentifier)
|
|
if err != nil {
|
|
return "", "", fmt.Errorf("generating encoded security token: %w", err)
|
|
}
|
|
}
|
|
|
|
return binarySecToken, tokenValueType, nil
|
|
}
|