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