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_common_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 const static int32_t MAX_CALLBACK_SIZE = 200;
31 const static int32_t MAX_PERM_LIST_SIZE = 1024;
32 constexpr const char* CAMERA_PERMISSION_NAME = "ohos.permission.CAMERA";
33 std::recursive_mutex g_instanceMutex;
34 } // namespace
35
GetInstance()36 PrivacyManagerClient& PrivacyManagerClient::GetInstance()
37 {
38 static PrivacyManagerClient* instance = nullptr;
39 if (instance == nullptr) {
40 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
41 if (instance == nullptr) {
42 PrivacyManagerClient* tmp = new PrivacyManagerClient();
43 instance = std::move(tmp);
44 }
45 }
46 return *instance;
47 }
48
PrivacyManagerClient()49 PrivacyManagerClient::PrivacyManagerClient()
50 {}
51
~PrivacyManagerClient()52 PrivacyManagerClient::~PrivacyManagerClient()
53 {
54 LOGE(PRI_DOMAIN, PRI_TAG, "~PrivacyManagerClient");
55 std::lock_guard<std::mutex> lock(proxyMutex_);
56 ReleaseProxy();
57 }
58
AddPermissionUsedRecord(const AddPermParamInfo & info,bool asyncMode)59 int32_t PrivacyManagerClient::AddPermissionUsedRecord(const AddPermParamInfo& info, bool asyncMode)
60 {
61 auto proxy = GetProxy();
62 if (proxy == nullptr) {
63 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
64 return PrivacyError::ERR_SERVICE_ABNORMAL;
65 }
66 AddPermParamInfoParcel infoParcel;
67 infoParcel.info = info;
68 return proxy->AddPermissionUsedRecord(infoParcel, asyncMode);
69 }
70
SetPermissionUsedRecordToggleStatus(int32_t userID,bool status)71 int32_t PrivacyManagerClient::SetPermissionUsedRecordToggleStatus(int32_t userID, bool status)
72 {
73 auto proxy = GetProxy();
74 if (proxy == nullptr) {
75 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
76 return PrivacyError::ERR_SERVICE_ABNORMAL;
77 }
78
79 return proxy->SetPermissionUsedRecordToggleStatus(userID, status);
80 }
81
GetPermissionUsedRecordToggleStatus(int32_t userID,bool & status)82 int32_t PrivacyManagerClient::GetPermissionUsedRecordToggleStatus(int32_t userID, bool& status)
83 {
84 auto proxy = GetProxy();
85 if (proxy == nullptr) {
86 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
87 return PrivacyError::ERR_SERVICE_ABNORMAL;
88 }
89
90 return proxy->GetPermissionUsedRecordToggleStatus(userID, status);
91 }
92
StartUsingPermission(AccessTokenID tokenID,int32_t pid,const std::string & permissionName,PermissionUsedType type)93 int32_t PrivacyManagerClient::StartUsingPermission(
94 AccessTokenID tokenID, int32_t pid, const std::string& permissionName, PermissionUsedType type)
95 {
96 auto proxy = GetProxy();
97 if (proxy == nullptr) {
98 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
99 return PrivacyError::ERR_SERVICE_ABNORMAL;
100 }
101
102 PermissionUsedTypeInfoParcel parcel;
103 parcel.info.tokenId = tokenID;
104 parcel.info.pid = pid;
105 parcel.info.permissionName = permissionName;
106 parcel.info.type = type;
107
108 auto anonyStub = GetAnonyStub();
109 if (anonyStub == nullptr) {
110 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy death recipent is null.");
111 return PrivacyError::ERR_MALLOC_FAILED;
112 }
113 return proxy->StartUsingPermission(parcel, anonyStub);
114 }
115
CreateStateChangeCbk(uint64_t id,const std::shared_ptr<StateCustomizedCbk> & callback,sptr<StateChangeCallback> & callbackWrap)116 int32_t PrivacyManagerClient::CreateStateChangeCbk(uint64_t id,
117 const std::shared_ptr<StateCustomizedCbk>& callback, sptr<StateChangeCallback>& callbackWrap)
118 {
119 std::lock_guard<std::mutex> lock(stateCbkMutex_);
120 auto iter = stateChangeCallbackMap_.find(id);
121 if (iter != stateChangeCallbackMap_.end()) {
122 LOGE(PRI_DOMAIN, PRI_TAG, " Callback has been used.");
123 return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
124 } else {
125 callbackWrap = new (std::nothrow) StateChangeCallback(callback);
126 if (callbackWrap == nullptr) {
127 LOGE(PRI_DOMAIN, PRI_TAG, "Memory allocation for callbackWrap failed!");
128 return PrivacyError::ERR_MALLOC_FAILED;
129 }
130 }
131 return RET_SUCCESS;
132 }
133
StartUsingPermission(AccessTokenID tokenId,int32_t pid,const std::string & permissionName,const std::shared_ptr<StateCustomizedCbk> & callback,PermissionUsedType type)134 int32_t PrivacyManagerClient::StartUsingPermission(AccessTokenID tokenId, int32_t pid,
135 const std::string& permissionName, const std::shared_ptr<StateCustomizedCbk>& callback, PermissionUsedType type)
136 {
137 if (callback == nullptr) {
138 LOGE(PRI_DOMAIN, PRI_TAG, "Callback is nullptr.");
139 return PrivacyError::ERR_PARAM_INVALID;
140 }
141
142 sptr<StateChangeCallback> callbackWrap = nullptr;
143 uint64_t id = GetUniqueId(tokenId, pid);
144 int32_t result = CreateStateChangeCbk(id, callback, callbackWrap);
145 if (result != RET_SUCCESS) {
146 return result;
147 }
148
149 auto proxy = GetProxy();
150 if (proxy == nullptr) {
151 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
152 return PrivacyError::ERR_SERVICE_ABNORMAL;
153 }
154 PermissionUsedTypeInfoParcel parcel;
155 parcel.info.tokenId = tokenId;
156 parcel.info.pid = pid;
157 parcel.info.permissionName = permissionName;
158 parcel.info.type = type;
159 auto anonyStub = GetAnonyStub();
160 if (anonyStub == nullptr) {
161 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy death recipent is null.");
162 return PrivacyError::ERR_MALLOC_FAILED;
163 }
164 result = proxy->StartUsingPermission(parcel, callbackWrap->AsObject(), anonyStub);
165 if (result == RET_SUCCESS) {
166 std::lock_guard<std::mutex> lock(stateCbkMutex_);
167 stateChangeCallbackMap_[id] = callbackWrap;
168 LOGI(PRI_DOMAIN, PRI_TAG, "CallbackObject added.");
169 }
170 return result;
171 }
172
StopUsingPermission(AccessTokenID tokenID,int32_t pid,const std::string & permissionName)173 int32_t PrivacyManagerClient::StopUsingPermission(
174 AccessTokenID tokenID, int32_t pid, const std::string& permissionName)
175 {
176 auto proxy = GetProxy();
177 if (proxy == nullptr) {
178 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
179 return PrivacyError::ERR_SERVICE_ABNORMAL;
180 }
181 if (permissionName == CAMERA_PERMISSION_NAME) {
182 uint64_t id = GetUniqueId(tokenID, pid);
183 std::lock_guard<std::mutex> lock(stateCbkMutex_);
184 auto iter = stateChangeCallbackMap_.find(id);
185 if (iter != stateChangeCallbackMap_.end()) {
186 stateChangeCallbackMap_.erase(id);
187 }
188 }
189
190 return proxy->StopUsingPermission(tokenID, pid, permissionName);
191 }
192
RemovePermissionUsedRecords(AccessTokenID tokenID)193 int32_t PrivacyManagerClient::RemovePermissionUsedRecords(AccessTokenID tokenID)
194 {
195 auto proxy = GetProxy();
196 if (proxy == nullptr) {
197 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
198 return PrivacyError::ERR_SERVICE_ABNORMAL;
199 }
200 return proxy->RemovePermissionUsedRecords(tokenID);
201 }
202
GetPermissionUsedRecords(const PermissionUsedRequest & request,PermissionUsedResult & result)203 int32_t PrivacyManagerClient::GetPermissionUsedRecords(
204 const PermissionUsedRequest& request, PermissionUsedResult& result)
205 {
206 auto proxy = GetProxy();
207 if (proxy == nullptr) {
208 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
209 return PrivacyError::ERR_SERVICE_ABNORMAL;
210 }
211
212 PermissionUsedRequestParcel requestParcel;
213 PermissionUsedResultParcel resultParcel;
214 requestParcel.request = request;
215 int32_t ret = proxy->GetPermissionUsedRecords(requestParcel, resultParcel);
216 result = resultParcel.result;
217 return ret;
218 }
219
GetPermissionUsedRecords(const PermissionUsedRequest & request,const sptr<OnPermissionUsedRecordCallback> & callback)220 int32_t PrivacyManagerClient::GetPermissionUsedRecords(const PermissionUsedRequest& request,
221 const sptr<OnPermissionUsedRecordCallback>& callback)
222 {
223 auto proxy = GetProxy();
224 if (proxy == nullptr) {
225 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
226 return PrivacyError::ERR_SERVICE_ABNORMAL;
227 }
228
229 PermissionUsedRequestParcel requestParcel;
230 requestParcel.request = request;
231 return proxy->GetPermissionUsedRecords(requestParcel, callback);
232 }
233
CreateActiveStatusChangeCbk(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback,sptr<PermActiveStatusChangeCallback> & callbackWrap)234 int32_t PrivacyManagerClient::CreateActiveStatusChangeCbk(
235 const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback, sptr<PermActiveStatusChangeCallback>& callbackWrap)
236 {
237 std::lock_guard<std::mutex> lock(activeCbkMutex_);
238
239 if (activeCbkMap_.size() >= MAX_CALLBACK_SIZE) {
240 return PrivacyError::ERR_CALLBACKS_EXCEED_LIMITATION;
241 }
242
243 auto goalCallback = activeCbkMap_.find(callback);
244 if (goalCallback != activeCbkMap_.end()) {
245 return PrivacyError::ERR_CALLBACK_ALREADY_EXIST;
246 } else {
247 callbackWrap =
248 new (std::nothrow) PermActiveStatusChangeCallback(callback);
249 if (!callbackWrap) {
250 return PrivacyError::ERR_MALLOC_FAILED;
251 }
252 }
253 return RET_SUCCESS;
254 }
255
RegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback)256 int32_t PrivacyManagerClient::RegisterPermActiveStatusCallback(
257 const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback)
258 {
259 if (callback == nullptr) {
260 LOGE(PRI_DOMAIN, PRI_TAG, "CustomizedCb is nullptr.");
261 return PrivacyError::ERR_PARAM_INVALID;
262 }
263
264 sptr<PermActiveStatusChangeCallback> callbackWrap = nullptr;
265 int32_t result = CreateActiveStatusChangeCbk(callback, callbackWrap);
266 if (result != RET_SUCCESS) {
267 LOGE(PRI_DOMAIN, PRI_TAG, "Failed to create callback, err: %{public}d.", result);
268 return result;
269 }
270
271 auto proxy = GetProxy();
272 if (proxy == nullptr) {
273 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
274 return PrivacyError::ERR_SERVICE_ABNORMAL;
275 }
276 std::vector<std::string> permList;
277 callback->GetPermList(permList);
278 if (permList.size() > MAX_PERM_LIST_SIZE) {
279 return PrivacyError::ERR_PARAM_INVALID;
280 }
281
282 result = proxy->RegisterPermActiveStatusCallback(permList, callbackWrap->AsObject());
283 if (result == RET_SUCCESS) {
284 std::lock_guard<std::mutex> lock(activeCbkMutex_);
285 activeCbkMap_[callback] = callbackWrap;
286 LOGI(PRI_DOMAIN, PRI_TAG, "CallbackObject added.");
287 }
288 return result;
289 }
290
UnRegisterPermActiveStatusCallback(const std::shared_ptr<PermActiveStatusCustomizedCbk> & callback)291 int32_t PrivacyManagerClient::UnRegisterPermActiveStatusCallback(
292 const std::shared_ptr<PermActiveStatusCustomizedCbk>& callback)
293 {
294 auto proxy = GetProxy();
295 if (proxy == nullptr) {
296 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
297 return PrivacyError::ERR_SERVICE_ABNORMAL;
298 }
299
300 std::lock_guard<std::mutex> lock(activeCbkMutex_);
301 auto goalCallback = activeCbkMap_.find(callback);
302 if (goalCallback == activeCbkMap_.end()) {
303 LOGE(PRI_DOMAIN, PRI_TAG, "GoalCallback already is not exist.");
304 return PrivacyError::ERR_CALLBACK_NOT_EXIST;
305 }
306
307 int32_t result = proxy->UnRegisterPermActiveStatusCallback(goalCallback->second->AsObject());
308 if (result == RET_SUCCESS) {
309 activeCbkMap_.erase(goalCallback);
310 }
311 return result;
312 }
313
IsAllowedUsingPermission(AccessTokenID tokenID,const std::string & permissionName,int32_t pid)314 bool PrivacyManagerClient::IsAllowedUsingPermission(AccessTokenID tokenID, const std::string& permissionName,
315 int32_t pid)
316 {
317 auto proxy = GetProxy();
318 if (proxy == nullptr) {
319 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
320 return false;
321 }
322 return proxy->IsAllowedUsingPermission(tokenID, permissionName, pid);
323 }
324
325 #ifdef SECURITY_COMPONENT_ENHANCE_ENABLE
RegisterSecCompEnhance(const SecCompEnhanceData & enhance)326 int32_t PrivacyManagerClient::RegisterSecCompEnhance(const SecCompEnhanceData& enhance)
327 {
328 auto proxy = GetProxy();
329 if (proxy == nullptr) {
330 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
331 return PrivacyError::ERR_PARAM_INVALID;
332 }
333 SecCompEnhanceDataParcel registerParcel;
334 registerParcel.enhanceData = enhance;
335 return proxy->RegisterSecCompEnhance(registerParcel);
336 }
337
UpdateSecCompEnhance(int32_t pid,uint32_t seqNum)338 int32_t PrivacyManagerClient::UpdateSecCompEnhance(int32_t pid, uint32_t seqNum)
339 {
340 auto proxy = GetProxy();
341 if (proxy == nullptr) {
342 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
343 return PrivacyError::ERR_PARAM_INVALID;
344 }
345 return proxy->UpdateSecCompEnhance(pid, seqNum);
346 }
347
GetSecCompEnhance(int32_t pid,SecCompEnhanceData & enhance)348 int32_t PrivacyManagerClient::GetSecCompEnhance(int32_t pid, SecCompEnhanceData& enhance)
349 {
350 auto proxy = GetProxy();
351 if (proxy == nullptr) {
352 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
353 return PrivacyError::ERR_PARAM_INVALID;
354 }
355 SecCompEnhanceDataParcel parcel;
356 int32_t res = proxy->GetSecCompEnhance(pid, parcel);
357 if (res != RET_SUCCESS) {
358 return res;
359 }
360 enhance = parcel.enhanceData;
361 return RET_SUCCESS;
362 }
363
GetSpecialSecCompEnhance(const std::string & bundleName,std::vector<SecCompEnhanceData> & enhanceList)364 int32_t PrivacyManagerClient::GetSpecialSecCompEnhance(const std::string& bundleName,
365 std::vector<SecCompEnhanceData>& enhanceList)
366 {
367 auto proxy = GetProxy();
368 if (proxy == nullptr) {
369 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
370 return PrivacyError::ERR_PARAM_INVALID;
371 }
372 std::vector<SecCompEnhanceDataParcel> parcelList;
373 int32_t res = proxy->GetSpecialSecCompEnhance(bundleName, parcelList);
374 if (res != RET_SUCCESS) {
375 return res;
376 }
377
378 std::transform(parcelList.begin(), parcelList.end(), std::back_inserter(enhanceList),
379 [](SecCompEnhanceDataParcel pair) { return pair.enhanceData; });
380 return RET_SUCCESS;
381 }
382 #endif
383
GetPermissionUsedTypeInfos(const AccessTokenID tokenId,const std::string & permissionName,std::vector<PermissionUsedTypeInfo> & results)384 int32_t PrivacyManagerClient::GetPermissionUsedTypeInfos(const AccessTokenID tokenId, const std::string& permissionName,
385 std::vector<PermissionUsedTypeInfo>& results)
386 {
387 auto proxy = GetProxy();
388 if (proxy == nullptr) {
389 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
390 return PrivacyError::ERR_SERVICE_ABNORMAL;
391 }
392
393 std::vector<PermissionUsedTypeInfoParcel> resultsParcel;
394 int32_t res = proxy->GetPermissionUsedTypeInfos(tokenId, permissionName, resultsParcel);
395 if (res != RET_SUCCESS) {
396 return res;
397 }
398
399 std::transform(resultsParcel.begin(), resultsParcel.end(), std::back_inserter(results),
400 [](PermissionUsedTypeInfoParcel parcel) { return parcel.info; });
401 return RET_SUCCESS;
402 }
403
SetMutePolicy(uint32_t policyType,uint32_t callerType,bool isMute,AccessTokenID tokenID)404 int32_t PrivacyManagerClient::SetMutePolicy(uint32_t policyType, uint32_t callerType, bool isMute,
405 AccessTokenID tokenID)
406 {
407 auto proxy = GetProxy();
408 if (proxy == nullptr) {
409 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
410 return PrivacyError::ERR_SERVICE_ABNORMAL;
411 }
412 return proxy->SetMutePolicy(policyType, callerType, isMute, tokenID);
413 }
414
SetHapWithFGReminder(uint32_t tokenId,bool isAllowed)415 int32_t PrivacyManagerClient::SetHapWithFGReminder(uint32_t tokenId, bool isAllowed)
416 {
417 auto proxy = GetProxy();
418 if (proxy == nullptr) {
419 LOGE(PRI_DOMAIN, PRI_TAG, "Proxy is null.");
420 return PrivacyError::ERR_SERVICE_ABNORMAL;
421 }
422 return proxy->SetHapWithFGReminder(tokenId, isAllowed);
423 }
424
GetUniqueId(uint32_t tokenId,int32_t pid) const425 uint64_t PrivacyManagerClient::GetUniqueId(uint32_t tokenId, int32_t pid) const
426 {
427 uint32_t tmpPid = (pid <= 0) ? 0 : static_cast<uint32_t>(pid);
428 return (static_cast<uint64_t>(tmpPid) << 32) | (static_cast<uint64_t>(tokenId) & 0xFFFFFFFF); // 32: bit
429 }
430
InitProxy()431 void PrivacyManagerClient::InitProxy()
432 {
433 if (proxy_ == nullptr || proxy_->AsObject() == nullptr || proxy_->AsObject()->IsObjectDead()) {
434 auto sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
435 if (sam == nullptr) {
436 LOGD(PRI_DOMAIN, PRI_TAG, "GetSystemAbilityManager is null");
437 return;
438 }
439 auto privacySa = sam->CheckSystemAbility(IPrivacyManager::SA_ID_PRIVACY_MANAGER_SERVICE);
440 if (privacySa == nullptr) {
441 LOGD(PRI_DOMAIN, PRI_TAG, "CheckSystemAbility %{public}d is null",
442 IPrivacyManager::SA_ID_PRIVACY_MANAGER_SERVICE);
443 return;
444 }
445
446 serviceDeathObserver_ = sptr<PrivacyDeathRecipient>::MakeSptr();
447 if (serviceDeathObserver_ != nullptr) {
448 privacySa->AddDeathRecipient(serviceDeathObserver_);
449 }
450 proxy_ = new PrivacyManagerProxy(privacySa);
451 if (proxy_ == nullptr || proxy_->AsObject() == nullptr || proxy_->AsObject()->IsObjectDead()) {
452 LOGD(PRI_DOMAIN, PRI_TAG, "Iface_cast get null");
453 }
454 }
455 }
456
OnRemoteDiedHandle()457 void PrivacyManagerClient::OnRemoteDiedHandle()
458 {
459 std::lock_guard<std::mutex> lock(proxyMutex_);
460 ReleaseProxy();
461 InitProxy();
462 }
463
GetProxy()464 sptr<IPrivacyManager> PrivacyManagerClient::GetProxy()
465 {
466 std::lock_guard<std::mutex> lock(proxyMutex_);
467 if (proxy_ == nullptr || proxy_->AsObject() == nullptr || proxy_->AsObject()->IsObjectDead()) {
468 InitProxy();
469 }
470 return proxy_;
471 }
472
ReleaseProxy()473 void PrivacyManagerClient::ReleaseProxy()
474 {
475 if (proxy_ != nullptr && serviceDeathObserver_ != nullptr) {
476 proxy_->AsObject()->RemoveDeathRecipient(serviceDeathObserver_);
477 }
478 proxy_ = nullptr;
479 serviceDeathObserver_ = nullptr;
480 }
481
GetAnonyStub()482 sptr<ProxyDeathCallBackStub> PrivacyManagerClient::GetAnonyStub()
483 {
484 std::lock_guard<std::mutex> lock(stubMutex_);
485 if (anonyStub_ == nullptr) {
486 anonyStub_ = sptr<ProxyDeathCallBackStub>::MakeSptr();
487 }
488 return anonyStub_;
489 }
490 } // namespace AccessToken
491 } // namespace Security
492 } // namespace OHOS
493