Skip to content

Commit 8909082

Browse files
gui: deny execution of hold&ask events immediately if unavailable (#749)
Prior to this change, if a hold & ask execution triggered a Santa dialog but biometry is not available (and the `EnableStandalonePasswordFallback` key is not set to true) the execution would remain held until the dialog was dismissed. With this change, the execution will be denied immediately.
1 parent 3597fdd commit 8909082

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

Source/gui/SNTBinaryMessageWindowView.swift

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,18 @@ struct SNTBinaryMessageWindowView: View {
250250

251251
@State public var preventFutureNotifications = false
252252
@State public var preventFutureNotificationPeriod: TimeInterval = NotificationSilencePeriods[0]
253+
@State private var repliedToCallback = false
253254

254255
let c = SNTConfigurator.configurator()
255256

257+
func callReplyCallback(_ response: Bool) {
258+
guard !repliedToCallback else { return }
259+
repliedToCallback = true
260+
if let cb = replyCallback {
261+
cb(response)
262+
}
263+
}
264+
256265
func getDismissText() -> String? {
257266
if event?.needsBundleHash ?? false && !bundleProgress.isFinished {
258267
return "Cancel"
@@ -290,8 +299,14 @@ struct SNTBinaryMessageWindowView: View {
290299
if event?.holdAndAsk ?? false {
291300
let (canAuthz, err) = CanAuthorizeWithTouchID()
292301
if !canAuthz {
293-
if let errMsg = err {
294-
Text(errMsg.localizedDescription).foregroundColor(.red)
302+
Group {
303+
if let errMsg = err {
304+
Text(errMsg.localizedDescription).foregroundColor(.red)
305+
}
306+
}.task {
307+
// If this is a holdAndAsk event but TouchID is not available,
308+
// call the reply block immediately with false.
309+
let _ = callReplyCallback(false)
295310
}
296311
}
297312
}
@@ -342,9 +357,7 @@ struct SNTBinaryMessageWindowView: View {
342357
}
343358
}
344359

345-
if let callback = replyCallback {
346-
callback(false)
347-
}
360+
callReplyCallback(false)
348361

349362
window?.close()
350363

@@ -357,22 +370,15 @@ struct SNTBinaryMessageWindowView: View {
357370
// the "Open Event" button.
358371
func standAloneButton() {
359372
guard let e = self.event else {
360-
if let cb = self.replyCallback {
361-
cb(false)
373+
DispatchQueue.main.async {
374+
callReplyCallback(false)
362375
}
363376
return
364377
}
365378

366-
// Force unwrap the callback because it should always be set and is a
367-
// programming error if it isn't.
368-
//
369-
// Note: this may prevent other replyBlocks from being run, but should only
370-
// crash the GUI process meaning policy decisions will still be enforced.
371-
let callback = self.replyCallback!;
372-
373379
SNTAuthorizationHelper.authorizeExecution(for: e) { success in
374-
callback(success)
375380
DispatchQueue.main.sync {
381+
callReplyCallback(success)
376382
window?.close()
377383
}
378384
}
@@ -388,9 +394,7 @@ struct SNTBinaryMessageWindowView: View {
388394
}
389395

390396
// Close the window after responding to the block.
391-
if let callback = replyCallback {
392-
callback(false)
393-
}
397+
callReplyCallback(false)
394398
window?.close()
395399
}
396400
}

0 commit comments

Comments
 (0)