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