• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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