Loading security/manager/ssl/nsNSSCallbacks.cpp +32 −8 Original line number Diff line number Diff line Loading @@ -491,6 +491,21 @@ mozilla::pkix::Result DoOCSPRequest( return Success; } // Helper struct to simplify thread coordination in `ShowProtectedAuthPrompt`. struct BackgroundPromptStatus final { explicit BackgroundPromptStatus(PK11SlotInfo* slot) : mSlot(slot), mDone(false), mResult(SECFailure) {} NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundPromptStatus) UniquePK11SlotInfo mSlot; Atomic<bool> mDone; SECStatus mResult; private: ~BackgroundPromptStatus() = default; }; static char* ShowProtectedAuthPrompt(PK11SlotInfo* slot, nsIPrompt* prompt) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(slot); Loading @@ -501,12 +516,13 @@ static char* ShowProtectedAuthPrompt(PK11SlotInfo* slot, nsIPrompt* prompt) { // Dispatch a background task to (eventually) call C_Login. The call will // block until the protected authentication succeeds or fails. Atomic<bool> done; Atomic<SECStatus> result; nsresult rv = NS_DispatchBackgroundTask(NS_NewRunnableFunction(__func__, [&]() mutable { result = PK11_CheckUserPassword(slot, nullptr); done = true; RefPtr<BackgroundPromptStatus> backgroundPromptStatus( new BackgroundPromptStatus(PK11_ReferenceSlot(slot))); nsresult rv = NS_DispatchBackgroundTask( NS_NewRunnableFunction(__func__, [backgroundPromptStatus]() mutable { backgroundPromptStatus->mResult = PK11_CheckUserPassword( backgroundPromptStatus->mSlot.get(), nullptr); backgroundPromptStatus->mDone = true; })); if (NS_FAILED(rv)) { return nullptr; Loading @@ -529,15 +545,23 @@ static char* ShowProtectedAuthPrompt(PK11SlotInfo* slot, nsIPrompt* prompt) { if (NS_FAILED(errorResult.StealNSResult())) { return nullptr; } // The idea here is to dispatch the background task before showing the // (synchronous) alert, so that the browser is telling the user what to do // while waiting for the protected authentication (if the alert were shown // before dispatching the task, the user would have to dismiss it first). rv = prompt->Alert(nullptr, NS_ConvertUTF8toUTF16(promptString).get()); if (NS_FAILED(rv)) { return nullptr; } // Spin the event loop until the background task has completed. MOZ_ALWAYS_TRUE(SpinEventLoopUntil( "ShowProtectedAuthPrompt"_ns, [&]() { return static_cast<bool>(done); })); "ShowProtectedAuthPrompt"_ns, [backgroundPromptStatus]() { return static_cast<bool>(backgroundPromptStatus->mDone); })); switch (result) { switch (backgroundPromptStatus->mResult) { case SECSuccess: return ToNewCString(nsDependentCString(PK11_PW_AUTHENTICATED)); case SECWouldBlock: Loading Loading
security/manager/ssl/nsNSSCallbacks.cpp +32 −8 Original line number Diff line number Diff line Loading @@ -491,6 +491,21 @@ mozilla::pkix::Result DoOCSPRequest( return Success; } // Helper struct to simplify thread coordination in `ShowProtectedAuthPrompt`. struct BackgroundPromptStatus final { explicit BackgroundPromptStatus(PK11SlotInfo* slot) : mSlot(slot), mDone(false), mResult(SECFailure) {} NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundPromptStatus) UniquePK11SlotInfo mSlot; Atomic<bool> mDone; SECStatus mResult; private: ~BackgroundPromptStatus() = default; }; static char* ShowProtectedAuthPrompt(PK11SlotInfo* slot, nsIPrompt* prompt) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(slot); Loading @@ -501,12 +516,13 @@ static char* ShowProtectedAuthPrompt(PK11SlotInfo* slot, nsIPrompt* prompt) { // Dispatch a background task to (eventually) call C_Login. The call will // block until the protected authentication succeeds or fails. Atomic<bool> done; Atomic<SECStatus> result; nsresult rv = NS_DispatchBackgroundTask(NS_NewRunnableFunction(__func__, [&]() mutable { result = PK11_CheckUserPassword(slot, nullptr); done = true; RefPtr<BackgroundPromptStatus> backgroundPromptStatus( new BackgroundPromptStatus(PK11_ReferenceSlot(slot))); nsresult rv = NS_DispatchBackgroundTask( NS_NewRunnableFunction(__func__, [backgroundPromptStatus]() mutable { backgroundPromptStatus->mResult = PK11_CheckUserPassword( backgroundPromptStatus->mSlot.get(), nullptr); backgroundPromptStatus->mDone = true; })); if (NS_FAILED(rv)) { return nullptr; Loading @@ -529,15 +545,23 @@ static char* ShowProtectedAuthPrompt(PK11SlotInfo* slot, nsIPrompt* prompt) { if (NS_FAILED(errorResult.StealNSResult())) { return nullptr; } // The idea here is to dispatch the background task before showing the // (synchronous) alert, so that the browser is telling the user what to do // while waiting for the protected authentication (if the alert were shown // before dispatching the task, the user would have to dismiss it first). rv = prompt->Alert(nullptr, NS_ConvertUTF8toUTF16(promptString).get()); if (NS_FAILED(rv)) { return nullptr; } // Spin the event loop until the background task has completed. MOZ_ALWAYS_TRUE(SpinEventLoopUntil( "ShowProtectedAuthPrompt"_ns, [&]() { return static_cast<bool>(done); })); "ShowProtectedAuthPrompt"_ns, [backgroundPromptStatus]() { return static_cast<bool>(backgroundPromptStatus->mDone); })); switch (result) { switch (backgroundPromptStatus->mResult) { case SECSuccess: return ToNewCString(nsDependentCString(PK11_PW_AUTHENTICATED)); case SECWouldBlock: Loading