Commit 685d17c2 authored by Ryan Hansberry's avatar Ryan Hansberry Committed by Chromium LUCI CQ

[Bluetooth] Support listening on insecure RFCOMM service in Mojo interface.

Nearby Connections needs to specify that its registered RFCOMM service
should not bond to the remote device on the other side of the connection;
CreateRfcommService() is adjusted to CreateRfcommServiceInsecurely() to
accommodate this need.

Sidenote: this further necessitates an allowlist on service UUIDs and
service names: that is tracked at b/162975217.

Fixed: 1151116
Change-Id: I8db8e9864ce22122b7af6c8554161f987f6114d0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2553188Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarJames Vecore <vecore@google.com>
Commit-Queue: Ryan Hansberry <hansberry@chromium.org>
Cr-Commit-Position: refs/heads/master@{#833047}
parent 7aa679e4
...@@ -94,7 +94,7 @@ std::unique_ptr<api::BluetoothServerSocket> ...@@ -94,7 +94,7 @@ std::unique_ptr<api::BluetoothServerSocket>
BluetoothClassicMedium::ListenForService(const std::string& service_name, BluetoothClassicMedium::ListenForService(const std::string& service_name,
const std::string& service_uuid) { const std::string& service_uuid) {
mojo::PendingRemote<bluetooth::mojom::ServerSocket> server_socket; mojo::PendingRemote<bluetooth::mojom::ServerSocket> server_socket;
bool success = adapter_->CreateRfcommService( bool success = adapter_->CreateRfcommServiceInsecurely(
service_name, device::BluetoothUUID(service_uuid), &server_socket); service_name, device::BluetoothUUID(service_uuid), &server_socket);
if (success && server_socket) { if (success && server_socket) {
......
...@@ -198,9 +198,10 @@ void FakeAdapter::ConnectToServiceInsecurely( ...@@ -198,9 +198,10 @@ void FakeAdapter::ConnectToServiceInsecurely(
std::move(callback).Run(std::move(connect_to_service_result)); std::move(callback).Run(std::move(connect_to_service_result));
} }
void FakeAdapter::CreateRfcommService(const std::string& service_name, void FakeAdapter::CreateRfcommServiceInsecurely(
const device::BluetoothUUID& service_uuid, const std::string& service_name,
CreateRfcommServiceCallback callback) { const device::BluetoothUUID& service_uuid,
CreateRfcommServiceInsecurelyCallback callback) {
if (!base::Contains(allowed_connections_for_service_name_and_uuid_pair_, if (!base::Contains(allowed_connections_for_service_name_and_uuid_pair_,
std::make_pair(service_name, service_uuid))) { std::make_pair(service_name, service_uuid))) {
std::move(callback).Run(/*server_socket=*/mojo::NullRemote()); std::move(callback).Run(/*server_socket=*/mojo::NullRemote());
......
...@@ -39,9 +39,10 @@ class FakeAdapter : public mojom::Adapter { ...@@ -39,9 +39,10 @@ class FakeAdapter : public mojom::Adapter {
const std::string& address, const std::string& address,
const device::BluetoothUUID& service_uuid, const device::BluetoothUUID& service_uuid,
ConnectToServiceInsecurelyCallback callback) override; ConnectToServiceInsecurelyCallback callback) override;
void CreateRfcommService(const std::string& service_name, void CreateRfcommServiceInsecurely(
const device::BluetoothUUID& service_uuid, const std::string& service_name,
CreateRfcommServiceCallback callback) override; const device::BluetoothUUID& service_uuid,
CreateRfcommServiceInsecurelyCallback callback) override;
void SetAdvertisementDestroyedCallback(base::OnceClosure callback); void SetAdvertisementDestroyedCallback(base::OnceClosure callback);
const std::vector<uint8_t>* GetRegisteredAdvertisementServiceData( const std::vector<uint8_t>* GetRegisteredAdvertisementServiceData(
......
...@@ -150,7 +150,7 @@ BluetoothInternalsTest.prototype = { ...@@ -150,7 +150,7 @@ BluetoothInternalsTest.prototype = {
return {result: null}; return {result: null};
} }
async createRfcommService(service_name, service_uuid) { async createRfcommServiceInsecurely(service_name, service_uuid) {
return {result: null}; return {result: null};
} }
......
...@@ -199,18 +199,20 @@ void Adapter::ConnectToServiceInsecurely( ...@@ -199,18 +199,20 @@ void Adapter::ConnectToServiceInsecurely(
#endif #endif
} }
void Adapter::CreateRfcommService(const std::string& service_name, void Adapter::CreateRfcommServiceInsecurely(
const device::BluetoothUUID& service_uuid, const std::string& service_name,
CreateRfcommServiceCallback callback) { const device::BluetoothUUID& service_uuid,
CreateRfcommServiceInsecurelyCallback callback) {
device::BluetoothAdapter::ServiceOptions service_options; device::BluetoothAdapter::ServiceOptions service_options;
service_options.name = service_name; service_options.name = service_name;
service_options.require_authentication = false;
auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback)); auto copyable_callback = base::AdaptCallbackForRepeating(std::move(callback));
adapter_->CreateRfcommService( adapter_->CreateRfcommService(
service_uuid, service_options, service_uuid, service_options,
base::BindOnce(&Adapter::OnCreateRfcommService, base::BindOnce(&Adapter::OnCreateRfcommServiceInsecurely,
weak_ptr_factory_.GetWeakPtr(), copyable_callback), weak_ptr_factory_.GetWeakPtr(), copyable_callback),
base::BindOnce(&Adapter::OnCreateRfcommServiceError, base::BindOnce(&Adapter::OnCreateRfcommServiceInsecurelyError,
weak_ptr_factory_.GetWeakPtr(), copyable_callback)); weak_ptr_factory_.GetWeakPtr(), copyable_callback));
} }
...@@ -421,8 +423,8 @@ void Adapter::OnConnectToServiceError( ...@@ -421,8 +423,8 @@ void Adapter::OnConnectToServiceError(
std::move(callback).Run(/*result=*/nullptr); std::move(callback).Run(/*result=*/nullptr);
} }
void Adapter::OnCreateRfcommService( void Adapter::OnCreateRfcommServiceInsecurely(
CreateRfcommServiceCallback callback, CreateRfcommServiceInsecurelyCallback callback,
scoped_refptr<device::BluetoothSocket> socket) { scoped_refptr<device::BluetoothSocket> socket) {
mojo::PendingRemote<mojom::ServerSocket> pending_server_socket; mojo::PendingRemote<mojom::ServerSocket> pending_server_socket;
mojo::MakeSelfOwnedReceiver( mojo::MakeSelfOwnedReceiver(
...@@ -431,8 +433,9 @@ void Adapter::OnCreateRfcommService( ...@@ -431,8 +433,9 @@ void Adapter::OnCreateRfcommService(
std::move(callback).Run(std::move(pending_server_socket)); std::move(callback).Run(std::move(pending_server_socket));
} }
void Adapter::OnCreateRfcommServiceError(CreateRfcommServiceCallback callback, void Adapter::OnCreateRfcommServiceInsecurelyError(
const std::string& message) { CreateRfcommServiceInsecurelyCallback callback,
const std::string& message) {
LOG(ERROR) << "Failed to create service: '" << message << "'"; LOG(ERROR) << "Failed to create service: '" << message << "'";
std::move(callback).Run(/*server_socket=*/mojo::NullRemote()); std::move(callback).Run(/*server_socket=*/mojo::NullRemote());
} }
......
...@@ -54,9 +54,10 @@ class Adapter : public mojom::Adapter, ...@@ -54,9 +54,10 @@ class Adapter : public mojom::Adapter,
const std::string& address, const std::string& address,
const device::BluetoothUUID& service_uuid, const device::BluetoothUUID& service_uuid,
ConnectToServiceInsecurelyCallback callback) override; ConnectToServiceInsecurelyCallback callback) override;
void CreateRfcommService(const std::string& service_name, void CreateRfcommServiceInsecurely(
const device::BluetoothUUID& service_uuid, const std::string& service_name,
CreateRfcommServiceCallback callback) override; const device::BluetoothUUID& service_uuid,
CreateRfcommServiceInsecurelyCallback callback) override;
// device::BluetoothAdapter::Observer overrides: // device::BluetoothAdapter::Observer overrides:
void AdapterPresentChanged(device::BluetoothAdapter* adapter, void AdapterPresentChanged(device::BluetoothAdapter* adapter,
...@@ -111,10 +112,12 @@ class Adapter : public mojom::Adapter, ...@@ -111,10 +112,12 @@ class Adapter : public mojom::Adapter,
void OnConnectToServiceError(ConnectToServiceInsecurelyCallback callback, void OnConnectToServiceError(ConnectToServiceInsecurelyCallback callback,
const std::string& message); const std::string& message);
void OnCreateRfcommService(CreateRfcommServiceCallback callback, void OnCreateRfcommServiceInsecurely(
scoped_refptr<device::BluetoothSocket> socket); CreateRfcommServiceInsecurelyCallback callback,
void OnCreateRfcommServiceError(CreateRfcommServiceCallback callback, scoped_refptr<device::BluetoothSocket> socket);
const std::string& message); void OnCreateRfcommServiceInsecurelyError(
CreateRfcommServiceInsecurelyCallback callback,
const std::string& message);
// The current Bluetooth adapter. // The current Bluetooth adapter.
scoped_refptr<device::BluetoothAdapter> adapter_; scoped_refptr<device::BluetoothAdapter> adapter_;
......
...@@ -307,7 +307,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter ...@@ -307,7 +307,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
const std::vector<uint8_t>& value) {} const std::vector<uint8_t>& value) {}
}; };
// Used to configure a listening servie. // Used to configure a listening service.
struct DEVICE_BLUETOOTH_EXPORT ServiceOptions { struct DEVICE_BLUETOOTH_EXPORT ServiceOptions {
ServiceOptions(); ServiceOptions();
~ServiceOptions(); ~ServiceOptions();
...@@ -315,6 +315,16 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter ...@@ -315,6 +315,16 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter
base::Optional<int> channel; base::Optional<int> channel;
base::Optional<int> psm; base::Optional<int> psm;
base::Optional<std::string> name; base::Optional<std::string> name;
// Clients can configure this option to choose if they want to enforce
// bonding with remote devices that connect to this device. Options:
// * Unset: bonding is not enforced by the local device, and the remote
// device can choose if they want to enforce bonding.
// * Set to false: bonding is prevented by the local device. Clients which
// use this are responsible for securing their communication at the
// application level.
// * Set to true: bonding is enforced by the local device.
base::Optional<bool> require_authentication;
}; };
// The ErrorCallback is used for methods that can fail in which case it is // The ErrorCallback is used for methods that can fail in which case it is
......
...@@ -106,7 +106,7 @@ void BluetoothSocketBlueZ::Connect(const BluetoothDeviceBlueZ* device, ...@@ -106,7 +106,7 @@ void BluetoothSocketBlueZ::Connect(const BluetoothDeviceBlueZ* device,
uuid_ = uuid; uuid_ = uuid;
options_.reset(new bluez::BluetoothProfileManagerClient::Options()); options_.reset(new bluez::BluetoothProfileManagerClient::Options());
if (security_level == SECURITY_LEVEL_LOW) if (security_level == SECURITY_LEVEL_LOW)
options_->require_authentication.reset(new bool(false)); options_->require_authentication = std::make_unique<bool>(false);
adapter_ = device->adapter(); adapter_ = device->adapter();
...@@ -150,6 +150,11 @@ void BluetoothSocketBlueZ::Listen( ...@@ -150,6 +150,11 @@ void BluetoothSocketBlueZ::Listen(
NOTREACHED(); NOTREACHED();
} }
if (service_options.require_authentication) {
options_->require_authentication =
std::make_unique<bool>(*service_options.require_authentication);
}
RegisterProfile(static_cast<BluetoothAdapterBlueZ*>(adapter.get()), RegisterProfile(static_cast<BluetoothAdapterBlueZ*>(adapter.get()),
std::move(success_callback), std::move(error_callback)); std::move(success_callback), std::move(error_callback));
} }
......
...@@ -198,11 +198,13 @@ interface Adapter { ...@@ -198,11 +198,13 @@ interface Adapter {
=> (ConnectToServiceResult? result); => (ConnectToServiceResult? result);
// Creates an RFCOMM service on this adapter advertised with |service_name| // Creates an RFCOMM service on this adapter advertised with |service_name|
// and |service_uuid|. If the service creation attempt fails, the returned // and |service_uuid|. This method is marked as "Insecurely" because the local
// |server_socket| will be null. See ServerSocket for details on how to stop // device will not request bonding (pairing) with the remote device: clients
// listening. // are responsible for securing the connection at the application-level. If
// the service creation attempt fails, the returned |server_socket| will be
// null. See ServerSocket for details on how to stop listening.
[Sync] [Sync]
CreateRfcommService(string service_name, UUID service_uuid) CreateRfcommServiceInsecurely(string service_name, UUID service_uuid)
=> (pending_remote<ServerSocket>? server_socket); => (pending_remote<ServerSocket>? server_socket);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment