1 /*
2  * Copyright (C) 2023-2023 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 "network_parser.h"
17 #include "wifi_logger.h"
18 #include "wifi_common_util.h"
19 #include "network_status_history_manager.h"
20 #include "wifi_global_func.h"
21 
22 namespace OHOS {
23 namespace Wifi {
24 DEFINE_WIFILOG_LABEL("NetworkXmlParser");
25 constexpr auto XML_TAG_MIGRATE_DOCUMENT_HEADER = "WifiConfigStoreData";
26 constexpr auto XML_TAG_CLONE_DOCUMENT_HEADER = "WifiBackupData";
27 constexpr auto XML_TAG_SECTION_HEADER_NETWORK_LIST = "NetworkList";
28 constexpr auto XML_TAG_SECTION_HEADER_NETWORK = "Network";
29 constexpr auto XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION = "WifiConfiguration";
30 constexpr auto XML_TAG_SECTION_HEADER_NETWORK_STATUS = "NetworkStatus";
31 constexpr auto XML_TAG_SECTION_HEADER_IP_CONFIGURATION = "IpConfiguration";
32 constexpr auto XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION = "WifiEnterpriseConfiguration";
33 constexpr auto XML_TAG_SSID = "SSID";
34 constexpr auto XML_TAG_PRE_SHARED_KEY = "PreSharedKey";
35 constexpr auto XML_TAG_WEP_KEYS = "WEPKeys";
36 constexpr auto XML_TAG_WEP_TX_KEY_INDEX = "WEPTxKeyIndex";
37 constexpr auto XML_TAG_HIDDEN_SSID = "HiddenSSID";
38 constexpr auto XML_TAG_ALLOWED_KEY_MGMT = "AllowedKeyMgmt";
39 constexpr auto XML_TAG_RANDOMIZED_MAC_ADDRESS = "RandomizedMacAddress";
40 constexpr auto XML_TAG_MAC_RANDOMIZATION_SETTING = "MacRandomizationSetting";
41 constexpr auto XML_TAG_STATUS = "SelectionStatus";
42 constexpr auto XML_TAG_IP_ASSIGNMENT = "IpAssignment";
43 constexpr auto XML_TAG_LINK_ADDRESS = "LinkAddress";
44 constexpr auto XML_TAG_LINK_PREFIX_LENGTH = "LinkPrefixLength";
45 constexpr auto XML_TAG_GATEWAY_ADDRESS = "GatewayAddress";
46 constexpr auto XML_TAG_DNS_SERVER_ADDRESSES = "DNSServers";
47 constexpr auto XML_TAG_PROXY_SETTINGS = "ProxySettings";
48 constexpr auto XML_TAG_PROXY_HOST = "ProxyHost";
49 constexpr auto XML_TAG_PROXY_PORT = "ProxyPort";
50 constexpr auto XML_TAG_PROXY_PAC_FILE = "ProxyPac";
51 constexpr auto XML_TAG_PROXY_EXCLUSION_LIST = "ProxyExclusionList";
52 constexpr auto XML_TAG_VALIDATED_INTERNET_ACCESS = "ValidatedInternetAccess";
53 constexpr auto XML_TAG_PORTAL_NETWORK = "PORTAL_NETWORK";
54 constexpr auto XML_TAG_INTERNET_HISTORY = "INTERNET_HISTORY";
55 constexpr auto XML_TAG_SECTION_HEADER_MAC_ADDRESS_MAP = "MacAddressMap";
56 constexpr auto XML_TAG_MAC_MAP_PLUS = "MacMapEntryPlus";
57 constexpr auto IP_DHCP = "DHCP";
58 constexpr auto IP_STATIC = "STATIC";
59 constexpr auto PROXY_STATIC = "STATIC";
60 constexpr auto PROXY_PAC = "PAC";
61 static const std::string DEFAULT_MAC_ADDRESS = "02:00:00:00:00:00";
62 
63 const std::unordered_map<std::string, WifiConfigType> g_wifiConfigMap = {
64     {XML_TAG_SSID, WifiConfigType::SSID},
65     {XML_TAG_PRE_SHARED_KEY, WifiConfigType::PRESHAREDKEY},
66     {XML_TAG_HIDDEN_SSID, WifiConfigType::HIDDENSSID},
67     {XML_TAG_ALLOWED_KEY_MGMT, WifiConfigType::ALLOWEDKEYMGMT},
68     {XML_TAG_MAC_RANDOMIZATION_SETTING, WifiConfigType::RANDOMIZATIONSETTING},
69     {XML_TAG_RANDOMIZED_MAC_ADDRESS, WifiConfigType::RANDOMIZEDMACADDRESS},
70     {XML_TAG_STATUS, WifiConfigType::STATUS},
71     {XML_TAG_WEP_TX_KEY_INDEX, WifiConfigType::WEPKEYINDEX},
72     {XML_TAG_WEP_KEYS, WifiConfigType::WEPKEYS},
73     {XML_TAG_IP_ASSIGNMENT, WifiConfigType::IPASSIGNMENT},
74     {XML_TAG_LINK_ADDRESS, WifiConfigType::LINKADDRESS},
75     {XML_TAG_LINK_PREFIX_LENGTH, WifiConfigType::PREFIXLENGTH},
76     {XML_TAG_GATEWAY_ADDRESS, WifiConfigType::GATEWAYADDRESS},
77     {XML_TAG_DNS_SERVER_ADDRESSES, WifiConfigType::DNSSERVERADDRESSES},
78     {XML_TAG_PROXY_SETTINGS, WifiConfigType::PROXYSETTINGS},
79     {XML_TAG_PROXY_PAC_FILE, WifiConfigType::PROXYPAC},
80     {XML_TAG_PROXY_HOST, WifiConfigType::PROXYHOST},
81     {XML_TAG_PROXY_PORT, WifiConfigType::PROXYPORT},
82     {XML_TAG_PROXY_EXCLUSION_LIST, WifiConfigType::PROXYEXCLUSIONLIST},
83     {XML_TAG_VALIDATED_INTERNET_ACCESS, WifiConfigType::VALIDATEDINTERNETACCESS},
84     {XML_TAG_PORTAL_NETWORK, WifiConfigType::PORTALNETWORK},
85     {XML_TAG_INTERNET_HISTORY, WifiConfigType::INTERNETHISTORY},
86 };
87 
88 const std::unordered_map<std::string, NetworkSection> g_networkSectionMap = {
89     {XML_TAG_SECTION_HEADER_WIFI_CONFIGURATION, NetworkSection::WIFI_CONFIGURATION},
90     {XML_TAG_SECTION_HEADER_NETWORK_STATUS, NetworkSection::NETWORK_STATUS},
91     {XML_TAG_SECTION_HEADER_IP_CONFIGURATION, NetworkSection::IP_CONFIGURATION},
92     {XML_TAG_SECTION_HEADER_WIFI_ENTERPRISE_CONFIGURATION, NetworkSection::ENTERPRISE_CONFIGURATION},
93 };
94 
GetIpConfig(xmlNodePtr innode)95 AssignIpMethod NetworkXmlParser::GetIpConfig(xmlNodePtr innode)
96 {
97     if (innode == nullptr) {
98         WIFI_LOGE("GetIpConfig node null");
99         return AssignIpMethod::UNASSIGNED;
100     }
101     for (xmlNodePtr node = innode->children; node != nullptr; node = node->next) {
102         if (GetConfigNameAsInt(node) != WifiConfigType::IPASSIGNMENT) {
103             continue;
104         }
105         if (GetStringValue(node) == IP_DHCP) {
106             return AssignIpMethod::DHCP;
107         } else if (GetStringValue(node) == IP_STATIC) {
108             return AssignIpMethod::STATIC;
109         }
110         break;
111     }
112     return AssignIpMethod::UNASSIGNED;
113 }
114 
~NetworkXmlParser()115 NetworkXmlParser::~NetworkXmlParser()
116 {
117     wifiConfigs.clear();
118     wifiStoreRandomMacs.clear();
119 }
120 
GotoNetworkList(xmlNodePtr innode)121 xmlNodePtr NetworkXmlParser::GotoNetworkList(xmlNodePtr innode)
122 {
123     if (innode == nullptr) {
124         WIFI_LOGE("GotoNetworkList node null");
125         return nullptr;
126     }
127     for (xmlNodePtr node = innode->children; node != nullptr; node = node->next) {
128         if (xmlStrcmp(node->name, BAD_CAST(XML_TAG_SECTION_HEADER_NETWORK_LIST)) == 0) {
129             return node;
130         }
131     }
132     return nullptr;
133 }
134 
GetConfigNameAsInt(xmlNodePtr node)135 WifiConfigType NetworkXmlParser::GetConfigNameAsInt(xmlNodePtr node)
136 {
137     if (node == nullptr) {
138         WIFI_LOGE("GetConfigNameAsInt node null");
139         return WifiConfigType::UNVALID;
140     }
141     std::string tagName = GetNameValue(node);
142     if (g_wifiConfigMap.find(tagName) != g_wifiConfigMap.end()) {
143         return g_wifiConfigMap.at(tagName);
144     }
145     return WifiConfigType::UNVALID;
146 }
147 
GetNodeNameAsInt(xmlNodePtr node)148 NetworkSection NetworkXmlParser::GetNodeNameAsInt(xmlNodePtr node)
149 {
150     if (node == nullptr) {
151         WIFI_LOGE("GetNodeNameAsInt node null");
152         return NetworkSection::UNVALID;
153     }
154     std::string tagName = GetNodeValue(node);
155     if (g_networkSectionMap.find(tagName) != g_networkSectionMap.end()) {
156         return g_networkSectionMap.at(tagName);
157     }
158     return NetworkSection::UNVALID;
159 }
160 
ParseIpConfig(xmlNodePtr innode)161 WifiIpConfig NetworkXmlParser::ParseIpConfig(xmlNodePtr innode)
162 {
163     WifiIpConfig ipConfig{};
164     if (innode == nullptr) {
165         WIFI_LOGE("ParseIpConfig node null");
166         return ipConfig;
167     }
168     ipConfig.assignMethod = GetIpConfig(innode);
169 
170     if (ipConfig.assignMethod != AssignIpMethod::STATIC) {
171         return ipConfig;
172     }
173     for (xmlNodePtr node = innode->children; node != nullptr; node = node->next) {
174         switch (GetConfigNameAsInt(node)) {
175             case WifiConfigType::LINKADDRESS: {
176                 std::string ipAddress = GetStringValue(node);
177                 ipConfig.staticIpAddress.ipAddress.address.SetIpv4Address(ipAddress);
178                 break;
179             }
180             case WifiConfigType::PREFIXLENGTH: {
181                 ipConfig.staticIpAddress.ipAddress.prefixLength = GetPrimValue<int>(node, PrimType::INT);
182                 break;
183             }
184             case WifiConfigType::GATEWAYADDRESS: {
185                 ipConfig.staticIpAddress.gateway.SetIpv4Address(GetStringValue(node));
186                 break;
187             }
188             case WifiConfigType::DNSSERVERADDRESSES: {
189                 std::vector<std::string> dnsArr = GetStringArrValue(node);
190                 if (dnsArr.size() == 2) { // 2 dns
191                     ipConfig.staticIpAddress.dnsServer1.SetIpv4Address(dnsArr[0]);
192                     ipConfig.staticIpAddress.dnsServer2.SetIpv4Address(dnsArr[1]);
193                 }
194                 break;
195             }
196             default: {
197                 break;
198             }
199         }
200     }
201     return ipConfig;
202 }
203 
GetProxyMethod(xmlNodePtr innode)204 ConfigureProxyMethod NetworkXmlParser::GetProxyMethod(xmlNodePtr innode)
205 {
206     if (innode == nullptr) {
207         WIFI_LOGE("GetProxyMethod node null");
208         return ConfigureProxyMethod::CLOSED;
209     }
210     for (xmlNodePtr node = innode->children; node != nullptr; node = node->next) {
211         if (GetConfigNameAsInt(node) != WifiConfigType::PROXYSETTINGS) {
212             continue;
213         }
214         if (GetStringValue(node) == PROXY_STATIC) {
215             return ConfigureProxyMethod::MANUALCONFIGUE;
216         } else if (GetStringValue(node) == PROXY_PAC) {
217             return ConfigureProxyMethod::AUTOCONFIGUE;
218         }
219         break;
220     }
221     return ConfigureProxyMethod::CLOSED;
222 }
223 
ParseProxyConfig(xmlNodePtr innode)224 WifiProxyConfig NetworkXmlParser::ParseProxyConfig(xmlNodePtr innode)
225 {
226     WifiProxyConfig wifiProxyConfig{};
227     if (innode == nullptr) {
228         WIFI_LOGE("ParseProxyConfig node null");
229         return wifiProxyConfig;
230     }
231     wifiProxyConfig.configureMethod = GetProxyMethod(innode);
232     if (wifiProxyConfig.configureMethod == ConfigureProxyMethod::CLOSED) {
233         return wifiProxyConfig;
234     }
235     for (xmlNodePtr node = innode->children; node != nullptr; node = node->next) {
236         switch (GetConfigNameAsInt(node)) {
237             case WifiConfigType::PROXYPAC:
238                 wifiProxyConfig.autoProxyConfig.pacWebAddress = GetStringValue(node);
239                 break;
240             case WifiConfigType::PROXYHOST: {
241                 wifiProxyConfig.manualProxyConfig.serverHostName = GetStringValue(node);
242                 break;
243             }
244             case WifiConfigType::PROXYPORT: {
245                 wifiProxyConfig.manualProxyConfig.serverPort = GetPrimValue<int>(node, PrimType::INT);
246                 break;
247             }
248             case WifiConfigType::PROXYEXCLUSIONLIST: {
249                 wifiProxyConfig.manualProxyConfig.exclusionObjectList = GetStringValue(node);
250                 break;
251             }
252             default: {
253                 break;
254             }
255         }
256     }
257     return wifiProxyConfig;
258 }
259 
HasWepKeys(WifiDeviceConfig wifiConfig)260 bool NetworkXmlParser::HasWepKeys(WifiDeviceConfig wifiConfig)
261 {
262     for (int i = 0; i < WEPKEYS_SIZE; i++) {
263         if (!wifiConfig.wepKeys[i].empty()) {
264             return true;
265         }
266     }
267     return false;
268 }
269 
GetKeyMgmt(xmlNodePtr node,WifiDeviceConfig & wifiConfig)270 void NetworkXmlParser::GetKeyMgmt(xmlNodePtr node, WifiDeviceConfig& wifiConfig)
271 {
272     if (node == nullptr) {
273         WIFI_LOGE("GetKeyMgmt node null");
274         return;
275     }
276     std::vector<unsigned char> keyMgmtByte = GetByteArrValue(node);
277     if (keyMgmtByte.size() > 4) { // trans byte to int always < 4
278         wifiConfig.keyMgmt = "";
279         return;
280     }
281     unsigned int keyMgmtInt = 0;
282     for (size_t i = 0; i < keyMgmtByte.size(); i++) {
283         keyMgmtInt |= (keyMgmtByte[i] << (8 * i)); // trans byte to int
284     }
285     if (keyMgmtInt & MGMT_SAE) {
286         wifiConfig.keyMgmt = KEY_MGMT_SAE;
287     } else if ((keyMgmtInt & MGMT_WPA_PSK) || (keyMgmtInt & MGMT_WPA2_PSK) || (keyMgmtInt & MGMT_FT_PSK)) {
288         wifiConfig.keyMgmt = KEY_MGMT_WPA_PSK;
289     } else if (keyMgmtInt & MGMT_NONE) {
290         if (HasWepKeys(wifiConfig)) {
291             wifiConfig.keyMgmt = KEY_MGMT_WEP;
292         } else {
293             wifiConfig.keyMgmt = KEY_MGMT_NONE;
294         }
295     } else {
296         wifiConfig.keyMgmt = "";
297     }
298     return;
299 }
300 
GetRandMacSetting(xmlNodePtr node)301 OHOS::Wifi::WifiPrivacyConfig NetworkXmlParser::GetRandMacSetting(xmlNodePtr node)
302 {
303     if (node == nullptr) {
304         WIFI_LOGE("GetRandMacSetting node null");
305         return OHOS::Wifi::WifiPrivacyConfig::RANDOMMAC;
306     }
307     int randMacSetting = GetPrimValue<int>(node, PrimType::INT);
308     if (randMacSetting == 0) {
309         return OHOS::Wifi::WifiPrivacyConfig::DEVICEMAC;
310     }
311     return OHOS::Wifi::WifiPrivacyConfig::RANDOMMAC;
312 }
313 
ParseWifiConfig(xmlNodePtr innode)314 WifiDeviceConfig NetworkXmlParser::ParseWifiConfig(xmlNodePtr innode)
315 {
316     WifiDeviceConfig wifiConfig;
317     if (innode == nullptr) {
318         WIFI_LOGE("ParseWifiConfig node null");
319         return wifiConfig;
320     }
321     for (xmlNodePtr node = innode->children; node != nullptr; node = node->next) {
322         switch (GetConfigNameAsInt(node)) {
323             case WifiConfigType::SSID:
324                 ParseSsid(node, wifiConfig);
325                 break;
326             case WifiConfigType::PRESHAREDKEY:
327                 ParsePreSharedKey(node, wifiConfig);
328                 break;
329             case WifiConfigType::HIDDENSSID:
330                 wifiConfig.hiddenSSID = GetPrimValue<bool>(node, PrimType::BOOLEAN);
331                 break;
332             case WifiConfigType::ALLOWEDKEYMGMT:
333                 GetKeyMgmt(node, wifiConfig);
334                 break;
335             case WifiConfigType::RANDOMIZATIONSETTING:
336                 wifiConfig.wifiPrivacySetting = GetRandMacSetting(node);
337                 break;
338             case WifiConfigType::RANDOMIZEDMACADDRESS:
339                 wifiConfig.macAddress = GetStringValue(node);
340                 break;
341             case WifiConfigType::WEPKEYINDEX:
342                 wifiConfig.wepTxKeyIndex = GetPrimValue<int>(node, PrimType::INT);
343                 break;
344             case WifiConfigType::WEPKEYS:
345                 ParseWepKeys(node, wifiConfig);
346                 break;
347             case WifiConfigType::VALIDATEDINTERNETACCESS:
348                 wifiConfig.noInternetAccess = !GetPrimValue<bool>(node, PrimType::BOOLEAN);
349                 break;
350             case WifiConfigType::PORTALNETWORK:
351                 wifiConfig.isPortal = GetPrimValue<bool>(node, PrimType::BOOLEAN);
352                 break;
353             case WifiConfigType::INTERNETHISTORY:
354                 ParseInternetHistory(node, wifiConfig);
355                 break;
356             default:
357                 break;
358         }
359     }
360     return wifiConfig;
361 }
362 
ParseSsid(xmlNodePtr node,WifiDeviceConfig & wifiConfig)363 void NetworkXmlParser::ParseSsid(xmlNodePtr node, WifiDeviceConfig& wifiConfig)
364 {
365     const int subStrBegin = 1;
366     const int quotesCount = 2;
367     if (node == nullptr) {
368         WIFI_LOGE("ParseSsid node null");
369         return;
370     }
371     std::string ssid = GetStringValue(node);
372     if (ssid.length() == 0) {
373         WIFI_LOGE("ParseSsid ssid is null");
374         return;
375     }
376     // remove ""
377     wifiConfig.ssid = ssid.substr(subStrBegin, ssid.length() - quotesCount);
378 }
379 
ParsePreSharedKey(xmlNodePtr node,WifiDeviceConfig & wifiConfig)380 void NetworkXmlParser::ParsePreSharedKey(xmlNodePtr node, WifiDeviceConfig& wifiConfig)
381 {
382     const int subStrBegin = 1;
383     const int quotesCount = 2;
384     if (node == nullptr) {
385         WIFI_LOGE("ParsePreSharedKey node null");
386         return;
387     }
388     std::string preSharedKey = GetStringValue(node);
389     if (preSharedKey.length() == 0) {
390         WIFI_LOGE("ParsePreSharedKey preSharedKey is null");
391         return;
392     }
393     // remove ""
394     wifiConfig.preSharedKey = preSharedKey.substr(subStrBegin, preSharedKey.length() - quotesCount);
395     std::string().swap(preSharedKey);
396 }
397 
ParseInternetHistory(xmlNodePtr node,WifiDeviceConfig & wifiConfig)398 void NetworkXmlParser::ParseInternetHistory(xmlNodePtr node, WifiDeviceConfig& wifiConfig)
399 {
400     if (node == nullptr) {
401         WIFI_LOGE("ParseInternetHistory node null");
402         return;
403     }
404 
405     const int historyNoInternet = 0;
406     const int historyInternet = 1;
407     const int historyPortal = 2;
408     std::string netHistory = GetStringValue(node);
409     std::vector<int> netHistoryVec = SplitStringToIntVector(netHistory, "/");
410     for (auto it = netHistoryVec.rbegin(); it != netHistoryVec.rend(); ++it) {
411         NetworkStatus netState = NetworkStatus::UNKNOWN;
412         if (*it == historyNoInternet) {
413             netState = NetworkStatus::NO_INTERNET;
414         } else if (*it == historyInternet) {
415             netState = NetworkStatus::HAS_INTERNET;
416         } else if (*it == historyPortal) {
417             netState = NetworkStatus::PORTAL;
418         } else {
419             continue;
420         }
421         // 2: Bits occupied by history record
422         wifiConfig.networkStatusHistory = wifiConfig.networkStatusHistory << 2;
423         wifiConfig.networkStatusHistory += static_cast<unsigned int>(netState);
424     }
425 }
426 
ParseNetworkStatus(xmlNodePtr innode,WifiDeviceConfig & wifiConfig)427 void NetworkXmlParser::ParseNetworkStatus(xmlNodePtr innode, WifiDeviceConfig& wifiConfig)
428 {
429     if (innode == nullptr) {
430         WIFI_LOGE("ParseWifiConfig node null");
431         return;
432     }
433     for (xmlNodePtr node = innode->children; node != nullptr; node = node->next) {
434         switch (GetConfigNameAsInt(node)) {
435             case WifiConfigType::STATUS: {
436                 ParseStatus(node, wifiConfig);
437                 break;
438             }
439             default: {
440                 break;
441             }
442         }
443     }
444 }
445 
ParseWepKeys(xmlNodePtr node,WifiDeviceConfig & wifiDeviceConfig)446 void NetworkXmlParser::ParseWepKeys(xmlNodePtr node, WifiDeviceConfig& wifiDeviceConfig)
447 {
448     if (node == nullptr) {
449         WIFI_LOGE("ParseWepKeys node null");
450         return;
451     }
452     std::vector<std::string> wepKeys = GetStringArrValue(node);
453     if (wepKeys.size() == WEPKEYS_SIZE) {
454         for (size_t i = 0; i < wepKeys.size(); i++) {
455             wifiDeviceConfig.wepKeys[i] = wepKeys[i];
456         }
457     }
458 }
459 
ParseStatus(xmlNodePtr node,WifiDeviceConfig & wifiDeviceConfig)460 void NetworkXmlParser::ParseStatus(xmlNodePtr node, WifiDeviceConfig& wifiDeviceConfig)
461 {
462     if (node == nullptr) {
463         WIFI_LOGE("ParseStatus node null");
464         return;
465     }
466     std::string status = GetStringValue(node);
467     if (status.compare("NETWORK_SELECTION_ENABLED")) {
468         wifiDeviceConfig.status = static_cast<int>(WifiDeviceConfigStatus::DISABLED);
469     } else {
470         wifiDeviceConfig.status = static_cast<int>(WifiDeviceConfigStatus::ENABLED);
471     }
472 }
473 
474 
ParseNetwork(xmlNodePtr innode)475 WifiDeviceConfig NetworkXmlParser::ParseNetwork(xmlNodePtr innode)
476 {
477     WifiDeviceConfig wifiConfig;
478     if (innode == nullptr) {
479         WIFI_LOGE("ParseNetwork node null");
480         return wifiConfig;
481     }
482     for (xmlNodePtr node = innode->children; node != nullptr; node = node->next) {
483         switch (GetNodeNameAsInt(node)) {
484             case NetworkSection::WIFI_CONFIGURATION: {
485                 wifiConfig = ParseWifiConfig(node);
486                 break;
487             }
488             case NetworkSection::NETWORK_STATUS: {
489                 ParseNetworkStatus(node, wifiConfig);
490                 break;
491             }
492             case NetworkSection::IP_CONFIGURATION: {
493                 wifiConfig.wifiIpConfig = ParseIpConfig(node);
494                 wifiConfig.wifiProxyconfig = ParseProxyConfig(node);
495                 break;
496             }
497             default: {
498                 break;
499             }
500         }
501     }
502     return wifiConfig;
503 }
504 
ParseNetworkList(xmlNodePtr innode)505 void NetworkXmlParser::ParseNetworkList(xmlNodePtr innode)
506 {
507     if (innode == nullptr) {
508         WIFI_LOGE("ParseNetworkList node null");
509         return;
510     }
511     xmlNodePtr networkNodeList = GotoNetworkList(innode);
512     if (networkNodeList == nullptr) {
513         WIFI_LOGE("networkNodeList null");
514         return;
515     }
516     int xmlSavedNetworkCount = 0;
517     for (xmlNodePtr node = networkNodeList->children; node != nullptr; node = node->next) {
518         if (xmlStrcmp(node->name, BAD_CAST(XML_TAG_SECTION_HEADER_NETWORK)) == 0) {
519             xmlSavedNetworkCount++;
520             WifiDeviceConfig wifiDeviceConfig = ParseNetwork(node);
521             if (IsWifiConfigValid(wifiDeviceConfig)) {
522                 wifiConfigs.push_back(wifiDeviceConfig);
523             }
524         }
525     }
526     WIFI_LOGI("ParseNetwork size=%{public}lu, xml config total size=%{public}d",
527         (unsigned long) wifiConfigs.size(), xmlSavedNetworkCount);
528 }
529 
GotoMacAddressMap(xmlNodePtr innode)530 xmlNodePtr NetworkXmlParser::GotoMacAddressMap(xmlNodePtr innode)
531 {
532     if (innode == nullptr) {
533         WIFI_LOGE("GotoMacAddressMap node null");
534         return nullptr;
535     }
536     for (xmlNodePtr node = innode->children; node != nullptr; node = node->next) {
537         if (xmlStrcmp(node->name, BAD_CAST(XML_TAG_SECTION_HEADER_MAC_ADDRESS_MAP)) == 0) {
538             return node;
539         }
540     }
541     return nullptr;
542 }
543 
ParseMacMapPlus(xmlNodePtr innode)544 void NetworkXmlParser::ParseMacMapPlus(xmlNodePtr innode)
545 {
546     if (innode == nullptr) {
547         WIFI_LOGE("ParseMacMapPlus node null");
548         return;
549     }
550     xmlNodePtr macAddrNode = GotoMacAddressMap(innode);
551     if (macAddrNode == nullptr) {
552         WIFI_LOGE("ParseMacMapPlus macAddrNode null");
553         return;
554     }
555     for (xmlNodePtr node = macAddrNode->children; node != nullptr; node = node->next) {
556         if (GetNameValue(node) == XML_TAG_MAC_MAP_PLUS) {
557             std::map<std::string, std::string> macMap = GetStringMapValue(node);
558             SetMacByMacMapPlus(macMap);
559             FillupMacByConfig();
560         }
561     }
562     WIFI_LOGI("ParseMacMapPlus size[%{public}d]", static_cast<int>(wifiStoreRandomMacs.size()));
563 }
564 
SetMacByMacMapPlus(std::map<std::string,std::string> macMap)565 void NetworkXmlParser::SetMacByMacMapPlus(std::map<std::string, std::string> macMap)
566 {
567     for (auto it = macMap.begin(); it != macMap.end(); ++it) {
568         if (!IsRandomMacValid(it->second)) {
569             continue;
570         }
571         bool isExist = false;
572         for (auto &item : wifiStoreRandomMacs) {
573             if (item.randomMac == it->second) {
574                 item.fuzzyBssids.insert(it->first);
575                 isExist = true;
576                 break;
577             }
578         }
579         if (!isExist) {
580             WifiStoreRandomMac wifiStoreRandomMac{};
581             // need set default psk for GetRandomMac and AddRandomMac
582             wifiStoreRandomMac.keyMgmt = KEY_MGMT_WPA_PSK;
583             wifiStoreRandomMac.fuzzyBssids.insert(it->first);
584             wifiStoreRandomMac.randomMac = it->second;
585             wifiStoreRandomMacs.push_back(wifiStoreRandomMac);
586         }
587     }
588 }
589 
FillupMacByConfig()590 void NetworkXmlParser::FillupMacByConfig()
591 {
592     for (auto cfgItem : wifiConfigs) {
593         if (!IsRandomMacValid(cfgItem.macAddress)) {
594             continue;
595         }
596         bool isExist = false;
597         for (auto &macItem : wifiStoreRandomMacs) {
598             if (macItem.randomMac == cfgItem.macAddress) {
599                 macItem.ssid = cfgItem.ssid;
600                 macItem.keyMgmt = cfgItem.keyMgmt;
601                 isExist = true;
602                 break;
603             }
604         }
605         if (!isExist) {
606             WifiStoreRandomMac wifiStoreRandomMac{};
607             wifiStoreRandomMac.ssid = cfgItem.ssid;
608             wifiStoreRandomMac.keyMgmt = cfgItem.keyMgmt;
609             wifiStoreRandomMac.randomMac = cfgItem.macAddress;
610             wifiStoreRandomMacs.push_back(wifiStoreRandomMac);
611         }
612     }
613 }
614 
GetParseType(xmlNodePtr node)615 NetworkParseType NetworkXmlParser::GetParseType(xmlNodePtr node)
616 {
617     if (node == nullptr) {
618         WIFI_LOGE("GetParseType node null");
619         return NetworkParseType::UNKNOWN;
620     }
621 
622     if (xmlStrcmp(node->name, BAD_CAST(XML_TAG_MIGRATE_DOCUMENT_HEADER)) == 0) {
623         return NetworkParseType::MIGRATE;
624     } else if (xmlStrcmp(node->name, BAD_CAST(XML_TAG_CLONE_DOCUMENT_HEADER)) == 0) {
625         return NetworkParseType::CLONE;
626     }
627     return NetworkParseType::UNKNOWN;
628 }
629 
ParseInternal(xmlNodePtr node)630 bool NetworkXmlParser::ParseInternal(xmlNodePtr node)
631 {
632     if (node == nullptr) {
633         WIFI_LOGE("ParseInternal node null");
634         return false;
635     }
636 
637     NetworkParseType parseType = GetParseType(node);
638     if (parseType == NetworkParseType::UNKNOWN) {
639         WIFI_LOGE("ParseInternal Doc invaild");
640         return false;
641     }
642     WIFI_LOGI("ParseInternal parseType: %{public}d.", static_cast<int>(parseType));
643 
644     ParseNetworkList(node);
645     if (parseType == NetworkParseType::CLONE) {
646         // Enable all networks restored and no need to parse randommac.
647         EnableNetworks();
648     } else if (parseType == NetworkParseType::MIGRATE) {
649         ParseMacMapPlus(node);
650     }
651     return true;
652 }
653 
EnableNetworks()654 void NetworkXmlParser::EnableNetworks()
655 {
656     for (auto &wifiConfig : wifiConfigs) {
657         wifiConfig.status = static_cast<int>(WifiDeviceConfigStatus::ENABLED);
658     }
659 }
660 
IsWifiConfigValid(WifiDeviceConfig wifiConfig)661 bool NetworkXmlParser::IsWifiConfigValid(WifiDeviceConfig wifiConfig)
662 {
663     if (wifiConfig.keyMgmt == OHOS::Wifi::KEY_MGMT_SAE || wifiConfig.keyMgmt == OHOS::Wifi::KEY_MGMT_NONE
664         || wifiConfig.keyMgmt == OHOS::Wifi::KEY_MGMT_WEP || wifiConfig.keyMgmt == OHOS::Wifi::KEY_MGMT_WPA_PSK) {
665         return true;
666     }
667     WIFI_LOGE("invalid wifiConfig: ssid=%{public}s, keyMgmt=%{public}s",
668         SsidAnonymize(wifiConfig.ssid).c_str(), wifiConfig.keyMgmt.c_str());
669     return false;
670 }
671 
IsRandomMacValid(const std::string & macAddress)672 bool NetworkXmlParser::IsRandomMacValid(const std::string &macAddress)
673 {
674     constexpr size_t macStringLength = 17;
675     if (macAddress.empty() || macAddress == DEFAULT_MAC_ADDRESS || macAddress.length() != macStringLength) {
676         return false;
677     }
678     return true;
679 }
680 
GetNetworks()681 std::vector<WifiDeviceConfig> NetworkXmlParser::GetNetworks()
682 {
683     return wifiConfigs;
684 }
685 
GetRandomMacmap()686 std::vector<WifiStoreRandomMac> NetworkXmlParser::GetRandomMacmap()
687 {
688     return wifiStoreRandomMacs;
689 }
690 }
691 }