1 /*
2 * Copyright (c) 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 "open_vpn_ctl.h"
17
18 #include <fstream>
19
20 #include "base64_utils.h"
21 #include "netmanager_base_common_utils.h"
22 #include "netmgr_ext_log_wrapper.h"
23
24 namespace OHOS {
25 namespace NetManagerStandard {
26
OpenvpnCtl(sptr<VpnConfig> config, const std::string &pkg, int32_t userId, std::vector<int32_t> &activeUserIds)27 OpenvpnCtl::OpenvpnCtl(sptr<VpnConfig> config, const std::string &pkg, int32_t userId,
28 std::vector<int32_t> &activeUserIds) : NetVpnImpl(config, pkg, userId, activeUserIds)
29 {
30 }
31
SetUp()32 int32_t OpenvpnCtl::SetUp()
33 {
34 UpdateOpenvpnState(OPENVPN_STATE_SETUP);
35 return StartOpenvpn();
36 }
37
StartOpenvpn()38 int32_t OpenvpnCtl::StartOpenvpn()
39 {
40 if (openvpnConfig_ == nullptr) {
41 NETMGR_EXT_LOG_E("StartOpenvpn openvpnConfig_ is null");
42 return NETMANAGER_EXT_ERR_INTERNAL;
43 }
44 UpdateOpenvpnState(OPENVPN_STATE_STARTED);
45 if (!std::filesystem::exists(VPN_PIDDIR) || !std::filesystem::is_directory(VPN_PIDDIR)) {
46 NETMGR_EXT_LOG_E("StartOpenvpn config dir check error.");
47 return NETMANAGER_EXT_ERR_INTERNAL;
48 }
49 std::string cfg = Base64::Decode(openvpnConfig_->ovpnConfig_);
50 std::ofstream ofs(OPENVPN_CONFIG_FILE, std::ios::out | std::ios::trunc);
51 if (!ofs.is_open()) {
52 NETMGR_EXT_LOG_E("StartOpenvpn config file open failed");
53 return NETMANAGER_EXT_ERR_INTERNAL;
54 }
55 ofs << cfg;
56 if (!openvpnConfig_->askpass_.empty()) {
57 std::ofstream askpassOfs(OPENVPN_ASKPASS_FILE, std::ios::out | std::ios::trunc);
58 if (!askpassOfs.is_open()) {
59 NETMGR_EXT_LOG_E("StartOpenvpn askpass file open failed");
60 return NETMANAGER_EXT_ERR_INTERNAL;
61 }
62 askpassOfs << openvpnConfig_->askpass_ << std::endl;
63 ofs << OPENVPN_ASKPASS_PARAM << std::endl;
64 }
65 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_OPENVPN_RESTART);
66 return NETMANAGER_EXT_SUCCESS;
67 }
68
NotifyConnectStage(const std::string &stage, const int32_t &result)69 int32_t OpenvpnCtl::NotifyConnectStage(const std::string &stage, const int32_t &result)
70 {
71 if (stage.empty()) {
72 NETMGR_EXT_LOG_E("stage is empty");
73 return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
74 }
75 if (result != NETMANAGER_EXT_SUCCESS) {
76 NETMGR_EXT_LOG_E("vpn stage failed, result: %{public}d", result);
77 return NETMANAGER_EXT_ERR_INTERNAL;
78 }
79 return HandleClientMessage(stage);
80 }
81
SetUpVpnTun()82 int32_t OpenvpnCtl::SetUpVpnTun()
83 {
84 int result = NetVpnImpl::SetUp();
85 if (result != NETMANAGER_EXT_SUCCESS) {
86 NETMGR_EXT_LOG_W("openvpn SetUp failed");
87 StopOpenvpn();
88 UpdateOpenvpnState(OPENVPN_STATE_DISCONNECTED);
89 }
90 NETMGR_EXT_LOG_I("openvpn SetUp %{public}d", result);
91 return result;
92 }
93
HandleClientMessage(const std::string &msg)94 int32_t OpenvpnCtl::HandleClientMessage(const std::string &msg)
95 {
96 int result = NETMANAGER_EXT_SUCCESS;
97 if (msg.empty()) {
98 NETMGR_EXT_LOG_E("msg is empty");
99 return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
100 }
101 NETMGR_EXT_LOG_I("Process Request message: %{public}s", MaskOpenvpnMessage(msg).c_str());
102 if (strstr(msg.c_str(), OPENVPN_NODE_ROOT) != 0) {
103 const char *ret = strstr(msg.c_str(), "{");
104 if (ret == nullptr) {
105 NETMGR_EXT_LOG_E("client message format error");
106 return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
107 }
108 cJSON* message = cJSON_Parse(ret);
109 if (message == nullptr) {
110 NETMGR_EXT_LOG_E("not json string");
111 return NETMANAGER_EXT_ERR_PARAMETER_ERROR;
112 }
113 // is config message
114 cJSON* config = cJSON_GetObjectItem(message, OPENVPN_NODE_CONFIG);
115 if (config != nullptr && cJSON_IsObject(config)) {
116 UpdateConfig(config);
117 }
118 // is state message
119 cJSON* state = cJSON_GetObjectItem(message, OPENVPN_NODE_UPDATE_STATE);
120 if (state != nullptr && cJSON_IsObject(state)) {
121 UpdateState(state);
122 }
123 // is setup message
124 cJSON* vpnSetUp = cJSON_GetObjectItem(message, OPENVPN_NODE_SETUP_VPN_TUN);
125 if (vpnSetUp != nullptr && cJSON_IsObject(vpnSetUp)) {
126 result = SetUpVpnTun();
127 }
128 cJSON_Delete(message);
129 }
130 return result;
131 }
132
UpdateState(cJSON* state)133 void OpenvpnCtl::UpdateState(cJSON* state)
134 {
135 cJSON* updateState = cJSON_GetObjectItem(state, OPENVPN_NODE_STATE);
136 if (updateState != nullptr && cJSON_IsNumber(updateState)) {
137 int32_t openVpnState = static_cast<int32_t>(cJSON_GetNumberValue(updateState));
138 UpdateOpenvpnState(openVpnState);
139 if (openVpnState == OPENVPN_STATE_DISCONNECTED || openVpnState >= OPENVPN_STATE_ERROR_PRIVATE_KEY) {
140 NETMGR_EXT_LOG_I("UpdatesState: %{public}d", openVpnState);
141 StopOpenvpn();
142 }
143 }
144 }
145
UpdateConfig(cJSON *jConfig)146 void OpenvpnCtl::UpdateConfig(cJSON *jConfig)
147 {
148 if (vpnConfig_ == nullptr) {
149 NETMGR_EXT_LOG_E("UpdateConfig vpnConfig_ is null");
150 return;
151 }
152 cJSON *mtu = cJSON_GetObjectItem(jConfig, OPENVPN_NODE_MTU);
153 if (mtu != nullptr && cJSON_IsNumber(mtu)) {
154 int32_t openVpnMtu = static_cast<int32_t>(cJSON_GetNumberValue(mtu));
155 vpnConfig_->mtu_ = openVpnMtu;
156 NETMGR_EXT_LOG_I("UpdateConfig mtu %{public}d", openVpnMtu);
157 }
158 INetAddr iNetAddr;
159 INetAddr destination;
160 INetAddr gateway;
161 Route iRoute;
162 cJSON *address = cJSON_GetObjectItem(jConfig, OPENVPN_NODE_ADDRESS);
163 if (address != nullptr && cJSON_IsString(address)) {
164 std::string openVpnAddress = cJSON_GetStringValue(address);
165 iNetAddr.address_ = openVpnAddress;
166 gateway.address_ = openVpnAddress;
167 destination.address_ = openVpnAddress;
168 }
169 cJSON *netmask = cJSON_GetObjectItem(jConfig, OPENVPN_NODE_NETMASK);
170 if (netmask != nullptr && cJSON_IsString(netmask)) {
171 std::string openVpnNetmask = cJSON_GetStringValue(netmask);
172 iNetAddr.netMask_ = openVpnNetmask;
173 destination.prefixlen_ = CommonUtils::GetMaskLength(openVpnNetmask);
174 NETMGR_EXT_LOG_I("UpdateConfig prefixlen %{public}d", destination.prefixlen_);
175 }
176 vpnConfig_->addresses_.emplace_back(iNetAddr);
177
178 iRoute.iface_ = TUN_CARD_NAME;
179 iRoute.isDefaultRoute_ = true;
180 iRoute.destination_ = destination;
181 iRoute.gateway_ = gateway;
182 vpnConfig_->routes_.emplace_back(iRoute);
183 }
184
UpdateOpenvpnState(const int32_t state)185 void OpenvpnCtl::UpdateOpenvpnState(const int32_t state)
186 {
187 switch (state) {
188 case OPENVPN_STATE_CONNECTED:
189 NotifyConnectState(VpnConnectState::VPN_CONNECTED);
190 break;
191 case OPENVPN_STATE_DISCONNECTED:
192 case OPENVPN_STATE_ERROR_PRIVATE_KEY:
193 case OPENVPN_STATE_ERROR_CLIENT_CRT:
194 case OPENVPN_STATE_ERROR_CA_CAT:
195 case OPENVPN_STATE_ERROR_TIME_OUT:
196 NotifyConnectState(VpnConnectState::VPN_DISCONNECTED);
197 break;
198 default:
199 NETMGR_EXT_LOG_E("unknown openvpn state: %{public}d", state);
200 break;
201 }
202 openvpnState_ = state;
203 }
204
IsSystemVpn()205 bool OpenvpnCtl::IsSystemVpn()
206 {
207 return true;
208 }
209
Destroy()210 int32_t OpenvpnCtl::Destroy()
211 {
212 StopOpenvpn();
213 int result = NetVpnImpl::Destroy();
214 NETMGR_EXT_LOG_I("openvpn Destroy result %{public}d}", result);
215 return result;
216 }
217
StopOpenvpn()218 void OpenvpnCtl::StopOpenvpn()
219 {
220 NetsysController::GetInstance().ProcessVpnStage(SysVpnStageCode::VPN_STAGE_OPENVPN_STOP);
221 UpdateOpenvpnState(OPENVPN_STATE_DISCONNECTED);
222 }
223
GetConnectedSysVpnConfig(sptr<SysVpnConfig> &sysVpnConfig)224 int32_t OpenvpnCtl::GetConnectedSysVpnConfig(sptr<SysVpnConfig> &sysVpnConfig)
225 {
226 if (openvpnState_ == OPENVPN_STATE_CONNECTED && openvpnConfig_ != nullptr) {
227 sysVpnConfig = openvpnConfig_;
228 }
229 return NETMANAGER_EXT_SUCCESS;
230 }
231
IsInternalVpn()232 bool OpenvpnCtl::IsInternalVpn()
233 {
234 return true;
235 }
236
MaskOpenvpnMessage(const std::string &msg)237 std::string OpenvpnCtl::MaskOpenvpnMessage(const std::string &msg)
238 {
239 if (msg.empty()) {
240 NETMGR_EXT_LOG_E("msg is empty");
241 return "";
242 }
243 std::string result = msg;
244 size_t addressPos = result.find(OPENVPN_NODE_CONFIG);
245 if (addressPos != std::string::npos) {
246 size_t pos = addressPos + strlen(OPENVPN_NODE_CONFIG);
247 size_t replaceLen = result.size() - pos;
248 if (replaceLen > 0) {
249 result.replace(pos, replaceLen, OPENVPN_MASK_TAG);
250 }
251 return result;
252 }
253
254 return msg;
255 }
256 } // namespace NetManagerStandard
257 } // namespace OHOS