114cf0368Sopenharmony_ci/* 214cf0368Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 314cf0368Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 414cf0368Sopenharmony_ci * you may not use this file except in compliance with the License. 514cf0368Sopenharmony_ci * You may obtain a copy of the License at 614cf0368Sopenharmony_ci * 714cf0368Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 814cf0368Sopenharmony_ci * 914cf0368Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1014cf0368Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1114cf0368Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1214cf0368Sopenharmony_ci * See the License for the specific language governing permissions and 1314cf0368Sopenharmony_ci * limitations under the License. 1414cf0368Sopenharmony_ci */ 1514cf0368Sopenharmony_ci#define LOG_TAG "CustomUtdStore" 1614cf0368Sopenharmony_ci#include "custom_utd_store.h" 1714cf0368Sopenharmony_ci#include <fstream> 1814cf0368Sopenharmony_ci#include <sys/stat.h> 1914cf0368Sopenharmony_ci#include "logger.h" 2014cf0368Sopenharmony_ci#include "preset_type_descriptors.h" 2114cf0368Sopenharmony_ci#include "unistd.h" 2214cf0368Sopenharmony_ci#include "utd_cfgs_checker.h" 2314cf0368Sopenharmony_ci#include "utd_graph.h" 2414cf0368Sopenharmony_ci#ifdef WITH_SELINUX 2514cf0368Sopenharmony_ci#include <policycoreutils.h> 2614cf0368Sopenharmony_ci#endif 2714cf0368Sopenharmony_cinamespace OHOS { 2814cf0368Sopenharmony_cinamespace UDMF { 2914cf0368Sopenharmony_ciconstexpr const char* UTD_CFG_FILE = "utd-adt.json"; 3014cf0368Sopenharmony_ciconstexpr const char* CUSTOM_UTD_HAP_DIR = "/data/utd/utd-adt.json"; 3114cf0368Sopenharmony_ciconstexpr const char* CUSTOM_UTD_SA_DIR = "/data/service/el1/"; 3214cf0368Sopenharmony_ciconstexpr const char* OLD_CUSTOM_UTD_SA_SUB_DIR = "/distributeddata/utd/"; 3314cf0368Sopenharmony_ciconstexpr const char* CUSTOM_UTD_SA_SUB_DIR = "/utdtypes/utd/"; 3414cf0368Sopenharmony_ci 3514cf0368Sopenharmony_ciCustomUtdStore::CustomUtdStore() 3614cf0368Sopenharmony_ci{ 3714cf0368Sopenharmony_ci} 3814cf0368Sopenharmony_ci 3914cf0368Sopenharmony_ciCustomUtdStore::~CustomUtdStore() 4014cf0368Sopenharmony_ci{ 4114cf0368Sopenharmony_ci} 4214cf0368Sopenharmony_ci 4314cf0368Sopenharmony_ciCustomUtdStore &CustomUtdStore::GetInstance() 4414cf0368Sopenharmony_ci{ 4514cf0368Sopenharmony_ci static CustomUtdStore utdCustomPersistence; 4614cf0368Sopenharmony_ci return utdCustomPersistence; 4714cf0368Sopenharmony_ci} 4814cf0368Sopenharmony_ci 4914cf0368Sopenharmony_cistd::vector<TypeDescriptorCfg> CustomUtdStore::GetHapTypeCfgs() 5014cf0368Sopenharmony_ci{ 5114cf0368Sopenharmony_ci LOG_DEBUG(UDMF_CLIENT, "get utdcustom from cfg, Path:%{public}s.", CUSTOM_UTD_HAP_DIR); 5214cf0368Sopenharmony_ci std::string jsonStr; 5314cf0368Sopenharmony_ci std::ifstream fin(CUSTOM_UTD_HAP_DIR); 5414cf0368Sopenharmony_ci while (fin.good()) { 5514cf0368Sopenharmony_ci std::string line; 5614cf0368Sopenharmony_ci std::getline(fin, line); 5714cf0368Sopenharmony_ci jsonStr += line; 5814cf0368Sopenharmony_ci } 5914cf0368Sopenharmony_ci std::vector<TypeDescriptorCfg> customUtdTypes; 6014cf0368Sopenharmony_ci utdJsonParser_.ParseStoredCustomUtdJson(jsonStr, customUtdTypes); 6114cf0368Sopenharmony_ci LOG_DEBUG(UDMF_CLIENT, "GetTypeCfgs, customUtdTypes total:%{public}zu.", customUtdTypes.size()); 6214cf0368Sopenharmony_ci return customUtdTypes; 6314cf0368Sopenharmony_ci} 6414cf0368Sopenharmony_ci 6514cf0368Sopenharmony_cistd::vector<TypeDescriptorCfg> CustomUtdStore::GetTypeCfgs(int32_t userId) 6614cf0368Sopenharmony_ci{ 6714cf0368Sopenharmony_ci std::string path = CUSTOM_UTD_SA_DIR + std::to_string(userId) + CUSTOM_UTD_SA_SUB_DIR; 6814cf0368Sopenharmony_ci std::string old_path = CUSTOM_UTD_SA_DIR + std::to_string(userId) + OLD_CUSTOM_UTD_SA_SUB_DIR; 6914cf0368Sopenharmony_ci std::string cfgFilePath = path; 7014cf0368Sopenharmony_ci if (access(path.c_str(), F_OK) != 0 && access(old_path.c_str(), F_OK) == 0) { 7114cf0368Sopenharmony_ci cfgFilePath = old_path; 7214cf0368Sopenharmony_ci } 7314cf0368Sopenharmony_ci cfgFilePath.append(UTD_CFG_FILE); 7414cf0368Sopenharmony_ci LOG_DEBUG(UDMF_CLIENT, "get utdcustom from cfg, Path:%{public}s.", cfgFilePath.c_str()); 7514cf0368Sopenharmony_ci std::string jsonStr; 7614cf0368Sopenharmony_ci std::ifstream fin(cfgFilePath); 7714cf0368Sopenharmony_ci while (fin.good()) { 7814cf0368Sopenharmony_ci std::string line; 7914cf0368Sopenharmony_ci std::getline(fin, line); 8014cf0368Sopenharmony_ci jsonStr += line; 8114cf0368Sopenharmony_ci } 8214cf0368Sopenharmony_ci std::vector<TypeDescriptorCfg> customUtdTypes; 8314cf0368Sopenharmony_ci utdJsonParser_.ParseStoredCustomUtdJson(jsonStr, customUtdTypes); 8414cf0368Sopenharmony_ci LOG_DEBUG(UDMF_CLIENT, "GetTypeCfgs, customUtdTypes total:%{public}zu.", customUtdTypes.size()); 8514cf0368Sopenharmony_ci return customUtdTypes; 8614cf0368Sopenharmony_ci} 8714cf0368Sopenharmony_ci 8814cf0368Sopenharmony_ciint32_t CustomUtdStore::SaveTypeCfgs(const std::vector<TypeDescriptorCfg> &customUtdTypes, int32_t user) 8914cf0368Sopenharmony_ci{ 9014cf0368Sopenharmony_ci LOG_DEBUG(UDMF_CLIENT, "customUtdTypes total:%{public}zu.", customUtdTypes.size()); 9114cf0368Sopenharmony_ci std::string jsonData; 9214cf0368Sopenharmony_ci std::string cfgFileDir = CUSTOM_UTD_SA_DIR + std::to_string(user) + CUSTOM_UTD_SA_SUB_DIR; 9314cf0368Sopenharmony_ci if (utdJsonParser_.ConvertUtdCfgsToJson(customUtdTypes, jsonData) && CreateDirectory(cfgFileDir)) { 9414cf0368Sopenharmony_ci SavaCfgFile(jsonData, cfgFileDir.append(UTD_CFG_FILE)); 9514cf0368Sopenharmony_ci } 9614cf0368Sopenharmony_ci return 0; 9714cf0368Sopenharmony_ci} 9814cf0368Sopenharmony_ci 9914cf0368Sopenharmony_ciint32_t CustomUtdStore::SavaCfgFile(const std::string &jsonData, const std::string &cfgFilePath) 10014cf0368Sopenharmony_ci{ 10114cf0368Sopenharmony_ci std::ofstream ofs; 10214cf0368Sopenharmony_ci LOG_DEBUG(UDMF_CLIENT, "set cfg start, path:%{public}s ", cfgFilePath.c_str()); 10314cf0368Sopenharmony_ci ofs.open(cfgFilePath, 0x02); 10414cf0368Sopenharmony_ci if (!ofs.is_open()) { 10514cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "open cfg failed, path:%{public}s", cfgFilePath.c_str()); 10614cf0368Sopenharmony_ci } 10714cf0368Sopenharmony_ci ofs << jsonData << std::endl; 10814cf0368Sopenharmony_ci ofs.close(); 10914cf0368Sopenharmony_ci LOG_DEBUG(UDMF_CLIENT, "set cfg end."); 11014cf0368Sopenharmony_ci return 0; 11114cf0368Sopenharmony_ci} 11214cf0368Sopenharmony_ci 11314cf0368Sopenharmony_cibool CustomUtdStore::CreateDirectory(const std::string &path) const 11414cf0368Sopenharmony_ci{ 11514cf0368Sopenharmony_ci LOG_DEBUG(UDMF_CLIENT, "CreateDirectory start, path:%{public}s ", path.c_str()); 11614cf0368Sopenharmony_ci if (access(path.c_str(), F_OK) == 0) { 11714cf0368Sopenharmony_ci return true; 11814cf0368Sopenharmony_ci } 11914cf0368Sopenharmony_ci 12014cf0368Sopenharmony_ci std::string::size_type index = 0; 12114cf0368Sopenharmony_ci do { 12214cf0368Sopenharmony_ci std::string subPath; 12314cf0368Sopenharmony_ci index = path.find('/', index + 1); 12414cf0368Sopenharmony_ci if (index == std::string::npos) { 12514cf0368Sopenharmony_ci subPath = path; 12614cf0368Sopenharmony_ci } else { 12714cf0368Sopenharmony_ci subPath = path.substr(0, index); 12814cf0368Sopenharmony_ci } 12914cf0368Sopenharmony_ci 13014cf0368Sopenharmony_ci if (access(subPath.c_str(), F_OK) != 0) { 13114cf0368Sopenharmony_ci if (mkdir(subPath.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0) { 13214cf0368Sopenharmony_ci LOG_WARN(UDMF_CLIENT, "CreateDirectory, fail. path:%{public}s, subPath:%{public}s.", 13314cf0368Sopenharmony_ci path.c_str(), subPath.c_str()); 13414cf0368Sopenharmony_ci return false; 13514cf0368Sopenharmony_ci } 13614cf0368Sopenharmony_ci } 13714cf0368Sopenharmony_ci } while (index != std::string::npos); 13814cf0368Sopenharmony_ci 13914cf0368Sopenharmony_ci if (access(path.c_str(), F_OK) == 0) { 14014cf0368Sopenharmony_ci#ifdef WITH_SELINUX 14114cf0368Sopenharmony_ci Restorecon(path.c_str()); 14214cf0368Sopenharmony_ci#endif 14314cf0368Sopenharmony_ci return true; 14414cf0368Sopenharmony_ci } 14514cf0368Sopenharmony_ci 14614cf0368Sopenharmony_ci return false; 14714cf0368Sopenharmony_ci} 14814cf0368Sopenharmony_ci 14914cf0368Sopenharmony_cibool CustomUtdStore::InstallCustomUtds(const std::string &bundleName, const std::string &jsonStr, 15014cf0368Sopenharmony_ci int32_t user, std::vector<TypeDescriptorCfg> &customTyepCfgs) 15114cf0368Sopenharmony_ci{ 15214cf0368Sopenharmony_ci CustomUtdCfgs typeCfgs; 15314cf0368Sopenharmony_ci if (!utdJsonParser_.ParseUserCustomUtdJson(jsonStr, typeCfgs.first, typeCfgs.second)) { 15414cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "Parse json failed. bundleName:%{public}s", bundleName.c_str()); 15514cf0368Sopenharmony_ci return false; 15614cf0368Sopenharmony_ci } 15714cf0368Sopenharmony_ci std::vector<TypeDescriptorCfg> presetTypes = PresetTypeDescriptors::GetInstance().GetPresetTypes(); 15814cf0368Sopenharmony_ci 15914cf0368Sopenharmony_ci if (!UtdCfgsChecker::GetInstance().CheckTypeDescriptors( 16014cf0368Sopenharmony_ci typeCfgs, presetTypes, customTyepCfgs, bundleName)) { 16114cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "check type descriptors failed, bundleName:%{public}s", bundleName.c_str()); 16214cf0368Sopenharmony_ci return false; 16314cf0368Sopenharmony_ci } 16414cf0368Sopenharmony_ci 16514cf0368Sopenharmony_ci ProcessUtdForSave(typeCfgs, customTyepCfgs, bundleName); 16614cf0368Sopenharmony_ci if (CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, user) != E_OK) { 16714cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "Save failed, bundleName: %{public}s", bundleName.c_str()); 16814cf0368Sopenharmony_ci return false; 16914cf0368Sopenharmony_ci } 17014cf0368Sopenharmony_ci return true; 17114cf0368Sopenharmony_ci} 17214cf0368Sopenharmony_ci 17314cf0368Sopenharmony_cibool CustomUtdStore::UninstallCustomUtds(const std::string &bundleName, int32_t user, 17414cf0368Sopenharmony_ci std::vector<TypeDescriptorCfg> &customTyepCfgs) 17514cf0368Sopenharmony_ci{ 17614cf0368Sopenharmony_ci for (auto iter = customTyepCfgs.begin(); iter != customTyepCfgs.end();) { 17714cf0368Sopenharmony_ci auto it = find(iter->installerBundles.begin(), iter->installerBundles.end(), bundleName); 17814cf0368Sopenharmony_ci if (it != iter->installerBundles.end()) { 17914cf0368Sopenharmony_ci iter->installerBundles.erase(it); 18014cf0368Sopenharmony_ci } 18114cf0368Sopenharmony_ci if (iter->installerBundles.empty()) { 18214cf0368Sopenharmony_ci iter = customTyepCfgs.erase(iter); 18314cf0368Sopenharmony_ci } else { 18414cf0368Sopenharmony_ci iter++; 18514cf0368Sopenharmony_ci } 18614cf0368Sopenharmony_ci } 18714cf0368Sopenharmony_ci std::vector<TypeDescriptorCfg> presetTypes = PresetTypeDescriptors::GetInstance().GetPresetTypes(); 18814cf0368Sopenharmony_ci if (!UtdCfgsChecker::GetInstance().CheckBelongingToTypes(customTyepCfgs, presetTypes)) { 18914cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "belongingToTypes check failed. bundleName:%{public}s", bundleName.c_str()); 19014cf0368Sopenharmony_ci return false; 19114cf0368Sopenharmony_ci } 19214cf0368Sopenharmony_ci if (CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, user) != E_OK) { 19314cf0368Sopenharmony_ci LOG_ERROR(UDMF_CLIENT, "Save type cfgs failed, bundleName: %{public}s", bundleName.c_str()); 19414cf0368Sopenharmony_ci return false; 19514cf0368Sopenharmony_ci } 19614cf0368Sopenharmony_ci return true; 19714cf0368Sopenharmony_ci} 19814cf0368Sopenharmony_ci 19914cf0368Sopenharmony_civoid CustomUtdStore::ProcessUtdForSave(const CustomUtdCfgs &utdTypes, std::vector<TypeDescriptorCfg> &customTyepCfgs, 20014cf0368Sopenharmony_ci const std::string &bundleName) 20114cf0368Sopenharmony_ci{ 20214cf0368Sopenharmony_ci for (TypeDescriptorCfg declarationType : utdTypes.first) { 20314cf0368Sopenharmony_ci for (auto iter = customTyepCfgs.begin(); iter != customTyepCfgs.end();) { 20414cf0368Sopenharmony_ci if (iter->typeId == declarationType.typeId) { 20514cf0368Sopenharmony_ci declarationType.installerBundles = iter->installerBundles; 20614cf0368Sopenharmony_ci iter = customTyepCfgs.erase(iter); 20714cf0368Sopenharmony_ci } else { 20814cf0368Sopenharmony_ci iter++; 20914cf0368Sopenharmony_ci } 21014cf0368Sopenharmony_ci } 21114cf0368Sopenharmony_ci declarationType.installerBundles.emplace(bundleName); 21214cf0368Sopenharmony_ci declarationType.ownerBundle = bundleName; 21314cf0368Sopenharmony_ci customTyepCfgs.push_back(declarationType); 21414cf0368Sopenharmony_ci } 21514cf0368Sopenharmony_ci for (TypeDescriptorCfg referenceType : utdTypes.second) { 21614cf0368Sopenharmony_ci bool found = false; 21714cf0368Sopenharmony_ci for (auto &typeCfg : customTyepCfgs) { 21814cf0368Sopenharmony_ci if (typeCfg.typeId == referenceType.typeId) { 21914cf0368Sopenharmony_ci typeCfg.installerBundles.emplace(bundleName); 22014cf0368Sopenharmony_ci found = true; 22114cf0368Sopenharmony_ci break; 22214cf0368Sopenharmony_ci } 22314cf0368Sopenharmony_ci } 22414cf0368Sopenharmony_ci if (!found) { 22514cf0368Sopenharmony_ci referenceType.installerBundles.emplace(bundleName); 22614cf0368Sopenharmony_ci customTyepCfgs.push_back(referenceType); 22714cf0368Sopenharmony_ci } 22814cf0368Sopenharmony_ci } 22914cf0368Sopenharmony_ci} 23014cf0368Sopenharmony_ci} // namespace UDMF 23114cf0368Sopenharmony_ci} // namespace OHOS