1 /*
2 * Copyright (C) 2022-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 permissions and
13 * limitations under the License.
14 */
15
16 #include "netmanager_base_common_utils.h"
17
18 #include <algorithm>
19 #include <arpa/inet.h>
20 #include <cstddef>
21 #include <cstdlib>
22 #include <netinet/in.h>
23 #include <regex>
24 #include <sstream>
25 #include <set>
26 #include <string>
27 #include <sys/socket.h>
28 #include <sys/wait.h>
29 #include <thread>
30 #include <type_traits>
31 #include <unistd.h>
32 #include <vector>
33 #include <numeric>
34 #include <fstream>
35 #include <random>
36
37 #include "net_manager_constants.h"
38 #include "net_mgr_log_wrapper.h"
39 #include "securec.h"
40
41 namespace OHOS::NetManagerStandard::CommonUtils {
42 constexpr int32_t INET_OPTION_SUC = 1;
43 constexpr int32_t DECIMAL_SYSTEM = 10;
44 constexpr uint32_t CONST_MASK = 0x80000000;
45 constexpr size_t MAX_DISPLAY_NUM = 2;
46 constexpr uint32_t IPV4_DOT_NUM = 3;
47 constexpr int32_t MIN_BYTE = 0;
48 constexpr int32_t MAX_BYTE = 255;
49 constexpr int32_t BYTE_16 = 16;
50 constexpr uint32_t BIT_NUM_BYTE = 8;
51 constexpr int32_t BITS_32 = 32;
52 constexpr int32_t BITS_24 = 24;
53 constexpr int32_t BITS_16 = 16;
54 constexpr int32_t BITS_8 = 8;
55 constexpr uint32_t INTERFACE_NAME_MAX_SIZE = 16;
56 constexpr int32_t CHAR_ARRAY_SIZE_MAX = 1024;
57 constexpr int32_t PIPE_FD_NUM = 2;
58 constexpr int32_t PIPE_OUT = 0;
59 constexpr int32_t PIPE_IN = 1;
60 constexpr int32_t DOMAIN_VALID_MIN_PART_SIZE = 2;
61 constexpr int32_t DOMAIN_VALID_MAX_PART_SIZE = 5;
62 constexpr int32_t NET_MASK_MAX_LENGTH = 32;
63 constexpr int32_t NET_MASK_GROUP_COUNT = 4;
64 constexpr int32_t MAX_IPV6_PREFIX_LENGTH = 128;
65 constexpr int32_t WAIT_FOR_PID_TIME_MS = 20;
66 constexpr int32_t MAX_WAIT_PID_COUNT = 500;
67 const std::string IPADDR_DELIMITER = ".";
68 constexpr const char *CMD_SEP = " ";
69 constexpr const char *DOMAIN_DELIMITER = ".";
70 constexpr const char *TLDS_SPLIT_SYMBOL = "|";
71 constexpr const char *HOST_DOMAIN_PATTERN_HEADER = "^(https?://)?[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.(";
72 constexpr const char *HOST_DOMAIN_PATTERN_TAIL = ")$";
73 constexpr const char *DEFAULT_IPV6_ANY_INIT_ADDR = "::";
74 const std::regex IP_PATTERN{
75 "((2([0-4]\\d|5[0-5])|1\\d\\d|[1-9]\\d|\\d)\\.){3}(2([0-4]\\d|5[0-5])|1\\d\\d|[1-9]\\d|\\d)"};
76
77 const std::regex IP_MASK_PATTERN{
78 "((2([0-4]\\d|5[0-5])|1\\d\\d|[1-9]\\d|\\d)\\.){3}(2([0-4]\\d|5[0-5])|1\\d\\d|[1-9]\\d|\\d)/"
79 "(3[0-2]|[1-2]\\d|\\d)"};
80
81 const std::regex IPV6_PATTERN{"([\\da-fA-F]{0,4}:){2,7}([\\da-fA-F]{0,4})"};
82
83 const std::regex IPV6_MASK_PATTERN{"([\\da-fA-F]{0,4}:){2,7}([\\da-fA-F]{0,4})/(1[0-2][0-8]|[1-9]\\d|[1-9])"};
84
85 std::vector<std::string> HOST_DOMAIN_TLDS{"com", "net", "org", "edu", "gov", "mil", "cn", "hk", "tw",
86 "jp", "de", "uk", "fr", "au", "ca", "br", "ru", "it",
87 "es", "in", "online", "shop", "vip", "club", "xyz", "top", "icu",
88 "work", "website", "tech", "asia", "xin", "co", "mobi", "info"};
89 constexpr const char *BUNDLENAME_DELIMITER = ",";
90 constexpr const char *SIM_APP_BUNDLENAMES = "com.example.sim.tmp,com.example.sim";
91 constexpr const char *INSTALL_SOURCE_FROM_SIM = "com.sim.installSource";
92 constexpr const char *SIM2_BUNDLENAMES = "com.phony.bundleName.temp,com.phony.bundleName";
93 constexpr const char *INSTALL_SOURCE_FROM_SIM2 = "com.phony.installSource";
94 std::mutex g_commonUtilsMutex;
95
Strip(const std::string & str,char ch)96 std::string Strip(const std::string &str, char ch)
97 {
98 auto size = static_cast<int64_t>(str.size());
99 int64_t i = 0;
100 while (i < size && str[i] == ch) {
101 ++i;
102 }
103 int64_t j = size - 1;
104 while (j > 0 && str[j] == ch) {
105 --j;
106 }
107 if (i >= 0 && i < size && j >= 0 && j < size && j - i + 1 > 0) {
108 return str.substr(i, j - i + 1);
109 }
110 return "";
111 }
112
ToLower(const std::string & s)113 std::string ToLower(const std::string &s)
114 {
115 std::string res = s;
116 std::transform(res.begin(), res.end(), res.begin(), tolower);
117 return res;
118 }
119
IsValidIPV4(const std::string & ip)120 bool IsValidIPV4(const std::string &ip)
121 {
122 if (ip.empty()) {
123 return false;
124 }
125 struct in_addr s;
126 return inet_pton(AF_INET, ip.c_str(), reinterpret_cast<void *>(&s)) == INET_OPTION_SUC;
127 }
128
IsValidIPV6(const std::string & ip)129 bool IsValidIPV6(const std::string &ip)
130 {
131 if (ip.empty()) {
132 return false;
133 }
134 struct in6_addr s;
135 return inet_pton(AF_INET6, ip.c_str(), reinterpret_cast<void *>(&s)) == INET_OPTION_SUC;
136 }
137
GetAddrFamily(const std::string & ip)138 int8_t GetAddrFamily(const std::string &ip)
139 {
140 if (IsValidIPV4(ip)) {
141 return AF_INET;
142 }
143 if (IsValidIPV6(ip)) {
144 return AF_INET6;
145 }
146 return 0;
147 }
148
GetMaskLength(const std::string & mask)149 int GetMaskLength(const std::string &mask)
150 {
151 int netMask = 0;
152 unsigned int maskTmp = ntohl(static_cast<int>(inet_addr(mask.c_str())));
153 while (maskTmp & CONST_MASK) {
154 ++netMask;
155 maskTmp = (maskTmp << 1);
156 }
157 return netMask;
158 }
159
GetMaskByLength(uint32_t length)160 std::string GetMaskByLength(uint32_t length)
161 {
162 const uint32_t mask = length == 0 ? 0 : 0xFFFFFFFF << (NET_MASK_MAX_LENGTH - length);
163 auto maskGroup = new int[NET_MASK_GROUP_COUNT];
164 for (int i = 0; i < NET_MASK_GROUP_COUNT; i++) {
165 int pos = NET_MASK_GROUP_COUNT - 1 - i;
166 maskGroup[pos] = (static_cast<uint32_t>(mask) >> (i * BIT_NUM_BYTE)) & 0x000000ff;
167 }
168 std::string sMask = "" + std::to_string(maskGroup[0]);
169 for (int i = 1; i < NET_MASK_GROUP_COUNT; i++) {
170 sMask = sMask + "." + std::to_string(maskGroup[i]);
171 }
172 delete[] maskGroup;
173 return sMask;
174 }
175
GetIpv6Prefix(const std::string & ipv6Addr,uint8_t prefixLen)176 std::string GetIpv6Prefix(const std::string &ipv6Addr, uint8_t prefixLen)
177 {
178 if (prefixLen >= MAX_IPV6_PREFIX_LENGTH) {
179 return ipv6Addr;
180 }
181
182 in6_addr ipv6AddrBuf = IN6ADDR_ANY_INIT;
183 inet_pton(AF_INET6, ipv6Addr.c_str(), &ipv6AddrBuf);
184
185 char buf[INET6_ADDRSTRLEN] = {0};
186 if (inet_ntop(AF_INET6, &ipv6AddrBuf, buf, INET6_ADDRSTRLEN) == nullptr) {
187 return ipv6Addr;
188 }
189
190 in6_addr ipv6Prefix = IN6ADDR_ANY_INIT;
191 uint32_t byteIndex = prefixLen / BIT_NUM_BYTE;
192 if (memset_s(ipv6Prefix.s6_addr, sizeof(ipv6Prefix.s6_addr), 0, sizeof(ipv6Prefix.s6_addr)) != EOK ||
193 memcpy_s(ipv6Prefix.s6_addr, sizeof(ipv6Prefix.s6_addr), &ipv6AddrBuf, byteIndex) != EOK) {
194 return DEFAULT_IPV6_ANY_INIT_ADDR;
195 }
196 uint32_t bitOffset = prefixLen & 0x7;
197 if ((bitOffset != 0) && (byteIndex < INET_ADDRSTRLEN)) {
198 ipv6Prefix.s6_addr[byteIndex] = ipv6AddrBuf.s6_addr[byteIndex] & (0xff00 >> bitOffset);
199 }
200 char ipv6PrefixBuf[INET6_ADDRSTRLEN] = {0};
201 inet_ntop(AF_INET6, &ipv6Prefix, ipv6PrefixBuf, INET6_ADDRSTRLEN);
202 return ipv6PrefixBuf;
203 }
204
ConvertIpv4Address(uint32_t addressIpv4)205 std::string ConvertIpv4Address(uint32_t addressIpv4)
206 {
207 if (addressIpv4 == 0) {
208 return "";
209 }
210
211 std::ostringstream stream;
212 stream << ((addressIpv4 >> BITS_24) & 0xFF) << IPADDR_DELIMITER << ((addressIpv4 >> BITS_16) & 0xFF)
213 << IPADDR_DELIMITER << ((addressIpv4 >> BITS_8) & 0xFF) << IPADDR_DELIMITER << (addressIpv4 & 0xFF);
214 return stream.str();
215 }
216
ConvertIpv4Address(const std::string & address)217 uint32_t ConvertIpv4Address(const std::string &address)
218 {
219 std::string tmpAddress = address;
220 uint32_t addrInt = 0;
221 uint32_t i = 0;
222 for (i = 0; i < IPV4_DOT_NUM; i++) {
223 std::string::size_type npos = tmpAddress.find(IPADDR_DELIMITER);
224 if (npos == std::string::npos) {
225 break;
226 }
227 const auto &value = tmpAddress.substr(0, npos);
228 int32_t itmp = std::atoi(value.c_str());
229 if ((itmp < MIN_BYTE) || (itmp > MAX_BYTE)) {
230 break;
231 }
232 uint32_t utmp = static_cast<uint32_t>(itmp);
233 addrInt += utmp << ((IPV4_DOT_NUM - i) * BIT_NUM_BYTE);
234 tmpAddress = tmpAddress.substr(npos + 1);
235 }
236
237 if (i != IPV4_DOT_NUM) {
238 return 0;
239 }
240 int32_t itmp = std::atoi(tmpAddress.c_str());
241 if ((itmp < MIN_BYTE) || (itmp > MAX_BYTE)) {
242 return 0;
243 }
244 uint32_t utmp = static_cast<uint32_t>(itmp);
245 addrInt += utmp;
246
247 return addrInt;
248 }
249
Ipv4PrefixLen(const std::string & ip)250 int32_t Ipv4PrefixLen(const std::string &ip)
251 {
252 if (ip.empty()) {
253 return 0;
254 }
255 int32_t ret = 0;
256 uint32_t ipNum = 0;
257 uint8_t c1 = 0;
258 uint8_t c2 = 0;
259 uint8_t c3 = 0;
260 uint8_t c4 = 0;
261 int32_t cnt = 0;
262 ret = sscanf_s(ip.c_str(), "%hhu.%hhu.%hhu.%hhu", &c1, &c2, &c3, &c4);
263 if (ret != sizeof(int32_t)) {
264 return 0;
265 }
266 ipNum = (c1 << static_cast<uint32_t>(BITS_24)) | (c2 << static_cast<uint32_t>(BITS_16)) |
267 (c3 << static_cast<uint32_t>(BITS_8)) | c4;
268 if (ipNum == 0xFFFFFFFF) {
269 return BITS_32;
270 }
271 if (ipNum == 0xFFFFFF00) {
272 return BITS_24;
273 }
274 if (ipNum == 0xFFFF0000) {
275 return BITS_16;
276 }
277 if (ipNum == 0xFF000000) {
278 return BITS_8;
279 }
280 for (int32_t i = 0; i < BITS_32; i++) {
281 if ((ipNum << i) & 0x80000000) {
282 cnt++;
283 } else {
284 break;
285 }
286 }
287 return cnt;
288 }
289
Ipv6PrefixLen(const std::string & ip)290 int32_t Ipv6PrefixLen(const std::string &ip)
291 {
292 constexpr int32_t LENGTH_8 = 8;
293 constexpr int32_t LENGTH_7 = 7;
294 constexpr int32_t LENGTH_6 = 6;
295 constexpr int32_t LENGTH_5 = 5;
296 constexpr int32_t LENGTH_4 = 4;
297 constexpr int32_t LENGTH_3 = 3;
298 constexpr int32_t LENGTH_2 = 2;
299 constexpr int32_t LENGTH_1 = 1;
300 if (ip.empty()) {
301 return 0;
302 }
303 in6_addr addr{};
304 inet_pton(AF_INET6, ip.c_str(), &addr);
305 int32_t prefixLen = 0;
306 for (int32_t i = 0; i < BYTE_16; ++i) {
307 if (addr.s6_addr[i] == 0xFF) {
308 prefixLen += LENGTH_8;
309 } else if (addr.s6_addr[i] == 0xFE) {
310 prefixLen += LENGTH_7;
311 break;
312 } else if (addr.s6_addr[i] == 0xFC) {
313 prefixLen += LENGTH_6;
314 break;
315 } else if (addr.s6_addr[i] == 0xF8) {
316 prefixLen += LENGTH_5;
317 break;
318 } else if (addr.s6_addr[i] == 0xF0) {
319 prefixLen += LENGTH_4;
320 break;
321 } else if (addr.s6_addr[i] == 0xE0) {
322 prefixLen += LENGTH_3;
323 break;
324 } else if (addr.s6_addr[i] == 0xC0) {
325 prefixLen += LENGTH_2;
326 break;
327 } else if (addr.s6_addr[i] == 0x80) {
328 prefixLen += LENGTH_1;
329 break;
330 } else {
331 break;
332 }
333 }
334 return prefixLen;
335 }
336
ParseInt(const std::string & str,int32_t * value)337 bool ParseInt(const std::string &str, int32_t *value)
338 {
339 char *end;
340 long long v = strtoll(str.c_str(), &end, 10);
341 if (std::string(end) == str || *end != '\0' || v < INT_MIN || v > INT_MAX) {
342 return false;
343 }
344 *value = v;
345 return true;
346 }
347
ConvertToInt64(const std::string & str)348 int64_t ConvertToInt64(const std::string &str)
349 {
350 return strtoll(str.c_str(), nullptr, DECIMAL_SYSTEM);
351 }
352
MaskIpv4(std::string & maskedResult)353 std::string MaskIpv4(std::string &maskedResult)
354 {
355 int maxDisplayNum = MAX_DISPLAY_NUM;
356 for (char &i : maskedResult) {
357 if (i == '/') {
358 break;
359 }
360 if (maxDisplayNum > 0) {
361 if (i == '.') {
362 maxDisplayNum--;
363 }
364 } else {
365 if (i != '.') {
366 i = '*';
367 }
368 }
369 }
370 return maskedResult;
371 }
372
MaskIpv6(std::string & maskedResult)373 std::string MaskIpv6(std::string &maskedResult)
374 {
375 size_t colonCount = 0;
376 for (char &i : maskedResult) {
377 if (i == '/') {
378 break;
379 }
380 if (i == ':') {
381 colonCount++;
382 }
383
384 if (colonCount >= MAX_DISPLAY_NUM) { // An legal ipv6 address has at least 2 ':'.
385 if (i != ':' && i != '/') {
386 i = '*';
387 }
388 }
389 }
390 return maskedResult;
391 }
392
ToAnonymousIp(const std::string & input)393 std::string ToAnonymousIp(const std::string &input)
394 {
395 std::lock_guard<std::mutex> lock(g_commonUtilsMutex);
396 std::string maskedResult{input};
397 // Mask ipv4 address.
398 if (std::regex_match(maskedResult, IP_PATTERN) || std::regex_match(maskedResult, IP_MASK_PATTERN)) {
399 return MaskIpv4(maskedResult);
400 }
401 // Mask ipv6 address.
402 if (std::regex_match(maskedResult, IPV6_PATTERN) || std::regex_match(maskedResult, IPV6_MASK_PATTERN)) {
403 return MaskIpv6(maskedResult);
404 }
405 return input;
406 }
407
AnonymousIpInStr(const std::string & input)408 std::string AnonymousIpInStr(const std::string &input)
409 {
410 std::string result;
411 // Mask ipv4 address.
412 result = std::regex_replace(input, IP_PATTERN, "X.X.X.X");
413 // Mask ipv6 address.
414 result = std::regex_replace(result, IPV6_PATTERN, "X:X:X:X");
415 return result;
416 }
417
AnonymizeIptablesCommand(const std::string & command)418 std::string AnonymizeIptablesCommand(const std::string &command)
419 {
420 std::string temp{command};
421 std::transform(temp.cbegin(), temp.cend(), temp.begin(), [](char c) {
422 return std::isdigit(c) ? 'x' : c;
423 });
424 return temp;
425 }
426
StrToInt(const std::string & value,int32_t defaultErr)427 int32_t StrToInt(const std::string &value, int32_t defaultErr)
428 {
429 errno = 0;
430 char *pEnd = nullptr;
431 int64_t result = std::strtol(value.c_str(), &pEnd, 0);
432 if (pEnd == value.c_str() || (result < INT_MIN || result > LONG_MAX) || errno == ERANGE) {
433 return defaultErr;
434 }
435 return result;
436 }
437
StrToUint(const std::string & value,uint32_t defaultErr)438 uint32_t StrToUint(const std::string &value, uint32_t defaultErr)
439 {
440 errno = 0;
441 char *pEnd = nullptr;
442 uint64_t result = std::strtoul(value.c_str(), &pEnd, 0);
443 if (pEnd == value.c_str() || result > UINT32_MAX || errno == ERANGE) {
444 return defaultErr;
445 }
446 return result;
447 }
448
StrToBool(const std::string & value,bool defaultErr)449 bool StrToBool(const std::string &value, bool defaultErr)
450 {
451 errno = 0;
452 char *pEnd = nullptr;
453 uint64_t result = std::strtoul(value.c_str(), &pEnd, 0);
454 if (pEnd == value.c_str() || result > UINT32_MAX || errno == ERANGE) {
455 return defaultErr;
456 }
457 return static_cast<bool>(result);
458 }
459
StrToLong(const std::string & value,int64_t defaultErr)460 int64_t StrToLong(const std::string &value, int64_t defaultErr)
461 {
462 errno = 0;
463 char *pEnd = nullptr;
464 int64_t result = std::strtoll(value.c_str(), &pEnd, 0);
465 if (pEnd == value.c_str() || errno == ERANGE) {
466 return defaultErr;
467 }
468 return result;
469 }
470
StrToUint64(const std::string & value,uint64_t defaultErr)471 uint64_t StrToUint64(const std::string &value, uint64_t defaultErr)
472 {
473 errno = 0;
474 char *pEnd = nullptr;
475 uint64_t result = std::strtoull(value.c_str(), &pEnd, 0);
476 if (pEnd == value.c_str() || errno == ERANGE) {
477 return defaultErr;
478 }
479 return result;
480 }
481
CheckIfaceName(const std::string & name)482 bool CheckIfaceName(const std::string &name)
483 {
484 uint32_t index = 0;
485 if (name.empty()) {
486 return false;
487 }
488 size_t len = name.size();
489 if (len > INTERFACE_NAME_MAX_SIZE) {
490 return false;
491 }
492 while (index < len) {
493 if ((index == 0) && !isalnum(name[index])) {
494 return false;
495 }
496 if (!isalnum(name[index]) && (name[index] != '-') && (name[index] != '_') && (name[index] != '.') &&
497 (name[index] != ':')) {
498 return false;
499 }
500 index++;
501 }
502 return true;
503 }
504
FormatCmd(const std::vector<std::string> & cmd)505 std::vector<const char *> FormatCmd(const std::vector<std::string> &cmd)
506 {
507 std::vector<const char *> res;
508 res.reserve(cmd.size() + 1);
509
510 // string is converted to char * and the result is saved in res
511 std::transform(cmd.begin(), cmd.end(), std::back_inserter(res), [](const std::string &str) { return str.c_str(); });
512 res.emplace_back(nullptr);
513 return res;
514 }
515
ForkExecChildProcess(const int32_t * pipeFd,int32_t count,const std::vector<const char * > & args)516 int32_t ForkExecChildProcess(const int32_t *pipeFd, int32_t count, const std::vector<const char *> &args)
517 {
518 NETMGR_LOG_D("Fork OK");
519 if (count != PIPE_FD_NUM) {
520 NETMGR_LOG_E("fork exec parent process failed");
521 _exit(-1);
522 }
523 NETMGR_LOG_D("Fork done and ready to close");
524 if (close(pipeFd[PIPE_OUT]) != 0) {
525 NETMGR_LOG_E("close failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
526 _exit(-1);
527 }
528 NETMGR_LOG_D("Close done and ready for dup2");
529 if (dup2(pipeFd[PIPE_IN], STDOUT_FILENO) == -1) {
530 NETMGR_LOG_E("dup2 failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
531 _exit(-1);
532 }
533 NETMGR_LOG_D("ready for execv");
534 if (execv(args[0], const_cast<char *const *>(&args[0])) == -1) {
535 NETMGR_LOG_E("execv command failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
536 }
537 NETMGR_LOG_D("execv done");
538 if (close(pipeFd[PIPE_IN]) != 0) {
539 NETMGR_LOG_E("close failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
540 _exit(-1);
541 }
542 _exit(-1);
543 }
544
ForkExecParentProcess(const int32_t * pipeFd,int32_t count,pid_t childPid,std::string * out)545 int32_t ForkExecParentProcess(const int32_t *pipeFd, int32_t count, pid_t childPid, std::string *out)
546 {
547 if (count != PIPE_FD_NUM) {
548 NETMGR_LOG_E("fork exec parent process failed");
549 return NETMANAGER_ERROR;
550 }
551 if (close(pipeFd[PIPE_IN]) != 0) {
552 NETMGR_LOG_E("close failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
553 }
554 if (out != nullptr) {
555 char buf[CHAR_ARRAY_SIZE_MAX] = {0};
556 out->clear();
557 NETMGR_LOG_D("ready for read");
558 while (read(pipeFd[PIPE_OUT], buf, CHAR_ARRAY_SIZE_MAX - 1) > 0) {
559 out->append(buf);
560 if (memset_s(buf, sizeof(buf), 0, sizeof(buf)) != 0) {
561 NETMGR_LOG_E("memset is false");
562 }
563 }
564 }
565 NETMGR_LOG_D("read done");
566 if (close(pipeFd[PIPE_OUT]) != 0) {
567 NETMGR_LOG_E("close failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
568 }
569 int status = 0;
570 pid_t pidRet;
571 int waitCount;
572 for (waitCount = 0; waitCount < MAX_WAIT_PID_COUNT; waitCount++) {
573 pidRet = waitpid(childPid, &status, WNOHANG);
574 if (pidRet == 0) {
575 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_FOR_PID_TIME_MS));
576 } else {
577 break;
578 }
579 }
580 if (waitCount == MAX_WAIT_PID_COUNT) {
581 NETMGR_LOG_E("waitpid[%{public}d] timeout", childPid);
582 return NETMANAGER_ERROR;
583 }
584 if (pidRet != childPid) {
585 NETMGR_LOG_E("waitpid[%{public}d] failed, pidRet:%{public}d", childPid, pidRet);
586 return NETMANAGER_ERROR;
587 }
588 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
589 // child process abnormal exit
590 NETMGR_LOG_E("child process abnormal exit, status:%{public}d", status);
591 }
592 NETMGR_LOG_I("waitpid %{public}d done", childPid);
593 return NETMANAGER_SUCCESS;
594 }
595
ForkExec(const std::string & command,std::string * out)596 int32_t ForkExec(const std::string &command, std::string *out)
597 {
598 const std::vector<std::string> cmd = Split(command, CMD_SEP);
599 std::vector<const char *> args = FormatCmd(cmd);
600 int32_t pipeFd[PIPE_FD_NUM] = {0};
601 if (pipe(pipeFd) < 0) {
602 NETMGR_LOG_E("creat pipe failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
603 return NETMANAGER_ERROR;
604 }
605 NETMGR_LOG_D("ForkExec");
606 pid_t pid = fork();
607 NETMGR_LOG_D("ForkDone %{public}d", pid);
608 if (pid < 0) {
609 NETMGR_LOG_E("fork failed, errorno:%{public}d, errormsg:%{public}s", errno, strerror(errno));
610 return NETMANAGER_ERROR;
611 }
612 if (pid == 0) {
613 ForkExecChildProcess(pipeFd, PIPE_FD_NUM, args);
614 return NETMANAGER_SUCCESS;
615 } else {
616 return ForkExecParentProcess(pipeFd, PIPE_FD_NUM, pid, out);
617 }
618 }
619
IsValidDomain(const std::string & domain)620 bool IsValidDomain(const std::string &domain)
621 {
622 if (domain.empty()) {
623 return false;
624 }
625
626 std::string pattern = HOST_DOMAIN_PATTERN_HEADER;
627 pattern = std::accumulate(HOST_DOMAIN_TLDS.begin(), HOST_DOMAIN_TLDS.end(), pattern,
628 [](const std::string &pattern, const std::string &tlds) { return pattern + tlds + TLDS_SPLIT_SYMBOL; });
629 pattern = pattern.replace(pattern.size() - 1, 1, "") + HOST_DOMAIN_PATTERN_TAIL;
630 std::regex reg(pattern);
631 if (!std::regex_match(domain, reg)) {
632 NETMGR_LOG_E("Domain regex match failed.");
633 return false;
634 }
635
636 std::vector<std::string> parts = Split(domain, DOMAIN_DELIMITER);
637 if (parts.size() < DOMAIN_VALID_MIN_PART_SIZE || parts.size() > DOMAIN_VALID_MAX_PART_SIZE) {
638 NETMGR_LOG_E("The domain parts size:[%{public}d] is invalid", static_cast<int>(parts.size()));
639 return false;
640 }
641
642 std::set<std::string> tldsList;
643 for (const auto &item : parts) {
644 if (std::find(HOST_DOMAIN_TLDS.begin(), HOST_DOMAIN_TLDS.end(), item) == HOST_DOMAIN_TLDS.end()) {
645 continue;
646 }
647 if (tldsList.find(item) != tldsList.end()) {
648 NETMGR_LOG_E("Domain has duplicate tlds:%{public}s", item.c_str());
649 return false;
650 }
651 tldsList.insert(item);
652 }
653 return true;
654 }
655
WriteFile(const std::string & filePath,const std::string & fileContent)656 bool WriteFile(const std::string &filePath, const std::string &fileContent)
657 {
658 std::ofstream file(filePath, std::ios::out | std::ios::trunc);
659 if (!file.is_open()) {
660 NETMGR_LOG_E("write file=%{public}s fstream failed. err %{public}d %{public}s",
661 filePath.c_str(), errno, strerror(errno));
662 return false;
663 }
664 file << fileContent;
665 file.close();
666 return true;
667 }
668
HasInternetPermission()669 bool HasInternetPermission()
670 {
671 int testSock = socket(AF_INET, SOCK_STREAM, 0);
672 if (testSock < 0 && errno == EPERM) {
673 NETMGR_LOG_E("make tcp testSock failed errno is %{public}d %{public}s", errno, strerror(errno));
674 return false;
675 }
676 if (testSock > 0) {
677 close(testSock);
678 }
679 return true;
680 }
681
Trim(const std::string & str)682 std::string Trim(const std::string &str)
683 {
684 size_t start = str.find_first_not_of(" \t\n\r");
685 size_t end = str.find_last_not_of(" \t\n\r");
686 if (start == std::string::npos || end == std::string::npos) {
687 return "";
688 }
689 return str.substr(start, end - start + 1);
690 }
691
IsUrlRegexValid(const std::string & regex)692 bool IsUrlRegexValid(const std::string ®ex)
693 {
694 if (Trim(regex).empty()) {
695 return false;
696 }
697 return regex_match(regex, std::regex("^[a-zA-Z0-9\\-_\\.*]+$"));
698 }
699
InsertCharBefore(const std::string & input,const char from,const char preChar,const char nextChar)700 std::string InsertCharBefore(const std::string &input, const char from, const char preChar, const char nextChar)
701 {
702 std::ostringstream output;
703 for (size_t i = 0; i < input.size(); ++i) {
704 if (input[i] == from && (i == input.size() - 1 || input[i + 1] != nextChar)) {
705 output << preChar;
706 }
707 output << input[i];
708 }
709 return output.str();
710 }
711
ReplaceCharacters(const std::string & input)712 std::string ReplaceCharacters(const std::string &input)
713 {
714 std::string output = InsertCharBefore(input, '*', '.', '\0');
715 output = InsertCharBefore(output, '.', '\\', '*');
716 return output;
717 }
718
UrlRegexParse(const std::string & str,const std::string & patternStr)719 bool UrlRegexParse(const std::string &str, const std::string &patternStr)
720 {
721 if (patternStr.empty()) {
722 return false;
723 }
724 if (patternStr == "*") {
725 return true;
726 }
727 if (!IsUrlRegexValid(patternStr)) {
728 return patternStr == str;
729 }
730 std::regex pattern(ReplaceCharacters(patternStr));
731 return !patternStr.empty() && std::regex_match(str, pattern);
732 }
733
GenRandomNumber()734 uint64_t GenRandomNumber()
735 {
736 static std::random_device rd;
737 static std::uniform_int_distribution<uint64_t> dist(0ULL, UINT64_MAX);
738 uint64_t num = dist(rd);
739 return num;
740 }
741
IsSim(const std::string & bundleName)742 bool IsSim(const std::string &bundleName)
743 {
744 std::vector<std::string> list = Split(SIM_APP_BUNDLENAMES, BUNDLENAME_DELIMITER);
745 auto findRet =
746 std::find_if(list.begin(), list.end(), [&bundleName](const auto &item) { return item == bundleName; });
747 return findRet != list.end();
748 }
749
IsInstallSourceFromSim(const std::string & installSource)750 bool IsInstallSourceFromSim(const std::string &installSource)
751 {
752 return installSource == INSTALL_SOURCE_FROM_SIM;
753 }
754
GetHostnameFromURL(const std::string & url)755 std::string GetHostnameFromURL(const std::string &url)
756 {
757 if (url.empty()) {
758 return "";
759 }
760 std::string delimiter = "://";
761 std::string tempUrl = url;
762 std::replace(tempUrl.begin(), tempUrl.end(), '\\', '/');
763 size_t posStart = tempUrl.find(delimiter);
764 if (posStart != std::string::npos) {
765 posStart += delimiter.length();
766 } else {
767 posStart = 0;
768 }
769 size_t notSlash = tempUrl.find_first_not_of('/', posStart);
770 if (notSlash != std::string::npos) {
771 posStart = notSlash;
772 }
773 size_t posEnd = std::min({ tempUrl.find(':', posStart),
774 tempUrl.find('/', posStart), tempUrl.find('?', posStart) });
775 if (posEnd != std::string::npos) {
776 return tempUrl.substr(posStart, posEnd - posStart);
777 }
778 return tempUrl.substr(posStart);
779 }
780
IsSim2(const std::string & bundleName)781 bool IsSim2(const std::string &bundleName)
782 {
783 std::vector<std::string> list = Split(SIM2_BUNDLENAMES, BUNDLENAME_DELIMITER);
784 auto findRet =
785 std::find_if(list.begin(), list.end(), [&bundleName](const auto &item) { return item == bundleName; });
786 return findRet != list.end();
787 }
788
IsInstallSourceFromSim2(const std::string & installSource)789 bool IsInstallSourceFromSim2(const std::string &installSource)
790 {
791 return installSource == INSTALL_SOURCE_FROM_SIM2;
792 }
793
IsSimAnco(const std::string & bundleName)794 bool IsSimAnco(const std::string &bundleName)
795 {
796 return bundleName == INSTALL_SOURCE_FROM_SIM;
797 }
798
IsSim2Anco(const std::string & bundleName)799 bool IsSim2Anco(const std::string &bundleName)
800 {
801 return bundleName == INSTALL_SOURCE_FROM_SIM2;
802 }
803 } // namespace OHOS::NetManagerStandard::CommonUtils
804