• 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_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