From 20a07b9bdc726599ab8168cd486bf003c7599ce1 Mon Sep 17 00:00:00 2001 From: Calvin Lee Date: Thu, 21 Jul 2022 15:58:27 -0700 Subject: [PATCH] Add Logging for plist parse errors This is useful to debug errors that occur because of bad plists sent by clients. Usually in this case, one receives a not-very-useful error such as `HTTP status 400 (Bad Request): `. ## Test Plan 1. Patch `mdmb` so that it sends bad checkins ``` diff --git a/internal/device/mdm.go b/internal/device/mdm.go index 33a4c50..cda3d69 100644 --- a/internal/device/mdm.go +++ b/internal/device/mdm.go @@ -185,10 +185,7 @@ func (c *MDMClient) connect(client *http.Client, connReq interface{}) error { return errors.New("device not enrolled") } - plistBytes, err := plist.Marshal(connReq) - if err != nil { - return err - } + plistBytes := []byte("aoeuaoeuaoeu") ``` 2. Run ``` $mdmb -uuids $uuid devices-connect ``` 3. Observe more verbose NanoMDM log: ``` 2022/07/21 15:52:43 level=info handler=checkin-command trace_id=1af087fdc6de5381 msg=command report results err=HTTP status 400 (Bad Request): decoding command results: parse error: EOF: raw body: aoeuaoeuaoeu ``` --- mdm/checkin.go | 3 +++ mdm/command.go | 3 ++- mdm/mdm.go | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mdm/checkin.go b/mdm/checkin.go index 425756f..8f4e6ff 100644 --- a/mdm/checkin.go +++ b/mdm/checkin.go @@ -149,6 +149,9 @@ func (w *checkinUnmarshaller) UnmarshalPlist(f func(interface{}) error) error { func DecodeCheckin(rawMessage []byte) (message interface{}, err error) { w := &checkinUnmarshaller{raw: rawMessage} err = plist.Unmarshal(rawMessage, w) + if err != nil { + err = &ParseError{Err: err, Body: rawMessage} + } message = w.message return } diff --git a/mdm/command.go b/mdm/command.go index f7c1ea1..f10b707 100644 --- a/mdm/command.go +++ b/mdm/command.go @@ -35,6 +35,7 @@ func DecodeCommandResults(rawResults []byte) (results *CommandResults, err error results = new(CommandResults) err = plist.Unmarshal(rawResults, results) if err != nil { + err = &ParseError{Err: err, Body: rawResults} return } results.Raw = rawResults @@ -58,7 +59,7 @@ func DecodeCommand(rawCommand []byte) (command *Command, err error) { command = new(Command) err = plist.Unmarshal(rawCommand, command) if err != nil { - return + return nil, &ParseError{Err: err, Body: rawCommand} } command.Raw = rawCommand if command.CommandUUID == "" || command.Command.RequestType == "" { diff --git a/mdm/mdm.go b/mdm/mdm.go index e3ec762..23c62b7 100644 --- a/mdm/mdm.go +++ b/mdm/mdm.go @@ -5,6 +5,7 @@ import ( "context" "crypto/x509" "errors" + "fmt" ) // Enrollment represents the various enrollment-related data sent with requests. @@ -59,3 +60,16 @@ func (r *Request) Clone() *Request { *r2 = *r return r2 } + +type ParseError struct { + Err error + Body []byte +} + +func (e *ParseError) Unwrap() error { + return e.Err +} + +func (e *ParseError) Error() string { + return fmt.Sprintf("parse error: %s: raw body: %v", e.Err, string(e.Body)) +}