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 
16 #include "native_token_info_inner.h"
17 
18 #include "access_token_error.h"
19 #include "accesstoken_dfx_define.h"
20 #include "accesstoken_log.h"
21 #include "data_translator.h"
22 #include "data_validator.h"
23 #include "nlohmann/json.hpp"
24 #include "token_field_const.h"
25 
26 namespace OHOS {
27 namespace Security {
28 namespace AccessToken {
29 namespace {
30 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "NativeTokenInfoInner"};
31 }
32 
NativeTokenInfoInner()33 NativeTokenInfoInner::NativeTokenInfoInner() : isRemote_(false)
34 {
35     tokenInfoBasic_.ver = DEFAULT_TOKEN_VERSION;
36     tokenInfoBasic_.tokenID = 0;
37     tokenInfoBasic_.tokenAttr = 0;
38     tokenInfoBasic_.apl = APL_NORMAL;
39 }
40 
NativeTokenInfoInner(NativeTokenInfo & native,const std::vector<PermissionStateFull> & permStateList)41 NativeTokenInfoInner::NativeTokenInfoInner(NativeTokenInfo& native,
42     const std::vector<PermissionStateFull>& permStateList) : isRemote_(false)
43 {
44     tokenInfoBasic_ = native;
45     permPolicySet_ = PermissionPolicySet::BuildPermissionPolicySet(native.tokenID,
46         permStateList);
47 }
48 
~NativeTokenInfoInner()49 NativeTokenInfoInner::~NativeTokenInfoInner()
50 {
51     ACCESSTOKEN_LOG_DEBUG(LABEL, "TokenID: %{public}u destruction", tokenInfoBasic_.tokenID);
52 }
53 
Init(const TokenInfo & tokenInfo,const std::vector<std::string> & dcap,const std::vector<std::string> & nativeAcls,const std::vector<PermissionStateFull> & permStateList)54 int NativeTokenInfoInner::Init(const TokenInfo& tokenInfo, const std::vector<std::string>& dcap,
55     const std::vector<std::string>& nativeAcls,
56     const std::vector<PermissionStateFull>& permStateList)
57 {
58     tokenInfoBasic_.tokenID = tokenInfo.id;
59     if (!DataValidator::IsProcessNameValid(tokenInfo.processName)) {
60         ACCESSTOKEN_LOG_ERROR(LABEL,
61             "tokenID: %{public}u process name is null", tokenInfoBasic_.tokenID);
62         return ERR_PARAM_INVALID;
63     }
64     tokenInfoBasic_.processName = tokenInfo.processName;
65     if (!DataValidator::IsAplNumValid(tokenInfo.apl)) {
66         ACCESSTOKEN_LOG_ERROR(LABEL,
67             "tokenID: %{public}u init failed, apl %{public}d is invalid",
68             tokenInfoBasic_.tokenID, tokenInfo.apl);
69         return ERR_PARAM_INVALID;
70     }
71     tokenInfoBasic_.apl = static_cast<ATokenAplEnum>(tokenInfo.apl);
72     tokenInfoBasic_.dcap = dcap;
73     tokenInfoBasic_.nativeAcls = nativeAcls;
74 
75     permPolicySet_ = PermissionPolicySet::BuildPermissionPolicySet(tokenInfo.id,
76         permStateList);
77     return RET_SUCCESS;
78 }
79 
DcapToString(const std::vector<std::string> & dcap) const80 std::string NativeTokenInfoInner::DcapToString(const std::vector<std::string>& dcap) const
81 {
82     std::string dcapStr;
83     for (auto iter = dcap.begin(); iter != dcap.end(); iter++) {
84         dcapStr.append(*iter);
85         if (iter != (dcap.end() - 1)) {
86             dcapStr.append(",");
87         }
88     }
89     return dcapStr;
90 }
91 
NativeAclsToString(const std::vector<std::string> & nativeAcls) const92 std::string NativeTokenInfoInner::NativeAclsToString(const std::vector<std::string>& nativeAcls) const
93 {
94     std::string nativeAclsStr;
95     for (auto iter = nativeAcls.begin(); iter != nativeAcls.end(); iter++) {
96         nativeAclsStr.append(*iter);
97         if (iter != (nativeAcls.end() - 1)) {
98             nativeAclsStr.append(",");
99         }
100     }
101     return nativeAclsStr;
102 }
103 
TranslationIntoGenericValues(GenericValues & outGenericValues) const104 int NativeTokenInfoInner::TranslationIntoGenericValues(GenericValues& outGenericValues) const
105 {
106     outGenericValues.Put(TokenFiledConst::FIELD_TOKEN_ID, static_cast<int32_t>(tokenInfoBasic_.tokenID));
107     outGenericValues.Put(TokenFiledConst::FIELD_PROCESS_NAME, tokenInfoBasic_.processName);
108     outGenericValues.Put(TokenFiledConst::FIELD_APL, tokenInfoBasic_.apl);
109     outGenericValues.Put(TokenFiledConst::FIELD_TOKEN_VERSION, tokenInfoBasic_.ver);
110     outGenericValues.Put(TokenFiledConst::FIELD_DCAP, DcapToString(tokenInfoBasic_.dcap));
111     outGenericValues.Put(TokenFiledConst::FIELD_NATIVE_ACLS, NativeAclsToString(tokenInfoBasic_.nativeAcls));
112     outGenericValues.Put(TokenFiledConst::FIELD_TOKEN_ATTR, static_cast<int32_t>(tokenInfoBasic_.tokenAttr));
113 
114     return RET_SUCCESS;
115 }
116 
RestoreNativeTokenInfo(AccessTokenID tokenId,const GenericValues & inGenericValues,const std::vector<GenericValues> & permStateRes)117 int NativeTokenInfoInner::RestoreNativeTokenInfo(AccessTokenID tokenId, const GenericValues& inGenericValues,
118     const std::vector<GenericValues>& permStateRes)
119 {
120     tokenInfoBasic_.tokenID = tokenId;
121     tokenInfoBasic_.processName = inGenericValues.GetString(TokenFiledConst::FIELD_PROCESS_NAME);
122     if (!DataValidator::IsProcessNameValid(tokenInfoBasic_.processName)) {
123         ACCESSTOKEN_LOG_ERROR(LABEL,
124             "tokenID: %{public}u process name is null", tokenInfoBasic_.tokenID);
125         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "PERMISSION_CHECK",
126             HiviewDFX::HiSysEvent::EventType::FAULT, "CODE", LOAD_DATABASE_ERROR,
127             "ERROR_REASON", "native token processName error");
128         return ERR_PARAM_INVALID;
129     }
130     int aplNum = inGenericValues.GetInt(TokenFiledConst::FIELD_APL);
131     if (!DataValidator::IsAplNumValid(aplNum)) {
132         ACCESSTOKEN_LOG_ERROR(LABEL,
133             "tokenID: %{public}u apl is error, value %{public}d",
134             tokenInfoBasic_.tokenID, aplNum);
135         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "PERMISSION_CHECK",
136             HiviewDFX::HiSysEvent::EventType::FAULT, "CODE", LOAD_DATABASE_ERROR,
137             "ERROR_REASON", "native token apl error");
138         return ERR_PARAM_INVALID;
139     }
140     tokenInfoBasic_.apl = static_cast<ATokenAplEnum>(aplNum);
141     tokenInfoBasic_.ver = (char)inGenericValues.GetInt(TokenFiledConst::FIELD_TOKEN_VERSION);
142     if (tokenInfoBasic_.ver != DEFAULT_TOKEN_VERSION) {
143         ACCESSTOKEN_LOG_ERROR(LABEL,
144             "tokenID: %{public}u version is error, version %{public}d",
145             tokenInfoBasic_.tokenID, tokenInfoBasic_.ver);
146         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::ACCESS_TOKEN, "PERMISSION_CHECK",
147             HiviewDFX::HiSysEvent::EventType::FAULT, "CODE", LOAD_DATABASE_ERROR,
148             "ERROR_REASON", "native token version error");
149         return ERR_PARAM_INVALID;
150     }
151 
152     SetDcaps(inGenericValues.GetString(TokenFiledConst::FIELD_DCAP));
153     SetNativeAcls(inGenericValues.GetString(TokenFiledConst::FIELD_NATIVE_ACLS));
154     tokenInfoBasic_.tokenAttr = (uint32_t)inGenericValues.GetInt(TokenFiledConst::FIELD_TOKEN_ATTR);
155 
156     permPolicySet_ = PermissionPolicySet::RestorePermissionPolicy(tokenId, permStateRes);
157     return RET_SUCCESS;
158 }
159 
TranslateToNativeTokenInfo(NativeTokenInfo & infoParcel) const160 void NativeTokenInfoInner::TranslateToNativeTokenInfo(NativeTokenInfo& infoParcel) const
161 {
162     infoParcel.apl = tokenInfoBasic_.apl;
163     infoParcel.ver = tokenInfoBasic_.ver;
164     infoParcel.processName = tokenInfoBasic_.processName;
165     infoParcel.dcap = tokenInfoBasic_.dcap;
166     infoParcel.nativeAcls = tokenInfoBasic_.nativeAcls;
167     infoParcel.tokenID = tokenInfoBasic_.tokenID;
168     infoParcel.tokenAttr = tokenInfoBasic_.tokenAttr;
169 }
170 
StoreNativeInfo(std::vector<GenericValues> & valueList) const171 void NativeTokenInfoInner::StoreNativeInfo(std::vector<GenericValues>& valueList) const
172 {
173     if (isRemote_) {
174         ACCESSTOKEN_LOG_INFO(LABEL,
175             "token %{public}x is remote hap token, will not store", tokenInfoBasic_.tokenID);
176         return;
177     }
178     GenericValues genericValues;
179     TranslationIntoGenericValues(genericValues);
180     valueList.emplace_back(genericValues);
181 }
182 
StorePermissionPolicy(std::vector<GenericValues> & permStateValues) const183 void NativeTokenInfoInner::StorePermissionPolicy(std::vector<GenericValues>& permStateValues) const
184 {
185     if (isRemote_) {
186         ACCESSTOKEN_LOG_INFO(LABEL,
187             "token %{public}x is remote hap token, will not store", tokenInfoBasic_.tokenID);
188         return;
189     }
190     if (permPolicySet_ != nullptr) {
191         permPolicySet_->StorePermissionPolicySet(permStateValues);
192     }
193 }
194 
GetTokenID() const195 AccessTokenID NativeTokenInfoInner::GetTokenID() const
196 {
197     return tokenInfoBasic_.tokenID;
198 }
199 
GetDcap() const200 std::vector<std::string> NativeTokenInfoInner::GetDcap() const
201 {
202     return tokenInfoBasic_.dcap;
203 }
204 
GetNativeAcls() const205 std::vector<std::string> NativeTokenInfoInner::GetNativeAcls() const
206 {
207     return tokenInfoBasic_.nativeAcls;
208 }
209 
GetProcessName() const210 std::string NativeTokenInfoInner::GetProcessName() const
211 {
212     return tokenInfoBasic_.processName;
213 }
214 
GetNativeInfoPermissionPolicySet() const215 std::shared_ptr<PermissionPolicySet> NativeTokenInfoInner::GetNativeInfoPermissionPolicySet() const
216 {
217     return permPolicySet_;
218 }
219 
GetReqPermissionSize() const220 uint32_t NativeTokenInfoInner::GetReqPermissionSize() const
221 {
222     if (permPolicySet_ != nullptr) {
223         return permPolicySet_->GetReqPermissionSize();
224     }
225     return static_cast<uint32_t>(0);
226 }
227 
IsRemote() const228 bool NativeTokenInfoInner::IsRemote() const
229 {
230     return isRemote_;
231 }
232 
SetRemote(bool isRemote)233 void NativeTokenInfoInner::SetRemote(bool isRemote)
234 {
235     isRemote_ = isRemote;
236 }
237 
SetDcaps(const std::string & dcapStr)238 void NativeTokenInfoInner::SetDcaps(const std::string& dcapStr)
239 {
240     std::string::size_type start = 0;
241     while (true) {
242         std::string::size_type offset = dcapStr.find(',', start);
243         if (offset == std::string::npos) {
244             tokenInfoBasic_.dcap.push_back(dcapStr.substr(start));
245             break;
246         }
247         tokenInfoBasic_.dcap.push_back(dcapStr.substr(start, offset));
248         start = offset + 1;
249     }
250 }
251 
SetNativeAcls(const std::string & AclsStr)252 void NativeTokenInfoInner::SetNativeAcls(const std::string& AclsStr)
253 {
254     std::string::size_type start = 0;
255     while (true) {
256         std::string::size_type offset = AclsStr.find(',', start);
257         if (offset == std::string::npos) {
258             tokenInfoBasic_.nativeAcls.push_back(AclsStr.substr(start));
259             break;
260         }
261         tokenInfoBasic_.nativeAcls.push_back(AclsStr.substr(start, offset));
262         start = offset + 1;
263     }
264 }
265 
ToString(std::string & info) const266 void NativeTokenInfoInner::ToString(std::string& info) const
267 {
268     info.append(R"({)");
269     info.append("\n");
270     info.append(R"(  "tokenID": )" + std::to_string(tokenInfoBasic_.tokenID) + ",\n");
271     info.append(R"(  "tokenAttr": )" + std::to_string(tokenInfoBasic_.tokenAttr) + ",\n");
272     info.append(R"(  "ver": )" + std::to_string(tokenInfoBasic_.ver) + ",\n");
273     info.append(R"(  "processName": ")" + tokenInfoBasic_.processName + R"(")" + ",\n");
274     info.append(R"(  "apl": )" + std::to_string(tokenInfoBasic_.apl) + ",\n");
275     info.append(R"(  "dcap": ")" + DcapToString(tokenInfoBasic_.dcap) + R"(")" + ",\n");
276     info.append(R"(  "nativeAcls": ")" + NativeAclsToString(tokenInfoBasic_.nativeAcls) + R"(")" + ",\n");
277     info.append(R"(  "isRemote": )" + std::to_string(isRemote_? 1 : 0) + ",\n");
278     if (permPolicySet_ != nullptr) {
279         permPolicySet_->PermStateToString(tokenInfoBasic_.apl, tokenInfoBasic_.nativeAcls, info);
280     }
281     info.append("}");
282 }
283 } // namespace AccessToken
284 } // namespace Security
285 } // namespace OHOS
286