diff --git a/xplat/Flipper/ConnectionContextStore.cpp b/xplat/Flipper/ConnectionContextStore.cpp index 514eef14f..ffcf2d515 100644 --- a/xplat/Flipper/ConnectionContextStore.cpp +++ b/xplat/Flipper/ConnectionContextStore.cpp @@ -6,6 +6,7 @@ */ #include "ConnectionContextStore.h" +#include #include #include #include @@ -110,6 +111,21 @@ std::string ConnectionContextStore::getDeviceId() { } } +folly::Optional +ConnectionContextStore::getLastKnownMedium() { + try { + std::string config = + loadStringFromFile(absoluteFilePath(CONNECTION_CONFIG_FILE)); + auto maybeMedium = folly::parseJson(config)["medium"]; + return maybeMedium.isInt() + ? folly::Optional{static_cast< + FlipperCertificateExchangeMedium>(maybeMedium.getInt())} + : folly::none; + } catch (std::exception&) { + return folly::none; + } +} + void ConnectionContextStore::storeConnectionConfig(folly::dynamic& config) { std::string json = folly::toJson(config); writeStringToFile(json, absoluteFilePath(CONNECTION_CONFIG_FILE)); diff --git a/xplat/Flipper/ConnectionContextStore.h b/xplat/Flipper/ConnectionContextStore.h index a8a2b0eb1..bc13898b4 100644 --- a/xplat/Flipper/ConnectionContextStore.h +++ b/xplat/Flipper/ConnectionContextStore.h @@ -7,9 +7,11 @@ #pragma once +#include #include #include #include +#include "FlipperCertificateExchangeMedium.h" #include "FlipperInitConfig.h" namespace facebook { @@ -24,6 +26,10 @@ class ConnectionContextStore { std::string getCertificateDirectoryPath(); std::string getCACertificatePath(); std::string getDeviceId(); + /** + * Get medium over which the certificate was received. + */ + folly::Optional getLastKnownMedium(); void storeConnectionConfig(folly::dynamic& config); bool resetState(); diff --git a/xplat/Flipper/FlipperCertificateExchangeMedium.h b/xplat/Flipper/FlipperCertificateExchangeMedium.h index 552b081e5..0604dcd68 100644 --- a/xplat/Flipper/FlipperCertificateExchangeMedium.h +++ b/xplat/Flipper/FlipperCertificateExchangeMedium.h @@ -5,4 +5,6 @@ * LICENSE file in the root directory of this source tree. */ +#pragma once + enum FlipperCertificateExchangeMedium { FS_ACCESS = 1, WWW = 2 }; diff --git a/xplat/Flipper/FlipperConnectionManagerImpl.cpp b/xplat/Flipper/FlipperConnectionManagerImpl.cpp index 506db8580..a5ab36a35 100644 --- a/xplat/Flipper/FlipperConnectionManagerImpl.cpp +++ b/xplat/Flipper/FlipperConnectionManagerImpl.cpp @@ -357,6 +357,21 @@ bool FlipperConnectionManagerImpl::isCertificateExchangeNeeded() { return true; } + auto last_known_medium = contextStore_->getLastKnownMedium(); + if (!last_known_medium) { + return true; + } + + // When we exchange certs over WWW, we use a fake generated serial number and + // a virtual device. If medium changes to FS_ACCESS at some point, we should + // restart the exchange process to get the device ID of the real device. + int medium = certProvider_ != nullptr + ? certProvider_->getCertificateExchangeMedium() + : FlipperCertificateExchangeMedium::FS_ACCESS; + if (last_known_medium != medium) { + return true; + } + auto step = flipperState_->start("Check required certificates are present"); bool hasRequiredFiles = contextStore_->hasRequiredFiles(); if (hasRequiredFiles) { @@ -380,10 +395,10 @@ void FlipperConnectionManagerImpl::requestSignedCertFromFlipper() { certificateExchangeCompleted_ = false; - flipperEventBase_->add([this, message, gettingCert]() { + flipperEventBase_->add([this, message, gettingCert, medium]() { client_->sendExpectResponse( folly::toJson(message), - [this, message, gettingCert]( + [this, message, gettingCert, medium]( const std::string& response, bool isError) { /** Need to keep track of whether the response has been handled. @@ -412,6 +427,7 @@ void FlipperConnectionManagerImpl::requestSignedCertFromFlipper() { } if (!response.empty()) { folly::dynamic config = folly::parseJson(response); + config["medium"] = medium; contextStore_->storeConnectionConfig(config); } if (certProvider_) {