From d261762e8342b52be41cdc1cce021e52d062b1a9 Mon Sep 17 00:00:00 2001 From: Roberto Dip Date: Fri, 15 Mar 2024 10:51:47 -0300 Subject: [PATCH] add base types and handlers for DDM (#17657) This includes the base types and the request handlers to reduce the chances of conflicts. --- server/fleet/apple_mdm.go | 77 +++++++++++++++++++++++++++++++++++++ server/service/apple_mdm.go | 22 ++++++++++- 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/server/fleet/apple_mdm.go b/server/fleet/apple_mdm.go index 02a0b65f47..c6a0061694 100644 --- a/server/fleet/apple_mdm.go +++ b/server/fleet/apple_mdm.go @@ -532,3 +532,80 @@ type SCEPIdentityAssociation struct { EnrollReference string `db:"enroll_reference"` RenewCommandUUID string `db:"renew_command_uuid"` } + +// MDMAppleDeclarationType is the type for the supported declaration types. +type MDMAppleDeclarationType string + +const ( + // MDMAppleConfigurationDeclaration is the value for [configuration][1] declarations + // + // [1]: https://developer.apple.com/documentation/devicemanagement/declarations#3813088 + MDMAppleDeclarativeConfiguration MDMAppleDeclarationType = "com.apple.configuration" + + // MDMAppleActivationConfiguration is the value for [activation][1] declarations + // + // [1]: https://developer.apple.com/documentation/devicemanagement/declarations#3829708 + MDMAppleDeclarativeActivation MDMAppleDeclarationType = "com.apple.activation" +) + +// MDMAppleDeclaration represents a DDM JSON declaration. +type MDMAppleDeclaration struct { + // DeclarationUUID is the unique identifier of the declaration in + // Fleet. Since we use the same endpoints for declarations and profiles: + // - This is marshalled as profile_uuid + // - The value has a prefix (TODO: @jahzielv to determine and document this) + DeclarationUUID string `db:"declaration_uuid" json:"profile_uuid"` + + // TeamID is the id of the team with which the declaration is associated. A nil team id + // represents a declaration that is not associated with any team. + TeamID *uint `db:"team_id" json:"team_id"` + + // Identifier corresponds to the "Identifier" key of the associated declaration. + // Fleet requires that Identifier must be unique in combination with the Name and TeamID. + Identifier string `db:"identifier" json:"identifier"` + + // Name corresponds to the file name of the associated JSON declaration payload. + // Fleet requires that Name must be unique in combination with the Identifier and TeamID. + Name string `db:"name" json:"name"` + + // DeclarationType is the type of the declaration, at the moment we + // only support configurations and activations. + DeclarationType MDMAppleDeclarationType `db:"declaration_type"` + + // Declaration is the raw JSON content of the declaration + Declaration json.RawMessage `db:"declaration" json:"-"` + + // MD5Checksum is a checsum of the JSON contents + MD5Checksum string `db:"md5_checksum" json:"-"` + + CreatedAt time.Time `db:"created_at" json:"created_at"` + UploadedAt time.Time `db:"uploaded_at" json:"uploaded_at"` +} + +// MDMAppleHostDeclaration represents the state of a declaration on a host +type MDMAppleHostDeclaration struct { + // HostUUID is the uuid of the host affected by this declaration + HostUUID string `db:"host_uuid" json:"-"` + + // DeclarationUUID is the unique identifier of the declaration in + // Fleet. Since we use the same endpoints for declarations and profiles: + // - This is marshalled as profile_uuid + // - The value has a prefix (TODO: @jahzielv to determine and document this) + DeclarationUUID string `db:"declaration_uuid" json:"profile_uuid"` + + // Name corresponds to the file name of the associated JSON declaration payload. + Name string `db:"name" json:"name"` + + // Identifier corresponds to the "Identifier" key of the associated declaration. + Identifier string `db:"identifier" json:"-"` + + // Status represent the current state of the declaration, as known by the Fleet server. + Status *MDMDeliveryStatus `db:"status" json:"status"` + + // Operation type represents the operation being performed. + OperationType MDMOperationType `db:"operation_type" json:"operation_type"` + + // Detail contains any messages that must be surfaced to the user, + // either by the MDM protocol or the Fleet server. + Detail string `db:"detail" json:"detail"` +} diff --git a/server/service/apple_mdm.go b/server/service/apple_mdm.go index de9e26403d..3c67f76b4f 100644 --- a/server/service/apple_mdm.go +++ b/server/service/apple_mdm.go @@ -2354,8 +2354,26 @@ func (svc *MDMAppleCheckinAndCommandService) UserAuthenticate(*mdm.Request, *mdm // This method is executed after the request has been handled by nanomdm. // // [1]: https://developer.apple.com/documentation/devicemanagement/declarative_management_checkin -func (svc *MDMAppleCheckinAndCommandService) DeclarativeManagement(*mdm.Request, *mdm.DeclarativeManagement) ([]byte, error) { - return nil, nil +func (svc *MDMAppleCheckinAndCommandService) DeclarativeManagement(r *mdm.Request, cmd *mdm.DeclarativeManagement) ([]byte, error) { + switch cmd.Endpoint { + case "tokens": + return nil, nil + case "declaration-items": + return nil, nil + case "status": + return nil, nil + default: + parts := strings.Split(cmd.Endpoint, "/") + if len(parts) != 3 { + return nil, ctxerr.New(r.Context, "unrecognized DDM endpoint") + } + + declarationType := parts[1] + declarationIdentifier := parts[2] + fmt.Println(declarationType, declarationIdentifier) + + return nil, nil + } } // CommandAndReportResults handles MDM [Commands and Queries][1].