1 /*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "security/facade.h"
17
18 #include "grpc/grpc_event_queue.h"
19 #include "hci/address_with_type.h"
20 #include "os/handler.h"
21 #include "security/facade.grpc.pb.h"
22 #include "security/security_manager_listener.h"
23 #include "security/security_module.h"
24
25 namespace bluetooth {
26 namespace security {
27
28 class SecurityModuleFacadeService : public SecurityModuleFacade::Service, public ISecurityManagerListener, public UI {
29 public:
SecurityModuleFacadeService(SecurityModule * security_module,::bluetooth::os::Handler * security_handler)30 SecurityModuleFacadeService(SecurityModule* security_module, ::bluetooth::os::Handler* security_handler)
31 : security_module_(security_module), security_handler_(security_handler) {
32 security_module_->GetSecurityManager()->RegisterCallbackListener(this, security_handler_);
33 }
34
CreateBond(::grpc::ServerContext * context,const facade::BluetoothAddressWithType * request,::google::protobuf::Empty * response)35 ::grpc::Status CreateBond(::grpc::ServerContext* context, const facade::BluetoothAddressWithType* request,
36 ::google::protobuf::Empty* response) override {
37 hci::Address peer;
38 ASSERT(hci::Address::FromString(request->address().address(), peer));
39 hci::AddressType peer_type = hci::AddressType::PUBLIC_DEVICE_ADDRESS;
40 security_module_->GetSecurityManager()->CreateBond(hci::AddressWithType(peer, peer_type));
41 return ::grpc::Status::OK;
42 }
43
CancelBond(::grpc::ServerContext * context,const facade::BluetoothAddressWithType * request,::google::protobuf::Empty * response)44 ::grpc::Status CancelBond(::grpc::ServerContext* context, const facade::BluetoothAddressWithType* request,
45 ::google::protobuf::Empty* response) override {
46 hci::Address peer;
47 ASSERT(hci::Address::FromString(request->address().address(), peer));
48 hci::AddressType peer_type = hci::AddressType::PUBLIC_DEVICE_ADDRESS;
49 security_module_->GetSecurityManager()->CancelBond(hci::AddressWithType(peer, peer_type));
50 return ::grpc::Status::OK;
51 }
52
RemoveBond(::grpc::ServerContext * context,const facade::BluetoothAddressWithType * request,::google::protobuf::Empty * response)53 ::grpc::Status RemoveBond(::grpc::ServerContext* context, const facade::BluetoothAddressWithType* request,
54 ::google::protobuf::Empty* response) override {
55 hci::Address peer;
56 ASSERT(hci::Address::FromString(request->address().address(), peer));
57 hci::AddressType peer_type = hci::AddressType::PUBLIC_DEVICE_ADDRESS;
58 security_module_->GetSecurityManager()->RemoveBond(hci::AddressWithType(peer, peer_type));
59 return ::grpc::Status::OK;
60 }
61
FetchUiEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<UiMsg> * writer)62 ::grpc::Status FetchUiEvents(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
63 ::grpc::ServerWriter<UiMsg>* writer) override {
64 return ui_events_.RunLoop(context, writer);
65 }
66
SendUiCallback(::grpc::ServerContext * context,const UiCallbackMsg * request,::google::protobuf::Empty * response)67 ::grpc::Status SendUiCallback(::grpc::ServerContext* context, const UiCallbackMsg* request,
68 ::google::protobuf::Empty* response) override {
69 switch (request->message_type()) {
70 case UiCallbackType::PASSKEY:
71 // TODO: security_module_->GetSecurityManager()->OnPasskeyEntry();
72 break;
73 case UiCallbackType::YES_NO:
74 // TODO: security_module_->GetSecurityManager()->OnConfirmYesNo(request->boolean());
75 break;
76 default:
77 LOG_ERROR("Unknown UiCallbackType %d", static_cast<int>(request->message_type()));
78 return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Unknown UiCallbackType");
79 }
80 return ::grpc::Status::OK;
81 }
82
FetchBondEvents(::grpc::ServerContext * context,const::google::protobuf::Empty * request,::grpc::ServerWriter<BondMsg> * writer)83 ::grpc::Status FetchBondEvents(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
84 ::grpc::ServerWriter<BondMsg>* writer) override {
85 return bond_events_.RunLoop(context, writer);
86 }
87
DisplayPairingPrompt(const bluetooth::hci::AddressWithType & peer,std::string name)88 void DisplayPairingPrompt(const bluetooth::hci::AddressWithType& peer, std::string name) {
89 LOG_INFO("%s", peer.ToString().c_str());
90 UiMsg display_yes_no;
91 display_yes_no.mutable_peer()->mutable_address()->set_address(peer.ToString());
92 display_yes_no.mutable_peer()->set_type(facade::BluetoothAddressTypeEnum::PUBLIC_DEVICE_ADDRESS);
93 display_yes_no.set_message_type(UiMsgType::DISPLAY_YES_NO);
94 display_yes_no.set_unique_id(unique_id++);
95 }
96
DisplayConfirmValue(const bluetooth::hci::AddressWithType & peer,std::string name,uint32_t numeric_value)97 virtual void DisplayConfirmValue(const bluetooth::hci::AddressWithType& peer, std::string name,
98 uint32_t numeric_value) {
99 LOG_INFO("%s value = 0x%x", peer.ToString().c_str(), numeric_value);
100 UiMsg display_with_value;
101 display_with_value.mutable_peer()->mutable_address()->set_address(peer.ToString());
102 display_with_value.mutable_peer()->set_type(facade::BluetoothAddressTypeEnum::PUBLIC_DEVICE_ADDRESS);
103 display_with_value.set_message_type(UiMsgType::DISPLAY_YES_NO_WITH_VALUE);
104 display_with_value.set_numeric_value(numeric_value);
105 display_with_value.set_unique_id(unique_id++);
106 ui_events_.OnIncomingEvent(display_with_value);
107 }
108
DisplayYesNoDialog(const bluetooth::hci::AddressWithType & peer,std::string name)109 void DisplayYesNoDialog(const bluetooth::hci::AddressWithType& peer, std::string name) override {
110 LOG_INFO("%s", peer.ToString().c_str());
111 UiMsg display_yes_no;
112 display_yes_no.mutable_peer()->mutable_address()->set_address(peer.ToString());
113 display_yes_no.mutable_peer()->set_type(facade::BluetoothAddressTypeEnum::PUBLIC_DEVICE_ADDRESS);
114 display_yes_no.set_message_type(UiMsgType::DISPLAY_YES_NO);
115 display_yes_no.set_unique_id(unique_id++);
116 }
117
DisplayPasskey(const bluetooth::hci::AddressWithType & peer,std::string name,uint32_t passkey)118 void DisplayPasskey(const bluetooth::hci::AddressWithType& peer, std::string name, uint32_t passkey) override {
119 LOG_INFO("%s value = 0x%x", peer.ToString().c_str(), passkey);
120 UiMsg display_passkey;
121 display_passkey.mutable_peer()->mutable_address()->set_address(peer.ToString());
122 display_passkey.mutable_peer()->set_type(facade::BluetoothAddressTypeEnum::PUBLIC_DEVICE_ADDRESS);
123 display_passkey.set_message_type(UiMsgType::DISPLAY_PASSKEY);
124 display_passkey.set_numeric_value(passkey);
125 display_passkey.set_unique_id(unique_id++);
126 ui_events_.OnIncomingEvent(display_passkey);
127 }
128
DisplayEnterPasskeyDialog(const bluetooth::hci::AddressWithType & peer,std::string name)129 void DisplayEnterPasskeyDialog(const bluetooth::hci::AddressWithType& peer, std::string name) override {
130 LOG_INFO("%s", peer.ToString().c_str());
131 UiMsg display_passkey_input;
132 display_passkey_input.mutable_peer()->mutable_address()->set_address(peer.ToString());
133 display_passkey_input.mutable_peer()->set_type(facade::BluetoothAddressTypeEnum::PUBLIC_DEVICE_ADDRESS);
134 display_passkey_input.set_message_type(UiMsgType::DISPLAY_PASSKEY_ENTRY);
135 display_passkey_input.set_unique_id(unique_id++);
136 ui_events_.OnIncomingEvent(display_passkey_input);
137 }
138
Cancel(const bluetooth::hci::AddressWithType & peer)139 void Cancel(const bluetooth::hci::AddressWithType& peer) override {
140 LOG_INFO("%s", peer.ToString().c_str());
141 UiMsg display_cancel;
142 display_cancel.mutable_peer()->mutable_address()->set_address(peer.ToString());
143 display_cancel.mutable_peer()->set_type(facade::BluetoothAddressTypeEnum::PUBLIC_DEVICE_ADDRESS);
144 display_cancel.set_message_type(UiMsgType::DISPLAY_CANCEL);
145 display_cancel.set_unique_id(unique_id++);
146 ui_events_.OnIncomingEvent(display_cancel);
147 }
148
OnDeviceBonded(hci::AddressWithType peer)149 void OnDeviceBonded(hci::AddressWithType peer) override {
150 LOG_INFO("%s", peer.ToString().c_str());
151 BondMsg bonded;
152 bonded.mutable_peer()->mutable_address()->set_address(peer.ToString());
153 bonded.mutable_peer()->set_type(facade::BluetoothAddressTypeEnum::PUBLIC_DEVICE_ADDRESS);
154 bonded.set_message_type(BondMsgType::DEVICE_BONDED);
155 bond_events_.OnIncomingEvent(bonded);
156 }
157
OnDeviceUnbonded(hci::AddressWithType peer)158 void OnDeviceUnbonded(hci::AddressWithType peer) override {
159 LOG_INFO("%s", peer.ToString().c_str());
160 BondMsg unbonded;
161 unbonded.mutable_peer()->mutable_address()->set_address(peer.ToString());
162 unbonded.mutable_peer()->set_type(facade::BluetoothAddressTypeEnum::PUBLIC_DEVICE_ADDRESS);
163 unbonded.set_message_type(BondMsgType::DEVICE_UNBONDED);
164 bond_events_.OnIncomingEvent(unbonded);
165 }
166
OnDeviceBondFailed(hci::AddressWithType peer)167 void OnDeviceBondFailed(hci::AddressWithType peer) override {
168 LOG_INFO("%s", peer.ToString().c_str());
169 BondMsg bond_failed;
170 bond_failed.mutable_peer()->mutable_address()->set_address(peer.ToString());
171 bond_failed.mutable_peer()->set_type(facade::BluetoothAddressTypeEnum::PUBLIC_DEVICE_ADDRESS);
172 bond_failed.set_message_type(BondMsgType::DEVICE_BOND_FAILED);
173 bond_events_.OnIncomingEvent(bond_failed);
174 }
175
176 private:
177 SecurityModule* security_module_;
178 ::bluetooth::os::Handler* security_handler_;
179 ::bluetooth::grpc::GrpcEventQueue<UiMsg> ui_events_{"UI events"};
180 ::bluetooth::grpc::GrpcEventQueue<BondMsg> bond_events_{"Bond events"};
181 uint32_t unique_id{1};
182 std::map<uint32_t, common::OnceCallback<void(bool)>> user_yes_no_callbacks_;
183 std::map<uint32_t, common::OnceCallback<void(uint32_t)>> user_passkey_callbacks_;
184 };
185
ListDependencies(ModuleList * list)186 void SecurityModuleFacadeModule::ListDependencies(ModuleList* list) {
187 ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
188 list->add<SecurityModule>();
189 }
190
Start()191 void SecurityModuleFacadeModule::Start() {
192 ::bluetooth::grpc::GrpcFacadeModule::Start();
193 service_ = new SecurityModuleFacadeService(GetDependency<SecurityModule>(), GetHandler());
194 }
195
Stop()196 void SecurityModuleFacadeModule::Stop() {
197 delete service_;
198 ::bluetooth::grpc::GrpcFacadeModule::Stop();
199 }
200
GetService() const201 ::grpc::Service* SecurityModuleFacadeModule::GetService() const {
202 return service_;
203 }
204
205 const ModuleFactory SecurityModuleFacadeModule::Factory =
__anon515b9c8c0102() 206 ::bluetooth::ModuleFactory([]() { return new SecurityModuleFacadeModule(); });
207
208 } // namespace security
209 } // namespace bluetooth
210