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 <mutex>
18 #include "accesstoken_common_log.h"
19 #include "access_token_error.h"
20 #include "data_validator.h"
21 #include "random.h"
22
23 namespace OHOS {
24 namespace Security {
25 namespace AccessToken {
26 namespace {
27 std::recursive_mutex g_instanceMutex;
28 }
29
GetTokenIdTypeEnum(AccessTokenID id)30 ATokenTypeEnum AccessTokenIDManager::GetTokenIdTypeEnum(AccessTokenID id)
31 {
32 AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&id);
33 return static_cast<ATokenTypeEnum>(idInner->type);
34 }
35
GetTokenIdDlpFlag(AccessTokenID id)36 int AccessTokenIDManager::GetTokenIdDlpFlag(AccessTokenID id)
37 {
38 AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&id);
39 return idInner->dlpFlag;
40 }
41
GetTokenIdCloneFlag(AccessTokenID id)42 int AccessTokenIDManager::GetTokenIdCloneFlag(AccessTokenID id)
43 {
44 AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&id);
45 return idInner->cloneFlag;
46 }
47
GetTokenIdType(AccessTokenID id)48 ATokenTypeEnum AccessTokenIDManager::GetTokenIdType(AccessTokenID id)
49 {
50 {
51 Utils::UniqueReadGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
52 if (tokenIdSet_.count(id) == 0) {
53 return TOKEN_INVALID;
54 }
55 }
56 return GetTokenIdTypeEnum(id);
57 }
58
RegisterTokenId(AccessTokenID id,ATokenTypeEnum type)59 int AccessTokenIDManager::RegisterTokenId(AccessTokenID id, ATokenTypeEnum type)
60 {
61 AccessTokenIDInner *idInner = reinterpret_cast<AccessTokenIDInner *>(&id);
62 if (idInner->version != DEFAULT_TOKEN_VERSION || idInner->type != type) {
63 return ERR_PARAM_INVALID;
64 }
65
66 Utils::UniqueWriteGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
67
68 for (std::set<AccessTokenID>::iterator it = tokenIdSet_.begin(); it != tokenIdSet_.end(); ++it) {
69 AccessTokenID tokenId = *it;
70 AccessTokenIDInner *idInnerExist = reinterpret_cast<AccessTokenIDInner *>(&tokenId);
71 if ((type == idInnerExist->type) && (idInnerExist->tokenUniqueID == idInner->tokenUniqueID)) {
72 return ERR_TOKENID_HAS_EXISTED;
73 }
74 }
75 tokenIdSet_.insert(id);
76 return RET_SUCCESS;
77 }
78
CreateTokenId(ATokenTypeEnum type,int32_t dlpFlag,int32_t cloneFlag) const79 AccessTokenID AccessTokenIDManager::CreateTokenId(ATokenTypeEnum type, int32_t dlpFlag, int32_t cloneFlag) const
80 {
81 unsigned int rand = GetRandomUint32();
82 if (rand == 0) {
83 LOGE(ATM_DOMAIN, ATM_TAG, "Get random failed");
84 return 0;
85 }
86
87 AccessTokenIDInner innerId = {0};
88 innerId.version = DEFAULT_TOKEN_VERSION;
89 innerId.type = type;
90 innerId.res = 0;
91 innerId.cloneFlag = static_cast<uint32_t>(cloneFlag);
92 innerId.renderFlag = 0;
93 innerId.dlpFlag = static_cast<uint32_t>(dlpFlag);
94 innerId.tokenUniqueID = rand & TOKEN_RANDOM_MASK;
95 AccessTokenID tokenId = *reinterpret_cast<AccessTokenID *>(&innerId);
96 return tokenId;
97 }
98
CreateAndRegisterTokenId(ATokenTypeEnum type,int32_t dlpFlag,int32_t cloneFlag)99 AccessTokenID AccessTokenIDManager::CreateAndRegisterTokenId(ATokenTypeEnum type, int32_t dlpFlag, int32_t cloneFlag)
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, dlpFlag, cloneFlag);
105 if (tokenId == INVALID_TOKENID) {
106 LOGE(ATM_DOMAIN, ATM_TAG, "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 LOGW(ATM_DOMAIN, ATM_TAG, "Reigster tokenId failed(error=%{public}d), maybe repeat, retry.", ret);
115 } else {
116 LOGE(ATM_DOMAIN, ATM_TAG, "Reigster tokenId finally failed(error=%{public}d).", ret);
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 LOGI(ATM_DOMAIN, ATM_TAG, "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 = nullptr;
136 if (instance == nullptr) {
137 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
138 if (instance == nullptr) {
139 AccessTokenIDManager* tmp = new AccessTokenIDManager();
140 instance = std::move(tmp);
141 }
142 }
143 return *instance;
144 }
145 } // namespace AccessToken
146 } // namespace Security
147 } // namespace OHOS
148