1fc0b0055Sopenharmony_ci/*
2fc0b0055Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3fc0b0055Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fc0b0055Sopenharmony_ci * you may not use this file except in compliance with the License.
5fc0b0055Sopenharmony_ci * You may obtain a copy of the License at
6fc0b0055Sopenharmony_ci *
7fc0b0055Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fc0b0055Sopenharmony_ci *
9fc0b0055Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fc0b0055Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fc0b0055Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fc0b0055Sopenharmony_ci * See the License for the specific language governing permissions and
13fc0b0055Sopenharmony_ci * limitations under the License.
14fc0b0055Sopenharmony_ci */
15fc0b0055Sopenharmony_ci
16fc0b0055Sopenharmony_ci#include "json_parser.h"
17fc0b0055Sopenharmony_ci
18fc0b0055Sopenharmony_ci#include <fcntl.h>
19fc0b0055Sopenharmony_ci#include <memory>
20fc0b0055Sopenharmony_ci#include <sys/stat.h>
21fc0b0055Sopenharmony_ci#include <sys/types.h>
22fc0b0055Sopenharmony_ci#include <unistd.h>
23fc0b0055Sopenharmony_ci
24fc0b0055Sopenharmony_ci#include "accesstoken_log.h"
25fc0b0055Sopenharmony_ci#include "access_token_error.h"
26fc0b0055Sopenharmony_ci#include "access_token.h"
27fc0b0055Sopenharmony_ci
28fc0b0055Sopenharmony_cinamespace OHOS {
29fc0b0055Sopenharmony_cinamespace Security {
30fc0b0055Sopenharmony_cinamespace AccessToken {
31fc0b0055Sopenharmony_cinamespace {
32fc0b0055Sopenharmony_cistatic constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "JsonParser"};
33fc0b0055Sopenharmony_ciconstexpr int MAX_NATIVE_CONFIG_FILE_SIZE = 5 * 1024 * 1024; // 5M
34fc0b0055Sopenharmony_ciconstexpr size_t BUFFER_SIZE = 1024;
35fc0b0055Sopenharmony_ci}
36fc0b0055Sopenharmony_ci
37fc0b0055Sopenharmony_cibool JsonParser::GetStringFromJson(const nlohmann::json& j, const std::string& tag, std::string& out)
38fc0b0055Sopenharmony_ci{
39fc0b0055Sopenharmony_ci    if (j.find(tag) != j.end() && j.at(tag).is_string()) {
40fc0b0055Sopenharmony_ci        out = j.at(tag).get<std::string>();
41fc0b0055Sopenharmony_ci        return true;
42fc0b0055Sopenharmony_ci    }
43fc0b0055Sopenharmony_ci    return false;
44fc0b0055Sopenharmony_ci}
45fc0b0055Sopenharmony_ci
46fc0b0055Sopenharmony_cibool JsonParser::GetIntFromJson(const nlohmann::json& j, const std::string& tag, int& out)
47fc0b0055Sopenharmony_ci{
48fc0b0055Sopenharmony_ci    if (j.find(tag) != j.end() && j.at(tag).is_number()) {
49fc0b0055Sopenharmony_ci        out = j.at(tag).get<int>();
50fc0b0055Sopenharmony_ci        return true;
51fc0b0055Sopenharmony_ci    }
52fc0b0055Sopenharmony_ci    return false;
53fc0b0055Sopenharmony_ci}
54fc0b0055Sopenharmony_ci
55fc0b0055Sopenharmony_cibool JsonParser::GetUnsignedIntFromJson(const nlohmann::json& j, const std::string& tag, unsigned int& out)
56fc0b0055Sopenharmony_ci{
57fc0b0055Sopenharmony_ci    if (j.find(tag) != j.end() && j.at(tag).is_number()) {
58fc0b0055Sopenharmony_ci        out = j.at(tag).get<unsigned int>();
59fc0b0055Sopenharmony_ci        return true;
60fc0b0055Sopenharmony_ci    }
61fc0b0055Sopenharmony_ci    return false;
62fc0b0055Sopenharmony_ci}
63fc0b0055Sopenharmony_ci
64fc0b0055Sopenharmony_cibool JsonParser::GetBoolFromJson(const nlohmann::json& j, const std::string& tag, bool& out)
65fc0b0055Sopenharmony_ci{
66fc0b0055Sopenharmony_ci    if (j.find(tag) != j.end() && j.at(tag).is_boolean()) {
67fc0b0055Sopenharmony_ci        out = j.at(tag).get<bool>();
68fc0b0055Sopenharmony_ci        return true;
69fc0b0055Sopenharmony_ci    }
70fc0b0055Sopenharmony_ci    return false;
71fc0b0055Sopenharmony_ci}
72fc0b0055Sopenharmony_ci
73fc0b0055Sopenharmony_ciint32_t JsonParser::ReadCfgFile(const std::string& file, std::string& rawData)
74fc0b0055Sopenharmony_ci{
75fc0b0055Sopenharmony_ci    char filePath[PATH_MAX + 1] = {0};
76fc0b0055Sopenharmony_ci    if (realpath(file.c_str(), filePath) == NULL) {
77fc0b0055Sopenharmony_ci        return ERR_FILE_OPERATE_FAILED;
78fc0b0055Sopenharmony_ci    }
79fc0b0055Sopenharmony_ci    int32_t fd = open(filePath, O_RDONLY);
80fc0b0055Sopenharmony_ci    if (fd < 0) {
81fc0b0055Sopenharmony_ci        ACCESSTOKEN_LOG_ERROR(LABEL, "Open failed errno %{public}d.", errno);
82fc0b0055Sopenharmony_ci        return ERR_FILE_OPERATE_FAILED;
83fc0b0055Sopenharmony_ci    }
84fc0b0055Sopenharmony_ci    struct stat statBuffer;
85fc0b0055Sopenharmony_ci
86fc0b0055Sopenharmony_ci    if (fstat(fd, &statBuffer) != 0) {
87fc0b0055Sopenharmony_ci        ACCESSTOKEN_LOG_ERROR(LABEL, "Fstat failed.");
88fc0b0055Sopenharmony_ci        close(fd);
89fc0b0055Sopenharmony_ci        return ERR_FILE_OPERATE_FAILED;
90fc0b0055Sopenharmony_ci    }
91fc0b0055Sopenharmony_ci
92fc0b0055Sopenharmony_ci    if (statBuffer.st_size == 0) {
93fc0b0055Sopenharmony_ci        ACCESSTOKEN_LOG_ERROR(LABEL, "Config file size is invalid.");
94fc0b0055Sopenharmony_ci        close(fd);
95fc0b0055Sopenharmony_ci        return ERR_PARAM_INVALID;
96fc0b0055Sopenharmony_ci    }
97fc0b0055Sopenharmony_ci    if (statBuffer.st_size > MAX_NATIVE_CONFIG_FILE_SIZE) {
98fc0b0055Sopenharmony_ci        ACCESSTOKEN_LOG_ERROR(LABEL, "Config file size is too large.");
99fc0b0055Sopenharmony_ci        close(fd);
100fc0b0055Sopenharmony_ci        return ERR_OVERSIZE;
101fc0b0055Sopenharmony_ci    }
102fc0b0055Sopenharmony_ci    rawData.reserve(statBuffer.st_size);
103fc0b0055Sopenharmony_ci
104fc0b0055Sopenharmony_ci    char buff[BUFFER_SIZE] = { 0 };
105fc0b0055Sopenharmony_ci    ssize_t readLen = 0;
106fc0b0055Sopenharmony_ci    while ((readLen = read(fd, buff, BUFFER_SIZE)) > 0) {
107fc0b0055Sopenharmony_ci        rawData.append(buff, readLen);
108fc0b0055Sopenharmony_ci    }
109fc0b0055Sopenharmony_ci    close(fd);
110fc0b0055Sopenharmony_ci    if (readLen == 0) {
111fc0b0055Sopenharmony_ci        return RET_SUCCESS;
112fc0b0055Sopenharmony_ci    }
113fc0b0055Sopenharmony_ci    return ERR_FILE_OPERATE_FAILED;
114fc0b0055Sopenharmony_ci}
115fc0b0055Sopenharmony_ci
116fc0b0055Sopenharmony_cibool JsonParser::IsDirExsit(const std::string& file)
117fc0b0055Sopenharmony_ci{
118fc0b0055Sopenharmony_ci    if (file.empty()) {
119fc0b0055Sopenharmony_ci        ACCESSTOKEN_LOG_ERROR(LABEL, "File path is empty");
120fc0b0055Sopenharmony_ci        return false;
121fc0b0055Sopenharmony_ci    }
122fc0b0055Sopenharmony_ci
123fc0b0055Sopenharmony_ci    struct stat buf;
124fc0b0055Sopenharmony_ci    if (stat(file.c_str(), &buf) != 0) {
125fc0b0055Sopenharmony_ci        ACCESSTOKEN_LOG_ERROR(LABEL, "Get file attributes failed, errno %{public}d.", errno);
126fc0b0055Sopenharmony_ci        return false;
127fc0b0055Sopenharmony_ci    }
128fc0b0055Sopenharmony_ci
129fc0b0055Sopenharmony_ci    if (!S_ISDIR(buf.st_mode)) {
130fc0b0055Sopenharmony_ci        ACCESSTOKEN_LOG_ERROR(LABEL, "File mode is not directory.");
131fc0b0055Sopenharmony_ci        return false;
132fc0b0055Sopenharmony_ci    }
133fc0b0055Sopenharmony_ci
134fc0b0055Sopenharmony_ci    return true;
135fc0b0055Sopenharmony_ci}
136fc0b0055Sopenharmony_ci} // namespace AccessToken
137fc0b0055Sopenharmony_ci} // namespace Security
138fc0b0055Sopenharmony_ci} // namespace OHOS