• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "short_grant_manager.h"
17 
18 #include <chrono>
19 #include <iostream>
20 #include <thread>
21 
22 #include "access_token.h"
23 #include "access_token_error.h"
24 #include "accesstoken_common_log.h"
25 #include "app_manager_access_client.h"
26 #include "permission_manager.h"
27 
28 namespace OHOS {
29 namespace Security {
30 namespace AccessToken {
31 std::recursive_mutex g_instanceMutex;
32 static constexpr int32_t DEFAULT_MAX_TIME_MILLISECONDS = 30 * 60; // 30 minutes
33 static constexpr int32_t DEFAULT_MAX_ONCE_TIME_MILLISECONDS = 5 * 60; // 5 minutes
34 static const std::string TASK_NAME_SHORT_GRANT_PERMISSION = "atm_permission_manager_short_grant";
35 static const std::vector<std::string> g_shortGrantPermission = {
36     "ohos.permission.SHORT_TERM_WRITE_IMAGEVIDEO"
37 };
38 
GetInstance()39 ShortGrantManager& ShortGrantManager::GetInstance()
40 {
41     static ShortGrantManager* instance = nullptr;
42     if (instance == nullptr) {
43         std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
44         if (instance == nullptr) {
45             ShortGrantManager* tmp = new (std::nothrow) ShortGrantManager();
46             instance = std::move(tmp);
47         }
48     }
49     return *instance;
50 }
51 
NotifyAppManagerDeath()52 void ShortPermAppManagerDeathCallback::NotifyAppManagerDeath()
53 {
54     LOGI(ATM_DOMAIN, ATM_TAG, "ShortGrantManager AppManagerDeath called");
55 
56     ShortGrantManager::GetInstance().OnAppMgrRemoteDiedHandle();
57 }
58 
OnAppStopped(const AppStateData & appStateData)59 void ShortPermAppStateObserver::OnAppStopped(const AppStateData &appStateData)
60 {
61     if (appStateData.state == static_cast<int32_t>(ApplicationState::APP_STATE_TERMINATED)) {
62         uint32_t tokenID = appStateData.accessTokenId;
63         LOGI(ATM_DOMAIN, ATM_TAG, "TokenID:%{public}d died.", tokenID);
64 
65         ShortGrantManager::GetInstance().ClearShortPermissionByTokenID(tokenID);
66     }
67 }
68 
OnAppMgrRemoteDiedHandle()69 void ShortGrantManager::OnAppMgrRemoteDiedHandle()
70 {
71     std::unique_lock<std::mutex> lck(shortGrantDataMutex_);
72     auto item = shortGrantData_.begin();
73     while (item != shortGrantData_.end()) {
74         if (PermissionManager::GetInstance().UpdatePermission(
75             item->tokenID, item->permissionName, false, PERMISSION_USER_FIXED, false) != RET_SUCCESS) {
76             LOGE(ATM_DOMAIN, ATM_TAG, "TokenID:%{public}d revoke permission:%{public}s failed!",
77                 item->tokenID, item->permissionName.c_str());
78         }
79         std::string taskName = TASK_NAME_SHORT_GRANT_PERMISSION + std::to_string(item->tokenID) + item->permissionName;
80         (void)ShortGrantManager::GetInstance().CancelTaskOfPermissionRevoking(taskName);
81         ++item;
82     }
83     shortGrantData_.clear();
84     LOGI(ATM_DOMAIN, ATM_TAG, "shortGrantData_ clear!");
85     appStopCallBack_ = nullptr;
86 }
87 
~ShortGrantManager()88 ShortGrantManager::~ShortGrantManager()
89 {
90     UnRegisterAppStopListener();
91 }
92 
93 #ifdef EVENTHANDLER_ENABLE
InitEventHandler()94 void ShortGrantManager::InitEventHandler()
95 {
96     auto eventRunner = AppExecFwk::EventRunner::Create(true, AppExecFwk::ThreadMode::FFRT);
97     if (!eventRunner) {
98         LOGE(ATM_DOMAIN, ATM_TAG, "Failed to create a shortGrantEventRunner.");
99         return;
100     }
101     eventHandler_ = std::make_shared<AccessEventHandler>(eventRunner);
102 }
103 
GetEventHandler()104 std::shared_ptr<AccessEventHandler> ShortGrantManager::GetEventHandler()
105 {
106     std::lock_guard<std::mutex> lock(eventHandlerLock_);
107     if (eventHandler_ == nullptr) {
108         InitEventHandler();
109     }
110     return eventHandler_;
111 }
112 #endif
113 
CancelTaskOfPermissionRevoking(const std::string & taskName)114 bool ShortGrantManager::CancelTaskOfPermissionRevoking(const std::string& taskName)
115 {
116 #ifdef EVENTHANDLER_ENABLE
117     auto eventHandler = GetEventHandler();
118     if (eventHandler == nullptr) {
119         LOGE(ATM_DOMAIN, ATM_TAG, "Fail to get EventHandler");
120         return false;
121     }
122 
123     LOGI(ATM_DOMAIN, ATM_TAG, "Revoke permission task name:%{public}s", taskName.c_str());
124     eventHandler->ProxyRemoveTask(taskName);
125     return true;
126 #else
127     LOGW(ATM_DOMAIN, ATM_TAG, "EventHandler is not existed");
128     return false;
129 #endif
130 }
131 
RefreshPermission(AccessTokenID tokenID,const std::string & permission,uint32_t onceTime)132 int ShortGrantManager::RefreshPermission(AccessTokenID tokenID, const std::string& permission, uint32_t onceTime)
133 {
134     if (tokenID == 0 || onceTime == 0 || onceTime > DEFAULT_MAX_ONCE_TIME_MILLISECONDS || onceTime > maxTime_) {
135         LOGE(ATM_DOMAIN, ATM_TAG, "Input invalid, tokenID: %{public}d, onceTime %{public}u!", tokenID, onceTime);
136         return AccessTokenError::ERR_PARAM_INVALID;
137     }
138     std::string taskName = TASK_NAME_SHORT_GRANT_PERMISSION + std::to_string(tokenID) + permission;
139     std::unique_lock<std::mutex> lck(shortGrantDataMutex_);
140 
141     auto iter = std::find_if(
142         shortGrantData_.begin(), shortGrantData_.end(), [tokenID, permission](const PermTimerData& data) {
143         return data.tokenID == tokenID && data.permissionName == permission;
144     });
145 
146     if (iter == shortGrantData_.end()) {
147         auto iterator = std::find(g_shortGrantPermission.begin(), g_shortGrantPermission.end(), permission);
148         if (iterator == g_shortGrantPermission.end()) {
149             LOGE(ATM_DOMAIN, ATM_TAG, "Permission is not available to short grant: %{public}s!", permission.c_str());
150             return AccessTokenError::ERR_PARAM_INVALID;
151         }
152         PermTimerData data;
153         data.tokenID = tokenID;
154         data.permissionName = permission;
155         data.firstGrantTimes = GetCurrentTime();
156         data.revokeTimes = data.firstGrantTimes + onceTime;
157         int32_t ret = PermissionManager::GetInstance().GrantPermission(tokenID, permission, PERMISSION_USER_FIXED);
158         if (ret != RET_SUCCESS) {
159             LOGE(ATM_DOMAIN, ATM_TAG, "GrantPermission failed result %{public}d", ret);
160             return ret;
161         }
162         shortGrantData_.emplace_back(data);
163         ShortGrantManager::GetInstance().ScheduleRevokeTask(tokenID, permission, taskName, onceTime);
164         RegisterAppStopListener();
165         return RET_SUCCESS;
166     }
167 
168     uint32_t maxRemainedTime = maxTime_ > (GetCurrentTime() - iter->firstGrantTimes) ?
169         (maxTime_ - (GetCurrentTime() - iter->firstGrantTimes)) : 0;
170     uint32_t currRemainedTime = iter->revokeTimes > GetCurrentTime() ?
171         (iter->revokeTimes - GetCurrentTime()) : 0;
172     uint32_t cancelTimes = (maxRemainedTime > onceTime) ? onceTime : maxRemainedTime;
173     if (cancelTimes > currRemainedTime) {
174         iter->revokeTimes = GetCurrentTime() + cancelTimes;
175         (void)ShortGrantManager::GetInstance().CancelTaskOfPermissionRevoking(taskName);
176         int32_t ret = PermissionManager::GetInstance().GrantPermission(tokenID, permission, PERMISSION_USER_FIXED);
177         if (ret != RET_SUCCESS) {
178             LOGE(ATM_DOMAIN, ATM_TAG, "GrantPermission failed result %{public}d", ret);
179             return ret;
180         }
181         ShortGrantManager::GetInstance().ScheduleRevokeTask(iter->tokenID, iter->permissionName, taskName, cancelTimes);
182     }
183     RegisterAppStopListener();
184     return RET_SUCCESS;
185 }
186 
ClearShortPermissionData(AccessTokenID tokenID,const std::string & permission)187 void ShortGrantManager::ClearShortPermissionData(AccessTokenID tokenID, const std::string& permission)
188 {
189     std::unique_lock<std::mutex> lck(shortGrantDataMutex_);
190     auto item = shortGrantData_.begin();
191     while (item != shortGrantData_.end()) {
192         if (item->tokenID == tokenID && item->permissionName == permission) {
193             // revoke without kill the app
194             if (PermissionManager::GetInstance().UpdatePermission(
195                 tokenID, permission, false, PERMISSION_USER_FIXED, false) != RET_SUCCESS) {
196                 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID:%{public}d revoke permission:%{public}s failed!",
197                     tokenID, permission.c_str());
198                 return;
199             }
200             // clear data
201             shortGrantData_.erase(item);
202             if (shortGrantData_.empty()) {
203                 UnRegisterAppStopListener();
204             }
205             break;
206         } else {
207             ++item;
208         }
209     }
210 }
211 
ClearShortPermissionByTokenID(AccessTokenID tokenID)212 void ShortGrantManager::ClearShortPermissionByTokenID(AccessTokenID tokenID)
213 {
214     std::unique_lock<std::mutex> lck(shortGrantDataMutex_);
215     auto item = shortGrantData_.begin();
216     while (item != shortGrantData_.end()) {
217         if (item->tokenID == tokenID) {
218             if (PermissionManager::GetInstance().UpdatePermission(
219                 tokenID, item->permissionName, false, PERMISSION_USER_FIXED, false) != RET_SUCCESS) {
220                 LOGE(ATM_DOMAIN, ATM_TAG, "TokenID:%{public}d revoke permission:%{public}s failed!",
221                     tokenID, item->permissionName.c_str());
222                 return;
223             }
224             // clear task and data
225             std::string taskName = TASK_NAME_SHORT_GRANT_PERMISSION + std::to_string(tokenID) + item->permissionName;
226             (void)ShortGrantManager::GetInstance().CancelTaskOfPermissionRevoking(taskName);
227             item = shortGrantData_.erase(item);
228         } else {
229             ++item;
230         }
231     }
232     if (shortGrantData_.empty()) {
233         UnRegisterAppStopListener();
234     }
235 }
236 
ScheduleRevokeTask(AccessTokenID tokenID,const std::string & permission,const std::string & taskName,uint32_t cancelTimes)237 void ShortGrantManager::ScheduleRevokeTask(AccessTokenID tokenID, const std::string& permission,
238     const std::string& taskName, uint32_t cancelTimes)
239 {
240 #ifdef EVENTHANDLER_ENABLE
241     auto eventHandler = GetEventHandler();
242     if (eventHandler == nullptr) {
243         LOGE(ATM_DOMAIN, ATM_TAG, "Fail to get EventHandler");
244         return;
245     }
246 
247     LOGI(ATM_DOMAIN, ATM_TAG, "Add permission task name:%{public}s", taskName.c_str());
248 
249     std::function<void()> delayed = ([tokenID, permission]() {
250         ShortGrantManager::GetInstance().ClearShortPermissionData(tokenID, permission);
251         LOGI(ATM_DOMAIN, ATM_TAG,
252             "Token: %{public}d, permission: %{public}s, delay revoke permission end.", tokenID, permission.c_str());
253     });
254     LOGI(ATM_DOMAIN, ATM_TAG, "cancelTimes %{public}d", cancelTimes);
255     eventHandler->ProxyPostTask(delayed, taskName, cancelTimes * 1000); // 1000 means to ms
256     return;
257 #else
258     LOGW(ATM_DOMAIN, ATM_TAG, "eventHandler is not existed");
259     return;
260 #endif
261 }
262 
GetCurrentTime()263 uint32_t ShortGrantManager::GetCurrentTime()
264 {
265     return static_cast<uint32_t>(std::chrono::system_clock::now().time_since_epoch() / std::chrono::seconds(1));
266 }
267 
IsShortGrantPermission(const std::string & permissionName)268 bool ShortGrantManager::IsShortGrantPermission(const std::string& permissionName)
269 {
270     auto it = find(g_shortGrantPermission.begin(), g_shortGrantPermission.end(), permissionName);
271     if (it == g_shortGrantPermission.end()) {
272         return false;
273     }
274     return true;
275 }
276 
RegisterAppStopListener()277 void ShortGrantManager::RegisterAppStopListener()
278 {
279     {
280         std::lock_guard<std::mutex> lock(appManagerDeathMutex_);
281         if (appManagerDeathCallback_ == nullptr) {
282             appManagerDeathCallback_ = std::make_shared<ShortPermAppManagerDeathCallback>();
283             if (appManagerDeathCallback_ == nullptr) {
284                 LOGE(ATM_DOMAIN, ATM_TAG, "Register appManagerDeathCallback failed.");
285                 return;
286             }
287             AppManagerAccessClient::GetInstance().RegisterDeathCallback(appManagerDeathCallback_);
288         }
289     }
290     {
291         std::lock_guard<std::mutex> lock(appStopCallbackMutex_);
292         if (appStopCallBack_ == nullptr) {
293             appStopCallBack_ = new (std::nothrow) ShortPermAppStateObserver();
294             if (appStopCallBack_ == nullptr) {
295                 LOGE(ATM_DOMAIN, ATM_TAG, "Register appStopCallBack failed.");
296                 return;
297             }
298             int ret = AppManagerAccessClient::GetInstance().RegisterApplicationStateObserver(appStopCallBack_);
299             if (ret != ERR_OK) {
300                 LOGI(ATM_DOMAIN, ATM_TAG, "Register appStopCallBack %{public}d.", ret);
301             }
302         }
303     }
304 }
305 
UnRegisterAppStopListener()306 void ShortGrantManager::UnRegisterAppStopListener()
307 {
308     std::lock_guard<std::mutex> lock(appStopCallbackMutex_);
309     if (appStopCallBack_ != nullptr) {
310         int32_t ret = AppManagerAccessClient::GetInstance().UnregisterApplicationStateObserver(appStopCallBack_);
311         if (ret != ERR_OK) {
312             LOGI(ATM_DOMAIN, ATM_TAG, "Unregister appStopCallback %{public}d.", ret);
313         }
314         appStopCallBack_= nullptr;
315     }
316 }
317 
ShortGrantManager()318 ShortGrantManager::ShortGrantManager() : maxTime_(DEFAULT_MAX_TIME_MILLISECONDS)
319 {}
320 } // namespace AccessToken
321 } // namespace Security
322 } // namespace OHOS