Process certificate signing request in the right event loop
Summary: To ensure that no deadlocks take place, it is important that there are no re-entrant calls from within the callbacks or event handlers. For the most part, this was already the case. Event and message handlers run critical sections into a Folly event scheduler. The only exception was the sendExpectResponse used during the certificate exchange. Once the response was received, the non-secure socket was disconnected. The solution was to put that operation in the Folly event scheduler as it should've been from the beginning. changelog: Certificate signing request response to be processed on the right event loop. Reviewed By: fabiomassimo Differential Revision: D35548148 fbshipit-source-id: cea2476ad66137f376acda66cdbc27801c0c47e1
This commit is contained in:
committed by
Facebook GitHub Bot
parent
30a1d09a83
commit
2bafe32f2a
@@ -233,7 +233,7 @@ bool FlipperConnectionManagerImpl::connectAndExchangeCertificate() {
|
|||||||
contextStore_->resetState();
|
contextStore_->resetState();
|
||||||
resettingState->complete();
|
resettingState->complete();
|
||||||
|
|
||||||
requestSignedCertFromFlipper();
|
requestSignedCertificate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,33 +377,17 @@ bool FlipperConnectionManagerImpl::isCertificateExchangeNeeded() {
|
|||||||
return !hasRequiredFiles;
|
return !hasRequiredFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlipperConnectionManagerImpl::requestSignedCertFromFlipper() {
|
void FlipperConnectionManagerImpl::processSignedCertificateResponse(
|
||||||
auto generatingCSR = flipperState_->start("Generate CSR");
|
std::shared_ptr<FlipperStep> gettingCert,
|
||||||
std::string csr = contextStore_->getCertificateSigningRequest();
|
std::string response,
|
||||||
generatingCSR->complete();
|
bool isError) {
|
||||||
int medium = certProvider_ != nullptr
|
|
||||||
? certProvider_->getCertificateExchangeMedium()
|
|
||||||
: FlipperCertificateExchangeMedium::FS_ACCESS;
|
|
||||||
folly::dynamic message = folly::dynamic::object("method", "signCertificate")(
|
|
||||||
"csr", csr.c_str())(
|
|
||||||
"destination",
|
|
||||||
contextStore_->getCertificateDirectoryPath().c_str())("medium", medium);
|
|
||||||
auto gettingCert = flipperState_->start("Getting cert from desktop");
|
|
||||||
|
|
||||||
certificateExchangeCompleted_ = false;
|
|
||||||
|
|
||||||
flipperEventBase_->add([this, message, gettingCert, medium]() {
|
|
||||||
client_->sendExpectResponse(
|
|
||||||
folly::toJson(message),
|
|
||||||
[this, message, gettingCert, medium](
|
|
||||||
const std::string& response, bool isError) {
|
|
||||||
/**
|
/**
|
||||||
Need to keep track of whether the response has been handled.
|
Need to keep track of whether the response has been
|
||||||
On success, the completion handler deallocates the socket which in
|
handled. On success, the completion handler deallocates the socket which in
|
||||||
turn triggers a disconnect. A disconnect is called within the
|
turn triggers a disconnect. A disconnect is called within
|
||||||
context of a subscription handler. This means that the completion
|
the context of a subscription handler. This means that the completion
|
||||||
handler can be called again to notify that the stream has been
|
handler can be called again to notify that the stream has
|
||||||
interrupted because we are effectively still handing the response
|
been interrupted because we are effectively still handing the response
|
||||||
read. So, if already handled, ignore and return;
|
read. So, if already handled, ignore and return;
|
||||||
*/
|
*/
|
||||||
if (certificateExchangeCompleted_)
|
if (certificateExchangeCompleted_)
|
||||||
@@ -418,6 +402,10 @@ void FlipperConnectionManagerImpl::requestSignedCertFromFlipper() {
|
|||||||
client_ = nullptr;
|
client_ = nullptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int medium = certProvider_ != nullptr
|
||||||
|
? certProvider_->getCertificateExchangeMedium()
|
||||||
|
: FlipperCertificateExchangeMedium::FS_ACCESS;
|
||||||
|
|
||||||
if (!response.empty()) {
|
if (!response.empty()) {
|
||||||
folly::dynamic config = folly::parseJson(response);
|
folly::dynamic config = folly::parseJson(response);
|
||||||
config["medium"] = medium;
|
config["medium"] = medium;
|
||||||
@@ -456,6 +444,32 @@ void FlipperConnectionManagerImpl::requestSignedCertFromFlipper() {
|
|||||||
// which will be handled by Flipper which will initiate
|
// which will be handled by Flipper which will initiate
|
||||||
// a reconnect sequence.
|
// a reconnect sequence.
|
||||||
client_ = nullptr;
|
client_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlipperConnectionManagerImpl::requestSignedCertificate() {
|
||||||
|
auto generatingCSR = flipperState_->start("Generate CSR");
|
||||||
|
std::string csr = contextStore_->getCertificateSigningRequest();
|
||||||
|
generatingCSR->complete();
|
||||||
|
|
||||||
|
int medium = certProvider_ != nullptr
|
||||||
|
? certProvider_->getCertificateExchangeMedium()
|
||||||
|
: FlipperCertificateExchangeMedium::FS_ACCESS;
|
||||||
|
folly::dynamic message = folly::dynamic::object("method", "signCertificate")(
|
||||||
|
"csr", csr.c_str())(
|
||||||
|
"destination",
|
||||||
|
contextStore_->getCertificateDirectoryPath().c_str())("medium", medium);
|
||||||
|
|
||||||
|
auto gettingCert = flipperState_->start("Getting cert from desktop");
|
||||||
|
|
||||||
|
certificateExchangeCompleted_ = false;
|
||||||
|
flipperEventBase_->add([this, message, gettingCert]() {
|
||||||
|
client_->sendExpectResponse(
|
||||||
|
folly::toJson(message),
|
||||||
|
[this, gettingCert](const std::string& response, bool isError) {
|
||||||
|
flipperEventBase_->add([this, gettingCert, response, isError]() {
|
||||||
|
this->processSignedCertificateResponse(
|
||||||
|
gettingCert, response, isError);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
failedConnectionAttempts_ = 0;
|
failedConnectionAttempts_ = 0;
|
||||||
|
|||||||
@@ -82,7 +82,11 @@ class FlipperConnectionManagerImpl : public FlipperConnectionManager {
|
|||||||
bool connectAndExchangeCertificate();
|
bool connectAndExchangeCertificate();
|
||||||
bool connectSecurely();
|
bool connectSecurely();
|
||||||
bool isCertificateExchangeNeeded();
|
bool isCertificateExchangeNeeded();
|
||||||
void requestSignedCertFromFlipper();
|
void requestSignedCertificate();
|
||||||
|
void processSignedCertificateResponse(
|
||||||
|
std::shared_ptr<FlipperStep> gettingCertificateStep,
|
||||||
|
std::string response,
|
||||||
|
bool isError);
|
||||||
bool isRunningInOwnThread();
|
bool isRunningInOwnThread();
|
||||||
void reevaluateSocketProvider();
|
void reevaluateSocketProvider();
|
||||||
std::string getDeviceId();
|
std::string getDeviceId();
|
||||||
|
|||||||
Reference in New Issue
Block a user