1 /*
2 * Copyright (c) 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 "dm_anonymous.h"
17 #include "dm_log.h"
18 #include <sstream>
19 #include <set>
20
21 namespace OHOS {
22 namespace DistributedHardware {
23 namespace {
24 constexpr uint32_t MAX_MESSAGE_LEN = 40 * 1024 * 1024;
25 constexpr uint32_t MAX_MAP_LEN = 1000;
26 constexpr uint32_t MAX_INT_LEN = 20;
27 constexpr uint32_t MAX_ID_LEN = 256;
28 }
29 const char* PRINT_LIST_SPLIT = ", ";
30 const int32_t LIST_SPLIT_LEN = 2;
31
GetAnonyString(const std::string & value)32 std::string GetAnonyString(const std::string &value)
33 {
34 const int32_t INT32_SHORT_ID_LENGTH = 20;
35 const int32_t INT32_PLAINTEXT_LENGTH = 4;
36 const int32_t INT32_MIN_ID_LENGTH = 3;
37
38 std::string tmpStr("******");
39 size_t strLen = value.length();
40 if (strLen < INT32_MIN_ID_LENGTH) {
41 return tmpStr;
42 }
43
44 std::string res;
45 if (strLen <= INT32_SHORT_ID_LENGTH) {
46 res += value[0];
47 res += tmpStr;
48 res += value[strLen - 1];
49 } else {
50 res.append(value, 0, INT32_PLAINTEXT_LENGTH);
51 res += tmpStr;
52 res.append(value, strLen - INT32_PLAINTEXT_LENGTH, INT32_PLAINTEXT_LENGTH);
53 }
54
55 return res;
56 }
57
GetAnonyStringList(const std::vector<std::string> & values)58 std::string GetAnonyStringList(const std::vector<std::string> &values)
59 {
60 std::string temp = "[ ";
61 bool flag = false;
62 for (auto const &v : values) {
63 temp += GetAnonyString(v) + PRINT_LIST_SPLIT;
64 flag = true;
65 }
66 if (flag) {
67 temp.erase(temp.length() - LIST_SPLIT_LEN);
68 }
69 temp += " ]";
70 return temp;
71 }
72
GetAnonyInt32(const int32_t value)73 std::string GetAnonyInt32(const int32_t value)
74 {
75 std::string tempString = std::to_string(value);
76 size_t length = tempString.length();
77 if (length == 0x01) {
78 tempString[0] = '*';
79 return tempString;
80 }
81 for (size_t i = 1; i < length - 1; i++) {
82 tempString[i] = '*';
83 }
84 return tempString;
85 }
86
GetAnonyInt32List(const std::vector<int32_t> & values)87 std::string GetAnonyInt32List(const std::vector<int32_t> &values)
88 {
89 std::string temp = "[ ";
90 bool flag = false;
91 for (auto const &v : values) {
92 temp += GetAnonyInt32(v) + PRINT_LIST_SPLIT;
93 flag = true;
94 }
95 if (flag) {
96 temp.erase(temp.length() - LIST_SPLIT_LEN);
97 }
98 temp += " ]";
99 return temp;
100 }
101
IsNumberString(const std::string & inputString)102 bool IsNumberString(const std::string &inputString)
103 {
104 if (inputString.length() == 0 || inputString.length() > MAX_INT_LEN) {
105 LOGE("inputString is Null or inputString length is too long");
106 return false;
107 }
108 const int32_t MIN_ASCII_NUM = 48;
109 const int32_t MAX_ASCII_NUM = 57;
110 for (size_t i = 0; i < inputString.length(); i++) {
111 int num = (int)inputString[i];
112 if (num >= MIN_ASCII_NUM && num <= MAX_ASCII_NUM) {
113 continue;
114 } else {
115 return false;
116 }
117 }
118 return true;
119 }
120
IsString(const JsonItemObject & jsonObj,const std::string & key)121 bool IsString(const JsonItemObject &jsonObj, const std::string &key)
122 {
123 bool res = (jsonObj.Contains(key) && jsonObj[key].IsString()
124 && jsonObj[key].Get<std::string>().size() <= MAX_MESSAGE_LEN);
125 if (!res) {
126 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
127 }
128 return res;
129 }
130
IsInt32(const JsonItemObject & jsonObj,const std::string & key)131 bool IsInt32(const JsonItemObject &jsonObj, const std::string &key)
132 {
133 bool res = jsonObj.Contains(key) && jsonObj[key].IsNumberInteger() && jsonObj[key].Get<int64_t>() >= INT32_MIN &&
134 jsonObj[key].Get<int64_t>() <= INT32_MAX;
135 if (!res) {
136 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
137 }
138 return res;
139 }
140
IsUint32(const JsonItemObject & jsonObj,const std::string & key)141 bool IsUint32(const JsonItemObject &jsonObj, const std::string &key)
142 {
143 bool res = jsonObj.Contains(key) && jsonObj[key].IsNumberInteger() && jsonObj[key].Get<int64_t>() >= 0 &&
144 jsonObj[key].Get<int64_t>() <= UINT32_MAX;
145 if (!res) {
146 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
147 }
148 return res;
149 }
150
IsInt64(const JsonItemObject & jsonObj,const std::string & key)151 bool IsInt64(const JsonItemObject &jsonObj, const std::string &key)
152 {
153 bool res = jsonObj.Contains(key) && jsonObj[key].IsNumberInteger() && jsonObj[key].Get<int64_t>() >= INT64_MIN &&
154 jsonObj[key].Get<int64_t>() <= INT64_MAX;
155 if (!res) {
156 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
157 }
158 return res;
159 }
160
IsUint64(const JsonItemObject & jsonObj,const std::string & key)161 bool IsUint64(const JsonItemObject &jsonObj, const std::string &key)
162 {
163 bool res = jsonObj.Contains(key) && jsonObj[key].IsNumberInteger() && jsonObj[key].Get<uint64_t>() >= 0 &&
164 jsonObj[key].Get<uint64_t>() <= UINT64_MAX;
165 if (!res) {
166 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
167 }
168 return res;
169 }
170
IsArray(const JsonItemObject & jsonObj,const std::string & key)171 bool IsArray(const JsonItemObject &jsonObj, const std::string &key)
172 {
173 bool res = jsonObj.Contains(key) && jsonObj[key].IsArray();
174 if (!res) {
175 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
176 }
177 return res;
178 }
179
IsBool(const JsonItemObject & jsonObj,const std::string & key)180 bool IsBool(const JsonItemObject &jsonObj, const std::string &key)
181 {
182 bool res = jsonObj.Contains(key) && jsonObj[key].IsBoolean();
183 if (!res) {
184 LOGE("the key %{public}s in jsonObj is invalid.", key.c_str());
185 }
186 return res;
187 }
188
ConvertMapToJsonString(const std::map<std::string,std::string> & paramMap)189 std::string ConvertMapToJsonString(const std::map<std::string, std::string> ¶mMap)
190 {
191 std::string jsonStr = "";
192 if (paramMap.size() > MAX_MAP_LEN) {
193 LOGE("invalid paramMap");
194 return jsonStr;
195 }
196 if (!paramMap.empty()) {
197 JsonObject jsonObj;
198 for (const auto &it : paramMap) {
199 jsonObj[it.first] = it.second;
200 }
201 jsonStr = jsonObj.Dump();
202 }
203 return jsonStr;
204 }
205
ParseMapFromJsonString(const std::string & jsonStr,std::map<std::string,std::string> & paramMap)206 void ParseMapFromJsonString(const std::string &jsonStr, std::map<std::string, std::string> ¶mMap)
207 {
208 if (jsonStr.empty()) {
209 return;
210 }
211 if (paramMap.size() > MAX_MAP_LEN) {
212 LOGE("invalid paramMap");
213 return;
214 }
215 JsonObject paramJson(jsonStr);
216 if (paramJson.IsDiscarded()) {
217 return;
218 }
219 for (auto &element : paramJson.Items()) {
220 if (element.IsString()) {
221 paramMap.insert(std::pair<std::string, std::string>(element.Key(), element.Get<std::string>()));
222 }
223 }
224 }
225
IsInvalidPeerTargetId(const PeerTargetId & targetId)226 bool IsInvalidPeerTargetId(const PeerTargetId &targetId)
227 {
228 return targetId.deviceId.empty() && targetId.brMac.empty() && targetId.bleMac.empty() && targetId.wifiIp.empty();
229 }
230
ConvertCharArray2String(const char * srcData,uint32_t srcLen)231 std::string ConvertCharArray2String(const char *srcData, uint32_t srcLen)
232 {
233 if (srcData == nullptr || srcLen == 0 || srcLen >= MAX_MESSAGE_LEN) {
234 LOGE("Invalid parameter.");
235 return "";
236 }
237 char *dstData = new char[srcLen + 1]();
238 if (memcpy_s(dstData, srcLen + 1, srcData, srcLen) != 0) {
239 LOGE("memcpy_s failed.");
240 delete[] dstData;
241 return "";
242 }
243 std::string temp(dstData);
244 delete[] dstData;
245 return temp;
246 }
247
StringToInt(const std::string & str,int32_t base)248 int32_t StringToInt(const std::string &str, int32_t base)
249 {
250 if (str.empty()) {
251 LOGE("Str is empty.");
252 return 0;
253 }
254 char *nextPtr = nullptr;
255 long result = strtol(str.c_str(), &nextPtr, base);
256 if (errno == ERANGE || *nextPtr != '\0') {
257 LOGE("parse int error");
258 return 0;
259 }
260 return static_cast<int32_t>(result);
261 }
262
StringToInt64(const std::string & str,int32_t base)263 int64_t StringToInt64(const std::string &str, int32_t base)
264 {
265 if (str.empty()) {
266 LOGE("Str is empty.");
267 return 0;
268 }
269 char *nextPtr = nullptr;
270 int64_t result = strtoll(str.c_str(), &nextPtr, base);
271 if (errno == ERANGE || nextPtr == nullptr || nextPtr == str.c_str() || *nextPtr != '\0') {
272 LOGE("parse int error");
273 return 0;
274 }
275 return result;
276 }
277
VersionSplitToInt(const std::string & str,const char split,std::vector<int> & numVec)278 void VersionSplitToInt(const std::string &str, const char split, std::vector<int> &numVec)
279 {
280 std::istringstream iss(str);
281 std::string item = "";
282 while (getline(iss, item, split)) {
283 numVec.push_back(atoi(item.c_str()));
284 }
285 }
286
CompareVecNum(const std::vector<int32_t> & srcVecNum,const std::vector<int32_t> & sinkVecNum)287 bool CompareVecNum(const std::vector<int32_t> &srcVecNum, const std::vector<int32_t> &sinkVecNum)
288 {
289 for (uint32_t index = 0; index < std::min(srcVecNum.size(), sinkVecNum.size()); index++) {
290 if (srcVecNum[index] > sinkVecNum[index]) {
291 return true;
292 } else if (srcVecNum[index] < sinkVecNum[index]) {
293 return false;
294 } else {
295 continue;
296 }
297 }
298 if (srcVecNum.size() > sinkVecNum.size()) {
299 return true;
300 }
301 return false;
302 }
303
CompareVersion(const std::string & remoteVersion,const std::string & oldVersion)304 bool CompareVersion(const std::string &remoteVersion, const std::string &oldVersion)
305 {
306 LOGI("remoteVersion %{public}s, oldVersion %{public}s.", remoteVersion.c_str(), oldVersion.c_str());
307 std::vector<int32_t> remoteVersionVec;
308 std::vector<int32_t> oldVersionVec;
309 VersionSplitToInt(remoteVersion, '.', remoteVersionVec);
310 VersionSplitToInt(oldVersion, '.', oldVersionVec);
311 return CompareVecNum(remoteVersionVec, oldVersionVec);
312 }
313
GetVersionNumber(const std::string dmVersion,int32_t & versionNum)314 bool GetVersionNumber(const std::string dmVersion, int32_t &versionNum)
315 {
316 LOGI("dmVersion %{public}s,", dmVersion.c_str());
317 std::string number = "";
318 std::istringstream iss(dmVersion);
319 std::string item = "";
320 while (getline(iss, item, '.')) {
321 number += item;
322 }
323 LOGI("number %{public}s,", number.c_str());
324 versionNum = atoi(number.c_str());
325 if (versionNum <= 0) {
326 LOGE("convert failed, number: %{public}s,", number.c_str());
327 return false;
328 }
329 return true;
330 }
331
ComposeStr(const std::string & pkgName,uint16_t subscribeId)332 std::string ComposeStr(const std::string &pkgName, uint16_t subscribeId)
333 {
334 std::string strTemp = pkgName + "#" + std::to_string(subscribeId);
335 return strTemp;
336 }
337
GetCallerPkgName(const std::string & pkgName)338 std::string GetCallerPkgName(const std::string &pkgName)
339 {
340 std::istringstream stream(pkgName);
341 std::string item = "";
342 getline(stream, item, '#');
343 return item;
344 }
345
GetSubscribeId(const std::string & pkgName)346 uint16_t GetSubscribeId(const std::string &pkgName)
347 {
348 std::vector<std::string> strVec;
349 size_t subIdIndex = 1;
350 size_t start = 0;
351 size_t end = pkgName.find("#");
352
353 while (end != std::string::npos) {
354 strVec.push_back(pkgName.substr(start, end - start));
355 start = end + 1;
356 end = pkgName.find("#", start);
357 }
358 strVec.push_back(pkgName.substr(start));
359 if (strVec.size() >= subIdIndex + 1) {
360 return std::atoi(strVec.at(subIdIndex).c_str());
361 }
362 return 0;
363 }
364
IsIdLengthValid(const std::string & inputID)365 bool IsIdLengthValid(const std::string &inputID)
366 {
367 if (inputID.empty() || inputID.length() > MAX_ID_LEN) {
368 LOGE("On parameter length error, maybe empty or beyond MAX_ID_LEN!");
369 return false;
370 }
371 return true;
372 }
373
IsMessageLengthValid(const std::string & inputMessage)374 bool IsMessageLengthValid(const std::string &inputMessage)
375 {
376 if (inputMessage.empty() || inputMessage.length() > MAX_MESSAGE_LEN) {
377 LOGE("On parameter error, maybe empty or beyond MAX_MESSAGE_LEN!");
378 return false;
379 }
380 return true;
381 }
382
IsValueExist(const std::multimap<std::string,int32_t> unorderedmap,const std::string & udid,int32_t userId)383 bool IsValueExist(const std::multimap<std::string, int32_t> unorderedmap, const std::string &udid, int32_t userId)
384 {
385 for (const auto &item : unorderedmap) {
386 if (item.first == udid && item.second == userId) {
387 return true;
388 }
389 }
390 return false;
391 }
392
IsDmCommonNotifyEventValid(DmCommonNotifyEvent dmCommonNotifyEvent)393 bool IsDmCommonNotifyEventValid(DmCommonNotifyEvent dmCommonNotifyEvent)
394 {
395 if (dmCommonNotifyEvent > DmCommonNotifyEvent::MIN && dmCommonNotifyEvent < DmCommonNotifyEvent::MAX) {
396 return true;
397 }
398 return false;
399 }
400
GetSubStr(const std::string & rawStr,const std::string & separator,int32_t index)401 std::string GetSubStr(const std::string &rawStr, const std::string &separator, int32_t index)
402 {
403 if (rawStr.empty() || separator.empty() || index < 0) {
404 LOGE("param invalid");
405 return "";
406 }
407 std::vector<std::string> strVec;
408 size_t start = 0;
409 size_t end = rawStr.find(separator);
410
411 while (end != std::string::npos) {
412 strVec.push_back(rawStr.substr(start, end - start));
413 start = end + separator.size();
414 end = rawStr.find(separator, start);
415 }
416 strVec.push_back(rawStr.substr(start));
417 if (strVec.size() >= static_cast<size_t>(index + 1)) {
418 return strVec.at(index);
419 }
420 LOGE("get failed");
421 return "";
422 }
423
IsJsonValIntegerString(const JsonItemObject & jsonObj,const std::string & key)424 bool IsJsonValIntegerString(const JsonItemObject &jsonObj, const std::string &key)
425 {
426 if (!IsString(jsonObj, key)) {
427 LOGE("%{public}s is not string", key.c_str());
428 return false;
429 }
430 std::string retValStr = jsonObj[key].Get<std::string>();
431 if (!IsNumberString(retValStr)) {
432 LOGE("%{public}s is not number", key.c_str());
433 return false;
434 }
435 return true;
436 }
437
GetAnonyJsonString(const std::string & value)438 std::string GetAnonyJsonString(const std::string &value)
439 {
440 if (value.empty()) {
441 return "";
442 }
443 JsonObject paramJson(value);
444 if (paramJson.IsDiscarded()) {
445 return "";
446 }
447 const std::set<std::string> sensitiveKey = { "LOCALDEVICEID", "localAccountId", "networkId", "lnnPublicKey",
448 "transmitPublicKey", "DEVICEID", "deviceId", "keyValue", "deviceName", "REMOTE_DEVICE_NAME", "data" };
449
450 for (auto &element : paramJson.Items()) {
451 if (element.IsString() && sensitiveKey.find(element.Key()) != sensitiveKey.end()) {
452 paramJson[element.Key()] = GetAnonyString(element.Get<std::string>());
453 }
454 }
455 return paramJson.Dump();
456 }
457
GetCurrentTimestamp()458 int64_t GetCurrentTimestamp()
459 {
460 auto now = std::chrono::system_clock::now();
461 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
462 return duration.count();
463 }
464 } // namespace DistributedHardware
465 } // namespace OHOS