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 "accesstoken_id_manager.h"
17 #include "accesstoken_log.h"
18 #include "data_validator.h"
19 #include "random.h"
20
21 namespace OHOS {
22 namespace Security {
23 namespace AccessToken {
24 namespace {
25 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_ACCESSTOKEN, "AccessTokenIDManager"};
26 }
27
GetTokenIdTypeEnum(AccessTokenID id)28 ATokenTypeEnum AccessTokenIDManager::GetTokenIdTypeEnum(AccessTokenID id)
29 {
30 AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&id);
31 return static_cast<ATokenTypeEnum>(idInner->type);
32 }
33
GetTokenIdDlpFlag(AccessTokenID id)34 int AccessTokenIDManager::GetTokenIdDlpFlag(AccessTokenID id)
35 {
36 AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&id);
37 return idInner->dlpFlag;
38 }
39
GetTokenIdType(AccessTokenID id)40 ATokenTypeEnum AccessTokenIDManager::GetTokenIdType(AccessTokenID id)
41 {
42 {
43 Utils::UniqueReadGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
44 if (tokenIdSet_.count(id) == 0) {
45 return TOKEN_INVALID;
46 }
47 }
48 return GetTokenIdTypeEnum(id);
49 }
50
RegisterTokenId(AccessTokenID id,ATokenTypeEnum type)51 int AccessTokenIDManager::RegisterTokenId(AccessTokenID id, ATokenTypeEnum type)
52 {
53 AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&id);
54 if (idInner->version != DEFAULT_TOKEN_VERSION || idInner->type != type) {
55 return RET_FAILED;
56 }
57
58 Utils::UniqueWriteGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
59
60 for (std::set<AccessTokenID>::iterator it = tokenIdSet_.begin(); it != tokenIdSet_.end(); ++it) {
61 AccessTokenID tokenId = *it;
62 AccessTokenIDInner *idInnerExist = reinterpret_cast<AccessTokenIDInner *>(&tokenId);
63 if (idInnerExist->tokenUniqueID == idInner->tokenUniqueID) {
64 return RET_FAILED;
65 }
66 }
67 tokenIdSet_.insert(id);
68 return RET_SUCCESS;
69 }
70
GetHapTokenIdList(std::vector<AccessTokenID> & idList)71 void AccessTokenIDManager::GetHapTokenIdList(std::vector<AccessTokenID>& idList)
72 {
73 Utils::UniqueReadGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
74
75 for (std::set<AccessTokenID>::iterator it = tokenIdSet_.begin(); it != tokenIdSet_.end(); ++it) {
76 idList.emplace_back(*it);
77 }
78 }
79
CreateTokenId(ATokenTypeEnum type,int dlpType) const80 AccessTokenID AccessTokenIDManager::CreateTokenId(ATokenTypeEnum type, int dlpType) const
81 {
82 unsigned int rand = GetRandomUint32();
83 if (rand == 0) {
84 ACCESSTOKEN_LOG_ERROR(LABEL, "get random failed");
85 return 0;
86 }
87
88 AccessTokenIDInner innerId = {0};
89 innerId.version = DEFAULT_TOKEN_VERSION;
90 innerId.type = type;
91 innerId.res = 0;
92 innerId.renderFlag = 0;
93 innerId.dlpFlag = (dlpType == 0) ? 0 : 1;
94 innerId.tokenUniqueID = rand & TOKEN_RANDOM_MASK;
95 AccessTokenID tokenId = *reinterpret_cast<AccessTokenID *>(&innerId);
96 return tokenId;
97 }
98
CreateAndRegisterTokenId(ATokenTypeEnum type,int dlpType)99 AccessTokenID AccessTokenIDManager::CreateAndRegisterTokenId(ATokenTypeEnum type, int dlpType)
100 {
101 AccessTokenID tokenId = 0;
102 // random maybe repeat, retry twice.
103 for (int i = 0; i < MAX_CREATE_TOKEN_ID_RETRY; i++) {
104 tokenId = CreateTokenId(type, dlpType);
105 if (tokenId == INVALID_TOKENID) {
106 ACCESSTOKEN_LOG_ERROR(LABEL, "create tokenId failed");
107 return INVALID_TOKENID;
108 }
109
110 int ret = RegisterTokenId(tokenId, type);
111 if (ret == RET_SUCCESS) {
112 break;
113 } else if (i < MAX_CREATE_TOKEN_ID_RETRY - 1) {
114 ACCESSTOKEN_LOG_WARN(LABEL, "reigster tokenId failed, maybe repeat, retry");
115 } else {
116 ACCESSTOKEN_LOG_ERROR(LABEL, "reigster tokenId finally failed");
117 tokenId = INVALID_TOKENID;
118 }
119 }
120 return tokenId;
121 }
122
ReleaseTokenId(AccessTokenID id)123 void AccessTokenIDManager::ReleaseTokenId(AccessTokenID id)
124 {
125 Utils::UniqueWriteGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
126 if (tokenIdSet_.count(id) == 0) {
127 ACCESSTOKEN_LOG_INFO(LABEL, "id %{public}x is not exist", id);
128 return;
129 }
130 tokenIdSet_.erase(id);
131 }
132
GetInstance()133 AccessTokenIDManager& AccessTokenIDManager::GetInstance()
134 {
135 static AccessTokenIDManager instance;
136 return instance;
137 }
138 } // namespace AccessToken
139 } // namespace Security
140 } // namespace OHOS
141