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