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