• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &regex)
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