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 "permission_manager.h"
25
26 namespace OHOS {
27 namespace Security {
28 namespace AccessToken {
29 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "ShortGrantManager"};
30 std::recursive_mutex g_instanceMutex;
31 static constexpr int32_t DEFAULT_MAX_TIME_MILLISECONDS = 30 * 60; // 30 minutes
32 static constexpr int32_t DEFAULT_MAX_ONCE_TIME_MILLISECONDS = 5 * 60; // 5 minutes
33 static const std::string TASK_NAME_SHORT_GRANT_PERMISSION = "atm_permission_manager_short_grant";
34 static const std::vector<std::string> g_shortGrantPermission = {
35 "ohos.permission.SHORT_TERM_WRITE_IMAGEVIDEO"
36 };
37
GetInstance()38 ShortGrantManager& ShortGrantManager::GetInstance()
39 {
40 static ShortGrantManager* instance = nullptr;
41 if (instance == nullptr) {
42 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
43 if (instance == nullptr) {
44 instance = new ShortGrantManager();
45 }
46 }
47 return *instance;
48 }
49
InitEventHandler(const std::shared_ptr<AccessEventHandler> & eventHandler)50 void ShortGrantManager::InitEventHandler(const std::shared_ptr<AccessEventHandler>& eventHandler)
51 {
52 eventHandler_ = eventHandler;
53 }
54
CancelTaskOfPermissionRevoking(const std::string & taskName)55 bool ShortGrantManager::CancelTaskOfPermissionRevoking(const std::string& taskName)
56 {
57 #ifdef EVENTHANDLER_ENABLE
58 if (eventHandler_ == nullptr) {
59 ACCESSTOKEN_LOG_ERROR(LABEL, "Fail to get EventHandler");
60 return false;
61 }
62
63 ACCESSTOKEN_LOG_INFO(LABEL, "Revoke permission task name:%{public}s", taskName.c_str());
64 eventHandler_->ProxyRemoveTask(taskName);
65 return true;
66 #else
67 ACCESSTOKEN_LOG_WARN(LABEL, "EventHandler is not existed");
68 return false;
69 #endif
70 }
71
RefreshPermission(AccessTokenID tokenID,const std::string & permission,uint32_t onceTime)72 int ShortGrantManager::RefreshPermission(AccessTokenID tokenID, const std::string& permission, uint32_t onceTime)
73 {
74 if (tokenID == 0 || onceTime == 0 || onceTime > DEFAULT_MAX_ONCE_TIME_MILLISECONDS || onceTime > maxTime_) {
75 ACCESSTOKEN_LOG_ERROR(LABEL,
76 "Input invalid, tokenID is: %{public}d, onceTime is %{public}u!", tokenID, onceTime);
77 return AccessTokenError::ERR_PARAM_INVALID;
78 }
79 std::string taskName = TASK_NAME_SHORT_GRANT_PERMISSION + std::to_string(tokenID) + permission;
80 std::unique_lock<std::mutex> lck(shortGrantDataMutex_);
81
82 auto iter = std::find_if(
83 shortGrantData_.begin(), shortGrantData_.end(), [tokenID, permission](const PermTimerData& data) {
84 return data.tokenID == tokenID && data.permissionName == permission;
85 });
86 if (iter == shortGrantData_.end()) {
87 auto iterator = std::find(g_shortGrantPermission.begin(), g_shortGrantPermission.end(), permission);
88 if (iterator == g_shortGrantPermission.end()) {
89 ACCESSTOKEN_LOG_ERROR(LABEL, "Permission is not available to short grant: %{public}s!", permission.c_str());
90 return AccessTokenError::ERR_PARAM_INVALID;
91 }
92 PermTimerData data;
93 data.tokenID = tokenID;
94 data.permissionName = permission;
95 data.firstGrantTimes = GetCurrentTime();
96 data.revokeTimes = data.firstGrantTimes + onceTime;
97 int32_t ret = PermissionManager::GetInstance().GrantPermission(tokenID, permission, PERMISSION_USER_FIXED);
98 if (ret != RET_SUCCESS) {
99 ACCESSTOKEN_LOG_ERROR(LABEL, "GrantPermission failed result %{public}d", ret);
100 return ret;
101 }
102 shortGrantData_.emplace_back(data);
103 ShortGrantManager::GetInstance().ScheduleRevokeTask(tokenID, permission, taskName, onceTime);
104 return RET_SUCCESS;
105 }
106
107 uint32_t maxRemainedTime = maxTime_ > (GetCurrentTime() - iter->firstGrantTimes) ?
108 (maxTime_ - (GetCurrentTime() - iter->firstGrantTimes)) : 0;
109 uint32_t currRemainedTime = iter->revokeTimes > GetCurrentTime() ?
110 (iter->revokeTimes - GetCurrentTime()) : 0;
111 uint32_t cancelTimes = (maxRemainedTime > onceTime) ? onceTime : maxRemainedTime;
112 if (cancelTimes > currRemainedTime) {
113 iter->revokeTimes = GetCurrentTime() + cancelTimes;
114 ShortGrantManager::GetInstance().CancelTaskOfPermissionRevoking(taskName);
115 int32_t ret = PermissionManager::GetInstance().GrantPermission(tokenID, permission, PERMISSION_USER_FIXED);
116 if (ret != RET_SUCCESS) {
117 ACCESSTOKEN_LOG_ERROR(LABEL, "GrantPermission failed result %{public}d", ret);
118 return ret;
119 }
120 ShortGrantManager::GetInstance().ScheduleRevokeTask(iter->tokenID, iter->permissionName, taskName, cancelTimes);
121 }
122 return RET_SUCCESS;
123 }
124
ClearShortPermissionData(AccessTokenID tokenID,const std::string & permission)125 void ShortGrantManager::ClearShortPermissionData(AccessTokenID tokenID, const std::string& permission)
126 {
127 std::unique_lock<std::mutex> lck(shortGrantDataMutex_);
128 auto item = shortGrantData_.begin();
129 while (item != shortGrantData_.end()) {
130 if (item->tokenID == tokenID && item->permissionName == permission) {
131 // revoke without kill the app
132 if (PermissionManager::GetInstance().UpdatePermission(
133 tokenID, permission, false, PERMISSION_USER_FIXED, false) != RET_SUCCESS) {
134 ACCESSTOKEN_LOG_ERROR(LABEL, "TokenID:%{public}d revoke permission:%{public}s failed!",
135 tokenID, permission.c_str());
136 return;
137 }
138 // clear data
139 shortGrantData_.erase(item);
140 break;
141 } else {
142 ++item;
143 }
144 }
145 }
146
ScheduleRevokeTask(AccessTokenID tokenID,const std::string & permission,const std::string & taskName,uint32_t cancelTimes)147 void ShortGrantManager::ScheduleRevokeTask(AccessTokenID tokenID, const std::string& permission,
148 const std::string& taskName, uint32_t cancelTimes)
149 {
150 #ifdef EVENTHANDLER_ENABLE
151 if (eventHandler_ == nullptr) {
152 ACCESSTOKEN_LOG_ERROR(LABEL, "Fail to get EventHandler");
153 return;
154 }
155
156 ACCESSTOKEN_LOG_INFO(LABEL, "Add permission task name:%{public}s", taskName.c_str());
157
158 std::function<void()> delayed = ([tokenID, permission]() {
159 ShortGrantManager::GetInstance().ClearShortPermissionData(tokenID, permission);
160 ACCESSTOKEN_LOG_INFO(LABEL,
161 "Token: %{public}d, permission: %{public}s, delay revoke permission end.", tokenID, permission.c_str());
162 });
163 eventHandler_->ProxyPostTask(delayed, taskName, cancelTimes * 1000); // 1000 means to ms
164 return;
165 #else
166 ACCESSTOKEN_LOG_WARN(LABEL, "eventHandler is not existed");
167 return;
168 #endif
169 }
170
GetCurrentTime()171 uint32_t ShortGrantManager::GetCurrentTime()
172 {
173 return static_cast<uint32_t>(std::chrono::system_clock::now().time_since_epoch() / std::chrono::seconds(1));
174 }
175
IsShortGrantPermission(const std::string & permissionName)176 bool ShortGrantManager::IsShortGrantPermission(const std::string& permissionName)
177 {
178 auto it = find(g_shortGrantPermission.begin(), g_shortGrantPermission.end(), permissionName);
179 if (it == g_shortGrantPermission.end()) {
180 return false;
181 }
182 return true;
183 }
184
ShortGrantManager()185 ShortGrantManager::ShortGrantManager() : maxTime_(DEFAULT_MAX_TIME_MILLISECONDS)
186 {}
187 } // namespace AccessToken
188 } // namespace Security
189 } // namespace OHOS