• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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