Skip to content

Commit 05684b0

Browse files
committed
Bug 1851294 - Add nsITLSSocketControl.asyncStartTLS r=jschanck,necko-reviewers,kershaw
Thunderbird uses nsITLSSocketControl.startTLS to drive the XMPP connection, but since we started enforcing proper thread safety in bug 1847260, it's asserting when called on the main thread. This patch marks StartTLS and proxyStartTLS as [noscript] and adds asyncStartTLS. This new method dispatches a runnable to the socket thread to call startTLS, then resolves (or rejects with the nsresult as an arg) on the main thread. Differential Revision: https://phabricator.services.mozilla.com/D207692
1 parent 2f65cf2 commit 05684b0

File tree

5 files changed

+71
-2
lines changed

5 files changed

+71
-2
lines changed

netwerk/base/FuzzySocketControl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,12 @@ FuzzySocketControl::ProxyStartSSL() { return NS_OK; }
123123
NS_IMETHODIMP
124124
FuzzySocketControl::StartTLS() { return NS_OK; }
125125

126+
NS_IMETHODIMP
127+
FuzzySocketControl::AsyncStartTLS(JSContext* aCx,
128+
mozilla::dom::Promise** aPromise) {
129+
return NS_OK;
130+
}
131+
126132
NS_IMETHODIMP
127133
FuzzySocketControl::SetNPNList(nsTArray<nsCString>& protocolArray) {
128134
return NS_OK;

security/manager/ssl/CommonSocketControl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,12 @@ CommonSocketControl::ProxyStartSSL(void) { return NS_ERROR_NOT_IMPLEMENTED; }
124124
NS_IMETHODIMP
125125
CommonSocketControl::StartTLS(void) { return NS_ERROR_NOT_IMPLEMENTED; }
126126

127+
NS_IMETHODIMP
128+
CommonSocketControl::AsyncStartTLS(JSContext* aCx,
129+
mozilla::dom::Promise** aPromise) {
130+
return NS_ERROR_NOT_IMPLEMENTED;
131+
}
132+
127133
NS_IMETHODIMP
128134
CommonSocketControl::SetNPNList(nsTArray<nsCString>& aNPNList) {
129135
return NS_ERROR_NOT_IMPLEMENTED;

security/manager/ssl/NSSSocketControl.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "nsISocketProvider.h"
1212
#include "secerr.h"
1313
#include "mozilla/Base64.h"
14+
#include "mozilla/dom/Promise.h"
1415
#include "nsNSSCallbacks.h"
1516

1617
using namespace mozilla;
@@ -292,6 +293,53 @@ NSSSocketControl::StartTLS() {
292293
return ActivateSSL();
293294
}
294295

296+
NS_IMETHODIMP
297+
NSSSocketControl::AsyncStartTLS(JSContext* aCx,
298+
mozilla::dom::Promise** aPromise) {
299+
MOZ_RELEASE_ASSERT(NS_IsMainThread());
300+
NS_ENSURE_ARG_POINTER(aCx);
301+
NS_ENSURE_ARG_POINTER(aPromise);
302+
303+
nsIGlobalObject* globalObject = xpc::CurrentNativeGlobal(aCx);
304+
if (!globalObject) {
305+
return NS_ERROR_UNEXPECTED;
306+
}
307+
308+
ErrorResult result;
309+
RefPtr<mozilla::dom::Promise> promise =
310+
mozilla::dom::Promise::Create(globalObject, result);
311+
if (result.Failed()) {
312+
return result.StealNSResult();
313+
}
314+
315+
nsCOMPtr<nsIEventTarget> target(
316+
do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID));
317+
if (!target) {
318+
return NS_ERROR_UNEXPECTED;
319+
}
320+
321+
nsCOMPtr<nsIRunnable> runnable(NS_NewRunnableFunction(
322+
"AsyncStartTLS::StartTLS", [promise, self = RefPtr{this}]() {
323+
nsresult rv = self->StartTLS();
324+
NS_DispatchToMainThread(
325+
NS_NewRunnableFunction("AsyncStartTLS::Resolve", [rv, promise]() {
326+
if (NS_FAILED(rv)) {
327+
promise->MaybeReject(rv);
328+
} else {
329+
promise->MaybeResolveWithUndefined();
330+
}
331+
}));
332+
}));
333+
334+
nsresult rv = target->Dispatch(runnable, NS_DISPATCH_NORMAL);
335+
if (NS_FAILED(rv)) {
336+
return rv;
337+
}
338+
339+
promise.forget(aPromise);
340+
return NS_OK;
341+
}
342+
295343
NS_IMETHODIMP
296344
NSSSocketControl::SetNPNList(nsTArray<nsCString>& protocolArray) {
297345
COMMON_SOCKET_CONTROL_ASSERT_ON_OWNING_THREAD();

security/manager/ssl/NSSSocketControl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class NSSSocketControl final : public CommonSocketControl {
5151
// From nsITLSSocketControl.
5252
NS_IMETHOD ProxyStartSSL(void) override;
5353
NS_IMETHOD StartTLS(void) override;
54+
NS_IMETHOD AsyncStartTLS(JSContext* aCx,
55+
mozilla::dom::Promise** aPromise) override;
5456
NS_IMETHOD SetNPNList(nsTArray<nsCString>& aNPNList) override;
5557
NS_IMETHOD GetAlpnEarlySelection(nsACString& _retval) override;
5658
NS_IMETHOD GetEarlyDataAccepted(bool* aEarlyDataAccepted) override;

security/manager/ssl/nsITLSSocketControl.idl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,15 @@ interface nsIX509Cert;
2323
// thread (except for asyncGetSecurityInfo);
2424
[scriptable, builtinclass, uuid(418265c8-654e-4fbb-ba62-4eed27de1f03)]
2525
interface nsITLSSocketControl : nsISupports {
26-
void proxyStartSSL();
27-
void StartTLS();
26+
[noscript] void proxyStartSSL();
27+
[noscript] void StartTLS();
28+
29+
/**
30+
* Calls StartTLS on the socket thread, and resolves with the nsresult
31+
* return value of that call.
32+
*/
33+
[implicit_jscontext,must_use]
34+
Promise asyncStartTLS();
2835

2936
/* NPN (Next Protocol Negotiation) is a mechanism for
3037
negotiating the protocol to be spoken inside the SSL

0 commit comments

Comments
 (0)