• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 "eap_hdi_wpa_manager.h"
17 
18 #include <filesystem>
19 #include <map>
20 #include <charconv>
21 #include <codecvt>
22 #include <fstream>
23 
24 #include "base64_utils.h"
25 #include "net_eap_handler.h"
26 #include "netmgr_ext_log_wrapper.h"
27 #include "netmanager_base_common_utils.h"
28 #include "net_manager_constants.h"
29 
30 namespace OHOS {
31 namespace NetManagerStandard {
32 
33 static constexpr const char* ETHERNET_SERVICE_NAME = "ethernet_service";
34 static constexpr const char* ITEM_WPA_CTRL = "wpa_ctrl_";
35 static constexpr const char* ETH_CONFIG_ROOR_DIR = "/data/service/el1/public/eth";
36 static constexpr const char* ETH_WPA_CONFIG_PATH = "/data/service/el1/public/eth/eth_wpa_supplicant.conf";
37 
38 static constexpr const char* ITEM_CTRL_IFACE = "ctrl_interface=/data/service/el1/public/eth\n";
39 static constexpr const char* ITEM_LINE = "\n";
40 static constexpr const char* ITEM_AP_SCAN = "ap_scan=0\n";
41 static constexpr const char* ITEM_NETWORK_START = "network={\n";
42 static constexpr const char* ITEM_NETWORK_END = "}\n";
43 static constexpr const char* ITEM_KEYMGMT = "key_mgmt=IEEE8021X\n";
44 static constexpr const char* ITEM_EAP = "eap=";
45 static constexpr const char* ITEM_PHASE2 = "phase2=";
46 static constexpr const char* ITEM_IDENTITY = "identity=";
47 static constexpr const char* ITEM_PASSWORD = "password=";
48 static constexpr const char* ITEM_CA_CERT = "ca_cert=";
49 static constexpr const char* ITEM_CLIENT_CERT = "client_cert=";
50 static constexpr const char* ITEM_PRIVATE_KEY = "private_key=";
51 
52 static constexpr int8_t IDX_0 = 0;
53 static constexpr int8_t IDX_1 = 1;
54 static constexpr int8_t IDX_2 = 2;
55 static constexpr int8_t IDX_3 = 3;
56 static constexpr int8_t IDX_4 = 4;
57 static constexpr int8_t BASE_10 = 10;
58 static constexpr int8_t WPA_EVENT_REPORT_PARAM_CNT = 5;
59 
60 static std::map<Phase2Method, std::string> PHASE2_METHOD_STR_MAP = {
61     { Phase2Method::PHASE2_NONE, "NONE" },
62     { Phase2Method::PHASE2_PAP, "PAP" },
63     { Phase2Method::PHASE2_MSCHAP, "MSCHAP" },
64     { Phase2Method::PHASE2_MSCHAPV2, "MSCHAPV2" },
65     { Phase2Method::PHASE2_GTC, "GTC" },
66     { Phase2Method::PHASE2_SIM, "SIM" },
67     { Phase2Method::PHASE2_AKA, "AKA" },
68     { Phase2Method::PHASE2_AKA_PRIME, "AKA" },
69 };
70 static std::map<EapMethod, std::string> EAP_METHOD_STR_MAP = {
71     { EapMethod::EAP_NONE, "NONE" },
72     { EapMethod::EAP_PEAP, "PEAP" },
73     { EapMethod::EAP_TLS, "TLS" },
74     { EapMethod::EAP_TTLS, "TTLS" },
75     { EapMethod::EAP_PWD, "PWD" },
76     { EapMethod::EAP_SIM, "SIM" },
77     { EapMethod::EAP_AKA, "AKA" },
78     { EapMethod::EAP_AKA_PRIME, "AKA'" },
79     { EapMethod::EAP_UNAUTH_TLS, "AKA" },
80 };
81 
EapHdiWpaManager()82 EapHdiWpaManager::EapHdiWpaManager()
83 {
84     memset_s(&ethCallback_, sizeof(ethCallback_), 0, sizeof(ethCallback_));
85 }
86 
LoadEthernetHdiService()87 int32_t EapHdiWpaManager::LoadEthernetHdiService()
88 {
89     std::lock_guard<std::mutex> lock(wpaMutex_);
90     if (iEthernet_ != nullptr && devMgr_ != nullptr) {
91         NETMGR_EXT_LOG_I("EthService already load");
92         return EAP_ERRCODE_SUCCESS;
93     }
94     devMgr_ = HDIDeviceManagerGet();
95     if (devMgr_ == nullptr) {
96         NETMGR_EXT_LOG_E("EthService devMgr_ null");
97         return EAP_ERRCODE_INTERNAL_ERROR;
98     }
99     int32_t loadDevRet = devMgr_->LoadDevice(devMgr_, ETHERNET_SERVICE_NAME);
100     if ((loadDevRet != HDF_SUCCESS)) {
101         HDIDeviceManagerRelease(devMgr_);
102         devMgr_ = nullptr;
103         NETMGR_EXT_LOG_E("EthService load fail");
104         return EAP_ERRCODE_INTERNAL_ERROR;
105     }
106     iEthernet_ = IEthernetGetInstance(ETHERNET_SERVICE_NAME, false);
107     if (iEthernet_ == nullptr) {
108         NETMGR_EXT_LOG_E("EthService iEthernet_ null");
109         UnloadDeviceManager();
110         return EAP_ERRCODE_INTERNAL_ERROR;
111     }
112     NETMGR_EXT_LOG_I("EthService succ");
113     return EAP_ERRCODE_SUCCESS;
114 }
115 
StartEap(const std::string & ifName,const EthEapProfile & profile)116 int32_t EapHdiWpaManager::StartEap(const std::string& ifName, const EthEapProfile& profile)
117 {
118     std::lock_guard<std::mutex> lock(wpaMutex_);
119     if (iEthernet_ == nullptr) {
120         NETMGR_EXT_LOG_E("StartEap iEthernet_ null");
121         return EAP_ERRCODE_INTERNAL_ERROR;
122     }
123     RemoveHistoryCtrl();
124     SetEapConfig(profile, ifName);
125     RegisterEapEventCallback(ifName);
126     int32_t ret = iEthernet_->StartEap(iEthernet_, ifName.c_str());
127     if (ret != HDF_SUCCESS) {
128         NETMGR_EXT_LOG_E("StartEap fail %{public}d", ret);
129         IEthernetReleaseInstance(ETHERNET_SERVICE_NAME, iEthernet_, false);
130         iEthernet_ = nullptr;
131         UnloadDeviceManager();
132         return EAP_ERRCODE_INTERNAL_ERROR;
133     }
134     NETMGR_EXT_LOG_I("StartEap succ");
135     return EAP_ERRCODE_SUCCESS;
136 }
137 
StopEap(const std::string & ifName)138 int32_t EapHdiWpaManager::StopEap(const std::string& ifName)
139 {
140     std::lock_guard<std::mutex> lock(wpaMutex_);
141     if (iEthernet_ == nullptr) {
142         NETMGR_EXT_LOG_E("StopEap iEthernet_ null");
143         return EAP_ERRCODE_INTERNAL_ERROR;
144     }
145     UnregisterEapEventCallback(ifName);
146     int32_t ret = iEthernet_->StopEap(iEthernet_, ifName.c_str());
147     NETMGR_EXT_LOG_I("StopEap ret %{public}d", ret);
148     IEthernetReleaseInstance(ETHERNET_SERVICE_NAME, iEthernet_, false);
149     iEthernet_ = nullptr;
150     if (devMgr_ != nullptr) {
151         devMgr_->UnloadDevice(devMgr_, ETHERNET_SERVICE_NAME);
152         HDIDeviceManagerRelease(devMgr_);
153         devMgr_ = nullptr;
154     }
155     NETMGR_EXT_LOG_I("StopEap succ");
156     return (ret == HDF_SUCCESS) ? EAP_ERRCODE_SUCCESS : EAP_ERRCODE_LOGOFF_FAIL;
157 }
158 
RemoveHistoryCtrl()159 void EapHdiWpaManager::RemoveHistoryCtrl()
160 {
161     std::filesystem::path filePath(ETH_CONFIG_ROOR_DIR);
162     if (!std::filesystem::exists(filePath)) {
163         return;
164     }
165     auto truePath = std::filesystem::canonical(filePath);
166     for (const auto& entry : std::filesystem::directory_iterator(truePath)) {
167         if (entry.is_regular_file()) {
168             std::string filename = entry.path().filename().string();
169             if (filename.find(ITEM_WPA_CTRL) != std::string::npos) {
170                 std::filesystem::remove(entry.path());
171             }
172         }
173     }
174 }
175 
SetEapConfig(const EthEapProfile & config,const std::string & ifName)176 int32_t EapHdiWpaManager::SetEapConfig(const EthEapProfile& config, const std::string& ifName)
177 {
178     std::string fileContext;
179     fileContext.append(ITEM_CTRL_IFACE);
180     fileContext.append(ITEM_AP_SCAN);
181     fileContext.append(ITEM_NETWORK_START);
182     fileContext.append(ITEM_KEYMGMT);
183     fileContext.append(ITEM_EAP + EAP_METHOD_STR_MAP[config.eapMethod] + ITEM_LINE);
184     fileContext.append(ITEM_IDENTITY + config.identity + ITEM_LINE);
185     switch (config.eapMethod) {
186         case EapMethod::EAP_PEAP:
187         case EapMethod::EAP_TTLS:
188             fileContext.append(ITEM_PASSWORD + config.password + ITEM_LINE);
189             fileContext.append(ITEM_CA_CERT + config.caPath + ITEM_LINE);
190             fileContext.append(ITEM_PHASE2 + Phase2MethodToStr(config.eapMethod, config.phase2Method) + ITEM_LINE);
191             break;
192         case EapMethod::EAP_TLS:
193             fileContext.append(ITEM_PASSWORD + config.password + ITEM_LINE);
194             fileContext.append(ITEM_CA_CERT + config.caPath + ITEM_LINE);
195             fileContext.append(ITEM_CLIENT_CERT + config.clientCertAliases + ITEM_LINE);
196             fileContext.append(ITEM_PRIVATE_KEY + config.certPassword + ITEM_LINE);
197             break;
198         case EapMethod::EAP_PWD:
199             fileContext.append(ITEM_PASSWORD + config.password + ITEM_LINE);
200             break;
201         default:
202             break;
203     }
204     fileContext.append(ITEM_NETWORK_END);
205     if (!WriteEapConfigToFile(fileContext)) {
206         NETMGR_EXT_LOG_E("SetEapConfig fail");
207         return EAP_ERRCODE_INTERNAL_ERROR;
208     }
209     NETMGR_EXT_LOG_I("SetEapConfig succ");
210     return EAP_ERRCODE_SUCCESS;
211 }
212 
EapShellCmd(const std::string & ifName,const std::string & cmd)213 int32_t EapHdiWpaManager::EapShellCmd(const std::string& ifName, const std::string& cmd)
214 {
215     std::lock_guard<std::mutex> lock(wpaMutex_);
216     if (iEthernet_ == nullptr) {
217         NETMGR_EXT_LOG_E("EapShellCmd iEthernet_ null");
218         return EAP_ERRCODE_INTERNAL_ERROR;
219     }
220     int32_t ret = iEthernet_->EapShellCmd(iEthernet_, ifName.c_str(), cmd.c_str());
221     NETMGR_EXT_LOG_I("EthShellCmd cmd = %{public}s res = %{public}d", cmd.c_str(), ret);
222     return ret;
223 }
224 
RegisterEapEventCallback(const std::string & ifName)225 int32_t EapHdiWpaManager::RegisterEapEventCallback(const std::string& ifName)
226 {
227     if (iEthernet_ == nullptr) {
228         NETMGR_EXT_LOG_E("RegisterEapEvent iEthernet_ null");
229         return EAP_ERRCODE_INTERNAL_ERROR;
230     }
231     ethCallback_.OnEapEventNotify = OnEapEventReport;
232     return iEthernet_->RegisterEapEventCallback(iEthernet_, &ethCallback_, ifName.c_str());
233 }
234 
UnregisterEapEventCallback(const std::string & ifName)235 int32_t EapHdiWpaManager::UnregisterEapEventCallback(const std::string& ifName)
236 {
237     if (iEthernet_ == nullptr) {
238         NETMGR_EXT_LOG_E("UnregisterEapEvent iEthernet_ null");
239         return EAP_ERRCODE_INTERNAL_ERROR;
240     }
241     ethCallback_.OnEapEventNotify = OnEapEventReport;
242     return iEthernet_->UnregisterEapEventCallback(iEthernet_, &ethCallback_, ifName.c_str());
243 }
244 
Phase2MethodToStr(EapMethod eap,Phase2Method method)245 std::string EapHdiWpaManager::Phase2MethodToStr(EapMethod eap, Phase2Method method)
246 {
247     std::string prefix = (eap == EapMethod::EAP_TTLS && method == Phase2Method::PHASE2_GTC) ? "autheap=" : "auth=";
248     return prefix + PHASE2_METHOD_STR_MAP[method];
249 }
250 
WriteEapConfigToFile(const std::string & fileContext)251 bool EapHdiWpaManager::WriteEapConfigToFile(const std::string &fileContext)
252 {
253     std::string destPath = ETH_WPA_CONFIG_PATH;
254     std::ofstream file;
255     file.open(destPath, std::ios::out);
256     if (!file.is_open()) {
257         NETMGR_EXT_LOG_E("WriteEapConfig fail");
258         return false;
259     }
260     file << fileContext << std::endl;
261     file.close();
262     return true;
263 }
264 
OnEapEventReport(IEthernetCallback * self,const char * ifName,const char * value)265 int32_t EapHdiWpaManager::OnEapEventReport(IEthernetCallback *self, const char *ifName, const char *value)
266 {
267     /* @param value -> msgId:eapCode:eapType:bufferLen:eapBuffer */
268     NETMGR_EXT_LOG_I("OnEapEventReport ifName = %{public}s", ifName);
269     std::vector<std::string> vecEapDatas = CommonUtils::Split(value, ":");
270     if (vecEapDatas.size() != WPA_EVENT_REPORT_PARAM_CNT) {
271         NETMGR_EXT_LOG_E("OnEapEventReport value size err");
272         return EAP_ERRCODE_INTERNAL_ERROR;
273     }
274     sptr<EapData> notifyEapData = (std::make_unique<EapData>()).release();
275     ConvertStrToInt(vecEapDatas[IDX_0], notifyEapData->msgId);
276     int32_t eapValue;
277     ConvertStrToInt(vecEapDatas[IDX_1], eapValue);
278     notifyEapData->eapCode = static_cast<uint32_t>(eapValue);
279     ConvertStrToInt(vecEapDatas[IDX_2], eapValue);
280     notifyEapData->eapType = static_cast<uint32_t>(eapValue);
281     ConvertStrToInt(vecEapDatas[IDX_3], notifyEapData->bufferLen);
282     std::string decodeEapBuf = Base64::Decode(vecEapDatas[IDX_4]);
283     notifyEapData->eapBuffer.assign(decodeEapBuf.begin(), decodeEapBuf.end());
284     return NetEapHandler::GetInstance().NotifyWpaEapInterceptInfo(NetType::ETH0, notifyEapData);
285 }
286 
ConvertStrToInt(const std::string & str,int32_t & value)287 bool EapHdiWpaManager::ConvertStrToInt(const std::string &str, int32_t &value)
288 {
289     auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), value, BASE_10);
290     return ec == std::errc{} && ptr == str.data() + str.size();
291 }
292 
RegisterCustomEapCallback(const std::string & ifName,const std::string & regCmd)293 int32_t EapHdiWpaManager::RegisterCustomEapCallback(const std::string &ifName, const std::string &regCmd)
294 {
295     /*  @param regCmd -> netType:size:composeParam1:composeParam2...((eapCode << 8) | eapType) */
296     NETMGR_EXT_LOG_I("RegisterEapCallback regCmd = %{public}s", regCmd.c_str());
297     std::lock_guard<std::mutex> lock(wpaMutex_);
298     if (iEthernet_ == nullptr) {
299         NETMGR_EXT_LOG_E("RegisterEapCallback iEthernet_ null");
300         return EAP_ERRCODE_INTERNAL_ERROR;
301     }
302     std::string cmd = "EXT_AUTH_REG " + regCmd;
303     int32_t result = iEthernet_->EapShellCmd(iEthernet_, ifName.c_str(), cmd.c_str());
304     if (result != HDF_SUCCESS) {
305         NETMGR_EXT_LOG_E("EapShellCmd fail %{public}d", result);
306         return EAP_ERRCODE_INTERNAL_ERROR;
307     }
308     return EAP_ERRCODE_SUCCESS;
309 }
310 
ReplyCustomEapData(const std::string & ifName,int32_t result,const sptr<EapData> & eapData)311 int32_t EapHdiWpaManager::ReplyCustomEapData(const std::string &ifName, int32_t result,
312     const sptr<EapData> &eapData)
313 {
314     NETMGR_EXT_LOG_I("ReplyEapData ifName = %{public}s res = %{public}d", ifName.c_str(), result);
315     std::lock_guard<std::mutex> lock(wpaMutex_);
316     if (iEthernet_ == nullptr) {
317         NETMGR_EXT_LOG_E("ReplyEapData iEthernet_ null");
318         return EAP_ERRCODE_INTERNAL_ERROR;
319     }
320     std::string replyCmd = "EXT_AUTH_DATA " + std::to_string(result) + ":";
321     replyCmd.append(std::to_string(eapData->msgId) + ":");
322     replyCmd.append(std::to_string(eapData->bufferLen) + ":");
323     std::string encodeEapBuf = Base64::Encode(std::string(eapData->eapBuffer.begin(), eapData->eapBuffer.end()));
324     replyCmd.append(encodeEapBuf);
325     NETMGR_EXT_LOG_I("ReplyEapData cmd = %{public}s", replyCmd.c_str());
326     int32_t ret = iEthernet_->EapShellCmd(iEthernet_, ifName.c_str(), replyCmd.c_str());
327     if (ret != HDF_SUCCESS) {
328         NETMGR_EXT_LOG_E("ReplyEapData fail %{public}d", ret);
329         return EAP_ERRCODE_INTERNAL_ERROR;
330     }
331     return EAP_ERRCODE_SUCCESS;
332 }
333 
UnloadDeviceManager()334 void EapHdiWpaManager::UnloadDeviceManager()
335 {
336     if (devMgr_ != nullptr) {
337         devMgr_->UnloadDevice(devMgr_, ETHERNET_SERVICE_NAME);
338         HDIDeviceManagerRelease(devMgr_);
339         devMgr_ = nullptr;
340     }
341 }
342 
343 } // namespace NetManagerStandard
344 }  // namespace OHOS
345