• 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 
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 (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 
CreateTokenId(ATokenTypeEnum type,int dlpType) const71 AccessTokenID AccessTokenIDManager::CreateTokenId(ATokenTypeEnum type, int dlpType) const
72 {
73     unsigned int rand = GetRandomUint32();
74     if (rand == 0) {
75         ACCESSTOKEN_LOG_ERROR(LABEL, "get random failed");
76         return 0;
77     }
78 
79     AccessTokenIDInner innerId = {0};
80     innerId.version = DEFAULT_TOKEN_VERSION;
81     innerId.type = type;
82     innerId.res = 0;
83     innerId.dlpFlag = (dlpType == 0) ? 0 : 1;
84     innerId.tokenUniqueID = rand & TOKEN_RANDOM_MASK;
85     AccessTokenID tokenId = *(AccessTokenID *)&innerId;
86     return tokenId;
87 }
88 
CreateAndRegisterTokenId(ATokenTypeEnum type,int dlpType)89 AccessTokenID AccessTokenIDManager::CreateAndRegisterTokenId(ATokenTypeEnum type, int dlpType)
90 {
91     AccessTokenID tokenId = 0;
92     // random maybe repeat, retry twice.
93     for (int i = 0; i < MAX_CREATE_TOKEN_ID_RETRY; i++) {
94         tokenId = CreateTokenId(type, dlpType);
95         if (tokenId == INVALID_TOKENID) {
96             ACCESSTOKEN_LOG_ERROR(LABEL, "create tokenId failed");
97             return INVALID_TOKENID;
98         }
99 
100         int ret = RegisterTokenId(tokenId, type);
101         if (ret == RET_SUCCESS) {
102             break;
103         } else if (i < MAX_CREATE_TOKEN_ID_RETRY - 1) {
104             ACCESSTOKEN_LOG_WARN(LABEL, "reigster tokenId failed, maybe repeat, retry");
105         } else {
106             ACCESSTOKEN_LOG_ERROR(LABEL, "reigster tokenId finally failed");
107             tokenId = INVALID_TOKENID;
108         }
109     }
110     return tokenId;
111 }
112 
ReleaseTokenId(AccessTokenID id)113 void AccessTokenIDManager::ReleaseTokenId(AccessTokenID id)
114 {
115     Utils::UniqueWriteGuard<Utils::RWLock> idGuard(this->tokenIdLock_);
116     if (tokenIdSet_.count(id) == 0) {
117         ACCESSTOKEN_LOG_INFO(LABEL, "id %{public}x is not exist", id);
118         return;
119     }
120     tokenIdSet_.erase(id);
121 }
122 
GetInstance()123 AccessTokenIDManager& AccessTokenIDManager::GetInstance()
124 {
125     static AccessTokenIDManager instance;
126     return instance;
127 }
128 } // namespace AccessToken
129 } // namespace Security
130 } // namespace OHOS
131