1 /*
2 * Copyright (c) 2023-2024 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 permission and
13 * limitations under the License.
14 */
15
16 #include "auth_deviceprofile.h"
17
18 #include <cstring>
19 #include <set>
20 #include <mutex>
21 #include <string>
22 #include <vector>
23
24 #include <securec.h>
25
26 #include "access_control_profile.h"
27 #include "anonymizer.h"
28 #include "auth_interface.h"
29 #include "bus_center_manager.h"
30 #include "distributed_device_profile_client.h"
31 #include "lnn_distributed_net_ledger.h"
32 #include "lnn_local_net_ledger.h"
33 #include "lnn_log.h"
34 #include "lnn_ohos_account_adapter.h"
35 #include "lnn_ohos_account.h"
36 #include "ohos_account_kits.h"
37 #include "os_account_manager.h"
38 #include "softbus_adapter_crypto.h"
39 #include "softbus_common.h"
40 #include "softbus_error_code.h"
41 #include "softbus_utils.h"
42 #include "trust_device_profile.h"
43
44 using DpClient = OHOS::DistributedDeviceProfile::DistributedDeviceProfileClient;
45 static std::set<std::string> g_notTrustedDevices;
46 static std::mutex g_mutex;
47 static constexpr const int32_t LONG_TO_STRING_MAX_LEN = 21;
48
IsNotTrustDevice(std::string deviceIdHash)49 static bool IsNotTrustDevice(std::string deviceIdHash)
50 {
51 std::lock_guard<std::mutex> autoLock(g_mutex);
52 if (g_notTrustedDevices.find(deviceIdHash) != g_notTrustedDevices.end()) {
53 return true;
54 }
55 return false;
56 }
57
InsertNotTrustDevice(std::string deviceIdHash)58 static void InsertNotTrustDevice(std::string deviceIdHash)
59 {
60 std::lock_guard<std::mutex> autoLock(g_mutex);
61 g_notTrustedDevices.insert(deviceIdHash);
62 }
63
DelNotTrustDevice(const char *udid)64 void DelNotTrustDevice(const char *udid)
65 {
66 if (udid == nullptr) {
67 LNN_LOGE(LNN_STATE, "udid is null");
68 return;
69 }
70 uint8_t udidHash[SHA_256_HASH_LEN] = {0};
71 char hashStr[CUST_UDID_LEN + 1] = {0};
72 if (SoftBusGenerateStrHash((const unsigned char *)udid, strlen(udid), udidHash) != SOFTBUS_OK) {
73 LNN_LOGE(LNN_STATE, "generate udidhash fail");
74 return;
75 }
76 if (ConvertBytesToHexString(hashStr, CUST_UDID_LEN + 1, udidHash, CUST_UDID_LEN / HEXIFY_UNIT_LEN) != SOFTBUS_OK) {
77 LNN_LOGE(LNN_STATE, "convert udidhash hex string fail");
78 return;
79 }
80 std::lock_guard<std::mutex> autoLock(g_mutex);
81 if (g_notTrustedDevices.find(hashStr) != g_notTrustedDevices.end()) {
82 LNN_LOGI(LNN_STATE, "remove not trust device");
83 g_notTrustedDevices.erase(hashStr);
84 return;
85 }
86 LNN_LOGI(LNN_STATE, "not need remove");
87 }
88
IsTrustDevice(std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> &trustDevices, const char *deviceIdHash, const char *anonyDeviceIdHash)89 static bool IsTrustDevice(std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> &trustDevices,
90 const char *deviceIdHash, const char *anonyDeviceIdHash)
91 {
92 for (const auto &trustDevice : trustDevices) {
93 if (trustDevice.GetDeviceIdType() != (uint32_t)OHOS::DistributedDeviceProfile::DeviceIdType::UDID ||
94 trustDevice.GetBindType() == (uint32_t)OHOS::DistributedDeviceProfile::BindType::SAME_ACCOUNT ||
95 trustDevice.GetTrustDeviceId().empty()) {
96 continue;
97 }
98 char *anonyUdid = nullptr;
99 Anonymize(trustDevice.GetTrustDeviceId().c_str(), &anonyUdid);
100 LNN_LOGI(LNN_STATE, "udid=%{public}s, deviceIdHash=%{public}s",
101 AnonymizeWrapper(anonyUdid), anonyDeviceIdHash);
102 AnonymizeFree(anonyUdid);
103 uint8_t udidHash[SHA_256_HASH_LEN] = {0};
104 char hashStr[CUST_UDID_LEN + 1] = {0};
105 if (SoftBusGenerateStrHash((const unsigned char *)trustDevice.GetTrustDeviceId().c_str(),
106 trustDevice.GetTrustDeviceId().length(), udidHash) != SOFTBUS_OK) {
107 LNN_LOGE(LNN_STATE, "generate udidhash fail");
108 continue;
109 }
110 if (ConvertBytesToHexString(hashStr, CUST_UDID_LEN + 1, udidHash,
111 CUST_UDID_LEN / HEXIFY_UNIT_LEN) != SOFTBUS_OK) {
112 LNN_LOGE(LNN_STATE, "convert udidhash hex string fail");
113 continue;
114 }
115 if (strncmp(hashStr, deviceIdHash, strlen(deviceIdHash)) == 0) {
116 LNN_LOGI(LNN_STATE, "device trusted in dp continue verify, deviceIdHash=%{public}s", anonyDeviceIdHash);
117 return true;
118 }
119 }
120 return false;
121 }
122
IsPotentialTrustedDeviceDp(const char *deviceIdHash)123 bool IsPotentialTrustedDeviceDp(const char *deviceIdHash)
124 {
125 if (deviceIdHash == nullptr) {
126 LNN_LOGE(LNN_STATE, "deviceIdHash is null");
127 return false;
128 }
129 if (IsNotTrustDevice(deviceIdHash)) {
130 LNN_LOGD(LNN_STATE, "device not trusted");
131 return false;
132 }
133 std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
134 int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
135 if (ret != OHOS::DistributedDeviceProfile::DP_NOT_FIND_DATA && ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
136 LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
137 return false;
138 }
139 if (aclProfiles.empty()) {
140 LNN_LOGE(LNN_STATE, "aclProfiles is empty");
141 InsertNotTrustDevice(deviceIdHash);
142 return false;
143 }
144 char *anonyDeviceIdHash = nullptr;
145 Anonymize(deviceIdHash, &anonyDeviceIdHash);
146 static uint32_t callCount = 0;
147 if (IsTrustDevice(aclProfiles, deviceIdHash, anonyDeviceIdHash)) {
148 AnonymizeFree(anonyDeviceIdHash);
149 return true;
150 }
151 InsertNotTrustDevice(deviceIdHash);
152 LNN_LOGI(LNN_STATE, "device is not trusted in dp, deviceIdHash=%{public}s, callCount=%{public}u",
153 AnonymizeWrapper(anonyDeviceIdHash), callCount++);
154 AnonymizeFree(anonyDeviceIdHash);
155 return false;
156 }
DumpAccountId(int64_t localAccountId, int64_t peerAccountId)157 static void DumpAccountId(int64_t localAccountId, int64_t peerAccountId)
158 {
159 char localAccountString[LONG_TO_STRING_MAX_LEN] = {0};
160 if (sprintf_s(localAccountString, LONG_TO_STRING_MAX_LEN, "%" PRId64, localAccountId) == -1) {
161 LNN_LOGE(LNN_STATE, "long to string fail");
162 return;
163 }
164
165 char peerAccountString[LONG_TO_STRING_MAX_LEN] = {0};
166 if (sprintf_s(peerAccountString, LONG_TO_STRING_MAX_LEN, "%" PRId64, peerAccountId) == -1) {
167 LNN_LOGE(LNN_STATE, "long to string fail");
168 return;
169 }
170
171 char *anonyLocalAccountId = nullptr;
172 char *anonyPeerAccountId = nullptr;
173 Anonymize(localAccountString, &anonyLocalAccountId);
174 Anonymize(peerAccountString, &anonyPeerAccountId);
175 LNN_LOGI(LNN_STATE, "localAccountId=%{public}s, peerAccountId=%{public}s",
176 AnonymizeWrapper(anonyLocalAccountId), AnonymizeWrapper(anonyPeerAccountId));
177 AnonymizeFree(anonyLocalAccountId);
178 AnonymizeFree(anonyPeerAccountId);
179 }
180
IsSameAccount(int64_t accountId)181 static bool IsSameAccount(int64_t accountId)
182 {
183 int64_t localAccountId = 0;
184 int32_t ret = LnnGetLocalNum64Info(NUM_KEY_ACCOUNT_LONG, &localAccountId);
185 if (ret != SOFTBUS_OK) {
186 LNN_LOGE(LNN_STATE, "get local accountId fail");
187 return false;
188 }
189 DumpAccountId(localAccountId, accountId);
190 if (localAccountId == accountId && !LnnIsDefaultOhosAccount()) {
191 return true;
192 }
193 return false;
194 }
195
GenerateDpAccesserAndAccessee(OHOS::DistributedDeviceProfile::Accesser &accesser, OHOS::DistributedDeviceProfile::Accessee &accessee, std::string peerUdid)196 static int32_t GenerateDpAccesserAndAccessee(OHOS::DistributedDeviceProfile::Accesser &accesser,
197 OHOS::DistributedDeviceProfile::Accessee &accessee, std::string peerUdid)
198 {
199 char udid[UDID_BUF_LEN] = {0};
200 if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, udid, UDID_BUF_LEN) != SOFTBUS_OK) {
201 LNN_LOGE(LNN_STATE, "get local udid fail");
202 return SOFTBUS_ERR;
203 }
204 std::string localUdid(udid);
205 accesser.SetAccesserDeviceId(localUdid);
206 accesser.SetAccesserUserId(GetActiveOsAccountIds());
207 OHOS::AccountSA::OhosAccountInfo accountInfo;
208 OHOS::ErrCode ret = OHOS::AccountSA::OhosAccountKits::GetInstance().GetOhosAccountInfo(accountInfo);
209 if (ret != OHOS::ERR_OK || accountInfo.uid_.empty()) {
210 LNN_LOGE(LNN_STATE, "getOhosAccountInfo fail ret=%{public}d", ret);
211 return SOFTBUS_ERR;
212 }
213 accesser.SetAccesserAccountId(accountInfo.uid_);
214 accessee.SetAccesseeDeviceId(peerUdid);
215 return SOFTBUS_OK;
216 }
217
InsertDpSameAccount(const std::string udid)218 static void InsertDpSameAccount(const std::string udid)
219 {
220 std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
221 int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
222 if (ret != OHOS::DistributedDeviceProfile::DP_NOT_FIND_DATA && ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
223 LNN_LOGE(LNN_STATE, "getAllAccessControlProfile failed, ret=%{public}d", ret);
224 return;
225 }
226 for (const auto &aclProfile : aclProfiles) {
227 if (aclProfile.GetDeviceIdType() == (uint32_t)OHOS::DistributedDeviceProfile::DeviceIdType::UDID &&
228 aclProfile.GetBindType() == (uint32_t)OHOS::DistributedDeviceProfile::BindType::SAME_ACCOUNT &&
229 udid == aclProfile.GetTrustDeviceId()) {
230 LNN_LOGI(LNN_STATE, "dp has same account no need insert");
231 return;
232 }
233 }
234
235 OHOS::DistributedDeviceProfile::AccessControlProfile accessControlProfile;
236 OHOS::DistributedDeviceProfile::Accesser accesser;
237 OHOS::DistributedDeviceProfile::Accessee accessee;
238 ret = GenerateDpAccesserAndAccessee(accesser, accessee, udid);
239 if (ret != SOFTBUS_OK) {
240 LNN_LOGE(LNN_STATE, "generate accesser accessee fail");
241 return;
242 }
243 accessControlProfile.SetBindType((uint32_t)OHOS::DistributedDeviceProfile::BindType::SAME_ACCOUNT);
244 accessControlProfile.SetDeviceIdType((uint32_t)OHOS::DistributedDeviceProfile::DeviceIdType::UDID);
245 accessControlProfile.SetStatus((uint32_t)OHOS::DistributedDeviceProfile::Status::ACTIVE);
246 accessControlProfile.SetAuthenticationType((uint32_t)OHOS::DistributedDeviceProfile::
247 AuthenticationType::PERMANENT);
248 accessControlProfile.SetTrustDeviceId(udid);
249 accessControlProfile.SetAccesser(accesser);
250 accessControlProfile.SetAccessee(accessee);
251 ret = DpClient::GetInstance().PutAccessControlProfile(accessControlProfile);
252 if (ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
253 LNN_LOGE(LNN_STATE, "putAccessControlProfile failed, ret=%{public}d", ret);
254 return;
255 }
256 char *anonyUdid = nullptr;
257 Anonymize(udid.c_str(), &anonyUdid);
258 LNN_LOGI(LNN_STATE, "insert dp same account succ, udid=%{public}s", AnonymizeWrapper(anonyUdid));
259 AnonymizeFree(anonyUdid);
260 }
261
UpdateDpSameAccount(int64_t accountId, const char *deviceId)262 void UpdateDpSameAccount(int64_t accountId, const char *deviceId)
263 {
264 if (deviceId == nullptr) {
265 LNN_LOGE(LNN_STATE, "deviceId is null");
266 return;
267 }
268 std::string udid(deviceId);
269 if (IsSameAccount(accountId)) {
270 InsertDpSameAccount(udid);
271 }
272 }
273
274