1 /*
2 * Copyright (c) 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 "password_policy_utils.h"
17
18 #include <unistd.h>
19
20 #include "cjson_check.h"
21 #include "directory_ex.h"
22 #include "edm_log.h"
23
24 namespace OHOS {
25 namespace EDM {
26 const std::string CONFIG_PATH = "/data/service/el1/public/edm/config/system/all/security/passwordPolicy.json";
27 const std::string CONFIG_SYSTEM_ALL_DIR = "/data/service/el1/public/edm/config/system/all";
28 const std::string SECURITY_DIR = "security";
29 const std::string SEPARATOR = "/";
30 constexpr int32_t EDM_UID = 3057;
31 constexpr int32_t EDM_GID = 3057;
32 const std::string COMPLEXITY_REG = "complexityReg";
33 const std::string VALIDITY_PERIOD = "validityPeriod";
34 const std::string ADDITIONAL_DESCRIPTION = "additionalDescription";
35
PasswordPolicyUtils()36 PasswordPolicyUtils::PasswordPolicyUtils()
37 {
38 EDMLOGI("PasswordPolicyUtils::PasswordPolicyUtils()");
39 std::vector<std::string> files;
40 OHOS::GetDirFiles(CONFIG_SYSTEM_ALL_DIR, files);
41 if (std::find(files.begin(), files.end(), SECURITY_DIR) == files.end()) {
42 CreateConfigDir(CONFIG_SYSTEM_ALL_DIR + SEPARATOR + SECURITY_DIR);
43 }
44 LoadConfig();
45 }
46
CreateConfigDir(const std::string & dir)47 bool PasswordPolicyUtils::CreateConfigDir(const std::string &dir)
48 {
49 EDMLOGI("PasswordPolicyUtils::CreateConfigDir");
50 if (!OHOS::ForceCreateDirectory(dir)) {
51 EDMLOGE("mkdir dir failed");
52 return false;
53 }
54 if (chown(dir.c_str(), EDM_UID, EDM_GID) != 0) {
55 EDMLOGE("fail to change dir ownership");
56 return false;
57 }
58 mode_t mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
59 if (!OHOS::ChangeModeFile(dir, mode)) {
60 EDMLOGE("change mode failed, temp install dir");
61 return false;
62 }
63 return true;
64 }
65
~PasswordPolicyUtils()66 PasswordPolicyUtils::~PasswordPolicyUtils()
67 {
68 EDMLOGI("PasswordPolicyUtils::~PasswordPolicyUtils()");
69 if (root_) {
70 cJSON_Delete(root_);
71 }
72 }
73
UpdatePasswordPolicy(PasswordPolicy & policy)74 bool PasswordPolicyUtils::UpdatePasswordPolicy(PasswordPolicy &policy)
75 {
76 EDMLOGI("PasswordPolicyUtils::UpdatePasswordPolicy()");
77 // 通用前置检查
78 if (!root_ && !LoadConfig()) {
79 EDMLOGE("Failed to load config before update protocol");
80 return false;
81 }
82 cJSON_DeleteItemFromObject(root_, COMPLEXITY_REG.c_str());
83 cJSON_DeleteItemFromObject(root_, VALIDITY_PERIOD.c_str());
84 cJSON_DeleteItemFromObject(root_, ADDITIONAL_DESCRIPTION.c_str());
85 cJSON_AddStringToObject(root_, COMPLEXITY_REG.c_str(), policy.complexityReg.c_str());
86 cJSON_AddNumberToObject(root_, VALIDITY_PERIOD.c_str(), policy.validityPeriod);
87 cJSON_AddStringToObject(root_, ADDITIONAL_DESCRIPTION.c_str(), policy.additionalDescription.c_str());
88 return SaveConfig();
89 }
90
GetPasswordPolicy(PasswordPolicy & policy)91 bool PasswordPolicyUtils::GetPasswordPolicy(PasswordPolicy &policy)
92 {
93 EDMLOGI("PasswordPolicyUtils::GetPasswordPolicy()");
94 // 通用前置检查
95 if (!root_ && !LoadConfig()) {
96 EDMLOGE("Failed to load config before update protocol");
97 return false;
98 }
99 cJSON *complexityReg = cJSON_GetObjectItem(root_, COMPLEXITY_REG.c_str());
100 cJSON *validityPeriod = cJSON_GetObjectItem(root_, VALIDITY_PERIOD.c_str());
101 cJSON *additionalDescription = cJSON_GetObjectItem(root_, ADDITIONAL_DESCRIPTION.c_str());
102 if (!cJSON_IsString(complexityReg) || !cJSON_IsNumber(validityPeriod) || !cJSON_IsString(additionalDescription)) {
103 return false;
104 }
105 policy.complexityReg = cJSON_GetStringValue(complexityReg);
106 policy.validityPeriod = cJSON_GetNumberValue(validityPeriod);
107 policy.additionalDescription = cJSON_GetStringValue(additionalDescription);
108 return true;
109 }
110
LoadConfig()111 bool PasswordPolicyUtils::LoadConfig()
112 {
113 EDMLOGI("PasswordPolicyUtils::LoadConfig");
114 std::ifstream inFile(CONFIG_PATH, std::ios::binary);
115 if (inFile.good()) {
116 EDMLOGI("PasswordPolicyUtils::LoadConfig inFile.good");
117 inFile.seekg(0, std::ios::end);
118 size_t size = static_cast<size_t>(inFile.tellg());
119 if (size == 0) {
120 inFile.close();
121 CJSON_CREATE_OBJECT_AND_CHECK(root_, false);
122 return true;
123 }
124 inFile.seekg(0, std::ios::beg);
125 std::string jsonStr(size, ' ');
126 inFile.read(&jsonStr[0], size);
127 inFile.close();
128 root_ = cJSON_Parse(jsonStr.c_str());
129 return root_ != nullptr;
130 }
131 EDMLOGI("PasswordPolicyUtils::LoadConfig inFile fail");
132 inFile.close();
133 CJSON_CREATE_OBJECT_AND_CHECK(root_, false);
134 return true;
135 }
136
SaveConfig()137 bool PasswordPolicyUtils::SaveConfig()
138 {
139 EDMLOGI("PasswordPolicyUtils::saveConfig");
140 if (!root_) {
141 EDMLOGI("PasswordPolicyUtils::SaveConfig error root is null");
142 return false;
143 }
144 char *jsonStr = cJSON_Print(root_);
145 if (!jsonStr) {
146 EDMLOGI("PasswordPolicyUtils::SaveConfig error jsonStr is null");
147 return false;
148 }
149 std::ofstream file(CONFIG_PATH);
150 if (!file.is_open()) {
151 EDMLOGI("PasswordPolicyUtils::SaveConfig open file is error");
152 cJSON_free(jsonStr);
153 return false;
154 }
155 file << jsonStr;
156 file.close();
157 cJSON_free(jsonStr);
158 return true;
159 }
160 } // namespace EDM
161 } // namespace OHOS