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 #include "sec_comp_perm_manager.h"
16 
17 #include "sec_comp_err.h"
18 #include "sec_comp_log.h"
19 
20 namespace OHOS {
21 namespace Security {
22 namespace SecurityComponent {
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_SECURITY_COMPONENT, "SecCompPermManager"};
25 static const int32_t DELAY_REVOKE_MILLISECONDS = 10 * 1000;
26 static const std::string REVOKE_TASK_PREFIX = "RevokeAll";
27 static const std::string REVOKE_SAVE_PERM_TASK_PREFIX = "RevokeSavePerm";
28 }
29 
GetInstance()30 SecCompPermManager& SecCompPermManager::GetInstance()
31 {
32     static SecCompPermManager instance;
33     return instance;
34 }
35 
DelaySaveRevokePermission(AccessToken::AccessTokenID tokenId,const std::string & taskName)36 bool SecCompPermManager::DelaySaveRevokePermission(AccessToken::AccessTokenID tokenId, const std::string& taskName)
37 {
38     if (secHandler_ == nullptr) {
39         SC_LOG_ERROR(LABEL, "fail to get EventHandler");
40         return false;
41     }
42 
43     std::function<void()> delayed = ([tokenId]() {
44         SC_LOG_DEBUG(LABEL, "delay revoke save permission");
45         SecCompPermManager::GetInstance().RevokeTempSavePermissionCount(tokenId);
46     });
47 
48     SC_LOG_DEBUG(LABEL, "revoke save permission after %{public}d ms", DELAY_REVOKE_MILLISECONDS);
49     secHandler_->ProxyPostTask(delayed, taskName, DELAY_REVOKE_MILLISECONDS);
50     return true;
51 }
52 
RevokeSavePermissionTask(const std::string & taskName)53 bool SecCompPermManager::RevokeSavePermissionTask(const std::string& taskName)
54 {
55     if (secHandler_ == nullptr) {
56         SC_LOG_ERROR(LABEL, "fail to get EventHandler");
57         return false;
58     }
59 
60     SC_LOG_DEBUG(LABEL, "revoke save permission task name:%{public}s", taskName.c_str());
61     secHandler_->ProxyRemoveTask(taskName);
62     return true;
63 }
64 
GrantTempSavePermission(AccessToken::AccessTokenID tokenId)65 int32_t SecCompPermManager::GrantTempSavePermission(AccessToken::AccessTokenID tokenId)
66 {
67     auto current = static_cast<uint64_t>(std::chrono::high_resolution_clock::now().time_since_epoch().count());
68     std::string taskName = std::to_string(tokenId) + std::to_string(current);
69     if (!DelaySaveRevokePermission(tokenId, taskName)) {
70         return SC_SERVICE_ERROR_PERMISSION_OPER_FAIL;
71     }
72     std::lock_guard<std::mutex> lock(mutex_);
73     saveTaskDequeMap_[tokenId].push_back(taskName);
74     applySaveCountMap_[tokenId]++;
75     SC_LOG_DEBUG(LABEL, "tokenId: %{public}d current permission apply counts is: %{public}d.",
76         tokenId, applySaveCountMap_[tokenId]);
77     return SC_OK;
78 }
79 
RevokeTempSavePermissionCount(AccessToken::AccessTokenID tokenId)80 void SecCompPermManager::RevokeTempSavePermissionCount(AccessToken::AccessTokenID tokenId)
81 {
82     std::lock_guard<std::mutex> lock(mutex_);
83     auto iter = applySaveCountMap_.find(tokenId);
84     if (iter == applySaveCountMap_.end()) {
85         SC_LOG_ERROR(LABEL, "This hap has no permissions to save files.");
86         return;
87     }
88     if (saveTaskDequeMap_[tokenId].size() == 0) {
89         SC_LOG_ERROR(LABEL, "Current no task need to be revoke.");
90         return;
91     }
92     std::string taskName = saveTaskDequeMap_[tokenId].front();
93     if (!RevokeSavePermissionTask(taskName)) {
94         return;
95     }
96     saveTaskDequeMap_[tokenId].pop_front();
97     SC_LOG_DEBUG(LABEL, "tokenId: %{public}d current permission apply counts is: %{public}d.",
98         tokenId, applySaveCountMap_[tokenId]);
99     if ((--applySaveCountMap_[tokenId]) == 0) {
100         applySaveCountMap_.erase(tokenId);
101         SC_LOG_INFO(LABEL, "tokenId: %{public}d save permission count is 0, revoke it.", tokenId);
102     }
103     return;
104 }
105 
RevokeTempSavePermission(AccessToken::AccessTokenID tokenId)106 void SecCompPermManager::RevokeTempSavePermission(AccessToken::AccessTokenID tokenId)
107 {
108     std::lock_guard<std::mutex> lock(mutex_);
109     applySaveCountMap_.erase(tokenId);
110     auto& taskDeque = saveTaskDequeMap_[tokenId];
111     for (auto iter = taskDeque.begin(); iter != taskDeque.end(); ++iter) {
112         if (!RevokeSavePermissionTask(*iter)) {
113             continue;
114         }
115     }
116     taskDeque.clear();
117     SC_LOG_INFO(LABEL, "tokenId: %{public}d revoke save permission.", tokenId);
118     return;
119 }
120 
VerifySavePermission(AccessToken::AccessTokenID tokenId)121 bool SecCompPermManager::VerifySavePermission(AccessToken::AccessTokenID tokenId)
122 {
123     std::lock_guard<std::mutex> lock(mutex_);
124     auto iter = applySaveCountMap_.find(tokenId);
125     if (iter == applySaveCountMap_.end() || applySaveCountMap_[tokenId] == 0) {
126         SC_LOG_ERROR(LABEL, "This hap has no permissions to save files.");
127         return false;
128     }
129     return true;
130 }
131 
VerifyPermission(AccessToken::AccessTokenID tokenId,SecCompType type)132 bool SecCompPermManager::VerifyPermission(AccessToken::AccessTokenID tokenId, SecCompType type)
133 {
134     int32_t res;
135     switch (type) {
136         case LOCATION_COMPONENT:
137             res = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.LOCATION");
138             if (res != AccessToken::TypePermissionState::PERMISSION_GRANTED) {
139                 return false;
140             }
141             res = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, "ohos.permission.APPROXIMATELY_LOCATION");
142             return (res == AccessToken::TypePermissionState::PERMISSION_GRANTED);
143         case PASTE_COMPONENT:
144             res = AccessToken::AccessTokenKit::VerifyAccessToken(tokenId,
145                 "ohos.permission.SECURE_PASTE");
146             return (res == AccessToken::TypePermissionState::PERMISSION_GRANTED);
147         case SAVE_COMPONENT:
148             return VerifySavePermission(tokenId);
149         default:
150             SC_LOG_ERROR(LABEL, "Unknown component type.");
151     }
152     return false;
153 }
154 
AddAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,const std::string & permissionName)155 void SecCompPermManager::AddAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,
156     const std::string& permissionName)
157 {
158     auto iter = grantMap_.find(tokenId);
159     if (iter != grantMap_.end()) {
160         iter->second.insert(permissionName);
161         return;
162     }
163     std::set<std::string> permSet;
164     permSet.insert(permissionName);
165     grantMap_[tokenId] = permSet;
166 }
167 
RemoveAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,const std::string & permissionName)168 void SecCompPermManager::RemoveAppGrantPermissionRecord(AccessToken::AccessTokenID tokenId,
169     const std::string& permissionName)
170 {
171     auto iter = grantMap_.find(tokenId);
172     if (iter == grantMap_.end()) {
173         return;
174     }
175 
176     grantMap_[tokenId].erase(permissionName);
177 }
178 
GrantAppPermission(AccessToken::AccessTokenID tokenId,const std::string & permissionName)179 int32_t SecCompPermManager::GrantAppPermission(AccessToken::AccessTokenID tokenId,
180     const std::string& permissionName)
181 {
182     std::lock_guard<std::mutex> lock(grantMtx_);
183     int32_t res = AccessToken::AccessTokenKit::GrantPermission(tokenId, permissionName,
184         AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
185     SC_LOG_INFO(LABEL, "grant permission res: %{public}d, permission: %{public}s, tokenId:%{public}d",
186         res, permissionName.c_str(), tokenId);
187 
188     AddAppGrantPermissionRecord(tokenId, permissionName);
189     return res;
190 }
191 
RevokeAppPermission(AccessToken::AccessTokenID tokenId,const std::string & permissionName)192 int32_t SecCompPermManager::RevokeAppPermission(AccessToken::AccessTokenID tokenId,
193     const std::string& permissionName)
194 {
195     std::lock_guard<std::mutex> lock(grantMtx_);
196     int32_t res = AccessToken::AccessTokenKit::RevokePermission(tokenId, permissionName,
197         AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
198     SC_LOG_INFO(LABEL, "revoke permission res: %{public}d, permission: %{public}s, tokenId:%{public}d",
199         res, permissionName.c_str(), tokenId);
200 
201     RemoveAppGrantPermissionRecord(tokenId, permissionName);
202     return res;
203 }
204 
RevokeAppPermissions(AccessToken::AccessTokenID tokenId)205 void SecCompPermManager::RevokeAppPermissions(AccessToken::AccessTokenID tokenId)
206 {
207     RevokeAppPermisionsImmediately(tokenId);
208     CancelAppRevokingPermisions(tokenId);
209 }
210 
RevokeAppPermisionsDelayed(AccessToken::AccessTokenID tokenId)211 void SecCompPermManager::RevokeAppPermisionsDelayed(AccessToken::AccessTokenID tokenId)
212 {
213     if (secHandler_ == nullptr) {
214         SC_LOG_ERROR(LABEL, "fail to get EventHandler");
215         return;
216     }
217 
218     std::function<void()> delayed = ([tokenId]() {
219         SC_LOG_DEBUG(LABEL, "delay revoke token id %{public}d permissions", tokenId);
220         SecCompPermManager::GetInstance().RevokeAppPermisionsImmediately(tokenId);
221     });
222 
223     SC_LOG_DEBUG(LABEL, "revoke token id %{public}d permissions after %{public}d ms",
224         tokenId, DELAY_REVOKE_MILLISECONDS);
225     std::string taskName = REVOKE_TASK_PREFIX + std::to_string(tokenId);
226     secHandler_->ProxyPostTask(delayed, taskName, DELAY_REVOKE_MILLISECONDS);
227 }
228 
RevokeAppPermisionsImmediately(AccessToken::AccessTokenID tokenId)229 void SecCompPermManager::RevokeAppPermisionsImmediately(AccessToken::AccessTokenID tokenId)
230 {
231     std::lock_guard<std::mutex> lock(grantMtx_);
232     auto it = grantMap_.find(tokenId);
233     if (it == grantMap_.end()) {
234         return;
235     }
236 
237     auto& grantSet = grantMap_[tokenId];
238     for (auto iter = grantSet.begin(); iter != grantSet.end(); ++iter) {
239         int32_t res = AccessToken::AccessTokenKit::RevokePermission(tokenId, *iter,
240             AccessToken::PermissionFlag::PERMISSION_COMPONENT_SET);
241         SC_LOG_INFO(LABEL, "revoke token id %{public}d permission %{public}s res %{public}d",
242             tokenId, iter->c_str(), res);
243     }
244     grantSet.clear();
245 }
246 
CancelAppRevokingPermisions(AccessToken::AccessTokenID tokenId)247 void SecCompPermManager::CancelAppRevokingPermisions(AccessToken::AccessTokenID tokenId)
248 {
249     if (secHandler_ == nullptr) {
250         SC_LOG_ERROR(LABEL, "fail to get EventHandler");
251         return;
252     }
253 
254     SC_LOG_DEBUG(LABEL, "cancel revoke token id %{public}d permission", tokenId);
255     std::string taskName = REVOKE_TASK_PREFIX + std::to_string(tokenId);
256     secHandler_->ProxyRemoveTask(taskName);
257 }
258 
InitEventHandler(const std::shared_ptr<SecEventHandler> & secHandler)259 void SecCompPermManager::InitEventHandler(const std::shared_ptr<SecEventHandler>& secHandler)
260 {
261     secHandler_ = secHandler;
262 }
263 }  // namespace SecurityComponent
264 }  // namespace Security
265 }  // namespace OHOS
266