• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 #include <fcntl.h>
16 #include <memory>
17 #include <sys/stat.h>
18 #include <sys/types.h>
19 #include <unistd.h>
20 
21 #include "accesstoken_id_manager.h"
22 #include "accesstoken_info_manager.h"
23 #include "accesstoken_log.h"
24 #include "data_validator.h"
25 #include "native_token_receptor.h"
26 #include "securec.h"
27 
28 namespace OHOS {
29 namespace Security {
30 namespace AccessToken {
31 namespace {
32 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "NativeTokenReceptor"};
33 static const std::string DEFAULT_DEVICEID = "0";
34 static const std::string JSON_PROCESS_NAME = "processName";
35 static const std::string JSON_APL = "APL";
36 static const std::string JSON_VERSION = "version";
37 static const std::string JSON_TOKEN_ID = "tokenId";
38 static const std::string JSON_TOKEN_ATTR = "tokenAttr";
39 static const std::string JSON_DCAPS = "dcaps";
40 static const std::string JSON_PERMS = "permissions";
41 static const std::string JSON_ACLS = "nativeAcls";
42 }
43 
NativeReqPermsGet(const nlohmann::json & j,std::vector<PermissionStateFull> & permStateList)44 int32_t NativeReqPermsGet(
45     const nlohmann::json& j, std::vector<PermissionStateFull>& permStateList)
46 {
47     std::vector<std::string> permReqList;
48     if (j.find(JSON_PERMS) == j.end()) {
49         return RET_FAILED;
50     }
51     permReqList = j.at(JSON_PERMS).get<std::vector<std::string>>();
52     if (permReqList.size() > MAX_REQ_PERM_NUM) {
53         return RET_FAILED;
54     }
55     std::set<std::string> permRes;
56     for (const auto& permReq : permReqList) {
57         PermissionStateFull permState;
58         if (permRes.count(permReq) != 0) {
59             continue;
60         }
61         permState.permissionName = permReq;
62         permState.isGeneral = true;
63         permState.resDeviceID.push_back(DEFAULT_DEVICEID);
64         permState.grantStatus.push_back(PERMISSION_GRANTED);
65         permState.grantFlags.push_back(PERMISSION_SYSTEM_FIXED);
66         permStateList.push_back(permState);
67         permRes.insert(permReq);
68     }
69     return RET_SUCCESS;
70 }
71 
72 // nlohmann json need the function named from_json to parse NativeTokenInfo
from_json(const nlohmann::json & j,std::shared_ptr<NativeTokenInfoInner> & p)73 void from_json(const nlohmann::json& j, std::shared_ptr<NativeTokenInfoInner>& p)
74 {
75     NativeTokenInfo native;
76     if (j.find(JSON_PROCESS_NAME) != j.end()) {
77         native.processName = j.at(JSON_PROCESS_NAME).get<std::string>();
78         if (!DataValidator::IsProcessNameValid(native.processName)) {
79             return;
80         }
81     } else {
82         return;
83     }
84 
85     if (j.find(JSON_APL) != j.end()) {
86         int aplNum = j.at(JSON_APL).get<int>();
87         if (DataValidator::IsAplNumValid(aplNum)) {
88             native.apl = static_cast<ATokenAplEnum>(aplNum);
89         } else {
90             return;
91         }
92     } else {
93         return;
94     }
95 
96     if (j.find(JSON_VERSION) != j.end()) {
97         native.ver = (uint8_t)j.at(JSON_VERSION).get<int>();
98         if (native.ver != DEFAULT_TOKEN_VERSION) {
99             return;
100         }
101     } else {
102         return;
103     }
104 
105     if (j.find(JSON_TOKEN_ID) != j.end()) {
106         native.tokenID = j.at(JSON_TOKEN_ID).get<unsigned int>();
107         if (native.tokenID == 0) {
108             return;
109         }
110         ATokenTypeEnum type = AccessTokenIDManager::GetTokenIdTypeEnum(native.tokenID);
111         if ((type != TOKEN_NATIVE) && (type != TOKEN_SHELL)) {
112             return;
113         }
114     } else {
115         return;
116     }
117 
118     if (j.find(JSON_TOKEN_ATTR) != j.end()) {
119         native.tokenAttr = j.at(JSON_TOKEN_ATTR).get<unsigned int>();
120     } else {
121         return;
122     }
123 
124     if (j.find(JSON_DCAPS) != j.end()) {
125         native.dcap = j.at(JSON_DCAPS).get<std::vector<std::string>>();
126         if (native.dcap.size() > MAX_DCAPS_NUM) {
127             return;
128         }
129     } else {
130         return;
131     }
132 
133     if (j.find(JSON_ACLS) != j.end()) {
134         native.nativeAcls = j.at(JSON_ACLS).get<std::vector<std::string>>();
135         if (native.nativeAcls.size() > MAX_REQ_PERM_NUM) {
136             return;
137         }
138     } else {
139         return;
140     }
141 
142     std::vector<PermissionStateFull> permStateList;
143     if (NativeReqPermsGet(j, permStateList) != RET_SUCCESS) {
144         return;
145     }
146 
147     p = std::make_shared<NativeTokenInfoInner>(native, permStateList);
148 }
149 
ParserNativeRawData(const std::string & nativeRawData,std::vector<std::shared_ptr<NativeTokenInfoInner>> & tokenInfos)150 int32_t NativeTokenReceptor::ParserNativeRawData(const std::string& nativeRawData,
151     std::vector<std::shared_ptr<NativeTokenInfoInner>>& tokenInfos)
152 {
153     nlohmann::json jsonRes = nlohmann::json::parse(nativeRawData, nullptr, false);
154     if (jsonRes.is_discarded()) {
155         ACCESSTOKEN_LOG_ERROR(LABEL, "jsonRes is invalid.");
156         return RET_FAILED;
157     }
158     for (auto it = jsonRes.begin(); it != jsonRes.end(); it++) {
159         auto token = it->get<std::shared_ptr<NativeTokenInfoInner>>();
160         if (token != nullptr) {
161             tokenInfos.emplace_back(token);
162         }
163     }
164     return RET_SUCCESS;
165 }
166 
ReadCfgFile(std::string & nativeRawData)167 int NativeTokenReceptor::ReadCfgFile(std::string& nativeRawData)
168 {
169     int32_t fd = open(NATIVE_TOKEN_CONFIG_FILE.c_str(), O_RDONLY);
170     if (fd < 0) {
171         ACCESSTOKEN_LOG_ERROR(LABEL, "open failed errno %{public}d.", errno);
172         return RET_FAILED;
173     }
174     struct stat statBuffer;
175 
176     if (fstat(fd, &statBuffer) != 0) {
177         ACCESSTOKEN_LOG_ERROR(LABEL, "fstat failed.");
178         close(fd);
179         return RET_FAILED;
180     }
181 
182     if (statBuffer.st_size == 0) {
183         ACCESSTOKEN_LOG_ERROR(LABEL, "config file size is invalid.");
184         close(fd);
185         return RET_FAILED;
186     }
187     if (statBuffer.st_size > MAX_NATIVE_CONFIG_FILE_SIZE) {
188         ACCESSTOKEN_LOG_ERROR(LABEL, "config file size is too large.");
189         close(fd);
190         return RET_FAILED;
191     }
192     nativeRawData.reserve(statBuffer.st_size);
193 
194     char buff[BUFFER_SIZE] = { 0 };
195     ssize_t readLen = 0;
196     while ((readLen = read(fd, buff, BUFFER_SIZE)) > 0) {
197         nativeRawData.append(buff, readLen);
198     }
199     close(fd);
200 
201     if (readLen == 0) {
202         return RET_SUCCESS;
203     }
204     return RET_FAILED;
205 }
206 
Init()207 int NativeTokenReceptor::Init()
208 {
209     std::string nativeRawData;
210     int ret = ReadCfgFile(nativeRawData);
211     if (ret != RET_SUCCESS) {
212         ACCESSTOKEN_LOG_ERROR(LABEL, "readCfgFile failed.");
213         return RET_FAILED;
214     }
215     std::vector<std::shared_ptr<NativeTokenInfoInner>> tokenInfos;
216     ret = ParserNativeRawData(nativeRawData, tokenInfos);
217     if (ret != RET_SUCCESS) {
218         ACCESSTOKEN_LOG_ERROR(LABEL, "ParserNativeRawData failed.");
219         return RET_FAILED;
220     }
221     AccessTokenInfoManager::GetInstance().ProcessNativeTokenInfos(tokenInfos);
222 
223     ACCESSTOKEN_LOG_INFO(LABEL, "init ok.");
224     return RET_SUCCESS;
225 }
226 
GetInstance()227 NativeTokenReceptor& NativeTokenReceptor::GetInstance()
228 {
229     static NativeTokenReceptor instance;
230     return instance;
231 }
232 } // namespace AccessToken
233 } // namespace Security
234 } // namespace OHOS
235