1 /* Copyright (c) 2016, 2021, Oracle and/or its affiliates. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 22 23 #ifndef GCS_XCOM_NETWORKING_H 24 #define GCS_XCOM_NETWORKING_H 25 26 #include <vector> 27 #include <map> 28 #include <set> 29 #include <string> 30 31 #include "site_struct.h" 32 33 /** 34 This function gets all network addresses on this host and their 35 subnet masks as a string. IPv4 only. (SOCK_STREAM only) 36 @param[out] out maps IP addresses to subnetmasks 37 @param filter_out_inactive If set to true, only active interfaces will be added 38 to out 39 @return false on sucess, true otherwise. 40 */ 41 bool 42 get_ipv4_local_addresses(std::map<std::string, int>& out, 43 bool filter_out_inactive= false); 44 45 /** 46 This function gets all private network addresses and their 47 subnet masks as a string. IPv4 only. (SOCK_STREAM only) 48 @param[out] out maps IP addresses to subnetmasks 49 @param filter_out_inactive If set to true, only active interfaces will be added 50 to out 51 @return false on sucess, true otherwise. 52 */ 53 bool 54 get_ipv4_local_private_addresses(std::map<std::string, int>& out, 55 bool filter_out_inactive= false); 56 57 /** 58 This function translates hostnames to IP addresses. 59 60 @param[in] name The hostname to translate. 61 @param[out] ip The IP address after translation. 62 63 @return false on success, true otherwise. 64 */ 65 bool 66 resolve_ip_addr_from_hostname(std::string name, std::string& ip); 67 68 /** 69 Converts an address in string format (X.X.X.X/XX) into network octet format 70 71 @param[in] addr IP address in X.X.X.X format 72 @param[in] mask Network mask associated with the address 73 @param[out] out_pair 74 75 @return false on success, true otherwise. 76 */ 77 bool 78 get_address_for_whitelist(std::string addr, std::string mask, 79 std::pair<std::vector<unsigned char>, 80 std::vector<unsigned char> > &out_pair); 81 82 /** 83 @class Gcs_ip_whitelist_entry 84 @brief Base abstract class for the whitelist entries. 85 86 This is the base class for the Whitelist entries. Any derived class must 87 implement its two abstract methods: 88 - init_value(); 89 - get_value(); 90 */ 91 class Gcs_ip_whitelist_entry 92 { 93 public: 94 /** 95 Constructor 96 97 @param[in] addr IP address or hostname of this entry 98 @param[in] mask Network mask of this entry. 99 */ 100 Gcs_ip_whitelist_entry(std::string addr, std::string mask); 101 ~Gcs_ip_whitelist_entry()102 virtual ~Gcs_ip_whitelist_entry() {} 103 104 /** 105 Entry initialization. 106 107 If one needs to initialize internal values, it should be done in this 108 method. 109 110 @return false on success, true otherwise 111 */ 112 virtual bool init_value() = 0; 113 114 /** 115 Virtual member function that implements value retrieval for this entry. 116 117 The returned value must be an std::pair that contains both the address and the 118 mask in network octet value. 119 120 @return an std::pair with ip and mask in network octet form 121 */ 122 virtual std::pair< std::vector<unsigned char>, 123 std::vector<unsigned char> > *get_value() = 0; 124 125 /** Getters */ get_addr()126 std::string get_addr() const {return m_addr;}; get_mask()127 std::string get_mask() const {return m_mask;}; 128 129 private: 130 std::string m_addr; 131 std::string m_mask; 132 }; 133 134 struct Gcs_ip_whitelist_entry_pointer_comparator { operatorGcs_ip_whitelist_entry_pointer_comparator135 bool operator() (const Gcs_ip_whitelist_entry* lhs, 136 const Gcs_ip_whitelist_entry* rhs) const { 137 //Check if addresses are different in content 138 if(lhs->get_addr() != rhs->get_addr()) 139 { //Then compare only the addresses 140 return lhs->get_addr() < rhs->get_addr(); 141 } 142 else 143 { //If addresses are equal, then compare the masks to untie. 144 return lhs->get_mask() < rhs->get_mask(); 145 } 146 } 147 }; 148 149 /** 150 @class Gcs_ip_whitelist_entry_ip 151 @brief Implementation of Gcs_ip_whitelist_entry to use with 152 raw IP addresses in format X.X.X.X/XX 153 */ 154 class Gcs_ip_whitelist_entry_ip: public Gcs_ip_whitelist_entry 155 { 156 public: 157 Gcs_ip_whitelist_entry_ip(std::string addr, std::string mask); 158 159 public: 160 bool init_value(); 161 std::pair<std::vector<unsigned char>, std::vector<unsigned char> > *get_value(); 162 163 private: 164 std::pair<std::vector<unsigned char>, std::vector<unsigned char> > m_value; 165 }; 166 167 /** 168 @class Gcs_ip_whitelist_entry_hostname 169 @brief Implementation of Gcs_ip_whitelist_entry to use with 170 hostnames 171 */ 172 class Gcs_ip_whitelist_entry_hostname: public Gcs_ip_whitelist_entry 173 { 174 public: 175 Gcs_ip_whitelist_entry_hostname(std::string addr, std::string mask); 176 177 public: 178 bool init_value(); 179 std::pair<std::vector<unsigned char>, std::vector<unsigned char> > *get_value(); 180 }; 181 182 class Gcs_ip_whitelist 183 { 184 public: 185 static const std::string DEFAULT_WHITELIST; 186 187 private: 188 /* 189 The IP whitelist. It is a list of tuples Hexadecimal IP number 190 and subnet mask also in Hexadecimal. E.g.: 192.168.1.2/24 or 127.0.0.1/32. 191 192 This is for optimization purposes, so that we don't calculate the 193 values each time we want to check. 194 */ 195 std::set< Gcs_ip_whitelist_entry*, 196 Gcs_ip_whitelist_entry_pointer_comparator> m_ip_whitelist; 197 198 /** 199 This is the list that originally submitted to be parsed and to configure 200 the whitelist. 201 */ 202 std::string m_original_list; 203 204 public: Gcs_ip_whitelist()205 Gcs_ip_whitelist() : 206 m_ip_whitelist(), 207 m_original_list() {} 208 virtual ~Gcs_ip_whitelist(); 209 210 /** 211 This member function shall be used to configure the whitelist. 212 213 @param the_list The list with IP addresses. This list is a comma separated 214 list formatted only with IP addresses and/or in the form of 215 a subnet range, e.g., IP/netbits. 216 @return true if the configuration failed, false otherwise. 217 */ 218 bool configure(const std::string& the_list); 219 220 /** 221 This member function shall be used to validate the list that is used as input 222 to the configure member function. 223 224 @param the_list The list with IP addresses. This list is a comma separated 225 list formatted only with IP addresses and/or in the form of 226 a subnet range, e.g., IP/netbits. 227 228 @return true if the configuration failed, false otherwise. 229 */ 230 bool is_valid(const std::string& the_list) const; 231 232 /** 233 This member function SHALL return true if the given IP is to be blocked, 234 false otherwise. 235 236 @param ip_addr a string representation of an IPv4 address. 237 @param xcom_config the latest XCom configuration. 238 239 @return true if the ip should be blocked, false otherwise. 240 */ 241 bool shall_block(const std::string& ip_addr, 242 site_def const *xcom_config= NULL) const; 243 244 /** 245 This member function SHALL return true if the IP of the given file descriptor 246 is to be blocked, false otherwise. 247 248 @param fd the file descriptor of the accepted socket to check. 249 @param xcom_config the latest XCom configuration. 250 251 @return true if the ip should be blocked, false otherwise. 252 */ 253 bool shall_block(int fd, site_def const *xcom_config= NULL) const; 254 255 /** 256 This member function gets the textual representation of the list as 257 provided to the configure member function. 258 */ get_configured_ip_whitelist()259 const std::string& get_configured_ip_whitelist() const { return m_original_list; } 260 261 /** 262 A string representation of the internal list of IP addresses. Can have 263 more addresses than those submitted through the configure member 264 function, since there are addresses that are implicitly added when 265 configuring the list. 266 */ 267 std::string to_string() const; 268 269 private: 270 bool do_check_block(struct sockaddr_storage *sa, 271 site_def const *xcom_config) const; 272 bool do_check_block_whitelist( 273 std::vector<unsigned char> const& incoming_octets) const; 274 bool do_check_block_xcom(std::vector<unsigned char> const& incoming_octets, 275 site_def const *xcom_config) const; 276 bool add_address(std::string addr, std::string mask); 277 278 private: 279 Gcs_ip_whitelist(Gcs_ip_whitelist const&); 280 Gcs_ip_whitelist& operator=(Gcs_ip_whitelist const&); 281 }; 282 283 284 #endif /* GCS_XCOM_NETWORKING_H */ 285 286