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 "global_config_file_manager.h"
17 
18 #include "securec.h"
19 
20 #include "adaptor_file.h"
21 #include "adaptor_log.h"
22 #include "adaptor_memory.h"
23 #include "defines.h"
24 #include "file_manager_utils.h"
25 
26 #define GLOBAL_CONFIG_INFO "/data/service/el1/public/userauth/globalConfigInfo"
27 #define VERSION 0
28 
29 #ifdef IAM_TEST_ENABLE
30 #define IAM_STATIC
31 #else
32 #define IAM_STATIC static
33 #endif
34 
StreamWriteGlobalConfig(Buffer *parcel, GlobalConfigInfo *configInfo)35 IAM_STATIC bool StreamWriteGlobalConfig(Buffer *parcel, GlobalConfigInfo *configInfo)
36 {
37     if (StreamWrite(parcel, &(configInfo->type), sizeof(int32_t)) != RESULT_SUCCESS) {
38         LOG_ERROR("StreamWrite global config type failed");
39         return false;
40     }
41     switch (configInfo->type) {
42         case PIN_EXPIRED_PERIOD:
43             if (StreamWrite(parcel, &(configInfo->value.pinExpiredPeriod),
44                 sizeof(configInfo->value.pinExpiredPeriod)) != RESULT_SUCCESS) {
45                 LOG_ERROR("StreamWrite pinExpiredPeriod failed");
46                 return false;
47             }
48             break;
49         case ENABLE_STATUS:
50             {
51                 uint8_t enableStatus = configInfo->value.enableStatus ? 1 : 0;
52                 if (StreamWrite(parcel, &enableStatus, sizeof(uint8_t)) != RESULT_SUCCESS) {
53                     LOG_ERROR("StreamWrite enableStatus failed");
54                     return false;
55                 }
56                 break;
57             }
58         default:
59             LOG_ERROR("globalConfigType not support, type:%{public}d.", configInfo->type);
60             return false;
61     }
62     if (StreamWrite(parcel, &(configInfo->authType), sizeof(uint32_t)) != RESULT_SUCCESS) {
63         LOG_ERROR("StreamWrite authType failed");
64         return false;
65     }
66     if (StreamWrite(parcel, &(configInfo->userIdNum), sizeof(uint32_t)) != RESULT_SUCCESS ||
67         configInfo->userIdNum > MAX_USER) {
68         LOG_ERROR("StreamWrite userIdNum failed");
69         return false;
70     }
71     if (configInfo->userIdNum != 0 &&
72         StreamWrite(parcel, configInfo->userIds, (sizeof(int32_t) * configInfo->userIdNum)) != RESULT_SUCCESS) {
73         LOG_ERROR("StreamWrite userIds failed");
74         return false;
75     }
76     return true;
77 }
78 
CheckGlobalConfigType(int32_t type)79 IAM_STATIC bool CheckGlobalConfigType(int32_t type)
80 {
81     if (type != PIN_EXPIRED_PERIOD && type != ENABLE_STATUS) {
82         LOG_ERROR("skip type %{public}d, and delete the globalConfig", type);
83         return false;
84     }
85     return true;
86 }
87 
UpdateGlobalConfigFile(GlobalConfigInfo *globalConfigArray, uint32_t configInfoNum)88 ResultCode UpdateGlobalConfigFile(GlobalConfigInfo *globalConfigArray, uint32_t configInfoNum)
89 {
90     LOG_INFO("start");
91     if (globalConfigArray == NULL) {
92         LOG_ERROR("globalConfigArray is null");
93         return RESULT_BAD_PARAM;
94     }
95     FileOperator *fileOperator = GetFileOperator(DEFAULT_FILE_OPERATOR);
96     if (!IsFileOperatorValid(fileOperator)) {
97         LOG_ERROR("invalid file operation");
98         return RESULT_GENERAL_ERROR;
99     }
100 
101     int32_t configInfoSize = sizeof(uint32_t) * 2 + sizeof(GlobalConfigInfo) * MAX_GLOBAL_CONFIG_NUM;
102     Buffer *parcel = CreateBufferBySize(configInfoSize);
103     if (parcel == NULL) {
104         LOG_ERROR("parcel is null");
105         return RESULT_BAD_PARAM;
106     }
107     uint32_t version = VERSION;
108     ResultCode ret = StreamWrite(parcel, &version, sizeof(uint32_t));
109     if (ret != RESULT_SUCCESS) {
110         LOG_ERROR("StreamWrite failed");
111         DestoryBuffer(parcel);
112         return RESULT_GENERAL_ERROR;
113     }
114     ret = StreamWrite(parcel, &configInfoNum, sizeof(uint32_t));
115     if (ret != RESULT_SUCCESS) {
116         LOG_ERROR("StreamWrite failed");
117         DestoryBuffer(parcel);
118         return RESULT_GENERAL_ERROR;
119     }
120     for (uint32_t i = 0; i < configInfoNum; i++) {
121         if (CheckGlobalConfigType(globalConfigArray[i].type) &&
122             !StreamWriteGlobalConfig(parcel, &globalConfigArray[i])) {
123             LOG_ERROR("StreamWriteGlobalConfig failed");
124             DestoryBuffer(parcel);
125             return RESULT_GENERAL_ERROR;
126         }
127     }
128     // This is for example only. Should be implemented in trusted environment.
129     ret = (ResultCode)fileOperator->writeFile(GLOBAL_CONFIG_INFO, parcel->buf, parcel->contentSize);
130     if (ret != RESULT_SUCCESS) {
131         LOG_ERROR("write file failed, %{public}u", parcel->contentSize);
132     }
133     DestoryBuffer(parcel);
134     return ret;
135 }
136 
ReadGlobalConfigFile(FileOperator *fileOperator)137 IAM_STATIC Buffer *ReadGlobalConfigFile(FileOperator *fileOperator)
138 {
139     uint32_t fileSize;
140     int32_t ret = fileOperator->getFileLen(GLOBAL_CONFIG_INFO, &fileSize);
141     if (ret != RESULT_SUCCESS) {
142         LOG_ERROR("open file failed");
143         return NULL;
144     }
145     Buffer *parcel = CreateBufferBySize(fileSize);
146     if (parcel == NULL) {
147         LOG_ERROR("parcel create failed");
148         return NULL;
149     }
150     if (fileOperator->readFile(GLOBAL_CONFIG_INFO, parcel->buf, parcel->maxSize) != RESULT_SUCCESS) {
151         LOG_ERROR("read failed");
152         DestoryBuffer(parcel);
153         return NULL;
154     }
155     parcel->contentSize = fileSize;
156     return parcel;
157 }
158 
StreamReadGlobalConfig(Buffer *parcel, uint32_t *index, GlobalConfigInfo *configInfo)159 IAM_STATIC bool StreamReadGlobalConfig(Buffer *parcel, uint32_t *index, GlobalConfigInfo *configInfo)
160 {
161     if (StreamRead(parcel, index, &(configInfo->type), sizeof(int32_t)) != RESULT_SUCCESS) {
162         LOG_ERROR("read globalConfig type failed");
163         return false;
164     }
165     switch (configInfo->type) {
166         case PIN_EXPIRED_PERIOD:
167             if (StreamRead(parcel, index, &(configInfo->value.pinExpiredPeriod), sizeof(int64_t)) != RESULT_SUCCESS) {
168                 LOG_ERROR("read pinExpiredPeriod failed");
169                 return false;
170             }
171             break;
172         case ENABLE_STATUS:
173             {
174                 uint8_t enableStatus = 0;
175                 if (StreamRead(parcel, index, &enableStatus, sizeof(uint8_t)) != RESULT_SUCCESS) {
176                     LOG_ERROR("read enableStatus failed");
177                     return false;
178                 }
179                 configInfo->value.enableStatus = (enableStatus != 0) ? true : false;
180             }
181             break;
182         default:
183             LOG_ERROR("globalConfigType not support, type:%{public}d.", configInfo->type);
184             return false;
185     }
186     if (StreamRead(parcel, index, &(configInfo->authType), sizeof(uint32_t)) != RESULT_SUCCESS) {
187         LOG_ERROR("read authType failed");
188         return false;
189     }
190     if (StreamRead(parcel, index, &(configInfo->userIdNum), sizeof(uint32_t)) != RESULT_SUCCESS ||
191         configInfo->userIdNum > MAX_USER) {
192         LOG_ERROR("read userIdNum failed");
193         return false;
194     }
195     if (configInfo->userIdNum != 0 &&
196         StreamRead(parcel, index, configInfo->userIds, (sizeof(int32_t) * configInfo->userIdNum)) != RESULT_SUCCESS) {
197         LOG_ERROR("read userIds failed");
198         return false;
199     }
200     return true;
201 }
202 
ReadGlobalConfigInfo(Buffer *parcel, GlobalConfigInfo *globalConfigInfo, uint32_t *configInfoNum, uint32_t maxNum)203 IAM_STATIC ResultCode ReadGlobalConfigInfo(Buffer *parcel, GlobalConfigInfo *globalConfigInfo,
204     uint32_t *configInfoNum, uint32_t maxNum)
205 {
206     uint32_t index = 0;
207     uint32_t version = 0;
208     ResultCode result = StreamRead(parcel, &index, &version, sizeof(uint32_t));
209     if (result != RESULT_SUCCESS) {
210         LOG_ERROR("read version failed");
211         return RESULT_GENERAL_ERROR;
212     }
213     result = StreamRead(parcel, &index, configInfoNum, sizeof(uint32_t));
214     if (result != RESULT_SUCCESS || (*configInfoNum) > maxNum) {
215         LOG_ERROR("read configInfoNum failed");
216         return RESULT_GENERAL_ERROR;
217     }
218     for (uint32_t i = 0; i < (*configInfoNum); i++) {
219         if (!StreamReadGlobalConfig(parcel, &index, &globalConfigInfo[i])) {
220             LOG_ERROR("read StreamReadGlobalConfig failed");
221             return RESULT_GENERAL_ERROR;
222         }
223     }
224     return RESULT_SUCCESS;
225 }
226 
LoadGlobalConfigInfo(GlobalConfigInfo *globalConfigArray, uint32_t len, uint32_t *configInfoNum)227 ResultCode LoadGlobalConfigInfo(GlobalConfigInfo *globalConfigArray, uint32_t len, uint32_t *configInfoNum)
228 {
229     LOG_INFO("start");
230     if (globalConfigArray == NULL || configInfoNum == NULL) {
231         LOG_ERROR("bad param");
232         return RESULT_BAD_PARAM;
233     }
234     (void)memset_s(globalConfigArray, sizeof(GlobalConfigInfo) * len, 0, sizeof(GlobalConfigInfo) * len);
235     *configInfoNum = 0;
236     FileOperator *fileOperator = GetFileOperator(DEFAULT_FILE_OPERATOR);
237     if (!IsFileOperatorValid(fileOperator)) {
238         LOG_ERROR("invalid file operation");
239         return RESULT_GENERAL_ERROR;
240     }
241     if (!fileOperator->isFileExist(GLOBAL_CONFIG_INFO)) {
242         LOG_ERROR("file is not exist");
243         *configInfoNum = 0;
244         return RESULT_SUCCESS;
245     }
246     Buffer *parcel = ReadGlobalConfigFile(fileOperator);
247     if (parcel == NULL) {
248         LOG_ERROR("ReadGlobalConfigFile failed");
249         return RESULT_GENERAL_ERROR;
250     }
251     ResultCode ret = ReadGlobalConfigInfo(parcel, globalConfigArray, configInfoNum, len);
252     if (ret != RESULT_SUCCESS) {
253         LOG_ERROR("ReadGlobalConfigInfo failed");
254         DestoryBuffer(parcel);
255         (void)memset_s(globalConfigArray, sizeof(GlobalConfigInfo) * len, 0, sizeof(GlobalConfigInfo) * len);
256         *configInfoNum = 0;
257         return ret;
258     }
259     DestoryBuffer(parcel);
260     return RESULT_SUCCESS;
261 }
262