Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for encoding/decoding XPC connections #12

Closed
amomchilov opened this issue Nov 10, 2021 · 1 comment · Fixed by #53
Closed

Add support for encoding/decoding XPC connections #12

amomchilov opened this issue Nov 10, 2021 · 1 comment · Fixed by #53
Assignees

Comments

@amomchilov
Copy link
Contributor


Originally posted by @amomchilov in #6 (comment):

File descriptors and shared memory are intentionally not supported as they are concepts incompatible with Codable which is designed for indefinite serialization and cross-device transfer. As such choosing Codable for SecureXPC had tradeoffs because XPC does not have the same requirements — it can represent live resources on a single device. However, I decided the tradeoff was worth it because of Swift's excellent built in support for Codable (particularly the compiler automatically generating conformance in many cases). If there was a desire to support file descriptors and shared memory, I can envision ways to add them in the future, although it would mean expanding the API quite considerably.

I don't have an immediate need for passing FDs or shared memory regions in my program yet, but my app does need to pass an xpc_endpoint_t. My main app is sandboxed, so the only way it can use SMBless is by delegating that work to an unsandboxed XPC helper service. Once the installation is done, it opens the XPC connection to the privileged helper service, and passes the endpoint back to the main app.

This is the approach that's recommended in Apple's EvenBetterAuthorizationSample, so I think supporting xpc_endpoint_t is pretty crucial. So at a minimum, at least some level of special-casing needs to happen.

@amomchilov
Copy link
Contributor Author

amomchilov commented Nov 10, 2021

Some observations:

  • You can't retroactively add protocol conformances to xpc_object_t (and its variants):

    // error: extension of protocol 'OS_xpc_object' cannot have an inheritance clause
    extension xpc_connection_t: Codable {
    
    }
  • You can use a property wrapper (which itself can be codable, even if its wrappedValue is not).

The only solution approaches I can think of involve wrapping the xpc_connection_t (or xpc_endpoint_t; I propose we make both codable). Either explicitly by the user, or implicitly via a property wrapper. I don't see any down-side to the latter over the former, so I propose we go with a property wrapper.

I see two ways we can make this work:

  1. "Fake" the implementation of Codable on the property wrapper
    • Make the init(from:) and encode(to:) call fatalError().
      • The message should inform users that these values can only ever be encoded/decoded by the SecureXPC library.
    • Add special-cases to the XPCEncoder/XPCDecoder (well really, their containers), such that they intercept these values and never actually call their init(from:) or encode(to:) methods.
    • I haven't had time to spike this one out yet
  2. Conform to Codable for real
    • Make the init(from:) and encode(to:) cast their Encoder/Decoder param to a concrete XPCEncoderImpl/XPCDecoderImpl. If the cast fails, fatalError() out.
      • Again, the message should inform users that these values can only ever be encoded/decoded by the SecureXPC library.
    • Make a single value container (in either case), and down cast to the XPCSingleValueEncodingContainer/XPCSingleValueDecodingContainer (this is safe to force-cast)
    • Don't special case anything. Let the default implementation of Codable take its course. init(from:) and encode(to:) will be called like normal.
    • Add methods to XPCEncoder/XPCDecoder (their containers) that handle xpc_connection_t and xpc_endpoint_t. Use these to implement init(from:) and encode(to:)
    • I made a proof of concept of this for xpc_connection_t, here: [Proof of Concept] Codable xpc_connection_t #13

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants