• 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 "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