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_callback.h"
17 #include "installd_client.h"
18 #include "bundle_service_constants.h"
19 #include "bundle_constants.h"
20 
21 #include <sys/stat.h>
22 
23 namespace OHOS {
24 namespace AppExecFwk {
OnRegenerateAppKey(std::vector<Security::AccessToken::AppKeyInfo> & infos)25 void El5FilekeyCallback::OnRegenerateAppKey(std::vector<Security::AccessToken::AppKeyInfo> &infos)
26 {
27     APP_LOGI("el5 callback");
28     if (infos.empty()) {
29         APP_LOGE("OnRegenerateAppKey infos is empty");
30         return;
31     }
32     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
33     if (dataMgr == nullptr) {
34         APP_LOGE("OnRegenerateAppKey dataMgr is nullptr");
35         return;
36     }
37     for (auto &info : infos) {
38         InnerBundleInfo bundleInfo;
39         bool isAppExist = dataMgr->FetchInnerBundleInfo(info.bundleName, bundleInfo);
40         if (!isAppExist) {
41             APP_LOGE("OnRegenerateAppKey bundleInfo is not exist");
42             continue;
43         }
44         CheckEl5Dir(info, bundleInfo);
45         std::string keyId = "";
46         auto result = InstalldClient::GetInstance()->SetEncryptionPolicy(
47             info.uid, info.bundleName, info.userId, keyId);
48         if (result != ERR_OK) {
49             APP_LOGE("SetEncryptionPolicy failed for %{public}s", info.bundleName.c_str());
50         }
51         // update the keyId to the bundleInfo
52         bundleInfo.SetkeyId(info.userId, keyId);
53         if (!dataMgr->UpdateInnerBundleInfo(bundleInfo)) {
54             APP_LOGE("save keyId failed");
55             continue;
56         }
57         APP_LOGI("OnRegenerateAppKey success for %{public}s", info.bundleName.c_str());
58     }
59 }
60 
CheckEl5Dir(Security::AccessToken::AppKeyInfo & info,const InnerBundleInfo & bundleInfo)61 void El5FilekeyCallback::CheckEl5Dir(Security::AccessToken::AppKeyInfo &info, const InnerBundleInfo &bundleInfo)
62 {
63     std::string parentDir = std::string(ServiceConstants::SCREEN_LOCK_FILE_DATA_PATH) +
64         ServiceConstants::PATH_SEPARATOR + std::to_string(info.userId) + ServiceConstants::BASE;
65     bool isDirExisted = false;
66     auto result = InstalldClient::GetInstance()->IsExistDir(parentDir, isDirExisted);
67     if (result != ERR_OK || !isDirExisted) {
68         return;
69     }
70     std::string baseDir = parentDir + info.bundleName;
71     result = InstalldClient::GetInstance()->IsExistDir(baseDir, isDirExisted);
72     if (result == ERR_OK && isDirExisted) {
73         return;
74     }
75 
76     int32_t mode = S_IRWXU;
77     if (InstalldClient::GetInstance()->Mkdir(baseDir, mode, info.uid, info.uid) != ERR_OK) {
78         APP_LOGW("create Screen Lock Protection dir %{public}s failed", baseDir.c_str());
79     }
80     result = InstalldClient::GetInstance()->SetDirApl(
81         baseDir, info.bundleName, bundleInfo.GetAppPrivilegeLevel(), bundleInfo.IsPreInstallApp(),
82         bundleInfo.GetBaseApplicationInfo().appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG);
83     if (result != ERR_OK) {
84         APP_LOGW("fail to SetDirApl dir %{public}s, error is %{public}d", baseDir.c_str(), result);
85     }
86 
87     std::string databaseDir = std::string(ServiceConstants::SCREEN_LOCK_FILE_DATA_PATH) +
88         ServiceConstants::PATH_SEPARATOR + std::to_string(info.userId) + ServiceConstants::DATABASE + info.bundleName;
89     mode = S_IRWXU | S_IRWXG | S_ISGID;
90     int32_t gid = ServiceConstants::DATABASE_DIR_GID;
91     if (InstalldClient::GetInstance()->Mkdir(databaseDir, mode, info.uid, gid) != ERR_OK) {
92         APP_LOGW("create Screen Lock Protection dir %{public}s failed", databaseDir.c_str());
93     }
94     result = InstalldClient::GetInstance()->SetDirApl(
95         databaseDir, info.bundleName, bundleInfo.GetAppPrivilegeLevel(), bundleInfo.IsPreInstallApp(),
96         bundleInfo.GetBaseApplicationInfo().appProvisionType == Constants::APP_PROVISION_TYPE_DEBUG);
97     if (result != ERR_OK) {
98         APP_LOGW("fail to SetDirApl dir %{public}s, error is %{public}d", databaseDir.c_str(), result);
99     }
100 }
101 } // AppExecFwk
102 } // OHOS
103