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