1 /*
2 * Copyright (c) 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
16 #include "temp_permission_observer.h"
17
18 #include "access_token.h"
19 #include "access_token_error.h"
20 #include "accesstoken_info_manager.h"
21 #include "accesstoken_log.h"
22 #include "app_manager_access_client.h"
23
24 namespace OHOS {
25 namespace Security {
26 namespace AccessToken {
27 namespace {
28 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "TempPermissionObserver"};
29 static const std::string TASK_NAME_TEMP_PERMISSION = "atm_permission_manager_temp_permission";
30 #ifdef EVENTHANDLER_ENABLE
31 static constexpr int32_t WAIT_MILLISECONDS = 10 * 1000; // 10s
32 #endif
33 }
34
GetInstance()35 TempPermissionObserver& TempPermissionObserver::GetInstance()
36 {
37 static TempPermissionObserver instance;
38 return instance;
39 }
40
OnProcessDied(const ProcessData & processData)41 void PermissionAppStateObserver::OnProcessDied(const ProcessData &processData)
42 {
43 ACCESSTOKEN_LOG_INFO(LABEL, "OnProcessDied die accessTokenId %{public}d", processData.accessTokenId);
44
45 uint32_t tokenID = processData.accessTokenId;
46 // cancle task when process die
47 std::string taskName = TASK_NAME_TEMP_PERMISSION + std::to_string(tokenID);
48 TempPermissionObserver::GetInstance().CancleTaskOfPermissionRevoking(taskName);
49 TempPermissionObserver::GetInstance().RevokeAllTempPermission(tokenID);
50 }
51
OnForegroundApplicationChanged(const AppStateData & appStateData)52 void PermissionAppStateObserver::OnForegroundApplicationChanged(const AppStateData &appStateData)
53 {
54 ACCESSTOKEN_LOG_DEBUG(LABEL, "OnChange(accessTokenId=%{public}d, state=%{public}d)",
55 appStateData.accessTokenId, appStateData.state);
56 uint32_t tokenID = appStateData.accessTokenId;
57 if (appStateData.state == static_cast<int32_t>(ApplicationState::APP_STATE_FOREGROUND)) {
58 std::string taskName = TASK_NAME_TEMP_PERMISSION + std::to_string(tokenID);
59 if (!TempPermissionObserver::GetInstance().CancleTaskOfPermissionRevoking(taskName)) {
60 ACCESSTOKEN_LOG_ERROR(LABEL, "CancleTaskOfPermissionRevoking failed!!!");
61 }
62 } else if (appStateData.state == static_cast<int32_t>(ApplicationState::APP_STATE_BACKGROUND)) {
63 std::string taskName = TASK_NAME_TEMP_PERMISSION + std::to_string(tokenID);
64 if (!TempPermissionObserver::GetInstance().DelayRevokePermission(tokenID, taskName)) {
65 ACCESSTOKEN_LOG_ERROR(LABEL, "DelayRevokePermission failed!!!");
66 }
67 }
68 }
69
NotifyAppManagerDeath()70 void PermissionAppManagerDeathCallback::NotifyAppManagerDeath()
71 {
72 ACCESSTOKEN_LOG_INFO(LABEL, "TempPermissionObserver AppManagerDeath called");
73
74 TempPermissionObserver::GetInstance().OnAppMgrRemoteDiedHandle();
75 }
76
TempPermissionObserver()77 TempPermissionObserver::TempPermissionObserver()
78 {}
79
~TempPermissionObserver()80 TempPermissionObserver::~TempPermissionObserver()
81 {
82 std::lock_guard<std::mutex> lock(tempPermissionMutex_);
83 if (appStateCallback_ != nullptr) {
84 AppManagerAccessClient::GetInstance().UnregisterApplicationStateObserver(appStateCallback_);
85 appStateCallback_= nullptr;
86 }
87 }
88
RegisterCallback()89 void TempPermissionObserver::RegisterCallback()
90 {
91 if (appStateCallback_ == nullptr) {
92 appStateCallback_ = new(std::nothrow) PermissionAppStateObserver();
93 if (appStateCallback_ == nullptr) {
94 ACCESSTOKEN_LOG_ERROR(LABEL, "register appStateCallback failed.");
95 return;
96 }
97 AppManagerAccessClient::GetInstance().RegisterApplicationStateObserver(appStateCallback_);
98 }
99 if (appManagerDeathCallback_ == nullptr) {
100 appManagerDeathCallback_ = std::make_shared<PermissionAppManagerDeathCallback>();
101 AppManagerAccessClient::GetInstance().RegisterDeathCallbak(appManagerDeathCallback_);
102 }
103 }
104
AddTempPermTokenToList(AccessTokenID tokenID,const std::string & permissionName)105 void TempPermissionObserver::AddTempPermTokenToList(AccessTokenID tokenID, const std::string& permissionName)
106 {
107 std::unique_lock<std::mutex> lck(tempPermissionMutex_);
108 RegisterCallback();
109 auto iter = std::find_if(tempPermTokenList_.begin(), tempPermTokenList_.end(), [tokenID](const AccessTokenID& id) {
110 return tokenID == id;
111 });
112 if (iter != tempPermTokenList_.end()) {
113 ACCESSTOKEN_LOG_INFO(LABEL, "tokenID:%{public}d has existed in tokenList", tokenID);
114 return;
115 }
116 ACCESSTOKEN_LOG_INFO(LABEL, "tokenID:%{public}d added in tokenList", tokenID);
117 tempPermTokenList_.emplace_back(tokenID);
118 }
119
DeleteTempPermFromList(AccessTokenID tokenID,const std::string & permissionName)120 void TempPermissionObserver::DeleteTempPermFromList(AccessTokenID tokenID, const std::string& permissionName)
121 {
122 std::unique_lock<std::mutex> lck(tempPermissionMutex_);
123 auto iter = std::find_if(tempPermTokenList_.begin(), tempPermTokenList_.end(), [tokenID](const AccessTokenID& id) {
124 return tokenID == id;
125 });
126 if (iter == tempPermTokenList_.end()) {
127 ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID:%{public}d not exist in tokenList", tokenID);
128 return;
129 }
130 ACCESSTOKEN_LOG_DEBUG(LABEL, "permission:%{public}s has been erased from permList", permissionName.c_str());
131 tempPermTokenList_.erase(iter);
132 if (tempPermTokenList_.empty()) {
133 if (appStateCallback_ != nullptr) {
134 AppManagerAccessClient::GetInstance().UnregisterApplicationStateObserver(appStateCallback_);
135 appStateCallback_= nullptr;
136 }
137 }
138 }
139
GetPermissionStateFull(AccessTokenID tokenID,std::vector<PermissionStateFull> & permissionStateFullList)140 bool TempPermissionObserver::GetPermissionStateFull(AccessTokenID tokenID,
141 std::vector<PermissionStateFull>& permissionStateFullList)
142 {
143 std::shared_ptr<HapTokenInfoInner> infoPtr = AccessTokenInfoManager::GetInstance().GetHapTokenInfoInner(tokenID);
144 if (infoPtr == nullptr) {
145 ACCESSTOKEN_LOG_ERROR(LABEL, "token %{public}u is invalid.", tokenID);
146 return false;
147 }
148 if (infoPtr->IsRemote()) {
149 ACCESSTOKEN_LOG_ERROR(LABEL, "it is a remote hap token %{public}u!", tokenID);
150 return false;
151 }
152 std::shared_ptr<PermissionPolicySet> permPolicySet = infoPtr->GetHapInfoPermissionPolicySet();
153 if (permPolicySet == nullptr) {
154 ACCESSTOKEN_LOG_ERROR(LABEL, "invalid params!");
155 return false;
156 }
157
158 permPolicySet->GetPermissionStateFulls(permissionStateFullList);
159 return true;
160 }
161
RevokeAllTempPermission(AccessTokenID tokenID)162 void TempPermissionObserver::RevokeAllTempPermission(AccessTokenID tokenID)
163 {
164 std::unique_lock<std::mutex> lck(tempPermissionMutex_);
165 auto iter = std::find_if(tempPermTokenList_.begin(), tempPermTokenList_.end(), [tokenID](const AccessTokenID& id) {
166 return tokenID == id;
167 });
168 if (iter == tempPermTokenList_.end()) {
169 ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID:%{public}d not exist in permList", tokenID);
170 return;
171 }
172 tempPermTokenList_.erase(iter);
173 if (tempPermTokenList_.empty()) {
174 if (appStateCallback_ != nullptr) {
175 AppManagerAccessClient::GetInstance().UnregisterApplicationStateObserver(appStateCallback_);
176 appStateCallback_= nullptr;
177 }
178 }
179
180 std::vector<PermissionStateFull> tmpList;
181 if (!GetPermissionStateFull(tokenID, tmpList)) {
182 ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID:%{public}d get permission state full fail!", tokenID);
183 return;
184 }
185 for (const auto& permissionState : tmpList) {
186 if (permissionState.grantFlags[0] == PERMISSION_ALLOW_THIS_TIME) {
187 if (PermissionManager::GetInstance().RevokePermission(
188 tokenID, permissionState.permissionName, PERMISSION_ALLOW_THIS_TIME) != RET_SUCCESS) {
189 ACCESSTOKEN_LOG_ERROR(LABEL, "tokenID:%{public}d revoke permission:%{public}s failed!",
190 tokenID, permissionState.permissionName.c_str());
191 return;
192 }
193 }
194 }
195 }
196
OnAppMgrRemoteDiedHandle()197 void TempPermissionObserver::OnAppMgrRemoteDiedHandle()
198 {
199 std::unique_lock<std::mutex> lck(tempPermissionMutex_);
200 for (auto iter = tempPermTokenList_.begin(); iter != tempPermTokenList_.end(); ++iter) {
201 std::vector<PermissionStateFull> tmpList;
202 GetPermissionStateFull(*iter, tmpList);
203 for (const auto& permissionState : tmpList) {
204 if (permissionState.grantFlags[0] == PERMISSION_ALLOW_THIS_TIME) {
205 PermissionManager::GetInstance().RevokePermission(
206 *iter, permissionState.permissionName, PERMISSION_ALLOW_THIS_TIME);
207 }
208 }
209 std::string taskName = TASK_NAME_TEMP_PERMISSION + std::to_string(*iter);
210 TempPermissionObserver::GetInstance().CancleTaskOfPermissionRevoking(taskName);
211 }
212 tempPermTokenList_.clear();
213 ACCESSTOKEN_LOG_INFO(LABEL, "tempPermTokenList_ clear!");
214 appStateCallback_= nullptr;
215 }
216
217 #ifdef EVENTHANDLER_ENABLE
InitEventHandler(const std::shared_ptr<AccessEventHandler> & eventHandler)218 void TempPermissionObserver::InitEventHandler(const std::shared_ptr<AccessEventHandler>& eventHandler)
219 {
220 eventHandler_ = eventHandler;
221 }
222 #endif
223
DelayRevokePermission(AccessToken::AccessTokenID tokenID,const std::string & taskName)224 bool TempPermissionObserver::DelayRevokePermission(AccessToken::AccessTokenID tokenID, const std::string& taskName)
225 {
226 #ifdef EVENTHANDLER_ENABLE
227 if (eventHandler_ == nullptr) {
228 ACCESSTOKEN_LOG_ERROR(LABEL, "fail to get EventHandler");
229 return false;
230 }
231
232 ACCESSTOKEN_LOG_INFO(LABEL, "add permission task name:%{public}s", taskName.c_str());
233
234 std::function<void()> delayed = ([tokenID]() {
235 TempPermissionObserver::GetInstance().RevokeAllTempPermission(tokenID);
236 ACCESSTOKEN_LOG_INFO(LABEL, "token: %{public}d, delay revoke permission end", tokenID);
237 });
238
239 eventHandler_->ProxyPostTask(delayed, taskName, WAIT_MILLISECONDS);
240 return true;
241 #else
242 return false;
243 #endif
244 }
245
CancleTaskOfPermissionRevoking(const std::string & taskName)246 bool TempPermissionObserver::CancleTaskOfPermissionRevoking(const std::string& taskName)
247 {
248 #ifdef EVENTHANDLER_ENABLE
249 if (eventHandler_ == nullptr) {
250 ACCESSTOKEN_LOG_ERROR(LABEL, "fail to get EventHandler");
251 return false;
252 }
253
254 ACCESSTOKEN_LOG_INFO(LABEL, "revoke permission task name:%{public}s", taskName.c_str());
255 eventHandler_->ProxyRemoveTask(taskName);
256 return true;
257 #else
258 return false;
259 #endif
260 }
261 } // namespace AccessToken
262 } // namespace Security
263 } // namespace OHOS
264