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