Documentation
¶
Overview ¶
Package proxywire defines the internal protocol between separately deployed MDM and declaration-engine roles.
Design ¶
POST /v1/declarative-management carries the original DeclarativeManagement check-in plist. Versioned request HMACs bind method, target, content type, timestamp, nonce and body. Response HMACs bind the request envelope, status, content type and body. Verification checks five-minute freshness and atomically claims nonces in a caller-supplied shared store for ten minutes. Shared helpers apply body limits and signature encoding. Proxyserver can additionally require mutual TLS or another authorization check.
This is a project-specific deployment protocol, not an Apple or NanoMDM transport contract. The adapters resolve enrollment from the forwarded message. HMAC does not encrypt data; the adapters require HTTPS, with an explicit literal-loopback exception for tests. Replicas must share replay state.
References ¶
- Decision record 0023: https://github.com/deploymenttheory/go-apple-dm/blob/main/docs/research/decisions/0023-ddm-adapters-and-wire-contract.md
- Threat model: https://github.com/deploymenttheory/go-apple-dm/blob/main/docs/security/threat-model.md (private DDM proxy)
- Apple: https://developer.apple.com/documentation/devicemanagement/declarativemanagementrequest
- RFC 2104 (HMAC): https://www.rfc-editor.org/rfc/rfc2104
Index ¶
- Constants
- Variables
- func ReadBody(r io.Reader, limit int64) ([]byte, error)
- func Sign(key, body []byte) string
- func SignBoundResponse(key []byte, request string, status int, ct string, body []byte) string
- func SignRequest(key []byte, r *http.Request, body []byte) (string, error)
- func SignResponse(key []byte, status int, body []byte) string
- func ValidKeys(send, recv []byte) bool
- func Verify(key []byte, header string, body []byte) error
- func VerifyBoundResponse(key []byte, header, request string, status int, ct string, body []byte) error
- func VerifyRequest(ctx context.Context, st state.Store, key []byte, r *http.Request, body []byte) error
- func VerifyResponse(key []byte, header string, status int, body []byte) error
Constants ¶
const ( // Path is the only route the ddm role serves for the mdm role. Path = "/v1/declarative-management" // ContentType is the request body type: the check-in plist as received. ContentType = "application/x-apple-aspen-mdm-checkin" // HeaderSignature carries base64(HMAC-SHA256(key, ...)): the body on a // request, and the status with the body on a response. HeaderSignature = "X-MDM-Signature" // DefaultMaxBody bounds request and response bodies (1 MiB). DefaultMaxBody = 1 << 20 )
Wire constants.
Variables ¶
var ( ErrMissingSignature = errors.New("proxywire: missing signature") ErrBadSignature = errors.New("proxywire: bad signature") ErrBodyTooLarge = errors.New("proxywire: body too large") ErrContentType = errors.New("proxywire: unexpected content type") )
Errors.
Functions ¶
func ReadBody ¶
ReadBody reads at most limit bytes from r; a longer body is ErrBodyTooLarge. A non-positive limit means DefaultMaxBody.
func Sign ¶
Sign returns the header value for a request body under key. A request is the whole message, so the body is the whole of what needs covering.
func SignBoundResponse ¶
SignBoundResponse binds a response to this request and its exact representation.
func SignRequest ¶
SignRequest creates a fresh v2 envelope covering the method, target and body.
func SignResponse ¶
SignResponse authenticates status and body together. Covering status prevents an authenticated empty error body from being replayed as a declaration-removal 404. Content type is excluded because the adapter does not use it for authorization decisions.
func Verify ¶
Verify checks header against a request body under key. A missing header is ErrMissingSignature; anything that does not match is ErrBadSignature.
func VerifyBoundResponse ¶
func VerifyBoundResponse( key []byte, header, request string, status int, ct string, body []byte, ) error
VerifyBoundResponse rejects response substitution, including another request's response.
Types ¶
This section is empty.