Capturing NSXPCConnectionCodeSigningRequirementFailure in XPC service

I’m working on a launch daemon. I’m in the process of adding setCodeSigningRequirement to both sides of the connection, starting with the XPC service. I’ve already made it so that the service calls setCodeSigningRequirement on a new connection passed to the listener method of NSXPCListenerDelegate.

It works and the connection does get invalidated. The launch daemon logs stdout and stderr to a file already. So I figured that if a connection gets invalidated because of a code signing failure, it’d be nice to NSLog this to make it easier for users to debug what’s going on, without forcing them to use Console.app.

The docs for setCodeSigningRequirement include an example of how to capture this error on the client side, when the client calls that method. What I cannot figure out is how to capture this error on the side of the XPC service.

I could use setInvalidationHandler, but the problem with it is that a connection can be invalidated for a myriad of reasons and the handler doesn’t know what happened. Is there perhaps an equivalent of remoteObjectProxyWithErrorHandler but for the service side of the connection?

Answered by DTS Engineer in 796823022
Is there perhaps an equivalent of remoteObjectProxyWithErrorHandler but for the service side of the connection?

Why not call -setConnectionCodeSigningRequirement: on the NSXPCListener itself?

Is there perhaps an equivalent of remoteObjectProxyWithErrorHandler but for the service side of the connection?

No.

Note that you can actually message from the server to the client using -remoteObjectProxyWithErrorHandler:, but it’s unlikely to help in this case because the connection will never get to a point where you can do that [1].

ps It’s time to move away from NSLog. For lots of hints and tips about the system log APIs, see Your Friend the System Log.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Because the requirement check, and hence the invalidation, is driven by the first message on the connection, and in this setup that’s always going to be from the client to the server.

Is there perhaps an equivalent of remoteObjectProxyWithErrorHandler but for the service side of the connection?

Why not call -setConnectionCodeSigningRequirement: on the NSXPCListener itself?

Is there perhaps an equivalent of remoteObjectProxyWithErrorHandler but for the service side of the connection?

No.

Note that you can actually message from the server to the client using -remoteObjectProxyWithErrorHandler:, but it’s unlikely to help in this case because the connection will never get to a point where you can do that [1].

ps It’s time to move away from NSLog. For lots of hints and tips about the system log APIs, see Your Friend the System Log.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Because the requirement check, and hence the invalidation, is driven by the first message on the connection, and in this setup that’s always going to be from the client to the server.

Oh, I was about to add that with setConnectionCodeSigningRequirement called on the listener it’s even harder to log on the service side that something happened with the connection. In that case, the listener method of NSXPCListenerDelegate is not called at all. This means I can’t set up an invalidation handler on a new connection.

Is there any way to (in code) notice from the service side that the connection was invalidated due to a code signing requirement failure? At the moment, the only workaround I'm aware of is to run Console.app while trying to start the launch daemon and then spot xpc_support_check_token: <private> error: <private> status: -67050 in the logs.

Thanks for the tip about logging, I wasn't aware of that. The launch daemon is mostly written in Go, with a small part in Objective-C that handles all of the XPC stuff and I don't have a whole lot of knowledge about Objective-C.

it’s even harder to log on the service side that something happened with the connection.

Right, because nothing has happened with the connection because, from your perspective, there is no connection. What are you actually trying to achieve by logging this?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

In the rare situation where the app cannot contact the launch daemon due to not satisfying the code signing requirement, I'd like the Go part of the launch daemon to leave a clear message in the log file. It already logs there a bunch of other information and this would be the go-to place which our users and customer support check.

As it stands, on the client side I get NSXPCConnectionInterrupted and no indication of a problem on the service side. I'm writing up a debug log message on the client side that points towards Console.app and looking for xpc_support_check_token: <private> error: <private> status: -67050 if the client encounters NSXPCConnectionInterrupted. But as I understand, a connection can get interrupted for a multitude of reasons. It'd be nice to get a clearer indication of a code signing problem on the service side without having to go through Console.app.

(In this message, I used "the launch daemon" and "the service side" interchangeably.)

Capturing NSXPCConnectionCodeSigningRequirementFailure in XPC service
 
 
Q