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