OpenVPN 3 Core Library
Loading...
Searching...
No Matches
httpvpn.hpp
Go to the documentation of this file.
1//
2// OpenVPN
3//
4// Copyright (C) 2012-2022 OpenVPN Technologies, Inc.
5// All rights reserved.
6//
7
8#pragma once
9
10#include <utility>
11#include <memory>
12
16
17namespace openvpn::WS {
18
19// Helper class for HTTP client and server connections
20// to strongly bind to a VPN client tunnel interface.
21class ViaVPN : public RC<thread_unsafe_refcount>
22{
23 public:
25
26 OPENVPN_EXCEPTION(via_vpn_error);
27
29 {
34 };
35
36 static bool is_enabled(const OptionList &opt)
37 {
38 return opt.exists("vpn-connection-info");
39 }
40
41 ViaVPN(const OptionList &opt)
42 {
43 const Option &o = opt.get("vpn-connection-info");
44 connection_info_fn = o.get(1, 256);
46 }
47
48 ViaVPN(std::string conn_info_fn,
49 const std::string &gw)
50 : connection_info_fn(std::move(conn_info_fn)),
52 {
53 }
54
56 {
57 if (is_enabled(opt))
58 return ViaVPN::Ptr(new WS::ViaVPN(opt));
59 else
60 return ViaVPN::Ptr();
61 }
62
63 template <typename HOST>
64 Json::Value client_update_host(HOST &host) const
65 {
66 Json::Value root = json::parse_from_file(connection_info_fn);
67 set_host_field(host.local_addr, root, "vpn_ip4", connection_info_fn);
68 set_host_field(host.local_addr_alt, root, "vpn_ip6", connection_info_fn);
69 maybe_swap(host.local_addr, host.local_addr_alt);
70
71 // use gw4/gw6 as host hint
72 if (gw_type == GW || gw_type == GW4)
73 set_host_field(host.hint, root, "gw4", connection_info_fn);
74 if (gw_type == GW || gw_type == GW6)
75 set_host_field(host.hint, root, "gw6", connection_info_fn);
76
77 return root;
78 }
79
80 template <typename LISTEN_ITEM>
81 static IP::Addr server_local_addr(const LISTEN_ITEM &listen_item,
82 const GatewayType gw_type)
83 {
84 if (listen_item.addr.empty())
85 throw via_vpn_error("listen_item is empty");
86
87 // via-VPN processing enabled?
88 if (listen_item.addr[0] == '@')
89 {
90 const Json::Value root = json::parse_from_file(listen_item.addr.substr(1));
91 std::string ipstr;
92 if (gw_type == GW || gw_type == GW4)
93 set_host_field(ipstr, root, "vpn_ip4", listen_item.addr);
94 if (gw_type == GW || gw_type == GW6)
95 set_host_field(ipstr, root, "vpn_ip6", listen_item.addr);
96 if (ipstr.empty())
97 throw via_vpn_error("cannot find local address in " + listen_item.addr);
98 const IP::Addr ret = IP::Addr(ipstr, listen_item.addr);
99 OPENVPN_LOG("using local address " << ret.to_string() << " for " << listen_item.directive << ' ' << listen_item.addr);
100 return ret;
101 }
102 else
103 return IP::Addr(listen_item.addr, listen_item.directive);
104 }
105
106 // returns the "client-ip" directive pushed by the server
108 {
109 const Json::Value root = json::parse_from_file(connection_info_fn);
110 return IP::Addr(json::get_string_ref(root, "client_ip", connection_info_fn), connection_info_fn);
111 }
112
113 std::string to_string() const
114 {
115 std::string ret;
116 ret.reserve(128);
117 ret += "[ViaVPN ";
119 if (gw_type != NONE)
120 {
121 ret += ' ';
123 }
124 ret += ']';
125 return ret;
126 }
127
128 private:
129 static void set_host_field(std::string &dest,
130 const Json::Value &root,
131 const std::string &name,
132 const std::string &title)
133 {
134 std::string value = json::get_string_optional(root, name, std::string(), title);
135 if (dest.empty() && !value.empty())
136 dest = std::move(value);
137 }
138
139 // if only one of s1 and s2 are non-empty, make sure it is s1
140 static void maybe_swap(std::string &s1, std::string &s2)
141 {
142 if (s1.empty() && !s2.empty())
143 std::swap(s1, s2);
144 }
145
146 static GatewayType parse_gw_type(const std::string &gw)
147 {
148 if (gw.empty())
149 return NONE;
150 else if (gw == "gw")
151 return GW;
152 else if (gw == "gw4")
153 return GW4;
154 else if (gw == "gw6")
155 return GW6;
156 else
157 throw via_vpn_error("ViaVPN: bad gw parameter");
158 }
159
160 static std::string gw_type_to_string(const GatewayType gw_type)
161 {
162 switch (gw_type)
163 {
164 case NONE:
165 return "GW-NONE";
166 case GW:
167 return "GW";
168 case GW4:
169 return "GW4";
170 case GW6:
171 return "GW6";
172 default:
173 return "GW-?";
174 }
175 }
176
179};
180
181} // namespace openvpn::WS
const Option & get(const std::string &name) const
Definition options.hpp:1254
bool exists(const std::string &name) const
Definition options.hpp:1325
std::string get_optional(const size_t index, const size_t max_len) const
Definition options.hpp:194
const std::string & get(const size_t index, const size_t max_len) const
Definition options.hpp:187
The smart pointer class.
Definition rc.hpp:119
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
Definition rc.hpp:912
OPENVPN_EXCEPTION(via_vpn_error)
static void maybe_swap(std::string &s1, std::string &s2)
Definition httpvpn.hpp:140
ViaVPN(std::string conn_info_fn, const std::string &gw)
Definition httpvpn.hpp:48
ViaVPN(const OptionList &opt)
Definition httpvpn.hpp:41
static GatewayType parse_gw_type(const std::string &gw)
Definition httpvpn.hpp:146
std::string connection_info_fn
Definition httpvpn.hpp:177
static ViaVPN::Ptr client_new_if_enabled(const OptionList &opt)
Definition httpvpn.hpp:55
Json::Value client_update_host(HOST &host) const
Definition httpvpn.hpp:64
static std::string gw_type_to_string(const GatewayType gw_type)
Definition httpvpn.hpp:160
GatewayType gw_type
Definition httpvpn.hpp:178
static void set_host_field(std::string &dest, const Json::Value &root, const std::string &name, const std::string &title)
Definition httpvpn.hpp:129
static bool is_enabled(const OptionList &opt)
Definition httpvpn.hpp:36
std::string to_string() const
Definition httpvpn.hpp:113
IP::Addr client_ip() const
Definition httpvpn.hpp:107
RCPtr< ViaVPN > Ptr
Definition httpvpn.hpp:24
static IP::Addr server_local_addr(const LISTEN_ITEM &listen_item, const GatewayType gw_type)
Definition httpvpn.hpp:81
#define OPENVPN_LOG(args)
Json::Value parse_from_file(const std::string &fn)
std::string get_string_optional(const Json::Value &root, const NAME &name, const std::string &default_value, const TITLE &title)
proxy_host_port host
std::string ret