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", anonyUdid, anonyDeviceIdHash);
101 AnonymizeFree(anonyUdid);
102 uint8_t udidHash[SHA_256_HASH_LEN] = {0};
103 char hashStr[CUST_UDID_LEN + 1] = {0};
104 if (SoftBusGenerateStrHash((const unsigned char *)trustDevice.GetTrustDeviceId().c_str(),
105 trustDevice.GetTrustDeviceId().length(), udidHash) != SOFTBUS_OK) {
106 LNN_LOGE(LNN_STATE, "generate udidhash fail");
107 continue;
108 }
109 if (ConvertBytesToHexString(hashStr, CUST_UDID_LEN + 1, udidHash,
110 CUST_UDID_LEN / HEXIFY_UNIT_LEN) != SOFTBUS_OK) {
111 LNN_LOGE(LNN_STATE, "convert udidhash hex string fail");
112 continue;
113 }
114 if (strncmp(hashStr, deviceIdHash, strlen(deviceIdHash)) == 0) {
115 LNN_LOGI(LNN_STATE, "device trusted in dp continue verify, deviceIdHash=%{public}s", anonyDeviceIdHash);
116 return true;
117 }
118 }
119 return false;
120 }
121
IsPotentialTrustedDeviceDp(const char * deviceIdHash)122 bool IsPotentialTrustedDeviceDp(const char *deviceIdHash)
123 {
124 if (deviceIdHash == nullptr) {
125 LNN_LOGE(LNN_STATE, "deviceIdHash is null");
126 return false;
127 }
128 if (IsNotTrustDevice(deviceIdHash)) {
129 LNN_LOGD(LNN_STATE, "device not trusted");
130 return false;
131 }
132 std::vector<OHOS::DistributedDeviceProfile::AccessControlProfile> aclProfiles;
133 int32_t ret = DpClient::GetInstance().GetAllAccessControlProfile(aclProfiles);
134 if (ret != OHOS::DistributedDeviceProfile::DP_NOT_FIND_DATA && ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
135 LNN_LOGE(LNN_STATE, "GetAllAccessControlProfile ret=%{public}d", ret);
136 return false;
137 }
138 if (aclProfiles.empty()) {
139 LNN_LOGE(LNN_STATE, "aclProfiles is empty");
140 InsertNotTrustDevice(deviceIdHash);
141 return false;
142 }
143 char *anonyDeviceIdHash = nullptr;
144 Anonymize(deviceIdHash, &anonyDeviceIdHash);
145 static uint32_t callCount = 0;
146 if (IsTrustDevice(aclProfiles, deviceIdHash, anonyDeviceIdHash)) {
147 AnonymizeFree(anonyDeviceIdHash);
148 return true;
149 }
150 InsertNotTrustDevice(deviceIdHash);
151 LNN_LOGI(LNN_STATE, "device is not trusted in dp, deviceIdHash=%{public}s, callCount=%{public}u",
152 anonyDeviceIdHash, callCount++);
153 AnonymizeFree(anonyDeviceIdHash);
154 return false;
155 }
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
InsertDpSameAccount(const std::string peerUdid)196 static void InsertDpSameAccount(const std::string peerUdid)
197 {
198 OHOS::DistributedDeviceProfile::AccessControlProfile accessControlProfile;
199 OHOS::DistributedDeviceProfile::Accesser accesser;
200 OHOS::DistributedDeviceProfile::Accessee accessee;
201 char udid[UDID_BUF_LEN] = {0};
202 if (LnnGetLocalStrInfo(STRING_KEY_DEV_UDID, udid, UDID_BUF_LEN) != SOFTBUS_OK) {
203 LNN_LOGE(LNN_STATE, "get local udid fail");
204 return;
205 }
206 std::string localUdid(udid);
207 accesser.SetAccesserDeviceId(localUdid);
208 accesser.SetAccesserUserId(GetActiveOsAccountIds());
209 OHOS::AccountSA::OhosAccountInfo accountInfo;
210 OHOS::ErrCode ret = OHOS::AccountSA::OhosAccountKits::GetInstance().GetOhosAccountInfo(accountInfo);
211 if (ret != OHOS::ERR_OK || accountInfo.uid_.empty()) {
212 LNN_LOGE(LNN_STATE, "getOhosAccountInfo fail ret=%{public}d", ret);
213 return;
214 }
215 accesser.SetAccesserAccountId(accountInfo.uid_);
216 accessee.SetAccesseeDeviceId(peerUdid);
217 accessControlProfile.SetBindType((uint32_t)OHOS::DistributedDeviceProfile::BindType::SAME_ACCOUNT);
218 accessControlProfile.SetDeviceIdType((uint32_t)OHOS::DistributedDeviceProfile::DeviceIdType::UDID);
219 accessControlProfile.SetStatus((uint32_t)OHOS::DistributedDeviceProfile::Status::ACTIVE);
220 accessControlProfile.SetAuthenticationType((uint32_t)OHOS::DistributedDeviceProfile::
221 AuthenticationType::PERMANENT);
222 accessControlProfile.SetTrustDeviceId(peerUdid);
223 accessControlProfile.SetAccesser(accesser);
224 accessControlProfile.SetAccessee(accessee);
225 ret = DpClient::GetInstance().PutAccessControlProfile(accessControlProfile);
226 if (ret != OHOS::DistributedDeviceProfile::DP_SUCCESS) {
227 LNN_LOGE(LNN_STATE, "putAccessControlProfile failed, ret=%{public}d", ret);
228 return;
229 }
230 char *anonyUdid = nullptr;
231 Anonymize(peerUdid.c_str(), &anonyUdid);
232 LNN_LOGI(LNN_STATE, "insert dp same account succ, udid=%{public}s", anonyUdid);
233 AnonymizeFree(anonyUdid);
234 }
235
UpdateDpSameAccount(int64_t accountId,const char * deviceId)236 void UpdateDpSameAccount(int64_t accountId, const char *deviceId)
237 {
238 if (deviceId == nullptr) {
239 LNN_LOGE(LNN_STATE, "deviceId is null");
240 return;
241 }
242 std::string peerUdid(deviceId);
243 if (IsSameAccount(accountId)) {
244 InsertDpSameAccount(peerUdid);
245 }
246 }
247