OpenVPN 3 Core Library
Loading...
Searching...
No Matches
hostport.hpp
Go to the documentation of this file.
1// OpenVPN -- An application to securely tunnel IP networks
2// over a single port, with support for SSL/TLS-based
3// session authentication and key exchange,
4// packet encryption, packet authentication, and
5// packet compression.
6//
7// Copyright (C) 2012- OpenVPN Inc.
8//
9// SPDX-License-Identifier: MPL-2.0 OR AGPL-3.0-only WITH openvpn3-openssl-exception
10//
11
12#ifndef OPENVPN_COMMON_HOSTPORT_H
13#define OPENVPN_COMMON_HOSTPORT_H
14
15#include <string>
16
20
22OPENVPN_EXCEPTION(host_port_error);
23
24inline bool is_valid_port(const unsigned int port)
25{
26 return port < 65536;
27}
28
29inline bool is_valid_port(const std::string &port, unsigned int *value = nullptr)
30{
31 return parse_number_validate<unsigned int>(port, 5, 1, 65535, value);
32}
33
34inline void validate_port(const std::string &port, const std::string &title, unsigned int *value = nullptr)
35{
36 if (!is_valid_port(port, value))
37 OPENVPN_THROW(host_port_error, "bad " << title << " port number: " << Unicode::utf8_printable(port, 16));
38}
39
40inline void validate_port(const unsigned int port, const std::string &title)
41{
42 if (!is_valid_port(port))
43 OPENVPN_THROW(host_port_error, "bad " << title << " port number: " << port);
44}
45
46inline unsigned short parse_port(const std::string &port, const std::string &title)
47{
48 unsigned int ret = 0;
49 validate_port(port, title, &ret);
50 return static_cast<unsigned short>(ret);
51}
52
53// An IP address is also considered to be a valid host
54inline bool is_valid_host_char(const char c)
55{
56 return (c >= 'a' && c <= 'z')
57 || (c >= 'A' && c <= 'Z')
58 || (c >= '0' && c <= '9')
59 || c == '.'
60 || c == '-'
61 || c == ':'; // for IPv6
62}
63
64inline bool is_valid_host(const std::string &host)
65{
66 if (!host.length() || host.length() > 256)
67 return false;
68 for (const auto &c : host)
69 {
70 if (!is_valid_host_char(c))
71 return false;
72 }
73 return true;
74}
75
76inline bool is_valid_unix_sock_char(const unsigned char c)
77{
78 return c >= 0x21 && c <= 0x7E;
79}
80
81inline bool is_valid_unix_sock(const std::string &host)
82{
83 if (!host.length() || host.length() > 256)
84 return false;
85 for (const auto &c : host)
86 {
88 return false;
89 }
90 return true;
91}
92
93inline void validate_host(const std::string &host, const std::string &title)
94{
95 if (!is_valid_host(host))
96 OPENVPN_THROW(host_port_error, "bad " << title << " host: " << Unicode::utf8_printable(host, 64));
97}
98
99inline bool split_host_port(const std::string &str,
100 std::string &host,
101 std::string &port,
102 const std::string &default_port,
103 const bool allow_unix,
104 unsigned int *port_save = nullptr)
105{
106 if (port_save)
107 *port_save = 0;
108 const size_t fpos = str.find_first_of(':');
109 const size_t lpos = str.find_last_of(':');
110 const size_t cb = str.find_last_of(']');
111 if (lpos != std::string::npos // has one or more colons (':')
112 && (cb == std::string::npos || cb + 1 == lpos) // either has no closing bracket (']') or closing bracket followed by a colon ("]:")
113 && (cb != std::string::npos || fpos == lpos)) // either has a closing bracket (']') or a single colon (':') to avoid fake-out by IPv6 addresses without a port
114 {
115 // host:port or [host]:port specified
116 host = str.substr(0, lpos);
117 port = str.substr(lpos + 1);
118 }
119 else if (!default_port.empty())
120 {
121 // only host specified
122 host = str;
123 port = default_port;
124 }
125 else
126 return false;
127
128 // unbracket host
129 if (host.length() >= 2 && host[0] == '[' && host[host.length() - 1] == ']')
130 host = host.substr(1, host.length() - 2);
131
132 if (allow_unix && port == "unix")
133 return is_valid_unix_sock(host);
134 else
135 return is_valid_host(host) && is_valid_port(port, port_save);
136}
137
138} // namespace openvpn::HostPort
139
140#endif
#define OPENVPN_EXCEPTION(C)
#define OPENVPN_THROW(exc, stuff)
void validate_host(const std::string &host, const std::string &title)
Definition hostport.hpp:93
void validate_port(const std::string &port, const std::string &title, unsigned int *value=nullptr)
Definition hostport.hpp:34
bool is_valid_port(const unsigned int port)
Definition hostport.hpp:24
bool is_valid_unix_sock(const std::string &host)
Definition hostport.hpp:81
bool split_host_port(const std::string &str, std::string &host, std::string &port, const std::string &default_port, const bool allow_unix, unsigned int *port_save=nullptr)
Definition hostport.hpp:99
bool is_valid_host_char(const char c)
Definition hostport.hpp:54
unsigned short parse_port(const std::string &port, const std::string &title)
Definition hostport.hpp:46
bool is_valid_host(const std::string &host)
Definition hostport.hpp:64
bool is_valid_unix_sock_char(const unsigned char c)
Definition hostport.hpp:76
STRING utf8_printable(const STRING &str, size_t max_len_flags)
Definition unicode.hpp:129
proxy_host_port port
os<< "Session Name: "<< tbc-> session_name<< '\n';os<< "Layer: "<< tbc-> layer str()<< '\n'
proxy_host_port host
std::string ret