On a macOS machine running v15.0, I have a daemon run by launchd which subscribes to the sleep and wakeup notifications using the IORegisterForSystemPower method.
void PowerCallBack(void* refCon, io_service_t service, natural_t messageType, void* messageArgument)
{
switch (messageType)
{
case kIOMessageSystemWillSleep:
logger->Debug("Received sleep notification from macOS");
if (refCon)
{
//Handle Sleep
}
IOAllowPowerChange(root_port, (long)messageArgument);
break;
case kIOMessageSystemHasPoweredOn:
logger->Debug("Received wakeup notification from macOS");
if (refCon)
{
// Handle Wakeup
}
break;
default:
break;
}
}
void MacOSNotification::RegisterNotifications()
{
logger->Debug("Registering for notifications from macOS");
powerNotificationThread = [[NSThread alloc] initWithBlock:^{
// Notifier object, used to deregister later
root_port = IORegisterForSystemPower(this, ¬ifyPortRef, PowerCallBack, ¬ifierObject);
if (root_port == 0)
{
return;
}
logger->Debug("Registered for system power notifications from macOS");
// Add the notification port to the application runloop
CFRunLoopAddSource(CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notifyPortRef),
kCFRunLoopCommonModes);
CFRunLoopRun();
}]; //END OF THREAD BLOCK
[powerNotificationThread start];
}
Using this mechanism, I am getting notifications for normal sleep and wakeup transitions like closing and opening the lid. I need these notifications to terminate/reconnect my connection to a cloud service when we go to sleep/wakeup respectively.
I have noticed from the power logs at /private/var/log/powermanagement that the after the sleep initiated by lid closing or clicking sleep in the top apple menu (both of which I can detect as they generate power notification), the macOS machine wakes up with the following message from powerd logs:
DarkWake from Deep Idle [CDNP] : due to SMC.OutboxNotEmpty smc.70070000 wifibt/
I do not get any notification for this wakeup and my application threads start running. This happens every 15 to 16 mins from my observation.
After this DarkWake, we go back to 'Maintenance' sleep in under a minute as can be seen by the following powerd log:
Entering Sleep state due to 'Maintenance Sleep':TCPKeepAlive=active
I do not get any notifications for this either.
Is there a way to track and get notified of these DarkWake -> Maintenance sleep cycles? At the very least I would like to log when we go into and come out of these states. Currently I just rely on seeing a 15 min window of no logs to know this must have a DarkWake -> Maintenance sleep cycle.
Also is there a way to make sure my application and its threads are not woken up by DarkWake (like an opt-out)? I would like to make it so that my application only runs when we are properly sleeping and waking.
Post
Replies
Boosts
Views
Activity
I have a certificate and private key imported into the System Keychain which is used for client authentication in mTLS connections.
I can go into the Keychain Access UI and open up the options for the private key, navigate to the "Access Control List" tab and whitelist certain applications which have access to this key.
I am aware of the "security import" CLI command which allows me to set up the private key permissions using either the -A (allow all applications to access imported key) or -T (allow specific application to access imported key). But these only work for scenarios where I am importing a completely new Certificate + Private Key.
However, is there a way to make these "Access Control List" changes from a CLI command for a private key that is already present in the keychain?
I am deploying an application to a large number of machines and it is not feasible to have a manual step for adding the application to a whitelist in Keychain Access. Need to automate this stuff
I have written a WebSocket client using Apple Network Framework in C++. I use a sec_protocol_options_set_verify_block to customize the server SSL certificate trust evaluation. This includes logic to append a revocation policy to the trust object like this:
Code snippet
If CRL checks are set to HARD i.e kSecRevocationRequirePositiveResponse bit is set. Then the evaluation always fails with Trust evaluation result - kSecTrustResultRecoverableTrustFailure and the revocation result is FALSE. The error code is -67635 corresponding to errSecIncompleteCertRevocationCheck. But weirdly the error message printed is '"leafCert","CACert" certificates do not meet pinning requirements'. This does not match up to the error code seen.
These are placeholder names for my self signed server
certificates. The root is added to the Keychain and marked trusted in the keychain. If I put CRL checks to SOFT, no CRL check takes place but the trust evaluation succeeds.
Putting the error message anomaly aside. If I run WireShark traces on the server machine where the CRL distribution point is also located, I do not see any HTTP requests coming in for the CRL list. I have checked the CRL DP URL in a browser and it is reachable.
Is there something wrong with the policy creation process? Why is it not at least trying to access the CRL DP?