1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "privacy_manager_client.h"
16
17 #include <algorithm>
18 #include "accesstoken_log.h"
19 #include "iservice_registry.h"
20 #include "privacy_error.h"
21 #include "privacy_manager_proxy.h"
22 #ifdef SECURITY_COMPONENT_ENHANCE_ENABLE
23 #include "sec_comp_enhance_data_parcel.h"
24 #endif
25
26 namespace OHOS {
27 namespace Security {
28 namespace AccessToken {
29 namespace {
30 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
31 LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PrivacyManagerClient"
32 };
33 } // namespace
34
35 const static int32_t MAX_CALLBACK_SIZE = 200;
36 const static int32_t MAX_PERM_LIST_SIZE = 1024;
37
GetInstance()38 PrivacyManagerClient& PrivacyManagerClient::GetInstance()
39 {
40 static PrivacyManagerClient instance;
41 return instance;
42 }
43
PrivacyManagerClient()44 PrivacyManagerClient::PrivacyManagerClient()
45 {}
46
~PrivacyManagerClient()47 PrivacyManagerClient::~PrivacyManagerClient()
48 {}
49
AddPermissionUsedRecord(AccessTokenID tokenID,const std::string & permissionName,int32_t successCount,int32_t failCount,bool asyncMode)50 int32_t PrivacyManagerClient::AddPermissionUsedRecord(AccessTokenID tokenID, const std::string& permissionName,
51 int32_t successCount, int32_t failCount, bool asyncMode)
52 {
53 auto proxy = GetProxy();
54 if (proxy == nullptr) {
55 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
56 return PrivacyError::ERR_SERVICE_ABNORMAL;
57 }
58 return proxy->AddPermissionUsedRecord(tokenID, permissionName, successCount, failCount, asyncMode);
59 }
60
StartUsingPermission(AccessTokenID tokenID,const std::string & permissionName)61 int32_t PrivacyManagerClient::StartUsingPermission(AccessTokenID tokenID, const std::string& permissionName)
62 {
63 auto proxy = GetProxy();
64 if (proxy == nullptr) {
65 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
66 return PrivacyError::ERR_SERVICE_ABNORMAL;
67 }
68 return proxy->StartUsingPermission(tokenID, permissionName);
69 }
70
CreateStateChangeCbk(const std::shared_ptr<StateCustomizedCbk> & callback,sptr<StateChangeCallback> & callbackWrap)71 int32_t PrivacyManagerClient::CreateStateChangeCbk(
72 const std::shared_ptr<StateCustomizedCbk>& callback, sptr<StateChangeCallback>& callbackWrap)
73 {
74 std::lock_guard<std::mutex> lock(stateCbkMutex_);
75
76 if (stateChangeCallback_ != nullptr) {
77 ACCESSTOKEN_LOG_ERROR(LABEL, " callback has been used");
78 return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
79 } else {
80 callbackWrap = new (std::nothrow) StateChangeCallback(callback);
81 if (callbackWrap == nullptr) {
82 ACCESSTOKEN_LOG_ERROR(LABEL, "memory allocation for callbackWrap failed!");
83 return PrivacyError::ERR_SERVICE_ABNORMAL;
84 }
85 }
86 return RET_SUCCESS;
87 }
88
StartUsingPermission(AccessTokenID tokenId,const std::string & permissionName,const std::shared_ptr<StateCustomizedCbk> & callback)89 int32_t PrivacyManagerClient::StartUsingPermission(AccessTokenID tokenId, const std::string& permissionName,
90 const std::shared_ptr<StateCustomizedCbk>& callback)
91 {
92 if (callback == nullptr) {
93 ACCESSTOKEN_LOG_ERROR(LABEL, "customizedCb is nullptr");
94 return PrivacyError::ERR_PARAM_INVALID;
95 }
96
97 sptr<StateChangeCallback> callbackWrap = nullptr;
98 int32_t result = CreateStateChangeCbk(callback, callbackWrap);
99 if (result != RET_SUCCESS) {
100 return result;
101 }
102
103 auto proxy = GetProxy();
104 if (proxy == nullptr) {
105 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
106 return PrivacyError::ERR_SERVICE_ABNORMAL;
107 }
108
109 result = proxy->StartUsingPermission(tokenId, permissionName, callbackWrap->AsObject());
110 if (result == RET_SUCCESS) {
111 std::lock_guard<std::mutex> lock(stateCbkMutex_);
112 stateChangeCallback_ = callbackWrap;
113 ACCESSTOKEN_LOG_INFO(LABEL, "callbackObject added");
114 }
115 return result;
116 }
117
StopUsingPermission(AccessTokenID tokenID,const std::string & permissionName)118 int32_t PrivacyManagerClient::StopUsingPermission(AccessTokenID tokenID, const std::string& permissionName)
119 {
120 auto proxy = GetProxy();
121 if (proxy == nullptr) {
122 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
123 return PrivacyError::ERR_SERVICE_ABNORMAL;
124 }
125 {
126 std::lock_guard<std::mutex> lock(stateCbkMutex_);
127 stateChangeCallback_ = nullptr;
128 }
129
130 return proxy->StopUsingPermission(tokenID, permissionName);
131 }
132
RemovePermissionUsedRecords(AccessTokenID tokenID,const std::string & deviceID)133 int32_t PrivacyManagerClient::RemovePermissionUsedRecords(AccessTokenID tokenID, const std::string& deviceID)
134 {
135 auto proxy = GetProxy();
136 if (proxy == nullptr) {
137 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
138 return PrivacyError::ERR_SERVICE_ABNORMAL;
139 }
140 return proxy->RemovePermissionUsedRecords(tokenID, deviceID);
141 }
142
GetPermissionUsedRecords(const PermissionUsedRequest & request,PermissionUsedResult & result)143 int32_t PrivacyManagerClient::GetPermissionUsedRecords(
144 const PermissionUsedRequest& request, PermissionUsedResult& result)
145 {
146 auto proxy = GetProxy();
147 if (proxy == nullptr) {
148 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
149 return PrivacyError::ERR_SERVICE_ABNORMAL;
150 }
151
152 PermissionUsedRequestParcel requestParcel;
153 PermissionUsedResultParcel resultParcel;
154 requestParcel.request = request;
155 int32_t ret = proxy->GetPermissionUsedRecords(requestParcel, resultParcel);
156 result = resultParcel.result;
157 return ret;
158 }
159
GetPermissionUsedRecords(const PermissionUsedRequest & request,const sptr<OnPermissionUsedRecordCallback> & callback)160 int32_t PrivacyManagerClient::GetPermissionUsedRecords(const PermissionUsedRequest& request,
161 const sptr<OnPermissionUsedRecordCallback>& callback)
162 {
163 auto proxy = GetProxy();
164 if (proxy == nullptr) {
165 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
166 return PrivacyError::ERR_SERVICE_ABNORMAL;
167 }
168
169 PermissionUsedRequestParcel requestParcel;
170 requestParcel.request = request;
171 return proxy->GetPermissionUsedRecords(requestParcel, callback);
172 }
173
CreateActiveStatusChangeCbk(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback,sptr<PermActiveStatusChangeCallback> & callbackWrap)174 int32_t PrivacyManagerClient::CreateActiveStatusChangeCbk(
175 const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback, sptr<PermActiveStatusChangeCallback>& callbackWrap)
176 {
177 std::lock_guard<std::mutex> lock(activeCbkMutex_);
178
179 if (activeCbkMap_.size() >= MAX_CALLBACK_SIZE) {
180 ACCESSTOKEN_LOG_ERROR(LABEL, "the maximum number of subscribers has been reached");
181 return PrivacyError::ERR_CALLBACKS_EXCEED_LIMITATION;
182 }
183
184 auto goalCallback = activeCbkMap_.find(callback);
185 if (goalCallback != activeCbkMap_.end()) {
186 ACCESSTOKEN_LOG_ERROR(LABEL, "activeCbkMap_ already has such callback");
187 return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
188 } else {
189 callbackWrap =
190 new (std::nothrow) PermActiveStatusChangeCallback(callback);
191 if (!callbackWrap) {
192 ACCESSTOKEN_LOG_ERROR(LABEL, "memory allocation for callbackWrap failed!");
193 return PrivacyError::ERR_MALLOC_FAILED;
194 }
195 }
196 return RET_SUCCESS;
197 }
198
RegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback)199 int32_t PrivacyManagerClient::RegisterPermActiveStatusCallback(
200 const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback)
201 {
202 ACCESSTOKEN_LOG_INFO(LABEL, "called!");
203 if (callback == nullptr) {
204 ACCESSTOKEN_LOG_ERROR(LABEL, "customizedCb is nullptr");
205 return PrivacyError::ERR_PARAM_INVALID;
206 }
207
208 sptr<PermActiveStatusChangeCallback> callbackWrap = nullptr;
209 int32_t result = CreateActiveStatusChangeCbk(callback, callbackWrap);
210 if (result != RET_SUCCESS) {
211 return result;
212 }
213
214 auto proxy = GetProxy();
215 if (proxy == nullptr) {
216 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
217 return PrivacyError::ERR_SERVICE_ABNORMAL;
218 }
219 std::vector<std::string> permList;
220 callback->GetPermList(permList);
221 if (permList.size() > MAX_PERM_LIST_SIZE) {
222 return PrivacyError::ERR_PARAM_INVALID;
223 }
224
225 result = proxy->RegisterPermActiveStatusCallback(permList, callbackWrap->AsObject());
226 if (result == RET_SUCCESS) {
227 std::lock_guard<std::mutex> lock(activeCbkMutex_);
228 activeCbkMap_[callback] = callbackWrap;
229 ACCESSTOKEN_LOG_INFO(LABEL, "callbackObject added");
230 }
231 return result;
232 }
233
UnRegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback)234 int32_t PrivacyManagerClient::UnRegisterPermActiveStatusCallback(
235 const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback)
236 {
237 ACCESSTOKEN_LOG_INFO(LABEL, "called!");
238
239 auto proxy = GetProxy();
240 if (proxy == nullptr) {
241 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
242 return PrivacyError::ERR_SERVICE_ABNORMAL;
243 }
244
245 std::lock_guard<std::mutex> lock(activeCbkMutex_);
246 auto goalCallback = activeCbkMap_.find(callback);
247 if (goalCallback == activeCbkMap_.end()) {
248 ACCESSTOKEN_LOG_ERROR(LABEL, "goalCallback already is not exist");
249 return PrivacyError::ERR_CALLBACK_NOT_EXIST;
250 }
251
252 int32_t result = proxy->UnRegisterPermActiveStatusCallback(goalCallback->second->AsObject());
253 if (result == RET_SUCCESS) {
254 activeCbkMap_.erase(goalCallback);
255 }
256 return result;
257 }
258
IsAllowedUsingPermission(AccessTokenID tokenID,const std::string & permissionName)259 bool PrivacyManagerClient::IsAllowedUsingPermission(AccessTokenID tokenID, const std::string& permissionName)
260 {
261 auto proxy = GetProxy();
262 if (proxy == nullptr) {
263 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
264 return false;
265 }
266 return proxy->IsAllowedUsingPermission(tokenID, permissionName);
267 }
268
269 #ifdef SECURITY_COMPONENT_ENHANCE_ENABLE
RegisterSecCompEnhance(const SecCompEnhanceData & enhance)270 int32_t PrivacyManagerClient::RegisterSecCompEnhance(const SecCompEnhanceData& enhance)
271 {
272 auto proxy = GetProxy();
273 if (proxy == nullptr) {
274 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
275 return PrivacyError::ERR_PARAM_INVALID;
276 }
277 SecCompEnhanceDataParcel registerParcel;
278 registerParcel.enhanceData = enhance;
279 return proxy->RegisterSecCompEnhance(registerParcel);
280 }
281
DepositSecCompEnhance(const std::vector<SecCompEnhanceData> & enhanceList)282 int32_t PrivacyManagerClient::DepositSecCompEnhance(const std::vector<SecCompEnhanceData>& enhanceList)
283 {
284 auto proxy = GetProxy();
285 if (proxy == nullptr) {
286 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
287 return PrivacyError::ERR_PARAM_INVALID;
288 }
289 std::vector<SecCompEnhanceDataParcel> parcelList;
290 for (const auto& data : enhanceList) {
291 SecCompEnhanceDataParcel parcel;
292 parcel.enhanceData = data;
293 parcelList.emplace_back(parcel);
294 }
295 return proxy->DepositSecCompEnhance(parcelList);
296 }
297
RecoverSecCompEnhance(std::vector<SecCompEnhanceData> & enhanceList)298 int32_t PrivacyManagerClient::RecoverSecCompEnhance(std::vector<SecCompEnhanceData>& enhanceList)
299 {
300 auto proxy = GetProxy();
301 if (proxy == nullptr) {
302 ACCESSTOKEN_LOG_ERROR(LABEL, "proxy is null");
303 return PrivacyError::ERR_PARAM_INVALID;
304 }
305 std::vector<SecCompEnhanceDataParcel> parcelList;
306 int32_t res = proxy->RecoverSecCompEnhance(parcelList);
307 if (res != RET_SUCCESS) {
308 return res;
309 }
310
311 std::transform(parcelList.begin(), parcelList.end(), std::back_inserter(enhanceList),
312 [](SecCompEnhanceDataParcel pair) { return pair.enhanceData; });
313 return RET_SUCCESS;
314 }
315 #endif
316
InitProxy()317 void PrivacyManagerClient::InitProxy()
318 {
319 std::lock_guard<std::mutex> lock(proxyMutex_);
320 if (proxy_ == nullptr) {
321 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
322 if (sam == nullptr) {
323 ACCESSTOKEN_LOG_DEBUG(LABEL, "GetSystemAbilityManager is null");
324 return;
325 }
326 auto privacySa = sam->GetSystemAbility(IPrivacyManager::SA_ID_PRIVACY_MANAGER_SERVICE);
327 if (privacySa == nullptr) {
328 ACCESSTOKEN_LOG_DEBUG(LABEL, "GetSystemAbility %{public}d is null",
329 IPrivacyManager::SA_ID_PRIVACY_MANAGER_SERVICE);
330 return;
331 }
332
333 serviceDeathObserver_ = new (std::nothrow) PrivacyDeathRecipient();
334 if (serviceDeathObserver_ != nullptr) {
335 privacySa->AddDeathRecipient(serviceDeathObserver_);
336 }
337 proxy_ = iface_cast<IPrivacyManager>(privacySa);
338 if (proxy_ == nullptr) {
339 ACCESSTOKEN_LOG_DEBUG(LABEL, "iface_cast get null");
340 }
341 }
342 }
343
OnRemoteDiedHandle()344 void PrivacyManagerClient::OnRemoteDiedHandle()
345 {
346 {
347 std::lock_guard<std::mutex> lock(proxyMutex_);
348 proxy_ = nullptr;
349 }
350 InitProxy();
351 }
352
GetProxy()353 sptr<IPrivacyManager> PrivacyManagerClient::GetProxy()
354 {
355 if (proxy_ == nullptr) {
356 InitProxy();
357 }
358 return proxy_;
359 }
360 } // namespace AccessToken
361 } // namespace Security
362 } // namespace OHOS
363