google / santa

A binary authorization and monitoring system for macOS
https://santa.dev
Apache License 2.0
4.43k stars 297 forks source link

Bundle Scanning Does Not Start When EnableSilentMode = YES #1212

Closed eopeter closed 10 months ago

eopeter commented 11 months ago

It seems Bundle Scanning happens only when showQueuedWindow calls hashBundleBinariesForEvent in SNTNotificationManager.m but its never called when EnableSilentMode is true. So in SilentMode, the bundle scanning service never starts. Is this a bug?

- (void)queueMessage:(SNTMessageWindowController *)pendingMsg {
  // Post a distributed notification, regardless of queue state.
  [self postDistributedNotification:pendingMsg];

  // If GUI is in silent mode or if there's already a notification queued for
  // this message, don't do anything else.
  if ([SNTConfigurator configurator].enableSilentMode) return;
  if ([self notificationAlreadyQueued:pendingMsg]) return;

  .
  .
  .

  pendingMsg.delegate = self;
  [self.pendingNotifications addObject:pendingMsg];

  if (!self.currentWindowController) {
    [self showQueuedWindow];
  }
}
russellhancox commented 11 months ago

That's working as intended. Bundle scanning is a potentially intensive process and allowing it to run unchecked could cause severe performance issues, so we tie the scanning process to the UI notification such that if the notification never appears or the user dismisses it with no action the bundle scanning never starts or is interrupted.

eopeter commented 11 months ago

Can I independently start the Bundle Scanning service when I receive the distributed notification? If so, how would I start it with the right parameters for the current blocked bundle?

russellhancox commented 11 months ago

No, that's not possible right now.

It sounds like a good feature req., if EnableSilentMode is on we can have santabundleservice listen for a distributed notification and have it publish notifications too. So the flow would look something like this:

sequenceDiagram
    santad->>+Distributed Listener: Execution blocked
    Distributed Listener->>+santabundleservice: Hash bundle with path
    santabundleservice->>+Distributed Listener: Bundle hash progress: 10%
    santabundleservice->>+Distributed Listener: Bundle hash progress: 20%
    santabundleservice->>+Distributed Listener: Bundle hash complete

Some very rough steps for implementation:

1) Move the existing code in SantaGUI that forwards the results from santabundleservice to santad. Once santabundleservice finishes scanning a bundle it should send the results to santad directly. Not only will this stop wasting time doing 2 transfers, it also means we can stop sending all the sub-event info to SantaGUI 1) Include the SNTStoredEvent.fileBundlePath property in the existing distributed notification posted from SantaGUI 1) Add a new distributed notification listener inside santabundleservice that is enabled only when EnableSilentMode is active. The listener should listen for com.google.santa.notification.requestbundlehash notifications. The userInfo for this notification must include a FileBundlePath key with the value sent in the notification from the GUI. 1) santabundleservice should post distributed notifications of its hashing progress. 1) santabundleserivce should post a distributed notification when bundle hashing completes (after pushing generated events to santad). This should contain the FileBundleHash that was generated and a FileBundleHashTime key with the number of milliseconds that bundle hashing took.

Another possibility: we're adding the ability to retrieve bundle hashes from the santactl fileinfo command. An existing distributed notification client could call this command with the --json flag and parse the output. Not as clean, but will be available much sooner (likely in the next Santa release)

eopeter commented 11 months ago

@russellhancox I added this PR #1227 to enable Bundle Scanning for when EnableSilentMode is YES. It preserves the existing functionality and borrows some of the suggestions you indicated above.

eopeter commented 10 months ago

using santactl fileinfo --bundleinfo /path/to/bundle.app works for our use case.