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 "el5_filekey_manager_service.h"
17
18 #include <dlfcn.h>
19
20 #ifdef COMMON_EVENT_SERVICE_ENABLE
21 #include "common_event_manager.h"
22 #include "common_event_support.h"
23 #endif
24 #include "el5_filekey_manager_error.h"
25 #include "ipc_skeleton.h"
26 #include "iservice_registry.h"
27 #ifdef THEME_SCREENLOCK_MGR_ENABLE
28 #include "screenlock_manager.h"
29 #endif
30 #include "system_ability_definition.h"
31 #include "tokenid_kit.h"
32
33 namespace OHOS {
34 namespace Security {
35 namespace AccessToken {
36 namespace {
37 const std::string PROTECT_DATA_PERMISSION = "ohos.permission.PROTECT_SCREEN_LOCK_DATA";
38 const std::string MEDIA_DATA_PERMISSION = "ohos.permission.ACCESS_SCREEN_LOCK_MEDIA_DATA";
39 const std::string ALL_DATA_PERMISSION = "ohos.permission.ACCESS_SCREEN_LOCK_ALL_DATA";
40 const std::string TASK_ID = "el5FilekeyManagerUnload";
41 const std::string STORAGE_DAEMON = "storage_daemon";
42 const std::string FOUNDATION = "foundation";
43 const std::string SET_POLICY_CALLER = "com.ohos.medialibrary.medialibrarydata";
44 constexpr uint32_t INSTALLS_UID = 3060;
45 constexpr uint32_t API_DELAY_TIME = 5 * 1000; // 5s
46 #ifdef THEME_SCREENLOCK_MGR_ENABLE
47 constexpr uint32_t SCREEN_ON_DELAY_TIME = 30 * 1000; // 30s
48 #endif
49 constexpr uint32_t USERID_MASK = 200000;
50 typedef El5FilekeyServiceExtInterface* (*GetExtInstance)(void);
51 }
52
El5FilekeyManagerService()53 El5FilekeyManagerService::El5FilekeyManagerService()
54 : serviceRunningState_(ServiceRunningState::STATE_NOT_START)
55 {
56 LOG_INFO("Instance created.");
57 }
58
~El5FilekeyManagerService()59 El5FilekeyManagerService::~El5FilekeyManagerService()
60 {
61 if (handler_) {
62 dlclose(handler_);
63 handler_ = nullptr;
64 }
65 LOG_INFO("Instance destroyed.");
66 }
67
Init()68 int32_t El5FilekeyManagerService::Init()
69 {
70 LOG_INFO("Ready to init.");
71 serviceRunningState_ = ServiceRunningState::STATE_RUNNING;
72
73 #ifdef EVENTHANDLER_ENABLE
74 auto runner = AppExecFwk::EventRunner::Create(true, AppExecFwk::ThreadMode::FFRT);
75 unloadHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
76 #endif
77
78 #ifdef COMMON_EVENT_SERVICE_ENABLE
79 if (subscriber_ == nullptr) {
80 EventFwk::MatchingSkills matchingSkills;
81 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED);
82 matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED);
83 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
84 subscriber_ = std::make_shared<El5FilekeyManagerSubscriber>(subscribeInfo);
85 bool ret = EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_);
86 if (!ret) {
87 LOG_ERROR("Subscribe common event failed.");
88 subscriber_ = nullptr;
89 }
90 }
91 #endif
92
93 #ifdef THEME_SCREENLOCK_MGR_ENABLE
94 // screen is unlocked, sa is called by USER_REMOVED, auto stop in 30s.
95 if (!ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked()) {
96 LOG_INFO("Init when screen is unlocked.");
97 PostDelayedUnloadTask(SCREEN_ON_DELAY_TIME);
98 }
99 #endif
100
101 handler_ = dlopen("/system/lib64/libel5_filekey_manager_api.z.so", RTLD_LAZY);
102 if (handler_ == nullptr) {
103 LOG_ERROR("Policy not exist, just start service.");
104 return EFM_SUCCESS;
105 }
106
107 GetExtInstance getExtInstance = reinterpret_cast<GetExtInstance>(dlsym(handler_, "GetExtInstance"));
108 if (getExtInstance == nullptr) {
109 LOG_ERROR("GetExtInstance failed.");
110 return EFM_ERR_CALL_POLICY_FAILED;
111 }
112
113 service_ = getExtInstance();
114 if (service_ == nullptr) {
115 LOG_ERROR("Ext instance is null.");
116 return EFM_ERR_CALL_POLICY_ERROR;
117 }
118
119 return EFM_SUCCESS;
120 }
121
PostDelayedUnloadTask(uint32_t delayedTime)122 void El5FilekeyManagerService::PostDelayedUnloadTask(uint32_t delayedTime)
123 {
124 #ifdef EVENTHANDLER_ENABLE
125 auto task = []() {
126 LOG_INFO("Start to unload el5_filekey_manager.");
127 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
128 if (systemAbilityManager == nullptr) {
129 LOG_ERROR("GetSystemAbilityManager is null.");
130 return;
131 }
132 int32_t ret = systemAbilityManager->UnloadSystemAbility(EL5_FILEKEY_MANAGER_SERVICE_ID);
133 if (ret != ERR_OK) {
134 LOG_ERROR("Unload el5_filekey_manager failed.");
135 return;
136 }
137 };
138 unloadHandler_->RemoveTask(TASK_ID);
139 unloadHandler_->PostTask(task, TASK_ID, delayedTime);
140 #endif
141 }
142
CancelDelayedUnloadTask()143 void El5FilekeyManagerService::CancelDelayedUnloadTask()
144 {
145 #ifdef EVENTHANDLER_ENABLE
146 unloadHandler_->RemoveTask(TASK_ID);
147 #endif
148 }
149
AcquireAccess(DataLockType type)150 int32_t El5FilekeyManagerService::AcquireAccess(DataLockType type)
151 {
152 LOG_INFO("Acquire type %{public}d.", type);
153 bool isApp = true;
154 int32_t ret = CheckReqLockPermission(type, isApp);
155 if (ret != EFM_SUCCESS) {
156 return ret;
157 }
158
159 if (service_ == nullptr) {
160 LOG_ERROR("Failed to get policy.");
161 PostDelayedUnloadTask(API_DELAY_TIME);
162 return EFM_SUCCESS;
163 }
164
165 return service_->AcquireAccess(type, isApp);
166 }
167
ReleaseAccess(DataLockType type)168 int32_t El5FilekeyManagerService::ReleaseAccess(DataLockType type)
169 {
170 LOG_INFO("Release type %{public}d.", type);
171 bool isApp = true;
172 int32_t ret = CheckReqLockPermission(type, isApp);
173 if (ret != EFM_SUCCESS) {
174 return ret;
175 }
176
177 if (service_ == nullptr) {
178 LOG_ERROR("Failed to get policy.");
179 PostDelayedUnloadTask(API_DELAY_TIME);
180 return EFM_SUCCESS;
181 }
182
183 return service_->ReleaseAccess(type, isApp);
184 }
185
GenerateAppKey(uint32_t uid,const std::string & bundleName,std::string & keyId)186 int32_t El5FilekeyManagerService::GenerateAppKey(uint32_t uid, const std::string& bundleName, std::string& keyId)
187 {
188 LOG_INFO("Generate app key for %{public}s.", bundleName.c_str());
189 if (IPCSkeleton::GetCallingUid() != INSTALLS_UID) {
190 LOG_ERROR("Generate app key permission denied.");
191 return EFM_ERR_NO_PERMISSION;
192 }
193
194 if (service_ == nullptr) {
195 LOG_ERROR("Failed to get policy.");
196 PostDelayedUnloadTask(API_DELAY_TIME);
197 return EFM_SUCCESS;
198 }
199
200 return service_->GenerateAppKey(uid, bundleName, keyId);
201 }
202
DeleteAppKey(const std::string & bundleName,int32_t userId)203 int32_t El5FilekeyManagerService::DeleteAppKey(const std::string& bundleName, int32_t userId)
204 {
205 LOG_INFO("Delete %{public}d's %{public}s app key.", userId, bundleName.c_str());
206 if (userId < 0) {
207 LOG_ERROR("UserId is invalid!");
208 return EFM_ERR_INVALID_PARAMETER;
209 }
210 if (IPCSkeleton::GetCallingUid() != INSTALLS_UID) {
211 LOG_ERROR("Delete app key permission denied.");
212 return EFM_ERR_NO_PERMISSION;
213 }
214
215 if (service_ == nullptr) {
216 LOG_ERROR("Failed to get policy.");
217 PostDelayedUnloadTask(API_DELAY_TIME);
218 return EFM_SUCCESS;
219 }
220
221 return service_->DeleteAppKey(bundleName, userId);
222 }
223
GetUserAppKey(int32_t userId,bool getAllFlag,std::vector<std::pair<int32_t,std::string>> & keyInfos)224 int32_t El5FilekeyManagerService::GetUserAppKey(int32_t userId, bool getAllFlag,
225 std::vector<std::pair<int32_t, std::string>> &keyInfos)
226 {
227 LOG_INFO("Get user %{public}d app key.", userId);
228 if (userId < 0) {
229 LOG_ERROR("UserId is invalid!");
230 return EFM_ERR_INVALID_PARAMETER;
231 }
232 if (!VerifyNativeCallingProcess(STORAGE_DAEMON, IPCSkeleton::GetCallingTokenID())) {
233 LOG_ERROR("Get user app key permission denied.");
234 return EFM_ERR_NO_PERMISSION;
235 }
236
237 if (service_ == nullptr) {
238 LOG_ERROR("Failed to get policy.");
239 PostDelayedUnloadTask(API_DELAY_TIME);
240 return EFM_SUCCESS;
241 }
242
243 return service_->GetUserAppKey(userId, getAllFlag, keyInfos);
244 }
245
ChangeUserAppkeysLoadInfo(int32_t userId,std::vector<std::pair<std::string,bool>> & loadInfos)246 int32_t El5FilekeyManagerService::ChangeUserAppkeysLoadInfo(int32_t userId,
247 std::vector<std::pair<std::string, bool>> &loadInfos)
248 {
249 LOG_INFO("Change user %{public}d load infos.", userId);
250 if (userId < 0) {
251 LOG_ERROR("UserId is invalid!");
252 return EFM_ERR_INVALID_PARAMETER;
253 }
254 if (!VerifyNativeCallingProcess(STORAGE_DAEMON, IPCSkeleton::GetCallingTokenID())) {
255 LOG_ERROR("Change user load infos permission denied.");
256 return EFM_ERR_NO_PERMISSION;
257 }
258
259 if (service_ == nullptr) {
260 LOG_ERROR("Failed to get policy.");
261 PostDelayedUnloadTask(API_DELAY_TIME);
262 return EFM_SUCCESS;
263 }
264
265 return service_->ChangeUserAppkeysLoadInfo(userId, loadInfos);
266 }
267
SetFilePathPolicy()268 int32_t El5FilekeyManagerService::SetFilePathPolicy()
269 {
270 int32_t userId = IPCSkeleton::GetCallingUid() / USERID_MASK;
271 LOG_INFO("Set user %{public}d file path policy.", userId);
272 if (!VerifyHapCallingProcess(userId, SET_POLICY_CALLER, IPCSkeleton::GetCallingTokenID())) {
273 LOG_ERROR("Set file path policy permission denied.");
274 return EFM_ERR_NO_PERMISSION;
275 }
276
277 if (service_ == nullptr) {
278 LOG_ERROR("Failed to get policy.");
279 PostDelayedUnloadTask(API_DELAY_TIME);
280 return EFM_SUCCESS;
281 }
282
283 return service_->SetFilePathPolicy(userId);
284 }
285
RegisterCallback(const sptr<El5FilekeyCallbackInterface> & callback)286 int32_t El5FilekeyManagerService::RegisterCallback(const sptr<El5FilekeyCallbackInterface> &callback)
287 {
288 LOG_INFO("Register callback.");
289 if (!VerifyNativeCallingProcess(FOUNDATION, IPCSkeleton::GetCallingTokenID())) {
290 LOG_ERROR("Register callback permission denied.");
291 return EFM_ERR_NO_PERMISSION;
292 }
293
294 if (service_ == nullptr) {
295 LOG_ERROR("Failed to get policy.");
296 PostDelayedUnloadTask(API_DELAY_TIME);
297 return EFM_SUCCESS;
298 }
299
300 return service_->RegisterCallback(callback);
301 }
302
IsSystemApp()303 bool El5FilekeyManagerService::IsSystemApp()
304 {
305 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
306 return TokenIdKit::IsSystemAppByFullTokenID(fullTokenId);
307 }
308
CheckReqLockPermission(DataLockType type,bool & isApp)309 int32_t El5FilekeyManagerService::CheckReqLockPermission(DataLockType type, bool& isApp)
310 {
311 int32_t ret = EFM_ERR_NO_PERMISSION;
312 AccessTokenID callingTokenID = IPCSkeleton::GetCallingTokenID();
313 isApp = AccessTokenKit::GetTokenType(callingTokenID) == ATokenTypeEnum::TOKEN_HAP;
314 switch (type) {
315 case DataLockType::DEFAULT_DATA:
316 if (!isApp || (AccessTokenKit::VerifyAccessToken(callingTokenID, PROTECT_DATA_PERMISSION) !=
317 PermissionState::PERMISSION_GRANTED)) {
318 LOG_ERROR("Data protection is not enabled.");
319 ret = EFM_ERR_FIND_ACCESS_FAILED;
320 } else {
321 ret = EFM_SUCCESS;
322 }
323 break;
324 case DataLockType::MEDIA_DATA:
325 if (isApp && !IsSystemApp()) {
326 ret = EFM_ERR_NOT_SYSTEM_APP;
327 LOG_ERROR("Not system app.");
328 } else {
329 if (AccessTokenKit::VerifyAccessToken(callingTokenID, MEDIA_DATA_PERMISSION) !=
330 PermissionState::PERMISSION_GRANTED) {
331 LOG_ERROR("Acquire or release type %{public}d permission denied.", type);
332 } else {
333 ret = EFM_SUCCESS;
334 }
335 }
336 break;
337 case DataLockType::ALL_DATA:
338 if (isApp && !IsSystemApp()) {
339 ret = EFM_ERR_NOT_SYSTEM_APP;
340 LOG_ERROR("Not system app.");
341 } else {
342 if (AccessTokenKit::VerifyAccessToken(callingTokenID, ALL_DATA_PERMISSION) !=
343 PermissionState::PERMISSION_GRANTED) {
344 LOG_ERROR("Acquire or release type %{public}d permission denied.", type);
345 } else {
346 ret = EFM_SUCCESS;
347 }
348 }
349 break;
350 default:
351 break;
352 }
353 return ret;
354 }
355
VerifyNativeCallingProcess(const std::string & validCaller,const AccessTokenID & callerTokenId)356 bool El5FilekeyManagerService::VerifyNativeCallingProcess(const std::string &validCaller,
357 const AccessTokenID &callerTokenId)
358 {
359 AccessTokenID tokenId = AccessTokenKit::GetNativeTokenId(validCaller);
360 return tokenId == callerTokenId;
361 }
362
VerifyHapCallingProcess(int32_t userId,const std::string & validCaller,const AccessTokenID & callerTokenId)363 bool El5FilekeyManagerService::VerifyHapCallingProcess(int32_t userId, const std::string &validCaller,
364 const AccessTokenID &callerTokenId)
365 {
366 AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(userId, validCaller, 0);
367 return tokenId == callerTokenId;
368 }
369
SetPolicyScreenLocked()370 int32_t El5FilekeyManagerService::SetPolicyScreenLocked()
371 {
372 LOG_INFO("service SetPolicyScreenLocked");
373 if (service_ == nullptr) {
374 LOG_ERROR("Failed to get policy.");
375 PostDelayedUnloadTask(API_DELAY_TIME);
376 return EFM_SUCCESS;
377 }
378 return service_->SetPolicyScreenLocked();
379 }
380
HandleUserCommonEvent(const std::string & eventName,int32_t userId)381 int32_t El5FilekeyManagerService::HandleUserCommonEvent(const std::string &eventName, int32_t userId)
382 {
383 LOG_INFO("service handle event:%{public}s userId:%{public}d", eventName.c_str(), userId);
384 if (service_ == nullptr) {
385 LOG_ERROR("Failed to get policy.");
386 PostDelayedUnloadTask(API_DELAY_TIME);
387 return EFM_SUCCESS;
388 }
389 return service_->HandleUserCommonEvent(eventName, userId);
390 }
391
Dump(int fd,const std::vector<std::u16string> & args)392 int El5FilekeyManagerService::Dump(int fd, const std::vector<std::u16string>& args)
393 {
394 LOG_INFO("El5FilekeyManager Dump");
395 if (fd < 0) {
396 return EFM_ERR_INVALID_PARAMETER;
397 }
398
399 dprintf(fd, "El5FilekeyManager Dump:\n");
400 std::string arg0 = ((args.size() == 0) ? "" : Str16ToStr8(args.at(0)));
401 if (arg0.compare("-h") == 0) {
402 dprintf(fd, "Usage:\n");
403 dprintf(fd, " -h: command help\n");
404 dprintf(fd, " -a: dump all el5 data information \n");
405 return EFM_SUCCESS;
406 }
407
408 if (service_ == nullptr) {
409 LOG_ERROR("Failed to get policy.");
410 PostDelayedUnloadTask(API_DELAY_TIME);
411 return EFM_SUCCESS;
412 }
413 LOG_INFO("start dump data");
414 service_->DumpData(fd, args);
415
416 return EFM_SUCCESS;
417 }
418 } // namespace AccessToken
419 } // namespace Security
420 } // namespace OHOS
421