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_callback.h"
17 #include "inner_bundle_clone_common.h"
18 #include "installd_client.h"
19 #include "bundle_service_constants.h"
20 #include "bundle_constants.h"
21
22 #include <sys/stat.h>
23
24 namespace OHOS {
25 namespace AppExecFwk {
OnRegenerateAppKey(std::vector<Security::AccessToken::AppKeyInfo> & infos)26 void El5FilekeyCallback::OnRegenerateAppKey(std::vector<Security::AccessToken::AppKeyInfo> &infos)
27 {
28 APP_LOGI("el5 callback");
29 if (infos.empty()) {
30 APP_LOGE("OnRegenerateAppKey infos is empty");
31 return;
32 }
33 for (auto &info : infos) {
34 switch (info.type) {
35 case Security::AccessToken::AppKeyType::APP:
36 ProcessAppEl5Dir(info);
37 break;
38 case Security::AccessToken::AppKeyType::GROUPID:
39 ProcessGroupEl5Dir(info);
40 break;
41 }
42 }
43 }
44
ProcessAppEl5Dir(const Security::AccessToken::AppKeyInfo & info)45 void El5FilekeyCallback::ProcessAppEl5Dir(const Security::AccessToken::AppKeyInfo &info)
46 {
47 auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
48 if (dataMgr == nullptr) {
49 APP_LOGE("OnRegenerateAppKey dataMgr is nullptr");
50 return;
51 }
52 int32_t appIndex = 0;
53 std::string bundleName = info.bundleName;
54 if (info.bundleName.find(ServiceConstants::CLONE_PREFIX) == 0 &&
55 !BundleCloneCommonHelper::ParseCloneDataDir(info.bundleName, bundleName, appIndex)) {
56 APP_LOGE("parse clone name failed %{public}s", info.bundleName.c_str());
57 return;
58 }
59 InnerBundleInfo bundleInfo;
60 bool isAppExist = dataMgr->FetchInnerBundleInfo(bundleName, bundleInfo);
61 if (!isAppExist || !bundleInfo.HasInnerBundleUserInfo(info.userId)) {
62 APP_LOGE("%{public}s is not exist %{public}d", bundleName.c_str(), info.userId);
63 return;
64 }
65 if (appIndex != 0) {
66 bool isAppIndexExisted = false;
67 ErrCode res = bundleInfo.IsCloneAppIndexExisted(info.userId, appIndex, isAppIndexExisted);
68 if (res != ERR_OK || !isAppIndexExisted) {
69 APP_LOGE("appIndex is not existed");
70 return;
71 }
72 }
73 CheckEl5Dir(info, bundleInfo, bundleName);
74 std::string keyId = "";
75 EncryptionParam encryptionParam(info.bundleName, "", info.uid, info.userId, EncryptionDirType::APP);
76 auto result = InstalldClient::GetInstance()->SetEncryptionPolicy(encryptionParam, keyId);
77 if (result != ERR_OK) {
78 APP_LOGE("SetEncryptionPolicy failed for %{public}s", info.bundleName.c_str());
79 return;
80 }
81 // update the keyId to the bundleInfo
82 bundleInfo.SetkeyId(info.userId, keyId, appIndex);
83 bundleInfo.SetBundleStatus(InnerBundleInfo::BundleStatus::ENABLED);
84 if (!dataMgr->UpdateInnerBundleInfo(bundleInfo)) {
85 APP_LOGE("save keyId failed");
86 return;
87 }
88 APP_LOGI("OnRegenerateAppKey success for %{public}s", info.bundleName.c_str());
89 }
90
ProcessGroupEl5Dir(const Security::AccessToken::AppKeyInfo & info)91 void El5FilekeyCallback::ProcessGroupEl5Dir(const Security::AccessToken::AppKeyInfo &info)
92 {
93 if (info.type != Security::AccessToken::AppKeyType::GROUPID || info.uid < 0 || info.groupID.empty()) {
94 APP_LOGE("param error, type %{public}d uid %{public}d", static_cast<int32_t>(info.type), info.uid);
95 return;
96 }
97 int32_t userId = info.uid / Constants::BASE_USER_RANGE;
98 std::string parentDir = std::string(ServiceConstants::SCREEN_LOCK_FILE_DATA_PATH) +
99 ServiceConstants::PATH_SEPARATOR + std::to_string(userId);
100 bool isDirExisted = false;
101 auto result = InstalldClient::GetInstance()->IsExistDir(parentDir, isDirExisted);
102 if (result != ERR_OK || !isDirExisted) {
103 return;
104 }
105 // create el5 group dir
106 std::string dir = parentDir + ServiceConstants::DATA_GROUP_PATH + info.groupID;
107 auto mdkirRes = InstalldClient::GetInstance()->Mkdir(dir,
108 ServiceConstants::DATA_GROUP_DIR_MODE, info.uid, info.uid);
109 if (mdkirRes != ERR_OK) {
110 APP_LOGW("el5 group dir %{private}s userId %{public}d create failed",
111 info.groupID.c_str(), userId);
112 }
113 // set el5 group dirs encryption policy
114 EncryptionParam encryptionParam("", info.groupID, info.uid, userId, EncryptionDirType::GROUP);
115 std::string keyId = "";
116 auto setPolicyRes = InstalldClient::GetInstance()->SetEncryptionPolicy(encryptionParam, keyId);
117 if (setPolicyRes != ERR_OK) {
118 LOG_E(BMS_TAG_INSTALLER, "SetEncryptionPolicy failed, %{public}d", setPolicyRes);
119 }
120 }
121
CheckEl5Dir(const Security::AccessToken::AppKeyInfo & info,const InnerBundleInfo & bundleInfo,const std::string & bundleName)122 void El5FilekeyCallback::CheckEl5Dir(const Security::AccessToken::AppKeyInfo &info, const InnerBundleInfo &bundleInfo,
123 const std::string &bundleName)
124 {
125 std::string parentDir = std::string(ServiceConstants::SCREEN_LOCK_FILE_DATA_PATH) +
126 ServiceConstants::PATH_SEPARATOR + std::to_string(info.userId) + ServiceConstants::BASE;
127 bool isDirExisted = false;
128 auto result = InstalldClient::GetInstance()->IsExistDir(parentDir, isDirExisted);
129 if (result != ERR_OK || !isDirExisted) {
130 return;
131 }
132 std::string baseDir = parentDir + info.bundleName;
133 result = InstalldClient::GetInstance()->IsExistDir(baseDir, isDirExisted);
134 if (result == ERR_OK && isDirExisted) {
135 return;
136 }
137
138 int32_t mode = S_IRWXU;
139 if (InstalldClient::GetInstance()->Mkdir(baseDir, mode, info.uid, info.uid) != ERR_OK) {
140 APP_LOGW("create Screen Lock Protection dir %{public}s failed", baseDir.c_str());
141 }
142 result = InstalldClient::GetInstance()->SetDirApl(
143 baseDir, bundleName, bundleInfo.GetAppPrivilegeLevel(), bundleInfo.IsPreInstallApp(),
144 bundleInfo.GetBaseApplicationInfo().appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG);
145 if (result != ERR_OK) {
146 APP_LOGW("fail to SetDirApl dir %{public}s, error is %{public}d", baseDir.c_str(), result);
147 }
148
149 std::string databaseDir = std::string(ServiceConstants::SCREEN_LOCK_FILE_DATA_PATH) +
150 ServiceConstants::PATH_SEPARATOR + std::to_string(info.userId) + ServiceConstants::DATABASE + info.bundleName;
151 mode = S_IRWXU | S_IRWXG | S_ISGID;
152 int32_t gid = ServiceConstants::DATABASE_DIR_GID;
153 if (InstalldClient::GetInstance()->Mkdir(databaseDir, mode, info.uid, gid) != ERR_OK) {
154 APP_LOGW("create Screen Lock Protection dir %{public}s failed", databaseDir.c_str());
155 }
156 result = InstalldClient::GetInstance()->SetDirApl(
157 databaseDir, bundleName, bundleInfo.GetAppPrivilegeLevel(), bundleInfo.IsPreInstallApp(),
158 bundleInfo.GetBaseApplicationInfo().appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG);
159 if (result != ERR_OK) {
160 APP_LOGW("fail to SetDirApl dir %{public}s, error is %{public}d", databaseDir.c_str(), result);
161 }
162 }
163 } // AppExecFwk
164 } // OHOS
165