Wi-Fi Direct security implementation

PiperOrigin-RevId: 939931482
This commit is contained in:
hai007
2026-06-29 11:18:55 -07:00
committed by Copybara-Service
parent fa3ea7efd5
commit e0e428b00b
18 changed files with 128 additions and 25 deletions
@@ -1591,7 +1591,8 @@ Status BasePcpHandler::AcceptConnection(ClientProxy* client,
Exception write_exception =
channel->Write(parser::ForConnectionResponse(
Status::kSuccess, client->GetLocalOsInfo()));
Status::kSuccess, client->GetLocalOsInfo(),
client->GetLocalDeviceName()));
if (!write_exception.Ok()) {
LOG(INFO) << "AcceptConnection: failed to send response: endpoint_id="
<< endpoint_id;
@@ -1652,7 +1653,8 @@ Status BasePcpHandler::RejectConnection(ClientProxy* client,
Exception write_exception =
channel->Write(parser::ForConnectionResponse(
Status::kConnectionRejected, client->GetLocalOsInfo()));
Status::kConnectionRejected, client->GetLocalOsInfo(),
client->GetLocalDeviceName()));
if (!write_exception.Ok()) {
LOG(INFO) << "RejectConnection: failed to send response: endpoint_id="
<< endpoint_id;
@@ -1735,6 +1737,10 @@ void BasePcpHandler::OnIncomingFrame(
EvaluateConnectionResult(client, endpoint_id,
/* can_close_immediately= */ true);
if (connection_response.has_wifi_direct_device_name()) {
client->SetRemoteDeviceName(
endpoint_id, connection_response.wifi_direct_device_name());
}
latch.CountDown();
});
WaitForLatch("OnIncomingFrame()", &latch);
@@ -1609,8 +1609,8 @@ TEST_P(BasePcpHandlerTest, OnIncomingFrameChangesState) {
Status{Status::kSuccess});
LOG(INFO) << "Simulating remote accept: id=" << endpoint_id;
OsInfo os_info;
auto frame = parser::FromBytes(
parser::ForConnectionResponse(Status::kSuccess, os_info));
auto frame = parser::FromBytes(parser::ForConnectionResponse(
Status::kSuccess, os_info, "device_name"));
EXPECT_CALL(mock_connection_listener_.bandwidth_changed_cb, Call).Times(1);
pcp_handler.OnIncomingFrame(frame.result(), endpoint_id, client_.get(),
connect_medium);
+2 -1
View File
@@ -305,7 +305,8 @@ void BwuManager::InitiateBwuForEndpoint(ClientProxy* client,
->Write(parser::ForBwuPathRequest(
proposed_medium,
client->GetUpgradeMediums(endpoint_id).GetMediums(true),
medium_role))
medium_role,
mediums_->GetWifi().GetCapability().supports_5_ghz))
.Ok()) {
LOG(ERROR) << "BwuManager couldn't complete the upgrade for endpoint "
<< endpoint_id << " to medium "
@@ -1343,7 +1343,8 @@ TEST_F(BwuManagerTest, ProcessUpgradePathRequest_CanHost_True) {
location::nearby::connections::MediumRole remote_medium_role;
remote_medium_role.set_support_wifi_direct_group_client(true);
std::string bytes = parser::ForBwuPathRequest(
Medium::WIFI_DIRECT, {Medium::WIFI_DIRECT}, remote_medium_role);
Medium::WIFI_DIRECT, {Medium::WIFI_DIRECT}, remote_medium_role,
/*supports_5_ghz=*/true);
OfflineFrame frame;
frame.ParseFromString(bytes);
@@ -1390,7 +1391,8 @@ TEST_F(BwuManagerTest, ProcessUpgradePathRequest_CanHost_False) {
// Build the UpgradePathRequest frame where remote doesn't support GC
location::nearby::connections::MediumRole remote_medium_role;
std::string bytes = parser::ForBwuPathRequest(
Medium::WIFI_DIRECT, {Medium::WIFI_DIRECT}, remote_medium_role);
Medium::WIFI_DIRECT, {Medium::WIFI_DIRECT}, remote_medium_role,
/*supports_5_ghz=*/true);
OfflineFrame frame;
frame.ParseFromString(bytes);
@@ -1438,7 +1440,8 @@ TEST_F(BwuManagerTest, ProcessUpgradePathRequest_DynamicRoleSwitchDisabled) {
location::nearby::connections::MediumRole remote_medium_role;
remote_medium_role.set_support_wifi_direct_group_client(true);
std::string bytes = parser::ForBwuPathRequest(
Medium::WIFI_DIRECT, {Medium::WIFI_DIRECT}, remote_medium_role);
Medium::WIFI_DIRECT, {Medium::WIFI_DIRECT}, remote_medium_role,
/*supports_5_ghz=*/true);
OfflineFrame frame;
frame.ParseFromString(bytes);
@@ -276,6 +276,12 @@ ClientProxy::ClientProxy(std::unique_ptr<AnalyticsRecorder> analytics_recorder)
// Load advertising info from preferences.
LoadClientInfoFromPreferences();
#ifndef NEARBY_CHROMIUM
local_device_name_ = api::ImplementationPlatform::CreateDeviceInfo()
->GetOsDeviceName()
.value_or("");
#endif
if (preferences_manager_ != nullptr) {
app_lifecycle_monitor_ =
api::ImplementationPlatform::CreateAppLifecycleMonitor(
@@ -1176,6 +1182,26 @@ void ClientProxy::SetRemoteOsInfo(absl::string_view endpoint_id,
}
}
void ClientProxy::SetRemoteDeviceName(absl::string_view endpoint_id,
absl::string_view device_name) {
MutexLock lock(&mutex_);
ConnectionPair* item = LookupConnection(endpoint_id);
if (item != nullptr) {
item->first.device_name = std::string(device_name);
LOG(INFO) << "ClientProxy [SetRemoteDeviceName]: " << device_name;
}
}
std::string ClientProxy::GetRemoteDeviceName(
absl::string_view endpoint_id) const {
MutexLock lock(&mutex_);
const ConnectionPair* item = LookupConnection(endpoint_id);
if (item != nullptr) {
return item->first.device_name;
}
return "";
}
std::optional<std::int32_t> ClientProxy::GetRemoteSafeToDisconnectVersion(
absl::string_view endpoint_id) const {
MutexLock lock(&mutex_);
@@ -1655,6 +1681,7 @@ std::string ClientProxy::Dump() {
? location::nearby::connections::OsInfo::OsType_Name(
it->second.first.os_info->type())
: "unknown")
<< ", (remote device name) " << it->second.first.device_name
<< std::endl;
}
+8 -1
View File
@@ -75,6 +75,9 @@ class ClientProxy final {
std::string GetLocalEndpointId();
std::string GetLocalEndpointInfo() { return local_endpoint_info_; }
std::string GetLocalDeviceName() {
return local_device_name_;
}
// Override the base for received file attachments from a specific endpoint.
// Returns true if the endpoint is found and the path is overridden.
@@ -148,7 +151,6 @@ class ClientProxy final {
MutexLock lock(&mutex_);
local_endpoint_info_ = std::string(endpoint_info);
}
void UpdateAdvertisingOptions(const AdvertisingOptions& advertising_options) {
MutexLock lock(&mutex_);
advertising_options_ = advertising_options;
@@ -298,6 +300,9 @@ class ClientProxy final {
void SetRemoteOsInfo(
absl::string_view endpoint_id,
const location::nearby::connections::OsInfo& remote_os_info);
void SetRemoteDeviceName(absl::string_view endpoint_id,
absl::string_view device_name);
std::string GetRemoteDeviceName(absl::string_view endpoint_id) const;
void RegisterDeviceProvider(NearbyDeviceProvider* provider) {
external_device_provider_ = provider;
@@ -395,6 +400,7 @@ class ClientProxy final {
std::int32_t safe_to_disconnect_version;
std::int32_t remote_multiplex_socket_bitmask;
std::string save_path;
std::string device_name;
};
using ConnectionPair = std::pair<Connection, PayloadListener>;
@@ -465,6 +471,7 @@ class ClientProxy final {
std::string local_endpoint_id_;
std::string local_endpoint_info_;
std::string last_local_endpoint_id_;
std::string local_device_name_;
// If advertising is in stable endpoint ID mode, the endpoint ID is stable
// for 30s after advertising or disconnection. When stable_endpoint_id_mode_
@@ -1345,6 +1345,7 @@ TEST_F(ClientProxyTest, GetRemoteInfoNullWithoutConnections) {
EXPECT_FALSE(client1()
->GetRemoteSafeToDisconnectVersion(advertising_endpoint.id)
.has_value());
EXPECT_EQ(client1()->GetRemoteDeviceName(advertising_endpoint.id), "");
}
TEST_F(ClientProxyTest, SetRemoteInfoCorrect) {
@@ -1365,6 +1366,10 @@ TEST_F(ClientProxyTest, SetRemoteInfoCorrect) {
EXPECT_EQ(
client1()->GetRemoteSafeToDisconnectVersion(advertising_endpoint.id),
nearby_connections_version);
std::string device_name = "device_name";
client1()->SetRemoteDeviceName(advertising_endpoint.id, device_name);
EXPECT_EQ(client1()->GetRemoteDeviceName(advertising_endpoint.id),
device_name);
}
// Test ClientProxy::AddCancellationFlag, where if a flag is already in the map,
@@ -58,7 +58,8 @@ class WifiDirect {
bool IsGOStarted() ABSL_LOCKS_EXCLUDED(mutex_);
// Start WifiDirect Group Owner. Returns true if WifiDirect GO is successfully
// started.
bool StartWifiDirect() ABSL_LOCKS_EXCLUDED(mutex_);
bool StartWifiDirect()
ABSL_LOCKS_EXCLUDED(mutex_);
// Stop WifiDirect Group Owner
bool StopWifiDirect() ABSL_LOCKS_EXCLUDED(mutex_);
@@ -54,6 +54,11 @@ WifiDirectBwuHandler::WifiDirectBwuHandler(
std::string WifiDirectBwuHandler::HandleInitializeUpgradedMediumForEndpoint(
ClientProxy* client, const std::string& upgrade_service_id,
const std::string& endpoint_id) {
auto remote_device_name = client->GetRemoteDeviceName(endpoint_id);
WifiDirectCredentials* wifi_direct_crendential =
wifi_direct_medium_.GetCredentials(upgrade_service_id);
wifi_direct_crendential->SetRemoteDeviceName(remote_device_name);
// Create WifiDirect GO
if (!wifi_direct_medium_.StartWifiDirect()) {
LOG(INFO) << "Failed to start Wifi Direct!";
@@ -82,7 +87,7 @@ std::string WifiDirectBwuHandler::HandleInitializeUpgradedMediumForEndpoint(
// Note: Credentials are not generated until Medium StartWifiDirect() is
// called and the server socket is created. Be careful moving this codeblock
// around.
WifiDirectCredentials* wifi_direct_crendential =
wifi_direct_crendential =
wifi_direct_medium_.GetCredentials(upgrade_service_id);
std::string ssid = wifi_direct_crendential->GetSSID();
std::string password = wifi_direct_crendential->GetPassword();
+8 -2
View File
@@ -180,7 +180,8 @@ std::string ForConnectionRequestPresence(
return frame.SerializeAsString();
}
std::string ForConnectionResponse(std::int32_t status, const OsInfo& os_info) {
std::string ForConnectionResponse(std::int32_t status, const OsInfo& os_info,
const std::string& device_name) {
OfflineFrame frame;
frame.set_version(OfflineFrame::V1);
@@ -201,6 +202,7 @@ std::string ForConnectionResponse(std::int32_t status, const OsInfo& os_info) {
NearbyFlags::GetInstance().GetInt64Flag(
config_package_nearby::nearby_connections_feature::
kSafeToDisconnectVersion));
sub_frame->set_wifi_direct_device_name(device_name);
return frame.SerializeAsString();
}
@@ -508,7 +510,8 @@ std::string ForBwuFailure(const UpgradePathInfo& info) {
}
std::string ForBwuPathRequest(Medium medium, const std::vector<Medium>& mediums,
const MediumRole& medium_role) {
const MediumRole& medium_role,
bool supports_5_ghz) {
OfflineFrame frame;
frame.set_version(OfflineFrame::V1);
@@ -524,6 +527,9 @@ std::string ForBwuPathRequest(Medium medium, const std::vector<Medium>& mediums,
for (const auto& medium : mediums) {
upgrade_path_request->add_mediums(MediumToUpgradePathInfoMedium(medium));
}
LOG(INFO) << "ForBwuPathRequest: supports_5_ghz: " << supports_5_ghz;
upgrade_path_request->mutable_medium_meta_data()->set_supports_5_ghz(
supports_5_ghz);
auto* role =
upgrade_path_request->mutable_medium_meta_data()->mutable_medium_role();
role->MergeFrom(medium_role);
+4 -2
View File
@@ -59,7 +59,8 @@ std::string ForConnectionRequestPresence(
const location::nearby::connections::PresenceDevice& proto_presence_device,
const ConnectionInfo& connection_info);
std::string ForConnectionResponse(
std::int32_t status, const location::nearby::connections::OsInfo& os_info);
std::int32_t status, const location::nearby::connections::OsInfo& os_info,
const std::string& device_name);
// Builds Payload transfer messages.
std::string ForDataPayloadTransfer(
@@ -109,7 +110,8 @@ std::string ForBwuWebrtcPathAvailable(
std::string ForBwuFailure(const UpgradePathInfo& info);
std::string ForBwuPathRequest(
Medium medium, const std::vector<Medium>& mediums,
const location::nearby::connections::MediumRole& medium_role);
const location::nearby::connections::MediumRole& medium_role,
bool supports_5_ghz);
std::string ForBwuLastWrite();
std::string ForBwuSafeToClose();
@@ -352,6 +352,7 @@ TEST(OfflineFramesTest, CanGenerateConnectionResponse) {
os_info { type: LINUX }
multiplex_socket_bitmask: 0
safe_to_disconnect_version: 5
wifi_direct_device_name: "device_name"
>
>)pb";
@@ -361,7 +362,8 @@ TEST(OfflineFramesTest, CanGenerateConnectionResponse) {
config_package_nearby::nearby_connections_feature::
kSafeToDisconnectVersion,
5);
auto response = FromBytes(ForConnectionResponse(1, os_info));
auto response = FromBytes(
ForConnectionResponse(1, os_info, "device_name"));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
@@ -734,6 +736,7 @@ TEST(OfflineFramesTest, CanGenerateBwuPathRequest) {
upgrade_path_request: <
mediums: WIFI_HOTSPOT
medium_meta_data: <
supports_5_ghz: true
medium_role: < support_wifi_hotspot_client: true >
>
>
@@ -745,7 +748,8 @@ TEST(OfflineFramesTest, CanGenerateBwuPathRequest) {
MediumRole medium_role;
medium_role.set_support_wifi_hotspot_client(true);
auto response =
FromBytes(ForBwuPathRequest(Medium::WIFI_HOTSPOT, mediums, medium_role));
FromBytes(ForBwuPathRequest(Medium::WIFI_HOTSPOT, mediums, medium_role,
/*supports_5_ghz=*/true));
ASSERT_TRUE(response.ok());
OfflineFrame message = response.result();
EXPECT_THAT(message, EqualsProto(kExpected));
@@ -72,7 +72,7 @@ constexpr int kWifiDirectPinMinLength = 0;
constexpr int kWifiDirectPinMaxLength = 16;
inline bool WithinRange(int value, int min, int max) {
return value >= min && value < max;
return value >= min && value <= max;
}
Exception EnsureValidConnectionRequestFrame(
@@ -292,7 +292,7 @@ Exception EnsureValidBandwidthUpgradeWifiDirectPathAvailableFrame(
std::string(kWifiDirectSsidPatternString).c_str());
bool ssid_valid =
wifi_direct_credentials.has_ssid() &&
wifi_direct_credentials.ssid().length() < kWifiDirectSsidMaxLength &&
wifi_direct_credentials.ssid().length() <= kWifiDirectSsidMaxLength &&
std::regex_match(wifi_direct_credentials.ssid(), ssid_pattern);
bool password_valid =
wifi_direct_credentials.has_password() &&
@@ -179,7 +179,8 @@ TEST(OfflineFramesValidatorTest,
OfflineFrame offline_frame;
OsInfo os_info;
std::string bytes = ForConnectionResponse(kStatusAccepted, os_info);
std::string bytes = ForConnectionResponse(kStatusAccepted, os_info,
"device_name");
offline_frame.ParseFromString(bytes);
auto ret_value = EnsureValidOfflineFrame(offline_frame);
@@ -192,7 +193,8 @@ TEST(OfflineFramesValidatorTest,
OfflineFrame offline_frame;
OsInfo os_info;
std::string bytes = ForConnectionResponse(kStatusAccepted, os_info);
std::string bytes =
ForConnectionResponse(kStatusAccepted, os_info, "device_name");
offline_frame.ParseFromString(bytes);
auto* v1_frame = offline_frame.mutable_v1();
@@ -208,7 +210,8 @@ TEST(OfflineFramesValidatorTest,
OfflineFrame offline_frame;
OsInfo os_info;
std::string bytes = ForConnectionResponse(-1, os_info);
std::string bytes =
ForConnectionResponse(-1, os_info, "device_name");
offline_frame.ParseFromString(bytes);
auto ret_value = EnsureValidOfflineFrame(offline_frame);
@@ -776,6 +779,25 @@ TEST(OfflineFramesValidatorTest,
EXPECT_FALSE(ret_value.Ok());
std::string wifi_direct_ssid_64_length =
"DIRECT-A0-" + std::string(54, 'A');
bytes = ForBwuWifiDirectPathAvailable(
wifi_direct_ssid_64_length, std::string(kWifiDirectPassword), kPort,
kWifiDirectFrequency, kSupportsDisablingEncryption, std::string(kGateway),
std::string(kWifiDirectDeviceName), /*pin=*/"01234567890123456");
offline_frame_2.ParseFromString(bytes);
ret_value = EnsureValidOfflineFrame(offline_frame_2);
EXPECT_FALSE(ret_value.Ok());
std::string wifi_direct_pin_16_length = "0123456789012345";
bytes = ForBwuWifiDirectPathAvailable(
std::string(kWifiDirectSsid), std::string(kWifiDirectPassword), kPort,
kWifiDirectFrequency, kSupportsDisablingEncryption, std::string(kGateway),
std::string(kWifiDirectDeviceName), wifi_direct_pin_16_length);
offline_frame_2.ParseFromString(bytes);
ret_value = EnsureValidOfflineFrame(offline_frame_2);
EXPECT_TRUE(ret_value.Ok());
std::string wifi_direct_ssid_wrong_length =
std::string{kWifiDirectSsid} + "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
std::string wifi_direct_device_name_wrong_length =
@@ -239,7 +239,6 @@ class WifiDirectMedium : public api::WifiDirectMedium {
std::unique_ptr<api::WifiDirectServerSocket> ListenForService(
int port) override;
// Advertiser start WiFiDirect GO with specific Credentials.
bool StartWifiDirect(WifiDirectCredentials* wifi_direct_credentials) override;
// Advertiser stop the current WiFiDirect GO.
bool StopWifiDirect() override;
@@ -347,6 +346,7 @@ class WifiDirectMedium : public api::WifiDirectMedium {
std::string ip_address_local_;
std::string ip_address_remote_;
absl::CondVar is_ip_address_ready_;
std::string remote_device_name_;
WifiDirectServerSocket* server_socket_ptr_ ABSL_GUARDED_BY(mutex_) = nullptr;
SubmittableExecutor listener_executor_;
@@ -251,8 +251,10 @@ std::unique_ptr<api::WifiDirectServerSocket> WifiDirectMedium::ListenForService(
bool WifiDirectMedium::StartWifiDirect(
WifiDirectCredentials* wifi_direct_credentials) {
remote_device_name_ = wifi_direct_credentials->GetRemoteDeviceName();
LOG(INFO) << __func__ << ": remote_device_name from credentials: "
<< remote_device_name_;
absl::MutexLock lock(mutex_);
LOG(INFO) << __func__ << ": Start to create WiFiDirect.";
if (IsBeaconing()) {
LOG(WARNING) << "Cannot create WiFiDirect GO again when it is running.";
return true;
@@ -431,6 +433,12 @@ fire_and_forget WifiDirectMedium::OnConnectionRequested(
LOG(INFO) << "Receive connection request from: "
<< winrt::to_string(device_name)
<< "; device ID: " << winrt::to_string(device_id);
if (!remote_device_name_.empty() &&
!absl::EqualsIgnoreCase(remote_device_name_,
winrt::to_string(device_name))) {
LOG(INFO) << "Ignore the connection request from the unrelated device.";
return winrt::fire_and_forget();
}
DeviceInformation windows_device_info(connection_request.DeviceInformation());
auto deviceInfoP =
@@ -14,7 +14,6 @@
#include <windows.h>
#include <exception>
#include <memory>
#include <string>
#include <utility>
+7
View File
@@ -123,6 +123,12 @@ class WifiDirectCredentials {
return technology_;
}
// Get/Set Remote Device Name.
std::string GetRemoteDeviceName() const { return remote_device_name_; }
void SetRemoteDeviceName(const std::string& remote_device_name) {
remote_device_name_ = remote_device_name;
}
private:
// There are 2 types of WifiDirectAuthType.
// 1. Without Service Discovery: the credentials are ssid/password.
@@ -137,6 +143,7 @@ class WifiDirectCredentials {
std::string gateway_ = "0.0.0.0";
int port_ = 0;
int frequency_ = -1;
std::string remote_device_name_;
location::nearby::proto::connections::ConnectionBand band_;
location::nearby::proto::connections::ConnectionTechnology technology_;
};