• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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