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 ®ex)
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